diff --git a/src/app/(dashboard)/parametres/page.tsx b/src/app/(dashboard)/parametres/page.tsx index 2798756..9393038 100644 --- a/src/app/(dashboard)/parametres/page.tsx +++ b/src/app/(dashboard)/parametres/page.tsx @@ -4,36 +4,42 @@ import { useSession } from 'next-auth/react' import { Header } from '@/components/layout/Header' import { UsersManager } from '@/components/settings/UsersManager' import { ConnectionStatus } from '@/components/settings/ConnectionStatus' +import { TemplateLibrary } from '@/components/mockup/TemplateLibrary' -type Tab = 'connexions' | 'utilisateurs' +type Tab = 'connexions' | 'utilisateurs' | 'mockup-templates' export default function ParametresPage() { const { data: session } = useSession() const isAdmin = session?.user?.role === 'admin' const [tab, setTab] = useState('connexions') + const tabs: { id: Tab; label: string; adminOnly?: boolean }[] = [ + { id: 'connexions', label: 'Connexions' }, + { id: 'mockup-templates', label: 'Templates mockup' }, + { id: 'utilisateurs', label: 'Utilisateurs', adminOnly: true }, + ] + return ( <>
- {isAdmin && ( -
- {(['connexions', 'utilisateurs'] as Tab[]).map((t) => ( - - ))} -
- )} - {(!isAdmin || tab === 'connexions') && } +
+ {tabs.filter(t => !t.adminOnly || isAdmin).map(t => ( + + ))} +
+ {tab === 'connexions' && } + {tab === 'mockup-templates' && } {isAdmin && tab === 'utilisateurs' && }
diff --git a/src/components/mockup/TemplateLibrary.tsx b/src/components/mockup/TemplateLibrary.tsx index 52f1f25..d344d2c 100644 --- a/src/components/mockup/TemplateLibrary.tsx +++ b/src/components/mockup/TemplateLibrary.tsx @@ -2,24 +2,31 @@ import { useState, useEffect, useRef } from 'react' import type { MockupTemplate } from '@/types/mockup' -const FAMILIES = ['Menuiserie', 'Baies vitrées', 'Carrelage', 'Tous'] - export function TemplateLibrary() { const [templates, setTemplates] = useState([]) + const [families, setFamilies] = useState(['Tous']) const [loading, setLoading] = useState(true) const [uploading, setUploading] = useState(false) const [error, setError] = useState(null) const [name, setName] = useState('') - const [family, setFamily] = useState('Menuiserie') + const [family, setFamily] = useState('Tous') const [description, setDescription] = useState('') const fileRef = useRef(null) const load = () => { setLoading(true) - fetch('/api/mockup/templates') - .then(r => r.json()) - .then(setTemplates) - .finally(() => setLoading(false)) + Promise.all([ + fetch('/api/mockup/templates').then(r => r.json()), + fetch('/api/sheets/tabs').then(r => r.json()), + ]).then(([tplData, tabsData]) => { + setTemplates(tplData as MockupTemplate[]) + const tabs: string[] = (tabsData.tabs ?? []).filter((t: string) => + !['COLLECTIONS', 'LIVRAISONS', 'ECOPART', 'RECAP'].some(x => t.toUpperCase().includes(x)) + ) + const allFamilies = ['Tous', ...tabs] + setFamilies(allFamilies) + if (!allFamilies.includes(family)) setFamily(allFamilies[0]) + }).finally(() => setLoading(false)) } useEffect(load, []) @@ -53,91 +60,84 @@ export function TemplateLibrary() { load() } - const byFamily = FAMILIES.reduce>((acc, f) => { - acc[f] = templates.filter(t => t.family === f) - return acc - }, {}) + const allUsedFamilies = Array.from(new Set(templates.map(t => t.family))) + const displayFamilies = families.filter(f => allUsedFamilies.includes(f) || f === 'Tous') return (
+ {/* Upload form */}

Ajouter un template

- setName(e.target.value)} + setName(e.target.value)} placeholder="ex: Entrée moderne" - className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:ring-1 focus:ring-indigo-500" - /> + className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:ring-1 focus:ring-indigo-500" />
- setFamily(e.target.value)} + className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:ring-1 focus:ring-indigo-500"> + {families.map(f => )}
- setDescription(e.target.value)} + setDescription(e.target.value)} placeholder="ex: Pièce lumineuse avec parquet" - className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:ring-1 focus:ring-indigo-500" - /> + className="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:ring-1 focus:ring-indigo-500" />
{error &&

{error}

} -
+ {/* Templates grouped by family */} {loading ? (

Chargement…

+ ) : templates.length === 0 ? ( +

Aucun template. Ajoutez-en un ci-dessus.

) : ( - FAMILIES.map(f => byFamily[f]?.length > 0 ? ( -
-

{f}

-
- {byFamily[f].map(t => ( -
- {t.name} -
-

{t.name}

- {t.description &&

{t.description}

} -
- +
+ {displayFamilies.map(f => { + const byFamily = templates.filter(t => t.family === f) + if (byFamily.length === 0) return null + return ( +
+

+ {f} + {byFamily.length} template{byFamily.length > 1 ? 's' : ''} +

+
+ {byFamily.map(t => ( +
+ {t.name} +
+

{t.name}

+ {t.description &&

{t.description}

} +
+ +
+ ))}
- ))} -
-
- ) : null) +
+ ) + })} +
)}
)