admin felület fejlesztése garázs, előfizeztési csomagok

This commit is contained in:
Roo
2026-06-25 01:58:04 +00:00
parent 80a5d67f79
commit 52011606ff
334 changed files with 46636 additions and 1606 deletions

View File

@@ -26,6 +26,8 @@ export const NuxtTime: typeof import("../node_modules/nuxt/dist/app/components/n
export const NuxtRouteAnnouncer: typeof import("../node_modules/nuxt/dist/app/components/nuxt-route-announcer")['default']
export const NuxtImg: typeof import("../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtImg']
export const NuxtPicture: typeof import("../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtPicture']
export const NuxtLinkLocale: typeof import("../node_modules/@nuxtjs/i18n/dist/runtime/components/NuxtLinkLocale")['default']
export const SwitchLocalePathLink: typeof import("../node_modules/@nuxtjs/i18n/dist/runtime/components/SwitchLocalePathLink")['default']
export const NuxtPage: typeof import("../node_modules/nuxt/dist/pages/runtime/page")['default']
export const NoScript: typeof import("../node_modules/nuxt/dist/head/runtime/components")['NoScript']
export const Link: typeof import("../node_modules/nuxt/dist/head/runtime/components")['Link']
@@ -49,6 +51,8 @@ export const LazyNuxtTime: LazyComponent<typeof import("../node_modules/nuxt/dis
export const LazyNuxtRouteAnnouncer: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-route-announcer")['default']>
export const LazyNuxtImg: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtImg']>
export const LazyNuxtPicture: LazyComponent<typeof import("../node_modules/nuxt/dist/app/components/nuxt-stubs")['NuxtPicture']>
export const LazyNuxtLinkLocale: LazyComponent<typeof import("../node_modules/@nuxtjs/i18n/dist/runtime/components/NuxtLinkLocale")['default']>
export const LazySwitchLocalePathLink: LazyComponent<typeof import("../node_modules/@nuxtjs/i18n/dist/runtime/components/SwitchLocalePathLink")['default']>
export const LazyNuxtPage: LazyComponent<typeof import("../node_modules/nuxt/dist/pages/runtime/page")['default']>
export const LazyNoScript: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['NoScript']>
export const LazyLink: LazyComponent<typeof import("../node_modules/nuxt/dist/head/runtime/components")['Link']>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as h}from"./Da4aCGAe.js";import{p as v,e as y,g as _,c as n,a as t,f as k,h as s,t as c,i as u,j as S,k as p,v as m,l as x,b as V,w as L,m as f,o as i,d as C}from"./CqYPuxVf.js";import{u as N}from"./CWA6Xjbg.js";const B=v("/sf_logo.png"),E={class:"min-h-screen bg-slate-900 flex items-center justify-center px-4"},R={class:"w-full max-w-md"},j={class:"bg-slate-800 rounded-xl shadow-2xl border border-slate-700 p-8"},A={key:0,class:"mb-6 p-3 rounded-lg bg-red-900/40 border border-red-700 text-red-300 text-sm"},D=["disabled"],F={key:0,class:"animate-spin h-5 w-5 text-white",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24"},I={class:"mt-6 text-center"},T=y({__name:"login",setup(M){const a=f(""),l=f(""),b=_(),o=N();async function g(){try{await o.login(a.value,l.value),b.push("/")}catch(d){console.error("Login failed:",d)}}return(d,e)=>{const w=h;return i(),n("div",E,[t("div",R,[e[6]||(e[6]=k('<div class="text-center mb-8"><div class="flex items-center justify-center gap-3 mb-4"><img src="'+B+'" class="h-12 w-auto drop-shadow-md" alt="ServiceFinder Logo"><span class="text-3xl font-extrabold tracking-wider"><span class="text-white">SERVICE</span><span class="text-cyan-400">FINDER</span></span></div><h1 class="text-xl font-semibold text-slate-300">Staff Portal</h1><p class="text-sm text-slate-500 mt-1">Authorised personnel only</p></div>',1)),t("div",j,[s(o).error?(i(),n("div",A,c(s(o).error),1)):u("",!0),t("form",{onSubmit:S(g,["prevent"]),class:"space-y-5"},[t("div",null,[e[2]||(e[2]=t("label",{for:"email",class:"block text-sm font-medium text-slate-300 mb-1.5"}," Email Address ",-1)),p(t("input",{id:"email","onUpdate:modelValue":e[0]||(e[0]=r=>x(a)?a.value=r:null),type:"email",autocomplete:"email",required:"",placeholder:"admin@example.com",class:"w-full px-4 py-2.5 bg-slate-700 border border-slate-600 rounded-lg text-white placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition"},null,512),[[m,s(a)]])]),t("div",null,[e[3]||(e[3]=t("label",{for:"password",class:"block text-sm font-medium text-slate-300 mb-1.5"}," Password ",-1)),p(t("input",{id:"password","onUpdate:modelValue":e[1]||(e[1]=r=>x(l)?l.value=r:null),type:"password",autocomplete:"current-password",required:"",placeholder:"••••••••",class:"w-full px-4 py-2.5 bg-slate-700 border border-slate-600 rounded-lg text-white placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition"},null,512),[[m,s(l)]])]),t("button",{type:"submit",disabled:s(o).isLoading,class:"w-full py-2.5 px-4 bg-cyan-600 hover:bg-cyan-500 disabled:bg-cyan-800 disabled:cursor-not-allowed text-white font-semibold rounded-lg transition duration-200 flex items-center justify-center gap-2"},[s(o).isLoading?(i(),n("svg",F,[...e[4]||(e[4]=[t("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),t("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"},null,-1)])])):u("",!0),t("span",null,c(s(o).isLoading?"Signing in...":"Sign In"),1)],8,D)],32),t("div",I,[V(w,{to:"/",class:"text-sm text-slate-500 hover:text-cyan-400 transition"},{default:L(()=>[...e[5]||(e[5]=[C(" ← Back to ServiceFinder ",-1)])]),_:1})])])])])}}});export{T as default};

View File

