refactor: Clean lint errors and organise files
This commit is contained in:
@@ -19,80 +19,12 @@ import { User, UserStatus } from '../../../shared-kernel';
|
||||
UserAvatarComponent
|
||||
],
|
||||
viewProviders: [provideIcons({ lucideChevronDown })],
|
||||
template: `
|
||||
<div
|
||||
class="w-72 rounded-lg border border-border bg-card shadow-xl"
|
||||
style="animation: profile-card-in 120ms cubic-bezier(0.2, 0, 0, 1) both"
|
||||
>
|
||||
<!-- Banner -->
|
||||
<div class="h-24 rounded-t-lg bg-gradient-to-r from-primary/30 to-primary/10"></div>
|
||||
|
||||
<!-- Avatar (overlapping banner) -->
|
||||
<div class="relative px-4">
|
||||
<div class="-mt-9">
|
||||
<app-user-avatar
|
||||
[name]="user().displayName"
|
||||
[avatarUrl]="user().avatarUrl"
|
||||
size="xl"
|
||||
[status]="user().status"
|
||||
[showStatusBadge]="true"
|
||||
ringClass="ring-4 ring-card"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Info -->
|
||||
<div class="px-5 pt-3 pb-4">
|
||||
<p class="text-base font-semibold text-foreground truncate">{{ user().displayName }}</p>
|
||||
<p class="text-sm text-muted-foreground truncate">{{ user().username }}</p>
|
||||
|
||||
@if (editable()) {
|
||||
<!-- Status picker -->
|
||||
<div class="relative mt-3">
|
||||
<button
|
||||
type="button"
|
||||
class="flex w-full items-center gap-2 rounded-md border border-border px-2.5 py-1.5 text-xs hover:bg-secondary/60 transition-colors"
|
||||
(click)="toggleStatusMenu()"
|
||||
>
|
||||
<span class="w-2 h-2 rounded-full" [class]="currentStatusColor()"></span>
|
||||
<span class="flex-1 text-left text-foreground">{{ currentStatusLabel() }}</span>
|
||||
<ng-icon
|
||||
name="lucideChevronDown"
|
||||
class="w-3 h-3 text-muted-foreground"
|
||||
/>
|
||||
</button>
|
||||
@if (showStatusMenu()) {
|
||||
<div class="absolute left-0 bottom-full mb-1 w-full bg-card border border-border rounded-md shadow-lg py-1 z-10">
|
||||
@for (opt of statusOptions; track opt.label) {
|
||||
<button
|
||||
type="button"
|
||||
class="w-full px-3 py-1.5 text-left text-xs hover:bg-secondary flex items-center gap-2"
|
||||
(click)="setStatus(opt.value)"
|
||||
>
|
||||
<span class="w-2 h-2 rounded-full" [class]="opt.color"></span>
|
||||
<span>{{ opt.label }}</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
} @else {
|
||||
<div class="mt-2 flex items-center gap-1.5 text-xs text-muted-foreground">
|
||||
<span class="w-2 h-2 rounded-full" [class]="currentStatusColor()"></span>
|
||||
<span>{{ currentStatusLabel() }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
templateUrl: './profile-card.component.html'
|
||||
})
|
||||
export class ProfileCardComponent {
|
||||
user = signal<User>({ id: '', oderId: '', username: '', displayName: '', status: 'offline', role: 'member', joinedAt: 0 });
|
||||
editable = signal(false);
|
||||
|
||||
private userStatus = inject(UserStatusService);
|
||||
showStatusMenu = signal(false);
|
||||
readonly user = signal<User>({ id: '', oderId: '', username: '', displayName: '', status: 'offline', role: 'member', joinedAt: 0 });
|
||||
readonly editable = signal(false);
|
||||
readonly showStatusMenu = signal(false);
|
||||
|
||||
readonly statusOptions: { value: UserStatus | null; label: string; color: string }[] = [
|
||||
{ value: null, label: 'Online', color: 'bg-green-500' },
|
||||
@@ -101,6 +33,8 @@ export class ProfileCardComponent {
|
||||
{ value: 'offline', label: 'Invisible', color: 'bg-gray-500' }
|
||||
];
|
||||
|
||||
private readonly userStatus = inject(UserStatusService);
|
||||
|
||||
currentStatusColor(): string {
|
||||
switch (this.user().status) {
|
||||
case 'online': return 'bg-green-500';
|
||||
@@ -124,7 +58,7 @@ export class ProfileCardComponent {
|
||||
}
|
||||
|
||||
toggleStatusMenu(): void {
|
||||
this.showStatusMenu.update((v) => !v);
|
||||
this.showStatusMenu.update((isOpen) => !isOpen);
|
||||
}
|
||||
|
||||
setStatus(status: UserStatus | null): void {
|
||||
|
||||
Reference in New Issue
Block a user