diff --git a/components/settings/AdvancedSettingsPageClient.tsx b/components/settings/AdvancedSettingsPageClient.tsx index 8442f97..e034fdf 100644 --- a/components/settings/AdvancedSettingsPageClient.tsx +++ b/components/settings/AdvancedSettingsPageClient.tsx @@ -79,19 +79,16 @@ export function AdvancedSettingsPageClient({ }; const formatTimeAgo = (date: Date): string => { - const now = new Date(); - const diffMs = now.getTime() - new Date(date).getTime(); - const diffMins = Math.floor(diffMs / (1000 * 60)); - const diffHours = Math.floor(diffMins / 60); - const diffDays = Math.floor(diffHours / 24); - - if (diffMins < 60) { - return `il y a ${diffMins}min`; - } else if (diffHours < 24) { - return `il y a ${diffHours}h ${diffMins % 60}min`; - } else { - return `il y a ${diffDays}j`; - } + // Format fixe pour éviter les erreurs d'hydratation + const d = new Date(date); + return d.toLocaleDateString('fr-FR', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit', + hour12: false + }); }; const getNextBackupTime = (): string => { diff --git a/components/settings/BackupSettingsPageClient.tsx b/components/settings/BackupSettingsPageClient.tsx index 7a7aac0..8b083eb 100644 --- a/components/settings/BackupSettingsPageClient.tsx +++ b/components/settings/BackupSettingsPageClient.tsx @@ -158,7 +158,17 @@ export default function BackupSettingsPageClient({ initialData }: BackupSettings }; const formatDate = (date: string | Date): string => { - return new Date(date).toLocaleString(); + // Format cohérent serveur/client pour éviter les erreurs d'hydratation + const d = new Date(date); + return d.toLocaleDateString('fr-FR', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: false + }); }; if (isLoading) { diff --git a/services/backup.ts b/services/backup.ts index 795545f..c51b05e 100644 --- a/services/backup.ts +++ b/services/backup.ts @@ -27,14 +27,16 @@ export interface BackupInfo { } export class BackupService { - private defaultConfig: BackupConfig = { - enabled: true, - interval: 'hourly', - maxBackups: 5, - backupPath: this.getDefaultBackupPath(), - includeUploads: true, - compression: true, - }; + private get defaultConfig(): BackupConfig { + return { + enabled: true, + interval: 'hourly', + maxBackups: 5, + backupPath: this.getDefaultBackupPath(), + includeUploads: true, + compression: true, + }; + } private getDefaultBackupPath(): string { // 1. Variable d'environnement explicite @@ -110,7 +112,7 @@ export class BackupService { const backupId = `backup_${Date.now()}`; const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const filename = `towercontrol_${timestamp}.db`; - const backupPath = path.join(this.config.backupPath, filename); + const backupPath = path.join(this.getCurrentBackupPath(), filename); console.log(`🔄 Starting ${type} backup: ${filename}`); @@ -226,7 +228,7 @@ export class BackupService { * Restaure une sauvegarde */ async restoreBackup(filename: string): Promise { - const backupPath = path.join(this.config.backupPath, filename); + const backupPath = path.join(this.getCurrentBackupPath(), filename); // Résoudre le chemin de la base de données let dbPath: string; @@ -304,19 +306,30 @@ export class BackupService { } } + /** + * Obtient le chemin de sauvegarde actuel (toujours à jour) + * Force la relecture des variables d'environnement à chaque appel + */ + private getCurrentBackupPath(): string { + // Toujours recalculer depuis les variables d'environnement + // pour éviter les problèmes de cache lors des refresh + return this.getDefaultBackupPath(); + } + /** * Liste toutes les sauvegardes disponibles */ async listBackups(): Promise { try { + const currentBackupPath = this.getCurrentBackupPath(); await this.ensureBackupDirectory(); - const files = await fs.readdir(this.config.backupPath); + const files = await fs.readdir(currentBackupPath); const backups: BackupInfo[] = []; for (const file of files) { if (file.startsWith('towercontrol_') && (file.endsWith('.db') || file.endsWith('.db.gz'))) { - const filePath = path.join(this.config.backupPath, file); + const filePath = path.join(currentBackupPath, file); const stats = await fs.stat(filePath); // Extraire la date du nom de fichier @@ -353,7 +366,7 @@ export class BackupService { * Supprime une sauvegarde */ async deleteBackup(filename: string): Promise { - const backupPath = path.join(this.config.backupPath, filename); + const backupPath = path.join(this.getCurrentBackupPath(), filename); try { await fs.unlink(backupPath); @@ -411,11 +424,12 @@ export class BackupService { * S'assure que le dossier de backup existe */ private async ensureBackupDirectory(): Promise { + const currentBackupPath = this.getCurrentBackupPath(); try { - await fs.access(this.config.backupPath); + await fs.access(currentBackupPath); } catch { - await fs.mkdir(this.config.backupPath, { recursive: true }); - console.log(`📁 Created backup directory: ${this.config.backupPath}`); + await fs.mkdir(currentBackupPath, { recursive: true }); + console.log(`📁 Created backup directory: ${currentBackupPath}`); } } @@ -447,7 +461,11 @@ export class BackupService { * Obtient la configuration actuelle */ getConfig(): BackupConfig { - return { ...this.config }; + // Retourner une config avec le chemin à jour + return { + ...this.config, + backupPath: this.getCurrentBackupPath() + }; } }