Ajout du système d'administration avec token unique et QR code

- Implémentation complète du système d'administration (/admin)
- Gestion des clients avec base de données JSON
- Génération de token unique et QR code pour chaque client
- Intégration des données client dans l'application (bungalow, WiFi, message)
- Amélioration du composant WifiCard avec fallback de copie
- Optimisation du hook useClientData pour chargement immédiat
- Ajout de la variable d'environnement ADMIN_PASSWORD
This commit is contained in:
2025-11-23 08:55:50 +01:00
parent 444a2729ee
commit f633dbb1c0
19 changed files with 1076 additions and 22 deletions

101
lib/admin/client-utils.ts Normal file
View File

@ -0,0 +1,101 @@
import { randomBytes } from "crypto";
import { Client, ClientInput } from "@/lib/types/client";
import { readFileSync, writeFileSync } from "fs";
import { join } from "path";
const CLIENTS_FILE = join(process.cwd(), "lib/data/clients.json");
export function generateToken(): string {
return randomBytes(32).toString("hex");
}
export function validateEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
export function loadClients(): Client[] {
try {
const data = readFileSync(CLIENTS_FILE, "utf-8");
return JSON.parse(data);
} catch (error) {
return [];
}
}
export function saveClients(clients: Client[]): void {
try {
writeFileSync(CLIENTS_FILE, JSON.stringify(clients, null, 2), "utf-8");
} catch (error) {
console.error("Erreur lors de la sauvegarde des clients:", error);
throw error;
}
}
export function createClient(input: ClientInput): Client {
const clients = loadClients();
// Vérifier si l'email existe déjà
if (clients.some((c) => c.email === input.email)) {
throw new Error("Un client avec cet email existe déjà");
}
const now = new Date().toISOString();
const client: Client = {
id: `client-${Date.now()}`,
email: input.email,
token: generateToken(),
bungalowNumber: input.bungalowNumber,
wifiName: input.wifiName,
wifiPassword: input.wifiPassword,
gerantMessage: input.gerantMessage,
createdAt: now,
updatedAt: now,
};
clients.push(client);
saveClients(clients);
return client;
}
export function getClientByToken(token: string): Client | null {
const clients = loadClients();
return clients.find((c) => c.token === token) || null;
}
export function getClientByEmail(email: string): Client | null {
const clients = loadClients();
return clients.find((c) => c.email === email) || null;
}
export function updateClient(id: string, input: Partial<ClientInput>): Client | null {
const clients = loadClients();
const index = clients.findIndex((c) => c.id === id);
if (index === -1) {
return null;
}
clients[index] = {
...clients[index],
...input,
updatedAt: new Date().toISOString(),
};
saveClients(clients);
return clients[index];
}
export function deleteClient(id: string): boolean {
const clients = loadClients();
const filtered = clients.filter((c) => c.id !== id);
if (filtered.length === clients.length) {
return false;
}
saveClients(filtered);
return true;
}