Fix product stock, booking actions, settings, reservation UX, nav and category filter

This commit is contained in:
belviskhoremk
2026-05-20 23:56:43 +00:00
parent a89793a059
commit affff1c502
12 changed files with 137 additions and 102 deletions

View File

@@ -13,6 +13,8 @@ interface LanguageContextType {
const translations: Record<string, Record<Language, string>> = {
// ── Public nav ────────────────────────────────────────────────────────────────
"nav.home": { fr: "Accueil", de: "Startseite", en: "Home" },
"auth.confirm_email": { fr: "Vérifiez votre email pour confirmer votre compte", de: "Überprüfen Sie Ihre E-Mail, um Ihr Konto zu bestätigen", en: "Check your email to confirm your account" },
"nav.shop": { fr: "Boutique", de: "Shop", en: "Shop" },
"nav.booking": { fr: "Réservation", de: "Terminbuchung", en: "Book Appointment" },
"nav.about": { fr: "À propos", de: "Über uns", en: "About" },
@@ -94,6 +96,7 @@ const translations: Record<string, Record<Language, string>> = {
"booking.confirmed_desc": { fr: "Vous recevrez une confirmation par email. Nous vous contacterons pour finaliser le paiement.", de: "Sie erhalten eine Bestätigungs-E-Mail. Wir werden Sie kontaktieren, um die Zahlung abzuschließen.", en: "You will receive a confirmation email. We will contact you to finalize the payment." },
"booking.no_services": { fr: "Aucun service disponible pour le moment.", de: "Derzeit keine Dienstleistungen verfügbar.", en: "No services available at the moment." },
"booking.no_slots": { fr: "Aucun créneau disponible ce jour. Choisissez une autre date.", de: "Keine Zeitfenster an diesem Tag. Wählen Sie ein anderes Datum.", en: "No slots available this day. Choose another date." },
"booking.new_booking": { fr: "Faire une nouvelle réservation", de: "Neue Buchung", en: "Make another booking" },
"booking.submitting": { fr: "Envoi en cours…", de: "Wird gesendet…", en: "Submitting…" },
"booking.success": { fr: "Réservation confirmée !", de: "Buchung bestätigt!", en: "Booking confirmed!" },
"booking.error": { fr: "Erreur lors de la réservation", de: "Buchungsfehler", en: "Booking error" },
@@ -298,6 +301,7 @@ const translations: Record<string, Record<Language, string>> = {
"admin.products.col_name": { fr: "Nom", de: "Name", en: "Name" },
"admin.products.col_category": { fr: "Catégorie", de: "Kategorie", en: "Category" },
"admin.products.col_price": { fr: "Prix", de: "Preis", en: "Price" },
"admin.products.col_stock": { fr: "Stock", de: "Bestand", en: "Stock" },
"admin.products.col_status": { fr: "Statut", de: "Status", en: "Status" },
"admin.products.badge_new": { fr: "Nouveau", de: "Neu", en: "New" },
"admin.products.create_title": { fr: "Nouveau produit", de: "Neues Produkt", en: "New product" },
@@ -307,6 +311,7 @@ const translations: Record<string, Record<Language, string>> = {
"admin.products.category": { fr: "Catégorie", de: "Kategorie", en: "Category" },
"admin.products.price": { fr: "Prix (€)", de: "Preis (€)", en: "Price (€)" },
"admin.products.original_price": { fr: "Prix barré (€)", de: "Durchgestrichener Preis (€)", en: "Original price (€)" },
"admin.products.stock_quantity": { fr: "Quantité en stock", de: "Lagerbestand", en: "Stock quantity" },
"admin.products.optional": { fr: "Optionnel", de: "Optional", en: "Optional" },
"admin.products.image": { fr: "Image", de: "Bild", en: "Image" },
"admin.products.description": { fr: "Description", de: "Beschreibung", en: "Description" },
@@ -367,7 +372,9 @@ const translations: Record<string, Record<Language, string>> = {
"admin.settings.no_settings": { fr: "Aucun paramètre configuré. Les valeurs par défaut sont utilisées.", de: "Keine Einstellungen konfiguriert. Standardwerte werden verwendet.", en: "No settings configured. Default values are used." },
"admin.settings.other": { fr: "Autres paramètres", de: "Weitere Einstellungen", en: "Other settings" },
"admin.settings.last_updated": { fr: "Dernière modification :", de: "Zuletzt geändert:", en: "Last updated:" },
"admin.settings.saved": { fr: "Paramètre enregistré", de: "Einstellung gespeichert", en: "Setting saved" },
"admin.settings.saved": { fr: "Paramètre enregistré", de: "Einstellung gespeichert", en: "Setting saved" },
"admin.settings.booking_price_label": { fr: "Prix de réservation par défaut (€)", de: "Standardpreis für Reservierungen (€)", en: "Default booking price (€)" },
"admin.settings.booking_price_desc": { fr: "Prix appliqué à chaque rendez-vous (0 = gratuit)", de: "Preis pro Termin (0 = kostenlos)", en: "Price applied to each appointment (0 = free)" },
};
const LOCALE_MAP: Record<Language, string> = {