Views added: - ShiftsView (Schichtplanung) - PatrolsView (Wächterkontrolle) - IncidentsView (Vorfallberichte) - VehiclesView (Fahrzeuge) - DocumentsView (Dokumente) - CustomersView (Kunden/CRM) - BillingView (Abrechnung) - ObjectsView (enhanced with contacts, instructions) Updated: - Router with all new routes - Sidebar with complete navigation
2 lines
11 KiB
JavaScript
2 lines
11 KiB
JavaScript
import{d as E,q as U,o as n,c as r,a as e,n as P,t as c,e as b,F,x as D,r as i,u as j,y as A,w as K,b as N,v as _,z as q,k as z,m as Z}from"./index-CWxNv9Fc.js";const L={class:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"},T={class:"bg-white rounded-2xl shadow-xl w-full max-w-md overflow-hidden"},J={class:"bg-gradient-to-r from-purple-600 to-indigo-600 p-6 text-white"},R={class:"flex justify-between items-center"},W={class:"p-6"},G={key:0,class:"space-y-4"},H={class:"bg-gray-50 rounded-lg p-4 mb-4"},O={class:"flex items-center justify-between"},Q={class:"space-y-3"},X={class:"flex-1"},Y={class:"text-sm text-gray-500"},ee={key:0,class:"text-purple-600"},te={class:"flex-1"},se={class:"text-sm text-gray-500"},le={key:0,class:"text-purple-600"},ne={key:1,class:"text-center"},ie={class:"text-lg font-semibold mb-2"},re={class:"flex justify-center space-x-3 mb-8"},ae={key:0,class:"text-red-500 text-sm mb-4"},oe={class:"grid grid-cols-3 gap-3 max-w-xs mx-auto"},ue=["onClick"],de={key:2,class:"text-center py-8"},ce={key:0,class:"text-red-500 text-sm"},me=E({__name:"SecuritySettings",emits:["close"],setup(V,{emit:w}){const h=w,l=i("menu"),g=i(""),f=i(""),a=i(""),m=i(["","","","","",""]),v=i(0),u=i(!1),x=i(!1),S=i(!1),o=i("none");U(async()=>{if(x.value=!!localStorage.getItem("appPin"),u.value=!!localStorage.getItem("biometricCredentialId"),o.value=localStorage.getItem("lockMethod")||"none",window.PublicKeyCredential)try{S.value=await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{S.value=!1}});function I(p){v.value<6&&(m.value[v.value]=p,v.value++,v.value===6&&(l.value==="setup-pin"?(g.value=m.value.join(""),s(),l.value="confirm-pin"):l.value==="confirm-pin"&&(f.value=m.value.join(""),C())))}function y(){v.value>0&&(v.value--,m.value[v.value]=""),a.value=""}function s(){m.value=["","","","","",""],v.value=0,a.value=""}function C(){g.value===f.value?(localStorage.setItem("appPin",g.value),localStorage.setItem("lockMethod","pin"),x.value=!0,o.value="pin",l.value="menu",g.value="",f.value="",s()):(a.value="PINs stimmen nicht überein",setTimeout(()=>{s(),l.value="setup-pin",g.value="",f.value=""},1e3))}async function $(){l.value="setup-biometric",a.value="";try{if(!window.PublicKeyCredential)throw new Error("WebAuthn nicht unterstützt");const p=new Uint8Array(16);crypto.getRandomValues(p);const t=await navigator.credentials.create({publicKey:{challenge:new Uint8Array(32),rp:{name:"SeCu",id:window.location.hostname},user:{id:p,name:localStorage.getItem("userEmail")||"user",displayName:"SeCu User"},pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],authenticatorSelection:{authenticatorAttachment:"platform",userVerification:"required",residentKey:"preferred"},timeout:6e4,attestation:"none"}});if(t){const d=btoa(String.fromCharCode(...new Uint8Array(t.rawId)));localStorage.setItem("biometricCredentialId",d),localStorage.setItem("lockMethod","biometric"),u.value=!0,o.value="biometric",l.value="menu"}}catch(p){console.error("Biometric setup failed:",p),a.value=p.message||"Biometrie-Einrichtung fehlgeschlagen",l.value="menu"}}function k(){confirm("App-Sperre wirklich deaktivieren?")&&(localStorage.removeItem("appPin"),localStorage.removeItem("biometricCredentialId"),localStorage.removeItem("lockMethod"),x.value=!1,u.value=!1,o.value="none")}function M(p){localStorage.setItem("lockMethod",p),o.value=p}return(p,t)=>(n(),r("div",L,[e("div",T,[e("div",J,[e("div",R,[t[7]||(t[7]=e("h2",{class:"text-xl font-bold"},"🔐 App-Sicherheit",-1)),e("button",{onClick:t[0]||(t[0]=d=>h("close")),class:"text-white/70 hover:text-white"},"✕")])]),e("div",W,[l.value==="menu"?(n(),r("div",G,[t[14]||(t[14]=e("p",{class:"text-gray-600 text-sm mb-4"}," Schütze deine App mit Fingerabdruck, Face ID oder PIN. ",-1)),e("div",H,[e("div",O,[t[8]||(t[8]=e("span",{class:"text-gray-700"},"Aktueller Schutz:",-1)),e("span",{class:P(["px-3 py-1 rounded-full text-sm font-medium",o.value==="none"?"bg-red-100 text-red-700":"bg-green-100 text-green-700"])},c(o.value==="biometric"?"👆 Biometrie":o.value==="pin"?"🔢 PIN":"❌ Aus"),3)])]),e("div",Q,[S.value?(n(),r("button",{key:0,onClick:t[1]||(t[1]=d=>u.value?M("biometric"):$()),class:P(["w-full p-4 rounded-lg border-2 text-left transition flex items-center",o.value==="biometric"?"border-purple-500 bg-purple-50":"border-gray-200 hover:border-purple-300"])},[t[10]||(t[10]=e("span",{class:"text-2xl mr-4"},"👆",-1)),e("div",X,[t[9]||(t[9]=e("div",{class:"font-semibold"},"Fingerabdruck / Face ID",-1)),e("div",Y,c(u.value?"Eingerichtet":"Jetzt einrichten"),1)]),o.value==="biometric"?(n(),r("span",ee,"✓")):b("",!0)],2)):b("",!0),e("button",{onClick:t[2]||(t[2]=d=>x.value?M("pin"):l.value="setup-pin"),class:P(["w-full p-4 rounded-lg border-2 text-left transition flex items-center",o.value==="pin"?"border-purple-500 bg-purple-50":"border-gray-200 hover:border-purple-300"])},[t[12]||(t[12]=e("span",{class:"text-2xl mr-4"},"🔢",-1)),e("div",te,[t[11]||(t[11]=e("div",{class:"font-semibold"},"PIN-Code (6 Ziffern)",-1)),e("div",se,c(x.value?"Eingerichtet":"Jetzt einrichten"),1)]),o.value==="pin"?(n(),r("span",le,"✓")):b("",!0)],2),o.value!=="none"?(n(),r("button",{key:1,onClick:k,class:"w-full p-4 rounded-lg border-2 border-red-200 text-left transition flex items-center hover:border-red-300 hover:bg-red-50"},[...t[13]||(t[13]=[e("span",{class:"text-2xl mr-4"},"🔓",-1),e("div",{class:"flex-1"},[e("div",{class:"font-semibold text-red-700"},"Sperre deaktivieren"),e("div",{class:"text-sm text-gray-500"},"Nicht empfohlen")],-1)])])):b("",!0)]),x.value?(n(),r("button",{key:0,onClick:t[3]||(t[3]=d=>l.value="setup-pin"),class:"w-full text-center text-purple-600 text-sm hover:underline mt-4"}," PIN ändern ")):b("",!0)])):l.value==="setup-pin"||l.value==="confirm-pin"?(n(),r("div",ne,[e("h3",ie,c(l.value==="setup-pin"?"Neuen PIN eingeben":"PIN bestätigen"),1),t[15]||(t[15]=e("p",{class:"text-gray-500 text-sm mb-6"},"6 Ziffern",-1)),e("div",re,[(n(!0),r(F,null,D(m.value,(d,B)=>(n(),r("div",{key:B,class:P(["w-4 h-4 rounded-full transition-all",d?"bg-purple-600 scale-110":"bg-gray-300",a.value?"bg-red-400 animate-shake":""])},null,2))),128))]),a.value?(n(),r("p",ae,c(a.value),1)):b("",!0),e("div",oe,[(n(),r(F,null,D([1,2,3,4,5,6,7,8,9],d=>e("button",{key:d,onClick:B=>I(String(d)),class:"w-14 h-14 bg-gray-100 rounded-full text-xl font-semibold hover:bg-gray-200 transition"},c(d),9,ue)),64)),e("button",{onClick:t[4]||(t[4]=d=>{l.value="menu",s()}),class:"w-14 h-14 text-gray-500 text-sm"}," Zurück "),e("button",{onClick:t[5]||(t[5]=d=>I("0")),class:"w-14 h-14 bg-gray-100 rounded-full text-xl font-semibold hover:bg-gray-200 transition"}," 0 "),e("button",{onClick:y,class:"w-14 h-14 text-xl hover:bg-gray-100 rounded-full transition"}," ⌫ ")])])):l.value==="setup-biometric"?(n(),r("div",de,[t[16]||(t[16]=e("div",{class:"text-6xl mb-4 animate-pulse"},"👆",-1)),t[17]||(t[17]=e("h3",{class:"text-lg font-semibold mb-2"},"Biometrie einrichten",-1)),t[18]||(t[18]=e("p",{class:"text-gray-500 text-sm mb-4"}," Bitte Fingerabdruck scannen oder Face ID verwenden... ",-1)),a.value?(n(),r("p",ce,c(a.value),1)):b("",!0),e("button",{onClick:t[6]||(t[6]=d=>l.value="menu"),class:"mt-4 text-gray-500 text-sm hover:underline"}," Abbrechen ")])):b("",!0)])])]))}}),ve={class:"space-y-6"},pe={class:"card"},be={class:"grid grid-cols-2 gap-4"},ge={class:"font-medium"},fe={class:"font-medium"},xe={class:"font-medium capitalize"},ye={class:"card"},ke={class:"flex items-center justify-between p-4 bg-gray-50 rounded-lg"},we={class:"card"},he={key:0,class:"text-red-600 text-sm"},Se={key:1,class:"text-green-600 text-sm"},Pe=["disabled"],Ce=E({__name:"SettingsView",setup(V){const w=j(),h=i(""),l=i(""),g=i(""),f=i(!1),a=i(""),m=i(""),v=i(!1),u=i(null);U(()=>{var y;u.value=localStorage.getItem("lockMethod"),(y=w.user)!=null&&y.email&&localStorage.setItem("userEmail",w.user.email)});const x=z(()=>!u.value||u.value==="none"?"Deaktiviert":u.value==="biometric"?"Fingerabdruck / Face ID":u.value==="pin"?"PIN-Code":"Unbekannt"),S=z(()=>!u.value||u.value==="none"?"bg-red-100 text-red-700":"bg-green-100 text-green-700");async function o(){if(l.value!==g.value){m.value="Passwörter stimmen nicht überein";return}if(l.value.length<8){m.value="Passwort muss mindestens 8 Zeichen haben";return}f.value=!0,m.value="",a.value="";try{await Z.post("/auth/change-password",{currentPassword:h.value,newPassword:l.value}),a.value="Passwort erfolgreich geändert",h.value="",l.value="",g.value=""}catch(y){m.value=y instanceof Error?y.message:"Fehler beim Ändern"}finally{f.value=!1}}function I(){v.value=!1,u.value=localStorage.getItem("lockMethod")}return(y,s)=>{var C,$;return n(),r("div",ve,[s[15]||(s[15]=e("h1",{class:"text-2xl font-bold text-gray-900 dark:text-white"},"🔧 Einstellungen",-1)),e("div",pe,[s[7]||(s[7]=e("h2",{class:"text-lg font-semibold mb-4"},"👤 Profil",-1)),e("div",be,[e("div",null,[s[4]||(s[4]=e("label",{class:"block text-sm text-gray-500"},"Name",-1)),e("p",ge,c(A(w).fullName),1)]),e("div",null,[s[5]||(s[5]=e("label",{class:"block text-sm text-gray-500"},"E-Mail",-1)),e("p",fe,c((C=A(w).user)==null?void 0:C.email),1)]),e("div",null,[s[6]||(s[6]=e("label",{class:"block text-sm text-gray-500"},"Rolle",-1)),e("p",xe,c(($=A(w).user)==null?void 0:$.role),1)])])]),e("div",ye,[s[9]||(s[9]=e("h2",{class:"text-lg font-semibold mb-4"},"🔐 App-Sicherheit",-1)),s[10]||(s[10]=e("p",{class:"text-gray-600 text-sm mb-4"}," Schütze deine App mit Fingerabdruck, Face ID oder PIN. Bei jedem Öffnen der App musst du dich verifizieren. ",-1)),e("div",ke,[e("div",null,[s[8]||(s[8]=e("div",{class:"font-medium"},"App-Sperre",-1)),e("div",{class:P(["inline-block px-2 py-1 rounded text-sm mt-1",S.value])},c(x.value),3)]),e("button",{onClick:s[0]||(s[0]=k=>v.value=!0),class:"btn btn-primary"}," Konfigurieren ")])]),e("div",we,[s[14]||(s[14]=e("h2",{class:"text-lg font-semibold mb-4"},"🔑 Passwort ändern",-1)),e("form",{onSubmit:K(o,["prevent"]),class:"space-y-4 max-w-md"},[e("div",null,[s[11]||(s[11]=e("label",{class:"block text-sm font-medium mb-1"},"Aktuelles Passwort",-1)),N(e("input",{"onUpdate:modelValue":s[1]||(s[1]=k=>h.value=k),type:"password",required:"",class:"input"},null,512),[[_,h.value]])]),e("div",null,[s[12]||(s[12]=e("label",{class:"block text-sm font-medium mb-1"},"Neues Passwort",-1)),N(e("input",{"onUpdate:modelValue":s[2]||(s[2]=k=>l.value=k),type:"password",required:"",class:"input"},null,512),[[_,l.value]])]),e("div",null,[s[13]||(s[13]=e("label",{class:"block text-sm font-medium mb-1"},"Passwort bestätigen",-1)),N(e("input",{"onUpdate:modelValue":s[3]||(s[3]=k=>g.value=k),type:"password",required:"",class:"input"},null,512),[[_,g.value]])]),m.value?(n(),r("div",he,c(m.value),1)):b("",!0),a.value?(n(),r("div",Se,c(a.value),1)):b("",!0),e("button",{type:"submit",disabled:f.value,class:"btn btn-primary"},c(f.value?"Speichern...":"Passwort ändern"),9,Pe)],32)]),v.value?(n(),q(me,{key:0,onClose:I})):b("",!0)])}}});export{Ce as default};
|