@@ -1 +0,0 @@
import{y as e,z as t}from"./C3Ck-LNv.js";import{u as a}from"./BoAo7BJa.js";const u=e((o,i)=>{if(o.path==="/login")return;if(!a("access_token").value)return t("/login")});export{u as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
import{I as y,J as C,x as u,H as l}from"./C3Ck-LNv.js";import{u as r}from"./BoAo7BJa.js";const x=y("/sf_logo.png"),I=C("auth",()=>{const a=u(null),n=u(null),c=u(!1),s=u(null),v=u(!1),p=l(()=>!!n.value&&!!a.value),d=l(()=>{const e=a.value?.role;return e?["SUPERADMIN","ADMIN","MODERATOR","SALES_REP","SERVICE_MGR"].includes(e.toUpperCase()):!1}),h=l(()=>{if(!a.value)return"";const{first_name:e,last_name:o}=a.value;return e&&o?`${e} ${o}`:e||o||a.value.email}),k=l(()=>a.value?.email??""),_=l(()=>a.value?.role??"guest");async function w(e,o){c.value=!0,s.value=null;try{const t=new URLSearchParams;t.append("username",e),t.append("password",o);const m=await $fetch("/api/v1/auth/login",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:t}),A=r("access_token",{maxAge:3600*24*7,path:"/",sameSite:"lax",secure:!0});A.value=m.access_token,n.value=m.access_token,await i()}catch(t){throw s.value=t?.data?.detail||t?.message||"Login failed",t}finally{c.value=!1}}async function i(){const o=r("access_token").value||n.value;if(o)try{const t=await $fetch("/api/v1/auth/me",{headers:{Authorization:`Bearer ${o}`}});a.value=t}catch(t){throw t?.response?.status===401&&f(),t}}function f(){n.value=null,a.value=null,s.value=null;const e=r("access_token");e.value=null}async function R(){const e=r("access_token");if(e.value){n.value=e.value;try{await i()}catch{f()}}v.value=!0}function g(){s.value=null}return{user:a,token:n,isLoading:c,error:s,isInitialized:v,isAuthenticated:p,isAdmin:d,userName:h,userEmail:k,userRole:_,login:w,fetchUser:i,logout:f,init:R,clearError:g}});export{x as _,I as u};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as a}from"./Da4aCGAe.js";import{_ as i,u,o as c,c as l,a as e,t as r,b as d,w as p,d as f}from"./CqYPuxVf.js";const m={class:"antialiased bg-white dark:bg-black dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-black"},g={class:"max-w-520px text-center z-20"},b=["textContent"],h=["textContent"],x={class:"flex items-center justify-center w-full"},y={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},status:{type:Number,default:404},statusText:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const n=t;return u({title:`${n.status} - ${n.statusText} | ${n.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}h1,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(k,o)=>{const s=a;return c(),l("div",m,[o[0]||(o[0]=e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),e("div",g,[e("h1",{class:"font-medium mb-8 sm:text-10xl text-8xl",textContent:r(t.status)},null,8,b),e("p",{class:"font-light leading-tight mb-16 px-8 sm:px-0 sm:text-4xl text-xl",textContent:r(t.description)},null,8,h),e("div",x,[d(s,{to:"/",class:"cursor-pointer gradient-border px-4 py-2 sm:px-6 sm:py-3 sm:text-xl text-md"},{default:p(()=>[f(r(t.backHome),1)]),_:1})])])])}}},v=i(y,[["__scopeId","data-v-1bd9e11a"]]);export{v as default};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{K as C,m as u,x as l,A as r}from"./CqYPuxVf.js";const g=C("auth",()=>{const t=u(null),o=u(null),c=u(!1),s=u(null),v=u(!1),h=l(()=>!!o.value&&!!t.value),k=l(()=>{const e=t.value?.role;return e?["SUPERADMIN","ADMIN","MODERATOR","SALES_REP","SERVICE_MGR"].includes(e.toUpperCase()):!1}),m=l(()=>{if(!t.value)return"";const{first_name:e,last_name:n}=t.value;return e&&n?`${e} ${n}`:e||n||t.value.email}),p=l(()=>t.value?.email??""),w=l(()=>t.value?.role??"guest");async function A(e,n){c.value=!0,s.value=null;try{const a=new URLSearchParams;a.append("username",e),a.append("password",n);const d=await $fetch("/api/v1/auth/login",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:a}),y=r("access_token",{maxAge:3600*24*7,path:"/",sameSite:"lax",secure:!0});y.value=d.access_token,o.value=d.access_token,await i()}catch(a){throw s.value=a?.data?.detail||a?.message||"Login failed",a}finally{c.value=!1}}async function i(){const n=r("access_token").value||o.value;if(n)try{const a=await $fetch("/api/v1/auth/me",{headers:{Authorization:`Bearer ${n}`}});t.value=a}catch(a){throw a?.response?.status===401&&f(),a}}function f(){o.value=null,t.value=null,s.value=null;const e=r("access_token");e.value=null}async function R(){const e=r("access_token");if(e.value){o.value=e.value;try{await i()}catch{f()}}v.value=!0}function _(){s.value=null}return{user:t,token:o,isLoading:c,error:s,isInitialized:v,isAuthenticated:h,isAdmin:k,userName:m,userEmail:p,userRole:w,login:A,fetchUser:i,logout:f,init:R,clearError:_}});export{g as u};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as s,u as a,o as i,c as u,a as e,t as o}from"./CqYPuxVf.js";const l={class:"antialiased bg-white dark:bg-black dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-black"},c={class:"max-w-520px text-center"},d=["textContent"],p=["textContent"],f={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},status:{type:Number,default:500},statusText:{type:String,default:"Server error"},description:{type:String,default:"This page is temporarily unavailable."}},setup(t){const n=t;return a({title:`${n.status} - ${n.statusText} | ${n.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1{font-size:inherit;font-weight:inherit}h1,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(g,r)=>(i(),u("div",l,[r[0]||(r[0]=e("div",{class:"-bottom-1/2 fixed h-1/2 left-0 right-0 spotlight"},null,-1)),e("div",c,[e("h1",{class:"font-medium mb-8 sm:text-10xl text-8xl",textContent:o(t.status)},null,8,d),e("p",{class:"font-light leading-tight mb-16 px-8 sm:px-0 sm:text-4xl text-xl",textContent:o(t.description)},null,8,p)])]))}},b=s(f,[["__scopeId","data-v-a01dd0ba"]]);export{b as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{K as _,m as u,x as a}from"./CqYPuxVf.js";const h=_("region",()=>{const t=u([]),n=u(null),c=u(!1),l=u(null),o=a(()=>t.value.find(e=>e.country_code==="DEFAULT")||null),s=a(()=>{const e=new Map;for(const r of t.value)e.set(r.country_code,r);return e}),i=a(()=>n.value?.currency||o.value?.currency||"EUR"),v=a(()=>n.value?.locale_code||o.value?.locale_code||"en-EU"),f=a(()=>n.value?.default_vat_rate??o.value?.default_vat_rate??0),d=a(()=>n.value?.timezone||o.value?.timezone||"Europe/Brussels");async function g(){if(!(t.value.length>0)){c.value=!0,l.value=null;try{const e=await $fetch("/api/v1/system/regions");t.value=e||[]}catch(e){l.value=e?.data?.detail||e?.message||"Failed to load regions",console.error("[RegionStore] Fetch error:",e)}finally{c.value=!1}}}function m(e){const r=t.value.find(R=>R.country_code===e);n.value=r||o.value}function y(e){return s.value.get(e)}return{regions:t,activeRegion:n,isLoading:c,error:l,defaultRegion:o,regionMap:s,activeCurrency:i,activeLocale:v,activeVatRate:f,activeTimezone:d,fetchRegions:g,setActiveRegion:m,getRegion:y}});export{h as u};

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
import{u as a,e as s,h as u,i as r,f as o}from"./C3Ck-LNv.js";function i(e){const t=e||s();return t?.ssrContext?.head||t?.runWithContext(()=>{if(u())return r(o)})}function x(e,t={}){const n=i(t.nuxt);if(n)return a(e,{head:n,...t})}export{x as u};

View File

@@ -0,0 +1 @@
import{B as o,A as t,C as a}from"./CqYPuxVf.js";const s=o((e,i)=>{if(e.path==="/login")return;if(!t("access_token").value)return a("/login")});export{s as default};

View File

@@ -1 +0,0 @@
import{_ as a}from"./QKJPEFuj.js";import{_ as i,o as u,c,a as e,t as r,b as l,w as d,d as p}from"./C3Ck-LNv.js";import{u as f}from"./Di-57MrI.js";const m={class:"antialiased bg-white dark:bg-black dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-black"},g={class:"max-w-520px text-center z-20"},b=["textContent"],h=["textContent"],x={class:"flex items-center justify-center w-full"},y={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},status:{type:Number,default:404},statusText:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const n=t;return f({title:`${n.status} - ${n.statusText} | ${n.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}h1,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(k,o)=>{const s=a;return u(),c("div",m,[o[0]||(o[0]=e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),e("div",g,[e("h1",{class:"font-medium mb-8 sm:text-10xl text-8xl",textContent:r(t.status)},null,8,b),e("p",{class:"font-light leading-tight mb-16 px-8 sm:px-0 sm:text-4xl text-xl",textContent:r(t.description)},null,8,h),e("div",x,[l(s,{to:"/",class:"cursor-pointer gradient-border px-4 py-2 sm:px-6 sm:py-3 sm:text-xl text-md"},{default:d(()=>[p(r(t.backHome),1)]),_:1})])])])}}},z=i(y,[["__scopeId","data-v-1bd9e11a"]]);export{z as default};

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
import{_ as v}from"./QKJPEFuj.js";import{g as y,k as h,c as n,a as t,j as _,l as s,t as c,m as u,p as k,q as p,v as m,s as x,b as S,w as V,x as f,o as i,d as C}from"./C3Ck-LNv.js";import{u as L,_ as N}from"./ByPKVH1D.js";import"./BoAo7BJa.js";const B={class:"min-h-screen bg-slate-900 flex items-center justify-center px-4"},E={class:"w-full max-w-md"},j={class:"bg-slate-800 rounded-xl shadow-2xl border border-slate-700 p-8"},R={key:0,class:"mb-6 p-3 rounded-lg bg-red-900/40 border border-red-700 text-red-300 text-sm"},q=["disabled"],A={key:0,class:"animate-spin h-5 w-5 text-white",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24"},D={class:"mt-6 text-center"},U=y({__name:"login",setup(F){const a=f(""),r=f(""),b=h(),o=L();async function g(){try{await o.login(a.value,r.value),b.push("/")}catch(d){console.error("Login failed:",d)}}return(d,e)=>{const w=v;return i(),n("div",B,[t("div",E,[e[6]||(e[6]=_('<div class="text-center mb-8"><div class="flex items-center justify-center gap-3 mb-4"><img src="'+N+'" class="h-12 w-auto drop-shadow-md" alt="ServiceFinder Logo"><span class="text-3xl font-extrabold tracking-wider"><span class="text-white">SERVICE</span><span class="text-cyan-400">FINDER</span></span></div><h1 class="text-xl font-semibold text-slate-300">Staff Portal</h1><p class="text-sm text-slate-500 mt-1">Authorised personnel only</p></div>',1)),t("div",j,[s(o).error?(i(),n("div",R,c(s(o).error),1)):u("",!0),t("form",{onSubmit:k(g,["prevent"]),class:"space-y-5"},[t("div",null,[e[2]||(e[2]=t("label",{for:"email",class:"block text-sm font-medium text-slate-300 mb-1.5"}," Email Address ",-1)),p(t("input",{id:"email","onUpdate:modelValue":e[0]||(e[0]=l=>x(a)?a.value=l:null),type:"email",autocomplete:"email",required:"",placeholder:"admin@example.com",class:"w-full px-4 py-2.5 bg-slate-700 border border-slate-600 rounded-lg text-white placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition"},null,512),[[m,s(a)]])]),t("div",null,[e[3]||(e[3]=t("label",{for:"password",class:"block text-sm font-medium text-slate-300 mb-1.5"}," Password ",-1)),p(t("input",{id:"password","onUpdate:modelValue":e[1]||(e[1]=l=>x(r)?r.value=l:null),type:"password",autocomplete:"current-password",required:"",placeholder:"••••••••",class:"w-full px-4 py-2.5 bg-slate-700 border border-slate-600 rounded-lg text-white placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition"},null,512),[[m,s(r)]])]),t("button",{type:"submit",disabled:s(o).isLoading,class:"w-full py-2.5 px-4 bg-cyan-600 hover:bg-cyan-500 disabled:bg-cyan-800 disabled:cursor-not-allowed text-white font-semibold rounded-lg transition duration-200 flex items-center justify-center gap-2"},[s(o).isLoading?(i(),n("svg",A,[...e[4]||(e[4]=[t("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),t("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"},null,-1)])])):u("",!0),t("span",null,c(s(o).isLoading?"Signing in...":"Sign In"),1)],8,q)],32),t("div",D,[S(w,{to:"/",class:"text-sm text-slate-500 hover:text-cyan-400 transition"},{default:V(()=>[...e[5]||(e[5]=[C(" ← Back to ServiceFinder ",-1)])]),_:1})])])])])}}});export{U as default};

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
import{_ as s,o as a,c as i,a as e,t as o}from"./C3Ck-LNv.js";import{u}from"./Di-57MrI.js";const l={class:"antialiased bg-white dark:bg-black dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-black"},c={class:"max-w-520px text-center"},d=["textContent"],p=["textContent"],f={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},status:{type:Number,default:500},statusText:{type:String,default:"Server error"},description:{type:String,default:"This page is temporarily unavailable."}},setup(t){const r=t;return u({title:`${r.status} - ${r.statusText} | ${r.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1{font-size:inherit;font-weight:inherit}h1,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(g,n)=>(a(),i("div",l,[n[0]||(n[0]=e("div",{class:"-bottom-1/2 fixed h-1/2 left-0 right-0 spotlight"},null,-1)),e("div",c,[e("h1",{class:"font-medium mb-8 sm:text-10xl text-8xl",textContent:o(t.status)},null,8,d),e("p",{class:"font-light leading-tight mb-16 px-8 sm:px-0 sm:text-4xl text-xl",textContent:o(t.description)},null,8,p)])]))}},h=s(f,[["__scopeId","data-v-a01dd0ba"]]);export{h as default};

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,4 @@
import { d as defineNuxtRouteMiddleware, n as navigateTo } from "../server.mjs";
import { u as useCookie } from "./cookie-CWIsZYm7.js";
import { d as defineNuxtRouteMiddleware, b as useCookie, n as navigateTo } from "../server.mjs";
import "vue";
import "/app/node_modules/ofetch/dist/node.mjs";
import "#internal/nuxt/paths";
@@ -11,10 +10,12 @@ import "/app/node_modules/defu/dist/defu.mjs";
import "vue-router";
import "/app/node_modules/ufo/dist/index.mjs";
import "/app/node_modules/klona/dist/index.mjs";
import "vue/server-renderer";
import "/app/node_modules/cookie-es/dist/index.mjs";
import "/app/node_modules/destr/dist/index.mjs";
import "/app/node_modules/ohash/dist/index.mjs";
import "/app/node_modules/@unhead/vue/dist/index.mjs";
import "@vue/devtools-api";
import "vue/server-renderer";
const auth = defineNuxtRouteMiddleware((to, from) => {
if (to.path === "/login") {
return;
@@ -27,4 +28,4 @@ const auth = defineNuxtRouteMiddleware((to, from) => {
export {
auth as default
};
//# sourceMappingURL=auth-D_CY0lMs.js.map
//# sourceMappingURL=auth-BgwR5zMA.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"auth-D_CY0lMs.js","sources":["../../../../middleware/auth.ts"],"sourcesContent":["export default defineNuxtRouteMiddleware((to, from) => {\n // Skip auth check on the login page itself\n if (to.path === '/login') {\n return\n }\n\n // Check for the access_token cookie\n const tokenCookie = useCookie('access_token')\n if (!tokenCookie.value) {\n return navigateTo('/login')\n }\n\n // If the store is already initialized, check isAuthenticated\n // Otherwise, the token cookie presence is sufficient for the guard\n // The store's init() will validate the token on app mount\n})\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,MAAA,OAAe,0BAA0B,CAAC,IAAI,SAAS;AAErD,MAAI,GAAG,SAAS,UAAU;AACxB;AAAA,EACF;AAGA,QAAM,cAAc,UAAU,cAAc;AAC5C,MAAI,CAAC,YAAY,OAAO;AACtB,WAAO,WAAW,QAAQ;AAAA,EAC5B;AAKF,CAAC;"}
{"version":3,"file":"auth-BgwR5zMA.js","sources":["../../../../middleware/auth.ts"],"sourcesContent":["export default defineNuxtRouteMiddleware((to, from) => {\n // Skip auth check on the login page itself\n if (to.path === '/login') {\n return\n }\n\n // Check for the access_token cookie\n const tokenCookie = useCookie('access_token')\n if (!tokenCookie.value) {\n return navigateTo('/login')\n }\n\n // If the store is already initialized, check isAuthenticated\n // Otherwise, the token cookie presence is sufficient for the guard\n // The store's init() will validate the token on app mount\n})\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,MAAA,OAAe,0BAA0B,CAAC,IAAI,SAAS;AAErD,MAAI,GAAG,SAAS,UAAU;AACxB;AAAA,EACF;AAGA,QAAM,cAAc,UAAU,cAAc;AAC5C,MAAI,CAAC,YAAY,OAAO;AACtB,WAAO,WAAW,QAAQ;AAAA,EAC5B;AAKF,CAAC;"}

View File

@@ -0,0 +1 @@
{"file":"auth-BgwR5zMA.js","mappings":";;;;;;;;;;;;;;;;;;AAAA,MAAA,OAAe,0BAA0B,CAAC,IAAI,SAAS;AAErD,MAAI,GAAG,SAAS,UAAU;AACxB;AAAA,EACF;AAGA,QAAM,cAAc,UAAU,cAAc;AAC5C,MAAI,CAAC,YAAY,OAAO;AACtB,WAAO,WAAW,QAAQ;AAAA,EAC5B;AAKF,CAAC;","names":[],"sources":["../../../../middleware/auth.ts"],"sourcesContent":["export default defineNuxtRouteMiddleware((to, from) => {\n // Skip auth check on the login page itself\n if (to.path === '/login') {\n return\n }\n\n // Check for the access_token cookie\n const tokenCookie = useCookie('access_token')\n if (!tokenCookie.value) {\n return navigateTo('/login')\n }\n\n // If the store is already initialized, check isAuthenticated\n // Otherwise, the token cookie presence is sufficient for the guard\n // The store's init() will validate the token on app mount\n})\n"],"version":3}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"file":"auth-D_CY0lMs.js","mappings":";;;;;;;;;;;;;;;;;AAAA,MAAA,OAAe,0BAA0B,CAAC,IAAI,SAAS;AAErD,MAAI,GAAG,SAAS,UAAU;AACxB;AAAA,EACF;AAGA,QAAM,cAAc,UAAU,cAAc;AAC5C,MAAI,CAAC,YAAY,OAAO;AACtB,WAAO,WAAW,QAAQ;AAAA,EAC5B;AAKF,CAAC;","names":[],"sources":["../../../../middleware/auth.ts"],"sourcesContent":["export default defineNuxtRouteMiddleware((to, from) => {\n // Skip auth check on the login page itself\n if (to.path === '/login') {\n return\n }\n\n // Check for the access_token cookie\n const tokenCookie = useCookie('access_token')\n if (!tokenCookie.value) {\n return navigateTo('/login')\n }\n\n // If the store is already initialized, check isAuthenticated\n // Otherwise, the token cookie presence is sufficient for the guard\n // The store's init() will validate the token on app mount\n})\n"],"version":3}

View File

@@ -1,8 +1,6 @@
import { publicAssetsURL } from "#internal/nuxt/paths";
import { defineStore } from "pinia";
import { ref, computed } from "vue";
import { u as useCookie } from "./cookie-CWIsZYm7.js";
const _imports_0 = publicAssetsURL("/sf_logo.png");
import { b as useCookie } from "../server.mjs";
const useAuthStore = defineStore("auth", () => {
const user = ref(null);
const token = ref(null);
@@ -113,7 +111,6 @@ const useAuthStore = defineStore("auth", () => {
};
});
export {
_imports_0 as _,
useAuthStore as u
};
//# sourceMappingURL=auth-CRAMW6e4.js.map
//# sourceMappingURL=auth-mCjBoLcA.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,79 +0,0 @@
import { ref } from "vue";
import { parse } from "/app/node_modules/cookie-es/dist/index.mjs";
import { getRequestHeader, setCookie, getCookie, deleteCookie } from "/app/node_modules/h3/dist/index.mjs";
import destr from "/app/node_modules/destr/dist/index.mjs";
import { isEqual } from "/app/node_modules/ohash/dist/index.mjs";
import { klona } from "/app/node_modules/klona/dist/index.mjs";
import { a as useNuxtApp } from "../server.mjs";
function useRequestEvent(nuxtApp) {
nuxtApp ||= useNuxtApp();
return nuxtApp.ssrContext?.event;
}
const CookieDefaults = {
path: "/",
watch: true,
decode: (val) => {
const decoded = decodeURIComponent(val);
const parsed = destr(decoded);
if (typeof parsed === "number" && (!Number.isFinite(parsed) || String(parsed) !== decoded)) {
return decoded;
}
return parsed;
},
encode: (val) => encodeURIComponent(typeof val === "string" ? val : JSON.stringify(val))
};
function useCookie(name, _opts) {
const opts = { ...CookieDefaults, ..._opts };
opts.filter ??= (key) => key === name;
const cookies = readRawCookies(opts) || {};
let delay;
if (opts.maxAge !== void 0) {
delay = opts.maxAge * 1e3;
} else if (opts.expires) {
delay = opts.expires.getTime() - Date.now();
}
const hasExpired = delay !== void 0 && delay <= 0;
const cookieValue = klona(hasExpired ? void 0 : cookies[name] ?? opts.default?.());
const cookie = ref(cookieValue);
{
const nuxtApp = useNuxtApp();
const writeFinalCookieValue = () => {
if (opts.readonly || isEqual(cookie.value, cookies[name])) {
return;
}
nuxtApp._cookies ||= {};
if (name in nuxtApp._cookies) {
if (isEqual(cookie.value, nuxtApp._cookies[name])) {
return;
}
}
nuxtApp._cookies[name] = cookie.value;
writeServerCookie(useRequestEvent(nuxtApp), name, cookie.value, opts);
};
const unhook = nuxtApp.hooks.hookOnce("app:rendered", writeFinalCookieValue);
nuxtApp.hooks.hookOnce("app:error", () => {
unhook();
return writeFinalCookieValue();
});
}
return cookie;
}
function readRawCookies(opts = {}) {
{
return parse(getRequestHeader(useRequestEvent(), "cookie") || "", opts);
}
}
function writeServerCookie(event, name, value, opts = {}) {
if (event) {
if (value !== null && value !== void 0) {
return setCookie(event, name, value, opts);
}
if (getCookie(event, name) !== void 0) {
return deleteCookie(event, name, opts);
}
}
}
export {
useCookie as u
};
//# sourceMappingURL=cookie-CWIsZYm7.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,22 +1,25 @@
import { _ as __nuxt_component_0 } from "./nuxt-link-DNVrgHUL.js";
import { defineComponent, ref, computed, mergeProps, withCtx, createVNode, toDisplayString, withDirectives, vShow, openBlock, createBlock, createTextVNode, useSSRContext } from "vue";
import { ssrRenderAttrs, ssrRenderClass, ssrRenderAttr, ssrRenderList, ssrInterpolate, ssrRenderStyle, ssrRenderComponent, ssrRenderSlot } from "vue/server-renderer";
import { u as useAuthStore, _ as _imports_0 } from "./auth-CRAMW6e4.js";
import { _ as __nuxt_component_0 } from "./nuxt-link-Cp-CAJwR.js";
import { defineComponent, computed, ref, mergeProps, withCtx, createVNode, toDisplayString, openBlock, createBlock, createTextVNode, useSSRContext } from "vue";
import { ssrRenderAttrs, ssrRenderClass, ssrRenderComponent, ssrRenderAttr, ssrRenderList, ssrRenderStyle, ssrInterpolate, ssrRenderSlot } from "vue/server-renderer";
import { publicAssetsURL } from "#internal/nuxt/paths";
import { useRoute } from "vue-router";
import { u as useRouter } from "../server.mjs";
import { u as useRegionStore } from "./region-0mvXqaMM.js";
import { a as useRouter, c as useI18n } from "../server.mjs";
import { u as useAuthStore } from "./auth-mCjBoLcA.js";
import "/app/node_modules/klona/dist/index.mjs";
import "/app/node_modules/hookable/dist/index.mjs";
import "/app/node_modules/ufo/dist/index.mjs";
import "/app/node_modules/defu/dist/defu.mjs";
import "#internal/nuxt/paths";
import "pinia";
import "./cookie-CWIsZYm7.js";
import "/app/node_modules/cookie-es/dist/index.mjs";
import "/app/node_modules/ofetch/dist/node.mjs";
import "/app/node_modules/unctx/dist/index.mjs";
import "/app/node_modules/h3/dist/index.mjs";
import "/app/node_modules/cookie-es/dist/index.mjs";
import "/app/node_modules/destr/dist/index.mjs";
import "/app/node_modules/ohash/dist/index.mjs";
import "/app/node_modules/klona/dist/index.mjs";
import "/app/node_modules/ofetch/dist/node.mjs";
import "/app/node_modules/hookable/dist/index.mjs";
import "/app/node_modules/unctx/dist/index.mjs";
import "/app/node_modules/@unhead/vue/dist/index.mjs";
import "@vue/devtools-api";
const _imports_0 = publicAssetsURL("/logo.svg");
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "default",
__ssrInlineRender: true,
@@ -24,6 +27,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
const route = useRoute();
useRouter();
const authStore = useAuthStore();
useRegionStore();
const { locale, locales } = useI18n();
const availableLocales = computed(() => locales.value);
const currentLocale = computed(() => locale.value);
const sidebarOpen = ref(false);
const sidebarCollapsed = ref(false);
const dropdownOpen = ref(false);
@@ -73,6 +80,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
}
]
},
{
title: "Pénzügyek",
items: [
{
path: "/packages",
label: "Csomagok",
icon: '<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5m8.25 3v6.75m0 0l-3-3m3 3l3-3M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" /></svg>'
}
]
},
{
title: "Rendszer",
items: [
@@ -101,6 +118,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
if (route.path.startsWith("/garages")) return "Garázsok";
if (route.path.startsWith("/users")) return "Felhasználók";
if (route.path.startsWith("/logs")) return "Rendszernaplók";
if (route.path.startsWith("/packages")) return "Csomagok";
return "Admin Panel";
});
function isActive(path) {
@@ -120,27 +138,47 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
_push(`<!---->`);
}
_push(`<aside class="${ssrRenderClass([
"fixed lg:static inset-y-0 left-0 z-30 flex flex-col bg-slate-800 border-r border-slate-700 transition-all duration-300",
sidebarOpen.value ? "w-64 translate-x-0" : "-translate-x-full lg:translate-x-0 lg:w-20"
])}"><div class="flex items-center h-16 px-4 border-b border-slate-700">`);
if (sidebarOpen.value || !sidebarCollapsed.value) {
_push(`<div class="flex items-center gap-3"><img${ssrRenderAttr("src", _imports_0)} class="h-8 w-auto" alt="SF Logo"><span class="text-lg font-bold text-white whitespace-nowrap">Admin Panel</span></div>`);
} else {
_push(`<div class="mx-auto"><img${ssrRenderAttr("src", _imports_0)} class="h-8 w-auto" alt="SF Logo"></div>`);
}
_push(`</div><button class="hidden lg:flex items-center justify-center h-10 mx-2 mt-2 rounded-lg text-slate-400 hover:text-white hover:bg-slate-700 transition"><svg class="${ssrRenderClass([{ "rotate-180": sidebarCollapsed.value }, "w-5 h-5 transition-transform duration-300"])}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 19l-7-7 7-7m8 14l-7-7 7-7"></path></svg></button><nav class="flex-1 px-2 py-4 space-y-2 overflow-y-auto"><!--[-->`);
"fixed lg:static inset-y-0 left-0 z-30 flex flex-col bg-slate-800 border-r border-slate-700 transition-all duration-300 ease-in-out overflow-hidden",
sidebarOpen.value || !sidebarCollapsed.value ? "w-52" : "w-20"
])}">`);
_push(ssrRenderComponent(_component_NuxtLink, {
to: "/",
class: "flex items-center h-16 px-4 border-b border-slate-700 overflow-hidden hover:bg-slate-700/50 transition"
}, {
default: withCtx((_, _push2, _parent2, _scopeId) => {
if (_push2) {
_push2(`<div class="flex items-center gap-3 min-w-0"${_scopeId}><img${ssrRenderAttr("src", _imports_0)} class="h-8 w-auto flex-shrink-0" alt="SF Logo"${_scopeId}><div class="${ssrRenderClass([sidebarOpen.value || !sidebarCollapsed.value ? "opacity-100 max-w-[200px]" : "opacity-0 max-w-0", "transition-all duration-300 ease-in-out overflow-hidden whitespace-nowrap"])}"${_scopeId}><div class="text-sm font-bold text-white leading-tight"${_scopeId}>Service Finder</div><div class="text-[10px] font-semibold uppercase tracking-wider text-indigo-400 leading-tight"${_scopeId}>Admin</div></div></div>`);
} else {
return [
createVNode("div", { class: "flex items-center gap-3 min-w-0" }, [
createVNode("img", {
src: _imports_0,
class: "h-8 w-auto flex-shrink-0",
alt: "SF Logo"
}),
createVNode("div", {
class: ["transition-all duration-300 ease-in-out overflow-hidden whitespace-nowrap", sidebarOpen.value || !sidebarCollapsed.value ? "opacity-100 max-w-[200px]" : "opacity-0 max-w-0"]
}, [
createVNode("div", { class: "text-sm font-bold text-white leading-tight" }, "Service Finder"),
createVNode("div", { class: "text-[10px] font-semibold uppercase tracking-wider text-indigo-400 leading-tight" }, "Admin")
], 2)
])
];
}
}),
_: 1
}, _parent));
_push(`<button class="hidden lg:flex items-center justify-center h-10 mx-2 mt-2 rounded-lg text-slate-400 hover:text-white hover:bg-slate-700 transition flex-shrink-0"><svg class="${ssrRenderClass([{ "rotate-180": sidebarCollapsed.value }, "w-5 h-5 transition-transform duration-300"])}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 19l-7-7 7-7m8 14l-7-7 7-7"></path></svg></button><nav class="flex-1 px-2 py-4 space-y-2 overflow-y-auto overflow-x-hidden"><!--[-->`);
ssrRenderList(menuGroups, (group) => {
_push(`<!--[-->`);
if (!sidebarCollapsed.value || sidebarOpen.value) {
_push(`<div class="px-3 py-1 text-xs font-semibold uppercase tracking-wider text-slate-500">${ssrInterpolate(group.title)}</div>`);
} else {
_push(`<!---->`);
}
_push(`<!--[-->`);
_push(`<!--[--><div class="px-3 py-1 text-xs font-semibold uppercase tracking-wider text-slate-500 whitespace-nowrap overflow-hidden" style="${ssrRenderStyle(sidebarOpen.value || !sidebarCollapsed.value ? null : { display: "none" })}">${ssrInterpolate(group.title)}</div><!--[-->`);
ssrRenderList(group.items, (item) => {
_push(`<!--[-->`);
if (item.children) {
_push(`<div><button class="${ssrRenderClass([isGroupActive(item) ? "bg-indigo-600/20 text-indigo-300" : "text-slate-300 hover:bg-slate-700 hover:text-white", "flex items-center w-full gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition"])}"><span class="flex-shrink-0 w-5 h-5">${item.icon ?? ""}</span><span class="flex-1 text-left whitespace-nowrap" style="${ssrRenderStyle(!sidebarCollapsed.value || sidebarOpen.value ? null : { display: "none" })}">${ssrInterpolate(item.label)}</span><svg class="${ssrRenderClass([{ "rotate-90": expandedGroups.value.has(item.label) }, "w-4 h-4 transition-transform duration-200"])}" fill="none" stroke="currentColor" viewBox="0 0 24 24" style="${ssrRenderStyle(!sidebarCollapsed.value || sidebarOpen.value ? null : { display: "none" })}"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg></button><div class="ml-2 mt-1 space-y-1 overflow-hidden transition-all duration-200" style="${ssrRenderStyle(expandedGroups.value.has(item.label) && (!sidebarCollapsed.value || sidebarOpen.value) ? null : { display: "none" })}"><!--[-->`);
_push(`<div><button class="${ssrRenderClass([isGroupActive(item) ? "bg-indigo-600/20 text-indigo-300" : "text-slate-300 hover:bg-slate-700 hover:text-white", "flex items-center w-full gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition"])}"><span class="flex-shrink-0 w-5 h-5">${item.icon ?? ""}</span><span class="${ssrRenderClass([sidebarOpen.value || !sidebarCollapsed.value ? "opacity-100 max-w-[200px]" : "opacity-0 max-w-0", "flex-1 text-left whitespace-nowrap overflow-hidden transition-all duration-300 ease-in-out"])}">${ssrInterpolate(item.label)}</span><svg class="${ssrRenderClass([{
"rotate-90": expandedGroups.value.has(item.label),
"opacity-100": sidebarOpen.value || !sidebarCollapsed.value,
"opacity-0": sidebarCollapsed.value && !sidebarOpen.value
}, "w-4 h-4 transition-all duration-300 ease-in-out flex-shrink-0"])}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg></button><div class="ml-2 mt-1 space-y-1 overflow-hidden transition-all duration-200" style="${ssrRenderStyle(expandedGroups.value.has(item.label) && (sidebarOpen.value || !sidebarCollapsed.value) ? null : { display: "none" })}"><!--[-->`);
ssrRenderList(item.children, (child) => {
_push(ssrRenderComponent(_component_NuxtLink, {
key: child.path,
@@ -150,14 +188,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
}, {
default: withCtx((_, _push2, _parent2, _scopeId) => {
if (_push2) {
_push2(`<span class="flex-shrink-0 w-4 h-4"${_scopeId}>${child.icon ?? ""}</span><span class="whitespace-nowrap"${_scopeId}>${ssrInterpolate(child.label)}</span>`);
_push2(`<span class="flex-shrink-0 w-4 h-4"${_scopeId}>${child.icon ?? ""}</span><span class="whitespace-nowrap overflow-hidden"${_scopeId}>${ssrInterpolate(child.label)}</span>`);
} else {
return [
createVNode("span", {
class: "flex-shrink-0 w-4 h-4",
innerHTML: child.icon
}, null, 8, ["innerHTML"]),
createVNode("span", { class: "whitespace-nowrap" }, toDisplayString(child.label), 1)
createVNode("span", { class: "whitespace-nowrap overflow-hidden" }, toDisplayString(child.label), 1)
];
}
}),
@@ -173,16 +211,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
}, {
default: withCtx((_, _push2, _parent2, _scopeId) => {
if (_push2) {
_push2(`<span class="flex-shrink-0 w-5 h-5"${_scopeId}>${item.icon ?? ""}</span><span class="whitespace-nowrap" style="${ssrRenderStyle(!sidebarCollapsed.value || sidebarOpen.value ? null : { display: "none" })}"${_scopeId}>${ssrInterpolate(item.label)}</span>`);
_push2(`<span class="flex-shrink-0 w-5 h-5"${_scopeId}>${item.icon ?? ""}</span><span class="${ssrRenderClass([sidebarOpen.value || !sidebarCollapsed.value ? "opacity-100 max-w-[200px]" : "opacity-0 max-w-0", "whitespace-nowrap overflow-hidden transition-all duration-300 ease-in-out"])}"${_scopeId}>${ssrInterpolate(item.label)}</span>`);
} else {
return [
createVNode("span", {
class: "flex-shrink-0 w-5 h-5",
innerHTML: item.icon
}, null, 8, ["innerHTML"]),
withDirectives(createVNode("span", { class: "whitespace-nowrap" }, toDisplayString(item.label), 513), [
[vShow, !sidebarCollapsed.value || sidebarOpen.value]
])
createVNode("span", {
class: ["whitespace-nowrap overflow-hidden transition-all duration-300 ease-in-out", sidebarOpen.value || !sidebarCollapsed.value ? "opacity-100 max-w-[200px]" : "opacity-0 max-w-0"]
}, toDisplayString(item.label), 3)
];
}
}),
@@ -193,13 +231,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
});
_push(`<!--]--><!--]-->`);
});
_push(`<!--]--></nav><div class="p-4 border-t border-slate-700">`);
if (!sidebarCollapsed.value || sidebarOpen.value) {
_push(`<div class="text-xs text-slate-500"> ServiceFinder v2.0 </div>`);
} else {
_push(`<!---->`);
}
_push(`</div></aside><div class="flex-1 flex flex-col min-w-0"><header class="sticky top-0 z-10 bg-slate-800/95 backdrop-blur-sm border-b border-slate-700"><div class="flex items-center justify-between h-16 px-4 lg:px-6"><div class="flex items-center gap-3"><button class="lg:hidden p-2 rounded-lg text-slate-400 hover:text-white hover:bg-slate-700 transition"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg></button><h1 class="text-lg font-semibold text-white truncate">${ssrInterpolate(pageTitle.value)}</h1></div><div class="relative"><button class="flex items-center gap-2 p-1.5 rounded-lg hover:bg-slate-700 transition"><div class="w-8 h-8 rounded-full bg-indigo-600 flex items-center justify-center text-sm font-bold text-white">${ssrInterpolate(userInitials.value)}</div><span class="hidden sm:block text-sm text-slate-300">${ssrInterpolate(userEmail.value)}</span><svg class="w-4 h-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg></button>`);
_push(`<!--]--></nav><div class="p-4 border-t border-slate-700 overflow-hidden"><div class="${ssrRenderClass([sidebarOpen.value || !sidebarCollapsed.value ? "opacity-100 max-w-[200px]" : "opacity-0 max-w-0", "text-xs text-slate-500 whitespace-nowrap transition-all duration-300 ease-in-out"])}"> ServiceFinder v2.0 </div></div></aside><div class="flex-1 flex flex-col min-w-0 transition-all duration-300 ease-in-out"><header class="sticky top-0 z-10 bg-slate-800/95 backdrop-blur-sm border-b border-slate-700"><div class="flex items-center justify-between h-16 px-4 lg:px-6"><div class="flex items-center gap-3"><button class="lg:hidden p-2 rounded-lg text-slate-400 hover:text-white hover:bg-slate-700 transition"><svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg></button><h1 class="text-lg font-semibold text-white truncate">${ssrInterpolate(pageTitle.value)}</h1></div><div class="flex items-center gap-3"><div class="flex items-center bg-slate-700/50 rounded-lg p-0.5"><!--[-->`);
ssrRenderList(availableLocales.value, (locale2) => {
_push(`<button class="${ssrRenderClass([currentLocale.value === locale2.code ? "bg-indigo-600 text-white shadow-sm" : "text-slate-400 hover:text-white", "px-2.5 py-1 text-xs font-medium rounded-md transition"])}">${ssrInterpolate(locale2.code === "hu" ? "HU" : "EN")}</button>`);
});
_push(`<!--]--></div><div class="relative"><button class="flex items-center gap-2 p-1.5 rounded-lg hover:bg-slate-700 transition"><div class="w-8 h-8 rounded-full bg-indigo-600 flex items-center justify-center text-sm font-bold text-white">${ssrInterpolate(userInitials.value)}</div><span class="hidden sm:block text-sm text-slate-300">${ssrInterpolate(userEmail.value)}</span><svg class="w-4 h-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg></button>`);
if (dropdownOpen.value) {
_push(`<div class="absolute right-0 mt-2 w-56 bg-slate-800 border border-slate-700 rounded-xl shadow-xl py-1 z-50"><div class="px-4 py-3 border-b border-slate-700"><p class="text-sm font-medium text-white">${ssrInterpolate(userEmail.value)}</p><p class="text-xs text-slate-400 mt-0.5">Administrator</p></div>`);
_push(ssrRenderComponent(_component_NuxtLink, {
@@ -235,7 +271,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
} else {
_push(`<!---->`);
}
_push(`</div></div></header><main class="flex-1 p-4 lg:p-6 overflow-auto">`);
_push(`</div></div></div></header><main class="flex-1 p-4 lg:p-6 overflow-auto">`);
ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent);
_push(`</main></div></div>`);
};
@@ -250,4 +286,4 @@ _sfc_main.setup = (props, ctx) => {
export {
_sfc_main as default
};
//# sourceMappingURL=default-DbJQlxCD.js.map
//# sourceMappingURL=default-B9tlXlqE.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,116 @@
const resource = {
"permissions": {
"title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Permissions Management" } },
"subtitle": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Permissions Management — Role-based access control & subscription feature flags" } },
"loading": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Loading permissions data..." } },
"error_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Failed to load permissions" } },
"retry": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Retry" } },
"save_changes": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Save Changes" } },
"discard": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Discard" } },
"modified_count": { "t": 0, "b": { "t": 2, "i": [{ "t": 4, "k": "count" }, { "t": 3, "v": " modification(s)" }] } },
"current_tier": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Current Tier" } },
"expires": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Expires" } },
"superadmin": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Superadmin" } },
"superadmin_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Full system access — user management, billing, robots, and system configuration." } },
"garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Garages" } },
"garages_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Garage-level access — vehicle management, service booking, customer data." } },
"feature_flags": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Feature Flags" } },
"feature_flags_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3, "v": "Subscription feature toggles — resolved from your current tier (" }, { "t": 4, "k": "tier" }, { "t": 3, "v": ")." }] } },
"rbac_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "RBAC Permission Matrix" } },
"rbac_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Role-based access control — which roles can perform which admin actions." } },
"action": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Action" } },
"perms": {
"user_mgmt": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "User Management" } },
"billing_admin": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Billing Administration" } },
"robot_config": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Robot Configuration" } },
"system_logs": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "System Logs Access" } },
"api_keys": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "API Key Management" } },
"vehicle_crud": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Vehicle CRUD" } },
"service_booking": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Service Booking" } },
"customer_view": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Customer Data View" } },
"report_export": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Report Export" } },
"bulk_import": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Bulk Import" } }
}
},
"packages": {
"title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Package Management" } },
"subtitle": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Manage subscription packages and feature flags — Free, Premium, Enterprise" } },
"loading": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Loading packages..." } },
"retry": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Retry" } },
"create_new": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Create Package" } },
"no_packages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "No packages yet" } },
"no_packages_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Create your first subscription package to get started." } },
"create_first": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Create First Package" } },
"popular": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Popular" } },
"fallback_badge": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Fallback" } },
"trial_badge": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Trial" } },
"month": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "month" } },
"feature_flags": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Available Features" } },
"edit": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Edit" } },
"delete": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Delete" } },
"set_as_default": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Set as default" } },
"set_as_default_success": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "set as default package!" } },
"edit_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Edit Package" } },
"create_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Create Package" } },
"cancel": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Cancel" } },
"save": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Save Changes" } },
"create": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Create" } },
"save_success": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Package updated successfully!" } },
"delete_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Delete Package" } },
"delete_confirm": { "t": 0, "b": { "t": 2, "i": [{ "t": 3, "v": 'Are you sure you want to delete "' }, { "t": 4, "k": "name" }, { "t": 3, "v": '"?' }] } },
"delete_btn": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Delete" } },
"allowances": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Allowances" } },
"max_vehicles": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Max Vehicles" } },
"max_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Max Garages" } },
"monthly_credits": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Monthly Credits" } },
"tier_level": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Tier Level" } },
"form_name": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "System Name" } },
"form_name_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "e.g. premium_2024" } },
"form_display_name": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Display Name" } },
"form_display_name_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "e.g. Premium Plus" } },
"form_type": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Type" } },
"type_private": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Private" } },
"type_corporate": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Corporate" } },
"form_tier_level": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Tier Level" } },
"form_tier_level_hint": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Higher number = more features & higher rank" } },
"form_monthly_price": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Monthly Price" } },
"form_yearly_price": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Yearly Price" } },
"form_currency": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Currency" } },
"form_subtitle": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Subtitle / Description" } },
"form_subtitle_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "e.g. Best for small businesses" } },
"form_badge": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Badge Text" } },
"form_badge_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "e.g. Most Popular" } },
"form_is_custom": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Custom Package (not publicly listed)" } },
"singleton_rules": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Singleton Rules" } },
"form_is_default_fallback": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Default Fallback Package — assigned when a subscription expires" } },
"form_trial_days": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Trial Days on Signup" } },
"form_trial_days_hint": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "New organizations get this many free days. Only one package can have trial > 0." } }
},
"garages": {
"title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Garages CRM" } },
"subtitle": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Garage list, package management and status changes" } },
"total_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Total Garages" } },
"active_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Active Garages" } },
"premium_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Premium Garages" } },
"enterprise_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Enterprise Garages" } },
"search_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Search by name, contact or email..." } },
"all_tiers": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "All packages" } },
"company_name": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Company Name" } },
"email": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Email" } },
"status": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Status" } },
"current_package": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Current Package" } },
"actions": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Actions" } },
"active": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Active" } },
"inactive": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Inactive" } },
"suspended": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Suspended" } },
"change_package": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Change Package" } },
"view": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "View" } },
"activate": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Activate" } },
"deactivate": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Deactivate" } },
"no_results": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "No garages match your search." } }
}
};
export {
resource as default
};
//# sourceMappingURL=en-BScPj1A-.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"en-BScPj1A-.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1 @@
{"file":"en-BScPj1A-.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","names":[],"sources":[],"sourcesContent":[],"version":3}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"entry-styles-1.mjs-CF-ChPYj.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}

