feat(frontend): add mobile-first Material redesign (#17)

This commit is contained in:
nessar committed 2026-08-17 14:18:14 +02:00
1 parent fd3fc0123a
commit 1a70bcd126
15 files changed
+1781 -721

No files matched your search

+44 -26
View File
@@ -1,20 +1,33 @@
import { Component, signal, inject, OnInit, effect } from '@angular/core';
import { Component, computed, signal, inject, OnInit, effect } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ApartmentService, Apartment } from './apartment.service';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatRadioModule } from '@angular/material/radio';
import { ThemeService } from './theme.service';
import { BrandMark } from './brand-mark';
@Component({
selector: 'app-root',
imports: [FormsModule],
imports: [
BrandMark,
FormsModule,
MatButtonModule,
MatFormFieldModule,
MatInputModule,
MatRadioModule,
],
templateUrl: './app.html',
styleUrl: './app.css'
styleUrl: './app.css',
})
export class App implements OnInit {
protected readonly title = signal('LMNP Organizer');
readonly helloMessage = signal<string>('');
// Tab & CRUD States
readonly activeTab = signal<'dashboard' | 'apartments'>('dashboard');
readonly activeTab = signal<'dashboard' | 'apartments' | 'settings'>('dashboard');
readonly apartments = signal<Apartment[]>([]);
readonly showForm = signal<boolean>(false);
readonly editingApartment = signal<Apartment | null>(null);
@@ -29,9 +42,12 @@ export class App implements OnInit {
private readonly _isLoggedIn = signal<boolean>(false);
private readonly _username = signal<string>('');
private readonly _email = signal<string>('');
readonly userInitial = computed(() => this._username().charAt(0).toUpperCase());
private readonly http = inject(HttpClient);
private readonly apartmentService = inject(ApartmentService);
protected readonly themeService = inject(ThemeService);
readonly themePreference = this.themeService.preference;
constructor() {
effect(() => {
@@ -42,25 +58,27 @@ export class App implements OnInit {
}
ngOnInit() {
this.http.get<{ authenticated: boolean, username?: string, email?: string }>('/api/user').subscribe({
next: (user) => {
if (user.authenticated) {
this._isLoggedIn.set(true);
this._username.set(user.username || 'User');
this._email.set(user.email || '');
} else {
this.http
.get<{ authenticated: boolean; username?: string; email?: string }>('/api/user')
.subscribe({
next: (user) => {
if (user.authenticated) {
this._isLoggedIn.set(true);
this._username.set(user.username || 'User');
this._email.set(user.email || '');
} else {
this._isLoggedIn.set(false);
this._username.set('');
this._email.set('');
}
},
error: (err) => {
console.error('Error fetching user authentication status', err);
this._isLoggedIn.set(false);
this._username.set('');
this._email.set('');
}
},
error: (err) => {
console.error('Error fetching user authentication status', err);
this._isLoggedIn.set(false);
this._username.set('');
this._email.set('');
}
});
},
});
}
get isLoggedIn(): boolean {
@@ -89,7 +107,7 @@ export class App implements OnInit {
error: (err) => {
console.error(err);
this.helloMessage.set('Failed to connect to backend: ' + err.statusText);
}
},
});
}
@@ -97,7 +115,7 @@ export class App implements OnInit {
loadApartments() {
this.apartmentService.getApartments().subscribe({
next: (data) => this.apartments.set(data),
error: (err) => console.error('Error loading apartments', err)
error: (err) => console.error('Error loading apartments', err),
});
}
@@ -136,7 +154,7 @@ export class App implements OnInit {
name: this.formName.trim(),
address: this.formAddress.trim(),
purchasePrice: this.formPurchasePrice,
description: this.formDescription.trim()
description: this.formDescription.trim(),
};
const editMode = this.editingApartment();
@@ -149,7 +167,7 @@ export class App implements OnInit {
error: (err) => {
console.error(err);
this.formError = 'Erreur lors de la modification.';
}
},
});
} else {
this.apartmentService.createApartment(apartmentData).subscribe({
@@ -160,7 +178,7 @@ export class App implements OnInit {
error: (err) => {
console.error(err);
this.formError = 'Erreur lors de la création.';
}
},
});
}
}
@@ -169,7 +187,7 @@ export class App implements OnInit {
if (confirm('Êtes-vous sûr de vouloir supprimer cet appartement ?')) {
this.apartmentService.deleteApartment(id).subscribe({
next: () => this.loadApartments(),
error: (err) => console.error('Error deleting apartment', err)
error: (err) => console.error('Error deleting apartment', err),
});
}
}