Checkpoint: Ajout d'une page de paramètres pour gérer l'URL des QR codes
Modifications apportées : - Création de la table parametres dans la base de données - Création du fichier server/parametresDb.ts avec les fonctions getParametres et updateUrlPublique - Ajout du router parametres dans server/routers.ts avec les procédures get et updateUrlPublique - Création de la page client/src/pages/AdminParametres.tsx avec formulaire de modification - Ajout de la route /admin/parametres dans App.tsx - Ajout du lien "Paramètres" dans le menu après "Configuration SMTP" dans DashboardLayout - Modification de server/qrCodeGenerator.ts pour utiliser l'URL de la BDD au lieu de getAppBaseUrl - URL par défaut définie : https://formations.itinova.org Fonctionnalités : - Interface graphique pour modifier l'URL publique de l'application - Les QR codes d'émargement utilisent maintenant l'URL configurée dans la base de données - Validation de l'URL avant enregistrement - Message d'information sur l'impact des modifications
This commit is contained in:
42
server/parametresDb.ts
Normal file
42
server/parametresDb.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { getDb } from "./db";
|
||||
import { parametres } from "../drizzle/schema";
|
||||
|
||||
/**
|
||||
* Récupérer les paramètres de l'application
|
||||
* S'il n'y a pas de paramètres, en créer un avec les valeurs par défaut
|
||||
*/
|
||||
export async function getParametres() {
|
||||
const db = await getDb();
|
||||
if (!db) throw new Error("Database not available");
|
||||
|
||||
const result = await db.select().from(parametres).limit(1);
|
||||
|
||||
if (result.length === 0) {
|
||||
// Créer les paramètres par défaut
|
||||
await db.insert(parametres).values({
|
||||
urlPublique: "https://formations.itinova.org",
|
||||
});
|
||||
|
||||
const newResult = await db.select().from(parametres).limit(1);
|
||||
return newResult[0];
|
||||
}
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Mettre à jour l'URL publique
|
||||
*/
|
||||
export async function updateUrlPublique(urlPublique: string) {
|
||||
const db = await getDb();
|
||||
if (!db) throw new Error("Database not available");
|
||||
|
||||
const params = await getParametres();
|
||||
|
||||
await db.update(parametres)
|
||||
.set({ urlPublique })
|
||||
.where(eq(parametres.id, params.id));
|
||||
|
||||
return getParametres();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import QRCode from "qrcode";
|
||||
import { randomBytes } from "crypto";
|
||||
import { getAppBaseUrl } from "./_core/appUrl";
|
||||
import { getParametres } from "./parametresDb";
|
||||
|
||||
/**
|
||||
* Générer un token unique pour le QR code
|
||||
@@ -16,8 +16,8 @@ export function generateQRToken(): string {
|
||||
*/
|
||||
export async function generateQRCodeDataURL(token: string): Promise<string> {
|
||||
// URL complète pour scanner le QR code
|
||||
const baseUrl = getAppBaseUrl();
|
||||
const url = `${baseUrl}/emargement/${token}`;
|
||||
const parametres = await getParametres();
|
||||
const url = `${parametres.urlPublique}/emargement/${token}`;
|
||||
|
||||
try {
|
||||
const qrCodeDataURL = await QRCode.toDataURL(url, {
|
||||
@@ -44,8 +44,8 @@ export async function generateQRCodeDataURL(token: string): Promise<string> {
|
||||
* @returns Un buffer PNG du QR code
|
||||
*/
|
||||
export async function generateQRCodeBuffer(token: string): Promise<Buffer> {
|
||||
const baseUrl = getAppBaseUrl();
|
||||
const url = `${baseUrl}/emargement/${token}`;
|
||||
const parametres = await getParametres();
|
||||
const url = `${parametres.urlPublique}/emargement/${token}`;
|
||||
|
||||
try {
|
||||
const buffer = await QRCode.toBuffer(url, {
|
||||
|
||||
@@ -1465,6 +1465,24 @@ export const appRouter = router({
|
||||
}),
|
||||
}),
|
||||
|
||||
// ===== PARAMÈTRES DE L'APPLICATION =====
|
||||
parametres: router({
|
||||
get: adminProcedure.query(async () => {
|
||||
const { getParametres } = await import("./parametresDb");
|
||||
return getParametres();
|
||||
}),
|
||||
|
||||
updateUrlPublique: adminProcedure
|
||||
.input(z.object({
|
||||
urlPublique: z.string().url(),
|
||||
}))
|
||||
.mutation(async ({ input }) => {
|
||||
const { updateUrlPublique } = await import("./parametresDb");
|
||||
await updateUrlPublique(input.urlPublique);
|
||||
return { success: true };
|
||||
}),
|
||||
}),
|
||||
|
||||
// ===== ANALYTICS =====
|
||||
analytics: router({
|
||||
globalStats: adminProcedure.query(async () => {
|
||||
|
||||
Reference in New Issue
Block a user