View File

@@ -1 +0,0 @@
{"file":"entry-styles-1.mjs-CF-ChPYj.js","mappings":";","names":[],"sources":[],"sourcesContent":[],"version":3}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"entry-styles-1.mjs-DTfYoqFp.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}

View File

@@ -0,0 +1 @@
{"file":"entry-styles-1.mjs-DTfYoqFp.js","mappings":";","names":[],"sources":[],"sourcesContent":[],"version":3}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"entry-styles-2.mjs-CM2W3GZ1.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}

View File

@@ -0,0 +1 @@
{"file":"entry-styles-2.mjs-CM2W3GZ1.js","mappings":";","names":[],"sources":[],"sourcesContent":[],"version":3}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"entry-styles-2.mjs-CntxBZab.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}

View File

@@ -1 +0,0 @@
{"file":"entry-styles-2.mjs-CntxBZab.js","mappings":";","names":[],"sources":[],"sourcesContent":[],"version":3}

View File

@@ -1,8 +0,0 @@
import style_0 from "./entry-styles-1.mjs-CF-ChPYj.js";
import style_1 from "./entry-styles-2.mjs-CntxBZab.js";
import style_2 from "./entry-styles-3.mjs-C1rWf53M.js";
export default [
style_0,
style_1,
style_2
]

