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 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 => {

View File

@@ -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) {

View File

@@ -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<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
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<BackupInfo[]> {
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<void> {
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<void> {
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()
};
}
}