diff --git a/hifi-src/src/pages/admin/AdminUsers.jsx b/hifi-src/src/pages/admin/AdminUsers.jsx index 0396214..bd6bbe1 100644 --- a/hifi-src/src/pages/admin/AdminUsers.jsx +++ b/hifi-src/src/pages/admin/AdminUsers.jsx @@ -22,6 +22,7 @@ export default function AdminUsers() { const [groups, setGroups] = useState([]); const [form, setForm] = useState(emptyForm); const [editingId, setEditingId] = useState(null); + const [editingIsPrimary, setEditingIsPrimary] = useState(false); const [error, setError] = useState(''); const load = () => { @@ -36,6 +37,7 @@ export default function AdminUsers() { const startEdit = (u) => { setEditingId(u.id); + setEditingIsPrimary(u.is_primary); setForm({ username: u.username, password: '', @@ -47,6 +49,7 @@ export default function AdminUsers() { const resetForm = () => { setEditingId(null); + setEditingIsPrimary(false); setForm(emptyForm); }; @@ -118,6 +121,7 @@ export default function AdminUsers() {
+ Der Erst-Administrator behält immer den Super-Admin-Status. +
+ )} +o(j.target.value),required:!0,autoFocus:!0,className:v})]}),n&&a.jsx("p",{className:"mb-4 text-sm text-red-600",children:n}),a.jsx("button",{type:"submit",disabled:s,className:"w-full rounded-md bg-brand-500 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-600 disabled:opacity-60",children:s?"Prüfe…":"Weiter"})]}),e==="database"&&a.jsxs("form",{onSubmit:w,children:[a.jsx("h1",{className:"mb-2 text-xl font-bold text-neutral-900 dark:text-white",children:"Datenbank-Zugangsdaten"}),a.jsx("p",{className:"mb-6 text-sm text-neutral-500 dark:text-neutral-400",children:"Trage die Zugangsdaten der Datenbank auf diesem Server ein. Die Verbindung wird vor dem Speichern getestet."}),a.jsxs("div",{className:"mb-3",children:[a.jsx("label",{className:k,children:"Host *"}),a.jsx("input",{required:!0,value:u.host,onChange:j=>c({...u,host:j.target.value}),className:v})]}),a.jsxs("div",{className:"mb-3",children:[a.jsx("label",{className:k,children:"Datenbankname *"}),a.jsx("input",{required:!0,value:u.name,onChange:j=>c({...u,name:j.target.value}),className:v})]}),a.jsxs("div",{className:"mb-3",children:[a.jsx("label",{className:k,children:"Benutzer *"}),a.jsx("input",{required:!0,value:u.user,onChange:j=>c({...u,user:j.target.value}),className:v})]}),a.jsxs("div",{className:"mb-3",children:[a.jsx("label",{className:k,children:"Passwort"}),a.jsx("input",{type:"password",value:u.password,onChange:j=>c({...u,password:j.target.value}),className:v})]}),a.jsxs("div",{className:"mb-6",children:[a.jsx("label",{className:k,children:"Zeichensatz"}),a.jsx("input",{value:u.charset,onChange:j=>c({...u,charset:j.target.value}),className:v})]}),n&&a.jsx("p",{className:"mb-4 text-sm text-red-600",children:n}),a.jsx("button",{type:"submit",disabled:s,className:"w-full rounded-md bg-brand-500 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-600 disabled:opacity-60",children:s?"Teste Verbindung…":"Verbindung testen & speichern"})]}),e==="schema"&&a.jsxs("div",{children:[a.jsx("h1",{className:"mb-2 text-xl font-bold text-neutral-900 dark:text-white",children:"Datenbankstruktur"}),a.jsx("p",{className:"mb-6 text-sm text-neutral-500 dark:text-neutral-400",children:"Die Datenbankverbindung funktioniert. Jetzt legen wir die benötigten Tabellen an."}),m&&a.jsx("ul",{className:"mb-4 space-y-1 rounded-md bg-neutral-50 p-3 text-sm text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300",children:m.map((j,S)=>a.jsx("li",{children:j},S))}),n&&a.jsx("p",{className:"mb-4 text-sm text-red-600",children:n}),a.jsx("button",{type:"button",onClick:x,disabled:s,className:"w-full rounded-md bg-brand-500 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-600 disabled:opacity-60",children:s?"Richte ein…":"Datenbankstruktur einrichten"})]}),e==="admin"&&a.jsxs("form",{onSubmit:p,children:[a.jsx("h1",{className:"mb-2 text-xl font-bold text-neutral-900 dark:text-white",children:"Erster Admin-Account"}),a.jsx("p",{className:"mb-6 text-sm text-neutral-500 dark:text-neutral-400",children:"Lege den ersten Super-Admin-Account an, mit dem du dich anschließend einloggen kannst."}),a.jsxs("div",{className:"mb-3",children:[a.jsx("label",{className:k,children:"Benutzername"}),a.jsx("input",{required:!0,autoFocus:!0,value:d.username,onChange:j=>h({...d,username:j.target.value}),className:v})]}),a.jsxs("div",{className:"mb-3",children:[a.jsx("label",{className:k,children:"Passwort"}),a.jsx("input",{type:"password",required:!0,minLength:8,value:d.password,onChange:j=>h({...d,password:j.target.value}),className:v})]}),a.jsxs("div",{className:"mb-6",children:[a.jsx("label",{className:k,children:"Passwort wiederholen"}),a.jsx("input",{type:"password",required:!0,minLength:8,value:d.password_confirmation,onChange:j=>h({...d,password_confirmation:j.target.value}),className:v})]}),n&&a.jsx("p",{className:"mb-4 text-sm text-red-600",children:n}),a.jsx("button",{type:"submit",disabled:s,className:"w-full rounded-md bg-brand-500 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-600 disabled:opacity-60",children:s?"Lege an…":"Admin-Account anlegen"})]}),e==="done"&&a.jsxs("div",{className:"text-center",children:[a.jsx("h1",{className:"mb-2 text-xl font-bold text-neutral-900 dark:text-white",children:"Fertig!"}),a.jsx("p",{className:"mb-6 text-sm text-neutral-500 dark:text-neutral-400",children:"Die Ersteinrichtung ist abgeschlossen. Du kannst dich jetzt mit deinem neuen Admin-Account anmelden."}),a.jsx(H,{to:"/admin/login",className:"inline-block w-full rounded-md bg-brand-500 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-600",children:"Zum Login"})]})]})]})}function fP(){const{user:e,login:t,verifyTwoFactor:n}=Bt(),r=ra(),[s,i]=g.useState("credentials"),[l,o]=g.useState(""),[u,c]=g.useState(""),[d,h]=g.useState(""),[m,f]=g.useState(""),[b,y]=g.useState(!1);if(e)return a.jsx(Gs,{to:"/admin",replace:!0});const w=async p=>{p.preventDefault(),y(!0),f("");try{(await t(l,u)).requires2fa?i("code"):r("/admin")}catch(v){f(v.message)}finally{y(!1)}},x=async p=>{p.preventDefault(),y(!0),f("");try{await n(d),r("/admin")}catch(v){f(v.message)}finally{y(!1)}};return a.jsxs("div",{className:"flex min-h-screen flex-col items-center justify-center gap-6 bg-neutral-50 px-4 dark:bg-neutral-950",children:[a.jsx("img",{src:Ks,alt:"HifiPlanet",className:"h-16 w-auto dark:hidden sm:h-20"}),a.jsx("img",{src:Li,alt:"HifiPlanet",className:"hidden h-16 w-auto dark:block sm:h-20"}),s==="credentials"?a.jsxs("form",{onSubmit:w,className:"w-full max-w-sm rounded-xl border border-neutral-200 bg-white p-8 shadow-sm dark:border-neutral-800 dark:bg-neutral-900",children:[a.jsx("h1",{className:"mb-6 text-xl font-bold text-neutral-900 dark:text-white",children:"Admin-Login"}),a.jsxs("div",{className:"mb-4",children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Benutzername"}),a.jsx("input",{value:l,onChange:p=>o(p.target.value),required:!0,autoFocus:!0,className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm focus:border-brand-500 focus:outline-none dark:border-neutral-700 dark:bg-neutral-900"})]}),a.jsxs("div",{className:"mb-6",children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Passwort"}),a.jsx("input",{type:"password",value:u,onChange:p=>c(p.target.value),required:!0,className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm focus:border-brand-500 focus:outline-none dark:border-neutral-700 dark:bg-neutral-900"})]}),m&&a.jsx("p",{className:"mb-4 text-sm text-red-600",children:m}),a.jsx("button",{type:"submit",disabled:b,className:"w-full rounded-md bg-brand-500 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-600 disabled:opacity-60",children:b?"Anmelden…":"Anmelden"})]}):a.jsxs("form",{onSubmit:x,className:"w-full max-w-sm rounded-xl border border-neutral-200 bg-white p-8 shadow-sm dark:border-neutral-800 dark:bg-neutral-900",children:[a.jsx("h1",{className:"mb-2 text-xl font-bold text-neutral-900 dark:text-white",children:"Bestätigungscode"}),a.jsx("p",{className:"mb-6 text-sm text-neutral-500 dark:text-neutral-400",children:"Öffne die Google Authenticator App und gib den 6-stelligen Code ein. Alternativ kannst du auch einen deiner Wiederherstellungscodes verwenden."}),a.jsxs("div",{className:"mb-6",children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Code"}),a.jsx("input",{value:d,onChange:p=>h(p.target.value),required:!0,autoFocus:!0,inputMode:"numeric",placeholder:"123456",className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-center text-lg tracking-widest focus:border-brand-500 focus:outline-none dark:border-neutral-700 dark:bg-neutral-900"})]}),m&&a.jsx("p",{className:"mb-4 text-sm text-red-600",children:m}),a.jsx("button",{type:"submit",disabled:b,className:"w-full rounded-md bg-brand-500 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-600 disabled:opacity-60",children:b?"Prüfe…":"Bestätigen"}),a.jsx("button",{type:"button",onClick:()=>{i("credentials"),h(""),f("")},className:"mt-3 w-full text-sm text-neutral-500 hover:underline dark:text-neutral-400",children:"Zurück zum Login"})]})]})}const pP={tag:"M4 4h7l9 9-7 7-9-9V4Zm3.5 3.5h.01",car:"M3 13.5 4.5 9A2 2 0 0 1 6.4 7.5h11.2A2 2 0 0 1 19.5 9L21 13.5M3 13.5v4a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1v-1h12v1a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1v-4M3 13.5h18M6.5 16.5h.01M17.5 16.5h.01",box:"M12 3 4 7.5v9L12 21l8-4.5v-9L12 3Zm0 9 8-4.5M12 12v9M12 12 4 7.5",mail:"M4 6h16a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Zm0 0 8 7 8-7"},gP=({path:e,className:t="h-6 w-6"})=>a.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.75",className:t,children:a.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:e})});function xP(){const[e,t]=g.useState(null),[n,r]=g.useState("");if(g.useEffect(()=>{M.get("/analytics/report").then(t).catch(i=>r(i.message))},[]),n)return a.jsxs("section",{className:"mt-8 rounded-xl border border-neutral-200 bg-white p-6 dark:border-neutral-800 dark:bg-neutral-900",children:[a.jsx("h2",{className:"mb-1 font-semibold text-neutral-900 dark:text-white",children:"Google Analytics"}),a.jsx("p",{className:"text-sm text-red-600",children:n})]});if(!e)return null;if(!e.configured)return a.jsxs("section",{className:"mt-8 rounded-xl border border-neutral-200 bg-white p-6 dark:border-neutral-800 dark:bg-neutral-900",children:[a.jsx("h2",{className:"mb-1 font-semibold text-neutral-900 dark:text-white",children:"Google Analytics"}),a.jsxs("p",{className:"text-sm text-neutral-500 dark:text-neutral-400",children:["Noch nicht eingerichtet. Unter"," ",a.jsx(H,{to:"/admin/settings/website",className:"text-brand-600 hover:underline dark:text-brand-400",children:"Einstellungen → Website"})," ","kannst du die Dashboard-Anbindung konfigurieren, um hier Besucherzahlen zu sehen."]})]});const s=Math.max(1,...e.daily.map(i=>i.pageviews));return a.jsxs("section",{className:"mt-8 rounded-xl border border-neutral-200 bg-white p-6 dark:border-neutral-800 dark:bg-neutral-900",children:[a.jsx("h2",{className:"mb-1 font-semibold text-neutral-900 dark:text-white",children:"Google Analytics"}),a.jsx("p",{className:"mb-5 text-sm text-neutral-500 dark:text-neutral-400",children:"Letzte 7 Tage."}),a.jsxs("div",{className:"mb-6 grid grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsx("p",{className:"text-2xl font-extrabold text-brand-600 dark:text-brand-400",children:e.totals.users}),a.jsx("p",{className:"text-xs text-neutral-500 dark:text-neutral-400",children:"Nutzer"})]}),a.jsxs("div",{children:[a.jsx("p",{className:"text-2xl font-extrabold text-brand-600 dark:text-brand-400",children:e.totals.sessions}),a.jsx("p",{className:"text-xs text-neutral-500 dark:text-neutral-400",children:"Sitzungen"})]}),a.jsxs("div",{children:[a.jsx("p",{className:"text-2xl font-extrabold text-brand-600 dark:text-brand-400",children:e.totals.pageviews}),a.jsx("p",{className:"text-xs text-neutral-500 dark:text-neutral-400",children:"Seitenaufrufe"})]})]}),e.daily.length>0&&a.jsx("div",{className:"mb-6 flex h-24 items-end gap-1.5",children:e.daily.map(i=>a.jsxs("div",{className:"flex flex-1 flex-col items-center gap-1",children:[a.jsx("div",{className:"w-full rounded-t bg-brand-400 dark:bg-brand-500",style:{height:`${Math.max(4,i.pageviews/s*80)}px`},title:`${i.date}: ${i.pageviews} Seitenaufrufe`}),a.jsxs("span",{className:"text-[10px] text-neutral-400",children:[i.date.slice(6,8),".",i.date.slice(4,6),"."]})]},i.date))}),e.top_pages.length>0&&a.jsxs("div",{children:[a.jsx("p",{className:"mb-2 text-xs font-semibold uppercase tracking-wide text-neutral-400",children:"Meistbesuchte Seiten"}),a.jsx("ul",{className:"space-y-1 text-sm",children:e.top_pages.map(i=>a.jsxs("li",{className:"flex items-center justify-between gap-3 text-neutral-700 dark:text-neutral-300",children:[a.jsx("span",{className:"truncate font-mono text-xs",children:i.path}),a.jsx("span",{className:"shrink-0 font-semibold",children:i.pageviews})]},i.path))})]})]})}function bP(){const{user:e,hasPermission:t}=Bt(),[n,r]=g.useState({});g.useEffect(()=>{t("brands.manage")&&M.get("/brands").then(i=>r(l=>({...l,brands:i.length}))),(t("models.manage")||t("packages.manage"))&&M.get("/models").then(i=>r(l=>({...l,models:i.length}))),t("packages.manage")&&M.get("/packages").then(i=>r(l=>({...l,packages:i.length}))),t("contact.manage")&&M.get("/contact").then(i=>r(l=>({...l,newContacts:i.filter(o=>o.status==="new").length})))},[]);const s=[{key:"brands",label:"Marken",icon:"tag",hint:"Die Hersteller, z. B. Audi oder BMW.",value:n.brands,to:"/admin/brands",show:t("brands.manage")},{key:"models",label:"Modelle",icon:"car",hint:"Die Fahrzeuge einer Marke, z. B. A4.",value:n.models,to:"/admin/models",show:t("models.manage")},{key:"packages",label:"Pakete",icon:"box",hint:"Die Sound-Pakete für ein Modell.",value:n.packages,to:"/admin/packages",show:t("packages.manage")},{key:"contacts",label:"Neue Anfragen",icon:"mail",hint:"Kunden, die noch auf Antwort warten.",value:n.newContacts,to:"/admin/contact-requests",show:t("contact.manage"),highlight:!0}].filter(i=>i.show);return a.jsxs("div",{children:[a.jsxs("h1",{className:"mb-1 text-xl font-bold text-neutral-900 dark:text-white",children:["Willkommen, ",e==null?void 0:e.username,"!"]}),a.jsx("p",{className:"mb-6 text-sm text-neutral-500 dark:text-neutral-400",children:"Hier siehst du auf einen Blick, wie viel in deinem Shop hinterlegt ist. Klicke auf eine Kachel, um dorthin zu gelangen."}),s.length===0?a.jsx("p",{className:"text-neutral-500 dark:text-neutral-400",children:"Für deinen Account sind noch keine Bereiche freigeschaltet. Bitte wende dich an einen Administrator."}):a.jsx("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",children:s.map(i=>a.jsxs(H,{to:i.to,className:`rounded-xl border p-5 shadow-sm transition hover:-translate-y-0.5 hover:shadow-md ${i.highlight&&i.value>0?"border-brand-300 bg-brand-50 dark:border-brand-900 dark:bg-brand-900/20":"border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900"}`,children:[a.jsx("div",{className:"mb-3 flex h-10 w-10 items-center justify-center rounded-full bg-brand-100 text-brand-600 dark:bg-brand-900/40 dark:text-brand-400",children:a.jsx(gP,{path:pP[i.icon]})}),a.jsx("p",{className:"text-sm font-semibold text-neutral-700 dark:text-neutral-200",children:i.label}),a.jsx("p",{className:"mt-1 text-3xl font-extrabold text-brand-600 dark:text-brand-400",children:i.value??"…"}),a.jsx("p",{className:"mt-2 text-xs text-neutral-500 dark:text-neutral-400",children:i.hint})]},i.key))}),t("settings.manage")&&a.jsx(xP,{})]})}const Bf={name:"",sort_order:0};function vP(){const[e,t]=g.useState([]),[n,r]=g.useState(Bf),[s,i]=g.useState(null),[l,o]=g.useState(""),u=()=>M.get("/brands").then(t);g.useEffect(()=>{u()},[]);const c=f=>{i(f.id),r({name:f.name,sort_order:f.sort_order})},d=()=>{i(null),r(Bf)},h=async f=>{f.preventDefault(),o("");try{s?await M.put(`/brands/${s}`,n):await M.post("/brands",n),d(),u()}catch(b){o(b.message)}},m=async f=>{confirm("Marke inkl. aller Modelle/Pakete/Produkte wirklich löschen?")&&(await M.delete(`/brands/${f}`),u())};return a.jsxs("div",{className:"grid gap-6 lg:grid-cols-3",children:[a.jsxs("div",{className:"lg:col-span-2",children:[a.jsx("h1",{className:"mb-4 text-xl font-bold text-neutral-900 dark:text-white",children:"Marken"}),a.jsx("div",{className:"overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-800",children:a.jsxs("table",{className:"w-full text-left text-sm",children:[a.jsx("thead",{className:"bg-neutral-50 text-neutral-500 dark:bg-neutral-900 dark:text-neutral-400",children:a.jsxs("tr",{children:[a.jsx("th",{className:"px-4 py-2",children:"Name"}),a.jsx("th",{className:"px-4 py-2",children:"Sortierung"}),a.jsx("th",{className:"px-4 py-2 text-right",children:"Aktionen"})]})}),a.jsxs("tbody",{className:"divide-y divide-neutral-100 dark:divide-neutral-800",children:[e.map(f=>a.jsxs("tr",{className:"bg-white dark:bg-neutral-950",children:[a.jsx("td",{className:"px-4 py-2 font-medium text-neutral-800 dark:text-neutral-100",children:a.jsx(H,{to:`/marken/${f.slug}`,target:"_blank",className:"hover:text-brand-500",children:f.name})}),a.jsx("td",{className:"px-4 py-2",children:f.sort_order}),a.jsxs("td",{className:"px-4 py-2 text-right",children:[a.jsx("button",{onClick:()=>c(f),className:"mr-3 text-brand-600 hover:underline",children:"Bearbeiten"}),a.jsx("button",{onClick:()=>m(f.id),className:"text-red-600 hover:underline",children:"Löschen"})]})]},f.id)),e.length===0&&a.jsx("tr",{children:a.jsx("td",{colSpan:3,className:"px-4 py-6 text-center text-neutral-400",children:"Noch keine Marken angelegt."})})]})]})})]}),a.jsxs("form",{onSubmit:h,className:"h-fit space-y-4 rounded-xl border border-neutral-200 bg-white p-5 dark:border-neutral-800 dark:bg-neutral-900",children:[a.jsx("h2",{className:"font-bold text-neutral-900 dark:text-white",children:s?"Marke bearbeiten":"Neue Marke"}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Name *"}),a.jsx("input",{required:!0,value:n.name,onChange:f=>r({...n,name:f.target.value}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"})]}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Sortierung"}),a.jsx("input",{type:"number",value:n.sort_order,onChange:f=>r({...n,sort_order:Number(f.target.value)}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"})]}),l&&a.jsx("p",{className:"text-sm text-red-600",children:l}),a.jsxs("div",{className:"flex gap-2",children:[a.jsx("button",{type:"submit",className:"rounded-md bg-brand-500 px-4 py-2 text-sm font-semibold text-white hover:bg-brand-600",children:s?"Speichern":"Anlegen"}),s&&a.jsx("button",{type:"button",onClick:d,className:"rounded-md border border-neutral-300 px-4 py-2 text-sm dark:border-neutral-700",children:"Abbrechen"})]})]})]})}const zf={name:"",brand_id:"",sort_order:0};function yP(){const[e,t]=g.useState([]),[n,r]=g.useState([]),[s,i]=g.useState(zf),[l,o]=g.useState(null),[u,c]=g.useState(""),[d,h]=g.useState("all"),m=g.useMemo(()=>d==="all"?e:e.filter(p=>String(p.brand_id)===d),[e,d]),f=()=>{M.get("/models").then(t),M.get("/brands").then(r)};g.useEffect(f,[]);const b=p=>{o(p.id),i({name:p.name,brand_id:p.brand_id,sort_order:p.sort_order})},y=()=>{o(null),i(zf)},w=async p=>{p.preventDefault(),c("");const v={...s,brand_id:Number(s.brand_id)};try{l?await M.put(`/models/${l}`,v):await M.post("/models",v),y(),f()}catch(k){c(k.message)}},x=async p=>{confirm("Modell inkl. aller Pakete/Produkte wirklich löschen?")&&(await M.delete(`/models/${p}`),f())};return a.jsxs("div",{className:"grid gap-6 lg:grid-cols-3",children:[a.jsxs("div",{className:"lg:col-span-2",children:[a.jsx("h1",{className:"mb-4 text-xl font-bold text-neutral-900 dark:text-white",children:"Modelle"}),a.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-2",children:[a.jsx("label",{className:"text-sm font-medium text-neutral-600 dark:text-neutral-300",children:"Nach Marke filtern:"}),a.jsxs("select",{value:d,onChange:p=>h(p.target.value),className:"rounded-md border border-neutral-300 bg-white px-3 py-1.5 text-sm dark:border-neutral-700 dark:bg-neutral-900",children:[a.jsx("option",{value:"all",children:"Alle Marken"}),n.map(p=>a.jsx("option",{value:String(p.id),children:p.name},p.id))]}),d!=="all"&&a.jsx("button",{onClick:()=>h("all"),className:"text-sm text-brand-600 hover:underline",children:"Filter zurücksetzen"}),a.jsxs("span",{className:"text-sm text-neutral-400",children:[m.length," von ",e.length]})]}),a.jsx("div",{className:"overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-800",children:a.jsxs("table",{className:"w-full text-left text-sm",children:[a.jsx("thead",{className:"bg-neutral-50 text-neutral-500 dark:bg-neutral-900 dark:text-neutral-400",children:a.jsxs("tr",{children:[a.jsx("th",{className:"px-4 py-2",children:"Marke"}),a.jsx("th",{className:"px-4 py-2",children:"Modell"}),a.jsx("th",{className:"px-4 py-2 text-right",children:"Aktionen"})]})}),a.jsxs("tbody",{className:"divide-y divide-neutral-100 dark:divide-neutral-800",children:[m.map(p=>a.jsxs("tr",{className:"bg-white dark:bg-neutral-950",children:[a.jsx("td",{className:"px-4 py-2",children:p.brand_name}),a.jsx("td",{className:"px-4 py-2 font-medium text-neutral-800 dark:text-neutral-100",children:p.name}),a.jsxs("td",{className:"px-4 py-2 text-right",children:[a.jsx("button",{onClick:()=>b(p),className:"mr-3 text-brand-600 hover:underline",children:"Bearbeiten"}),a.jsx("button",{onClick:()=>x(p.id),className:"text-red-600 hover:underline",children:"Löschen"})]})]},p.id)),m.length===0&&a.jsx("tr",{children:a.jsx("td",{colSpan:3,className:"px-4 py-6 text-center text-neutral-400",children:e.length===0?"Noch keine Modelle angelegt.":"Keine Modelle für diese Marke."})})]})]})})]}),a.jsxs("form",{onSubmit:w,className:"h-fit space-y-4 rounded-xl border border-neutral-200 bg-white p-5 dark:border-neutral-800 dark:bg-neutral-900",children:[a.jsx("h2",{className:"font-bold text-neutral-900 dark:text-white",children:l?"Modell bearbeiten":"Neues Modell"}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Marke *"}),a.jsxs("select",{required:!0,value:s.brand_id,onChange:p=>i({...s,brand_id:p.target.value}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900",children:[a.jsx("option",{value:"",children:"Bitte wählen…"}),n.map(p=>a.jsx("option",{value:p.id,children:p.name},p.id))]})]}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Modellname *"}),a.jsx("input",{required:!0,value:s.name,onChange:p=>i({...s,name:p.target.value}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"})]}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Sortierung"}),a.jsx("input",{type:"number",value:s.sort_order,onChange:p=>i({...s,sort_order:Number(p.target.value)}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"})]}),u&&a.jsx("p",{className:"text-sm text-red-600",children:u}),a.jsxs("div",{className:"flex gap-2",children:[a.jsx("button",{type:"submit",className:"rounded-md bg-brand-500 px-4 py-2 text-sm font-semibold text-white hover:bg-brand-600",children:l?"Speichern":"Anlegen"}),l&&a.jsx("button",{type:"button",onClick:y,className:"rounded-md border border-neutral-300 px-4 py-2 text-sm dark:border-neutral-700",children:"Abbrechen"})]})]})]})}function vl({value:e,onChange:t,label:n="Bild"}){const[r,s]=g.useState(!1),[i,l]=g.useState(""),o=async u=>{var d;const c=(d=u.target.files)==null?void 0:d[0];if(c){s(!0),l("");try{const h=new FormData;h.append("file",c);const m=await M.post("/uploads",h);t(m.path)}catch(h){l(h.message)}finally{s(!1)}}};return a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:n}),a.jsxs("div",{className:"flex items-center gap-3",children:[e&&a.jsx("img",{src:e,alt:"",className:"h-12 w-12 rounded-md object-cover"}),a.jsx("input",{type:"file",accept:"image/png,image/jpeg,image/webp",onChange:o,className:"text-sm"}),r&&a.jsx("span",{className:"text-sm text-neutral-500",children:"Lädt hoch…"})]}),i&&a.jsx("p",{className:"mt-1 text-sm text-red-600",children:i})]})}const If={name:"",cover_image_path:"",sort_order:0};function kP(){const[e,t]=g.useState([]),[n,r]=g.useState(If),[s,i]=g.useState(null),[l,o]=g.useState(""),u=()=>M.get("/gallery-brands").then(t);g.useEffect(()=>{u()},[]);const c=f=>{i(f.id),r({name:f.name,cover_image_path:f.cover_image_path||"",sort_order:f.sort_order})},d=()=>{i(null),r(If)},h=async f=>{f.preventDefault(),o("");try{s?await M.put(`/gallery-brands/${s}`,n):await M.post("/gallery-brands",n),d(),u()}catch(b){o(b.message)}},m=async f=>{confirm("Marke inkl. aller Projekte/Fotos wirklich löschen?")&&(await M.delete(`/gallery-brands/${f}`),u())};return a.jsxs("div",{className:"grid gap-6 lg:grid-cols-3",children:[a.jsxs("div",{className:"lg:col-span-2",children:[a.jsx("h1",{className:"mb-4 text-xl font-bold text-neutral-900 dark:text-white",children:"Galerie-Marken"}),a.jsx("div",{className:"overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-800",children:a.jsxs("table",{className:"w-full text-left text-sm",children:[a.jsx("thead",{className:"bg-neutral-50 text-neutral-500 dark:bg-neutral-900 dark:text-neutral-400",children:a.jsxs("tr",{children:[a.jsx("th",{className:"px-4 py-2",children:"Bild"}),a.jsx("th",{className:"px-4 py-2",children:"Name"}),a.jsx("th",{className:"px-4 py-2",children:"Sortierung"}),a.jsx("th",{className:"px-4 py-2 text-right",children:"Aktionen"})]})}),a.jsxs("tbody",{className:"divide-y divide-neutral-100 dark:divide-neutral-800",children:[e.map(f=>a.jsxs("tr",{className:"bg-white dark:bg-neutral-950",children:[a.jsx("td",{className:"px-4 py-2",children:f.cover_image_path?a.jsx("img",{src:f.cover_image_path,alt:"",className:"h-10 w-10 rounded-md object-cover"}):a.jsx("span",{className:"flex h-10 w-10 items-center justify-center rounded-md bg-neutral-100 text-xs text-neutral-400 dark:bg-neutral-800",children:"–"})}),a.jsx("td",{className:"px-4 py-2 font-medium text-neutral-800 dark:text-neutral-100",children:a.jsx(H,{to:`/galerie/${f.slug}`,target:"_blank",className:"hover:text-brand-500",children:f.name})}),a.jsx("td",{className:"px-4 py-2",children:f.sort_order}),a.jsxs("td",{className:"px-4 py-2 text-right",children:[a.jsx("button",{onClick:()=>c(f),className:"mr-3 text-brand-600 hover:underline",children:"Bearbeiten"}),a.jsx("button",{onClick:()=>m(f.id),className:"text-red-600 hover:underline",children:"Löschen"})]})]},f.id)),e.length===0&&a.jsx("tr",{children:a.jsx("td",{colSpan:4,className:"px-4 py-6 text-center text-neutral-400",children:"Noch keine Galerie-Marken angelegt."})})]})]})})]}),a.jsxs("form",{onSubmit:h,className:"h-fit space-y-4 rounded-xl border border-neutral-200 bg-white p-5 dark:border-neutral-800 dark:bg-neutral-900",children:[a.jsx("h2",{className:"font-bold text-neutral-900 dark:text-white",children:s?"Marke bearbeiten":"Neue Marke"}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Name *"}),a.jsx("input",{required:!0,value:n.name,onChange:f=>r({...n,name:f.target.value}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"})]}),a.jsx(vl,{value:n.cover_image_path,onChange:f=>r({...n,cover_image_path:f}),label:"Titelbild (optional)"}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Sortierung"}),a.jsx("input",{type:"number",value:n.sort_order,onChange:f=>r({...n,sort_order:Number(f.target.value)}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"})]}),l&&a.jsx("p",{className:"text-sm text-red-600",children:l}),a.jsxs("div",{className:"flex gap-2",children:[a.jsx("button",{type:"submit",className:"rounded-md bg-brand-500 px-4 py-2 text-sm font-semibold text-white hover:bg-brand-600",children:s?"Speichern":"Anlegen"}),s&&a.jsx("button",{type:"button",onClick:d,className:"rounded-md border border-neutral-300 px-4 py-2 text-sm dark:border-neutral-700",children:"Abbrechen"})]})]})]})}const Rf={name:"",gallery_brand_id:"",cover_image_path:"",sort_order:0};function wP(){const[e,t]=g.useState([]),[n,r]=g.useState([]),[s,i]=g.useState(Rf),[l,o]=g.useState(null),[u,c]=g.useState(""),[d,h]=g.useState("all"),m=g.useMemo(()=>d==="all"?e:e.filter(p=>String(p.gallery_brand_id)===d),[e,d]),f=()=>{M.get("/gallery-projects").then(t),M.get("/gallery-brands").then(r)};g.useEffect(f,[]);const b=p=>{o(p.id),i({name:p.name,gallery_brand_id:p.gallery_brand_id,cover_image_path:p.cover_image_path||"",sort_order:p.sort_order})},y=()=>{o(null),i(Rf)},w=async p=>{p.preventDefault(),c("");const v={...s,gallery_brand_id:Number(s.gallery_brand_id)};try{l?await M.put(`/gallery-projects/${l}`,v):await M.post("/gallery-projects",v),y(),f()}catch(k){c(k.message)}},x=async p=>{confirm("Projekt inkl. aller Fotos wirklich löschen?")&&(await M.delete(`/gallery-projects/${p}`),f())};return a.jsxs("div",{className:"grid gap-6 lg:grid-cols-3",children:[a.jsxs("div",{className:"lg:col-span-2",children:[a.jsx("h1",{className:"mb-4 text-xl font-bold text-neutral-900 dark:text-white",children:"Galerie-Projekte"}),a.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-2",children:[a.jsx("label",{className:"text-sm font-medium text-neutral-600 dark:text-neutral-300",children:"Nach Marke filtern:"}),a.jsxs("select",{value:d,onChange:p=>h(p.target.value),className:"rounded-md border border-neutral-300 bg-white px-3 py-1.5 text-sm dark:border-neutral-700 dark:bg-neutral-900",children:[a.jsx("option",{value:"all",children:"Alle Marken"}),n.map(p=>a.jsx("option",{value:String(p.id),children:p.name},p.id))]}),d!=="all"&&a.jsx("button",{onClick:()=>h("all"),className:"text-sm text-brand-600 hover:underline",children:"Filter zurücksetzen"}),a.jsxs("span",{className:"text-sm text-neutral-400",children:[m.length," von ",e.length]})]}),a.jsx("div",{className:"overflow-hidden rounded-xl border border-neutral-200 dark:border-neutral-800",children:a.jsxs("table",{className:"w-full text-left text-sm",children:[a.jsx("thead",{className:"bg-neutral-50 text-neutral-500 dark:bg-neutral-900 dark:text-neutral-400",children:a.jsxs("tr",{children:[a.jsx("th",{className:"px-4 py-2",children:"Marke"}),a.jsx("th",{className:"px-4 py-2",children:"Projekt"}),a.jsx("th",{className:"px-4 py-2 text-right",children:"Aktionen"})]})}),a.jsxs("tbody",{className:"divide-y divide-neutral-100 dark:divide-neutral-800",children:[m.map(p=>a.jsxs("tr",{className:"bg-white dark:bg-neutral-950",children:[a.jsx("td",{className:"px-4 py-2",children:p.brand_name}),a.jsx("td",{className:"px-4 py-2 font-medium text-neutral-800 dark:text-neutral-100",children:p.name}),a.jsxs("td",{className:"px-4 py-2 text-right",children:[a.jsx(H,{to:`/admin/gallery-projects/${p.id}/photos`,className:"mr-3 text-brand-600 hover:underline",children:"Fotos"}),a.jsx("button",{onClick:()=>b(p),className:"mr-3 text-brand-600 hover:underline",children:"Bearbeiten"}),a.jsx("button",{onClick:()=>x(p.id),className:"text-red-600 hover:underline",children:"Löschen"})]})]},p.id)),m.length===0&&a.jsx("tr",{children:a.jsx("td",{colSpan:3,className:"px-4 py-6 text-center text-neutral-400",children:e.length===0?"Noch keine Projekte angelegt.":"Keine Projekte für diese Marke."})})]})]})})]}),a.jsxs("form",{onSubmit:w,className:"h-fit space-y-4 rounded-xl border border-neutral-200 bg-white p-5 dark:border-neutral-800 dark:bg-neutral-900",children:[a.jsx("h2",{className:"font-bold text-neutral-900 dark:text-white",children:l?"Projekt bearbeiten":"Neues Projekt"}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Marke *"}),a.jsxs("select",{required:!0,value:s.gallery_brand_id,onChange:p=>i({...s,gallery_brand_id:p.target.value}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900",children:[a.jsx("option",{value:"",children:"Bitte wählen…"}),n.map(p=>a.jsx("option",{value:p.id,children:p.name},p.id))]})]}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Projektname *"}),a.jsx("input",{required:!0,placeholder:"z. B. Audi TT",value:s.name,onChange:p=>i({...s,name:p.target.value}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"})]}),a.jsx(vl,{value:s.cover_image_path,onChange:p=>i({...s,cover_image_path:p}),label:"Titelbild (optional)"}),a.jsxs("div",{children:[a.jsx("label",{className:"mb-1 block text-sm font-medium text-neutral-700 dark:text-neutral-300",children:"Sortierung"}),a.jsx("input",{type:"number",value:s.sort_order,onChange:p=>i({...s,sort_order:Number(p.target.value)}),className:"w-full rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"})]}),u&&a.jsx("p",{className:"text-sm text-red-600",children:u}),a.jsxs("div",{className:"flex gap-2",children:[a.jsx("button",{type:"submit",className:"rounded-md bg-brand-500 px-4 py-2 text-sm font-semibold text-white hover:bg-brand-600",children:l?"Speichern":"Anlegen"}),l&&a.jsx("button",{type:"button",onClick:y,className:"rounded-md border border-neutral-300 px-4 py-2 text-sm dark:border-neutral-700",children:"Abbrechen"})]})]})]})}function jP(){const{projectId:e}=Yn(),[t,n]=g.useState([]),[r,s]=g.useState(""),[i,l]=g.useState(!1),[o,u]=g.useState(""),c=g.useRef(null),d=()=>M.get(`/gallery-projects/${e}/photos`).then(n);g.useEffect(()=>{d()},[e]);const h=async w=>{const x=Array.from(w.target.files||[]);if(x.length!==0){s(""),l(!0);try{for(let p=0;p