View File

@@ -0,0 +1,8 @@
import style_0 from "./entry-styles-1.mjs-DTfYoqFp.js";
import style_1 from "./entry-styles-2.mjs-CM2W3GZ1.js";
import style_2 from "./entry-styles-3.mjs-C1rWf53M.js";
export default [
style_0,
style_1,
style_2
]

File diff suppressed because one or more lines are too long

View File

@@ -1,8 +1,7 @@
import { _ as __nuxt_component_0 } from "./nuxt-link-DNVrgHUL.js";
import { _ as __nuxt_component_0 } from "./nuxt-link-Cp-CAJwR.js";
import { mergeProps, withCtx, createTextVNode, toDisplayString, useSSRContext } from "vue";
import { ssrRenderAttrs, ssrInterpolate, ssrRenderComponent } from "vue/server-renderer";
import { _ as _export_sfc } from "../server.mjs";
import { u as useHead } from "./v3-DnDMBKvA.js";
import { _ as _export_sfc, u as useHead } from "../server.mjs";
import "/app/node_modules/ufo/dist/index.mjs";
import "/app/node_modules/defu/dist/defu.mjs";
import "/app/node_modules/ofetch/dist/node.mjs";
@@ -13,7 +12,11 @@ import "/app/node_modules/h3/dist/index.mjs";
import "pinia";
import "vue-router";
import "/app/node_modules/klona/dist/index.mjs";
import "/app/node_modules/cookie-es/dist/index.mjs";
import "/app/node_modules/destr/dist/index.mjs";
import "/app/node_modules/ohash/dist/index.mjs";
import "/app/node_modules/@unhead/vue/dist/index.mjs";
import "@vue/devtools-api";
const _sfc_main = {
__name: "error-404",
__ssrInlineRender: true,
@@ -90,4 +93,4 @@ const error404 = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-1
export {
error404 as default
};
//# sourceMappingURL=error-404-BDmq62MM.js.map
//# sourceMappingURL=error-404-C_elhLNc.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,6 @@
import { mergeProps, useSSRContext } from "vue";
import { ssrRenderAttrs, ssrInterpolate } from "vue/server-renderer";
import { _ as _export_sfc } from "../server.mjs";
import { u as useHead } from "./v3-DnDMBKvA.js";
import { _ as _export_sfc, u as useHead } from "../server.mjs";
import "/app/node_modules/ofetch/dist/node.mjs";
import "#internal/nuxt/paths";
import "/app/node_modules/hookable/dist/index.mjs";
@@ -12,7 +11,11 @@ import "/app/node_modules/defu/dist/defu.mjs";
import "vue-router";
import "/app/node_modules/ufo/dist/index.mjs";
import "/app/node_modules/klona/dist/index.mjs";
import "/app/node_modules/cookie-es/dist/index.mjs";
import "/app/node_modules/destr/dist/index.mjs";
import "/app/node_modules/ohash/dist/index.mjs";
import "/app/node_modules/@unhead/vue/dist/index.mjs";
import "@vue/devtools-api";
const _sfc_main = {
__name: "error-500",
__ssrInlineRender: true,
@@ -68,4 +71,4 @@ const error500 = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a
export {
error500 as default
};
//# sourceMappingURL=error-500-gzzPk_-U.js.map
//# sourceMappingURL=error-500-C6MJq2Cl.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,116 @@
const resource = {
"permissions": {
"title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Jogosultság Kezelés" } },
"subtitle": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Permissions Management — Role-based access control & subscription feature flags" } },
"loading": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Jogosultságok betöltése..." } },
"error_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Nem sikerült betölteni a jogosultságokat" } },
"retry": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Újra" } },
"save_changes": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Változtatások Mentése" } },
"discard": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Elvetés" } },
"modified_count": { "t": 0, "b": { "t": 2, "i": [{ "t": 4, "k": "count" }, { "t": 3, "v": " módosítás" }] } },
"current_tier": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Aktuális Csomag" } },
"expires": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Lejárat" } },
"superadmin": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Superadmin" } },
"superadmin_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Teljes rendszer hozzáférés — felhasználók, számlázás, robotok és rendszerkonfiguráció." } },
"garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Garázsok" } },
"garages_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Garázs szintű hozzáférés — járműkezelés, szervizfoglalás, ügyféladatok." } },
"feature_flags": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Feature Flags" } },
"feature_flags_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3, "v": "Előfizetési funkciók — a jelenlegi csomagod alapján (" }, { "t": 4, "k": "tier" }, { "t": 3, "v": ")." }] } },
"rbac_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "RBAC Jogosultsági Mátrix" } },
"rbac_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Szerepkör alapú hozzáférés-vezérlés — mely szerepkörök mely admin műveleteket végezhetik." } },
"action": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Művelet" } },
"perms": {
"user_mgmt": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Felhasználókezelés" } },
"billing_admin": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Számlázási Adminisztráció" } },
"robot_config": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Robot Konfiguráció" } },
"system_logs": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Rendszernaplók Elérése" } },
"api_keys": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "API Kulcs Kezelés" } },
"vehicle_crud": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Jármű CRUD" } },
"service_booking": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Szervizfoglalás" } },
"customer_view": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Ügyféladatok Megtekintése" } },
"report_export": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Jelentés Exportálás" } },
"bulk_import": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Tömeges Import" } }
}
},
"packages": {
"title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Csomagok Kezelése" } },
"subtitle": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Előfizetési csomagok és funkciók kezelése — Free, Premium, Enterprise" } },
"loading": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Csomagok betöltése..." } },
"retry": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Újra" } },
"create_new": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Új Csomag" } },
"no_packages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Még nincsenek csomagok" } },
"no_packages_desc": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Hozd létre az első előfizetési csomagot a kezdéshez." } },
"create_first": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Első Csomag Létrehozása" } },
"popular": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Népszerű" } },
"fallback_badge": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Visszaesési" } },
"trial_badge": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Próba" } },
"month": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "hó" } },
"feature_flags": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Elérhető Funkciók" } },
"edit": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Szerkesztés" } },
"delete": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Törlés" } },
"set_as_default": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Beállítás alapértelmezettként" } },
"set_as_default_success": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "alapértelmezett csomagként beállítva!" } },
"edit_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Csomag Szerkesztése" } },
"create_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Csomag Létrehozása" } },
"cancel": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Mégse" } },
"save": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Változtatások Mentése" } },
"create": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Létrehozás" } },
"save_success": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Csomag sikeresen frissítve!" } },
"delete_title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Csomag Törlése" } },
"delete_confirm": { "t": 0, "b": { "t": 2, "i": [{ "t": 3, "v": 'Biztosan törölni szeretnéd a "' }, { "t": 4, "k": "name" }, { "t": 3, "v": '" csomagot?' }] } },
"delete_btn": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Törlés" } },
"allowances": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Korlátok" } },
"max_vehicles": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Max Jármű" } },
"max_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Max Garázs" } },
"monthly_credits": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Havi Kredit" } },
"tier_level": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Szint" } },
"form_name": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Rendszer Név" } },
"form_name_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "pl. premium_2024" } },
"form_display_name": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Megjelenítési Név" } },
"form_display_name_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "pl. Premium Plus" } },
"form_type": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Típus" } },
"type_private": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Magán" } },
"type_corporate": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Vállalati" } },
"form_tier_level": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Szintszám" } },
"form_tier_level_hint": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Magasabb szám = több funkció és magasabb rang" } },
"form_monthly_price": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Havi Díj" } },
"form_yearly_price": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Éves Díj" } },
"form_currency": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Pénznem" } },
"form_subtitle": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Felirat / Leírás" } },
"form_subtitle_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "pl. Ideális kisvállalkozásoknak" } },
"form_badge": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Jelvény Szöveg" } },
"form_badge_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "pl. Legnépszerűbb" } },
"form_is_custom": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Egyedi Csomag (nem publikus)" } },
"singleton_rules": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Egyediségi Szabályok" } },
"form_is_default_fallback": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Alapértelmezett Visszaesési Csomag — lejárt előfizetés esetén erre vált" } },
"form_trial_days": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Próba Napok Regisztrációnál" } },
"form_trial_days_hint": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Az új szervezetek ennyi ingyenes napot kapnak. Csak egy csomagnál lehet > 0." } }
},
"garages": {
"title": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Garázsok CRM" } },
"subtitle": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Garázsok listája, csomagkezelés és státuszmódosítás" } },
"total_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Összes Garázs" } },
"active_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Aktív Garázsok" } },
"premium_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Premium Garázsok" } },
"enterprise_garages": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Enterprise Garázsok" } },
"search_placeholder": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Keresés név, kapcsolattartó vagy e-mail alapján..." } },
"all_tiers": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Összes csomag" } },
"company_name": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Cégnév" } },
"email": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "E-mail" } },
"status": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Státusz" } },
"current_package": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Aktuális Csomag" } },
"actions": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Műveletek" } },
"active": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Aktív" } },
"inactive": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Inaktív" } },
"suspended": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Felfüggesztve" } },
"change_package": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Csomag Módosítása" } },
"view": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Megtekintés" } },
"activate": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Aktiválás" } },
"deactivate": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Deaktiválás" } },
"no_results": { "t": 0, "b": { "t": 2, "i": [{ "t": 3 }], "s": "Nincs a keresésnek megfelelő garázs." } }
}
};
export {
resource as default
};
//# sourceMappingURL=hu-CoGcC81v.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"hu-CoGcC81v.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1 @@
{"file":"hu-CoGcC81v.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","names":[],"sources":[],"sourcesContent":[],"version":3}

View File

