Initial reforms

This commit is contained in:
2026-09-19 17:23:11 +03:30
parent ab5ce96529
commit 8be9280721
57 changed files with 476 additions and 67 deletions
@@ -1 +1 @@
import{L as e,Z as t,ct as n,rt as r,vt as i,yt as a,z as o}from"./index-BHqDDh7X.js";import{t as s}from"./BaseSwitch-DYYNQNXf.js";function c(e=480){return new Promise(t=>{window.setTimeout(t,e)})}function l(e){let t=i(null),n=i(null),r=o();async function a(i,a){if(t.value)return a;let o=!a;if(!o&&e.confirmOff&&!await e.confirmOff())return a;t.value=i,n.value=null;let s=a;try{return await e.onPersist(o),r.success(e.successMessage?.(o)??(o?`وضعیت فعال شد.`:`وضعیت غیرفعال شد.`)),o}catch{return n.value=i,r.error(e.errorMessage??`به‌روزرسانی وضعیت انجام نشد.`),s}finally{t.value=null}}function s(e){return t.value===e}function c(e){return n.value===e}return{toggle:a,isLoading:s,hasError:c}}var u=r({__name:`ActiveSwitchCell`,props:{id:{},modelValue:{type:Boolean},entityName:{},entityType:{},persist:{type:Function}},emits:[`update:modelValue`],setup(r,{emit:i}){let o=r,u=i,{toggle:d,isLoading:f,hasError:p}=l({onPersist:async e=>{o.persist?await o.persist(o.id,e):await c()},successMessage:e=>e?`${o.entityType??`مورد`} «${o.entityName}» فعال شد.`:`${o.entityType??`مورد`} «${o.entityName}» غیرفعال شد.`});async function m(t){if(t===o.modelValue)return;let n=o.entityType??`مورد`;if(!await e({title:t?`فعال‌سازی ${n}`:`غیرفعال‌سازی ${n}`,message:t?`آیا از فعال کردن «${o.entityName}» مطمئن هستید؟`:`آیا از غیرفعال کردن «${o.entityName}» مطمئن هستید؟`,tone:t?`primary`:`danger`,confirmLabel:t?`فعال کردن`:`غیرفعال کردن`,cancelLabel:`انصراف`}))return;let r=await d(o.id,o.modelValue);u(`update:modelValue`,r)}return(e,i)=>(n(),t(s,{"model-value":r.modelValue,loading:a(f)(r.id),error:a(p)(r.id),"onUpdate:modelValue":m},null,8,[`model-value`,`loading`,`error`]))}});export{u as t};
import{L as e,Z as t,ct as n,rt as r,vt as i,yt as a,z as o}from"./index-9Ae_VOzQ.js";import{t as s}from"./BaseSwitch-D8k_9W00.js";function c(e=480){return new Promise(t=>{window.setTimeout(t,e)})}function l(e){let t=i(null),n=i(null),r=o();async function a(i,a){if(t.value)return a;let o=!a;if(!o&&e.confirmOff&&!await e.confirmOff())return a;t.value=i,n.value=null;let s=a;try{return await e.onPersist(o),r.success(e.successMessage?.(o)??(o?`وضعیت فعال شد.`:`وضعیت غیرفعال شد.`)),o}catch{return n.value=i,r.error(e.errorMessage??`به‌روزرسانی وضعیت انجام نشد.`),s}finally{t.value=null}}function s(e){return t.value===e}function c(e){return n.value===e}return{toggle:a,isLoading:s,hasError:c}}var u=r({__name:`ActiveSwitchCell`,props:{id:{},modelValue:{type:Boolean},entityName:{},entityType:{},persist:{type:Function}},emits:[`update:modelValue`],setup(r,{emit:i}){let o=r,u=i,{toggle:d,isLoading:f,hasError:p}=l({onPersist:async e=>{o.persist?await o.persist(o.id,e):await c()},successMessage:e=>e?`${o.entityType??`مورد`} «${o.entityName}» فعال شد.`:`${o.entityType??`مورد`} «${o.entityName}» غیرفعال شد.`});async function m(t){if(t===o.modelValue)return;let n=o.entityType??`مورد`;if(!await e({title:t?`فعال‌سازی ${n}`:`غیرفعال‌سازی ${n}`,message:t?`آیا از فعال کردن «${o.entityName}» مطمئن هستید؟`:`آیا از غیرفعال کردن «${o.entityName}» مطمئن هستید؟`,tone:t?`primary`:`danger`,confirmLabel:t?`فعال کردن`:`غیرفعال کردن`,cancelLabel:`انصراف`}))return;let r=await d(o.id,o.modelValue);u(`update:modelValue`,r)}return(e,i)=>(n(),t(s,{"model-value":r.modelValue,loading:a(f)(r.id),error:a(p)(r.id),"onUpdate:modelValue":m},null,8,[`model-value`,`loading`,`error`]))}});export{u as t};
@@ -1 +1 @@
import{$ as e,B as t,Y as n,bt as r,ct as i,o as a,rt as o,t as s}from"./index-BHqDDh7X.js";var c=[`id`,`value`,`placeholder`,`disabled`],l=t(o({__name:`AdminCurrencyInput`,props:{modelValue:{default:null},placeholder:{default:``},disabled:{type:Boolean,default:!1},id:{},inputClass:{default:`admin-input`},allowEmpty:{type:Boolean,default:!0}},emits:[`update:modelValue`],setup(t,{emit:o}){let l=t,u=o,d=n(()=>l.modelValue==null||!Number.isFinite(l.modelValue)?``:a(l.modelValue));function f(e){let t=e.target,n=s(t.value);if(!n){u(`update:modelValue`,l.allowEmpty?null:0),t.value=``;return}let r=Number(n);u(`update:modelValue`,r),t.value=a(r)}return(n,a)=>(i(),e(`input`,{id:t.id,type:`text`,inputmode:`numeric`,dir:`ltr`,class:r([`admin-currency-input`,t.inputClass]),value:d.value,placeholder:t.placeholder,disabled:t.disabled,onInput:f},null,42,c))}}),[[`__scopeId`,`data-v-56435fc8`]]);export{l as t};
import{$ as e,B as t,Y as n,bt as r,ct as i,o as a,rt as o,t as s}from"./index-9Ae_VOzQ.js";var c=[`id`,`value`,`placeholder`,`disabled`],l=t(o({__name:`AdminCurrencyInput`,props:{modelValue:{default:null},placeholder:{default:``},disabled:{type:Boolean,default:!1},id:{},inputClass:{default:`admin-input`},allowEmpty:{type:Boolean,default:!0}},emits:[`update:modelValue`],setup(t,{emit:o}){let l=t,u=o,d=n(()=>l.modelValue==null||!Number.isFinite(l.modelValue)?``:a(l.modelValue));function f(e){let t=e.target,n=s(t.value);if(!n){u(`update:modelValue`,l.allowEmpty?null:0),t.value=``;return}let r=Number(n);u(`update:modelValue`,r),t.value=a(r)}return(n,a)=>(i(),e(`input`,{id:t.id,type:`text`,inputmode:`numeric`,dir:`ltr`,class:r([`admin-currency-input`,t.inputClass]),value:d.value,placeholder:t.placeholder,disabled:t.disabled,onInput:f},null,42,c))}}),[[`__scopeId`,`data-v-56435fc8`]]);export{l as t};
+1
View File
@@ -0,0 +1 @@
.image-picker__label[data-v-05db5be7]{margin:0 0 8px;font-size:.8125rem;font-weight:600}.image-picker__row[data-v-05db5be7]{align-items:center;gap:12px;display:flex}.image-picker__preview[data-v-05db5be7]{border:1px solid var(--color-border);background:#e8eceb 50%/cover no-repeat;border-radius:10px;flex-shrink:0;width:88px;height:72px}.image-picker__preview--empty[data-v-05db5be7]{background:repeating-linear-gradient(45deg,#eef1f0,#eef1f0 8px,#e4e8e6 8px 16px)}.image-picker__actions[data-v-05db5be7]{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.image-picker__file[data-v-05db5be7]{display:none}.image-picker__error[data-v-05db5be7]{width:100%;color:var(--color-danger);margin:0;font-size:.75rem}.image-picker__ok[data-v-05db5be7]{width:100%;color:var(--color-success-dark);margin:0;font-size:.75rem;font-weight:600}
+1
View File
@@ -0,0 +1 @@
import{$ as e,B as t,Q as n,St as r,X as i,bt as a,ct as o,rt as s,vt as c,xt as l,yt as u}from"./index-9Ae_VOzQ.js";var d=960,f=.82;function p(e){let t=e.trim();return t?`url("${t.replace(/"/g,`\\"`)}")`:``}async function m(e){if(!e.type.startsWith(`image/`))throw Error(`فقط فایل تصویری مجاز است.`);if(e.size>8388608)throw Error(`حجم تصویر نباید بیشتر از ۸ مگابایت باشد.`);return g(await h(e))}function h(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result??``)),r.onerror=()=>n(Error(`خواندن تصویر ناموفق بود.`)),r.readAsDataURL(e)})}function g(e){return new Promise((t,n)=>{let r=new Image;r.onload=()=>{let e=Math.min(1,d/Math.max(r.width,r.height)),i=Math.max(1,Math.round(r.width*e)),a=Math.max(1,Math.round(r.height*e)),o=document.createElement(`canvas`);o.width=i,o.height=a;let s=o.getContext(`2d`);if(!s){n(Error(`پردازش تصویر ناموفق بود.`));return}s.drawImage(r,0,0,i,a),t(o.toDataURL(`image/jpeg`,f))},r.onerror=()=>n(Error(`تصویر نامعتبر است.`)),r.src=e})}var _={class:`image-picker`},v={key:0,class:`image-picker__label`},y={class:`image-picker__row`},b={class:`image-picker__actions`},x=[`disabled`],S=[`disabled`],C={key:1,class:`image-picker__error`},w={key:2,class:`image-picker__ok`},T=t(s({__name:`AdminImagePicker`,props:{modelValue:{},label:{}},emits:[`update:modelValue`],setup(t,{emit:s}){let d=t,f=s,h=c(null),g=c(!1),T=c(``),E=c(!1);function D(){h.value?.click()}async function O(e){let t=e.target,n=t.files?.[0];if(t.value=``,n){g.value=!0,T.value=``,E.value=!1;try{f(`update:modelValue`,await m(n)),E.value=!0}catch(e){T.value=e instanceof Error?e.message:`بارگذاری تصویر ناموفق بود.`}finally{g.value=!1}}}function k(){f(`update:modelValue`,null)}return(s,c)=>(o(),e(`div`,_,[t.label?(o(),e(`p`,v,r(t.label),1)):n(``,!0),i(`div`,y,[i(`div`,{class:a([`image-picker__preview`,{"image-picker__preview--empty":!d.modelValue}]),style:l(d.modelValue?{backgroundImage:u(p)(d.modelValue)}:void 0)},null,6),i(`div`,b,[i(`button`,{type:`button`,class:`admin-btn admin-btn--outline admin-btn--sm`,disabled:g.value,onClick:D},r(d.modelValue?`تغییر تصویر`:`افزودن تصویر`),9,x),d.modelValue?(o(),e(`button`,{key:0,type:`button`,class:`admin-btn admin-btn--outline admin-btn--sm`,disabled:g.value,onClick:k},` حذف `,8,S)):n(``,!0),T.value?(o(),e(`p`,C,r(T.value),1)):E.value?(o(),e(`p`,w,`تصویر انتخاب شد — برای ثبت نهایی «ذخیره» را بزنید.`)):n(``,!0)])]),i(`input`,{ref_key:`inputRef`,ref:h,type:`file`,accept:`image/*`,class:`image-picker__file`,onChange:O},null,544)]))}}),[[`__scopeId`,`data-v-05db5be7`]]);export{m as n,p as r,T as t};
-1
View File
@@ -1 +0,0 @@
.image-picker__label[data-v-55584001]{margin:0 0 8px;font-size:.8125rem;font-weight:600}.image-picker__row[data-v-55584001]{align-items:center;gap:12px;display:flex}.image-picker__preview[data-v-55584001]{border:1px solid var(--color-border);background:#e8eceb 50%/cover no-repeat;border-radius:10px;flex-shrink:0;width:88px;height:72px}.image-picker__preview--empty[data-v-55584001]{background:repeating-linear-gradient(45deg,#eef1f0,#eef1f0 8px,#e4e8e6 8px 16px)}.image-picker__actions[data-v-55584001]{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.image-picker__file[data-v-55584001]{display:none}.image-picker__error[data-v-55584001]{width:100%;color:var(--color-danger);margin:0;font-size:.75rem}
-1
View File
@@ -1 +0,0 @@
import{$ as e,B as t,Q as n,St as r,X as i,bt as a,ct as o,rt as s,vt as c,xt as l}from"./index-BHqDDh7X.js";var u=960,d=.82;async function f(e){if(!e.type.startsWith(`image/`))throw Error(`فقط فایل تصویری مجاز است.`);if(e.size>8388608)throw Error(`حجم تصویر نباید بیشتر از ۸ مگابایت باشد.`);return m(await p(e))}function p(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result??``)),r.onerror=()=>n(Error(`خواندن تصویر ناموفق بود.`)),r.readAsDataURL(e)})}function m(e){return new Promise((t,n)=>{let r=new Image;r.onload=()=>{let e=Math.min(1,u/Math.max(r.width,r.height)),i=Math.max(1,Math.round(r.width*e)),a=Math.max(1,Math.round(r.height*e)),o=document.createElement(`canvas`);o.width=i,o.height=a;let s=o.getContext(`2d`);if(!s){n(Error(`پردازش تصویر ناموفق بود.`));return}s.drawImage(r,0,0,i,a),t(o.toDataURL(`image/jpeg`,d))},r.onerror=()=>n(Error(`تصویر نامعتبر است.`)),r.src=e})}var h={class:`image-picker`},g={key:0,class:`image-picker__label`},_={class:`image-picker__row`},v={class:`image-picker__actions`},y=[`disabled`],b=[`disabled`],x={key:1,class:`image-picker__error`},S=t(s({__name:`AdminImagePicker`,props:{modelValue:{},label:{}},emits:[`update:modelValue`],setup(t,{emit:s}){let u=t,d=s,p=c(null),m=c(!1),S=c(``);function C(){p.value?.click()}async function w(e){let t=e.target,n=t.files?.[0];if(t.value=``,n){m.value=!0,S.value=``;try{d(`update:modelValue`,await f(n))}catch(e){S.value=e instanceof Error?e.message:`بارگذاری تصویر ناموفق بود.`}finally{m.value=!1}}}function T(){d(`update:modelValue`,null)}return(s,c)=>(o(),e(`div`,h,[t.label?(o(),e(`p`,g,r(t.label),1)):n(``,!0),i(`div`,_,[i(`div`,{class:a([`image-picker__preview`,{"image-picker__preview--empty":!u.modelValue}]),style:l(u.modelValue?{backgroundImage:`url(${u.modelValue})`}:void 0)},null,6),i(`div`,v,[i(`button`,{type:`button`,class:`admin-btn admin-btn--outline admin-btn--sm`,disabled:m.value,onClick:C},r(u.modelValue?`تغییر تصویر`:`افزودن تصویر`),9,y),u.modelValue?(o(),e(`button`,{key:0,type:`button`,class:`admin-btn admin-btn--outline admin-btn--sm`,disabled:m.value,onClick:T},` حذف `,8,b)):n(``,!0),S.value?(o(),e(`p`,x,r(S.value),1)):n(``,!0)])]),i(`input`,{ref_key:`inputRef`,ref:p,type:`file`,accept:`image/*`,class:`image-picker__file`,onChange:w},null,544)]))}}),[[`__scopeId`,`data-v-55584001`]]);export{f as n,S as t};
@@ -1 +1 @@
import{$ as e,B as t,X as n,ct as r,et as i,q as a,rt as o,ut as s}from"./index-BHqDDh7X.js";var c={class:`admin-page-skeleton`,role:`status`,"aria-live":`polite`,"aria-busy":`true`,"aria-label":`در حال بارگذاری`},l={class:`admin-card admin-page-skeleton__table`},u={key:1,class:`admin-card admin-page-skeleton__form`},d={key:2,class:`admin-card admin-page-skeleton__detail`},f={key:3,class:`admin-page-skeleton__cards`},p=t(o({__name:`AdminPageSkeleton`,props:{variant:{default:`cards`},rows:{default:5}},setup(t){return(o,p)=>(r(),e(`div`,c,[t.variant===`table`?(r(),e(a,{key:0},[p[1]||=n(`div`,{class:`admin-page-skeleton__toolbar`},[n(`span`,{class:`admin-skeleton admin-page-skeleton__search`}),n(`span`,{class:`admin-skeleton admin-page-skeleton__btn`})],-1),n(`div`,l,[(r(!0),e(a,null,s(t.rows,t=>(r(),e(`div`,{key:t,class:`admin-page-skeleton__tr`},[...p[0]||=[i(`<span class="admin-skeleton" style="width:18%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:22%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:14%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:16%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:12%;height:12px;" data-v-8283cd1d></span>`,5)]]))),128))])],64)):t.variant===`form`?(r(),e(`div`,u,[(r(!0),e(a,null,s(t.rows,t=>(r(),e(`div`,{key:t,class:`admin-page-skeleton__field`},[...p[2]||=[n(`span`,{class:`admin-skeleton`,style:{width:`28%`,height:`10px`}},null,-1),n(`span`,{class:`admin-skeleton`,style:{width:`100%`,height:`40px`,"border-radius":`10px`}},null,-1)]]))),128))])):t.variant===`detail`?(r(),e(`div`,d,[...p[3]||=[i(`<span class="admin-skeleton" style="width:40%;height:18px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:70%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:100%;height:120px;border-radius:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:100%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:88%;height:12px;" data-v-8283cd1d></span>`,5)]])):(r(),e(`div`,f,[(r(!0),e(a,null,s(t.rows,t=>(r(),e(`div`,{key:t,class:`admin-card admin-page-skeleton__card`},[...p[4]||=[n(`span`,{class:`admin-skeleton`,style:{width:`45%`,height:`14px`}},null,-1),n(`span`,{class:`admin-skeleton`,style:{width:`70%`,height:`11px`}},null,-1),n(`span`,{class:`admin-skeleton`,style:{width:`35%`,height:`11px`}},null,-1)]]))),128))]))]))}}),[[`__scopeId`,`data-v-8283cd1d`]]);export{p as t};
import{$ as e,B as t,X as n,ct as r,et as i,q as a,rt as o,ut as s}from"./index-9Ae_VOzQ.js";var c={class:`admin-page-skeleton`,role:`status`,"aria-live":`polite`,"aria-busy":`true`,"aria-label":`در حال بارگذاری`},l={class:`admin-card admin-page-skeleton__table`},u={key:1,class:`admin-card admin-page-skeleton__form`},d={key:2,class:`admin-card admin-page-skeleton__detail`},f={key:3,class:`admin-page-skeleton__cards`},p=t(o({__name:`AdminPageSkeleton`,props:{variant:{default:`cards`},rows:{default:5}},setup(t){return(o,p)=>(r(),e(`div`,c,[t.variant===`table`?(r(),e(a,{key:0},[p[1]||=n(`div`,{class:`admin-page-skeleton__toolbar`},[n(`span`,{class:`admin-skeleton admin-page-skeleton__search`}),n(`span`,{class:`admin-skeleton admin-page-skeleton__btn`})],-1),n(`div`,l,[(r(!0),e(a,null,s(t.rows,t=>(r(),e(`div`,{key:t,class:`admin-page-skeleton__tr`},[...p[0]||=[i(`<span class="admin-skeleton" style="width:18%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:22%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:14%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:16%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:12%;height:12px;" data-v-8283cd1d></span>`,5)]]))),128))])],64)):t.variant===`form`?(r(),e(`div`,u,[(r(!0),e(a,null,s(t.rows,t=>(r(),e(`div`,{key:t,class:`admin-page-skeleton__field`},[...p[2]||=[n(`span`,{class:`admin-skeleton`,style:{width:`28%`,height:`10px`}},null,-1),n(`span`,{class:`admin-skeleton`,style:{width:`100%`,height:`40px`,"border-radius":`10px`}},null,-1)]]))),128))])):t.variant===`detail`?(r(),e(`div`,d,[...p[3]||=[i(`<span class="admin-skeleton" style="width:40%;height:18px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:70%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:100%;height:120px;border-radius:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:100%;height:12px;" data-v-8283cd1d></span><span class="admin-skeleton" style="width:88%;height:12px;" data-v-8283cd1d></span>`,5)]])):(r(),e(`div`,f,[(r(!0),e(a,null,s(t.rows,t=>(r(),e(`div`,{key:t,class:`admin-card admin-page-skeleton__card`},[...p[4]||=[n(`span`,{class:`admin-skeleton`,style:{width:`45%`,height:`14px`}},null,-1),n(`span`,{class:`admin-skeleton`,style:{width:`70%`,height:`11px`}},null,-1),n(`span`,{class:`admin-skeleton`,style:{width:`35%`,height:`11px`}},null,-1)]]))),128))]))]))}}),[[`__scopeId`,`data-v-8283cd1d`]]);export{p as t};
@@ -1 +1 @@
import{$ as e,B as t,G as n,J as r,K as i,O as a,P as o,Q as s,St as c,W as l,X as u,Y as d,Z as f,at as p,bt as m,ct as h,ht as g,nt as _,pt as v,q as y,rt as b,st as x,ut as S,vt as C,xt as w}from"./index-BHqDDh7X.js";var T=[`id`],E=[`aria-label`,`aria-expanded`],D={class:`admin-select__value`},O={class:`admin-select__chevron`,"aria-hidden":`true`},k=[`aria-label`],A={key:0,class:`admin-select__search`,role:`presentation`},j=[`placeholder`],M={key:1,class:`admin-select__empty`,role:`presentation`},N=[`aria-selected`,`onClick`],P=t(b({__name:`AdminSelect`,props:{modelValue:{},options:{},placeholder:{default:`انتخاب کنید`},ariaLabel:{default:`انتخاب`},block:{type:Boolean,default:!1},searchable:{type:Boolean,default:!1},searchPlaceholder:{default:`جستجو…`},id:{default:void 0}},emits:[`update:modelValue`],setup(t,{emit:b}){let P=t,F=b,I=C(!1),L=C(``),R=C(null),z=C(null),B=C(null),V=C({});a(R,()=>{I.value=!1,L.value=``},{ignore:[z]});let H=d(()=>P.options.find(e=>e.value===P.modelValue)?.label??P.placeholder),U=d(()=>{let e=L.value.trim().toLowerCase();return e?P.options.filter(t=>t.label.toLowerCase().includes(e)):P.options});function W(){let e=R.value;if(!e)return;let t=e.getBoundingClientRect(),n=Math.min(320,window.innerHeight*.5),r=window.innerHeight-t.bottom-6,i=t.top-6,a=r<Math.min(160,n)&&i>r,o=Math.max(120,Math.min(n,a?i:r));V.value={position:`fixed`,left:`${Math.max(8,Math.min(t.left,window.innerWidth-Math.max(t.width,220)-8))}px`,width:`${Math.max(t.width,220)}px`,zIndex:`1100`,maxHeight:`${o}px`,...a?{top:`auto`,bottom:`${window.innerHeight-t.top+6}px`}:{top:`${t.bottom+6}px`,bottom:`auto`}}}function G(e){e?(window.addEventListener(`resize`,W),window.addEventListener(`scroll`,W,!0)):(window.removeEventListener(`resize`,W),window.removeEventListener(`scroll`,W,!0))}async function K(){I.value=!I.value,I.value&&(await p(),W(),P.searchable&&(L.value=``,await p(),B.value?.focus()))}function q(e){F(`update:modelValue`,e),I.value=!1,L.value=``}return v(I,e=>{G(e),e&&p(()=>W())}),x(()=>{G(!1)}),(a,d)=>(h(),e(`div`,{id:t.id,ref_key:`rootRef`,ref:R,class:m([`admin-select`,{"admin-select--open":I.value,"admin-select--block":t.block}])},[u(`button`,{type:`button`,class:`admin-select__trigger`,"aria-label":t.ariaLabel,"aria-expanded":I.value,"aria-haspopup":`listbox`,onClick:K},[u(`span`,D,c(H.value),1),u(`span`,O,[_(o,{name:`chevron-down`,size:16})])],8,E),(h(),f(r,{to:`body`},[I.value?(h(),e(`ul`,{key:0,ref_key:`menuRef`,ref:z,class:`admin-select__menu`,role:`listbox`,"aria-label":t.ariaLabel,style:w(V.value)},[t.searchable?(h(),e(`li`,A,[g(u(`input`,{ref_key:`searchInputRef`,ref:B,"onUpdate:modelValue":d[0]||=e=>L.value=e,type:`search`,class:`admin-select__search-input`,placeholder:t.searchPlaceholder,onClick:d[1]||=i(()=>{},[`stop`]),onKeydown:d[2]||=n(i(e=>I.value=!1,[`stop`]),[`esc`])},null,40,j),[[l,L.value]])])):s(``,!0),U.value.length?s(``,!0):(h(),e(`li`,M,` موردی یافت نشد `)),(h(!0),e(y,null,S(U.value,n=>(h(),e(`li`,{key:n.value,role:`presentation`},[u(`button`,{type:`button`,class:m([`admin-select__option`,{"admin-select__option--active":n.value===t.modelValue}]),role:`option`,"aria-selected":n.value===t.modelValue,onClick:e=>q(n.value)},[u(`span`,null,c(n.label),1),n.value===t.modelValue?(h(),f(o,{key:0,name:`check`,size:16,class:`admin-select__check`})):s(``,!0)],10,N)]))),128))],12,k)):s(``,!0)]))],10,T))}}),[[`__scopeId`,`data-v-7f43c8c3`]]);export{P as t};
import{$ as e,B as t,G as n,J as r,K as i,O as a,P as o,Q as s,St as c,W as l,X as u,Y as d,Z as f,at as p,bt as m,ct as h,ht as g,nt as _,pt as v,q as y,rt as b,st as x,ut as S,vt as C,xt as w}from"./index-9Ae_VOzQ.js";var T=[`id`],E=[`aria-label`,`aria-expanded`],D={class:`admin-select__value`},O={class:`admin-select__chevron`,"aria-hidden":`true`},k=[`aria-label`],A={key:0,class:`admin-select__search`,role:`presentation`},j=[`placeholder`],M={key:1,class:`admin-select__empty`,role:`presentation`},N=[`aria-selected`,`onClick`],P=t(b({__name:`AdminSelect`,props:{modelValue:{},options:{},placeholder:{default:`انتخاب کنید`},ariaLabel:{default:`انتخاب`},block:{type:Boolean,default:!1},searchable:{type:Boolean,default:!1},searchPlaceholder:{default:`جستجو…`},id:{default:void 0}},emits:[`update:modelValue`],setup(t,{emit:b}){let P=t,F=b,I=C(!1),L=C(``),R=C(null),z=C(null),B=C(null),V=C({});a(R,()=>{I.value=!1,L.value=``},{ignore:[z]});let H=d(()=>P.options.find(e=>e.value===P.modelValue)?.label??P.placeholder),U=d(()=>{let e=L.value.trim().toLowerCase();return e?P.options.filter(t=>t.label.toLowerCase().includes(e)):P.options});function W(){let e=R.value;if(!e)return;let t=e.getBoundingClientRect(),n=Math.min(320,window.innerHeight*.5),r=window.innerHeight-t.bottom-6,i=t.top-6,a=r<Math.min(160,n)&&i>r,o=Math.max(120,Math.min(n,a?i:r));V.value={position:`fixed`,left:`${Math.max(8,Math.min(t.left,window.innerWidth-Math.max(t.width,220)-8))}px`,width:`${Math.max(t.width,220)}px`,zIndex:`1100`,maxHeight:`${o}px`,...a?{top:`auto`,bottom:`${window.innerHeight-t.top+6}px`}:{top:`${t.bottom+6}px`,bottom:`auto`}}}function G(e){e?(window.addEventListener(`resize`,W),window.addEventListener(`scroll`,W,!0)):(window.removeEventListener(`resize`,W),window.removeEventListener(`scroll`,W,!0))}async function K(){I.value=!I.value,I.value&&(await p(),W(),P.searchable&&(L.value=``,await p(),B.value?.focus()))}function q(e){F(`update:modelValue`,e),I.value=!1,L.value=``}return v(I,e=>{G(e),e&&p(()=>W())}),x(()=>{G(!1)}),(a,d)=>(h(),e(`div`,{id:t.id,ref_key:`rootRef`,ref:R,class:m([`admin-select`,{"admin-select--open":I.value,"admin-select--block":t.block}])},[u(`button`,{type:`button`,class:`admin-select__trigger`,"aria-label":t.ariaLabel,"aria-expanded":I.value,"aria-haspopup":`listbox`,onClick:K},[u(`span`,D,c(H.value),1),u(`span`,O,[_(o,{name:`chevron-down`,size:16})])],8,E),(h(),f(r,{to:`body`},[I.value?(h(),e(`ul`,{key:0,ref_key:`menuRef`,ref:z,class:`admin-select__menu`,role:`listbox`,"aria-label":t.ariaLabel,style:w(V.value)},[t.searchable?(h(),e(`li`,A,[g(u(`input`,{ref_key:`searchInputRef`,ref:B,"onUpdate:modelValue":d[0]||=e=>L.value=e,type:`search`,class:`admin-select__search-input`,placeholder:t.searchPlaceholder,onClick:d[1]||=i(()=>{},[`stop`]),onKeydown:d[2]||=n(i(e=>I.value=!1,[`stop`]),[`esc`])},null,40,j),[[l,L.value]])])):s(``,!0),U.value.length?s(``,!0):(h(),e(`li`,M,` موردی یافت نشد `)),(h(!0),e(y,null,S(U.value,n=>(h(),e(`li`,{key:n.value,role:`presentation`},[u(`button`,{type:`button`,class:m([`admin-select__option`,{"admin-select__option--active":n.value===t.modelValue}]),role:`option`,"aria-selected":n.value===t.modelValue,onClick:e=>q(n.value)},[u(`span`,null,c(n.label),1),n.value===t.modelValue?(h(),f(o,{key:0,name:`check`,size:16,class:`admin-select__check`})):s(``,!0)],10,N)]))),128))],12,k)):s(``,!0)]))],10,T))}}),[[`__scopeId`,`data-v-7f43c8c3`]]);export{P as t};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{$ as e,B as t,P as n,Q as r,St as i,X as a,bt as o,ct as s,dt as c,nt as l,rt as u}from"./index-BHqDDh7X.js";var d={class:`base-empty__icon`,"aria-hidden":`true`},f={class:`base-empty__title`},p={key:0,class:`base-empty__description`},m={key:1,class:`base-empty__actions`},h=t(u({__name:`BaseEmptyState`,props:{icon:{default:`file`},title:{},description:{},compact:{type:Boolean}},emits:[`action`,`secondary`],setup(t){return(u,h)=>(s(),e(`div`,{class:o([`base-empty`,{"base-empty--compact":t.compact}])},[a(`div`,d,[l(n,{name:t.icon,size:t.compact?28:36},null,8,[`name`,`size`])]),a(`h3`,f,i(t.title),1),t.description?(s(),e(`p`,p,i(t.description),1)):r(``,!0),u.$slots.default||u.$slots.secondary?(s(),e(`div`,m,[c(u.$slots,`default`,{},void 0,!0),c(u.$slots,`secondary`,{},void 0,!0)])):r(``,!0)],2))}}),[[`__scopeId`,`data-v-47ea81e4`]]);export{h as t};
import{$ as e,B as t,P as n,Q as r,St as i,X as a,bt as o,ct as s,dt as c,nt as l,rt as u}from"./index-9Ae_VOzQ.js";var d={class:`base-empty__icon`,"aria-hidden":`true`},f={class:`base-empty__title`},p={key:0,class:`base-empty__description`},m={key:1,class:`base-empty__actions`},h=t(u({__name:`BaseEmptyState`,props:{icon:{default:`file`},title:{},description:{},compact:{type:Boolean}},emits:[`action`,`secondary`],setup(t){return(u,h)=>(s(),e(`div`,{class:o([`base-empty`,{"base-empty--compact":t.compact}])},[a(`div`,d,[l(n,{name:t.icon,size:t.compact?28:36},null,8,[`name`,`size`])]),a(`h3`,f,i(t.title),1),t.description?(s(),e(`p`,p,i(t.description),1)):r(``,!0),u.$slots.default||u.$slots.secondary?(s(),e(`div`,m,[c(u.$slots,`default`,{},void 0,!0),c(u.$slots,`secondary`,{},void 0,!0)])):r(``,!0)],2))}}),[[`__scopeId`,`data-v-47ea81e4`]]);export{h as t};
@@ -1 +1 @@
import{$ as e,B as t,Q as n,St as r,X as i,Y as a,bt as o,ct as s,rt as c}from"./index-BHqDDh7X.js";var l=[`title`],u={key:0,class:`base-switch__label`},d={class:`base-switch__control`},f=[`id`,`checked`,`disabled`,`aria-checked`,`aria-label`],p={class:`base-switch__track`,"aria-hidden":`true`},m={class:`base-switch__thumb`},h={key:0,class:`base-switch__spinner`},g=t(c({__name:`BaseSwitch`,props:{modelValue:{type:Boolean},disabled:{type:Boolean},loading:{type:Boolean},error:{type:Boolean},label:{},activeText:{default:`فعال`},inactiveText:{default:`غیرفعال`},id:{}},emits:[`update:modelValue`],setup(t,{emit:c}){let g=t,_=c,v=a(()=>g.id??`switch-${crypto.randomUUID().slice(0,8)}`),y=a(()=>g.modelValue?g.activeText:g.inactiveText);function b(e){let t=e.target,n=t.checked;t.checked=g.modelValue,!(g.disabled||g.loading)&&_(`update:modelValue`,n)}return(a,c)=>(s(),e(`label`,{class:o([`base-switch`,{"base-switch--disabled":t.disabled||t.loading,"base-switch--error":t.error}]),title:y.value},[t.label?(s(),e(`span`,u,r(t.label),1)):n(``,!0),i(`span`,d,[i(`input`,{id:v.value,class:`base-switch__input`,type:`checkbox`,role:`switch`,checked:t.modelValue,disabled:t.disabled||t.loading,"aria-checked":t.modelValue,"aria-label":t.label||y.value,onChange:b},null,40,f),i(`span`,p,[i(`span`,m,[t.loading?(s(),e(`span`,h)):n(``,!0)])])])],10,l))}}),[[`__scopeId`,`data-v-0410eed4`]]);export{g as t};
import{$ as e,B as t,Q as n,St as r,X as i,Y as a,bt as o,ct as s,rt as c}from"./index-9Ae_VOzQ.js";var l=[`title`],u={key:0,class:`base-switch__label`},d={class:`base-switch__control`},f=[`id`,`checked`,`disabled`,`aria-checked`,`aria-label`],p={class:`base-switch__track`,"aria-hidden":`true`},m={class:`base-switch__thumb`},h={key:0,class:`base-switch__spinner`},g=t(c({__name:`BaseSwitch`,props:{modelValue:{type:Boolean},disabled:{type:Boolean},loading:{type:Boolean},error:{type:Boolean},label:{},activeText:{default:`فعال`},inactiveText:{default:`غیرفعال`},id:{}},emits:[`update:modelValue`],setup(t,{emit:c}){let g=t,_=c,v=a(()=>g.id??`switch-${crypto.randomUUID().slice(0,8)}`),y=a(()=>g.modelValue?g.activeText:g.inactiveText);function b(e){let t=e.target,n=t.checked;t.checked=g.modelValue,!(g.disabled||g.loading)&&_(`update:modelValue`,n)}return(a,c)=>(s(),e(`label`,{class:o([`base-switch`,{"base-switch--disabled":t.disabled||t.loading,"base-switch--error":t.error}]),title:y.value},[t.label?(s(),e(`span`,u,r(t.label),1)):n(``,!0),i(`span`,d,[i(`input`,{id:v.value,class:`base-switch__input`,type:`checkbox`,role:`switch`,checked:t.modelValue,disabled:t.disabled||t.loading,"aria-checked":t.modelValue,"aria-label":t.label||y.value,onChange:b},null,40,f),i(`span`,p,[i(`span`,m,[t.loading?(s(),e(`span`,h)):n(``,!0)])])])],10,l))}}),[[`__scopeId`,`data-v-0410eed4`]]);export{g as t};
@@ -1 +1 @@
import{$ as e,B as t,N as n,R as r,St as i,W as a,X as o,Y as s,Z as c,_t as l,ct as u,ht as d,mt as f,nt as p,ot as m,q as h,rt as g,tt as _,u as v,ut as y,vt as b,z as x}from"./index-BHqDDh7X.js";import{t as S}from"./AdminPageSkeleton-E50Kwv4j.js";import{t as C}from"./BaseSwitch-DYYNQNXf.js";import{t as w}from"./BaseEmptyState-vNIhbGdV.js";var T={class:`admin-page`},E={key:2,class:`admin-table`},D={dir:`ltr`},O=[`onClick`],k={class:`field`},A={class:`field`},j={class:`field`},M={class:`field`},N=[`disabled`],P=t(g({__name:`BrandsView`,setup(t){let g=b([]),P=b(!0),F=b(!1),I=b(null),L=x(),R=l({name:``,slug:``,description:``,displayOrder:0,isActive:!0}),z=s(()=>I.value?`ویرایش برند`:`افزودن برند`);async function B(){P.value=!0;try{g.value=await v.list()}catch(e){L.error(e instanceof n?e.message:`بارگذاری برندها ناموفق بود`)}finally{P.value=!1}}function V(){I.value=null,Object.assign(R,{name:``,slug:``,description:``,displayOrder:g.value.length+1,isActive:!0}),F.value=!0}function H(e){I.value=e.id,Object.assign(R,{name:e.name,slug:e.slug??``,description:e.description??``,displayOrder:e.displayOrder,isActive:e.isActive}),F.value=!0}async function U(){try{let e={name:R.name.trim(),slug:R.slug.trim()||void 0,description:R.description.trim()||void 0,displayOrder:R.displayOrder,isActive:R.isActive};I.value?await v.update(I.value,e):await v.create(e),F.value=!1,L.success(`ذخیره شد`),await B()}catch(e){L.error(e instanceof n?e.message:`ذخیره ناموفق بود`)}}return m(()=>{B()}),(t,n)=>(u(),e(`div`,T,[o(`header`,{class:`admin-page__head`},[n[6]||=o(`div`,null,[o(`h1`,null,`برندها`)],-1),o(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:V},`افزودن برند`)]),P.value?(u(),c(S,{key:0,variant:`table`})):g.value.length?(u(),e(`table`,E,[n[7]||=o(`thead`,null,[o(`tr`,null,[o(`th`,null,`نام`),o(`th`,null,`شناسه لاتین`),o(`th`,null,`مشتریان`),o(`th`,null,`فعال`),o(`th`)])],-1),o(`tbody`,null,[(u(!0),e(h,null,y(g.value,t=>(u(),e(`tr`,{key:t.id},[o(`td`,null,i(t.name),1),o(`td`,D,i(t.slug||`—`),1),o(`td`,null,i(t.customersCount??0),1),o(`td`,null,i(t.isActive?`بله`:`خیر`),1),o(`td`,null,[o(`button`,{type:`button`,class:`link`,onClick:e=>H(t)},`ویرایش`,8,O)])]))),128))])])):(u(),c(w,{key:1,title:`برندی ثبت نشده`})),p(r,{open:F.value,title:z.value,onClose:n[5]||=e=>F.value=!1},{footer:f(()=>[o(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!R.name.trim(),onClick:U},`ذخیره`,8,N)]),default:f(()=>[o(`label`,k,[n[8]||=_(`نام`,-1),d(o(`input`,{"onUpdate:modelValue":n[0]||=e=>R.name=e,class:`admin-input`},null,512),[[a,R.name]])]),o(`label`,A,[n[9]||=_(`شناسه لاتین`,-1),d(o(`input`,{"onUpdate:modelValue":n[1]||=e=>R.slug=e,class:`admin-input`,dir:`ltr`,placeholder:`مثلاً nademi-silk`},null,512),[[a,R.slug]])]),o(`label`,j,[n[10]||=_(`توضیح`,-1),d(o(`textarea`,{"onUpdate:modelValue":n[2]||=e=>R.description=e,class:`admin-input`,rows:`3`},null,512),[[a,R.description]])]),o(`label`,M,[n[11]||=_(`ترتیب`,-1),d(o(`input`,{"onUpdate:modelValue":n[3]||=e=>R.displayOrder=e,type:`number`,class:`admin-input`},null,512),[[a,R.displayOrder,void 0,{number:!0}]])]),p(C,{modelValue:R.isActive,"onUpdate:modelValue":n[4]||=e=>R.isActive=e,label:`فعال`},null,8,[`modelValue`])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-88043806`]]);export{P as default};
import{$ as e,B as t,N as n,R as r,St as i,W as a,X as o,Y as s,Z as c,_t as l,ct as u,ht as d,mt as f,nt as p,ot as m,q as h,rt as g,tt as _,u as v,ut as y,vt as b,z as x}from"./index-9Ae_VOzQ.js";import{t as S}from"./AdminPageSkeleton-CKg1wrlm.js";import{t as C}from"./BaseSwitch-D8k_9W00.js";import{t as w}from"./BaseEmptyState-DLwJ8N61.js";var T={class:`admin-page`},E={key:2,class:`admin-table`},D={dir:`ltr`},O=[`onClick`],k={class:`field`},A={class:`field`},j={class:`field`},M={class:`field`},N=[`disabled`],P=t(g({__name:`BrandsView`,setup(t){let g=b([]),P=b(!0),F=b(!1),I=b(null),L=x(),R=l({name:``,slug:``,description:``,displayOrder:0,isActive:!0}),z=s(()=>I.value?`ویرایش برند`:`افزودن برند`);async function B(){P.value=!0;try{g.value=await v.list()}catch(e){L.error(e instanceof n?e.message:`بارگذاری برندها ناموفق بود`)}finally{P.value=!1}}function V(){I.value=null,Object.assign(R,{name:``,slug:``,description:``,displayOrder:g.value.length+1,isActive:!0}),F.value=!0}function H(e){I.value=e.id,Object.assign(R,{name:e.name,slug:e.slug??``,description:e.description??``,displayOrder:e.displayOrder,isActive:e.isActive}),F.value=!0}async function U(){try{let e={name:R.name.trim(),slug:R.slug.trim()||void 0,description:R.description.trim()||void 0,displayOrder:R.displayOrder,isActive:R.isActive};I.value?await v.update(I.value,e):await v.create(e),F.value=!1,L.success(`ذخیره شد`),await B()}catch(e){L.error(e instanceof n?e.message:`ذخیره ناموفق بود`)}}return m(()=>{B()}),(t,n)=>(u(),e(`div`,T,[o(`header`,{class:`admin-page__head`},[n[6]||=o(`div`,null,[o(`h1`,null,`برندها`)],-1),o(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:V},`افزودن برند`)]),P.value?(u(),c(S,{key:0,variant:`table`})):g.value.length?(u(),e(`table`,E,[n[7]||=o(`thead`,null,[o(`tr`,null,[o(`th`,null,`نام`),o(`th`,null,`شناسه لاتین`),o(`th`,null,`مشتریان`),o(`th`,null,`فعال`),o(`th`)])],-1),o(`tbody`,null,[(u(!0),e(h,null,y(g.value,t=>(u(),e(`tr`,{key:t.id},[o(`td`,null,i(t.name),1),o(`td`,D,i(t.slug||`—`),1),o(`td`,null,i(t.customersCount??0),1),o(`td`,null,i(t.isActive?`بله`:`خیر`),1),o(`td`,null,[o(`button`,{type:`button`,class:`link`,onClick:e=>H(t)},`ویرایش`,8,O)])]))),128))])])):(u(),c(w,{key:1,title:`برندی ثبت نشده`})),p(r,{open:F.value,title:z.value,onClose:n[5]||=e=>F.value=!1},{footer:f(()=>[o(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!R.name.trim(),onClick:U},`ذخیره`,8,N)]),default:f(()=>[o(`label`,k,[n[8]||=_(`نام`,-1),d(o(`input`,{"onUpdate:modelValue":n[0]||=e=>R.name=e,class:`admin-input`},null,512),[[a,R.name]])]),o(`label`,A,[n[9]||=_(`شناسه لاتین`,-1),d(o(`input`,{"onUpdate:modelValue":n[1]||=e=>R.slug=e,class:`admin-input`,dir:`ltr`,placeholder:`مثلاً nademi-silk`},null,512),[[a,R.slug]])]),o(`label`,j,[n[10]||=_(`توضیح`,-1),d(o(`textarea`,{"onUpdate:modelValue":n[2]||=e=>R.description=e,class:`admin-input`,rows:`3`},null,512),[[a,R.description]])]),o(`label`,M,[n[11]||=_(`ترتیب`,-1),d(o(`input`,{"onUpdate:modelValue":n[3]||=e=>R.displayOrder=e,type:`number`,class:`admin-input`},null,512),[[a,R.displayOrder,void 0,{number:!0}]])]),p(C,{modelValue:R.isActive,"onUpdate:modelValue":n[4]||=e=>R.isActive=e,label:`فعال`},null,8,[`modelValue`])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-88043806`]]);export{P as default};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{$ as e,B as t,N as n,Q as r,St as i,X as a,Z as o,ct as s,f as c,i as l,nt as u,ot as d,q as f,rt as p,tt as m,ut as h,vt as g,yt as _,z as v}from"./index-BHqDDh7X.js";import{t as y}from"./AdminPageSkeleton-E50Kwv4j.js";import{t as b}from"./BaseEmptyState-vNIhbGdV.js";import{t as x}from"./AdminSelect-BjB6PHdr.js";var S={class:`admin-page`},C={class:`admin-page__head`},w={class:`request-card__top`},T={class:`muted`,dir:`ltr`},E={class:`badge`},D={key:0,class:`muted`},O={class:`admin-table`},k={dir:`ltr`},A={key:0,class:`movements`},j={class:`muted`},M=t(p({__name:`CatalogRequestsView`,setup(t){let p=[{value:``,label:`همه وضعیت‌ها`},{value:`new`,label:`درخواست جدید`},{value:`approved`,label:`تأیید شده`},{value:`ready_to_ship`,label:`آماده ارسال`},{value:`delivered`,label:`تحویل به مشتری`},{value:`returned`,label:`بازگردانده شده`},{value:`cancelled`,label:`لغو شده`}],M=[{value:`warehouse`,label:`انبار`},{value:`customer`,label:`مشتری`},{value:`agent`,label:`واسطه`}],N=Object.fromEntries(p.filter(e=>e.value).map(e=>[e.value,e.label])),P=Object.fromEntries(M.map(e=>[e.value,e.label])),F=g([]),I=g(``),L=g(!0),R=g(null),z=v();async function B(){L.value=!0;try{F.value=await c.list(I.value||void 0)}catch(e){z.error(e instanceof n?e.message:`بارگذاری انجام نشد`)}finally{L.value=!1}}async function V(e,t){try{await c.updateStatus(e,t),z.success(`وضعیت به‌روز شد`),await B()}catch(e){z.error(e instanceof n?e.message:`به‌روزرسانی ناموفق بود`)}}async function H(e,t){if(!R.value){R.value=e;try{await c.updateHolder(e,{holderType:t}),z.success(`محل نگهداری به‌روز شد`),await B()}catch(e){z.error(e instanceof n?e.message:`به‌روزرسانی محل ناموفق بود`)}finally{R.value=null}}}function U(e){return P[e]??e}return d(()=>{B()}),(t,n)=>(s(),e(`div`,S,[a(`header`,C,[n[1]||=a(`div`,null,[a(`h1`,null,`درخواست کالیته فیزیکی`),a(`p`,null,`بررسی، گردش وضعیت و محل نگهداری اقلام`)],-1),u(x,{modelValue:I.value,"onUpdate:modelValue":[n[0]||=e=>I.value=e,B],options:p},null,8,[`modelValue`])]),L.value?(s(),o(y,{key:0,variant:`cards`})):F.value.length?(s(!0),e(f,{key:2},h(F.value,t=>(s(),e(`div`,{key:t.id,class:`request-card`},[a(`div`,w,[a(`div`,null,[a(`strong`,null,i(t.customerName),1),a(`span`,T,i(t.customerPhone),1),a(`span`,E,i(_(N)[t.status]??t.status),1)]),u(x,{"model-value":t.status,options:p.filter(e=>e.value),"onUpdate:modelValue":e=>V(t.id,String(e))},null,8,[`model-value`,`options`,`onUpdate:modelValue`])]),t.note?(s(),e(`p`,D,i(t.note),1)):r(``,!0),a(`table`,O,[n[2]||=a(`thead`,null,[a(`tr`,null,[a(`th`,null,`محصول`),a(`th`,null,`کد`),a(`th`,null,`تعداد`),a(`th`,null,`محل`)])],-1),a(`tbody`,null,[(s(!0),e(f,null,h(t.items,t=>(s(),e(`tr`,{key:t.id},[a(`td`,null,i(t.productName),1),a(`td`,k,i(t.productCode),1),a(`td`,null,i(t.quantity),1),a(`td`,null,[u(x,{"model-value":t.holderType,options:M,"onUpdate:modelValue":e=>H(t.id,String(e))},null,8,[`model-value`,`onUpdate:modelValue`]),t.movements?.length?(s(),e(`ul`,A,[(s(!0),e(f,null,h(t.movements,t=>(s(),e(`li`,{key:t.id},[m(i(U(t.fromHolder))+` → `+i(U(t.toHolder))+` `,1),a(`span`,j,i(_(l)(t.movedAt)),1)]))),128))])):r(``,!0)])]))),128))])])]))),128)):(s(),o(b,{key:1,title:`درخواستی نیست`}))]))}}),[[`__scopeId`,`data-v-747d8f88`]]);export{M as default};
import{$ as e,B as t,N as n,Q as r,St as i,X as a,Z as o,ct as s,f as c,i as l,nt as u,ot as d,q as f,rt as p,tt as m,ut as h,vt as g,yt as _,z as v}from"./index-9Ae_VOzQ.js";import{t as y}from"./AdminPageSkeleton-CKg1wrlm.js";import{t as b}from"./BaseEmptyState-DLwJ8N61.js";import{t as x}from"./AdminSelect-BCHHmDtL.js";var S={class:`admin-page`},C={class:`admin-page__head`},w={class:`request-card__top`},T={class:`muted`,dir:`ltr`},E={class:`badge`},D={key:0,class:`muted`},O={class:`admin-table`},k={dir:`ltr`},A={key:0,class:`movements`},j={class:`muted`},M=t(p({__name:`CatalogRequestsView`,setup(t){let p=[{value:``,label:`همه وضعیت‌ها`},{value:`new`,label:`درخواست جدید`},{value:`approved`,label:`تأیید شده`},{value:`ready_to_ship`,label:`آماده ارسال`},{value:`delivered`,label:`تحویل به مشتری`},{value:`returned`,label:`بازگردانده شده`},{value:`cancelled`,label:`لغو شده`}],M=[{value:`warehouse`,label:`انبار`},{value:`customer`,label:`مشتری`},{value:`agent`,label:`واسطه`}],N=Object.fromEntries(p.filter(e=>e.value).map(e=>[e.value,e.label])),P=Object.fromEntries(M.map(e=>[e.value,e.label])),F=g([]),I=g(``),L=g(!0),R=g(null),z=v();async function B(){L.value=!0;try{F.value=await c.list(I.value||void 0)}catch(e){z.error(e instanceof n?e.message:`بارگذاری انجام نشد`)}finally{L.value=!1}}async function V(e,t){try{await c.updateStatus(e,t),z.success(`وضعیت به‌روز شد`),await B()}catch(e){z.error(e instanceof n?e.message:`به‌روزرسانی ناموفق بود`)}}async function H(e,t){if(!R.value){R.value=e;try{await c.updateHolder(e,{holderType:t}),z.success(`محل نگهداری به‌روز شد`),await B()}catch(e){z.error(e instanceof n?e.message:`به‌روزرسانی محل ناموفق بود`)}finally{R.value=null}}}function U(e){return P[e]??e}return d(()=>{B()}),(t,n)=>(s(),e(`div`,S,[a(`header`,C,[n[1]||=a(`div`,null,[a(`h1`,null,`درخواست کالیته فیزیکی`),a(`p`,null,`بررسی، گردش وضعیت و محل نگهداری اقلام`)],-1),u(x,{modelValue:I.value,"onUpdate:modelValue":[n[0]||=e=>I.value=e,B],options:p},null,8,[`modelValue`])]),L.value?(s(),o(y,{key:0,variant:`cards`})):F.value.length?(s(!0),e(f,{key:2},h(F.value,t=>(s(),e(`div`,{key:t.id,class:`request-card`},[a(`div`,w,[a(`div`,null,[a(`strong`,null,i(t.customerName),1),a(`span`,T,i(t.customerPhone),1),a(`span`,E,i(_(N)[t.status]??t.status),1)]),u(x,{"model-value":t.status,options:p.filter(e=>e.value),"onUpdate:modelValue":e=>V(t.id,String(e))},null,8,[`model-value`,`options`,`onUpdate:modelValue`])]),t.note?(s(),e(`p`,D,i(t.note),1)):r(``,!0),a(`table`,O,[n[2]||=a(`thead`,null,[a(`tr`,null,[a(`th`,null,`محصول`),a(`th`,null,`کد`),a(`th`,null,`تعداد`),a(`th`,null,`محل`)])],-1),a(`tbody`,null,[(s(!0),e(f,null,h(t.items,t=>(s(),e(`tr`,{key:t.id},[a(`td`,null,i(t.productName),1),a(`td`,k,i(t.productCode),1),a(`td`,null,i(t.quantity),1),a(`td`,null,[u(x,{"model-value":t.holderType,options:M,"onUpdate:modelValue":e=>H(t.id,String(e))},null,8,[`model-value`,`onUpdate:modelValue`]),t.movements?.length?(s(),e(`ul`,A,[(s(!0),e(f,null,h(t.movements,t=>(s(),e(`li`,{key:t.id},[m(i(U(t.fromHolder))+` → `+i(U(t.toHolder))+` `,1),a(`span`,j,i(_(l)(t.movedAt)),1)]))),128))])):r(``,!0)])]))),128))])])]))),128)):(s(),o(b,{key:1,title:`درخواستی نیست`}))]))}}),[[`__scopeId`,`data-v-747d8f88`]]);export{M as default};
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
.admin-page-header__sub[data-v-45420745]{color:var(--color-text-muted);margin:4px 0 0;font-size:.85rem}.categories-admin__grid[data-v-45420745]{align-items:start;gap:16px;display:grid}.categories-panel[data-v-45420745]{padding:20px}.categories-panel__head[data-v-45420745]{border-bottom:1px solid var(--color-border);justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:16px;padding-bottom:14px;display:flex}.categories-panel__head h2[data-v-45420745]{margin:0 0 4px;font-size:1.05rem;font-weight:700}.categories-panel__head p[data-v-45420745]{color:var(--color-text-muted);margin:0;font-size:.78rem}.categories-panel__add[data-v-45420745]{border:1px dashed var(--color-border);background:var(--color-bg);border-radius:12px;gap:8px;margin-bottom:16px;padding:14px;display:grid}.categories-panel__empty[data-v-45420745]{text-align:center;color:var(--color-text-muted);background:var(--color-bg);border-radius:12px;margin:0;padding:28px 12px;font-size:.875rem}.categories-panel__list[data-v-45420745]{gap:12px;display:grid}.category-row[data-v-45420745]{border:1px solid var(--color-border);background:var(--color-bg);border-radius:14px;grid-template-columns:auto minmax(0,1fr) auto;align-items:start;gap:12px;padding:12px;display:grid}.category-row__fields[data-v-45420745]{gap:8px;min-width:0;display:grid}.category-row__line[data-v-45420745]{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px;display:grid}.category-row__id[data-v-45420745]{color:var(--color-text-muted);margin:0;font-family:ui-monospace,monospace;font-size:.72rem}.category-row__remove[data-v-45420745]{color:var(--color-danger,#dc3545);font:inherit;cursor:pointer;white-space:nowrap;background:0 0;border:none;padding:6px 4px;font-size:.8125rem}.category-row[data-v-45420745] .image-picker__preview{width:72px;height:60px}@media (width>=900px){.categories-admin__grid[data-v-45420745]{grid-template-columns:1fr 1fr}}@media (width<=640px){.category-row[data-v-45420745]{grid-template-columns:1fr}.category-row__remove[data-v-45420745]{justify-self:start}}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
.admin-page-header__sub[data-v-bdf23952]{color:var(--color-text-muted);margin:4px 0 0;font-size:.85rem}.categories-admin__grid[data-v-bdf23952]{align-items:start;gap:16px;display:grid}.categories-panel[data-v-bdf23952]{padding:20px}.categories-panel__head[data-v-bdf23952]{border-bottom:1px solid var(--color-border);justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:16px;padding-bottom:14px;display:flex}.categories-panel__head h2[data-v-bdf23952]{margin:0 0 4px;font-size:1.05rem;font-weight:700}.categories-panel__head p[data-v-bdf23952]{color:var(--color-text-muted);margin:0;font-size:.78rem}.categories-panel__add[data-v-bdf23952]{border:1px dashed var(--color-border);background:var(--color-bg);border-radius:12px;gap:8px;margin-bottom:16px;padding:14px;display:grid}.categories-panel__empty[data-v-bdf23952]{text-align:center;color:var(--color-text-muted);background:var(--color-bg);border-radius:12px;margin:0;padding:28px 12px;font-size:.875rem}.categories-panel__list[data-v-bdf23952]{gap:12px;display:grid}.category-row[data-v-bdf23952]{border:1px solid var(--color-border);background:var(--color-bg);border-radius:14px;grid-template-columns:auto minmax(0,1fr) auto;align-items:start;gap:12px;padding:12px;display:grid}.category-row__fields[data-v-bdf23952]{gap:8px;min-width:0;display:grid}.category-row__line[data-v-bdf23952]{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px;display:grid}.category-row__id[data-v-bdf23952]{color:var(--color-text-muted);margin:0;font-family:ui-monospace,monospace;font-size:.72rem}.category-row__remove[data-v-bdf23952]{color:var(--color-danger,#dc3545);font:inherit;cursor:pointer;white-space:nowrap;background:0 0;border:none;padding:6px 4px;font-size:.8125rem}.category-row[data-v-bdf23952] .image-picker__preview{width:72px;height:60px}@media (width>=900px){.categories-admin__grid[data-v-bdf23952]{grid-template-columns:1fr 1fr}}@media (width<=640px){.category-row[data-v-bdf23952]{grid-template-columns:1fr}.category-row__remove[data-v-bdf23952]{justify-self:start}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
.checks-page__order-meta[data-v-1cb3ca79]{align-items:center;gap:8px;display:flex}.checks-page__stats[data-v-1cb3ca79]{grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin-bottom:14px;display:grid}.checks-page__stat[data-v-1cb3ca79]{border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface);flex-direction:column;gap:2px;padding:10px 12px;display:flex}.checks-page__stat span[data-v-1cb3ca79]{color:var(--color-text-muted);font-size:.75rem}.checks-page__stat strong[data-v-1cb3ca79]{font-size:.875rem;font-weight:700}.checks-page__list[data-v-1cb3ca79]{overflow:hidden}.check-row[data-v-1cb3ca79]{border-bottom:1px solid var(--color-border-light);grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px 12px;padding:8px 12px;display:grid}.check-row[data-v-1cb3ca79]:last-child{border-bottom:0}.check-row.open[data-v-1cb3ca79]{background:color-mix(in srgb, var(--color-primary-soft) 55%, transparent)}.check-row__main[data-v-1cb3ca79]{min-width:0;color:inherit;text-align:start;cursor:pointer;background:0 0;border:0;align-items:center;gap:10px;padding:4px 0;display:flex}.check-row__chevron[data-v-1cb3ca79]{width:14px;color:var(--color-text-muted);flex-shrink:0;font-size:.75rem}.check-row__thumb[data-v-1cb3ca79]{border:1px solid var(--color-border);cursor:zoom-in;background:#111;border-radius:6px;flex-shrink:0;place-items:center;width:44px;height:32px;padding:0;display:grid;overflow:hidden}.check-row__thumb img[data-v-1cb3ca79]{object-fit:cover;width:100%;height:100%;display:block}.check-row__thumb--empty[data-v-1cb3ca79]{color:var(--color-text-muted);cursor:default;font-size:.625rem}.check-row__meta[data-v-1cb3ca79]{flex:1;gap:2px;min-width:0;display:grid}.check-row__meta strong[data-v-1cb3ca79]{font-size:.875rem;font-weight:700}.check-row__meta small[data-v-1cb3ca79]{color:var(--color-text-muted);white-space:nowrap;text-overflow:ellipsis;font-size:.75rem;overflow:hidden}.check-row__actions[data-v-1cb3ca79]{flex-shrink:0;gap:6px;display:flex}.check-row__panel[data-v-1cb3ca79]{border-top:1px dashed var(--color-border);flex-wrap:wrap;grid-column:1/-1;align-items:flex-start;gap:12px 16px;padding:8px 0 4px 24px;display:flex}.check-row__fields[data-v-1cb3ca79]{flex-wrap:wrap;flex:1;gap:8px;min-width:200px;display:flex}.check-row__field[data-v-1cb3ca79]{background:var(--color-border-light);border-radius:999px;align-items:baseline;gap:6px;padding:4px 8px;font-size:.75rem;display:inline-flex}.check-row__field span[data-v-1cb3ca79]{color:var(--color-text-muted)}.check-row__field strong[data-v-1cb3ca79]{font-weight:600}.check-row__photos[data-v-1cb3ca79]{flex-shrink:0;gap:8px;display:flex}.check-row__photo[data-v-1cb3ca79]{border:1px solid var(--color-border);width:96px;color:inherit;cursor:zoom-in;text-align:center;background:0 0;border-radius:8px;padding:0;overflow:hidden}.check-row__photo img[data-v-1cb3ca79]{object-fit:cover;background:#111;width:100%;height:60px;display:block}.check-row__photo span[data-v-1cb3ca79]{color:var(--color-text-muted);padding:4px;font-size:.6875rem;display:block}.check-row__hint[data-v-1cb3ca79]{color:var(--color-text-muted);margin:0;font-size:.75rem}.checks-page__footer[data-v-1cb3ca79]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;margin-top:14px;display:flex}.checks-page__note[data-v-1cb3ca79]{color:var(--color-text-muted);margin:0;font-size:.75rem}.checks-page__history[data-v-1cb3ca79]{gap:8px;display:grid}.checks-page__history-item[data-v-1cb3ca79]{gap:6px;padding:12px;display:grid}.checks-page__history-item-head[data-v-1cb3ca79]{flex-wrap:wrap;justify-content:space-between;gap:12px;font-size:.875rem;display:flex}.checks-page__history-meta[data-v-1cb3ca79],.checks-page__history-note[data-v-1cb3ca79]{margin:0;font-size:.8125rem;line-height:1.5}.checks-page__history-meta[data-v-1cb3ca79]{color:var(--color-text-muted)}.checks-page__lightbox[data-v-1cb3ca79]{z-index:300000;background:#000000d6;place-items:center;padding:20px;display:grid;position:fixed;inset:0}.checks-page__lightbox img[data-v-1cb3ca79]{object-fit:contain;border-radius:8px;max-width:min(900px,100%);max-height:88vh}.checks-page__lightbox-close[data-v-1cb3ca79]{top:14px;cursor:pointer;border:0;border-radius:8px;padding:8px 12px;position:absolute;inset-inline-end:14px}@media (width<=800px){.checks-page__stats[data-v-1cb3ca79]{grid-template-columns:repeat(2,minmax(0,1fr))}.check-row[data-v-1cb3ca79]{grid-template-columns:1fr}.check-row__actions[data-v-1cb3ca79]{padding-inline-start:24px}.check-row__panel[data-v-1cb3ca79]{padding-inline-start:0}}
+1
View File
@@ -0,0 +1 @@
.checks-page__order-meta[data-v-af5e25db]{align-items:center;gap:8px;display:flex}.checks-page__stats[data-v-af5e25db]{grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin-bottom:14px;display:grid}.checks-page__stat[data-v-af5e25db]{border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface);flex-direction:column;gap:2px;padding:10px 12px;display:flex}.checks-page__stat span[data-v-af5e25db]{color:var(--color-text-muted);font-size:.75rem}.checks-page__stat strong[data-v-af5e25db]{font-size:.875rem;font-weight:700}.checks-page__list[data-v-af5e25db]{overflow:hidden}.check-row[data-v-af5e25db]{border-bottom:1px solid var(--color-border-light);grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px 12px;padding:8px 12px;display:grid}.check-row[data-v-af5e25db]:last-child{border-bottom:0}.check-row.open[data-v-af5e25db]{background:color-mix(in srgb, var(--color-primary-soft) 55%, transparent)}.check-row__main[data-v-af5e25db]{min-width:0;color:inherit;text-align:start;cursor:pointer;background:0 0;border:0;align-items:center;gap:10px;padding:4px 0;display:flex}.check-row__chevron[data-v-af5e25db]{width:14px;color:var(--color-text-muted);flex-shrink:0;font-size:.75rem}.check-row__thumb[data-v-af5e25db]{border:1px solid var(--color-border);cursor:zoom-in;background:#111;border-radius:6px;flex-shrink:0;place-items:center;width:44px;height:32px;padding:0;display:grid;overflow:hidden}.check-row__thumb img[data-v-af5e25db]{object-fit:cover;width:100%;height:100%;display:block}.check-row__thumb--empty[data-v-af5e25db]{color:var(--color-text-muted);cursor:default;font-size:.625rem}.check-row__meta[data-v-af5e25db]{flex:1;gap:2px;min-width:0;display:grid}.check-row__meta strong[data-v-af5e25db]{font-size:.875rem;font-weight:700}.check-row__meta small[data-v-af5e25db]{color:var(--color-text-muted);white-space:nowrap;text-overflow:ellipsis;font-size:.75rem;overflow:hidden}.check-row__actions[data-v-af5e25db]{flex-shrink:0;gap:6px;display:flex}.check-row__panel[data-v-af5e25db]{border-top:1px dashed var(--color-border);flex-wrap:wrap;grid-column:1/-1;align-items:flex-start;gap:12px 16px;padding:8px 0 4px 24px;display:flex}.check-row__fields[data-v-af5e25db]{flex-wrap:wrap;flex:1;gap:8px;min-width:200px;display:flex}.check-row__field[data-v-af5e25db]{background:var(--color-border-light);border-radius:999px;align-items:baseline;gap:6px;padding:4px 8px;font-size:.75rem;display:inline-flex}.check-row__field span[data-v-af5e25db]{color:var(--color-text-muted)}.check-row__field strong[data-v-af5e25db]{font-weight:600}.check-row__photos[data-v-af5e25db]{flex-shrink:0;gap:8px;display:flex}.check-row__photo[data-v-af5e25db]{border:1px solid var(--color-border);width:96px;color:inherit;cursor:zoom-in;text-align:center;background:0 0;border-radius:8px;padding:0;overflow:hidden}.check-row__photo img[data-v-af5e25db]{object-fit:cover;background:#111;width:100%;height:60px;display:block}.check-row__photo span[data-v-af5e25db]{color:var(--color-text-muted);padding:4px;font-size:.6875rem;display:block}.check-row__hint[data-v-af5e25db]{color:var(--color-text-muted);margin:0;font-size:.75rem}.checks-page__footer[data-v-af5e25db]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;margin-top:14px;display:flex}.checks-page__note[data-v-af5e25db]{color:var(--color-text-muted);margin:0;font-size:.75rem}.checks-page__history[data-v-af5e25db]{gap:8px;display:grid}.checks-page__history-item[data-v-af5e25db]{gap:6px;padding:12px;display:grid}.checks-page__history-item-head[data-v-af5e25db]{flex-wrap:wrap;justify-content:space-between;gap:12px;font-size:.875rem;display:flex}.checks-page__history-meta[data-v-af5e25db],.checks-page__history-note[data-v-af5e25db]{margin:0;font-size:.8125rem;line-height:1.5}.checks-page__history-meta[data-v-af5e25db]{color:var(--color-text-muted)}.checks-page__lightbox[data-v-af5e25db]{z-index:300000;background:#000000d6;place-items:center;padding:20px;display:grid;position:fixed;inset:0}.checks-page__lightbox img[data-v-af5e25db]{object-fit:contain;border-radius:8px;max-width:min(900px,100%);max-height:88vh}.checks-page__lightbox-close[data-v-af5e25db]{top:14px;cursor:pointer;border:0;border-radius:8px;padding:8px 12px;position:absolute;inset-inline-end:14px}@media (width<=800px){.checks-page__stats[data-v-af5e25db]{grid-template-columns:repeat(2,minmax(0,1fr))}.check-row[data-v-af5e25db]{grid-template-columns:1fr}.check-row__actions[data-v-af5e25db]{padding-inline-start:24px}.check-row__panel[data-v-af5e25db]{padding-inline-start:0}}
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
-1
View File
@@ -1 +0,0 @@
.customers-page__search[data-v-089d9237]{color:var(--color-text-muted);align-items:center;gap:10px;margin-bottom:16px;padding:10px 14px;display:flex}.customers-page__search-input[data-v-089d9237]{background:0 0;border:none;outline:none;flex:1;font-size:.875rem}.customers-page__table[data-v-089d9237]{overflow:hidden}.customers-page__brands[data-v-089d9237]{flex-wrap:wrap;gap:10px 16px;display:flex}.customers-page__brand[data-v-089d9237]{cursor:pointer;align-items:center;gap:8px;font-size:.875rem;display:flex}.customers-page__brand input[data-v-089d9237]{width:16px;height:16px;accent-color:var(--color-primary)}
+1
View File
@@ -0,0 +1 @@
.suggestions-panel[data-v-4182e847]{border-top:1px solid var(--color-border);margin-top:20px;padding-top:20px}.suggestions-panel__head[data-v-4182e847]{margin-bottom:12px}.suggestions-panel__title[data-v-4182e847]{margin:0 0 4px;font-size:.95rem}.suggestions-panel__hint[data-v-4182e847]{color:var(--color-text-muted);margin:0;font-size:.78rem;line-height:1.5}.suggestions-panel__loading[data-v-4182e847],.suggestions-panel__empty[data-v-4182e847]{color:var(--color-text-muted);font-size:.85rem}.suggestions-panel__add[data-v-4182e847]{flex-direction:column;gap:10px;display:flex}.field[data-v-4182e847]{flex-direction:column;gap:6px;font-size:.85rem;display:flex}.suggestions-panel__picked[data-v-4182e847]{flex-wrap:wrap;gap:6px;display:flex}.suggestions-panel__chip[data-v-4182e847]{background:var(--color-primary-soft);color:var(--color-primary);border-radius:999px;align-items:center;gap:6px;padding:4px 8px;font-size:.75rem;font-weight:700;display:inline-flex}.suggestions-panel__chip button[data-v-4182e847]{color:inherit;cursor:pointer;background:0 0;border:none;font-size:1rem;line-height:1}.suggestions-panel__sub[data-v-4182e847]{margin:16px 0 8px;font-size:.85rem}.suggestions-panel__list ul[data-v-4182e847]{flex-direction:column;gap:8px;margin:0;padding:0;list-style:none;display:flex}.suggestions-panel__row[data-v-4182e847]{background:var(--color-bg);border:1px solid var(--color-border);border-radius:10px;justify-content:space-between;align-items:flex-start;gap:12px;padding:10px 12px;display:flex}.suggestions-panel__actions[data-v-4182e847]{flex-direction:column;flex-shrink:0;align-items:flex-end;gap:4px;display:flex}.muted[data-v-4182e847]{color:var(--color-text-muted);margin-inline-start:4px;font-size:.75rem}.note[data-v-4182e847]{color:var(--color-text-muted);margin:4px 0 0;font-size:.75rem}.on[data-v-4182e847]{color:var(--color-success);font-size:.72rem;font-weight:700}.off[data-v-4182e847]{color:var(--color-text-muted);font-size:.72rem}.link[data-v-4182e847]{color:var(--color-primary);cursor:pointer;background:0 0;border:none;font-family:inherit;font-size:.78rem}.customers-page__tabs[data-v-db05c8d1]{gap:8px;margin-bottom:16px;display:flex}.customers-page__tab[data-v-db05c8d1]{border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-text-muted);font:inherit;cursor:pointer;border-radius:999px;padding:8px 16px;font-size:.875rem;font-weight:600}.customers-page__tab.is-active[data-v-db05c8d1]{border-color:var(--color-primary);background:var(--color-primary-soft);color:var(--color-primary)}.customers-page__search[data-v-db05c8d1]{color:var(--color-text-muted);align-items:center;gap:10px;margin-bottom:16px;padding:10px 14px;display:flex}.customers-page__search-input[data-v-db05c8d1]{background:0 0;border:none;outline:none;flex:1;font-size:.875rem}.customers-page__table[data-v-db05c8d1]{overflow:hidden}.customers-page__brands[data-v-db05c8d1]{flex-wrap:wrap;gap:10px 16px;display:flex}.customers-page__brand[data-v-db05c8d1]{cursor:pointer;align-items:center;gap:8px;font-size:.875rem;display:flex}.customers-page__brand input[data-v-db05c8d1]{width:16px;height:16px;accent-color:var(--color-primary)}
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
@@ -1,3 +1,3 @@
import{$ as e,B as t,N as n,R as r,St as i,W as a,X as o,Y as s,Z as c,_t as l,ct as u,ht as d,mt as f,nt as p,ot as m,q as h,rt as g,tt as _,ut as v,v as y,vt as b,z as x}from"./index-BHqDDh7X.js";import{t as S}from"./AdminPageSkeleton-E50Kwv4j.js";import{t as C}from"./BaseEmptyState-vNIhbGdV.js";var w={class:`admin-page`},T={key:2,class:`admin-table`},E={dir:`ltr`},D=[`onClick`],O={class:`field`},k={class:`field`},A={class:`field`},j={class:`field`},M=[`disabled`],N=t(g({__name:`LevelsView`,setup(t){let g=b([]),N=b(!0),P=b(!1),F=b(null),I=x(),L=l({code:``,label:``,sortOrder:0,benefitsText:``}),R=s(()=>F.value?`ویرایش سطح`:`سطح جدید`);function z(e){return e.split(`
import{$ as e,B as t,N as n,R as r,St as i,W as a,X as o,Y as s,Z as c,_t as l,ct as u,ht as d,mt as f,nt as p,ot as m,q as h,rt as g,tt as _,ut as v,v as y,vt as b,z as x}from"./index-9Ae_VOzQ.js";import{t as S}from"./AdminPageSkeleton-CKg1wrlm.js";import{t as C}from"./BaseEmptyState-DLwJ8N61.js";var w={class:`admin-page`},T={key:2,class:`admin-table`},E={dir:`ltr`},D=[`onClick`],O={class:`field`},k={class:`field`},A={class:`field`},j={class:`field`},M=[`disabled`],N=t(g({__name:`LevelsView`,setup(t){let g=b([]),N=b(!0),P=b(!1),F=b(null),I=x(),L=l({code:``,label:``,sortOrder:0,benefitsText:``}),R=s(()=>F.value?`ویرایش سطح`:`سطح جدید`);function z(e){return e.split(`
`).map(e=>e.trim()).filter(Boolean).map(e=>({title:e}))}async function B(){N.value=!0;try{g.value=await y.list()}catch(e){I.error(e instanceof n?e.message:`بارگذاری سطوح ناموفق بود`)}finally{N.value=!1}}function V(){F.value=null,Object.assign(L,{code:``,label:``,sortOrder:g.value.length+1,benefitsText:``}),P.value=!0}function H(e){F.value=e.id,Object.assign(L,{code:e.code,label:e.label,sortOrder:e.sortOrder,benefitsText:e.benefits.map(e=>e.title).join(`
`)}),P.value=!0}async function U(){try{let e={code:L.code.trim(),label:L.label.trim(),sortOrder:L.sortOrder,benefits:z(L.benefitsText)};F.value?await y.update(F.value,e):await y.create(e),P.value=!1,I.success(`ذخیره شد`),await B()}catch(e){I.error(e instanceof n?e.message:`ذخیره ناموفق بود`)}}return m(()=>{B()}),(t,n)=>(u(),e(`div`,w,[o(`header`,{class:`admin-page__head`},[n[5]||=o(`div`,null,[o(`h1`,null,`سطوح و مزایای مشتری`),o(`p`,null,`تعریف Level داخلی CRM و مزایای هر سطح (نمایش فقط در ادمین)`)],-1),o(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:V},`سطح جدید`)]),N.value?(u(),c(S,{key:0,variant:`table`})):g.value.length?(u(),e(`table`,T,[n[6]||=o(`thead`,null,[o(`tr`,null,[o(`th`,null,`کد`),o(`th`,null,`عنوان`),o(`th`,null,`مزایا`),o(`th`,null,`مشتریان`),o(`th`)])],-1),o(`tbody`,null,[(u(!0),e(h,null,v(g.value,t=>(u(),e(`tr`,{key:t.id},[o(`td`,E,i(t.code),1),o(`td`,null,i(t.label),1),o(`td`,null,i(t.benefits.map(e=>e.title).join(`، `)||`—`),1),o(`td`,null,i(t.customersCount),1),o(`td`,null,[o(`button`,{type:`button`,class:`link`,onClick:e=>H(t)},`ویرایش`,8,D)])]))),128))])])):(u(),c(C,{key:1,title:`سطحی تعریف نشده`})),p(r,{open:P.value,title:R.value,onClose:n[4]||=e=>P.value=!1},{footer:f(()=>[o(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!L.code.trim()||!L.label.trim(),onClick:U},` ذخیره `,8,M)]),default:f(()=>[o(`label`,O,[n[7]||=_(`کد`,-1),d(o(`input`,{"onUpdate:modelValue":n[0]||=e=>L.code=e,class:`admin-input`,dir:`ltr`},null,512),[[a,L.code]])]),o(`label`,k,[n[8]||=_(`عنوان`,-1),d(o(`input`,{"onUpdate:modelValue":n[1]||=e=>L.label=e,class:`admin-input`},null,512),[[a,L.label]])]),o(`label`,A,[n[9]||=_(`ترتیب`,-1),d(o(`input`,{"onUpdate:modelValue":n[2]||=e=>L.sortOrder=e,type:`number`,class:`admin-input`},null,512),[[a,L.sortOrder,void 0,{number:!0}]])]),o(`label`,j,[n[10]||=_(` مزایا (هر خط یک مورد) `,-1),d(o(`textarea`,{"onUpdate:modelValue":n[3]||=e=>L.benefitsText=e,class:`admin-input`,rows:`4`},null,512),[[a,L.benefitsText]])])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-44c7f808`]]);export{N as default};
@@ -1 +1 @@
import{$ as e,A as t,B as n,F as r,H as i,I as a,K as o,M as s,P as c,Q as l,St as u,V as d,W as f,X as p,Y as m,ct as h,et as g,ht as _,j as v,nt as y,rt as b,tt as x,vt as S,yt as C,z as w}from"./index-BHqDDh7X.js";var T={class:`login-page`},E={class:`login-page__form-wrap`},D={class:`login-page__card admin-card`},O={class:`login-page__header`},k={key:0,class:`login-page__mock-hint`},A={dir:`ltr`},j={dir:`ltr`},M={key:0,class:`admin-form__error`,role:`alert`},N={class:`admin-form__field`},P={class:`login-page__input-wrap`},F={class:`login-page__field-icon`,"aria-hidden":`true`},I={class:`admin-form__field`},L={class:`login-page__input-wrap login-page__input-wrap--password`},R={class:`login-page__field-icon`,"aria-hidden":`true`},z=[`type`],B=[`aria-label`],V={class:`login-page__remember`},H=[`disabled`],U={key:0,class:`admin-btn__spinner`,"aria-hidden":`true`},W=n(b({__name:`LoginView`,setup(n){let b=a(),W=r(),G=t(),K=w(),q=S(s()?v.phone:``),J=S(s()?v.password:``),Y=S(!0),X=S(!1),Z=s(),Q=m(()=>q.value.trim().length>0&&J.value.length>0);function $(e){return e.replace(/[۰-۹]/g,e=>String(`۰۱۲۳۴۵۶۷۸۹`.indexOf(e))).replace(/[٠-٩]/g,e=>String(`٠١٢٣٤٥٦٧٨٩`.indexOf(e)))}async function ee(){if(!Q.value){G.error=`لطفاً شماره موبایل و رمز عبور را وارد کنید.`;return}if(!await G.login($(q.value.trim()),J.value,Y.value))return;K.success(`خوش آمدید، ${G.fullName}`);let e=typeof W.query.redirect==`string`?W.query.redirect:`/`;b.replace(e)}return(t,n)=>(h(),e(`div`,T,[p(`div`,E,[p(`div`,D,[p(`div`,O,[n[8]||=p(`h2`,{class:`login-page__title`},`ورود به پنل مدیریت`,-1),n[9]||=p(`p`,{class:`login-page__subtitle`},`برای ادامه، اطلاعات حساب کاربری خود را وارد کنید.`,-1),C(Z)?(h(),e(`p`,k,[n[6]||=x(` حالت موک فعال است — `,-1),p(`span`,A,u(C(v).phone),1),n[7]||=x(` / `,-1),p(`span`,j,u(C(v).password),1)])):l(``,!0)]),p(`form`,{class:`admin-form login-page__form`,onSubmit:o(ee,[`prevent`])},[C(G).error?(h(),e(`p`,M,u(C(G).error),1)):l(``,!0),p(`div`,N,[n[10]||=p(`label`,{for:`login-phone`},`شماره موبایل`,-1),p(`div`,P,[p(`span`,F,[y(c,{name:`phone`,size:18})]),_(p(`input`,{id:`login-phone`,"onUpdate:modelValue":n[0]||=e=>q.value=e,type:`tel`,class:`admin-input login-page__input`,placeholder:`۰۹۱۲۱۱۱۱۲۲۲۲`,autocomplete:`username`,inputmode:`tel`,dir:`ltr`,onInput:n[1]||=e=>C(G).clearError()},null,544),[[f,q.value]])])]),p(`div`,I,[n[11]||=p(`label`,{for:`login-password`},`رمز عبور`,-1),p(`div`,L,[p(`span`,R,[y(c,{name:`lock`,size:18})]),_(p(`input`,{id:`login-password`,"onUpdate:modelValue":n[2]||=e=>J.value=e,type:X.value?`text`:`password`,class:`admin-input login-page__input login-page__input--with-toggle`,placeholder:`رمز عبور`,autocomplete:`current-password`,onInput:n[3]||=e=>C(G).clearError()},null,40,z),[[i,J.value]]),p(`button`,{type:`button`,class:`login-page__toggle-password`,"aria-label":X.value?`پنهان کردن رمز`:`نمایش رمز`,onClick:n[4]||=e=>X.value=!X.value},[y(c,{name:X.value?`eye-off`:`eye`,size:18},null,8,[`name`])],8,B)])]),p(`label`,V,[_(p(`input`,{"onUpdate:modelValue":n[5]||=e=>Y.value=e,type:`checkbox`},null,512),[[d,Y.value]]),n[12]||=p(`span`,null,`مرا به خاطر بسپار`,-1)]),p(`button`,{type:`submit`,class:`admin-btn admin-btn--primary login-page__submit`,disabled:!Q.value||C(G).loading},[C(G).loading?(h(),e(`span`,U)):l(``,!0),n[13]||=x(` ورود به پنل `,-1)],8,H)],32)])]),n[14]||=g(`<div class="login-page__brand" data-v-3c4fbd85><div class="login-page__brand-inner" data-v-3c4fbd85><p class="login-page__brand-badge" data-v-3c4fbd85>پارچه</p><h1 class="login-page__brand-title" data-v-3c4fbd85>پنل مدیریت سفارش‌های عمده</h1><p class="login-page__brand-text" data-v-3c4fbd85> مدیریت سفارش‌ها، مشتریان، قیمت‌گذاری، چک‌ها و گزارش‌های فروش در یک محیط یکپارچه. </p></div></div>`,1)]))}}),[[`__scopeId`,`data-v-3c4fbd85`]]);export{W as default};
import{$ as e,A as t,B as n,F as r,H as i,I as a,K as o,M as s,P as c,Q as l,St as u,V as d,W as f,X as p,Y as m,ct as h,et as g,ht as _,j as v,nt as y,rt as b,tt as x,vt as S,yt as C,z as w}from"./index-9Ae_VOzQ.js";var T={class:`login-page`},E={class:`login-page__form-wrap`},D={class:`login-page__card admin-card`},O={class:`login-page__header`},k={key:0,class:`login-page__mock-hint`},A={dir:`ltr`},j={dir:`ltr`},M={key:0,class:`admin-form__error`,role:`alert`},N={class:`admin-form__field`},P={class:`login-page__input-wrap`},F={class:`login-page__field-icon`,"aria-hidden":`true`},I={class:`admin-form__field`},L={class:`login-page__input-wrap login-page__input-wrap--password`},R={class:`login-page__field-icon`,"aria-hidden":`true`},z=[`type`],B=[`aria-label`],V={class:`login-page__remember`},H=[`disabled`],U={key:0,class:`admin-btn__spinner`,"aria-hidden":`true`},W=n(b({__name:`LoginView`,setup(n){let b=a(),W=r(),G=t(),K=w(),q=S(s()?v.phone:``),J=S(s()?v.password:``),Y=S(!0),X=S(!1),Z=s(),Q=m(()=>q.value.trim().length>0&&J.value.length>0);function $(e){return e.replace(/[۰-۹]/g,e=>String(`۰۱۲۳۴۵۶۷۸۹`.indexOf(e))).replace(/[٠-٩]/g,e=>String(`٠١٢٣٤٥٦٧٨٩`.indexOf(e)))}async function ee(){if(!Q.value){G.error=`لطفاً شماره موبایل و رمز عبور را وارد کنید.`;return}if(!await G.login($(q.value.trim()),J.value,Y.value))return;K.success(`خوش آمدید، ${G.fullName}`);let e=typeof W.query.redirect==`string`?W.query.redirect:`/`;b.replace(e)}return(t,n)=>(h(),e(`div`,T,[p(`div`,E,[p(`div`,D,[p(`div`,O,[n[8]||=p(`h2`,{class:`login-page__title`},`ورود به پنل مدیریت`,-1),n[9]||=p(`p`,{class:`login-page__subtitle`},`برای ادامه، اطلاعات حساب کاربری خود را وارد کنید.`,-1),C(Z)?(h(),e(`p`,k,[n[6]||=x(` حالت موک فعال است — `,-1),p(`span`,A,u(C(v).phone),1),n[7]||=x(` / `,-1),p(`span`,j,u(C(v).password),1)])):l(``,!0)]),p(`form`,{class:`admin-form login-page__form`,onSubmit:o(ee,[`prevent`])},[C(G).error?(h(),e(`p`,M,u(C(G).error),1)):l(``,!0),p(`div`,N,[n[10]||=p(`label`,{for:`login-phone`},`شماره موبایل`,-1),p(`div`,P,[p(`span`,F,[y(c,{name:`phone`,size:18})]),_(p(`input`,{id:`login-phone`,"onUpdate:modelValue":n[0]||=e=>q.value=e,type:`tel`,class:`admin-input login-page__input`,placeholder:`۰۹۱۲۱۱۱۱۲۲۲۲`,autocomplete:`username`,inputmode:`tel`,dir:`ltr`,onInput:n[1]||=e=>C(G).clearError()},null,544),[[f,q.value]])])]),p(`div`,I,[n[11]||=p(`label`,{for:`login-password`},`رمز عبور`,-1),p(`div`,L,[p(`span`,R,[y(c,{name:`lock`,size:18})]),_(p(`input`,{id:`login-password`,"onUpdate:modelValue":n[2]||=e=>J.value=e,type:X.value?`text`:`password`,class:`admin-input login-page__input login-page__input--with-toggle`,placeholder:`رمز عبور`,autocomplete:`current-password`,onInput:n[3]||=e=>C(G).clearError()},null,40,z),[[i,J.value]]),p(`button`,{type:`button`,class:`login-page__toggle-password`,"aria-label":X.value?`پنهان کردن رمز`:`نمایش رمز`,onClick:n[4]||=e=>X.value=!X.value},[y(c,{name:X.value?`eye-off`:`eye`,size:18},null,8,[`name`])],8,B)])]),p(`label`,V,[_(p(`input`,{"onUpdate:modelValue":n[5]||=e=>Y.value=e,type:`checkbox`},null,512),[[d,Y.value]]),n[12]||=p(`span`,null,`مرا به خاطر بسپار`,-1)]),p(`button`,{type:`submit`,class:`admin-btn admin-btn--primary login-page__submit`,disabled:!Q.value||C(G).loading},[C(G).loading?(h(),e(`span`,U)):l(``,!0),n[13]||=x(` ورود به پنل `,-1)],8,H)],32)])]),n[14]||=g(`<div class="login-page__brand" data-v-3c4fbd85><div class="login-page__brand-inner" data-v-3c4fbd85><p class="login-page__brand-badge" data-v-3c4fbd85>پارچه</p><h1 class="login-page__brand-title" data-v-3c4fbd85>پنل مدیریت سفارش‌های عمده</h1><p class="login-page__brand-text" data-v-3c4fbd85> مدیریت سفارش‌ها، مشتریان، قیمت‌گذاری، چک‌ها و گزارش‌های فروش در یک محیط یکپارچه. </p></div></div>`,1)]))}}),[[`__scopeId`,`data-v-3c4fbd85`]]);export{W 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
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
.products-page__filters[data-v-881243f1]{flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px;padding:12px 14px;display:flex}.products-page__search[data-v-881243f1]{min-width:200px;color:var(--color-text-muted);flex:1;align-items:center;gap:10px;display:flex}.products-page__search-input[data-v-881243f1]{background:0 0;border:none;outline:none;flex:1;font-size:.875rem}.products-page__catalog-filter[data-v-881243f1]{width:min(260px,100%)}.products-page__table[data-v-881243f1]{overflow:hidden}.product-thumb[data-v-881243f1]{background:#e8eceb 50%/cover no-repeat;border-radius:8px;width:44px;height:36px;display:block}.product-thumb--empty[data-v-881243f1]{background:#eef1f0}.color-variants[data-v-881243f1]{flex-direction:column;gap:14px;display:flex}.color-variants__hint[data-v-881243f1]{color:var(--color-text-muted);margin:0 0 10px;font-size:.75rem;line-height:1.6}.color-variant[data-v-881243f1]{border:1px solid var(--color-border);background:var(--color-bg,#f7f8f7);border-radius:12px;flex-wrap:wrap;align-items:center;gap:12px;padding:10px;display:flex}.color-variant__fields[data-v-881243f1]{flex-direction:column;flex:1;align-items:flex-start;gap:8px;min-width:180px;display:flex}.product-images[data-v-881243f1]{flex-wrap:wrap;gap:10px;display:flex}.product-images__item[data-v-881243f1]{flex-direction:column;gap:6px;width:92px;display:flex}.product-images__thumb[data-v-881243f1]{border:1px solid var(--color-border);background:#e8eceb 50%/cover no-repeat;border-radius:10px;width:92px;height:72px;display:block}.product-images__remove[data-v-881243f1],.product-images__add[data-v-881243f1]{border:1px dashed var(--color-border);cursor:pointer;text-align:center;background:0 0;border-radius:8px;padding:6px 8px;font-size:.75rem}.product-images__add[data-v-881243f1]{min-width:92px;min-height:72px;color:var(--color-text-muted);place-items:center;display:grid}
+1
View File
@@ -0,0 +1 @@
.products-page__filters[data-v-761ea8ca]{flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px;padding:12px 14px;display:flex}.products-page__search[data-v-761ea8ca]{min-width:200px;color:var(--color-text-muted);flex:1;align-items:center;gap:10px;display:flex}.products-page__search-input[data-v-761ea8ca]{background:0 0;border:none;outline:none;flex:1;font-size:.875rem}.products-page__catalog-filter[data-v-761ea8ca]{width:min(260px,100%)}.products-page__table[data-v-761ea8ca]{overflow:hidden}.product-thumb[data-v-761ea8ca]{background:#e8eceb 50%/cover no-repeat;border-radius:8px;width:44px;height:36px;display:block}.product-thumb--empty[data-v-761ea8ca]{background:#eef1f0}.color-variants[data-v-761ea8ca]{flex-direction:column;gap:14px;display:flex}.color-variants__hint[data-v-761ea8ca]{color:var(--color-text-muted);margin:0 0 10px;font-size:.75rem;line-height:1.6}.color-variant[data-v-761ea8ca]{border:1px solid var(--color-border);background:var(--color-bg,#f7f8f7);border-radius:12px;flex-wrap:wrap;align-items:center;gap:12px;padding:10px;display:flex}.color-variant__fields[data-v-761ea8ca]{flex-direction:column;flex:1;align-items:flex-start;gap:8px;min-width:180px;display:flex}.product-images[data-v-761ea8ca]{flex-wrap:wrap;gap:10px;display:flex}.product-images__item[data-v-761ea8ca]{flex-direction:column;gap:6px;width:92px;display:flex}.product-images__thumb[data-v-761ea8ca]{border:1px solid var(--color-border);background:#e8eceb 50%/cover no-repeat;border-radius:10px;width:92px;height:72px;display:block}.product-images__remove[data-v-761ea8ca],.product-images__add[data-v-761ea8ca]{border:1px dashed var(--color-border);cursor:pointer;text-align:center;background:0 0;border-radius:8px;padding:6px 8px;font-size:.75rem}.product-images__add[data-v-761ea8ca]{min-width:92px;min-height:72px;color:var(--color-text-muted);place-items:center;display:grid}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
.settings-page__grid[data-v-1b47466e]{grid-template-columns:repeat(2,1fr);gap:16px;display:grid}.settings-page__section[data-v-1b47466e]{padding:20px}.settings-page__title[data-v-1b47466e]{margin:0 0 16px;font-size:1rem;font-weight:700}.settings-page__checks[data-v-1b47466e]{flex-direction:column;gap:12px;display:flex}.settings-page__check[data-v-1b47466e]{cursor:pointer;align-items:center;gap:10px;font-size:.875rem;display:flex}.settings-page__check input[data-v-1b47466e]{width:16px;height:16px;accent-color:var(--color-primary)}.settings-page__customers[data-v-1b47466e]{flex-direction:column;gap:8px;max-height:220px;padding:8px 0;display:flex;overflow:auto}.settings-page__phone[data-v-1b47466e]{color:var(--color-text-muted);margin-right:6px;font-size:.8125rem}.settings-page__hint[data-v-1b47466e]{color:var(--color-text-muted);margin:6px 0 0;font-size:.75rem;line-height:1.5}@media (width<=1279px){.settings-page__grid[data-v-1b47466e]{grid-template-columns:1fr}}
+1
View File
@@ -0,0 +1 @@
.settings-page__grid[data-v-85da5885]{grid-template-columns:repeat(2,1fr);gap:16px;display:grid}.settings-page__section[data-v-85da5885]{padding:20px}.settings-page__title[data-v-85da5885]{margin:0 0 16px;font-size:1rem;font-weight:700}.settings-page__checks[data-v-85da5885]{flex-direction:column;gap:12px;display:flex}.settings-page__check[data-v-85da5885]{cursor:pointer;align-items:center;gap:10px;font-size:.875rem;display:flex}.settings-page__check input[data-v-85da5885]{width:16px;height:16px;accent-color:var(--color-primary)}.settings-page__customers[data-v-85da5885]{flex-direction:column;gap:8px;max-height:220px;padding:8px 0;display:flex;overflow:auto}.settings-page__phone[data-v-85da5885]{color:var(--color-text-muted);margin-right:6px;font-size:.8125rem}.settings-page__hint[data-v-85da5885]{color:var(--color-text-muted);margin:6px 0 0;font-size:.75rem;line-height:1.5}@media (width<=1279px){.settings-page__grid[data-v-85da5885]{grid-template-columns:1fr}}
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{$ as e,B as t,St as n,bt as r,ct as i,rt as a,yt as o}from"./index-BHqDDh7X.js";import{t as s}from"./orderStatus-CYVblRJB.js";var c=t(a({__name:`StatusBadge`,props:{status:{}},setup(t){let a={active:{label:`فعال`,tone:`success`},inactive:{label:`غیرفعال`,tone:`neutral`},pending_check_review:{label:`در انتظار بررسی`,tone:`warning`},check_approved:{label:`تأیید شده`,tone:`success`},check_rejected:{label:`رد شده`,tone:`danger`}};return(c,l)=>(i(),e(`span`,{class:r([`admin-badge status-badge`,`admin-badge--${(o(s)[t.status]??a[t.status])?.tone??`neutral`}`])},n((o(s)[t.status]??a[t.status])?.label??t.status),3))}}),[[`__scopeId`,`data-v-23aa055a`]]);export{c as t};
import{$ as e,B as t,St as n,bt as r,ct as i,rt as a,yt as o}from"./index-9Ae_VOzQ.js";import{t as s}from"./orderStatus-CYVblRJB.js";var c=t(a({__name:`StatusBadge`,props:{status:{}},setup(t){let a={active:{label:`فعال`,tone:`success`},inactive:{label:`غیرفعال`,tone:`neutral`},pending_check_review:{label:`در انتظار بررسی`,tone:`warning`},check_approved:{label:`تأیید شده`,tone:`success`},check_rejected:{label:`رد شده`,tone:`danger`}};return(c,l)=>(i(),e(`span`,{class:r([`admin-badge status-badge`,`admin-badge--${(o(s)[t.status]??a[t.status])?.tone??`neutral`}`])},n((o(s)[t.status]??a[t.status])?.label??t.status),3))}}),[[`__scopeId`,`data-v-23aa055a`]]);export{c as t};
@@ -1 +1 @@
import{$ as e,B as t,E as n,N as r,St as i,X as a,Z as o,ct as s,ot as c,q as l,rt as u,tt as d,ut as f,vt as p,z as m}from"./index-BHqDDh7X.js";import{t as h}from"./AdminPageSkeleton-E50Kwv4j.js";import{t as g}from"./BaseEmptyState-vNIhbGdV.js";var _={class:`admin-page`},v={key:2,class:`admin-table`},y={class:`muted`,dir:`ltr`},b={class:`muted`,dir:`ltr`},x=[`onClick`],S=t(u({__name:`StockAlertsView`,setup(t){let u=p([]),S=p(!0),C=m();async function w(){S.value=!0;try{u.value=await n.list()}catch(e){C.error(e instanceof r?e.message:`بارگذاری ناموفق بود`)}finally{S.value=!1}}async function T(e){try{await n.notify(e),C.success(`اعلان موجودی ارسال شد`),await w()}catch(e){C.error(e instanceof r?e.message:`ارسال ناموفق بود`)}}return c(()=>{w()}),(t,n)=>(s(),e(`div`,_,[n[1]||=a(`header`,{class:`admin-page__head`},[a(`div`,null,[a(`h1`,null,`درخواست خبر موجودی`),a(`p`,null,`مشتریانی که برای محصول ناموجود درخواست اطلاع داده‌اند`)])],-1),S.value?(s(),o(h,{key:0,variant:`table`})):u.value.length?(s(),e(`table`,v,[n[0]||=a(`thead`,null,[a(`tr`,null,[a(`th`,null,`مشتری`),a(`th`,null,`محصول`),a(`th`,null,`موجودی فعلی`),a(`th`)])],-1),a(`tbody`,null,[(s(!0),e(l,null,f(u.value,t=>(s(),e(`tr`,{key:t.id},[a(`td`,null,[d(i(t.customerName)+` `,1),a(`span`,y,i(t.customerPhone),1)]),a(`td`,null,[d(i(t.productName)+` `,1),a(`span`,b,`(`+i(t.productCode)+`)`,1)]),a(`td`,null,i(t.stock??`—`),1),a(`td`,null,[a(`button`,{type:`button`,class:`admin-btn admin-btn--primary admin-btn--sm`,onClick:e=>T(t.id)},`ارسال اعلان`,8,x)])]))),128))])])):(s(),o(g,{key:1,title:`درخواستی فعال نیست`}))]))}}),[[`__scopeId`,`data-v-61131544`]]);export{S as default};
import{$ as e,B as t,E as n,N as r,St as i,X as a,Z as o,ct as s,ot as c,q as l,rt as u,tt as d,ut as f,vt as p,z as m}from"./index-9Ae_VOzQ.js";import{t as h}from"./AdminPageSkeleton-CKg1wrlm.js";import{t as g}from"./BaseEmptyState-DLwJ8N61.js";var _={class:`admin-page`},v={key:2,class:`admin-table`},y={class:`muted`,dir:`ltr`},b={class:`muted`,dir:`ltr`},x=[`onClick`],S=t(u({__name:`StockAlertsView`,setup(t){let u=p([]),S=p(!0),C=m();async function w(){S.value=!0;try{u.value=await n.list()}catch(e){C.error(e instanceof r?e.message:`بارگذاری ناموفق بود`)}finally{S.value=!1}}async function T(e){try{await n.notify(e),C.success(`اعلان موجودی ارسال شد`),await w()}catch(e){C.error(e instanceof r?e.message:`ارسال ناموفق بود`)}}return c(()=>{w()}),(t,n)=>(s(),e(`div`,_,[n[1]||=a(`header`,{class:`admin-page__head`},[a(`div`,null,[a(`h1`,null,`درخواست خبر موجودی`),a(`p`,null,`مشتریانی که برای محصول ناموجود درخواست اطلاع داده‌اند`)])],-1),S.value?(s(),o(h,{key:0,variant:`table`})):u.value.length?(s(),e(`table`,v,[n[0]||=a(`thead`,null,[a(`tr`,null,[a(`th`,null,`مشتری`),a(`th`,null,`محصول`),a(`th`,null,`موجودی فعلی`),a(`th`)])],-1),a(`tbody`,null,[(s(!0),e(l,null,f(u.value,t=>(s(),e(`tr`,{key:t.id},[a(`td`,null,[d(i(t.customerName)+` `,1),a(`span`,y,i(t.customerPhone),1)]),a(`td`,null,[d(i(t.productName)+` `,1),a(`span`,b,`(`+i(t.productCode)+`)`,1)]),a(`td`,null,i(t.stock??`—`),1),a(`td`,null,[a(`button`,{type:`button`,class:`admin-btn admin-btn--primary admin-btn--sm`,onClick:e=>T(t.id)},`ارسال اعلان`,8,x)])]))),128))])])):(s(),o(g,{key:1,title:`درخواستی فعال نیست`}))]))}}),[[`__scopeId`,`data-v-61131544`]]);export{S as default};
@@ -1 +1 @@
import{$ as e,B as t,D as n,N as r,R as i,S as a,St as o,W as s,X as c,Y as l,Z as u,_t as d,ct as f,g as p,ht as m,mt as h,nt as g,ot as _,q as v,rt as y,tt as b,ut as x,vt as S,z as C}from"./index-BHqDDh7X.js";import{t as w}from"./AdminPageSkeleton-E50Kwv4j.js";import{t as T}from"./BaseEmptyState-vNIhbGdV.js";import{t as E}from"./AdminSelect-BjB6PHdr.js";var D={class:`admin-page`},O={class:`admin-page__head`},k={key:2,class:`admin-table`},A={class:`muted`,dir:`ltr`},j=[`onClick`],M={class:`field`},N={class:`field`},P={class:`field`},F=[`disabled`],I=t(y({__name:`SuggestionsView`,setup(t){let y=S([]),I=S(!0),L=S([]),R=S([]),z=S(!1),B=C(),V=d({customerId:``,productId:``,note:``}),H=l(()=>L.value.map(e=>({value:e.id,label:e.name?.trim()||e.phone}))),U=l(()=>R.value.map(e=>({value:e.id,label:`${e.name} (${e.productCode})`})));async function W(){I.value=!0;try{let[e,t,r]=await Promise.all([n.list(),p.list(),a.list()]);y.value=e,L.value=t,R.value=r}catch(e){B.error(e instanceof r?e.message:`بارگذاری ناموفق بود`)}finally{I.value=!1}}async function G(){try{await n.create({customerId:V.customerId,productId:V.productId,note:V.note.trim()||void 0}),z.value=!1,V.note=``,B.success(`پیشنهاد ثبت شد`),await W()}catch(e){B.error(e instanceof r?e.message:`ثبت ناموفق بود`)}}async function K(e){try{await n.setActive(e.id,!e.isActive),await W()}catch(e){B.error(e instanceof r?e.message:`به‌روزرسانی ناموفق بود`)}}return _(()=>{W()}),(t,n)=>(f(),e(`div`,D,[c(`header`,O,[n[5]||=c(`div`,null,[c(`h1`,null,`پیشنهاد محصول`),c(`p`,null,`پیشنهاد دستی محصول به مشتری`)],-1),c(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:n[0]||=e=>z.value=!0},`پیشنهاد جدید`)]),I.value?(f(),u(w,{key:0,variant:`table`})):y.value.length?(f(),e(`table`,k,[n[6]||=c(`thead`,null,[c(`tr`,null,[c(`th`,null,`مشتری`),c(`th`,null,`محصول`),c(`th`,null,`یادداشت`),c(`th`,null,`وضعیت`),c(`th`)])],-1),c(`tbody`,null,[(f(!0),e(v,null,x(y.value,t=>(f(),e(`tr`,{key:t.id},[c(`td`,null,o(t.customerName),1),c(`td`,null,[b(o(t.productName)+` `,1),c(`span`,A,`(`+o(t.productCode)+`)`,1)]),c(`td`,null,o(t.note||`—`),1),c(`td`,null,o(t.isActive?`فعال`:`غیرفعال`),1),c(`td`,null,[c(`button`,{type:`button`,class:`link`,onClick:e=>K(t)},o(t.isActive?`غیرفعال`:`فعال`),9,j)])]))),128))])])):(f(),u(T,{key:1,title:`پیشنهادی ثبت نشده`})),g(i,{open:z.value,title:`پیشنهاد محصول`,onClose:n[4]||=e=>z.value=!1},{footer:h(()=>[c(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!V.customerId||!V.productId,onClick:G},` ثبت `,8,F)]),default:h(()=>[c(`label`,M,[n[7]||=b(`مشتری `,-1),g(E,{modelValue:V.customerId,"onUpdate:modelValue":n[1]||=e=>V.customerId=e,options:H.value},null,8,[`modelValue`,`options`])]),c(`label`,N,[n[8]||=b(`محصول `,-1),g(E,{modelValue:V.productId,"onUpdate:modelValue":n[2]||=e=>V.productId=e,options:U.value},null,8,[`modelValue`,`options`])]),c(`label`,P,[n[9]||=b(`یادداشت`,-1),m(c(`textarea`,{"onUpdate:modelValue":n[3]||=e=>V.note=e,class:`admin-input`,rows:`3`},null,512),[[s,V.note]])])]),_:1},8,[`open`])]))}}),[[`__scopeId`,`data-v-56e3e728`]]);export{I as default};
import{$ as e,B as t,D as n,N as r,R as i,S as a,St as o,W as s,X as c,Y as l,Z as u,_t as d,ct as f,g as p,ht as m,mt as h,nt as g,ot as _,q as v,rt as y,tt as b,ut as x,vt as S,z as C}from"./index-9Ae_VOzQ.js";import{t as w}from"./AdminPageSkeleton-CKg1wrlm.js";import{t as T}from"./BaseEmptyState-DLwJ8N61.js";import{t as E}from"./AdminSelect-BCHHmDtL.js";var D={class:`admin-page`},O={class:`admin-page__head`},k={key:2,class:`admin-table`},A={class:`muted`,dir:`ltr`},j=[`onClick`],M={class:`field`},N={class:`field`},P={class:`field`},F=[`disabled`],I=t(y({__name:`SuggestionsView`,setup(t){let y=S([]),I=S(!0),L=S([]),R=S([]),z=S(!1),B=C(),V=d({customerId:``,productId:``,note:``}),H=l(()=>L.value.map(e=>({value:e.id,label:e.name?.trim()||e.phone}))),U=l(()=>R.value.map(e=>({value:e.id,label:`${e.name} (${e.productCode})`})));async function W(){I.value=!0;try{let[e,t,r]=await Promise.all([n.list(),p.list(),a.list()]);y.value=e,L.value=t,R.value=r}catch(e){B.error(e instanceof r?e.message:`بارگذاری ناموفق بود`)}finally{I.value=!1}}async function G(){try{await n.create({customerId:V.customerId,productId:V.productId,note:V.note.trim()||void 0}),z.value=!1,V.note=``,B.success(`پیشنهاد ثبت شد`),await W()}catch(e){B.error(e instanceof r?e.message:`ثبت ناموفق بود`)}}async function K(e){try{await n.setActive(e.id,!e.isActive),await W()}catch(e){B.error(e instanceof r?e.message:`به‌روزرسانی ناموفق بود`)}}return _(()=>{W()}),(t,n)=>(f(),e(`div`,D,[c(`header`,O,[n[5]||=c(`div`,null,[c(`h1`,null,`پیشنهاد محصول`),c(`p`,null,`پیشنهاد دستی محصول به مشتری`)],-1),c(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:n[0]||=e=>z.value=!0},`پیشنهاد جدید`)]),I.value?(f(),u(w,{key:0,variant:`table`})):y.value.length?(f(),e(`table`,k,[n[6]||=c(`thead`,null,[c(`tr`,null,[c(`th`,null,`مشتری`),c(`th`,null,`محصول`),c(`th`,null,`یادداشت`),c(`th`,null,`وضعیت`),c(`th`)])],-1),c(`tbody`,null,[(f(!0),e(v,null,x(y.value,t=>(f(),e(`tr`,{key:t.id},[c(`td`,null,o(t.customerName),1),c(`td`,null,[b(o(t.productName)+` `,1),c(`span`,A,`(`+o(t.productCode)+`)`,1)]),c(`td`,null,o(t.note||`—`),1),c(`td`,null,o(t.isActive?`فعال`:`غیرفعال`),1),c(`td`,null,[c(`button`,{type:`button`,class:`link`,onClick:e=>K(t)},o(t.isActive?`غیرفعال`:`فعال`),9,j)])]))),128))])])):(f(),u(T,{key:1,title:`پیشنهادی ثبت نشده`})),g(i,{open:z.value,title:`پیشنهاد محصول`,onClose:n[4]||=e=>z.value=!1},{footer:h(()=>[c(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!V.customerId||!V.productId,onClick:G},` ثبت `,8,F)]),default:h(()=>[c(`label`,M,[n[7]||=b(`مشتری `,-1),g(E,{modelValue:V.customerId,"onUpdate:modelValue":n[1]||=e=>V.customerId=e,options:H.value},null,8,[`modelValue`,`options`])]),c(`label`,N,[n[8]||=b(`محصول `,-1),g(E,{modelValue:V.productId,"onUpdate:modelValue":n[2]||=e=>V.productId=e,options:U.value},null,8,[`modelValue`,`options`])]),c(`label`,P,[n[9]||=b(`یادداشت`,-1),m(c(`textarea`,{"onUpdate:modelValue":n[3]||=e=>V.note=e,class:`admin-input`,rows:`3`},null,512),[[s,V.note]])])]),_:1},8,[`open`])]))}}),[[`__scopeId`,`data-v-56e3e728`]]);export{I 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
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -5,8 +5,8 @@
<link rel="icon" href="/admin/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>پنل مدیریت | پارچه</title>
<script type="module" crossorigin src="/admin/assets/index-BHqDDh7X.js"></script>
<link rel="stylesheet" crossorigin href="/admin/assets/index-FKaOTPi2.css">
<script type="module" crossorigin src="/admin/assets/index-9Ae_VOzQ.js"></script>
<link rel="stylesheet" crossorigin href="/admin/assets/index-C3X1YgAk.css">
</head>
<body>
<div id="app"></div>
+1 -1
View File
@@ -71,7 +71,7 @@ const router = createRouter({
path: 'customers',
name: 'customers',
component: () => import('@/views/customers/CustomersView.vue'),
meta: { title: 'مشتریان' },
meta: { title: 'مشتریان و واسطه‌ها' },
},
{
path: 'products',
+7
View File
@@ -622,9 +622,16 @@ export type ProductSuggestion = {
id: string
customerId: string
customerName: string
customerPhone?: string
productId: string
productName: string
productCode: string
catalogName?: string
catalogCode?: string
color?: string
subtitle?: string
imageUrl?: string
isNew?: boolean
note?: string
isActive: boolean
createdAt: string
+1 -1
View File
@@ -3,7 +3,7 @@ import type { NavItem } from '@/types'
export const ADMIN_NAV_ITEMS: NavItem[] = [
{ name: 'dashboard', label: 'داشبورد', path: '/', icon: 'home' },
{ name: 'orders', label: 'سفارش‌ها', path: '/orders', icon: 'orders' },
{ name: 'customers', label: 'مشتریان', path: '/customers', icon: 'customers' },
{ name: 'customers', label: 'مشتریان و واسطه‌ها', path: '/customers', icon: 'customers' },
{ name: 'products', label: 'محصولات', path: '/products', icon: 'products' },
{ name: 'categories', label: 'دسته‌بندی‌ها', path: '/categories', icon: 'catalogs' },
{ name: 'banners', label: 'بنرها', path: '/banners', icon: 'image' },
@@ -0,0 +1,308 @@
<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import AdminSelect from '@/components/ui/AdminSelect.vue'
import { productsApi, suggestionsApi, type ProductSuggestion } from '@/services/api'
import { ApiError } from '@/services/http'
import { useToast } from '@/composables/useToast'
import type { Product } from '@/types'
const props = defineProps<{
customerId: string
}>()
const toast = useToast()
const loading = ref(true)
const saving = ref(false)
const list = ref<ProductSuggestion[]>([])
const products = ref<Product[]>([])
const selectedProductIds = ref<string[]>([])
const note = ref('')
const productOptions = computed(() =>
products.value
.filter((p) => !list.value.some((s) => s.productId === p.id && s.isActive))
.map((p) => ({
value: p.id,
label: `${p.name} (${p.productCode})`,
})),
)
async function load() {
if (!props.customerId) return
loading.value = true
try {
const [suggestions, productRows] = await Promise.all([
suggestionsApi.list(props.customerId),
productsApi.list(),
])
list.value = suggestions
products.value = productRows
} catch (err) {
toast.error(err instanceof ApiError ? err.message : 'بارگذاری پیشنهادها ناموفق بود')
} finally {
loading.value = false
}
}
async function addSelected() {
if (!selectedProductIds.value.length) return
saving.value = true
try {
for (const productId of selectedProductIds.value) {
await suggestionsApi.create({
customerId: props.customerId,
productId,
note: note.value.trim() || undefined,
})
}
selectedProductIds.value = []
note.value = ''
toast.success('پیشنهادها به صفحه خانه مشتری اضافه شد')
await load()
} catch (err) {
toast.error(err instanceof ApiError ? err.message : 'ثبت پیشنهاد ناموفق بود')
} finally {
saving.value = false
}
}
async function toggle(row: ProductSuggestion) {
try {
await suggestionsApi.setActive(row.id, !row.isActive)
await load()
} catch (err) {
toast.error(err instanceof ApiError ? err.message : 'به‌روزرسانی ناموفق بود')
}
}
function onProductPick(productId: string) {
if (!productId) return
if (!selectedProductIds.value.includes(productId)) {
selectedProductIds.value = [...selectedProductIds.value, productId]
}
}
function removePick(productId: string) {
selectedProductIds.value = selectedProductIds.value.filter((id) => id !== productId)
}
watch(
() => props.customerId,
() => {
void load()
},
)
onMounted(() => {
void load()
})
</script>
<template>
<section class="suggestions-panel">
<header class="suggestions-panel__head">
<div>
<h3 class="suggestions-panel__title">پیشنهاد اختصاصی در اپ</h3>
<p class="suggestions-panel__hint">
محصولات انتخاب‌شده در بخش «پیشنهاد اختصاصی ما برای شما» در صفحه خانه مشتری نمایش داده می‌شوند.
</p>
</div>
</header>
<div v-if="loading" class="suggestions-panel__loading">در حال بارگذاری...</div>
<template v-else>
<div class="suggestions-panel__add">
<label class="field">
افزودن محصول (کد کالیته)
<AdminSelect
:model-value="''"
:options="[{ value: '', label: 'انتخاب محصول...' }, ...productOptions]"
@update:model-value="onProductPick"
/>
</label>
<div v-if="selectedProductIds.length" class="suggestions-panel__picked">
<span
v-for="id in selectedProductIds"
:key="id"
class="suggestions-panel__chip"
>
{{ products.find((p) => p.id === id)?.productCode || id }}
<button type="button" aria-label="حذف" @click="removePick(id)">×</button>
</span>
</div>
<label class="field">
یادداشت (اختیاری)
<textarea v-model="note" class="admin-input" rows="2" placeholder="دلیل پیشنهاد برای مشتری" />
</label>
<button
type="button"
class="admin-btn admin-btn--primary admin-btn--sm"
:disabled="!selectedProductIds.length || saving"
@click="addSelected"
>
افزودن به صفحه خانه مشتری
</button>
</div>
<div v-if="list.length" class="suggestions-panel__list">
<h4 class="suggestions-panel__sub">پیشنهادهای ثبت‌شده</h4>
<ul>
<li v-for="row in list" :key="row.id" class="suggestions-panel__row">
<div>
<strong>{{ row.productName }}</strong>
<span class="muted" dir="ltr">({{ row.productCode }})</span>
<p v-if="row.note" class="note">{{ row.note }}</p>
</div>
<div class="suggestions-panel__actions">
<span :class="row.isActive ? 'on' : 'off'">{{ row.isActive ? 'فعال' : 'غیرفعال' }}</span>
<button type="button" class="link" @click="toggle(row)">
{{ row.isActive ? 'حذف از خانه' : 'فعال‌سازی' }}
</button>
</div>
</li>
</ul>
</div>
<p v-else class="suggestions-panel__empty">هنوز پیشنهادی برای این مشتری ثبت نشده است.</p>
</template>
</section>
</template>
<style scoped>
.suggestions-panel {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid var(--color-border);
}
.suggestions-panel__head {
margin-bottom: 12px;
}
.suggestions-panel__title {
margin: 0 0 4px;
font-size: 0.95rem;
}
.suggestions-panel__hint {
margin: 0;
font-size: 0.78rem;
color: var(--color-text-muted);
line-height: 1.5;
}
.suggestions-panel__loading,
.suggestions-panel__empty {
font-size: 0.85rem;
color: var(--color-text-muted);
}
.suggestions-panel__add {
display: flex;
flex-direction: column;
gap: 10px;
}
.field {
display: flex;
flex-direction: column;
gap: 6px;
font-size: 0.85rem;
}
.suggestions-panel__picked {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.suggestions-panel__chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
border-radius: 999px;
background: var(--color-primary-soft);
color: var(--color-primary);
font-size: 0.75rem;
font-weight: 700;
}
.suggestions-panel__chip button {
border: none;
background: none;
color: inherit;
cursor: pointer;
font-size: 1rem;
line-height: 1;
}
.suggestions-panel__sub {
margin: 16px 0 8px;
font-size: 0.85rem;
}
.suggestions-panel__list ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 8px;
}
.suggestions-panel__row {
display: flex;
justify-content: space-between;
gap: 12px;
align-items: flex-start;
padding: 10px 12px;
border-radius: 10px;
background: var(--color-bg);
border: 1px solid var(--color-border);
}
.suggestions-panel__actions {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
flex-shrink: 0;
}
.muted {
color: var(--color-text-muted);
font-size: 0.75rem;
margin-inline-start: 4px;
}
.note {
margin: 4px 0 0;
font-size: 0.75rem;
color: var(--color-text-muted);
}
.on {
color: var(--color-success);
font-size: 0.72rem;
font-weight: 700;
}
.off {
color: var(--color-text-muted);
font-size: 0.72rem;
}
.link {
border: none;
background: none;
color: var(--color-primary);
cursor: pointer;
font-family: inherit;
font-size: 0.78rem;
}
</style>
+117 -23
View File
@@ -8,6 +8,7 @@ import ActiveSwitchCell from '@/components/ui/ActiveSwitchCell.vue'
import AdminIcon from '@/components/icons/AdminIcon.vue'
import AdminSelect from '@/components/ui/AdminSelect.vue'
import { brandsApi, customersApi, levelsApi, type Brand, type CustomerLevel } from '@/services/api'
import CustomerSuggestionsPanel from './CustomerSuggestionsPanel.vue'
import { ApiError } from '@/services/http'
import { useToast } from '@/composables/useToast'
import { CUSTOMER_TYPE_LABELS } from '@/utils/adminLabels'
@@ -19,6 +20,7 @@ const levels = ref<CustomerLevel[]>([])
const agents = ref<Customer[]>([])
const brands = ref<Brand[]>([])
const searchQuery = ref('')
const roleTab = ref<'customer' | 'agent'>('customer')
const loading = ref(true)
const modalMode = ref<'add' | 'edit' | null>(null)
const editingId = ref<string | null>(null)
@@ -49,6 +51,15 @@ const appRoleOptions = [
{ value: 'agent', label: 'واسطه' },
]
const APP_ROLE_LABELS: Record<'customer' | 'agent', string> = {
customer: 'مشتری',
agent: 'واسطه',
}
function appRoleLabel(role?: 'customer' | 'agent' | null) {
return APP_ROLE_LABELS[role === 'agent' ? 'agent' : 'customer']
}
const levelOptions = computed(() => [
{ value: '', label: 'بدون سطح' },
...levels.value.map((level) => ({ value: level.id, label: level.label })),
@@ -109,14 +120,27 @@ function toggleBrand(brandId: string, checked: boolean) {
async function loadCustomers() {
loading.value = true
try {
customerList.value = await customersApi.list()
customerList.value = await customersApi.list(undefined, roleTab.value)
} catch (err) {
toast.error(err instanceof ApiError ? err.message : 'بارگذاری مشتریان انجام نشد.')
toast.error(
err instanceof ApiError
? err.message
: roleTab.value === 'agent'
? 'بارگذاری واسطه‌ها انجام نشد.'
: 'بارگذاری مشتریان انجام نشد.',
)
} finally {
loading.value = false
}
}
function setRoleTab(tab: 'customer' | 'agent') {
if (roleTab.value === tab) return
roleTab.value = tab
searchQuery.value = ''
void loadCustomers()
}
async function loadLookups() {
try {
const [levelsData, agentsData, brandsData] = await Promise.all([
@@ -141,6 +165,7 @@ function openAddModal() {
modalMode.value = 'add'
editingId.value = null
Object.assign(form, emptyForm())
form.appRole = roleTab.value
formError.value = ''
}
@@ -219,10 +244,33 @@ function clearSearch() {
<div class="customers-page">
<div class="admin-page-header">
<div>
<h1 class="admin-page-header__title">مشتریان</h1>
<h1 class="admin-page-header__title">مشتریان و واسطه‌ها</h1>
</div>
<button type="button" class="admin-btn admin-btn--primary" @click="openAddModal">
افزودن مشتری
{{ roleTab === 'agent' ? 'افزودن واسطه' : 'افزودن مشتری' }}
</button>
</div>
<div class="customers-page__tabs" role="tablist" aria-label="نوع کاربر">
<button
type="button"
role="tab"
class="customers-page__tab"
:class="{ 'is-active': roleTab === 'customer' }"
:aria-selected="roleTab === 'customer'"
@click="setRoleTab('customer')"
>
مشتریان
</button>
<button
type="button"
role="tab"
class="customers-page__tab"
:class="{ 'is-active': roleTab === 'agent' }"
:aria-selected="roleTab === 'agent'"
@click="setRoleTab('agent')"
>
واسطه‌ها
</button>
</div>
@@ -241,18 +289,26 @@ function clearSearch() {
v-else-if="!filteredCustomers.length"
class="admin-card"
icon="customers"
:title="searchQuery.trim() ? 'نتیجه‌ای یافت نشد' : 'مشتریان ثبت شده'"
:title="
searchQuery.trim()
? 'نتیجه‌ای یافت نشد'
: roleTab === 'agent'
? 'واسطه‌ای ثبت نشده'
: 'مشتریان ثبت شده'
"
:description="
searchQuery.trim()
? 'عبارت جستجو را تغییر دهید یا فیلترها را پاک کنید.'
: 'برای شروع، اولین مشتری را ثبت کنید.'
: roleTab === 'agent'
? 'برای شروع، اولین واسطه را ثبت کنید.'
: 'برای شروع، اولین مشتری را ثبت کنید.'
"
>
<button v-if="searchQuery.trim()" type="button" class="admin-btn admin-btn--outline admin-btn--sm" @click="clearSearch">
پاک کردن جستجو
</button>
<button v-else type="button" class="admin-btn admin-btn--primary admin-btn--sm" @click="openAddModal">
افزودن مشتری
{{ roleTab === 'agent' ? 'افزودن واسطه' : 'افزودن مشتری' }}
</button>
</BaseEmptyState>
@@ -261,13 +317,14 @@ function clearSearch() {
<table class="admin-table">
<thead>
<tr>
<th>نام مشتری</th>
<th>{{ roleTab === 'agent' ? 'نام واسطه' : 'نام مشتری' }}</th>
<th>تلفن</th>
<th>شناسه ملی</th>
<th>نوع</th>
<th>سطح</th>
<th>واسطه</th>
<th>شرکت</th>
<th>نقش</th>
<th v-if="roleTab === 'agent'">کد واسطه</th>
<th v-if="roleTab === 'customer'">نوع</th>
<th v-if="roleTab === 'customer'">سطح</th>
<th v-if="roleTab === 'customer'">واسطه</th>
<th v-if="roleTab === 'customer'">شرکت</th>
<th class="numeric">تعداد سفارش</th>
<th class="numeric">مجموع متراژ</th>
<th class="status">وضعیت</th>
@@ -279,11 +336,12 @@ function clearSearch() {
<tr v-for="customer in filteredCustomers" :key="customer.id">
<td>{{ displayCell(customer.name) }}</td>
<td>{{ displayCell(customer.phone) }}</td>
<td>{{ displayCell(customer.nationalId) }}</td>
<td>{{ displayCell(CUSTOMER_TYPE_LABELS[customer.customerType]) }}</td>
<td>{{ displayCell(customer.levelLabel) }}</td>
<td>{{ displayCell(customer.assignedAgentName) }}</td>
<td>{{ displayCell(customer.companyName) }}</td>
<td>{{ appRoleLabel(customer.appRole) }}</td>
<td v-if="roleTab === 'agent'">{{ displayCell(customer.agentCode) }}</td>
<td v-if="roleTab === 'customer'">{{ displayCell(CUSTOMER_TYPE_LABELS[customer.customerType]) }}</td>
<td v-if="roleTab === 'customer'">{{ displayCell(customer.levelLabel) }}</td>
<td v-if="roleTab === 'customer'">{{ displayCell(customer.assignedAgentName) }}</td>
<td v-if="roleTab === 'customer'">{{ displayCell(customer.companyName) }}</td>
<td class="numeric">{{ displayCell(customer.orderCount) }}</td>
<td class="numeric">{{ displayMeterage(customer.totalMeterage) }}</td>
<td class="status">
@@ -326,10 +384,11 @@ function clearSearch() {
</div>
<div class="admin-card-item__meta">
<span>{{ displayCell(customer.phone) }}</span>
<span>{{ displayCell(CUSTOMER_TYPE_LABELS[customer.customerType]) }}</span>
<span>{{ displayCell(customer.levelLabel) }}</span>
<span>{{ displayCell(customer.assignedAgentName) }}</span>
<span>{{ displayCell(customer.companyName) }}</span>
<span v-if="roleTab === 'agent'">کد: {{ displayCell(customer.agentCode) }}</span>
<span v-if="roleTab === 'customer'">{{ displayCell(CUSTOMER_TYPE_LABELS[customer.customerType]) }}</span>
<span v-if="roleTab === 'customer'">{{ displayCell(customer.levelLabel) }}</span>
<span v-if="roleTab === 'customer'">واسطه: {{ displayCell(customer.assignedAgentName) }}</span>
<span v-if="roleTab === 'customer'">{{ displayCell(customer.companyName) }}</span>
<span>
{{ displayCell(customer.orderCount) }} سفارش · {{ displayMeterage(customer.totalMeterage) }}
</span>
@@ -441,13 +500,24 @@ function clearSearch() {
<div class="admin-form__field">
<BaseSwitch v-model="form.isActive" label="وضعیت" />
</div>
<CustomerSuggestionsPanel
v-if="modalMode === 'edit' && editingId && form.appRole === 'customer'"
:customer-id="editingId"
/>
</form>
<template #footer>
<button type="button" class="admin-btn admin-btn--outline" @click="closeModal">انصراف</button>
<button type="button" class="admin-btn admin-btn--primary" :disabled="!isFormValid || saving" @click="submitCustomer">
<span v-if="saving" class="admin-btn__spinner" aria-hidden="true" />
{{ modalMode === 'edit' ? 'ذخیره تغییرات' : 'ثبت مشتری' }}
{{
modalMode === 'edit'
? 'ذخیره تغییرات'
: form.appRole === 'agent'
? 'ثبت واسطه'
: 'ثبت مشتری'
}}
</button>
</template>
</BaseModal>
@@ -455,6 +525,30 @@ function clearSearch() {
</template>
<style scoped>
.customers-page__tabs {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
.customers-page__tab {
border: 1px solid var(--color-border);
border-radius: 999px;
background: var(--color-surface);
color: var(--color-text-muted);
padding: 8px 16px;
font: inherit;
font-size: 0.875rem;
font-weight: 600;
cursor: pointer;
}
.customers-page__tab.is-active {
border-color: var(--color-primary);
background: var(--color-primary-soft);
color: var(--color-primary);
}
.customers-page__search {
display: flex;
align-items: center;