fix: improve date formatting and backup path handling

- Updated `formatTimeAgo` in `AdvancedSettingsPageClient` to use a fixed format for hydration consistency.
- Refined `formatDate` in `BackupSettingsPageClient` for consistent server/client formatting.
- Refactored `BackupService` to use `getCurrentBackupPath` for all backup path references, ensuring up-to-date paths and avoiding caching issues.
- Added `getCurrentBackupPath` method to dynamically retrieve the current backup path based on environment variables.
This commit is contained in:
Julien Froidefond
2025-09-20 16:12:01 +02:00
parent ee442de773
commit 9a33d1ee48
3 changed files with 56 additions and 31 deletions

View File

@@ -79,19 +79,16 @@ export function AdvancedSettingsPageClient({
}; };
const formatTimeAgo = (date: Date): string => { const formatTimeAgo = (date: Date): string => {
const now = new Date(); // Format fixe pour éviter les erreurs d'hydratation
const diffMs = now.getTime() - new Date(date).getTime(); const d = new Date(date);
const diffMins = Math.floor(diffMs / (1000 * 60)); return d.toLocaleDateString('fr-FR', {
const diffHours = Math.floor(diffMins / 60); day: '2-digit',
const diffDays = Math.floor(diffHours / 24); month: '2-digit',
year: 'numeric',
if (diffMins < 60) { hour: '2-digit',
return `il y a ${diffMins}min`; minute: '2-digit',
} else if (diffHours < 24) { hour12: false
return `il y a ${diffHours}h ${diffMins % 60}min`; });
} else {
return `il y a ${diffDays}j`;
}
}; };
const getNextBackupTime = (): string => { const getNextBackupTime = (): string => {

View File

@@ -158,7 +158,17 @@ export default function BackupSettingsPageClient({ initialData }: BackupSettings
}; };
const formatDate = (date: string | Date): string => { 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) { if (isLoading) {

View File

@@ -27,14 +27,16 @@ export interface BackupInfo {
} }
export class BackupService { export class BackupService {
private defaultConfig: BackupConfig = { private get defaultConfig(): BackupConfig {
enabled: true, return {
interval: 'hourly', enabled: true,
maxBackups: 5, interval: 'hourly',
backupPath: this.getDefaultBackupPath(), maxBackups: 5,
includeUploads: true, backupPath: this.getDefaultBackupPath(),
compression: true, includeUploads: true,
}; compression: true,
};
}
private getDefaultBackupPath(): string { private getDefaultBackupPath(): string {
// 1. Variable d'environnement explicite // 1. Variable d'environnement explicite
@@ -110,7 +112,7 @@ export class BackupService {
const backupId = `backup_${Date.now()}`; const backupId = `backup_${Date.now()}`;
const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const filename = `towercontrol_${timestamp}.db`; 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}`); console.log(`🔄 Starting ${type} backup: ${filename}`);
@@ -226,7 +228,7 @@ export class BackupService {
* Restaure une sauvegarde * Restaure une sauvegarde
*/ */
async restoreBackup(filename: string): Promise<void> { async restoreBackup(filename: string): Promise<void> {
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 // Résoudre le chemin de la base de données
let dbPath: string; 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 * Liste toutes les sauvegardes disponibles
*/ */
async listBackups(): Promise<BackupInfo[]> { async listBackups(): Promise<BackupInfo[]> {
try { try {
const currentBackupPath = this.getCurrentBackupPath();
await this.ensureBackupDirectory(); await this.ensureBackupDirectory();
const files = await fs.readdir(this.config.backupPath); const files = await fs.readdir(currentBackupPath);
const backups: BackupInfo[] = []; const backups: BackupInfo[] = [];
for (const file of files) { for (const file of files) {
if (file.startsWith('towercontrol_') && (file.endsWith('.db') || file.endsWith('.db.gz'))) { 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); const stats = await fs.stat(filePath);
// Extraire la date du nom de fichier // Extraire la date du nom de fichier
@@ -353,7 +366,7 @@ export class BackupService {
* Supprime une sauvegarde * Supprime une sauvegarde
*/ */
async deleteBackup(filename: string): Promise<void> { async deleteBackup(filename: string): Promise<void> {
const backupPath = path.join(this.config.backupPath, filename); const backupPath = path.join(this.getCurrentBackupPath(), filename);
try { try {
await fs.unlink(backupPath); await fs.unlink(backupPath);
@@ -411,11 +424,12 @@ export class BackupService {
* S'assure que le dossier de backup existe * S'assure que le dossier de backup existe
*/ */
private async ensureBackupDirectory(): Promise<void> { private async ensureBackupDirectory(): Promise<void> {
const currentBackupPath = this.getCurrentBackupPath();
try { try {
await fs.access(this.config.backupPath); await fs.access(currentBackupPath);
} catch { } catch {
await fs.mkdir(this.config.backupPath, { recursive: true }); await fs.mkdir(currentBackupPath, { recursive: true });
console.log(`📁 Created backup directory: ${this.config.backupPath}`); console.log(`📁 Created backup directory: ${currentBackupPath}`);
} }
} }
@@ -447,7 +461,11 @@ export class BackupService {
* Obtient la configuration actuelle * Obtient la configuration actuelle
*/ */
getConfig(): BackupConfig { getConfig(): BackupConfig {
return { ...this.config }; // Retourner une config avec le chemin à jour
return {
...this.config,
backupPath: this.getCurrentBackupPath()
};
} }
} }