@@ -0,0 +1,159 @@
import { defineComponent, ref, computed, useSSRContext } from "vue";
import { ssrRenderAttrs, ssrInterpolate, ssrRenderClass, ssrRenderList, ssrIncludeBooleanAttr } from "vue/server-renderer";
import "/app/node_modules/hookable/dist/index.mjs";
import "/app/node_modules/klona/dist/index.mjs";
import "../server.mjs";
import "/app/node_modules/ofetch/dist/node.mjs";
import "#internal/nuxt/paths";
import "/app/node_modules/unctx/dist/index.mjs";
import "/app/node_modules/h3/dist/index.mjs";
import "pinia";
import "/app/node_modules/defu/dist/defu.mjs";
import "vue-router";
import "/app/node_modules/ufo/dist/index.mjs";
import "/app/node_modules/cookie-es/dist/index.mjs";
import "/app/node_modules/destr/dist/index.mjs";
import "/app/node_modules/ohash/dist/index.mjs";
import "/app/node_modules/@unhead/vue/dist/index.mjs";
import "@vue/devtools-api";
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "index",
__ssrInlineRender: true,
setup(__props) {
const loading = ref(true);
const error = ref(null);
const featureFlags = ref({
tier: "free",
features: {},
expires_at: null
});
const permissionMatrix = ref([]);
const allActions = ref([]);
const modifiedPermissions = ref(/* @__PURE__ */ new Map());
ref(/* @__PURE__ */ new Map());
const saveNotification = ref(null);
const featureEntries = computed(() => {
return Object.entries(featureFlags.value.features || {});
});
const hasModifications = computed(() => {
return modifiedPermissions.value.size > 0;
});
const tierBadgeClass = computed(() => {
const tier = featureFlags.value.tier;
if (tier === "enterprise") return "bg-purple-500/20 text-purple-300";
if (tier === "premium") return "bg-amber-500/20 text-amber-300";
return "bg-slate-500/20 text-slate-300";
});
const superadminPerms = [
{ key: "user_mgmt", label: "User Management", enabled: true },
{ key: "billing_admin", label: "Billing Administration", enabled: true },
{ key: "robot_config", label: "Robot Configuration", enabled: true },
{ key: "system_logs", label: "System Logs Access", enabled: true },
{ key: "api_keys", label: "API Key Management", enabled: false }
];
const garagePerms = [
{ key: "vehicle_crud", label: "Vehicle CRUD", enabled: true },
{ key: "service_booking", label: "Service Booking", enabled: true },
{ key: "customer_view", label: "Customer Data View", enabled: true },
{ key: "report_export", label: "Report Export", enabled: false },
{ key: "bulk_import", label: "Bulk Import", enabled: false }
];
function isPermEnabled(group, key) {
const mapKey = `${group}:${key}`;
if (modifiedPermissions.value.has(mapKey)) {
return modifiedPermissions.value.get(mapKey);
}
const perms = group === "superadmin" ? superadminPerms : garagePerms;
const perm = perms.find((p) => p.key === key);
return perm ? perm.enabled : false;
}
function formatFeatureLabel(key) {
return key.replace(/^cost_category:/, "").replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
}
function formatDate(dateStr) {
try {
const d = new Date(dateStr);
return d.toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" });
} catch {
return dateStr;
}
}
function hasPermission(role, action) {
return role.actions.includes(action);
}
return (_ctx, _push, _parent, _attrs) => {
_push(`<div${ssrRenderAttrs(_attrs)}><div class="mb-8"><h1 class="text-2xl font-bold text-white">${ssrInterpolate(_ctx.$t("permissions.title"))}</h1><p class="text-slate-400 mt-1">${ssrInterpolate(_ctx.$t("permissions.subtitle"))}</p></div>`);
if (loading.value) {
_push(`<div class="flex items-center justify-center py-20"><svg class="animate-spin h-8 w-8 text-indigo-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg><span class="ml-3 text-slate-400">${ssrInterpolate(_ctx.$t("permissions.loading"))}</span></div>`);
} else if (error.value) {
_push(`<div class="bg-red-500/10 border border-red-500/20 rounded-xl p-6 mb-8"><div class="flex items-center gap-3"><svg class="w-6 h-6 text-red-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><div><h3 class="text-red-300 font-medium">${ssrInterpolate(_ctx.$t("permissions.error_title"))}</h3><p class="text-red-400/80 text-sm mt-1">${ssrInterpolate(error.value)}</p></div></div><button class="mt-4 px-4 py-2 text-sm bg-red-600 hover:bg-red-500 text-white rounded-lg transition">${ssrInterpolate(_ctx.$t("permissions.retry"))}</button></div>`);
} else {
_push(`<!--[-->`);
if (saveNotification.value) {
_push(`<div class="${ssrRenderClass([saveNotification.value.type === "success" ? "bg-emerald-500/10 border border-emerald-500/20 text-emerald-300" : "bg-red-500/10 border border-red-500/20 text-red-300", "mb-6 px-4 py-3 rounded-lg text-sm font-medium"])}">${ssrInterpolate(saveNotification.value.message)}</div>`);
} else {
_push(`<!---->`);
}
if (hasModifications.value) {
_push(`<div class="mb-6 flex items-center gap-3"><button class="px-6 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white font-semibold rounded-lg shadow-lg shadow-emerald-600/20 transition-all hover:scale-[1.02] active:scale-[0.98] flex items-center gap-2"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"></path></svg> ${ssrInterpolate(_ctx.$t("permissions.save_changes"))}</button><span class="text-sm text-slate-400">${ssrInterpolate(_ctx.$t("permissions.modified_count", { count: modifiedPermissions.value.size }))}</span></div>`);
} else {
_push(`<!---->`);
}
_push(`<div class="bg-indigo-500/10 border border-indigo-500/20 rounded-xl p-4 mb-8 flex items-start gap-3"><svg class="w-5 h-5 text-indigo-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><div class="text-sm text-indigo-300"><span class="font-semibold">${ssrInterpolate(_ctx.$t("permissions.current_tier"))}:</span><span class="${ssrRenderClass([tierBadgeClass.value, "ml-2 px-2 py-0.5 rounded-full text-xs font-medium"])}">${ssrInterpolate(featureFlags.value.tier || "free")}</span>`);
if (featureFlags.value.expires_at) {
_push(`<span class="ml-3 text-indigo-400/70">${ssrInterpolate(_ctx.$t("permissions.expires"))}: ${ssrInterpolate(formatDate(featureFlags.value.expires_at))}</span>`);
} else {
_push(`<!---->`);
}
_push(`</div></div><div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8"><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><div class="flex items-center gap-3 mb-4"><div class="p-2 rounded-lg bg-purple-500/10 text-purple-400"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z"></path></svg></div><h2 class="text-lg font-semibold text-white">${ssrInterpolate(_ctx.$t("permissions.superadmin"))}</h2></div><p class="text-sm text-slate-400 mb-4">${ssrInterpolate(_ctx.$t("permissions.superadmin_desc"))}</p><div class="space-y-3"><!--[-->`);
ssrRenderList(superadminPerms, (perm) => {
_push(`<div class="flex items-center justify-between py-2 border-b border-slate-700/50 last:border-0"><span class="text-sm text-slate-300">${ssrInterpolate(_ctx.$t(`permissions.perms.${perm.key}`))}</span><label class="relative inline-flex items-center cursor-pointer"><input type="checkbox"${ssrIncludeBooleanAttr(isPermEnabled("superadmin", perm.key)) ? " checked" : ""} class="sr-only peer"><div class="w-9 h-5 bg-slate-600 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-purple-500/50 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[&#39;&#39;] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-purple-600"></div></label></div>`);
});
_push(`<!--]--></div></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><div class="flex items-center gap-3 mb-4"><div class="p-2 rounded-lg bg-cyan-500/10 text-cyan-400"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h1.125c.621 0 1.129-.504 1.09-1.124a17.902 17.902 0 00-3.213-9.193 2.056 2.056 0 00-1.58-.86H14.25M16.5 18.75h-2.25m0-11.177v-.958c0-.568-.422-1.048-.987-1.106a48.554 48.554 0 00-10.026 0 1.106 1.106 0 00-.987 1.106v7.635m12-6.677v6.677m0 4.5v-4.5m0 0h-12"></path></svg></div><h2 class="text-lg font-semibold text-white">${ssrInterpolate(_ctx.$t("permissions.garages"))}</h2></div><p class="text-sm text-slate-400 mb-4">${ssrInterpolate(_ctx.$t("permissions.garages_desc"))}</p><div class="space-y-3"><!--[-->`);
ssrRenderList(garagePerms, (perm) => {
_push(`<div class="flex items-center justify-between py-2 border-b border-slate-700/50 last:border-0"><span class="text-sm text-slate-300">${ssrInterpolate(_ctx.$t(`permissions.perms.${perm.key}`))}</span><label class="relative inline-flex items-center cursor-pointer"><input type="checkbox"${ssrIncludeBooleanAttr(isPermEnabled("garage", perm.key)) ? " checked" : ""} class="sr-only peer"><div class="w-9 h-5 bg-slate-600 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-cyan-500/50 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[&#39;&#39;] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-cyan-600"></div></label></div>`);
});
_push(`<!--]--></div></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><div class="flex items-center gap-3 mb-4"><div class="p-2 rounded-lg bg-amber-500/10 text-amber-400"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5m8.25 3v6.75m0 0l-3-3m3 3l3-3M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z"></path></svg></div><h2 class="text-lg font-semibold text-white">${ssrInterpolate(_ctx.$t("permissions.feature_flags"))}</h2></div><p class="text-sm text-slate-400 mb-4">${ssrInterpolate(_ctx.$t("permissions.feature_flags_desc", { tier: featureFlags.value.tier || "free" }))}</p><div class="space-y-3"><!--[-->`);
ssrRenderList(featureEntries.value, ([key, granted]) => {
_push(`<div class="flex items-center justify-between py-2 border-b border-slate-700/50 last:border-0"><div class="flex flex-col"><span class="text-sm text-slate-300">${ssrInterpolate(formatFeatureLabel(key))}</span><span class="text-xs text-slate-500">${ssrInterpolate(key)}</span></div><label class="relative inline-flex items-center cursor-pointer"><input type="checkbox"${ssrIncludeBooleanAttr(granted) ? " checked" : ""} class="sr-only peer"${ssrIncludeBooleanAttr(true) ? " disabled" : ""}><div class="${ssrRenderClass([granted ? "peer-checked:bg-amber-600" : "", "w-9 h-5 bg-slate-600 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-amber-500/50 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all"])}"></div></label></div>`);
});
_push(`<!--]--></div></div></div><div class="bg-slate-800/50 border border-slate-700 rounded-xl p-6 mb-8"><h3 class="text-lg font-semibold text-white mb-4">${ssrInterpolate(_ctx.$t("permissions.rbac_title"))}</h3><p class="text-sm text-slate-400 mb-6">${ssrInterpolate(_ctx.$t("permissions.rbac_desc"))}</p><div class="overflow-x-auto"><table class="w-full text-sm"><thead><tr class="border-b border-slate-700"><th class="text-left py-3 px-4 text-slate-400 font-medium">${ssrInterpolate(_ctx.$t("permissions.action"))}</th><!--[-->`);
ssrRenderList(permissionMatrix.value, (role) => {
_push(`<th class="text-center py-3 px-4 text-slate-400 font-medium">${ssrInterpolate(role.role)}</th>`);
});
_push(`<!--]--></tr></thead><tbody><!--[-->`);
ssrRenderList(allActions.value, (action) => {
_push(`<tr class="border-b border-slate-700/50 hover:bg-slate-700/30"><td class="py-2.5 px-4 text-slate-300">${ssrInterpolate(action)}</td><!--[-->`);
ssrRenderList(permissionMatrix.value, (role) => {
_push(`<td class="text-center py-2.5 px-4">`);
if (hasPermission(role, action)) {
_push(`<span class="inline-flex items-center justify-center w-6 h-6 rounded-full bg-emerald-400/10"><svg class="w-4 h-4 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg></span>`);
} else {
_push(`<span class="inline-flex items-center justify-center w-6 h-6 rounded-full bg-slate-700"><svg class="w-4 h-4 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg></span>`);
}
_push(`</td>`);
});
_push(`<!--]--></tr>`);
});
_push(`<!--]--></tbody></table></div></div>`);
if (hasModifications.value) {
_push(`<div class="flex items-center gap-3 pb-8"><button class="px-6 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white font-semibold rounded-lg shadow-lg shadow-emerald-600/20 transition-all hover:scale-[1.02] active:scale-[0.98] flex items-center gap-2"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"></path></svg> ${ssrInterpolate(_ctx.$t("permissions.save_changes"))}</button><button class="px-4 py-2.5 bg-slate-700 hover:bg-slate-600 text-slate-300 font-medium rounded-lg transition">${ssrInterpolate(_ctx.$t("permissions.discard"))}</button></div>`);
} else {
_push(`<!---->`);
}
_push(`<!--]-->`);
}
_push(`</div>`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/permissions/index.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
export {
_sfc_main as default
};
//# sourceMappingURL=index-7zBAzpaD.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,311 @@
import { defineComponent, ref, computed, reactive, unref, useSSRContext } from "vue";
import { ssrRenderAttrs, ssrInterpolate, ssrRenderList, ssrRenderClass, ssrRenderAttr, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual } from "vue/server-renderer";
import { u as useRegionStore } from "./region-0mvXqaMM.js";
import "/app/node_modules/hookable/dist/index.mjs";
import "/app/node_modules/klona/dist/index.mjs";
import "../server.mjs";
import "pinia";
import "/app/node_modules/ofetch/dist/node.mjs";
import "#internal/nuxt/paths";
import "/app/node_modules/unctx/dist/index.mjs";
import "/app/node_modules/h3/dist/index.mjs";
import "/app/node_modules/defu/dist/defu.mjs";
import "vue-router";
import "/app/node_modules/ufo/dist/index.mjs";
import "/app/node_modules/cookie-es/dist/index.mjs";
import "/app/node_modules/destr/dist/index.mjs";
import "/app/node_modules/ohash/dist/index.mjs";
import "/app/node_modules/@unhead/vue/dist/index.mjs";
import "@vue/devtools-api";
function useFormatter() {
const regionStore = useRegionStore();
function formatNumber(value, options) {
const locale = regionStore.activeLocale || "en-EU";
try {
return new Intl.NumberFormat(locale, options).format(value);
} catch {
return new Intl.NumberFormat("en-EU", options).format(value);
}
}
function formatCurrency(value, currency, options) {
const locale = regionStore.activeLocale || "en-EU";
const curr = currency || regionStore.activeCurrency || "EUR";
try {
return new Intl.NumberFormat(locale, {
style: "currency",
currency: curr,
minimumFractionDigits: 2,
maximumFractionDigits: 2,
...options
}).format(value);
} catch {
return `${value.toFixed(2)} ${curr}`;
}
}
function formatDate(date, options) {
const locale = regionStore.activeLocale || "en-EU";
const timezone = regionStore.activeTimezone || "Europe/Brussels";
const d = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
try {
return new Intl.DateTimeFormat(locale, {
timezone,
year: "numeric",
month: "2-digit",
day: "2-digit",
...options
}).format(d);
} catch {
return d.toLocaleDateString("en-GB");
}
}
function formatDateTime(date, options) {
const locale = regionStore.activeLocale || "en-EU";
const timezone = regionStore.activeTimezone || "Europe/Brussels";
const d = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
try {
return new Intl.DateTimeFormat(locale, {
timezone,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
...options
}).format(d);
} catch {
return d.toLocaleString("en-GB");
}
}
function formatPercent(value, options) {
const locale = regionStore.activeLocale || "en-EU";
try {
return new Intl.NumberFormat(locale, {
style: "percent",
minimumFractionDigits: 0,
maximumFractionDigits: 1,
...options
}).format(value / 100);
} catch {
return `${value}%`;
}
}
function calculatePriceWithVat(netPrice, vatRate) {
const rate = vatRate ?? regionStore.activeVatRate ?? 0;
const vat = netPrice * (rate / 100);
const gross = netPrice + vat;
return { net: netPrice, vat, gross, vatRate: rate };
}
function formatPriceWithVat(netPrice, vatRate, currency) {
const { net, vat, gross, vatRate: rate } = calculatePriceWithVat(netPrice, vatRate);
const curr = currency || regionStore.activeCurrency || "EUR";
return `Net: ${formatCurrency(net, curr)} | VAT: ${formatCurrency(vat, curr)} (${rate}%) | Gross: ${formatCurrency(gross, curr)}`;
}
return {
formatNumber,
formatCurrency,
formatDate,
formatDateTime,
formatPercent,
calculatePriceWithVat,
formatPriceWithVat
};
}
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "index",
__ssrInlineRender: true,
setup(__props) {
const regionStore = useRegionStore();
const { formatCurrency } = useFormatter();
const tabs = [
{ key: "basic", label: "📋 Basic Info" },
{ key: "pricing", label: "💰 Pricing" },
{ key: "features", label: "⚡ Features" }
];
const activeTab = ref("basic");
const activeTabLabel = computed(() => {
const tab = tabs.find((t) => t.key === activeTab.value);
return tab ? tab.label : "";
});
const packages = ref([]);
const loading = ref(true);
const error = ref(null);
const showModal = ref(false);
const showDeleteConfirm = ref(false);
const editingPackage = ref(null);
const deletingPackage = ref(null);
const isCreating = ref(false);
const saving = ref(false);
const saveNotification = ref(null);
const featureCapabilitiesError = ref(null);
const calcNetPrice = ref(0);
const calcVatRate = ref(27);
const calcCurrency = ref("EUR");
const defaultForm = {
name: "",
display_name: "",
type: "private",
tier_level: 0,
monthly_price: 0,
yearly_price: 0,
currency: "EUR",
max_vehicles: 1,
max_garages: 1,
monthly_free_credits: 0,
subtitle: "",
badge: "",
is_custom: false,
is_default_fallback: false,
trial_days_on_signup: 0,
feature_capabilities_json: '{\n "ai_analysis": false,\n "priority_support": false,\n "api_access": false\n}',
pricing_zones: {}
};
const form = reactive({ ...defaultForm });
function getZonePrice(countryCode, period) {
const zone = form.pricing_zones[countryCode];
if (!zone) return 0;
return period === "monthly" ? zone.monthly_price : zone.yearly_price;
}
function getZoneCurrency(countryCode) {
const zone = form.pricing_zones[countryCode];
if (!zone) return "EUR";
return zone.currency;
}
function getDisplayName(pkg) {
return pkg.rules?.display_name || pkg.name;
}
function getDescription(pkg) {
return pkg.rules?.marketing?.subtitle || pkg.rules?.marketing?.badge || "";
}
function getFormattedPrice(pkg) {
const zones = pkg.rules?.pricing_zones;
const pricing = pkg.rules?.pricing;
if (zones && zones["DEFAULT"]) {
const p = zones["DEFAULT"];
const currency = p.currency === "HUF" ? "Ft" : "€";
return `${p.monthly_price} ${currency}`;
}
if (pricing) {
const currency = pricing.currency === "HUF" ? "Ft" : "€";
return `${pricing.monthly_price} ${currency}`;
}
return "—";
}
function getAllowance(pkg, key) {
const allowances = pkg.rules?.allowances;
if (!allowances) return "—";
return allowances[key] ?? "—";
}
function getTierColorClass(level) {
if (level >= 2) return "bg-purple-500/10 text-purple-400";
if (level >= 1) return "bg-amber-500/10 text-amber-400";
return "bg-slate-500/10 text-slate-400";
}
function getTierIcon(level) {
if (level >= 2) return "🏢";
if (level >= 1) return "⭐";
return "🔓";
}
return (_ctx, _push, _parent, _attrs) => {
_push(`<div${ssrRenderAttrs(_attrs)}><div class="mb-8 flex items-center justify-between"><div><h1 class="text-2xl font-bold text-white">${ssrInterpolate(_ctx.$t("packages.title"))}</h1><p class="text-slate-400 mt-1">${ssrInterpolate(_ctx.$t("packages.subtitle"))}</p></div><button class="px-5 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white font-medium rounded-lg transition text-sm flex items-center gap-2"><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg> ${ssrInterpolate(_ctx.$t("packages.create_new"))}</button></div>`);
if (loading.value) {
_push(`<div class="flex items-center justify-center py-20"><div class="flex flex-col items-center gap-3"><svg class="animate-spin h-8 w-8 text-indigo-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg><span class="text-slate-400 text-sm">${ssrInterpolate(_ctx.$t("packages.loading"))}</span></div></div>`);
} else if (error.value) {
_push(`<div class="bg-red-900/30 border border-red-700 rounded-xl p-6 text-center"><p class="text-red-300 mb-3">${ssrInterpolate(error.value)}</p><button class="px-4 py-2 bg-red-700 hover:bg-red-600 text-white rounded-lg transition text-sm">${ssrInterpolate(_ctx.$t("packages.retry"))}</button></div>`);
} else if (packages.value.length === 0) {
_push(`<div class="bg-slate-800/50 border border-slate-700 rounded-xl p-12 text-center"><svg class="w-16 h-16 mx-auto text-slate-600 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"></path></svg><h3 class="text-lg font-medium text-slate-300 mb-2">${ssrInterpolate(_ctx.$t("packages.no_packages"))}</h3><p class="text-slate-500 mb-6">${ssrInterpolate(_ctx.$t("packages.no_packages_desc"))}</p><button class="px-5 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white font-medium rounded-lg transition text-sm">${ssrInterpolate(_ctx.$t("packages.create_first"))}</button></div>`);
} else {
_push(`<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 mb-8"><!--[-->`);
ssrRenderList(packages.value, (pkg) => {
_push(`<div class="bg-slate-800 rounded-xl border border-slate-700 p-6 flex flex-col transition-all hover:border-slate-600"><div class="flex items-center justify-between mb-4"><div class="flex items-center gap-3"><div class="${ssrRenderClass([getTierColorClass(pkg.tier_level), "p-2 rounded-lg"])}"><span class="w-5 h-5 text-lg">${getTierIcon(pkg.tier_level) ?? ""}</span></div><div><h2 class="text-lg font-semibold text-white">${ssrInterpolate(getDisplayName(pkg))}</h2><span class="text-xs text-slate-500 font-mono">${ssrInterpolate(pkg.name)}</span></div></div><div class="flex items-center gap-1.5 flex-wrap">`);
if (pkg.tier_level >= 1) {
_push(`<span class="px-2 py-0.5 text-xs font-semibold rounded-full bg-indigo-500/20 text-indigo-300">${ssrInterpolate(_ctx.$t("packages.popular"))}</span>`);
} else {
_push(`<!---->`);
}
if (pkg.is_default_fallback) {
_push(`<span class="px-2 py-0.5 text-xs font-semibold rounded-full bg-amber-500/20 text-amber-300" title="Default fallback package for expired subscriptions"> 🔒 ${ssrInterpolate(_ctx.$t("packages.fallback_badge"))}</span>`);
} else {
_push(`<!---->`);
}
if (pkg.trial_days_on_signup > 0) {
_push(`<span class="px-2 py-0.5 text-xs font-semibold rounded-full bg-emerald-500/20 text-emerald-300"${ssrRenderAttr("title", `${pkg.trial_days_on_signup} days trial on signup`)}> 🎯 ${ssrInterpolate(_ctx.$t("packages.trial_badge"))}: ${ssrInterpolate(pkg.trial_days_on_signup)}d </span>`);
} else {
_push(`<!---->`);
}
_push(`</div></div><div class="mb-4"><span class="text-3xl font-bold text-white">${ssrInterpolate(getFormattedPrice(pkg))}</span><span class="text-sm text-slate-400 ml-1">/ ${ssrInterpolate(_ctx.$t("packages.month"))}</span></div><p class="text-sm text-slate-400 mb-4 flex-1">${ssrInterpolate(getDescription(pkg))}</p><div class="border-t border-slate-700 pt-4 mb-4"><h3 class="text-xs font-semibold uppercase tracking-wider text-slate-500 mb-3">${ssrInterpolate(_ctx.$t("packages.allowances"))}</h3><div class="space-y-2"><div class="flex items-center justify-between text-sm"><span class="text-slate-400">${ssrInterpolate(_ctx.$t("packages.max_vehicles"))}</span><span class="text-slate-200 font-medium">${ssrInterpolate(getAllowance(pkg, "max_vehicles"))}</span></div><div class="flex items-center justify-between text-sm"><span class="text-slate-400">${ssrInterpolate(_ctx.$t("packages.max_garages"))}</span><span class="text-slate-200 font-medium">${ssrInterpolate(getAllowance(pkg, "max_garages"))}</span></div><div class="flex items-center justify-between text-sm"><span class="text-slate-400">${ssrInterpolate(_ctx.$t("packages.monthly_credits"))}</span><span class="text-slate-200 font-medium">${ssrInterpolate(getAllowance(pkg, "monthly_free_credits"))}</span></div></div></div><div class="mb-4"><span class="text-xs text-slate-500">${ssrInterpolate(_ctx.$t("packages.tier_level"))}: </span><span class="text-xs font-mono text-slate-400">${ssrInterpolate(pkg.tier_level)}</span></div><div class="flex gap-2"><button class="flex-1 px-4 py-2.5 bg-indigo-600 hover:bg-indigo-500 text-white font-medium rounded-lg transition text-sm">${ssrInterpolate(_ctx.$t("packages.edit"))}</button><button class="px-3 py-2.5 bg-red-700 hover:bg-red-600 text-red-200 rounded-lg transition"${ssrRenderAttr("title", _ctx.$t("packages.delete"))}><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path></svg></button></div></div>`);
});
_push(`<!--]--></div>`);
}
if (showModal.value) {
_push(`<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/60"><div class="bg-slate-800 border border-slate-700 rounded-xl w-full max-w-3xl mx-4 shadow-2xl max-h-[90vh] flex flex-col"><div class="flex items-center justify-between px-6 py-4 border-b border-slate-700"><h3 class="text-lg font-semibold text-white">${ssrInterpolate(isCreating.value ? _ctx.$t("packages.create_title") : _ctx.$t("packages.edit_title") + ": " + getDisplayName(editingPackage.value))}</h3><button class="p-1 rounded-lg text-slate-400 hover:text-white hover:bg-slate-700 transition"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg></button></div><div class="flex border-b border-slate-700 px-6"><!--[-->`);
ssrRenderList(tabs, (tab) => {
_push(`<button class="${ssrRenderClass([activeTab.value === tab.key ? "border-indigo-500 text-indigo-300" : "border-transparent text-slate-400 hover:text-slate-200 hover:border-slate-500", "px-4 py-3 text-sm font-medium border-b-2 transition"])}">${ssrInterpolate(tab.label)}</button>`);
});
_push(`<!--]--></div><div class="flex-1 overflow-y-auto px-6 py-5">`);
if (activeTab.value === "basic") {
_push(`<div class="space-y-4"><div><label class="block text-sm font-medium text-slate-300 mb-1">${ssrInterpolate(_ctx.$t("packages.form_name"))}</label><input${ssrRenderAttr("value", form.name)} type="text" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"${ssrRenderAttr("placeholder", _ctx.$t("packages.form_name_placeholder"))}></div><div><label class="block text-sm font-medium text-slate-300 mb-1">${ssrInterpolate(_ctx.$t("packages.form_display_name"))}</label><input${ssrRenderAttr("value", form.display_name)} type="text" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"${ssrRenderAttr("placeholder", _ctx.$t("packages.form_display_name_placeholder"))}></div><div class="grid grid-cols-2 gap-4"><div><label class="block text-sm font-medium text-slate-300 mb-1">${ssrInterpolate(_ctx.$t("packages.form_type"))}</label><select class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"><option value="private"${ssrIncludeBooleanAttr(Array.isArray(form.type) ? ssrLooseContain(form.type, "private") : ssrLooseEqual(form.type, "private")) ? " selected" : ""}>${ssrInterpolate(_ctx.$t("packages.type_private"))}</option><option value="corporate"${ssrIncludeBooleanAttr(Array.isArray(form.type) ? ssrLooseContain(form.type, "corporate") : ssrLooseEqual(form.type, "corporate")) ? " selected" : ""}>${ssrInterpolate(_ctx.$t("packages.type_corporate"))}</option></select></div><div><label class="block text-sm font-medium text-slate-300 mb-1">${ssrInterpolate(_ctx.$t("packages.form_tier_level"))}</label><input${ssrRenderAttr("value", form.tier_level)} type="number" min="0" max="10" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"><p class="text-xs text-slate-500 mt-1">${ssrInterpolate(_ctx.$t("packages.form_tier_level_hint"))}</p></div></div><div class="grid grid-cols-2 gap-4"><div><label class="block text-sm font-medium text-slate-300 mb-1">${ssrInterpolate(_ctx.$t("packages.form_subtitle"))}</label><input${ssrRenderAttr("value", form.subtitle)} type="text" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"${ssrRenderAttr("placeholder", _ctx.$t("packages.form_subtitle_placeholder"))}></div><div><label class="block text-sm font-medium text-slate-300 mb-1">${ssrInterpolate(_ctx.$t("packages.form_badge"))}</label><input${ssrRenderAttr("value", form.badge)} type="text" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"${ssrRenderAttr("placeholder", _ctx.$t("packages.form_badge_placeholder"))}></div></div><div class="flex items-center gap-3"><input${ssrIncludeBooleanAttr(Array.isArray(form.is_custom) ? ssrLooseContain(form.is_custom, null) : form.is_custom) ? " checked" : ""} type="checkbox" id="is_custom" class="rounded bg-slate-700 border-slate-600 text-indigo-600 focus:ring-indigo-500"><label for="is_custom" class="text-sm text-slate-300">${ssrInterpolate(_ctx.$t("packages.form_is_custom"))}</label></div><div class="border-t border-slate-700 pt-4"><h4 class="text-sm font-semibold text-slate-300 mb-3">${ssrInterpolate(_ctx.$t("packages.singleton_rules"))}</h4><div class="space-y-4"><div class="flex items-center gap-3"><input${ssrIncludeBooleanAttr(Array.isArray(form.is_default_fallback) ? ssrLooseContain(form.is_default_fallback, null) : form.is_default_fallback) ? " checked" : ""} type="checkbox" id="is_default_fallback" class="rounded bg-slate-700 border-slate-600 text-amber-500 focus:ring-amber-500"><label for="is_default_fallback" class="text-sm text-slate-300">${ssrInterpolate(_ctx.$t("packages.form_is_default_fallback"))}</label></div><div><label class="block text-sm text-slate-300 mb-1">${ssrInterpolate(_ctx.$t("packages.form_trial_days"))}</label><input${ssrRenderAttr("value", form.trial_days_on_signup)} type="number" min="0" max="365" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-emerald-500 focus:border-transparent"><p class="text-xs text-slate-500 mt-1">${ssrInterpolate(_ctx.$t("packages.form_trial_days_hint"))}</p></div></div></div></div>`);
} else {
_push(`<!---->`);
}
if (activeTab.value === "pricing") {
_push(`<div class="space-y-6"><div><h4 class="text-sm font-semibold text-slate-300 mb-3">${ssrInterpolate(_ctx.$t("packages.per_region_pricing"))}</h4><div class="overflow-x-auto"><table class="w-full text-sm"><thead><tr class="border-b border-slate-700"><th class="text-left py-2 px-3 text-slate-400 font-medium">Region</th><th class="text-left py-2 px-3 text-slate-400 font-medium">${ssrInterpolate(_ctx.$t("packages.form_monthly_price"))}</th><th class="text-left py-2 px-3 text-slate-400 font-medium">${ssrInterpolate(_ctx.$t("packages.form_yearly_price"))}</th><th class="text-left py-2 px-3 text-slate-400 font-medium">${ssrInterpolate(_ctx.$t("packages.form_currency"))}</th></tr></thead><tbody><!--[-->`);
ssrRenderList(unref(regionStore).regions, (region) => {
_push(`<tr class="border-b border-slate-700/50"><td class="py-2 px-3 text-slate-200 font-medium"><span class="inline-flex items-center gap-1.5"><span>${ssrInterpolate(region.country_code)}</span><span class="text-xs text-slate-500">(${ssrInterpolate(region.currency)}, ${ssrInterpolate(region.default_vat_rate)}% VAT)</span></span></td><td class="py-2 px-3"><input${ssrRenderAttr("value", getZonePrice(region.country_code, "monthly"))} type="number" step="0.01" min="0" class="w-full px-2 py-1.5 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"></td><td class="py-2 px-3"><input${ssrRenderAttr("value", getZonePrice(region.country_code, "yearly"))} type="number" step="0.01" min="0" class="w-full px-2 py-1.5 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"></td><td class="py-2 px-3"><input${ssrRenderAttr("value", getZoneCurrency(region.country_code))} type="text" maxlength="3" class="w-full px-2 py-1.5 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent uppercase"></td></tr>`);
});
_push(`<!--]--></tbody></table></div></div><div class="border-t border-slate-700 pt-5"><h4 class="text-sm font-semibold text-slate-300 mb-3">🧮 ${ssrInterpolate(_ctx.$t("packages.smart_calculator"))}</h4><div class="bg-slate-700/30 rounded-xl p-4 space-y-4"><div class="grid grid-cols-3 gap-4"><div><label class="block text-xs text-slate-400 mb-1">${ssrInterpolate(_ctx.$t("packages.calc_net_price"))}</label><input${ssrRenderAttr("value", calcNetPrice.value)} type="number" step="0.01" min="0" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-emerald-500 focus:border-transparent" placeholder="0.00"></div><div><label class="block text-xs text-slate-400 mb-1">${ssrInterpolate(_ctx.$t("packages.calc_vat_rate"))}</label><select class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-emerald-500 focus:border-transparent"><!--[-->`);
ssrRenderList(unref(regionStore).regions, (region) => {
_push(`<option${ssrRenderAttr("value", region.default_vat_rate)}${ssrIncludeBooleanAttr(Array.isArray(calcVatRate.value) ? ssrLooseContain(calcVatRate.value, region.default_vat_rate) : ssrLooseEqual(calcVatRate.value, region.default_vat_rate)) ? " selected" : ""}>${ssrInterpolate(region.country_code)}${ssrInterpolate(region.default_vat_rate)}% </option>`);
});
_push(`<!--]--></select></div><div><label class="block text-xs text-slate-400 mb-1">${ssrInterpolate(_ctx.$t("packages.calc_currency"))}</label><select class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-emerald-500 focus:border-transparent"><!--[-->`);
ssrRenderList(unref(regionStore).regions, (region) => {
_push(`<option${ssrRenderAttr("value", region.currency)}${ssrIncludeBooleanAttr(Array.isArray(calcCurrency.value) ? ssrLooseContain(calcCurrency.value, region.currency) : ssrLooseEqual(calcCurrency.value, region.currency)) ? " selected" : ""}>${ssrInterpolate(region.currency)} (${ssrInterpolate(region.country_code)}) </option>`);
});
_push(`<!--]--></select></div></div><div class="grid grid-cols-3 gap-4 pt-2"><div class="bg-slate-800 rounded-lg p-3 text-center"><p class="text-xs text-slate-400 mb-1">${ssrInterpolate(_ctx.$t("packages.calc_net"))}</p><p class="text-lg font-bold text-white">${ssrInterpolate(unref(formatCurrency)(calcNetPrice.value, calcCurrency.value))}</p></div><div class="bg-slate-800 rounded-lg p-3 text-center"><p class="text-xs text-slate-400 mb-1">${ssrInterpolate(_ctx.$t("packages.calc_vat"))} (${ssrInterpolate(calcVatRate.value)}%)</p><p class="text-lg font-bold text-amber-400">${ssrInterpolate(unref(formatCurrency)(calcNetPrice.value * (calcVatRate.value / 100), calcCurrency.value))}</p></div><div class="bg-slate-800 rounded-lg p-3 text-center ring-2 ring-emerald-500/50"><p class="text-xs text-slate-400 mb-1">${ssrInterpolate(_ctx.$t("packages.calc_gross"))}</p><p class="text-lg font-bold text-emerald-400">${ssrInterpolate(unref(formatCurrency)(calcNetPrice.value * (1 + calcVatRate.value / 100), calcCurrency.value))}</p></div></div><div class="flex justify-end pt-1"><button class="px-4 py-2 bg-emerald-600 hover:bg-emerald-500 text-white text-sm font-medium rounded-lg transition flex items-center gap-2"><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg> ${ssrInterpolate(_ctx.$t("packages.calc_apply"))}</button></div></div></div></div>`);
} else {
_push(`<!---->`);
}
if (activeTab.value === "features") {
_push(`<div class="space-y-5"><div><h4 class="text-sm font-semibold text-slate-300 mb-3">${ssrInterpolate(_ctx.$t("packages.allowances"))}</h4><div class="grid grid-cols-3 gap-4"><div><label class="block text-xs text-slate-400 mb-1">${ssrInterpolate(_ctx.$t("packages.max_vehicles"))}</label><input${ssrRenderAttr("value", form.max_vehicles)} type="number" min="0" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"></div><div><label class="block text-xs text-slate-400 mb-1">${ssrInterpolate(_ctx.$t("packages.max_garages"))}</label><input${ssrRenderAttr("value", form.max_garages)} type="number" min="0" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"></div><div><label class="block text-xs text-slate-400 mb-1">${ssrInterpolate(_ctx.$t("packages.monthly_credits"))}</label><input${ssrRenderAttr("value", form.monthly_free_credits)} type="number" min="0" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"></div></div></div><div class="border-t border-slate-700 pt-4"><h4 class="text-sm font-semibold text-slate-300 mb-3">${ssrInterpolate(_ctx.$t("packages.feature_capabilities"))}</h4><textarea rows="8" class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm font-mono focus:ring-2 focus:ring-indigo-500 focus:border-transparent" placeholder="{\\n &quot;ai_analysis&quot;: true,\\n &quot;priority_support&quot;: false,\\n &quot;api_access&quot;: true\\n}">${ssrInterpolate(form.feature_capabilities_json)}</textarea><p class="text-xs text-slate-500 mt-1">${ssrInterpolate(_ctx.$t("packages.feature_capabilities_hint"))}</p>`);
if (featureCapabilitiesError.value) {
_push(`<p class="text-xs text-red-400 mt-1">${ssrInterpolate(featureCapabilitiesError.value)}</p>`);
} else {
_push(`<!---->`);
}
_push(`</div></div>`);
} else {
_push(`<!---->`);
}
_push(`</div><div class="flex items-center justify-between px-6 py-4 border-t border-slate-700"><div class="text-xs text-slate-500">${ssrInterpolate(activeTabLabel.value)}</div><div class="flex items-center gap-3"><button class="px-4 py-2 text-sm text-slate-400 hover:text-white transition">${ssrInterpolate(_ctx.$t("packages.cancel"))}</button><button${ssrIncludeBooleanAttr(saving.value) ? " disabled" : ""} class="px-6 py-2 bg-emerald-600 hover:bg-emerald-500 disabled:bg-slate-600 disabled:cursor-not-allowed text-white font-medium rounded-lg transition text-sm flex items-center gap-2">`);
if (saving.value) {
_push(`<svg class="animate-spin h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg>`);
} else {
_push(`<!---->`);
}
_push(` ${ssrInterpolate(isCreating.value ? _ctx.$t("packages.create") : _ctx.$t("packages.save"))}</button></div></div></div></div>`);
} else {
_push(`<!---->`);
}
if (showDeleteConfirm.value && deletingPackage.value) {
_push(`<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/60"><div class="bg-slate-800 border border-slate-700 rounded-xl w-full max-w-md mx-4 p-6 shadow-2xl"><h3 class="text-lg font-semibold text-white mb-2">${ssrInterpolate(_ctx.$t("packages.delete_title"))}</h3><p class="text-slate-400 text-sm mb-6">${ssrInterpolate(_ctx.$t("packages.delete_confirm", { name: getDisplayName(deletingPackage.value) }))}</p><div class="flex items-center justify-end gap-3"><button class="px-4 py-2 text-sm text-slate-400 hover:text-white transition">${ssrInterpolate(_ctx.$t("packages.cancel"))}</button><button${ssrIncludeBooleanAttr(saving.value) ? " disabled" : ""} class="px-6 py-2 bg-red-600 hover:bg-red-500 disabled:bg-slate-600 disabled:cursor-not-allowed text-white font-medium rounded-lg transition text-sm">${ssrInterpolate(_ctx.$t("packages.delete_btn"))}</button></div></div></div>`);
} else {
_push(`<!---->`);
}
if (saveNotification.value) {
_push(`<div class="${ssrRenderClass([saveNotification.value.type === "success" ? "bg-emerald-600 text-white" : "bg-red-600 text-white", "fixed bottom-6 right-6 px-5 py-3 rounded-xl shadow-xl text-sm font-medium z-50"])}">${ssrInterpolate(saveNotification.value.message)}</div>`);
} else {
_push(`<!---->`);
}
_push(`</div>`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/packages/index.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
export {
_sfc_main as default
};
//# sourceMappingURL=index-BPETUF7a.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,55 +0,0 @@
import { defineComponent, useSSRContext } from "vue";
import { ssrRenderAttrs, ssrRenderList, ssrInterpolate, ssrRenderClass } from "vue/server-renderer";
import "/app/node_modules/hookable/dist/index.mjs";
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "index",
__ssrInlineRender: true,
setup(__props) {
const superadminPerms = [
{ key: "user_mgmt", label: "User Management", enabled: true },
{ key: "billing_admin", label: "Billing Administration", enabled: true },
{ key: "robot_config", label: "Robot Configuration", enabled: true },
{ key: "system_logs", label: "System Logs Access", enabled: true },
{ key: "api_keys", label: "API Key Management", enabled: false }
];
const garagePerms = [
{ key: "vehicle_crud", label: "Vehicle CRUD", enabled: true },
{ key: "service_booking", label: "Service Booking", enabled: true },
{ key: "customer_view", label: "Customer Data View", enabled: true },
{ key: "report_export", label: "Report Export", enabled: false },
{ key: "bulk_import", label: "Bulk Import", enabled: false }
];
const packagePerms = [
{ key: "premium_features", label: "Premium Features", enabled: true },
{ key: "analytics", label: "Analytics Dashboard", enabled: true },
{ key: "multi_garage", label: "Multi-Garage Support", enabled: false },
{ key: "white_label", label: "White Label Branding", enabled: false },
{ key: "api_access", label: "API Access", enabled: true }
];
return (_ctx, _push, _parent, _attrs) => {
_push(`<div${ssrRenderAttrs(_attrs)}><div class="mb-8"><h1 class="text-2xl font-bold text-white">Jogosultság Kezelés</h1><p class="text-slate-400 mt-1">Permissions Management — Role-based access control matrix</p></div><div class="bg-indigo-500/10 border border-indigo-500/20 rounded-xl p-4 mb-8 flex items-start gap-3"><svg class="w-5 h-5 text-indigo-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><p class="text-sm text-indigo-300"> This is the permissions management interface. The 3D Capability Matrix UI (Superadmin, Garages, and Packages toggles) will be implemented here in the next iteration. </p></div><div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8"><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><div class="flex items-center gap-3 mb-4"><div class="p-2 rounded-lg bg-purple-500/10 text-purple-400"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z"></path></svg></div><h2 class="text-lg font-semibold text-white">Superadmin</h2></div><p class="text-sm text-slate-400 mb-4">Full system access — user management, billing, robots, and system configuration.</p><div class="space-y-3"><!--[-->`);
ssrRenderList(superadminPerms, (perm) => {
_push(`<div class="flex items-center justify-between py-2 border-b border-slate-700/50 last:border-0"><span class="text-sm text-slate-300">${ssrInterpolate(perm.label)}</span><span class="${ssrRenderClass([perm.enabled ? "bg-emerald-400/10 text-emerald-400" : "bg-slate-700 text-slate-500", "text-xs px-2 py-0.5 rounded-full"])}">${ssrInterpolate(perm.enabled ? "Enabled" : "Disabled")}</span></div>`);
});
_push(`<!--]--></div><div class="mt-4 pt-4 border-t border-slate-700"><button class="w-full px-4 py-2 text-sm bg-purple-600 hover:bg-purple-500 text-white rounded-lg transition"> Configure Superadmin </button></div></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><div class="flex items-center gap-3 mb-4"><div class="p-2 rounded-lg bg-cyan-500/10 text-cyan-400"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h1.125c.621 0 1.129-.504 1.09-1.124a17.902 17.902 0 00-3.213-9.193 2.056 2.056 0 00-1.58-.86H14.25M16.5 18.75h-2.25m0-11.177v-.958c0-.568-.422-1.048-.987-1.106a48.554 48.554 0 00-10.026 0 1.106 1.106 0 00-.987 1.106v7.635m12-6.677v6.677m0 4.5v-4.5m0 0h-12"></path></svg></div><h2 class="text-lg font-semibold text-white">Garages</h2></div><p class="text-sm text-slate-400 mb-4">Garage-level access — vehicle management, service booking, customer data.</p><div class="space-y-3"><!--[-->`);
ssrRenderList(garagePerms, (perm) => {
_push(`<div class="flex items-center justify-between py-2 border-b border-slate-700/50 last:border-0"><span class="text-sm text-slate-300">${ssrInterpolate(perm.label)}</span><span class="${ssrRenderClass([perm.enabled ? "bg-emerald-400/10 text-emerald-400" : "bg-slate-700 text-slate-500", "text-xs px-2 py-0.5 rounded-full"])}">${ssrInterpolate(perm.enabled ? "Enabled" : "Disabled")}</span></div>`);
});
_push(`<!--]--></div><div class="mt-4 pt-4 border-t border-slate-700"><button class="w-full px-4 py-2 text-sm bg-cyan-600 hover:bg-cyan-500 text-white rounded-lg transition"> Configure Garages </button></div></div><div class="bg-slate-800 rounded-xl border border-slate-700 p-6"><div class="flex items-center gap-3 mb-4"><div class="p-2 rounded-lg bg-amber-500/10 text-amber-400"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5m8.25 3v6.75m0 0l-3-3m3 3l3-3M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z"></path></svg></div><h2 class="text-lg font-semibold text-white">Packages</h2></div><p class="text-sm text-slate-400 mb-4">Subscription package permissions — feature toggles per plan tier.</p><div class="space-y-3"><!--[-->`);
ssrRenderList(packagePerms, (perm) => {
_push(`<div class="flex items-center justify-between py-2 border-b border-slate-700/50 last:border-0"><span class="text-sm text-slate-300">${ssrInterpolate(perm.label)}</span><span class="${ssrRenderClass([perm.enabled ? "bg-emerald-400/10 text-emerald-400" : "bg-slate-700 text-slate-500", "text-xs px-2 py-0.5 rounded-full"])}">${ssrInterpolate(perm.enabled ? "Enabled" : "Disabled")}</span></div>`);
});
_push(`<!--]--></div><div class="mt-4 pt-4 border-t border-slate-700"><button class="w-full px-4 py-2 text-sm bg-amber-600 hover:bg-amber-500 text-white rounded-lg transition"> Configure Packages </button></div></div></div><div class="bg-slate-800/50 border-2 border-dashed border-slate-600 rounded-xl p-12 text-center"><svg class="w-12 h-12 mx-auto text-slate-600 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 17.25v1.007a3 3 0 01-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0115 18.257V17.25m6-12V15a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 15V5.25m18 0A2.25 2.25 0 0018.75 3H5.25A2.25 2.25 0 003 5.25m18 0V12a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 12V5.25"></path></svg><h3 class="text-lg font-semibold text-slate-400 mb-2">3D Capability Matrix</h3><p class="text-sm text-slate-500 max-w-md mx-auto"> The interactive permission matrix UI with toggles for Superadmin, Garages, and Packages will be rendered here in the next development phase. </p></div></div>`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/permissions/index.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
export {
_sfc_main as default
};
//# sourceMappingURL=index-nGH29Vk2.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,22 +1,24 @@
import { _ as __nuxt_component_0 } from "./nuxt-link-DNVrgHUL.js";
import { _ as __nuxt_component_0 } from "./nuxt-link-Cp-CAJwR.js";
import { defineComponent, ref, mergeProps, unref, withCtx, createTextVNode, useSSRContext } from "vue";
import { ssrRenderAttrs, ssrRenderAttr, ssrInterpolate, ssrIncludeBooleanAttr, ssrRenderComponent } from "vue/server-renderer";
import { u as useAuthStore, _ as _imports_0 } from "./auth-CRAMW6e4.js";
import { u as useRouter } from "../server.mjs";
import { publicAssetsURL } from "#internal/nuxt/paths";
import { a as useRouter } from "../server.mjs";
import { u as useAuthStore } from "./auth-mCjBoLcA.js";
import "/app/node_modules/ufo/dist/index.mjs";
import "/app/node_modules/defu/dist/defu.mjs";
import "#internal/nuxt/paths";
import "pinia";
import "./cookie-CWIsZYm7.js";
import "/app/node_modules/cookie-es/dist/index.mjs";
import "/app/node_modules/h3/dist/index.mjs";
import "/app/node_modules/destr/dist/index.mjs";
import "/app/node_modules/ohash/dist/index.mjs";
import "/app/node_modules/klona/dist/index.mjs";
import "/app/node_modules/ofetch/dist/node.mjs";
import "/app/node_modules/hookable/dist/index.mjs";
import "/app/node_modules/unctx/dist/index.mjs";
import "/app/node_modules/h3/dist/index.mjs";
import "pinia";
import "vue-router";
import "/app/node_modules/klona/dist/index.mjs";
import "/app/node_modules/cookie-es/dist/index.mjs";
import "/app/node_modules/destr/dist/index.mjs";
import "/app/node_modules/ohash/dist/index.mjs";
import "/app/node_modules/@unhead/vue/dist/index.mjs";
import "@vue/devtools-api";
const _imports_0 = publicAssetsURL("/sf_logo.png");
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "login",
__ssrInlineRender: true,
@@ -68,4 +70,4 @@ _sfc_main.setup = (props, ctx) => {
export {
_sfc_main as default
};
//# sourceMappingURL=login-CLIOTi6c.js.map
//# sourceMappingURL=login-BHmaTZZZ.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
import { defineComponent, shallowRef, h, resolveComponent, computed, unref } from "vue";
import { parseQuery, hasProtocol, joinURL, isScriptProtocol, withTrailingSlash, withoutTrailingSlash } from "/app/node_modules/ufo/dist/index.mjs";
import { u as useRouter, e as encodeRoutePath, r as resolveRouteObject, n as navigateTo, a as useNuxtApp, b as useRuntimeConfig, c as nuxtLinkDefaults } from "../server.mjs";
import { a as useRouter, e as encodeRoutePath, r as resolveRouteObject, n as navigateTo, f as useNuxtApp, g as useRuntimeConfig, h as nuxtLinkDefaults } from "../server.mjs";
import "/app/node_modules/defu/dist/defu.mjs";
const firstNonUndefined = (...args) => args.find((arg) => arg !== void 0);
function sanitizeExternalHref(value) {
@@ -304,4 +304,4 @@ function applyTrailingSlashBehavior(to, trailingSlash) {
export {
__nuxt_component_0 as _
};
//# sourceMappingURL=nuxt-link-DNVrgHUL.js.map
//# sourceMappingURL=nuxt-link-Cp-CAJwR.js.map

View File

@@ -0,0 +1,73 @@
import { defineStore } from "pinia";
import { ref, computed } from "vue";
const useRegionStore = defineStore("region", () => {
const regions = ref([]);
const activeRegion = ref(null);
const isLoading = ref(false);
const error = ref(null);
const defaultRegion = computed(() => {
return regions.value.find((r) => r.country_code === "DEFAULT") || null;
});
const regionMap = computed(() => {
const map = /* @__PURE__ */ new Map();
for (const r of regions.value) {
map.set(r.country_code, r);
}
return map;
});
const activeCurrency = computed(() => {
return activeRegion.value?.currency || defaultRegion.value?.currency || "EUR";
});
const activeLocale = computed(() => {
return activeRegion.value?.locale_code || defaultRegion.value?.locale_code || "en-EU";
});
const activeVatRate = computed(() => {
return activeRegion.value?.default_vat_rate ?? defaultRegion.value?.default_vat_rate ?? 0;
});
const activeTimezone = computed(() => {
return activeRegion.value?.timezone || defaultRegion.value?.timezone || "Europe/Brussels";
});
async function fetchRegions() {
if (regions.value.length > 0) return;
isLoading.value = true;
error.value = null;
try {
const data = await $fetch("/api/v1/system/regions");
regions.value = data || [];
} catch (err) {
error.value = err?.data?.detail || err?.message || "Failed to load regions";
console.error("[RegionStore] Fetch error:", err);
} finally {
isLoading.value = false;
}
}
function setActiveRegion(countryCode) {
const found = regions.value.find((r) => r.country_code === countryCode);
activeRegion.value = found || defaultRegion.value;
}
function getRegion(countryCode) {
return regionMap.value.get(countryCode);
}
return {
// State
regions,
activeRegion,
isLoading,
error,
// Getters
defaultRegion,
regionMap,
activeCurrency,
activeLocale,
activeVatRate,
activeTimezone,
// Actions
fetchRegions,
setActiveRegion,
getRegion
};
});
export {
useRegionStore as u
};
//# sourceMappingURL=region-0mvXqaMM.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"region-0mvXqaMM.js","sources":["../../../../stores/region.ts"],"sourcesContent":["import { defineStore } from 'pinia'\nimport { ref, computed } from 'vue'\n\nexport interface RegionConfig {\n country_code: string\n name: string\n currency: string\n default_vat_rate: number\n locale_code: string\n timezone: string\n is_active: boolean\n}\n\nexport const useRegionStore = defineStore('region', () => {\n // ── State ──────────────────────────────────────────────────────────\n const regions = ref<RegionConfig[]>([])\n const activeRegion = ref<RegionConfig | null>(null)\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n\n // ── Getters ────────────────────────────────────────────────────────\n const defaultRegion = computed(() => {\n return regions.value.find(r => r.country_code === 'DEFAULT') || null\n })\n\n const regionMap = computed(() => {\n const map = new Map<string, RegionConfig>()\n for (const r of regions.value) {\n map.set(r.country_code, r)\n }\n return map\n })\n\n const activeCurrency = computed(() => {\n return activeRegion.value?.currency || defaultRegion.value?.currency || 'EUR'\n })\n\n const activeLocale = computed(() => {\n return activeRegion.value?.locale_code || defaultRegion.value?.locale_code || 'en-EU'\n })\n\n const activeVatRate = computed(() => {\n return activeRegion.value?.default_vat_rate ?? defaultRegion.value?.default_vat_rate ?? 0\n })\n\n const activeTimezone = computed(() => {\n return activeRegion.value?.timezone || defaultRegion.value?.timezone || 'Europe/Brussels'\n })\n\n // ── Actions ────────────────────────────────────────────────────────\n\n /**\n * Fetch all active regions from the public API endpoint.\n * Called once on app initialization.\n */\n async function fetchRegions() {\n if (regions.value.length > 0) return // already loaded\n isLoading.value = true\n error.value = null\n\n try {\n const data = await $fetch<RegionConfig[]>('/api/v1/system/regions')\n regions.value = data || []\n } catch (err: any) {\n error.value = err?.data?.detail || err?.message || 'Failed to load regions'\n console.error('[RegionStore] Fetch error:', err)\n } finally {\n isLoading.value = false\n }\n }\n\n /**\n * Set the active region by country_code.\n * Falls back to DEFAULT if the code is not found.\n */\n function setActiveRegion(countryCode: string) {\n const found = regions.value.find(r => r.country_code === countryCode)\n activeRegion.value = found || defaultRegion.value\n }\n\n /**\n * Get a region config by country_code.\n */\n function getRegion(countryCode: string): RegionConfig | undefined {\n return regionMap.value.get(countryCode)\n }\n\n return {\n // State\n regions,\n activeRegion,\n isLoading,\n error,\n\n // Getters\n defaultRegion,\n regionMap,\n activeCurrency,\n activeLocale,\n activeVatRate,\n activeTimezone,\n\n // Actions\n fetchRegions,\n setActiveRegion,\n getRegion,\n }\n})\n"],"names":[],"mappings":";;AAaO,MAAM,iBAAiB,YAAY,UAAU,MAAM;AAExD,QAAM,UAAU,IAAoB,EAAE;AACtC,QAAM,eAAe,IAAyB,IAAI;AAClD,QAAM,YAAY,IAAI,KAAK;AAC3B,QAAM,QAAQ,IAAmB,IAAI;AAGrC,QAAM,gBAAgB,SAAS,MAAM;AACnC,WAAO,QAAQ,MAAM,KAAK,OAAK,EAAE,iBAAiB,SAAS,KAAK;AAAA,EAClE,CAAC;AAED,QAAM,YAAY,SAAS,MAAM;AAC/B,UAAM,0BAAU,IAAA;AAChB,eAAW,KAAK,QAAQ,OAAO;AAC7B,UAAI,IAAI,EAAE,cAAc,CAAC;AAAA,IAC3B;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,iBAAiB,SAAS,MAAM;AACpC,WAAO,aAAa,OAAO,YAAY,cAAc,OAAO,YAAY;AAAA,EAC1E,CAAC;AAED,QAAM,eAAe,SAAS,MAAM;AAClC,WAAO,aAAa,OAAO,eAAe,cAAc,OAAO,eAAe;AAAA,EAChF,CAAC;AAED,QAAM,gBAAgB,SAAS,MAAM;AACnC,WAAO,aAAa,OAAO,oBAAoB,cAAc,OAAO,oBAAoB;AAAA,EAC1F,CAAC;AAED,QAAM,iBAAiB,SAAS,MAAM;AACpC,WAAO,aAAa,OAAO,YAAY,cAAc,OAAO,YAAY;AAAA,EAC1E,CAAC;AAQD,iBAAe,eAAe;AAC5B,QAAI,QAAQ,MAAM,SAAS,EAAG;AAC9B,cAAU,QAAQ;AAClB,UAAM,QAAQ;AAEd,QAAI;AACF,YAAM,OAAO,MAAM,OAAuB,wBAAwB;AAClE,cAAQ,QAAQ,QAAQ,CAAA;AAAA,IAC1B,SAAS,KAAU;AACjB,YAAM,QAAQ,KAAK,MAAM,UAAU,KAAK,WAAW;AACnD,cAAQ,MAAM,8BAA8B,GAAG;AAAA,IACjD,UAAA;AACE,gBAAU,QAAQ;AAAA,IACpB;AAAA,EACF;AAMA,WAAS,gBAAgB,aAAqB;AAC5C,UAAM,QAAQ,QAAQ,MAAM,KAAK,CAAA,MAAK,EAAE,iBAAiB,WAAW;AACpE,iBAAa,QAAQ,SAAS,cAAc;AAAA,EAC9C;AAKA,WAAS,UAAU,aAA+C;AAChE,WAAO,UAAU,MAAM,IAAI,WAAW;AAAA,EACxC;AAEA,SAAO;AAAA;AAAA,IAEL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ,CAAC;"}

View File

@@ -0,0 +1 @@
{"file":"region-0mvXqaMM.js","mappings":";;AAaO,MAAM,iBAAiB,YAAY,UAAU,MAAM;AAExD,QAAM,UAAU,IAAoB,EAAE;AACtC,QAAM,eAAe,IAAyB,IAAI;AAClD,QAAM,YAAY,IAAI,KAAK;AAC3B,QAAM,QAAQ,IAAmB,IAAI;AAGrC,QAAM,gBAAgB,SAAS,MAAM;AACnC,WAAO,QAAQ,MAAM,KAAK,OAAK,EAAE,iBAAiB,SAAS,KAAK;AAAA,EAClE,CAAC;AAED,QAAM,YAAY,SAAS,MAAM;AAC/B,UAAM,0BAAU,IAAA;AAChB,eAAW,KAAK,QAAQ,OAAO;AAC7B,UAAI,IAAI,EAAE,cAAc,CAAC;AAAA,IAC3B;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,iBAAiB,SAAS,MAAM;AACpC,WAAO,aAAa,OAAO,YAAY,cAAc,OAAO,YAAY;AAAA,EAC1E,CAAC;AAED,QAAM,eAAe,SAAS,MAAM;AAClC,WAAO,aAAa,OAAO,eAAe,cAAc,OAAO,eAAe;AAAA,EAChF,CAAC;AAED,QAAM,gBAAgB,SAAS,MAAM;AACnC,WAAO,aAAa,OAAO,oBAAoB,cAAc,OAAO,oBAAoB;AAAA,EAC1F,CAAC;AAED,QAAM,iBAAiB,SAAS,MAAM;AACpC,WAAO,aAAa,OAAO,YAAY,cAAc,OAAO,YAAY;AAAA,EAC1E,CAAC;AAQD,iBAAe,eAAe;AAC5B,QAAI,QAAQ,MAAM,SAAS,EAAG;AAC9B,cAAU,QAAQ;AAClB,UAAM,QAAQ;AAEd,QAAI;AACF,YAAM,OAAO,MAAM,OAAuB,wBAAwB;AAClE,cAAQ,QAAQ,QAAQ,CAAA;AAAA,IAC1B,SAAS,KAAU;AACjB,YAAM,QAAQ,KAAK,MAAM,UAAU,KAAK,WAAW;AACnD,cAAQ,MAAM,8BAA8B,GAAG;AAAA,IACjD,UAAA;AACE,gBAAU,QAAQ;AAAA,IACpB;AAAA,EACF;AAMA,WAAS,gBAAgB,aAAqB;AAC5C,UAAM,QAAQ,QAAQ,MAAM,KAAK,CAAA,MAAK,EAAE,iBAAiB,WAAW;AACpE,iBAAa,QAAQ,SAAS,cAAc;AAAA,EAC9C;AAKA,WAAS,UAAU,aAA+C;AAChE,WAAO,UAAU,MAAM,IAAI,WAAW;AAAA,EACxC;AAEA,SAAO;AAAA;AAAA,IAEL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ,CAAC;","names":[],"sources":["../../../../stores/region.ts"],"sourcesContent":["import { defineStore } from 'pinia'\nimport { ref, computed } from 'vue'\n\nexport interface RegionConfig {\n country_code: string\n name: string\n currency: string\n default_vat_rate: number\n locale_code: string\n timezone: string\n is_active: boolean\n}\n\nexport const useRegionStore = defineStore('region', () => {\n // ── State ──────────────────────────────────────────────────────────\n const regions = ref<RegionConfig[]>([])\n const activeRegion = ref<RegionConfig | null>(null)\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n\n // ── Getters ────────────────────────────────────────────────────────\n const defaultRegion = computed(() => {\n return regions.value.find(r => r.country_code === 'DEFAULT') || null\n })\n\n const regionMap = computed(() => {\n const map = new Map<string, RegionConfig>()\n for (const r of regions.value) {\n map.set(r.country_code, r)\n }\n return map\n })\n\n const activeCurrency = computed(() => {\n return activeRegion.value?.currency || defaultRegion.value?.currency || 'EUR'\n })\n\n const activeLocale = computed(() => {\n return activeRegion.value?.locale_code || defaultRegion.value?.locale_code || 'en-EU'\n })\n\n const activeVatRate = computed(() => {\n return activeRegion.value?.default_vat_rate ?? defaultRegion.value?.default_vat_rate ?? 0\n })\n\n const activeTimezone = computed(() => {\n return activeRegion.value?.timezone || defaultRegion.value?.timezone || 'Europe/Brussels'\n })\n\n // ── Actions ────────────────────────────────────────────────────────\n\n /**\n * Fetch all active regions from the public API endpoint.\n * Called once on app initialization.\n */\n async function fetchRegions() {\n if (regions.value.length > 0) return // already loaded\n isLoading.value = true\n error.value = null\n\n try {\n const data = await $fetch<RegionConfig[]>('/api/v1/system/regions')\n regions.value = data || []\n } catch (err: any) {\n error.value = err?.data?.detail || err?.message || 'Failed to load regions'\n console.error('[RegionStore] Fetch error:', err)\n } finally {\n isLoading.value = false\n }\n }\n\n /**\n * Set the active region by country_code.\n * Falls back to DEFAULT if the code is not found.\n */\n function setActiveRegion(countryCode: string) {\n const found = regions.value.find(r => r.country_code === countryCode)\n activeRegion.value = found || defaultRegion.value\n }\n\n /**\n * Get a region config by country_code.\n */\n function getRegion(countryCode: string): RegionConfig | undefined {\n return regionMap.value.get(countryCode)\n }\n\n return {\n // State\n regions,\n activeRegion,\n isLoading,\n error,\n\n // Getters\n defaultRegion,\n regionMap,\n activeCurrency,\n activeLocale,\n activeVatRate,\n activeTimezone,\n\n // Actions\n fetchRegions,\n setActiveRegion,\n getRegion,\n }\n})\n"],"version":3}

View File

@@ -1,21 +0,0 @@
import { hasInjectionContext, inject } from "vue";
import { useHead as useHead$1, headSymbol } from "/app/node_modules/@unhead/vue/dist/index.mjs";
import { t as tryUseNuxtApp } from "../server.mjs";
function injectHead(nuxtApp) {
const nuxt = nuxtApp || tryUseNuxtApp();
return nuxt?.ssrContext?.head || nuxt?.runWithContext(() => {
if (hasInjectionContext()) {
return inject(headSymbol);
}
});
}
function useHead(input, options = {}) {
const head = injectHead(options.nuxt);
if (head) {
return useHead$1(input, { head, ...options });
}
}
export {
useHead as u
};
//# sourceMappingURL=v3-DnDMBKvA.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"v3-DnDMBKvA.js","sources":["../../../../node_modules/nuxt/dist/head/runtime/composables/v3.js"],"sourcesContent":["import { hasInjectionContext, inject } from \"vue\";\nimport {\n useHead as headCore,\n useHeadSafe as headSafe,\n headSymbol,\n useSeoMeta as seoMeta,\n useServerHead as serverHead,\n useServerHeadSafe as serverHeadSafe,\n useServerSeoMeta as serverSeoMeta\n} from \"@unhead/vue\";\nimport { tryUseNuxtApp } from \"#app/nuxt\";\nexport function injectHead(nuxtApp) {\n const nuxt = nuxtApp || tryUseNuxtApp();\n return nuxt?.ssrContext?.head || nuxt?.runWithContext(() => {\n if (hasInjectionContext()) {\n return inject(headSymbol);\n }\n });\n}\nexport function useHead(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return headCore(input, { head, ...options });\n }\n}\nexport function useHeadSafe(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return headSafe(input, { head, ...options });\n }\n}\nexport function useSeoMeta(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return seoMeta(input, { head, ...options });\n }\n}\nexport function useServerHead(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return serverHead(input, { head, ...options });\n }\n}\nexport function useServerHeadSafe(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return serverHeadSafe(input, { head, ...options });\n }\n}\nexport function useServerSeoMeta(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return serverSeoMeta(input, { head, ...options });\n }\n}\n"],"names":["headCore"],"mappings":";;;AAWO,SAAS,WAAW,SAAS;AAClC,QAAM,OAAO,WAAW,cAAa;AACrC,SAAO,MAAM,YAAY,QAAQ,MAAM,eAAe,MAAM;AAC1D,QAAI,oBAAmB,GAAI;AACzB,aAAO,OAAO,UAAU;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;AACO,SAAS,QAAQ,OAAO,UAAU,IAAI;AAC3C,QAAM,OAAO,WAAW,QAAQ,IAAI;AACpC,MAAI,MAAM;AACR,WAAOA,UAAS,OAAO,EAAE,MAAM,GAAG,QAAO,CAAE;AAAA,EAC7C;AACF;","x_google_ignoreList":[0]}

View File

@@ -1 +0,0 @@
{"file":"v3-DnDMBKvA.js","mappings":";;;AAWO,SAAS,WAAW,SAAS;AAClC,QAAM,OAAO,WAAW,cAAa;AACrC,SAAO,MAAM,YAAY,QAAQ,MAAM,eAAe,MAAM;AAC1D,QAAI,oBAAmB,GAAI;AACzB,aAAO,OAAO,UAAU;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;AACO,SAAS,QAAQ,OAAO,UAAU,IAAI;AAC3C,QAAM,OAAO,WAAW,QAAQ,IAAI;AACpC,MAAI,MAAM;AACR,WAAOA,UAAS,OAAO,EAAE,MAAM,GAAG,QAAO,CAAE;AAAA,EAC7C;AACF;","names":["headCore"],"sources":["../../../../node_modules/nuxt/dist/head/runtime/composables/v3.js"],"sourcesContent":["import { hasInjectionContext, inject } from \"vue\";\nimport {\n useHead as headCore,\n useHeadSafe as headSafe,\n headSymbol,\n useSeoMeta as seoMeta,\n useServerHead as serverHead,\n useServerHeadSafe as serverHeadSafe,\n useServerSeoMeta as serverSeoMeta\n} from \"@unhead/vue\";\nimport { tryUseNuxtApp } from \"#app/nuxt\";\nexport function injectHead(nuxtApp) {\n const nuxt = nuxtApp || tryUseNuxtApp();\n return nuxt?.ssrContext?.head || nuxt?.runWithContext(() => {\n if (hasInjectionContext()) {\n return inject(headSymbol);\n }\n });\n}\nexport function useHead(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return headCore(input, { head, ...options });\n }\n}\nexport function useHeadSafe(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return headSafe(input, { head, ...options });\n }\n}\nexport function useSeoMeta(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return seoMeta(input, { head, ...options });\n }\n}\nexport function useServerHead(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return serverHead(input, { head, ...options });\n }\n}\nexport function useServerHeadSafe(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return serverHeadSafe(input, { head, ...options });\n }\n}\nexport function useServerSeoMeta(input, options = {}) {\n const head = injectHead(options.nuxt);\n if (head) {\n return serverSeoMeta(input, { head, ...options });\n }\n}\n"],"version":3}

View File

@@ -1 +1 @@
export default ({"_BoAo7BJa.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"BoAo7BJa.js",name:"cookie",imports:["node_modules/nuxt/dist/app/entry.js"]},"_ByPKVH1D.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"ByPKVH1D.js",name:"auth",imports:["node_modules/nuxt/dist/app/entry.js","_BoAo7BJa.js"]},"_Di-57MrI.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"Di-57MrI.js",name:"v3",imports:["node_modules/nuxt/dist/app/entry.js"]},"_QKJPEFuj.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"QKJPEFuj.js",name:"nuxt-link",imports:["node_modules/nuxt/dist/app/entry.js"]},"layouts/default.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"BW9w-mbE.js",name:"default",src:"layouts/default.vue",isDynamicEntry:!0,imports:["_QKJPEFuj.js","node_modules/nuxt/dist/app/entry.js","_ByPKVH1D.js","_BoAo7BJa.js"]},"middleware/auth.ts":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"BFfxzM5G.js",name:"auth",src:"middleware/auth.ts",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js","_BoAo7BJa.js"]},"node_modules/nuxt/dist/app/components/error-404.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"Oih3kTQ2.js",name:"error-404",src:"node_modules/nuxt/dist/app/components/error-404.vue",isDynamicEntry:!0,imports:["_QKJPEFuj.js","node_modules/nuxt/dist/app/entry.js","_Di-57MrI.js"],css:[]},"error-404.DL_4WIao.css":{file:"error-404.DL_4WIao.css",resourceType:"style",prefetch:!0,preload:!0},"node_modules/nuxt/dist/app/components/error-500.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"usmOON9X.js",name:"error-500",src:"node_modules/nuxt/dist/app/components/error-500.vue",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js","_Di-57MrI.js"],css:[]},"error-500.I1Dtv2V5.css":{file:"error-500.I1Dtv2V5.css",resourceType:"style",prefetch:!0,preload:!0},"node_modules/nuxt/dist/app/entry.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"C3Ck-LNv.js",name:"entry",src:"node_modules/nuxt/dist/app/entry.js",isEntry:!0,dynamicImports:["middleware/auth.ts","layouts/default.vue","node_modules/nuxt/dist/app/components/error-404.vue","node_modules/nuxt/dist/app/components/error-500.vue"],css:[]},"entry.KrfumMBl.css":{file:"entry.KrfumMBl.css",resourceType:"style",prefetch:!0,preload:!0},"pages/index.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"Drr7KP9v.js",name:"index",src:"pages/index.vue",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js"]},"pages/login.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"XMkMKtwS.js",name:"login",src:"pages/login.vue",isDynamicEntry:!0,imports:["_QKJPEFuj.js","node_modules/nuxt/dist/app/entry.js","_ByPKVH1D.js","_BoAo7BJa.js"]},"pages/permissions/index.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"CyOWWS80.js",name:"index",src:"pages/permissions/index.vue",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js"]}})
export default ({"_CWA6Xjbg.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"CWA6Xjbg.js",name:"auth",imports:["node_modules/nuxt/dist/app/entry.js"]},"_DWjNh9rV.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"DWjNh9rV.js",name:"region",imports:["node_modules/nuxt/dist/app/entry.js"]},"_Da4aCGAe.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"Da4aCGAe.js",name:"nuxt-link",imports:["node_modules/nuxt/dist/app/entry.js"]},"i18n/locales/en.json":{resourceType:"script",module:!0,prefetch:!1,preload:!1,file:"CgyjcGAF.js",name:"en",src:"i18n/locales/en.json",isDynamicEntry:!0},"i18n/locales/hu.json":{resourceType:"script",module:!0,prefetch:!1,preload:!1,file:"DP_n9i02.js",name:"hu",src:"i18n/locales/hu.json",isDynamicEntry:!0},"layouts/default.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"CC4zKGJo.js",name:"default",src:"layouts/default.vue",isDynamicEntry:!0,imports:["_Da4aCGAe.js","node_modules/nuxt/dist/app/entry.js","_DWjNh9rV.js","_CWA6Xjbg.js"]},"middleware/auth.ts":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"DuYZ8wdr.js",name:"auth",src:"middleware/auth.ts",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js"]},"node_modules/nuxt/dist/app/components/error-404.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"C8yzOtqa.js",name:"error-404",src:"node_modules/nuxt/dist/app/components/error-404.vue",isDynamicEntry:!0,imports:["_Da4aCGAe.js","node_modules/nuxt/dist/app/entry.js"],css:[]},"error-404.DL_4WIao.css":{file:"error-404.DL_4WIao.css",resourceType:"style",prefetch:!0,preload:!0},"node_modules/nuxt/dist/app/components/error-500.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"Cx40nPNe.js",name:"error-500",src:"node_modules/nuxt/dist/app/components/error-500.vue",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js"],css:[]},"error-500.I1Dtv2V5.css":{file:"error-500.I1Dtv2V5.css",resourceType:"style",prefetch:!0,preload:!0},"node_modules/nuxt/dist/app/entry.js":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"CqYPuxVf.js",name:"entry",src:"node_modules/nuxt/dist/app/entry.js",isEntry:!0,dynamicImports:["middleware/auth.ts","layouts/default.vue","i18n/locales/hu.json","i18n/locales/en.json","node_modules/nuxt/dist/app/components/error-404.vue","node_modules/nuxt/dist/app/components/error-500.vue"],css:[]},"entry.KrfumMBl.css":{file:"entry.KrfumMBl.css",resourceType:"style",prefetch:!0,preload:!0},"pages/garages/index.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"zPyClsoP.js",name:"index",src:"pages/garages/index.vue",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js"]},"pages/index.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"CqyNVJx6.js",name:"index",src:"pages/index.vue",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js"]},"pages/login.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"9W9VXtTt.js",name:"login",src:"pages/login.vue",isDynamicEntry:!0,imports:["_Da4aCGAe.js","node_modules/nuxt/dist/app/entry.js","_CWA6Xjbg.js"]},"pages/packages/index.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"ncKxzOzI.js",name:"index",src:"pages/packages/index.vue",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js","_DWjNh9rV.js"]},"pages/permissions/index.vue":{resourceType:"script",module:!0,prefetch:!0,preload:!0,file:"BO90Bn6x.js",name:"index",src:"pages/permissions/index.vue",isDynamicEntry:!0,imports:["node_modules/nuxt/dist/app/entry.js"]}})

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More