Files
Toju/src/app/features/auth/login.component.ts
2025-12-28 08:23:30 +01:00

95 lines
3.8 KiB
TypeScript

import { Component, inject, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideLogIn } from '@ng-icons/lucide';
import { AuthService } from '../../core/services/auth.service';
import { ServerDirectoryService } from '../../core/services/server-directory.service';
import * as UsersActions from '../../store/users/users.actions';
import { User } from '../../core/models';
@Component({
selector: 'app-login',
standalone: true,
imports: [CommonModule, FormsModule, NgIcon],
viewProviders: [provideIcons({ lucideLogIn })],
template: `
<div class="h-full grid place-items-center bg-background">
<div class="w-[360px] bg-card border border-border rounded-xl p-6 shadow-sm">
<div class="flex items-center gap-2 mb-4">
<ng-icon name="lucideLogIn" class="w-5 h-5 text-primary" />
<h1 class="text-lg font-semibold text-foreground">Login</h1>
</div>
<div class="space-y-3">
<div>
<label class="block text-xs text-muted-foreground mb-1">Username</label>
<input [(ngModel)]="username" type="text" class="w-full px-3 py-2 rounded border border-border bg-secondary text-foreground" />
</div>
<div>
<label class="block text-xs text-muted-foreground mb-1">Password</label>
<input [(ngModel)]="password" type="password" class="w-full px-3 py-2 rounded border border-border bg-secondary text-foreground" />
</div>
<div>
<label class="block text-xs text-muted-foreground mb-1">Server App</label>
<select [(ngModel)]="serverId" class="w-full px-3 py-2 rounded border border-border bg-secondary text-foreground">
<option *ngFor="let s of servers(); trackBy: trackById" [value]="s.id">{{ s.name }}</option>
</select>
</div>
<p *ngIf="error()" class="text-xs text-destructive">{{ error() }}</p>
<button (click)="submit()" class="w-full px-3 py-2 rounded bg-primary text-primary-foreground hover:bg-primary/90">Login</button>
<div class="text-xs text-muted-foreground text-center mt-2">
No account? <a class="text-primary hover:underline" (click)="goRegister()">Register</a>
</div>
</div>
</div>
</div>
`,
})
export class LoginComponent {
private auth = inject(AuthService);
private serversSvc = inject(ServerDirectoryService);
private store = inject(Store);
private router = inject(Router);
servers = this.serversSvc.servers;
username = '';
password = '';
serverId: string | undefined = this.serversSvc.activeServer()?.id;
error = signal<string | null>(null);
trackById(_index: number, item: { id: string }) { return item.id; }
submit() {
this.error.set(null);
const sid = this.serverId || this.serversSvc.activeServer()?.id;
this.auth.login({ username: this.username.trim(), password: this.password, serverId: sid }).subscribe({
next: (resp) => {
if (sid) this.serversSvc.setActiveServer(sid);
const user: User = {
id: resp.id,
oderId: resp.id,
username: resp.username,
displayName: resp.displayName,
status: 'online',
role: 'member',
joinedAt: Date.now(),
};
try { localStorage.setItem('metoyou_currentUserId', resp.id); } catch {}
this.store.dispatch(UsersActions.setCurrentUser({ user }));
this.router.navigate(['/search']);
},
error: (err) => {
this.error.set(err?.error?.error || 'Login failed');
},
});
}
goRegister() {
this.router.navigate(['/register']);
}
}