change nademitex2
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
import{$ as e,g as t,k as n,l as r,st as i}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a}from"./http-BjLkjdQu.js";import{V as o}from"./index-BzcByePp.js";import{t as s}from"./BaseSwitch-pJwnFBVo.js";function c(e=480){return new Promise(t=>{window.setTimeout(t,e)})}function l(t){let n=e(null),r=e(null),i=a();async function o(e,a){if(n.value)return a;let o=!a;if(!o&&t.confirmOff&&!await t.confirmOff())return a;n.value=e,r.value=null;let s=a;try{return await t.onPersist(o),i.success(t.successMessage?.(o)??(o?`وضعیت فعال شد.`:`وضعیت غیرفعال شد.`)),o}catch{return r.value=e,i.error(t.errorMessage??`بهروزرسانی وضعیت انجام نشد.`),s}finally{n.value=null}}function s(e){return n.value===e}function c(e){return r.value===e}return{toggle:o,isLoading:s,hasError:c}}var u=t({__name:`ActiveSwitchCell`,props:{id:{},modelValue:{type:Boolean},entityName:{},entityType:{},persist:{type:Function}},emits:[`update:modelValue`],setup(e,{emit:t}){let a=e,u=t,{toggle:d,isLoading:f,hasError:p}=l({onPersist:async e=>{a.persist?await a.persist(a.id,e):await c()},successMessage:e=>e?`${a.entityType??`مورد`} «${a.entityName}» فعال شد.`:`${a.entityType??`مورد`} «${a.entityName}» غیرفعال شد.`});async function m(e){if(e===a.modelValue)return;let t=a.entityType??`مورد`;if(!await o({title:e?`فعالسازی ${t}`:`غیرفعالسازی ${t}`,message:e?`آیا از فعال کردن «${a.entityName}» مطمئن هستید؟`:`آیا از غیرفعال کردن «${a.entityName}» مطمئن هستید؟`,tone:e?`primary`:`danger`,confirmLabel:e?`فعال کردن`:`غیرفعال کردن`,cancelLabel:`انصراف`}))return;let n=await d(a.id,a.modelValue);u(`update:modelValue`,n)}return(t,a)=>(n(),r(s,{"model-value":e.modelValue,loading:i(f)(e.id),error:i(p)(e.id),"onUpdate:modelValue":m},null,8,[`model-value`,`loading`,`error`]))}});export{u as t};
|
||||
import{$ as e,g as t,k as n,l as r,st as i}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a}from"./http-BjLkjdQu.js";import{z as o}from"./index-SWzbcuqQ.js";import{t as s}from"./BaseSwitch-pJwnFBVo.js";function c(e=480){return new Promise(t=>{window.setTimeout(t,e)})}function l(t){let n=e(null),r=e(null),i=a();async function o(e,a){if(n.value)return a;let o=!a;if(!o&&t.confirmOff&&!await t.confirmOff())return a;n.value=e,r.value=null;let s=a;try{return await t.onPersist(o),i.success(t.successMessage?.(o)??(o?`وضعیت فعال شد.`:`وضعیت غیرفعال شد.`)),o}catch{return r.value=e,i.error(t.errorMessage??`بهروزرسانی وضعیت انجام نشد.`),s}finally{n.value=null}}function s(e){return n.value===e}function c(e){return r.value===e}return{toggle:o,isLoading:s,hasError:c}}var u=t({__name:`ActiveSwitchCell`,props:{id:{},modelValue:{type:Boolean},entityName:{},entityType:{},persist:{type:Function}},emits:[`update:modelValue`],setup(e,{emit:t}){let a=e,u=t,{toggle:d,isLoading:f,hasError:p}=l({onPersist:async e=>{a.persist?await a.persist(a.id,e):await c()},successMessage:e=>e?`${a.entityType??`مورد`} «${a.entityName}» فعال شد.`:`${a.entityType??`مورد`} «${a.entityName}» غیرفعال شد.`});async function m(e){if(e===a.modelValue)return;let t=a.entityType??`مورد`;if(!await o({title:e?`فعالسازی ${t}`:`غیرفعالسازی ${t}`,message:e?`آیا از فعال کردن «${a.entityName}» مطمئن هستید؟`:`آیا از غیرفعال کردن «${a.entityName}» مطمئن هستید؟`,tone:e?`primary`:`danger`,confirmLabel:e?`فعال کردن`:`غیرفعال کردن`,cancelLabel:`انصراف`}))return;let n=await d(a.id,a.modelValue);u(`update:modelValue`,n)}return(t,a)=>(n(),r(s,{"model-value":e.modelValue,loading:i(f)(e.id),error:i(p)(e.id),"onUpdate:modelValue":m},null,8,[`model-value`,`loading`,`error`]))}});export{u as t};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{Dt as e,d as t,g as n,k as r,s as i,t as a}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{c as o,r as s}from"./index-BzcByePp.js";var c=[`id`,`value`,`placeholder`,`disabled`],l=a(n({__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(n,{emit:a}){let l=n,u=a,d=i(()=>l.modelValue==null||!Number.isFinite(l.modelValue)?``:o(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=o(r)}return(i,a)=>(r(),t(`input`,{id:n.id,type:`text`,inputmode:`numeric`,dir:`ltr`,class:e([`admin-currency-input`,n.inputClass]),value:d.value,placeholder:n.placeholder,disabled:n.disabled,onInput:f},null,42,c))}}),[[`__scopeId`,`data-v-56435fc8`]]);export{l as t};
|
||||
import{Dt as e,d as t,g as n,k as r,s as i,t as a}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{c as o,r as s}from"./index-SWzbcuqQ.js";var c=[`id`,`value`,`placeholder`,`disabled`],l=a(n({__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(n,{emit:a}){let l=n,u=a,d=i(()=>l.modelValue==null||!Number.isFinite(l.modelValue)?``:o(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=o(r)}return(i,a)=>(r(),t(`input`,{id:n.id,type:`text`,inputmode:`numeric`,dir:`ltr`,class:e([`admin-currency-input`,n.inputClass]),value:d.value,placeholder:n.placeholder,disabled:n.disabled,onInput:f},null,42,c))}}),[[`__scopeId`,`data-v-56435fc8`]]);export{l as t};
|
||||
+1
@@ -0,0 +1 @@
|
||||
.image-picker__label[data-v-0959163b]{margin:0 0 8px;font-size:.8125rem;font-weight:600}.image-picker__row[data-v-0959163b]{align-items:center;gap:12px;display:flex}.image-picker__preview[data-v-0959163b]{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-0959163b]{background:repeating-linear-gradient(45deg,#eef1f0,#eef1f0 8px,#e4e8e6 8px 16px)}.image-picker__actions[data-v-0959163b]{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.image-picker__file[data-v-0959163b]{display:none}.image-picker__error[data-v-0959163b]{width:100%;color:var(--color-danger);margin:0;font-size:.75rem}.image-picker__ok[data-v-0959163b]{width:100%;color:var(--color-success-dark);margin:0;font-size:.75rem;font-weight:600}
|
||||
+1
@@ -0,0 +1 @@
|
||||
import{$ as e,At as t,Dt as n,c as r,d as i,g as a,k as o,kt as s,st as c,t as l,u}from"./_plugin-vue_export-helper-QrIvvHC8.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=l(a({__name:`AdminImagePicker`,props:{modelValue:{},label:{},showRemove:{type:Boolean,default:!0}},emits:[`update:modelValue`],setup(a,{emit:l}){let d=a,f=l,h=e(null),g=e(!1),T=e(``),E=e(!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(e,l)=>(o(),i(`div`,_,[a.label?(o(),i(`p`,v,t(a.label),1)):u(``,!0),r(`div`,y,[r(`div`,{class:n([`image-picker__preview`,{"image-picker__preview--empty":!d.modelValue}]),style:s(d.modelValue?{backgroundImage:c(p)(d.modelValue)}:void 0)},null,6),r(`div`,b,[r(`button`,{type:`button`,class:`admin-btn admin-btn--outline admin-btn--sm`,disabled:g.value,onClick:D},t(d.modelValue?`تغییر تصویر`:`افزودن تصویر`),9,x),d.showRemove&&d.modelValue?(o(),i(`button`,{key:0,type:`button`,class:`admin-btn admin-btn--outline admin-btn--sm`,disabled:g.value,onClick:k},` حذف `,8,S)):u(``,!0),T.value?(o(),i(`p`,C,t(T.value),1)):E.value?(o(),i(`p`,w,`تصویر انتخاب شد — برای ثبت نهایی «ثبت» را بزنید.`)):u(``,!0)])]),r(`input`,{ref_key:`inputRef`,ref:h,type:`file`,accept:`image/*`,class:`image-picker__file`,onChange:O},null,544)]))}}),[[`__scopeId`,`data-v-0959163b`]]);export{p as n,T as t};
|
||||
-1
@@ -1 +0,0 @@
|
||||
import{$ as e,At as t,Dt as n,c as r,d as i,g as a,k as o,kt as s,st as c,t as l,u}from"./_plugin-vue_export-helper-QrIvvHC8.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=l(a({__name:`AdminImagePicker`,props:{modelValue:{},label:{}},emits:[`update:modelValue`],setup(a,{emit:l}){let d=a,f=l,h=e(null),g=e(!1),T=e(``),E=e(!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(e,l)=>(o(),i(`div`,_,[a.label?(o(),i(`p`,v,t(a.label),1)):u(``,!0),r(`div`,y,[r(`div`,{class:n([`image-picker__preview`,{"image-picker__preview--empty":!d.modelValue}]),style:s(d.modelValue?{backgroundImage:c(p)(d.modelValue)}:void 0)},null,6),r(`div`,b,[r(`button`,{type:`button`,class:`admin-btn admin-btn--outline admin-btn--sm`,disabled:g.value,onClick:D},t(d.modelValue?`تغییر تصویر`:`افزودن تصویر`),9,x),d.modelValue?(o(),i(`button`,{key:0,type:`button`,class:`admin-btn admin-btn--outline admin-btn--sm`,disabled:g.value,onClick:k},` حذف `,8,S)):u(``,!0),T.value?(o(),i(`p`,C,t(T.value),1)):E.value?(o(),i(`p`,w,`تصویر انتخاب شد — برای ثبت نهایی «ثبت» را بزنید.`)):u(``,!0)])]),r(`input`,{ref_key:`inputRef`,ref:h,type:`file`,accept:`image/*`,class:`image-picker__file`,onChange:O},null,544)]))}}),[[`__scopeId`,`data-v-ab0add26`]]);export{p as n,T as t};
|
||||
-1
@@ -1 +0,0 @@
|
||||
.image-picker__label[data-v-ab0add26]{margin:0 0 8px;font-size:.8125rem;font-weight:600}.image-picker__row[data-v-ab0add26]{align-items:center;gap:12px;display:flex}.image-picker__preview[data-v-ab0add26]{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-ab0add26]{background:repeating-linear-gradient(45deg,#eef1f0,#eef1f0 8px,#e4e8e6 8px 16px)}.image-picker__actions[data-v-ab0add26]{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.image-picker__file[data-v-ab0add26]{display:none}.image-picker__error[data-v-ab0add26]{width:100%;color:var(--color-danger);margin:0;font-size:.75rem}.image-picker__ok[data-v-ab0add26]{width:100%;color:var(--color-success-dark);margin:0;font-size:.75rem;font-weight:600}
|
||||
@@ -1 +1 @@
|
||||
import{$ as e,At as t,B as n,D as r,Dt as i,M as a,N as o,U as s,a as c,c as l,d as u,g as d,h as f,k as p,kt as m,l as h,r as g,s as _,t as v,u as y,w as b}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{f as x,m as S,p as C}from"./http-BjLkjdQu.js";import{N as w,R as T}from"./index-BzcByePp.js";var E=[`id`],D=[`aria-label`,`aria-expanded`],O={class:`admin-select__trigger-content`},k={class:`admin-select__value`},A={class:`admin-select__chevron`,"aria-hidden":`true`},j=[`aria-label`],M={key:0,class:`admin-select__search`,role:`presentation`},N=[`placeholder`],P={key:1,class:`admin-select__empty`,role:`presentation`},F=[`aria-selected`,`onClick`],I={class:`admin-select__option-label`},L=v(d({__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(d,{emit:v}){let L=d,R=v,z=e(!1),B=e(``),V=e(null),H=e(null),U=e(null),W=e({});w(V,()=>{z.value=!1,B.value=``},{ignore:[H]});let G=_(()=>L.options.find(e=>e.value===L.modelValue)),K=_(()=>G.value?.label??L.placeholder),q=_(()=>{let e=B.value.trim().toLowerCase();return e?L.options.filter(t=>t.label.toLowerCase().includes(e)):L.options});function J(){let e=V.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));W.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 Y(e){e?(window.addEventListener(`resize`,J),window.addEventListener(`scroll`,J,!0)):(window.removeEventListener(`resize`,J),window.removeEventListener(`scroll`,J,!0))}async function X(){z.value=!z.value,z.value&&(await b(),J(),L.searchable&&(B.value=``,await b(),U.value?.focus()))}function Z(e){R(`update:modelValue`,e),z.value=!1,B.value=``}return n(z,e=>{Y(e),e&&b(()=>J())}),r(()=>{Y(!1)}),(e,n)=>(p(),u(`div`,{id:d.id,ref_key:`rootRef`,ref:V,class:i([`admin-select`,{"admin-select--open":z.value,"admin-select--block":d.block}])},[l(`button`,{type:`button`,class:`admin-select__trigger`,"aria-label":d.ariaLabel,"aria-expanded":z.value,"aria-haspopup":`listbox`,onClick:X},[l(`span`,O,[o(e.$slots,`option-leading`,{option:G.value},void 0,!0),l(`span`,k,t(K.value),1)]),l(`span`,A,[f(T,{name:`chevron-down`,size:16})])],8,D),(p(),h(c,{to:`body`},[z.value?(p(),u(`ul`,{key:0,ref_key:`menuRef`,ref:H,class:`admin-select__menu`,role:`listbox`,"aria-label":d.ariaLabel,style:m(W.value)},[d.searchable?(p(),u(`li`,M,[s(l(`input`,{ref_key:`searchInputRef`,ref:U,"onUpdate:modelValue":n[0]||=e=>B.value=e,type:`search`,class:`admin-select__search-input`,placeholder:d.searchPlaceholder,onClick:n[1]||=S(()=>{},[`stop`]),onKeydown:n[2]||=C(S(e=>z.value=!1,[`stop`]),[`esc`])},null,40,N),[[x,B.value]])])):y(``,!0),q.value.length?y(``,!0):(p(),u(`li`,P,` موردی یافت نشد `)),(p(!0),u(g,null,a(q.value,n=>(p(),u(`li`,{key:n.value,role:`presentation`},[l(`button`,{type:`button`,class:i([`admin-select__option`,{"admin-select__option--active":n.value===d.modelValue}]),role:`option`,"aria-selected":n.value===d.modelValue,onClick:e=>Z(n.value)},[l(`span`,I,[o(e.$slots,`option-leading`,{option:n},void 0,!0),l(`span`,null,t(n.label),1)]),n.value===d.modelValue?(p(),h(T,{key:0,name:`check`,size:16,class:`admin-select__check`})):y(``,!0)],10,F)]))),128))],12,j)):y(``,!0)]))],10,E))}}),[[`__scopeId`,`data-v-4623e322`]]);export{L as t};
|
||||
import{$ as e,At as t,B as n,D as r,Dt as i,M as a,N as o,U as s,a as c,c as l,d as u,g as d,h as f,k as p,kt as m,l as h,r as g,s as _,t as v,u as y,w as b}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{f as x,m as S,p as C}from"./http-BjLkjdQu.js";import{I as w,j as T}from"./index-SWzbcuqQ.js";var E=[`id`],D=[`aria-label`,`aria-expanded`],O={class:`admin-select__trigger-content`},k={class:`admin-select__value`},A={class:`admin-select__chevron`,"aria-hidden":`true`},j=[`aria-label`],M={key:0,class:`admin-select__search`,role:`presentation`},N=[`placeholder`],P={key:1,class:`admin-select__empty`,role:`presentation`},F=[`aria-selected`,`onClick`],I={class:`admin-select__option-label`},L=v(d({__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(d,{emit:v}){let L=d,R=v,z=e(!1),B=e(``),V=e(null),H=e(null),U=e(null),W=e({});T(V,()=>{z.value=!1,B.value=``},{ignore:[H]});let G=_(()=>L.options.find(e=>e.value===L.modelValue)),K=_(()=>G.value?.label??L.placeholder),q=_(()=>{let e=B.value.trim().toLowerCase();return e?L.options.filter(t=>t.label.toLowerCase().includes(e)):L.options});function J(){let e=V.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));W.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 Y(e){e?(window.addEventListener(`resize`,J),window.addEventListener(`scroll`,J,!0)):(window.removeEventListener(`resize`,J),window.removeEventListener(`scroll`,J,!0))}async function X(){z.value=!z.value,z.value&&(await b(),J(),L.searchable&&(B.value=``,await b(),U.value?.focus()))}function Z(e){R(`update:modelValue`,e),z.value=!1,B.value=``}return n(z,e=>{Y(e),e&&b(()=>J())}),r(()=>{Y(!1)}),(e,n)=>(p(),u(`div`,{id:d.id,ref_key:`rootRef`,ref:V,class:i([`admin-select`,{"admin-select--open":z.value,"admin-select--block":d.block}])},[l(`button`,{type:`button`,class:`admin-select__trigger`,"aria-label":d.ariaLabel,"aria-expanded":z.value,"aria-haspopup":`listbox`,onClick:X},[l(`span`,O,[o(e.$slots,`option-leading`,{option:G.value},void 0,!0),l(`span`,k,t(K.value),1)]),l(`span`,A,[f(w,{name:`chevron-down`,size:16})])],8,D),(p(),h(c,{to:`body`},[z.value?(p(),u(`ul`,{key:0,ref_key:`menuRef`,ref:H,class:`admin-select__menu`,role:`listbox`,"aria-label":d.ariaLabel,style:m(W.value)},[d.searchable?(p(),u(`li`,M,[s(l(`input`,{ref_key:`searchInputRef`,ref:U,"onUpdate:modelValue":n[0]||=e=>B.value=e,type:`search`,class:`admin-select__search-input`,placeholder:d.searchPlaceholder,onClick:n[1]||=S(()=>{},[`stop`]),onKeydown:n[2]||=C(S(e=>z.value=!1,[`stop`]),[`esc`])},null,40,N),[[x,B.value]])])):y(``,!0),q.value.length?y(``,!0):(p(),u(`li`,P,` موردی یافت نشد `)),(p(!0),u(g,null,a(q.value,n=>(p(),u(`li`,{key:n.value,role:`presentation`},[l(`button`,{type:`button`,class:i([`admin-select__option`,{"admin-select__option--active":n.value===d.modelValue}]),role:`option`,"aria-selected":n.value===d.modelValue,onClick:e=>Z(n.value)},[l(`span`,I,[o(e.$slots,`option-leading`,{option:n},void 0,!0),l(`span`,null,t(n.label),1)]),n.value===d.modelValue?(p(),h(w,{key:0,name:`check`,size:16,class:`admin-select__check`})):y(``,!0)],10,F)]))),128))],12,j)):y(``,!0)]))],10,E))}}),[[`__scopeId`,`data-v-4623e322`]]);export{L as t};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{At as e,Dt as t,N as n,c as r,d as i,g as a,h as o,k as s,t as c,u as l}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{R as u}from"./index-BzcByePp.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=c(a({__name:`BaseEmptyState`,props:{icon:{default:`file`},title:{},description:{},compact:{type:Boolean}},emits:[`action`,`secondary`],setup(a){return(c,h)=>(s(),i(`div`,{class:t([`base-empty`,{"base-empty--compact":a.compact}])},[r(`div`,d,[o(u,{name:a.icon,size:a.compact?28:36},null,8,[`name`,`size`])]),r(`h3`,f,e(a.title),1),a.description?(s(),i(`p`,p,e(a.description),1)):l(``,!0),c.$slots.default||c.$slots.secondary?(s(),i(`div`,m,[n(c.$slots,`default`,{},void 0,!0),n(c.$slots,`secondary`,{},void 0,!0)])):l(``,!0)],2))}}),[[`__scopeId`,`data-v-47ea81e4`]]);export{h as t};
|
||||
import{At as e,Dt as t,N as n,c as r,d as i,g as a,h as o,k as s,t as c,u as l}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{I as u}from"./index-SWzbcuqQ.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=c(a({__name:`BaseEmptyState`,props:{icon:{default:`file`},title:{},description:{},compact:{type:Boolean}},emits:[`action`,`secondary`],setup(a){return(c,h)=>(s(),i(`div`,{class:t([`base-empty`,{"base-empty--compact":a.compact}])},[r(`div`,d,[o(u,{name:a.icon,size:a.compact?28:36},null,8,[`name`,`size`])]),r(`h3`,f,e(a.title),1),a.description?(s(),i(`p`,p,e(a.description),1)):l(``,!0),c.$slots.default||c.$slots.secondary?(s(),i(`div`,m,[n(c.$slots,`default`,{},void 0,!0),n(c.$slots,`secondary`,{},void 0,!0)])):l(``,!0)],2))}}),[[`__scopeId`,`data-v-47ea81e4`]]);export{h as t};
|
||||
@@ -1 +1 @@
|
||||
import{$ as e,At as t,E as n,H as r,M as i,U as a,Z as o,c as s,d as c,g as l,h as u,k as d,l as f,m as p,r as m,s as h,t as g}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as _,f as v,t as y}from"./http-BjLkjdQu.js";import{H as b,p as x}from"./index-BzcByePp.js";import{t as S}from"./AdminPageSkeleton-oWhHYjl4.js";import{t as C}from"./BaseSwitch-pJwnFBVo.js";import{t as w}from"./BaseEmptyState-B7aEMvHg.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=g(l({__name:`BrandsView`,setup(l){let g=e([]),P=e(!0),F=e(!1),I=e(null),L=_(),R=o({name:``,slug:``,description:``,displayOrder:0,isActive:!0}),z=h(()=>I.value?`ویرایش برند`:`افزودن برند`);async function B(){P.value=!0;try{g.value=await x.list()}catch(e){L.error(e instanceof y?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 x.update(I.value,e):await x.create(e),F.value=!1,L.success(`ذخیره شد`),await B()}catch(e){L.error(e instanceof y?e.message:`ذخیره ناموفق بود`)}}return n(()=>{B()}),(e,n)=>(d(),c(`div`,T,[s(`header`,{class:`admin-page__head`},[n[6]||=s(`div`,null,[s(`h1`,null,`برندها`)],-1),s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:V},`افزودن برند`)]),P.value?(d(),f(S,{key:0,variant:`table`})):g.value.length?(d(),c(`table`,E,[n[7]||=s(`thead`,null,[s(`tr`,null,[s(`th`,null,`نام`),s(`th`,null,`شناسه لاتین`),s(`th`,null,`محصولات`),s(`th`,null,`فعال`),s(`th`)])],-1),s(`tbody`,null,[(d(!0),c(m,null,i(g.value,e=>(d(),c(`tr`,{key:e.id},[s(`td`,null,t(e.name),1),s(`td`,D,t(e.slug||`—`),1),s(`td`,null,t(e.productsCount??0),1),s(`td`,null,t(e.isActive?`بله`:`خیر`),1),s(`td`,null,[s(`button`,{type:`button`,class:`link`,onClick:t=>H(e)},`ویرایش`,8,O)])]))),128))])])):(d(),f(w,{key:1,title:`برندی ثبت نشده`})),u(b,{open:F.value,title:z.value,onClose:n[5]||=e=>F.value=!1},{footer:r(()=>[s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!R.name.trim(),onClick:U},`ذخیره`,8,N)]),default:r(()=>[s(`label`,k,[n[8]||=p(`نام`,-1),a(s(`input`,{"onUpdate:modelValue":n[0]||=e=>R.name=e,class:`admin-input`},null,512),[[v,R.name]])]),s(`label`,A,[n[9]||=p(`شناسه لاتین`,-1),a(s(`input`,{"onUpdate:modelValue":n[1]||=e=>R.slug=e,class:`admin-input`,dir:`ltr`,placeholder:`مثلاً nademi-silk`},null,512),[[v,R.slug]])]),s(`label`,j,[n[10]||=p(`توضیح`,-1),a(s(`textarea`,{"onUpdate:modelValue":n[2]||=e=>R.description=e,class:`admin-input`,rows:`3`},null,512),[[v,R.description]])]),s(`label`,M,[n[11]||=p(`ترتیب`,-1),a(s(`input`,{"onUpdate:modelValue":n[3]||=e=>R.displayOrder=e,type:`number`,class:`admin-input`},null,512),[[v,R.displayOrder,void 0,{number:!0}]])]),u(C,{modelValue:R.isActive,"onUpdate:modelValue":n[4]||=e=>R.isActive=e,label:`فعال`},null,8,[`modelValue`])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-a6f53b6f`]]);export{P as default};
|
||||
import{$ as e,At as t,E as n,H as r,M as i,U as a,Z as o,c as s,d as c,g as l,h as u,k as d,l as f,m as p,r as m,s as h,t as g}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as _,f as v,t as y}from"./http-BjLkjdQu.js";import{B as b,p as x}from"./index-SWzbcuqQ.js";import{t as S}from"./AdminPageSkeleton-oWhHYjl4.js";import{t as C}from"./BaseSwitch-pJwnFBVo.js";import{t as w}from"./BaseEmptyState-Bzvl_pTa.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=g(l({__name:`BrandsView`,setup(l){let g=e([]),P=e(!0),F=e(!1),I=e(null),L=_(),R=o({name:``,slug:``,description:``,displayOrder:0,isActive:!0}),z=h(()=>I.value?`ویرایش برند`:`افزودن برند`);async function B(){P.value=!0;try{g.value=await x.list()}catch(e){L.error(e instanceof y?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 x.update(I.value,e):await x.create(e),F.value=!1,L.success(`ذخیره شد`),await B()}catch(e){L.error(e instanceof y?e.message:`ذخیره ناموفق بود`)}}return n(()=>{B()}),(e,n)=>(d(),c(`div`,T,[s(`header`,{class:`admin-page__head`},[n[6]||=s(`div`,null,[s(`h1`,null,`برندها`)],-1),s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:V},`افزودن برند`)]),P.value?(d(),f(S,{key:0,variant:`table`})):g.value.length?(d(),c(`table`,E,[n[7]||=s(`thead`,null,[s(`tr`,null,[s(`th`,null,`نام`),s(`th`,null,`شناسه لاتین`),s(`th`,null,`محصولات`),s(`th`,null,`فعال`),s(`th`)])],-1),s(`tbody`,null,[(d(!0),c(m,null,i(g.value,e=>(d(),c(`tr`,{key:e.id},[s(`td`,null,t(e.name),1),s(`td`,D,t(e.slug||`—`),1),s(`td`,null,t(e.productsCount??0),1),s(`td`,null,t(e.isActive?`بله`:`خیر`),1),s(`td`,null,[s(`button`,{type:`button`,class:`link`,onClick:t=>H(e)},`ویرایش`,8,O)])]))),128))])])):(d(),f(w,{key:1,title:`برندی ثبت نشده`})),u(b,{open:F.value,title:z.value,onClose:n[5]||=e=>F.value=!1},{footer:r(()=>[s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!R.name.trim(),onClick:U},`ذخیره`,8,N)]),default:r(()=>[s(`label`,k,[n[8]||=p(`نام`,-1),a(s(`input`,{"onUpdate:modelValue":n[0]||=e=>R.name=e,class:`admin-input`},null,512),[[v,R.name]])]),s(`label`,A,[n[9]||=p(`شناسه لاتین`,-1),a(s(`input`,{"onUpdate:modelValue":n[1]||=e=>R.slug=e,class:`admin-input`,dir:`ltr`,placeholder:`مثلاً nademi-silk`},null,512),[[v,R.slug]])]),s(`label`,j,[n[10]||=p(`توضیح`,-1),a(s(`textarea`,{"onUpdate:modelValue":n[2]||=e=>R.description=e,class:`admin-input`,rows:`3`},null,512),[[v,R.description]])]),s(`label`,M,[n[11]||=p(`ترتیب`,-1),a(s(`input`,{"onUpdate:modelValue":n[3]||=e=>R.displayOrder=e,type:`number`,class:`admin-input`},null,512),[[v,R.displayOrder,void 0,{number:!0}]])]),u(C,{modelValue:R.isActive,"onUpdate:modelValue":n[4]||=e=>R.isActive=e,label:`فعال`},null,8,[`modelValue`])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-a6f53b6f`]]);export{P as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{$ as e,At as t,E as n,M as r,c as i,d as a,g as o,h as s,k as c,l,m as u,r as d,st as f,t as p,u as m}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as h,t as g}from"./http-BjLkjdQu.js";import{h as _,o as v}from"./index-BzcByePp.js";import{t as y}from"./AdminPageSkeleton-oWhHYjl4.js";import{t as b}from"./BaseEmptyState-B7aEMvHg.js";import{t as x}from"./AdminSelect-8XDtPu3U.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=p(o({__name:`CatalogRequestsView`,setup(o){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=e([]),I=e(``),L=e(!0),R=e(null),z=h();async function B(){L.value=!0;try{F.value=await _.list(I.value||void 0)}catch(e){z.error(e instanceof g?e.message:`بارگذاری انجام نشد`)}finally{L.value=!1}}async function V(e,t){try{await _.updateStatus(e,t),z.success(`وضعیت بهروز شد`),await B()}catch(e){z.error(e instanceof g?e.message:`بهروزرسانی ناموفق بود`)}}async function H(e,t){if(!R.value){R.value=e;try{await _.updateHolder(e,{holderType:t}),z.success(`محل نگهداری بهروز شد`),await B()}catch(e){z.error(e instanceof g?e.message:`بهروزرسانی محل ناموفق بود`)}finally{R.value=null}}}function U(e){return P[e]??e}return n(()=>{B()}),(e,n)=>(c(),a(`div`,S,[i(`header`,C,[n[1]||=i(`div`,null,[i(`h1`,null,`درخواست کالیته فیزیکی`),i(`p`,null,`بررسی، گردش وضعیت و محل نگهداری اقلام`)],-1),s(x,{modelValue:I.value,"onUpdate:modelValue":[n[0]||=e=>I.value=e,B],options:p},null,8,[`modelValue`])]),L.value?(c(),l(y,{key:0,variant:`cards`})):F.value.length?(c(!0),a(d,{key:2},r(F.value,e=>(c(),a(`div`,{key:e.id,class:`request-card`},[i(`div`,w,[i(`div`,null,[i(`strong`,null,t(e.customerName),1),i(`span`,T,t(e.customerPhone),1),i(`span`,E,t(f(N)[e.status]??e.status),1)]),s(x,{"model-value":e.status,options:p.filter(e=>e.value),"onUpdate:modelValue":t=>V(e.id,String(t))},null,8,[`model-value`,`options`,`onUpdate:modelValue`])]),e.note?(c(),a(`p`,D,t(e.note),1)):m(``,!0),i(`table`,O,[n[2]||=i(`thead`,null,[i(`tr`,null,[i(`th`,null,`محصول`),i(`th`,null,`کد`),i(`th`,null,`تعداد`),i(`th`,null,`محل`)])],-1),i(`tbody`,null,[(c(!0),a(d,null,r(e.items,e=>(c(),a(`tr`,{key:e.id},[i(`td`,null,t(e.productName),1),i(`td`,k,t(e.productCode),1),i(`td`,null,t(e.quantity),1),i(`td`,null,[s(x,{"model-value":e.holderType,options:M,"onUpdate:modelValue":t=>H(e.id,String(t))},null,8,[`model-value`,`onUpdate:modelValue`]),e.movements?.length?(c(),a(`ul`,A,[(c(!0),a(d,null,r(e.movements,e=>(c(),a(`li`,{key:e.id},[u(t(U(e.fromHolder))+` → `+t(U(e.toHolder))+` `,1),i(`span`,j,t(f(v)(e.movedAt)),1)]))),128))])):m(``,!0)])]))),128))])])]))),128)):(c(),l(b,{key:1,title:`درخواستی نیست`}))]))}}),[[`__scopeId`,`data-v-747d8f88`]]);export{M as default};
|
||||
import{$ as e,At as t,E as n,M as r,c as i,d as a,g as o,h as s,k as c,l,m as u,r as d,st as f,t as p,u as m}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as h,t as g}from"./http-BjLkjdQu.js";import{h as _,o as v}from"./index-SWzbcuqQ.js";import{t as y}from"./AdminPageSkeleton-oWhHYjl4.js";import{t as b}from"./BaseEmptyState-Bzvl_pTa.js";import{t as x}from"./AdminSelect-6a7SFr9x.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=p(o({__name:`CatalogRequestsView`,setup(o){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=e([]),I=e(``),L=e(!0),R=e(null),z=h();async function B(){L.value=!0;try{F.value=await _.list(I.value||void 0)}catch(e){z.error(e instanceof g?e.message:`بارگذاری انجام نشد`)}finally{L.value=!1}}async function V(e,t){try{await _.updateStatus(e,t),z.success(`وضعیت بهروز شد`),await B()}catch(e){z.error(e instanceof g?e.message:`بهروزرسانی ناموفق بود`)}}async function H(e,t){if(!R.value){R.value=e;try{await _.updateHolder(e,{holderType:t}),z.success(`محل نگهداری بهروز شد`),await B()}catch(e){z.error(e instanceof g?e.message:`بهروزرسانی محل ناموفق بود`)}finally{R.value=null}}}function U(e){return P[e]??e}return n(()=>{B()}),(e,n)=>(c(),a(`div`,S,[i(`header`,C,[n[1]||=i(`div`,null,[i(`h1`,null,`درخواست کالیته فیزیکی`),i(`p`,null,`بررسی، گردش وضعیت و محل نگهداری اقلام`)],-1),s(x,{modelValue:I.value,"onUpdate:modelValue":[n[0]||=e=>I.value=e,B],options:p},null,8,[`modelValue`])]),L.value?(c(),l(y,{key:0,variant:`cards`})):F.value.length?(c(!0),a(d,{key:2},r(F.value,e=>(c(),a(`div`,{key:e.id,class:`request-card`},[i(`div`,w,[i(`div`,null,[i(`strong`,null,t(e.customerName),1),i(`span`,T,t(e.customerPhone),1),i(`span`,E,t(f(N)[e.status]??e.status),1)]),s(x,{"model-value":e.status,options:p.filter(e=>e.value),"onUpdate:modelValue":t=>V(e.id,String(t))},null,8,[`model-value`,`options`,`onUpdate:modelValue`])]),e.note?(c(),a(`p`,D,t(e.note),1)):m(``,!0),i(`table`,O,[n[2]||=i(`thead`,null,[i(`tr`,null,[i(`th`,null,`محصول`),i(`th`,null,`کد`),i(`th`,null,`تعداد`),i(`th`,null,`محل`)])],-1),i(`tbody`,null,[(c(!0),a(d,null,r(e.items,e=>(c(),a(`tr`,{key:e.id},[i(`td`,null,t(e.productName),1),i(`td`,k,t(e.productCode),1),i(`td`,null,t(e.quantity),1),i(`td`,null,[s(x,{"model-value":e.holderType,options:M,"onUpdate:modelValue":t=>H(e.id,String(t))},null,8,[`model-value`,`onUpdate:modelValue`]),e.movements?.length?(c(),a(`ul`,A,[(c(!0),a(d,null,r(e.movements,e=>(c(),a(`li`,{key:e.id},[u(t(U(e.fromHolder))+` → `+t(U(e.toHolder))+` `,1),i(`span`,j,t(f(v)(e.movedAt)),1)]))),128))])):m(``,!0)])]))),128))])])]))),128)):(c(),l(b,{key:1,title:`درخواستی نیست`}))]))}}),[[`__scopeId`,`data-v-747d8f88`]]);export{M as default};
|
||||
Vendored
-1
File diff suppressed because one or more lines are too long
-1
@@ -1 +0,0 @@
|
||||
.catalogs-page__filters[data-v-4fb827ad]{flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px;padding:12px 14px;display:flex}.catalogs-page__search[data-v-4fb827ad]{min-width:200px;color:var(--color-text-muted);flex:1;align-items:center;gap:10px;display:flex}.catalogs-page__search-input[data-v-4fb827ad]{background:0 0;border:none;outline:none;flex:1;font-size:.875rem}.catalogs-page__company-filter[data-v-4fb827ad]{width:min(220px,100%)}.catalogs-page__table[data-v-4fb827ad]{overflow:hidden}.catalog-thumb[data-v-4fb827ad]{background:#e8eceb 50%/cover no-repeat;border-radius:8px;width:72px;height:44px;display:block}.catalog-thumb--empty[data-v-4fb827ad]{background:#eef1f0}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
-1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
-1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
-1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
-1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,3 +1,3 @@
|
||||
import{$ as e,At as t,E as n,H as r,M as i,U as a,Z as o,c as s,d as c,g as l,h as u,k as d,l as f,m as p,r as m,s as h,t as g}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as _,f as v,t as y}from"./http-BjLkjdQu.js";import{H as b,S as x}from"./index-BzcByePp.js";import{t as S}from"./AdminPageSkeleton-oWhHYjl4.js";import{t as C}from"./BaseEmptyState-B7aEMvHg.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=g(l({__name:`LevelsView`,setup(l){let g=e([]),N=e(!0),P=e(!1),F=e(null),I=_(),L=o({code:``,label:``,sortOrder:0,benefitsText:``}),R=h(()=>F.value?`ویرایش سطح`:`سطح جدید`);function z(e){return e.split(`
|
||||
import{$ as e,At as t,E as n,H as r,M as i,U as a,Z as o,c as s,d as c,g as l,h as u,k as d,l as f,m as p,r as m,s as h,t as g}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as _,f as v,t as y}from"./http-BjLkjdQu.js";import{B as b,x}from"./index-SWzbcuqQ.js";import{t as S}from"./AdminPageSkeleton-oWhHYjl4.js";import{t as C}from"./BaseEmptyState-Bzvl_pTa.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=g(l({__name:`LevelsView`,setup(l){let g=e([]),N=e(!0),P=e(!1),F=e(null),I=_(),L=o({code:``,label:``,sortOrder:0,benefitsText:``}),R=h(()=>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 x.list()}catch(e){I.error(e instanceof y?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 x.update(F.value,e):await x.create(e),P.value=!1,I.success(`ذخیره شد`),await B()}catch(e){I.error(e instanceof y?e.message:`ذخیره ناموفق بود`)}}return n(()=>{B()}),(e,n)=>(d(),c(`div`,w,[s(`header`,{class:`admin-page__head`},[n[5]||=s(`div`,null,[s(`h1`,null,`سطوح و مزایای مشتری`),s(`p`,null,`تعریف Level داخلی CRM و مزایای هر سطح (نمایش فقط در ادمین)`)],-1),s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:V},`سطح جدید`)]),N.value?(d(),f(S,{key:0,variant:`table`})):g.value.length?(d(),c(`table`,T,[n[6]||=s(`thead`,null,[s(`tr`,null,[s(`th`,null,`کد`),s(`th`,null,`عنوان`),s(`th`,null,`مزایا`),s(`th`,null,`مشتریان`),s(`th`)])],-1),s(`tbody`,null,[(d(!0),c(m,null,i(g.value,e=>(d(),c(`tr`,{key:e.id},[s(`td`,E,t(e.code),1),s(`td`,null,t(e.label),1),s(`td`,null,t(e.benefits.map(e=>e.title).join(`، `)||`—`),1),s(`td`,null,t(e.customersCount),1),s(`td`,null,[s(`button`,{type:`button`,class:`link`,onClick:t=>H(e)},`ویرایش`,8,D)])]))),128))])])):(d(),f(C,{key:1,title:`سطحی تعریف نشده`})),u(b,{open:P.value,title:R.value,onClose:n[4]||=e=>P.value=!1},{footer:r(()=>[s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!L.code.trim()||!L.label.trim(),onClick:U},` ذخیره `,8,M)]),default:r(()=>[s(`label`,O,[n[7]||=p(`کد`,-1),a(s(`input`,{"onUpdate:modelValue":n[0]||=e=>L.code=e,class:`admin-input`,dir:`ltr`},null,512),[[v,L.code]])]),s(`label`,k,[n[8]||=p(`عنوان`,-1),a(s(`input`,{"onUpdate:modelValue":n[1]||=e=>L.label=e,class:`admin-input`},null,512),[[v,L.label]])]),s(`label`,A,[n[9]||=p(`ترتیب`,-1),a(s(`input`,{"onUpdate:modelValue":n[2]||=e=>L.sortOrder=e,type:`number`,class:`admin-input`},null,512),[[v,L.sortOrder,void 0,{number:!0}]])]),s(`label`,j,[n[10]||=p(` مزایا (هر خط یک مورد) `,-1),a(s(`textarea`,{"onUpdate:modelValue":n[3]||=e=>L.benefitsText=e,class:`admin-input`,rows:`4`},null,512),[[v,L.benefitsText]])])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-44c7f808`]]);export{N as default};
|
||||
@@ -1 +1 @@
|
||||
import{$ as e,At as t,U as n,c as r,d as i,g as a,h as o,k as s,m as c,s as l,st as u,t as d,u as f}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as p,f as m,l as h,m as g,u as _}from"./http-BjLkjdQu.js";import{B as v,F as y,I as b,L as x,R as S,z as C}from"./index-BzcByePp.js";var w={class:`login-page`},T={class:`login-page__form-wrap`},E={class:`login-page__card admin-card`},D={class:`login-page__header`},O={key:0,class:`login-page__mock-hint`},k={dir:`ltr`},A={dir:`ltr`},j={key:0,class:`admin-form__error`,role:`alert`},M={class:`admin-form__field`},N={class:`login-page__input-wrap`},P={class:`login-page__field-icon`,"aria-hidden":`true`},F={class:`admin-form__field`},I={class:`login-page__input-wrap login-page__input-wrap--password`},L={class:`login-page__field-icon`,"aria-hidden":`true`},R=[`type`],z=[`aria-label`],B={class:`login-page__remember`},V=[`disabled`],H={key:0,class:`admin-btn__spinner`,"aria-hidden":`true`},U=d(a({__name:`LoginView`,setup(a){let d=v(),U=C(),W=y(),G=p(),K=e(x()?b.phone:``),q=e(x()?b.password:``),J=e(!0),Y=e(!1),X=x(),Z=l(()=>K.value.trim().length>0&&q.value.length>0);function Q(e){return e.replace(/[۰-۹]/g,e=>String(`۰۱۲۳۴۵۶۷۸۹`.indexOf(e))).replace(/[٠-٩]/g,e=>String(`٠١٢٣٤٥٦٧٨٩`.indexOf(e)))}async function $(){if(!Z.value){W.error=`لطفاً شماره موبایل و رمز عبور را وارد کنید.`;return}if(!await W.login(Q(K.value.trim()),q.value,J.value))return;G.success(`خوش آمدید، ${W.fullName}`);let e=typeof U.query.redirect==`string`?U.query.redirect:`/`,t=`/admin/`.replace(/\/$/,``),n=e.startsWith(t)?e.slice(t.length)||`/`:e;await d.replace(n)}return(e,a)=>(s(),i(`div`,w,[r(`div`,T,[r(`div`,E,[r(`div`,D,[a[8]||=r(`h2`,{class:`login-page__title`},`ورود به پنل مدیریت`,-1),a[9]||=r(`p`,{class:`login-page__subtitle`},`برای ادامه، اطلاعات حساب کاربری خود را وارد کنید.`,-1),u(X)?(s(),i(`p`,O,[a[6]||=c(` حالت موک فعال است — `,-1),r(`span`,k,t(u(b).phone),1),a[7]||=c(` / `,-1),r(`span`,A,t(u(b).password),1)])):f(``,!0)]),r(`form`,{class:`admin-form login-page__form`,onSubmit:g($,[`prevent`])},[u(W).error?(s(),i(`p`,j,t(u(W).error),1)):f(``,!0),r(`div`,M,[a[10]||=r(`label`,{for:`login-phone`},`شماره موبایل`,-1),r(`div`,N,[r(`span`,P,[o(S,{name:`phone`,size:18})]),n(r(`input`,{id:`login-phone`,"onUpdate:modelValue":a[0]||=e=>K.value=e,type:`tel`,class:`admin-input login-page__input`,placeholder:`۰۹۱۲۱۱۱۱۲۲۲۲`,autocomplete:`username`,inputmode:`tel`,dir:`ltr`,onInput:a[1]||=e=>u(W).clearError()},null,544),[[m,K.value]])])]),r(`div`,F,[a[11]||=r(`label`,{for:`login-password`},`رمز عبور`,-1),r(`div`,I,[r(`span`,L,[o(S,{name:`lock`,size:18})]),n(r(`input`,{id:`login-password`,"onUpdate:modelValue":a[2]||=e=>q.value=e,type:Y.value?`text`:`password`,class:`admin-input login-page__input login-page__input--with-toggle`,placeholder:`رمز عبور`,autocomplete:`current-password`,onInput:a[3]||=e=>u(W).clearError()},null,40,R),[[_,q.value]]),r(`button`,{type:`button`,class:`login-page__toggle-password`,"aria-label":Y.value?`پنهان کردن رمز`:`نمایش رمز`,onClick:a[4]||=e=>Y.value=!Y.value},[o(S,{name:Y.value?`eye-off`:`eye`,size:18},null,8,[`name`])],8,z)])]),r(`label`,B,[n(r(`input`,{"onUpdate:modelValue":a[5]||=e=>J.value=e,type:`checkbox`},null,512),[[h,J.value]]),a[12]||=r(`span`,null,`مرا به خاطر بسپار`,-1)]),r(`button`,{type:`submit`,class:`admin-btn admin-btn--primary login-page__submit`,disabled:!Z.value||u(W).loading},[u(W).loading?(s(),i(`span`,H)):f(``,!0),a[13]||=c(` ورود به پنل `,-1)],8,V)],32)])]),r(`div`,{class:`login-page__brand`},[r(`div`,{class:`login-page__brand-inner`},[r(`img`,{src:`/admin/brand-logo.png`,alt:`نادمی تکس`,class:`login-page__brand-logo`}),a[14]||=r(`p`,{class:`login-page__brand-badge`},`پارچه`,-1),a[15]||=r(`h1`,{class:`login-page__brand-title`},`پنل مدیریت سفارشهای عمده`,-1),a[16]||=r(`p`,{class:`login-page__brand-text`},` مدیریت سفارشها، مشتریان، قیمتگذاری، چکها و گزارشهای فروش در یک محیط یکپارچه. `,-1)])])]))}}),[[`__scopeId`,`data-v-df8d196a`]]);export{U as default};
|
||||
import{$ as e,At as t,U as n,c as r,d as i,g as a,h as o,k as s,m as c,s as l,st as u,t as d,u as f}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as p,f as m,l as h,m as g,u as _}from"./http-BjLkjdQu.js";import{F as v,I as y,L as b,N as x,P as S,R as C}from"./index-SWzbcuqQ.js";var w={class:`login-page`},T={class:`login-page__form-wrap`},E={class:`login-page__card admin-card`},D={class:`login-page__header`},O={key:0,class:`login-page__mock-hint`},k={dir:`ltr`},A={dir:`ltr`},j={key:0,class:`admin-form__error`,role:`alert`},M={class:`admin-form__field`},N={class:`login-page__input-wrap`},P={class:`login-page__field-icon`,"aria-hidden":`true`},F={class:`admin-form__field`},I={class:`login-page__input-wrap login-page__input-wrap--password`},L={class:`login-page__field-icon`,"aria-hidden":`true`},R=[`type`],z=[`aria-label`],B={class:`login-page__remember`},V=[`disabled`],H={key:0,class:`admin-btn__spinner`,"aria-hidden":`true`},U=d(a({__name:`LoginView`,setup(a){let d=C(),U=b(),W=x(),G=p(),K=e(v()?S.phone:``),q=e(v()?S.password:``),J=e(!0),Y=e(!1),X=v(),Z=l(()=>K.value.trim().length>0&&q.value.length>0);function Q(e){return e.replace(/[۰-۹]/g,e=>String(`۰۱۲۳۴۵۶۷۸۹`.indexOf(e))).replace(/[٠-٩]/g,e=>String(`٠١٢٣٤٥٦٧٨٩`.indexOf(e)))}async function $(){if(!Z.value){W.error=`لطفاً شماره موبایل و رمز عبور را وارد کنید.`;return}if(!await W.login(Q(K.value.trim()),q.value,J.value))return;G.success(`خوش آمدید، ${W.fullName}`);let e=typeof U.query.redirect==`string`?U.query.redirect:`/`,t=`/admin/`.replace(/\/$/,``),n=e.startsWith(t)?e.slice(t.length)||`/`:e;await d.replace(n)}return(e,a)=>(s(),i(`div`,w,[r(`div`,T,[r(`div`,E,[r(`div`,D,[a[8]||=r(`h2`,{class:`login-page__title`},`ورود به پنل مدیریت`,-1),a[9]||=r(`p`,{class:`login-page__subtitle`},`برای ادامه، اطلاعات حساب کاربری خود را وارد کنید.`,-1),u(X)?(s(),i(`p`,O,[a[6]||=c(` حالت موک فعال است — `,-1),r(`span`,k,t(u(S).phone),1),a[7]||=c(` / `,-1),r(`span`,A,t(u(S).password),1)])):f(``,!0)]),r(`form`,{class:`admin-form login-page__form`,onSubmit:g($,[`prevent`])},[u(W).error?(s(),i(`p`,j,t(u(W).error),1)):f(``,!0),r(`div`,M,[a[10]||=r(`label`,{for:`login-phone`},`شماره موبایل`,-1),r(`div`,N,[r(`span`,P,[o(y,{name:`phone`,size:18})]),n(r(`input`,{id:`login-phone`,"onUpdate:modelValue":a[0]||=e=>K.value=e,type:`tel`,class:`admin-input login-page__input`,placeholder:`۰۹۱۲۱۱۱۱۲۲۲۲`,autocomplete:`username`,inputmode:`tel`,dir:`ltr`,onInput:a[1]||=e=>u(W).clearError()},null,544),[[m,K.value]])])]),r(`div`,F,[a[11]||=r(`label`,{for:`login-password`},`رمز عبور`,-1),r(`div`,I,[r(`span`,L,[o(y,{name:`lock`,size:18})]),n(r(`input`,{id:`login-password`,"onUpdate:modelValue":a[2]||=e=>q.value=e,type:Y.value?`text`:`password`,class:`admin-input login-page__input login-page__input--with-toggle`,placeholder:`رمز عبور`,autocomplete:`current-password`,onInput:a[3]||=e=>u(W).clearError()},null,40,R),[[_,q.value]]),r(`button`,{type:`button`,class:`login-page__toggle-password`,"aria-label":Y.value?`پنهان کردن رمز`:`نمایش رمز`,onClick:a[4]||=e=>Y.value=!Y.value},[o(y,{name:Y.value?`eye-off`:`eye`,size:18},null,8,[`name`])],8,z)])]),r(`label`,B,[n(r(`input`,{"onUpdate:modelValue":a[5]||=e=>J.value=e,type:`checkbox`},null,512),[[h,J.value]]),a[12]||=r(`span`,null,`مرا به خاطر بسپار`,-1)]),r(`button`,{type:`submit`,class:`admin-btn admin-btn--primary login-page__submit`,disabled:!Z.value||u(W).loading},[u(W).loading?(s(),i(`span`,H)):f(``,!0),a[13]||=c(` ورود به پنل `,-1)],8,V)],32)])]),r(`div`,{class:`login-page__brand`},[r(`div`,{class:`login-page__brand-inner`},[r(`img`,{src:`/admin/brand-logo.png`,alt:`نادمی تکس`,class:`login-page__brand-logo`}),a[14]||=r(`p`,{class:`login-page__brand-badge`},`پارچه`,-1),a[15]||=r(`h1`,{class:`login-page__brand-title`},`پنل مدیریت سفارشهای عمده`,-1),a[16]||=r(`p`,{class:`login-page__brand-text`},` مدیریت سفارشها، مشتریان، قیمتگذاری، چکها و گزارشهای فروش در یک محیط یکپارچه. `,-1)])])]))}}),[[`__scopeId`,`data-v-df8d196a`]]);export{U as default};
|
||||
+1
@@ -0,0 +1 @@
|
||||
.pricing-page__summary[data-v-fb0720df]{margin-bottom:16px;padding:20px}.pricing-page__order-meta[data-v-fb0720df]{margin-bottom:16px}.pricing-page__order-id[data-v-fb0720df]{margin-bottom:4px;font-size:1rem;display:block}.pricing-page__customer[data-v-fb0720df]{color:var(--color-text-muted);margin:0 0 8px;font-size:.875rem}.pricing-page__table[data-v-fb0720df]{margin-bottom:16px;padding:0;overflow:hidden}.pricing-page__add-btn[data-v-fb0720df]{align-items:center;gap:6px;margin:12px 16px 16px;display:inline-flex}.pricing-page__compact-items[data-v-fb0720df]{margin-bottom:16px}.pricing-page__item-index[data-v-fb0720df]{color:var(--color-text-muted);font-size:.75rem}.pricing-page__compact-fields[data-v-fb0720df]{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:12px;display:grid}.pricing-page__compact-fields label[data-v-fb0720df]{color:var(--color-text-muted);flex-direction:column;gap:6px;min-width:0;font-size:.75rem;display:flex}.pricing-page__compact-fields[data-v-fb0720df] .admin-input,.pricing-page__compact-fields[data-v-fb0720df] input{width:100%;min-width:0}.pricing-page__invoice-hint[data-v-fb0720df]{color:var(--color-text-muted);margin:12px 0 0;font-size:.75rem;line-height:1.8}.pricing-page__line-total[data-v-fb0720df]{color:var(--color-text);grid-column:1/-1;margin:0;font-size:.875rem;font-weight:700}@media (width<=479px){.pricing-page__compact-fields[data-v-fb0720df]{grid-template-columns:1fr}}
|
||||
+1
File diff suppressed because one or more lines are too long
-1
File diff suppressed because one or more lines are too long
-1
@@ -1 +0,0 @@
|
||||
.pricing-page__summary[data-v-ba142b4c]{margin-bottom:16px;padding:20px}.pricing-page__order-meta[data-v-ba142b4c]{margin-bottom:16px}.pricing-page__order-id[data-v-ba142b4c]{margin-bottom:4px;font-size:1rem;display:block}.pricing-page__customer[data-v-ba142b4c]{color:var(--color-text-muted);margin:0 0 8px;font-size:.875rem}.pricing-page__table[data-v-ba142b4c]{margin-bottom:16px;padding:0;overflow:hidden}.pricing-page__add-btn[data-v-ba142b4c]{align-items:center;gap:6px;margin:12px 16px 16px;display:inline-flex}.pricing-page__compact-items[data-v-ba142b4c]{margin-bottom:16px}.pricing-page__item-index[data-v-ba142b4c]{color:var(--color-text-muted);font-size:.75rem}.pricing-page__compact-fields[data-v-ba142b4c]{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:12px;display:grid}.pricing-page__compact-fields label[data-v-ba142b4c]{color:var(--color-text-muted);flex-direction:column;gap:6px;min-width:0;font-size:.75rem;display:flex}.pricing-page__compact-fields[data-v-ba142b4c] .admin-input,.pricing-page__compact-fields[data-v-ba142b4c] input{width:100%;min-width:0}.pricing-page__invoice-hint[data-v-ba142b4c]{color:var(--color-text-muted);margin:12px 0 0;font-size:.75rem;line-height:1.8}.pricing-page__line-total[data-v-ba142b4c]{color:var(--color-text);grid-column:1/-1;margin:0;font-size:.875rem;font-weight:700}@media (width<=479px){.pricing-page__compact-fields[data-v-ba142b4c]{grid-template-columns:1fr}}
|
||||
Vendored
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
.products-page__filters[data-v-1acc8c48]{flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px;padding:12px 14px;display:flex}.products-page__search[data-v-1acc8c48]{min-width:200px;color:var(--color-text-muted);flex:1;align-items:center;gap:10px;display:flex}.products-page__search-input[data-v-1acc8c48]{background:0 0;border:none;outline:none;flex:1;font-size:.875rem}.products-page__catalog-filter[data-v-1acc8c48]{width:min(260px,100%)}.admin-form__hint[data-v-1acc8c48]{color:var(--color-text-muted);margin:6px 0 0;font-size:.75rem;line-height:1.5}.products-page__table[data-v-1acc8c48]{overflow:hidden}.product-thumb[data-v-1acc8c48]{background:#e8eceb 50%/cover no-repeat;border-radius:8px;width:44px;height:36px;display:block}.product-thumb--empty[data-v-1acc8c48]{background:#eef1f0}.color-variants[data-v-1acc8c48]{flex-direction:column;gap:14px;display:flex}.color-variants__hint[data-v-1acc8c48]{color:var(--color-text-muted);margin:0 0 10px;font-size:.75rem;line-height:1.6}.general-images[data-v-1acc8c48]{flex-direction:column;gap:12px;display:flex}.general-images__row[data-v-1acc8c48],.color-variant[data-v-1acc8c48]{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-1acc8c48]{flex-direction:column;flex:1;align-items:flex-start;gap:8px;min-width:180px;display:flex}
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
-1
@@ -1 +0,0 @@
|
||||
.products-page__filters[data-v-e062996d]{flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px;padding:12px 14px;display:flex}.products-page__search[data-v-e062996d]{min-width:200px;color:var(--color-text-muted);flex:1;align-items:center;gap:10px;display:flex}.products-page__search-input[data-v-e062996d]{background:0 0;border:none;outline:none;flex:1;font-size:.875rem}.products-page__catalog-filter[data-v-e062996d]{width:min(260px,100%)}.products-page__table[data-v-e062996d]{overflow:hidden}.product-thumb[data-v-e062996d]{background:#e8eceb 50%/cover no-repeat;border-radius:8px;width:44px;height:36px;display:block}.product-thumb--empty[data-v-e062996d]{background:#eef1f0}.color-variants[data-v-e062996d]{flex-direction:column;gap:14px;display:flex}.color-variants__hint[data-v-e062996d]{color:var(--color-text-muted);margin:0 0 10px;font-size:.75rem;line-height:1.6}.color-variant[data-v-e062996d]{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-e062996d]{flex-direction:column;flex:1;align-items:flex-start;gap:8px;min-width:180px;display:flex}
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
.admin-multi-select[data-v-9a22912b]{min-width:200px;max-width:100%;position:relative}.admin-multi-select--block[data-v-9a22912b]{width:100%;min-width:0}.admin-multi-select__trigger[data-v-9a22912b]{width:100%;min-height:var(--control-height,40px);border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text);cursor:pointer;transition:border-color var(--transition-fast), box-shadow var(--transition-fast), background var(--transition-fast);justify-content:space-between;align-items:center;gap:10px;padding:0 12px 0 10px;font-family:inherit;font-size:.875rem;font-weight:500;display:flex}.admin-multi-select--disabled .admin-multi-select__trigger[data-v-9a22912b]{opacity:.55;cursor:not-allowed}.admin-multi-select__trigger[data-v-9a22912b]:hover:not(:disabled){border-color:var(--color-primary);background:var(--color-elevated,var(--color-surface))}.admin-multi-select--open .admin-multi-select__trigger[data-v-9a22912b],.admin-multi-select__trigger[data-v-9a22912b]:focus-visible:not(:disabled){border-color:var(--color-primary);box-shadow:var(--focus-ring);outline:none}.admin-multi-select__value[data-v-9a22912b]{text-align:start;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.admin-multi-select__chevron[data-v-9a22912b]{color:var(--color-text-muted);transition:transform var(--transition-fast);flex-shrink:0;display:inline-flex}.admin-multi-select--open .admin-multi-select__chevron[data-v-9a22912b]{color:var(--color-primary);transform:rotate(180deg)}.admin-multi-select__chips[data-v-9a22912b]{flex-wrap:wrap;gap:6px;margin:8px 0 0;padding:0;list-style:none;display:flex}.admin-multi-select__chip[data-v-9a22912b]{background:var(--color-primary-soft);max-width:100%;color:var(--color-primary);border-radius:999px;align-items:center;gap:4px;padding:4px 8px;font-size:.75rem;font-weight:600;display:inline-flex}.admin-multi-select__chip-label[data-v-9a22912b]{text-overflow:ellipsis;white-space:nowrap;max-width:220px;overflow:hidden}.admin-multi-select__chip-remove[data-v-9a22912b]{color:inherit;cursor:pointer;background:0 0;border:none;padding:0 2px;font-size:1rem;line-height:1}.admin-multi-select__menu[data-v-9a22912b]{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:var(--shadow-card,0 12px 28px #0f172a1f);box-sizing:border-box;flex-direction:column;gap:4px;margin:0;padding:8px;list-style:none;display:flex;overflow-y:auto}.admin-multi-select__search[data-v-9a22912b]{z-index:1;background:var(--color-surface);padding-bottom:4px;position:sticky;top:0}.admin-multi-select__search-input[data-v-9a22912b]{border:1px solid var(--color-border);background:var(--color-bg);width:100%;height:36px;color:var(--color-text);font:inherit;border-radius:10px;padding:0 12px;font-size:.8125rem}.admin-multi-select__search-input[data-v-9a22912b]:focus{border-color:var(--color-primary);box-shadow:var(--focus-ring);outline:none}.admin-multi-select__empty[data-v-9a22912b]{color:var(--color-text-muted);text-align:center;padding:12px;font-size:.8125rem}.admin-multi-select__option[data-v-9a22912b]{width:100%;color:var(--color-text);text-align:start;cursor:pointer;transition:background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);background:0 0;border:1px solid #0000;border-radius:12px;justify-content:space-between;align-items:center;gap:10px;padding:10px 12px;font-family:inherit;font-size:.875rem;font-weight:500;display:flex}.admin-multi-select__option[data-v-9a22912b]:hover{background:var(--color-bg);border-color:var(--color-border)}.admin-multi-select__option--active[data-v-9a22912b]{background:var(--color-primary-soft);color:var(--color-primary);border-color:#0000;font-weight:600}.admin-multi-select__check[data-v-9a22912b]{color:var(--color-primary);flex-shrink:0}.settings-page__grid[data-v-e84a2579]{grid-template-columns:repeat(2,1fr);gap:16px;display:grid}.settings-page__section[data-v-e84a2579]{padding:20px}.settings-page__title[data-v-e84a2579]{margin:0 0 16px;font-size:1rem;font-weight:700}.settings-page__checks[data-v-e84a2579]{flex-direction:column;gap:12px;display:flex}.settings-page__check[data-v-e84a2579]{cursor:pointer;align-items:center;gap:10px;font-size:.875rem;display:flex}.settings-page__check input[data-v-e84a2579]{width:16px;height:16px;accent-color:var(--color-primary)}.settings-page__check--block[data-v-e84a2579]{margin-bottom:12px}.settings-page__broadcast-submit[data-v-e84a2579]{margin-top:4px}.settings-page__hint[data-v-e84a2579]{color:var(--color-text-muted);margin:6px 0 0;font-size:.75rem;line-height:1.5}@media (width<=1279px){.settings-page__grid[data-v-e84a2579]{grid-template-columns:1fr}}
|
||||
.admin-multi-select[data-v-9a22912b]{min-width:200px;max-width:100%;position:relative}.admin-multi-select--block[data-v-9a22912b]{width:100%;min-width:0}.admin-multi-select__trigger[data-v-9a22912b]{width:100%;min-height:var(--control-height,40px);border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text);cursor:pointer;transition:border-color var(--transition-fast), box-shadow var(--transition-fast), background var(--transition-fast);justify-content:space-between;align-items:center;gap:10px;padding:0 12px 0 10px;font-family:inherit;font-size:.875rem;font-weight:500;display:flex}.admin-multi-select--disabled .admin-multi-select__trigger[data-v-9a22912b]{opacity:.55;cursor:not-allowed}.admin-multi-select__trigger[data-v-9a22912b]:hover:not(:disabled){border-color:var(--color-primary);background:var(--color-elevated,var(--color-surface))}.admin-multi-select--open .admin-multi-select__trigger[data-v-9a22912b],.admin-multi-select__trigger[data-v-9a22912b]:focus-visible:not(:disabled){border-color:var(--color-primary);box-shadow:var(--focus-ring);outline:none}.admin-multi-select__value[data-v-9a22912b]{text-align:start;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.admin-multi-select__chevron[data-v-9a22912b]{color:var(--color-text-muted);transition:transform var(--transition-fast);flex-shrink:0;display:inline-flex}.admin-multi-select--open .admin-multi-select__chevron[data-v-9a22912b]{color:var(--color-primary);transform:rotate(180deg)}.admin-multi-select__chips[data-v-9a22912b]{flex-wrap:wrap;gap:6px;margin:8px 0 0;padding:0;list-style:none;display:flex}.admin-multi-select__chip[data-v-9a22912b]{background:var(--color-primary-soft);max-width:100%;color:var(--color-primary);border-radius:999px;align-items:center;gap:4px;padding:4px 8px;font-size:.75rem;font-weight:600;display:inline-flex}.admin-multi-select__chip-label[data-v-9a22912b]{text-overflow:ellipsis;white-space:nowrap;max-width:220px;overflow:hidden}.admin-multi-select__chip-remove[data-v-9a22912b]{color:inherit;cursor:pointer;background:0 0;border:none;padding:0 2px;font-size:1rem;line-height:1}.admin-multi-select__menu[data-v-9a22912b]{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:var(--shadow-card,0 12px 28px #0f172a1f);box-sizing:border-box;flex-direction:column;gap:4px;margin:0;padding:8px;list-style:none;display:flex;overflow-y:auto}.admin-multi-select__search[data-v-9a22912b]{z-index:1;background:var(--color-surface);padding-bottom:4px;position:sticky;top:0}.admin-multi-select__search-input[data-v-9a22912b]{border:1px solid var(--color-border);background:var(--color-bg);width:100%;height:36px;color:var(--color-text);font:inherit;border-radius:10px;padding:0 12px;font-size:.8125rem}.admin-multi-select__search-input[data-v-9a22912b]:focus{border-color:var(--color-primary);box-shadow:var(--focus-ring);outline:none}.admin-multi-select__empty[data-v-9a22912b]{color:var(--color-text-muted);text-align:center;padding:12px;font-size:.8125rem}.admin-multi-select__option[data-v-9a22912b]{width:100%;color:var(--color-text);text-align:start;cursor:pointer;transition:background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);background:0 0;border:1px solid #0000;border-radius:12px;justify-content:space-between;align-items:center;gap:10px;padding:10px 12px;font-family:inherit;font-size:.875rem;font-weight:500;display:flex}.admin-multi-select__option[data-v-9a22912b]:hover{background:var(--color-bg);border-color:var(--color-border)}.admin-multi-select__option--active[data-v-9a22912b]{background:var(--color-primary-soft);color:var(--color-primary);border-color:#0000;font-weight:600}.admin-multi-select__check[data-v-9a22912b]{color:var(--color-primary);flex-shrink:0}.settings-page__grid[data-v-230ea03a]{grid-template-columns:repeat(2,1fr);gap:16px;display:grid}.settings-page__section[data-v-230ea03a]{padding:20px}.settings-page__title[data-v-230ea03a]{margin:0 0 16px;font-size:1rem;font-weight:700}.settings-page__checks[data-v-230ea03a]{flex-direction:column;gap:12px;display:flex}.settings-page__check[data-v-230ea03a]{cursor:pointer;align-items:center;gap:10px;font-size:.875rem;display:flex}.settings-page__check input[data-v-230ea03a]{width:16px;height:16px;accent-color:var(--color-primary)}.settings-page__check--block[data-v-230ea03a]{margin-bottom:12px}.settings-page__broadcast-submit[data-v-230ea03a]{margin-top:4px}.settings-page__hint[data-v-230ea03a]{color:var(--color-text-muted);margin:6px 0 0;font-size:.75rem;line-height:1.5}@media (width<=1279px){.settings-page__grid[data-v-230ea03a]{grid-template-columns:1fr}}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
-1
@@ -1 +0,0 @@
|
||||
.admin-page__head[data-v-61131544]{margin-bottom:20px}.admin-page__head h1[data-v-61131544]{margin:0 0 4px;font-size:1.25rem}.admin-page__head p[data-v-61131544]{color:var(--color-text-muted);margin:0;font-size:.875rem}.admin-table[data-v-61131544]{border-collapse:collapse;width:100%}.admin-table th[data-v-61131544],.admin-table td[data-v-61131544]{text-align:right;border-bottom:1px solid var(--color-border);padding:10px 8px}.muted[data-v-61131544]{color:var(--color-text-muted);margin-right:6px;font-size:.75rem}
|
||||
-1
@@ -1 +0,0 @@
|
||||
import{$ as e,At as t,E as n,M as r,c as i,d as a,g as o,k as s,l as c,m as l,r as u,t as d}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as f,t as p}from"./http-BjLkjdQu.js";import{j as m}from"./index-BzcByePp.js";import{t as h}from"./AdminPageSkeleton-oWhHYjl4.js";import{t as g}from"./BaseEmptyState-B7aEMvHg.js";var _={class:`admin-page`},v={key:2,class:`admin-table`},y={class:`muted`,dir:`ltr`},b={class:`muted`,dir:`ltr`},x=[`onClick`],S=d(o({__name:`StockAlertsView`,setup(o){let d=e([]),S=e(!0),C=f();async function w(){S.value=!0;try{d.value=await m.list()}catch(e){C.error(e instanceof p?e.message:`بارگذاری ناموفق بود`)}finally{S.value=!1}}async function T(e){try{await m.notify(e),C.success(`اعلان موجودی ارسال شد`),await w()}catch(e){C.error(e instanceof p?e.message:`ارسال ناموفق بود`)}}return n(()=>{w()}),(e,n)=>(s(),a(`div`,_,[n[1]||=i(`header`,{class:`admin-page__head`},[i(`div`,null,[i(`h1`,null,`درخواست خبر موجودی`),i(`p`,null,`مشتریانی که برای محصول ناموجود درخواست اطلاع دادهاند`)])],-1),S.value?(s(),c(h,{key:0,variant:`table`})):d.value.length?(s(),a(`table`,v,[n[0]||=i(`thead`,null,[i(`tr`,null,[i(`th`,null,`مشتری`),i(`th`,null,`محصول`),i(`th`,null,`موجودی فعلی`),i(`th`)])],-1),i(`tbody`,null,[(s(!0),a(u,null,r(d.value,e=>(s(),a(`tr`,{key:e.id},[i(`td`,null,[l(t(e.customerName)+` `,1),i(`span`,y,t(e.customerPhone),1)]),i(`td`,null,[l(t(e.productName)+` `,1),i(`span`,b,`(`+t(e.productCode)+`)`,1)]),i(`td`,null,t(e.stock??`—`),1),i(`td`,null,[i(`button`,{type:`button`,class:`admin-btn admin-btn--primary admin-btn--sm`,onClick:t=>T(e.id)},`ارسال اعلان`,8,x)])]))),128))])])):(s(),c(g,{key:1,title:`درخواستی فعال نیست`}))]))}}),[[`__scopeId`,`data-v-61131544`]]);export{S as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{$ as e,At as t,E as n,H as r,M as i,U as a,Z as o,c as s,d as c,g as l,h as u,k as d,l as f,m as p,r as m,s as h,t as g}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as _,f as v,t as y}from"./http-BjLkjdQu.js";import{E as b,H as x,M as S,y as C}from"./index-BzcByePp.js";import{t as w}from"./AdminPageSkeleton-oWhHYjl4.js";import{t as T}from"./BaseEmptyState-B7aEMvHg.js";import{t as E}from"./AdminSelect-8XDtPu3U.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=g(l({__name:`SuggestionsView`,setup(l){let g=e([]),I=e(!0),L=e([]),R=e([]),z=e(!1),B=_(),V=o({customerId:``,productId:``,note:``}),H=h(()=>L.value.map(e=>({value:e.id,label:e.name?.trim()||e.phone}))),U=h(()=>R.value.map(e=>({value:e.id,label:`${e.name} (${e.productCode})`})));async function W(){I.value=!0;try{let[e,t,n]=await Promise.all([S.list(),C.list(),b.list()]);g.value=e,L.value=t,R.value=n}catch(e){B.error(e instanceof y?e.message:`بارگذاری ناموفق بود`)}finally{I.value=!1}}async function G(){try{await S.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 y?e.message:`ثبت ناموفق بود`)}}async function K(e){try{await S.setActive(e.id,!e.isActive),await W()}catch(e){B.error(e instanceof y?e.message:`بهروزرسانی ناموفق بود`)}}return n(()=>{W()}),(e,n)=>(d(),c(`div`,D,[s(`header`,O,[n[5]||=s(`div`,null,[s(`h1`,null,`پیشنهاد محصول`),s(`p`,null,`پیشنهاد دستی محصول به مشتری`)],-1),s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:n[0]||=e=>z.value=!0},`پیشنهاد جدید`)]),I.value?(d(),f(w,{key:0,variant:`table`})):g.value.length?(d(),c(`table`,k,[n[6]||=s(`thead`,null,[s(`tr`,null,[s(`th`,null,`مشتری`),s(`th`,null,`محصول`),s(`th`,null,`یادداشت`),s(`th`,null,`وضعیت`),s(`th`)])],-1),s(`tbody`,null,[(d(!0),c(m,null,i(g.value,e=>(d(),c(`tr`,{key:e.id},[s(`td`,null,t(e.customerName),1),s(`td`,null,[p(t(e.productName)+` `,1),s(`span`,A,`(`+t(e.productCode)+`)`,1)]),s(`td`,null,t(e.note||`—`),1),s(`td`,null,t(e.isActive?`فعال`:`غیرفعال`),1),s(`td`,null,[s(`button`,{type:`button`,class:`link`,onClick:t=>K(e)},t(e.isActive?`غیرفعال`:`فعال`),9,j)])]))),128))])])):(d(),f(T,{key:1,title:`پیشنهادی ثبت نشده`})),u(x,{open:z.value,title:`پیشنهاد محصول`,onClose:n[4]||=e=>z.value=!1},{footer:r(()=>[s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!V.customerId||!V.productId,onClick:G},` ثبت `,8,F)]),default:r(()=>[s(`label`,M,[n[7]||=p(`مشتری `,-1),u(E,{modelValue:V.customerId,"onUpdate:modelValue":n[1]||=e=>V.customerId=e,options:H.value},null,8,[`modelValue`,`options`])]),s(`label`,N,[n[8]||=p(`محصول `,-1),u(E,{modelValue:V.productId,"onUpdate:modelValue":n[2]||=e=>V.productId=e,options:U.value},null,8,[`modelValue`,`options`])]),s(`label`,P,[n[9]||=p(`یادداشت`,-1),a(s(`textarea`,{"onUpdate:modelValue":n[3]||=e=>V.note=e,class:`admin-input`,rows:`3`},null,512),[[v,V.note]])])]),_:1},8,[`open`])]))}}),[[`__scopeId`,`data-v-56e3e728`]]);export{I as default};
|
||||
import{$ as e,At as t,E as n,H as r,M as i,U as a,Z as o,c as s,d as c,g as l,h as u,k as d,l as f,m as p,r as m,s as h,t as g}from"./_plugin-vue_export-helper-QrIvvHC8.js";import{a as _,f as v,t as y}from"./http-BjLkjdQu.js";import{A as b,B as x,T as S,v as C}from"./index-SWzbcuqQ.js";import{t as w}from"./AdminPageSkeleton-oWhHYjl4.js";import{t as T}from"./BaseEmptyState-Bzvl_pTa.js";import{t as E}from"./AdminSelect-6a7SFr9x.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=g(l({__name:`SuggestionsView`,setup(l){let g=e([]),I=e(!0),L=e([]),R=e([]),z=e(!1),B=_(),V=o({customerId:``,productId:``,note:``}),H=h(()=>L.value.map(e=>({value:e.id,label:e.name?.trim()||e.phone}))),U=h(()=>R.value.map(e=>({value:e.id,label:`${e.name} (${e.productCode})`})));async function W(){I.value=!0;try{let[e,t,n]=await Promise.all([b.list(),C.list(),S.list()]);g.value=e,L.value=t,R.value=n}catch(e){B.error(e instanceof y?e.message:`بارگذاری ناموفق بود`)}finally{I.value=!1}}async function G(){try{await b.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 y?e.message:`ثبت ناموفق بود`)}}async function K(e){try{await b.setActive(e.id,!e.isActive),await W()}catch(e){B.error(e instanceof y?e.message:`بهروزرسانی ناموفق بود`)}}return n(()=>{W()}),(e,n)=>(d(),c(`div`,D,[s(`header`,O,[n[5]||=s(`div`,null,[s(`h1`,null,`پیشنهاد محصول`),s(`p`,null,`پیشنهاد دستی محصول به مشتری`)],-1),s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,onClick:n[0]||=e=>z.value=!0},`پیشنهاد جدید`)]),I.value?(d(),f(w,{key:0,variant:`table`})):g.value.length?(d(),c(`table`,k,[n[6]||=s(`thead`,null,[s(`tr`,null,[s(`th`,null,`مشتری`),s(`th`,null,`محصول`),s(`th`,null,`یادداشت`),s(`th`,null,`وضعیت`),s(`th`)])],-1),s(`tbody`,null,[(d(!0),c(m,null,i(g.value,e=>(d(),c(`tr`,{key:e.id},[s(`td`,null,t(e.customerName),1),s(`td`,null,[p(t(e.productName)+` `,1),s(`span`,A,`(`+t(e.productCode)+`)`,1)]),s(`td`,null,t(e.note||`—`),1),s(`td`,null,t(e.isActive?`فعال`:`غیرفعال`),1),s(`td`,null,[s(`button`,{type:`button`,class:`link`,onClick:t=>K(e)},t(e.isActive?`غیرفعال`:`فعال`),9,j)])]))),128))])])):(d(),f(T,{key:1,title:`پیشنهادی ثبت نشده`})),u(x,{open:z.value,title:`پیشنهاد محصول`,onClose:n[4]||=e=>z.value=!1},{footer:r(()=>[s(`button`,{type:`button`,class:`admin-btn admin-btn--primary`,disabled:!V.customerId||!V.productId,onClick:G},` ثبت `,8,F)]),default:r(()=>[s(`label`,M,[n[7]||=p(`مشتری `,-1),u(E,{modelValue:V.customerId,"onUpdate:modelValue":n[1]||=e=>V.customerId=e,options:H.value},null,8,[`modelValue`,`options`])]),s(`label`,N,[n[8]||=p(`محصول `,-1),u(E,{modelValue:V.productId,"onUpdate:modelValue":n[2]||=e=>V.productId=e,options:U.value},null,8,[`modelValue`,`options`])]),s(`label`,P,[n[9]||=p(`یادداشت`,-1),a(s(`textarea`,{"onUpdate:modelValue":n[3]||=e=>V.note=e,class:`admin-input`,rows:`3`},null,512),[[v,V.note]])])]),_:1},8,[`open`])]))}}),[[`__scopeId`,`data-v-56e3e728`]]);export{I as default};
|
||||
File diff suppressed because one or more lines are too long
Vendored
-382
File diff suppressed because one or more lines are too long
Vendored
+382
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -11,7 +11,7 @@
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>پنل مدیریت | پارچه</title>
|
||||
<script type="module" crossorigin src="/admin/assets/index-BzcByePp.js"></script>
|
||||
<script type="module" crossorigin src="/admin/assets/index-SWzbcuqQ.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/admin/assets/_plugin-vue_export-helper-QrIvvHC8.js">
|
||||
<link rel="modulepreload" crossorigin href="/admin/assets/http-BjLkjdQu.js">
|
||||
<link rel="stylesheet" crossorigin href="/admin/assets/index-CrGJrAMi.css">
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
import { ref } from 'vue'
|
||||
import { fileToCatalogImage, toCssBackgroundUrl } from '@/utils/catalogImage'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue?: string | null
|
||||
label?: string
|
||||
}>()
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue?: string | null
|
||||
label?: string
|
||||
/** دکمهٔ حذف تصویر (مثلاً برای رنگبندی که فقط «حذف رنگ» داریم) */
|
||||
showRemove?: boolean
|
||||
}>(),
|
||||
{ showRemove: true },
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string | null]
|
||||
@@ -57,7 +62,7 @@ function remove() {
|
||||
{{ props.modelValue ? 'تغییر تصویر' : 'افزودن تصویر' }}
|
||||
</button>
|
||||
<button
|
||||
v-if="props.modelValue"
|
||||
v-if="props.showRemove && props.modelValue"
|
||||
type="button"
|
||||
class="admin-btn admin-btn--outline admin-btn--sm"
|
||||
:disabled="busy"
|
||||
|
||||
@@ -522,7 +522,6 @@ export const catalogs: Catalog[] = [
|
||||
export const products: Product[] = [
|
||||
{
|
||||
id: 'prod-1',
|
||||
catalogId: 'cat-377',
|
||||
catalogCode: '377',
|
||||
companyName: 'شرکت پَر',
|
||||
name: 'پارچه آبی',
|
||||
@@ -536,7 +535,6 @@ export const products: Product[] = [
|
||||
},
|
||||
{
|
||||
id: 'prod-2',
|
||||
catalogId: 'cat-377',
|
||||
catalogCode: '377',
|
||||
companyName: 'شرکت پَر',
|
||||
name: 'پارچه مشکی',
|
||||
@@ -550,7 +548,6 @@ export const products: Product[] = [
|
||||
},
|
||||
{
|
||||
id: 'prod-3',
|
||||
catalogId: 'cat-378',
|
||||
catalogCode: '378',
|
||||
companyName: 'شرکت پَر',
|
||||
name: 'آبی پشت سفید',
|
||||
@@ -564,7 +561,6 @@ export const products: Product[] = [
|
||||
},
|
||||
{
|
||||
id: 'prod-4',
|
||||
catalogId: 'cat-378',
|
||||
catalogCode: '378',
|
||||
companyName: 'شرکت پَر',
|
||||
name: 'مشکی پشت سفید',
|
||||
@@ -578,7 +574,6 @@ export const products: Product[] = [
|
||||
},
|
||||
{
|
||||
id: 'prod-5',
|
||||
catalogId: 'cat-401',
|
||||
catalogCode: '401',
|
||||
companyName: 'شرکت فام بافت',
|
||||
name: 'پارچه کرم',
|
||||
|
||||
@@ -98,12 +98,6 @@ const router = createRouter({
|
||||
component: () => import('@/views/internal-messages/InternalMessagesView.vue'),
|
||||
meta: { title: 'پیامهای داخلی' },
|
||||
},
|
||||
{
|
||||
path: 'catalogs',
|
||||
name: 'catalogs',
|
||||
component: () => import('@/views/catalogs/CatalogsView.vue'),
|
||||
meta: { title: 'کالیتهها' },
|
||||
},
|
||||
{
|
||||
path: 'catalog-requests',
|
||||
name: 'catalog-requests',
|
||||
@@ -122,12 +116,6 @@ const router = createRouter({
|
||||
component: () => import('@/views/suggestions/SuggestionsView.vue'),
|
||||
meta: { title: 'پیشنهاد محصول' },
|
||||
},
|
||||
{
|
||||
path: 'stock-alerts',
|
||||
name: 'stock-alerts',
|
||||
component: () => import('@/views/stock-alerts/StockAlertsView.vue'),
|
||||
meta: { title: 'خبر موجودی' },
|
||||
},
|
||||
{
|
||||
path: 'levels',
|
||||
name: 'levels',
|
||||
|
||||
+2
-22
@@ -151,7 +151,6 @@ export const catalogsApi = {
|
||||
|
||||
export type CreateProductPayload = {
|
||||
companyId: string
|
||||
catalogId: string
|
||||
brandId?: string | null
|
||||
name: string
|
||||
code?: string
|
||||
@@ -183,14 +182,14 @@ export type CreateProductPayload = {
|
||||
export type UpdateProductPayload = Partial<Omit<CreateProductPayload, 'companyId'>>
|
||||
|
||||
export const productsApi = {
|
||||
list: (params?: { catalogId?: string; companyId?: string; activeOnly?: boolean }) =>
|
||||
list: (params?: { companyId?: string; activeOnly?: boolean }) =>
|
||||
apiRequest<Product[]>('/products', {
|
||||
query: {
|
||||
catalogId: params?.catalogId,
|
||||
companyId: params?.companyId,
|
||||
activeOnly: params?.activeOnly ? 'true' : undefined,
|
||||
},
|
||||
}),
|
||||
getById: (id: string) => apiRequest<Product>(`/products/${id}`),
|
||||
create: (body: CreateProductPayload) =>
|
||||
apiRequest<Product>('/products', { body, timeoutMs: 90_000 }),
|
||||
update: (id: string, body: UpdateProductPayload) =>
|
||||
@@ -675,25 +674,6 @@ export const suggestionsApi = {
|
||||
}),
|
||||
}
|
||||
|
||||
/* ── Stock alerts ─────────────────────────────────────────── */
|
||||
|
||||
export type StockAlert = {
|
||||
id: string
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
productName: string
|
||||
productCode: string
|
||||
stock: number | null
|
||||
active: boolean
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export const stockAlertsApi = {
|
||||
list: () => apiRequest<StockAlert[]>('/admin/stock-alerts'),
|
||||
notify: (id: string) =>
|
||||
apiRequest<StockAlert>(`/admin/stock-alerts/${id}/notify`, { method: 'PATCH' }),
|
||||
}
|
||||
|
||||
/* ── SMS wallet ───────────────────────────────────────────── */
|
||||
|
||||
export type SmsUsageStats = {
|
||||
|
||||
+3
-2
@@ -229,8 +229,8 @@ export interface Catalog {
|
||||
|
||||
export interface Product {
|
||||
id: string
|
||||
catalogId: string
|
||||
catalogCode: string
|
||||
companyId?: string
|
||||
catalogCode?: string
|
||||
companyName: string
|
||||
brandId?: string | null
|
||||
brandName?: string | null
|
||||
@@ -252,6 +252,7 @@ export interface Product {
|
||||
isNew?: boolean
|
||||
colors?: string[]
|
||||
colorImages?: Array<string | null>
|
||||
colorVariantImages?: string[][]
|
||||
imageUrls?: string[]
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ export function resolveAdminInboxLink(input: InboxLinkInput): string | null {
|
||||
if (isCash) return '/cash-payments'
|
||||
if (isReport) return '/reports'
|
||||
if (isCustomer) return '/customers'
|
||||
if (isCatalog) return '/catalogs'
|
||||
if (isCatalog) return '/products'
|
||||
if (isProduct) return '/products'
|
||||
if (isCompany) return '/companies'
|
||||
if (isSettings) return '/settings'
|
||||
|
||||
@@ -8,8 +8,7 @@ export const ADMIN_NAV_ITEMS: NavItem[] = [
|
||||
{ name: 'categories', label: 'دستهبندیها', path: '/categories', icon: 'catalogs' },
|
||||
{ name: 'banners', label: 'بنرها', path: '/banners', icon: 'image' },
|
||||
{ name: 'internal-messages', label: 'پیامهای داخلی', path: '/internal-messages', icon: 'message' },
|
||||
{ name: 'catalogs', label: 'کالیتهها', path: '/catalogs', icon: 'catalogs' },
|
||||
{
|
||||
{
|
||||
name: 'catalog-requests',
|
||||
label: 'درخواست کالیته فیزیکی',
|
||||
path: '/catalog-requests',
|
||||
@@ -17,7 +16,6 @@ export const ADMIN_NAV_ITEMS: NavItem[] = [
|
||||
},
|
||||
{ name: 'brands', label: 'برندها', path: '/brands', icon: 'building' },
|
||||
{ name: 'suggestions', label: 'پیشنهاد محصول', path: '/suggestions', icon: 'cart' },
|
||||
{ name: 'stock-alerts', label: 'خبر موجودی', path: '/stock-alerts', icon: 'bell' },
|
||||
{ name: 'levels', label: 'سطوح مشتری', path: '/levels', icon: 'users' },
|
||||
{ name: 'companies', label: 'شرکتها', path: '/companies', icon: 'companies' },
|
||||
{ name: 'checks', label: 'چکها', path: '/checks', icon: 'checks' },
|
||||
|
||||
@@ -1,397 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import AdminPageSkeleton from '@/components/ui/AdminPageSkeleton.vue'
|
||||
import BaseModal from '@/components/ui/BaseModal.vue'
|
||||
import BaseSwitch from '@/components/ui/BaseSwitch.vue'
|
||||
import BaseEmptyState from '@/components/ui/BaseEmptyState.vue'
|
||||
import ActiveSwitchCell from '@/components/ui/ActiveSwitchCell.vue'
|
||||
import AdminIcon from '@/components/icons/AdminIcon.vue'
|
||||
import AdminSelect from '@/components/ui/AdminSelect.vue'
|
||||
import AdminImagePicker from '@/components/ui/AdminImagePicker.vue'
|
||||
import { catalogsApi, companiesApi } from '@/services/api'
|
||||
import { ApiError } from '@/services/http'
|
||||
import { useToast } from '@/composables/useToast'
|
||||
import type { Catalog, Company } from '@/types'
|
||||
|
||||
const catalogList = ref<Catalog[]>([])
|
||||
const companies = ref<Company[]>([])
|
||||
const searchQuery = ref('')
|
||||
const companyFilter = ref('all')
|
||||
const loading = ref(true)
|
||||
const modalMode = ref<'add' | 'edit' | null>(null)
|
||||
const editingId = ref<string | null>(null)
|
||||
const formError = ref('')
|
||||
const saving = ref(false)
|
||||
const toast = useToast()
|
||||
|
||||
const companyFilterOptions = computed(() => [
|
||||
{ value: 'all', label: 'همه شرکتها' },
|
||||
...companies.value.map((company) => ({ value: company.id, label: company.name })),
|
||||
])
|
||||
|
||||
const companyFormOptions = computed(() =>
|
||||
companies.value.map((company) => ({ value: company.id, label: company.name })),
|
||||
)
|
||||
|
||||
const emptyForm = () => ({
|
||||
companyId: companies.value[0]?.id ?? '',
|
||||
code: '',
|
||||
name: '',
|
||||
displayOrder: catalogList.value.length + 1,
|
||||
isActive: true,
|
||||
imageUrl: null as string | null,
|
||||
})
|
||||
|
||||
const form = reactive(emptyForm())
|
||||
|
||||
const isModalOpen = computed(() => modalMode.value !== null)
|
||||
const modalTitle = computed(() => (modalMode.value === 'edit' ? 'ویرایش کالیته' : 'افزودن کالیته'))
|
||||
const isFormValid = computed(() => form.code.trim() && form.name.trim() && form.companyId)
|
||||
const hasActiveFilters = computed(
|
||||
() => searchQuery.value.trim().length > 0 || companyFilter.value !== 'all',
|
||||
)
|
||||
|
||||
const filteredCatalogs = computed(() => {
|
||||
let list = catalogList.value
|
||||
if (companyFilter.value !== 'all') {
|
||||
list = list.filter((c) => c.companyId === companyFilter.value)
|
||||
}
|
||||
const q = searchQuery.value.trim()
|
||||
if (q) {
|
||||
list = list.filter((c) => c.code.includes(q) || c.name.includes(q) || c.companyName.includes(q))
|
||||
}
|
||||
return list
|
||||
})
|
||||
|
||||
async function loadData() {
|
||||
loading.value = true
|
||||
try {
|
||||
const [catalogsData, companiesData] = await Promise.all([
|
||||
catalogsApi.list(),
|
||||
companiesApi.list(),
|
||||
])
|
||||
catalogList.value = catalogsData
|
||||
companies.value = companiesData
|
||||
} catch (err) {
|
||||
toast.error(err instanceof ApiError ? err.message : 'بارگذاری کالیتهها انجام نشد.')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void loadData()
|
||||
})
|
||||
|
||||
function companyName(companyId: string) {
|
||||
return companies.value.find((c) => c.id === companyId)?.name ?? '—'
|
||||
}
|
||||
|
||||
function openAddModal() {
|
||||
modalMode.value = 'add'
|
||||
editingId.value = null
|
||||
Object.assign(form, emptyForm())
|
||||
formError.value = ''
|
||||
}
|
||||
|
||||
function openEditModal(catalog: Catalog) {
|
||||
modalMode.value = 'edit'
|
||||
editingId.value = catalog.id
|
||||
form.companyId = catalog.companyId
|
||||
form.code = catalog.code
|
||||
form.name = catalog.name
|
||||
form.displayOrder = catalog.displayOrder
|
||||
form.isActive = catalog.isActive
|
||||
form.imageUrl = catalog.imageUrl ?? null
|
||||
formError.value = ''
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
modalMode.value = null
|
||||
editingId.value = null
|
||||
formError.value = ''
|
||||
}
|
||||
|
||||
async function submitCatalog() {
|
||||
if (!isFormValid.value) {
|
||||
formError.value = 'کد، نام و شرکت الزامی هستند.'
|
||||
return
|
||||
}
|
||||
|
||||
saving.value = true
|
||||
try {
|
||||
if (modalMode.value === 'edit' && editingId.value) {
|
||||
const updated = await catalogsApi.update(editingId.value, {
|
||||
code: form.code.trim(),
|
||||
name: form.name.trim(),
|
||||
displayOrder: Number(form.displayOrder) || 1,
|
||||
isActive: form.isActive,
|
||||
imageUrl: form.imageUrl,
|
||||
})
|
||||
const index = catalogList.value.findIndex((c) => c.id === editingId.value)
|
||||
if (index !== -1) {
|
||||
catalogList.value[index] = {
|
||||
...catalogList.value[index]!,
|
||||
...updated,
|
||||
companyName: companyName(form.companyId),
|
||||
}
|
||||
}
|
||||
toast.success('اطلاعات کالیته بهروزرسانی شد.')
|
||||
} else {
|
||||
const created = await catalogsApi.create({
|
||||
companyId: form.companyId,
|
||||
code: form.code.trim(),
|
||||
name: form.name.trim(),
|
||||
displayOrder: Number(form.displayOrder) || 1,
|
||||
isActive: form.isActive,
|
||||
imageUrl: form.imageUrl,
|
||||
})
|
||||
catalogList.value.push({
|
||||
...created,
|
||||
companyName: created.companyName || companyName(form.companyId),
|
||||
productCount: created.productCount ?? 0,
|
||||
})
|
||||
toast.success('کالیته جدید ثبت شد.')
|
||||
}
|
||||
closeModal()
|
||||
} catch (err) {
|
||||
toast.error(err instanceof ApiError ? err.message : 'ذخیره کالیته انجام نشد.')
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function persistActive(id: string, isActive: boolean) {
|
||||
await catalogsApi.setActive(id, isActive)
|
||||
}
|
||||
|
||||
function clearFilters() {
|
||||
searchQuery.value = ''
|
||||
companyFilter.value = 'all'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="catalogs-page">
|
||||
<div class="admin-page-header">
|
||||
<div>
|
||||
<h1 class="admin-page-header__title">کالیتهها</h1>
|
||||
</div>
|
||||
<button type="button" class="admin-btn admin-btn--primary" @click="openAddModal">
|
||||
افزودن کالیته
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="catalogs-page__filters admin-card">
|
||||
<div class="catalogs-page__search">
|
||||
<AdminIcon name="search" :size="18" />
|
||||
<input
|
||||
v-model="searchQuery"
|
||||
type="search"
|
||||
class="catalogs-page__search-input"
|
||||
placeholder="جستجو بر اساس کد یا نام..."
|
||||
/>
|
||||
</div>
|
||||
<AdminSelect
|
||||
v-model="companyFilter"
|
||||
class="catalogs-page__company-filter"
|
||||
aria-label="فیلتر شرکت"
|
||||
:options="companyFilterOptions"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<AdminPageSkeleton v-if="loading" variant="table" />
|
||||
<BaseEmptyState
|
||||
v-else-if="!filteredCatalogs.length"
|
||||
class="admin-card"
|
||||
icon="catalogs"
|
||||
:title="hasActiveFilters ? 'نتیجهای یافت نشد' : 'کالیتهای ثبت نشده'"
|
||||
:description="
|
||||
hasActiveFilters
|
||||
? 'عبارت جستجو را تغییر دهید یا فیلترها را پاک کنید.'
|
||||
: 'برای شروع، اولین کالیته را ثبت کنید.'
|
||||
"
|
||||
>
|
||||
<button v-if="hasActiveFilters" type="button" class="admin-btn admin-btn--outline admin-btn--sm" @click="clearFilters">
|
||||
پاک کردن فیلترها
|
||||
</button>
|
||||
<button v-else type="button" class="admin-btn admin-btn--primary admin-btn--sm" @click="openAddModal">
|
||||
افزودن کالیته
|
||||
</button>
|
||||
</BaseEmptyState>
|
||||
|
||||
<div v-else class="catalogs-page__table admin-card desktop-only">
|
||||
<div class="admin-table-wrap">
|
||||
<table class="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>تصویر</th>
|
||||
<th>کد</th>
|
||||
<th>نام کالیته</th>
|
||||
<th>شرکت</th>
|
||||
<th class="numeric">ترتیب</th>
|
||||
<th class="numeric">تعداد محصول</th>
|
||||
<th class="status">وضعیت</th>
|
||||
<th class="actions">عملیات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="catalog in filteredCatalogs" :key="catalog.id">
|
||||
<td>
|
||||
<span
|
||||
class="catalog-thumb"
|
||||
:class="{ 'catalog-thumb--empty': !catalog.imageUrl }"
|
||||
:style="catalog.imageUrl ? { backgroundImage: `url(${catalog.imageUrl})` } : undefined"
|
||||
/>
|
||||
</td>
|
||||
<td>{{ catalog.code }}</td>
|
||||
<td>{{ catalog.name }}</td>
|
||||
<td>{{ catalog.companyName }}</td>
|
||||
<td class="numeric">{{ catalog.displayOrder }}</td>
|
||||
<td class="numeric">{{ catalog.productCount }}</td>
|
||||
<td class="status">
|
||||
<ActiveSwitchCell
|
||||
:id="catalog.id"
|
||||
v-model="catalog.isActive"
|
||||
:entity-name="catalog.name"
|
||||
entity-type="کالیته"
|
||||
:persist="persistActive"
|
||||
/>
|
||||
</td>
|
||||
<td class="actions">
|
||||
<button type="button" class="admin-btn admin-btn--ghost admin-btn--xs" @click="openEditModal(catalog)">
|
||||
ویرایش
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!loading && filteredCatalogs.length" class="compact-only admin-card-list">
|
||||
<article v-for="catalog in filteredCatalogs" :key="catalog.id" class="admin-card-item">
|
||||
<div class="admin-card-item__header">
|
||||
<span
|
||||
class="catalog-thumb"
|
||||
:class="{ 'catalog-thumb--empty': !catalog.imageUrl }"
|
||||
:style="catalog.imageUrl ? { backgroundImage: `url(${catalog.imageUrl})` } : undefined"
|
||||
/>
|
||||
<p class="admin-card-item__title">کالیته {{ catalog.code }} — {{ catalog.name }}</p>
|
||||
<ActiveSwitchCell
|
||||
:id="catalog.id"
|
||||
v-model="catalog.isActive"
|
||||
:entity-name="catalog.name"
|
||||
entity-type="کالیته"
|
||||
:persist="persistActive"
|
||||
/>
|
||||
</div>
|
||||
<div class="admin-card-item__meta">
|
||||
<span>{{ catalog.companyName }}</span>
|
||||
<span>{{ catalog.productCount }} محصول</span>
|
||||
<span>ترتیب: {{ catalog.displayOrder }}</span>
|
||||
</div>
|
||||
<div class="admin-card-item__actions">
|
||||
<button type="button" class="admin-btn admin-btn--ghost admin-btn--xs" @click="openEditModal(catalog)">
|
||||
ویرایش
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<BaseModal :open="isModalOpen" :title="modalTitle" size="lg" @close="closeModal">
|
||||
<form class="admin-form" @submit.prevent="submitCatalog">
|
||||
<p v-if="formError" class="admin-form__error" role="alert">{{ formError }}</p>
|
||||
|
||||
<div class="admin-form__field">
|
||||
<label>شرکت <span class="admin-form__required">*</span></label>
|
||||
<AdminSelect
|
||||
v-model="form.companyId"
|
||||
block
|
||||
aria-label="انتخاب شرکت"
|
||||
placeholder="انتخاب شرکت"
|
||||
:options="companyFormOptions"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="admin-form__row">
|
||||
<div class="admin-form__field">
|
||||
<label for="catalog-code">کد کالیته <span class="admin-form__required">*</span></label>
|
||||
<input id="catalog-code" v-model="form.code" type="text" class="admin-input" placeholder="377" />
|
||||
</div>
|
||||
<div class="admin-form__field">
|
||||
<label for="catalog-name">نام کالیته <span class="admin-form__required">*</span></label>
|
||||
<input id="catalog-name" v-model="form.name" type="text" class="admin-input" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-form__row">
|
||||
<div class="admin-form__field">
|
||||
<label for="catalog-order">ترتیب نمایش</label>
|
||||
<input id="catalog-order" v-model.number="form.displayOrder" type="number" min="1" class="admin-input" />
|
||||
</div>
|
||||
<div class="admin-form__field">
|
||||
<BaseSwitch v-model="form.isActive" label="وضعیت" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AdminImagePicker v-model="form.imageUrl" label="تصویر بنر کالیته" />
|
||||
</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="submitCatalog">
|
||||
{{ modalMode === 'edit' ? 'ذخیره تغییرات' : 'ثبت کالیته' }}
|
||||
</button>
|
||||
</template>
|
||||
</BaseModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.catalogs-page__filters {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.catalogs-page__search {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.catalogs-page__search-input {
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 0.875rem;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.catalogs-page__company-filter {
|
||||
width: min(220px, 100%);
|
||||
}
|
||||
|
||||
.catalogs-page__table {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.catalog-thumb {
|
||||
display: block;
|
||||
width: 72px;
|
||||
height: 44px;
|
||||
border-radius: 8px;
|
||||
background: #e8eceb center / cover no-repeat;
|
||||
}
|
||||
|
||||
.catalog-thumb--empty {
|
||||
background: #eef1f0;
|
||||
}
|
||||
</style>
|
||||
@@ -164,7 +164,7 @@ function submitAddProduct() {
|
||||
items.value.push({
|
||||
id: `new-${crypto.randomUUID().slice(0, 8)}`,
|
||||
productId: product.id,
|
||||
catalogCode: product.catalogCode,
|
||||
catalogCode: product.catalogCode ?? product.productCode,
|
||||
productName: product.name,
|
||||
color: product.color || '—',
|
||||
requestedMeterage: form.requestedMeterage,
|
||||
@@ -321,7 +321,7 @@ async function sendInvoice() {
|
||||
<th>رنگ / نوع</th>
|
||||
<th>متراژ درخواستی</th>
|
||||
<th>متراژ تأیید شده</th>
|
||||
<th>قیمت تأمینی (واحد)</th>
|
||||
<th>قیمت هر متر (تومان)</th>
|
||||
<th>مبلغ کل (تومان)</th>
|
||||
<th>عملیات</th>
|
||||
</tr>
|
||||
@@ -386,7 +386,7 @@ async function sendInvoice() {
|
||||
<input v-model.number="item.confirmedMeterage" type="number" class="admin-input" />
|
||||
</label>
|
||||
<label>
|
||||
قیمت تأمینی
|
||||
قیمت هر متر (تومان)
|
||||
<AdminCurrencyInput v-model="item.supplyPrice" placeholder="—" />
|
||||
</label>
|
||||
<p v-if="item.totalAmount" class="pricing-page__line-total">
|
||||
|
||||
@@ -137,7 +137,7 @@ function addDraftProduct() {
|
||||
const added = addFormItem({
|
||||
productId: product.id,
|
||||
productName: product.name,
|
||||
catalogCode: product.catalogCode,
|
||||
catalogCode: product.catalogCode ?? product.productCode,
|
||||
meterage,
|
||||
})
|
||||
if (!added) {
|
||||
|
||||
@@ -239,8 +239,8 @@ function onCashReceiptAction() {
|
||||
<th>محصول</th>
|
||||
<th>رنگ</th>
|
||||
<th>متراژ</th>
|
||||
<th>قیمت</th>
|
||||
<th>مبلغ</th>
|
||||
<th>قیمت هر متر</th>
|
||||
<th>مبلغ کل</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
+162
-100
@@ -8,16 +8,16 @@ import BaseEmptyState from '@/components/ui/BaseEmptyState.vue'
|
||||
import ActiveSwitchCell from '@/components/ui/ActiveSwitchCell.vue'
|
||||
import AdminIcon from '@/components/icons/AdminIcon.vue'
|
||||
import AdminSelect from '@/components/ui/AdminSelect.vue'
|
||||
import { brandsApi, catalogsApi, productsApi, settingsApi, type Brand } from '@/services/api'
|
||||
import { brandsApi, companiesApi, productsApi, settingsApi, type Brand } from '@/services/api'
|
||||
import { ApiError } from '@/services/http'
|
||||
import { useToast } from '@/composables/useToast'
|
||||
import { formatCurrency, formatNumber } from '@/utils/format'
|
||||
import type { Catalog, Product } from '@/types'
|
||||
import type { Company, Product } from '@/types'
|
||||
import AdminCurrencyInput from '@/components/ui/AdminCurrencyInput.vue'
|
||||
import { toCssBackgroundUrl } from '@/utils/catalogImage'
|
||||
|
||||
const productList = ref<Product[]>([])
|
||||
const catalogs = ref<Catalog[]>([])
|
||||
const companies = ref<Company[]>([])
|
||||
const brands = ref<Brand[]>([])
|
||||
const usageOptions = ref<Array<{ value: string; label: string }>>([
|
||||
{ value: 'trousers', label: 'شلوار' },
|
||||
@@ -31,7 +31,7 @@ const seasonOptions = ref<Array<{ value: string; label: string }>>([
|
||||
{ value: 'all_season', label: 'چهارفصل' },
|
||||
])
|
||||
const searchQuery = ref('')
|
||||
const catalogFilter = ref('all')
|
||||
const companyFilter = ref('all')
|
||||
const loading = ref(true)
|
||||
const modalMode = ref<'add' | 'edit' | null>(null)
|
||||
const editingId = ref<string | null>(null)
|
||||
@@ -39,19 +39,21 @@ const formError = ref('')
|
||||
const saving = ref(false)
|
||||
const toast = useToast()
|
||||
|
||||
const catalogFilterOptions = computed(() => [
|
||||
{ value: 'all', label: 'همه کالیتهها' },
|
||||
...catalogs.value.map((catalog) => ({
|
||||
value: catalog.id,
|
||||
label: `${catalog.code} — ${catalog.name}`,
|
||||
const companyFilterOptions = computed(() => [
|
||||
{ value: 'all', label: 'همه شرکتها' },
|
||||
...companies.value.map((company) => ({
|
||||
value: company.id,
|
||||
label: company.name,
|
||||
})),
|
||||
])
|
||||
|
||||
const catalogFormOptions = computed(() =>
|
||||
catalogs.value.map((catalog) => ({
|
||||
value: catalog.id,
|
||||
label: `${catalog.code} — ${catalog.name} (${catalog.companyName})`,
|
||||
})),
|
||||
const companyFormOptions = computed(() =>
|
||||
companies.value
|
||||
.filter((c) => c.isActive)
|
||||
.map((company) => ({
|
||||
value: company.id,
|
||||
label: company.name,
|
||||
})),
|
||||
)
|
||||
|
||||
const brandFormOptions = computed(() => [
|
||||
@@ -62,7 +64,7 @@ const brandFormOptions = computed(() => [
|
||||
])
|
||||
|
||||
const emptyForm = () => ({
|
||||
catalogId: catalogs.value[0]?.id ?? '',
|
||||
companyId: companies.value[0]?.id ?? '',
|
||||
brandId: '',
|
||||
name: '',
|
||||
color: '',
|
||||
@@ -79,6 +81,7 @@ const emptyForm = () => ({
|
||||
subtitle: '',
|
||||
rollMeters: 50,
|
||||
isNew: false,
|
||||
generalImages: [] as string[],
|
||||
colorRows: [{ id: crypto.randomUUID(), name: '', imageUrl: '' }] as Array<{
|
||||
id: string
|
||||
name: string
|
||||
@@ -90,15 +93,15 @@ const form = reactive(emptyForm())
|
||||
|
||||
const isModalOpen = computed(() => modalMode.value !== null)
|
||||
const modalTitle = computed(() => (modalMode.value === 'edit' ? 'ویرایش محصول' : 'افزودن محصول'))
|
||||
const isFormValid = computed(() => form.name.trim() && form.catalogId && form.minMeterage > 0)
|
||||
const isFormValid = computed(() => form.name.trim() && form.companyId && form.minMeterage > 0)
|
||||
const hasActiveFilters = computed(
|
||||
() => searchQuery.value.trim().length > 0 || catalogFilter.value !== 'all',
|
||||
() => searchQuery.value.trim().length > 0 || companyFilter.value !== 'all',
|
||||
)
|
||||
|
||||
const filteredProducts = computed(() => {
|
||||
let list = productList.value
|
||||
if (catalogFilter.value !== 'all') {
|
||||
list = list.filter((p) => p.catalogId === catalogFilter.value)
|
||||
if (companyFilter.value !== 'all') {
|
||||
list = list.filter((p) => p.companyId === companyFilter.value)
|
||||
}
|
||||
const q = searchQuery.value.trim()
|
||||
if (q) {
|
||||
@@ -107,7 +110,7 @@ const filteredProducts = computed(() => {
|
||||
p.name.includes(q) ||
|
||||
p.color.includes(q) ||
|
||||
p.productCode.includes(q) ||
|
||||
p.catalogCode.includes(q),
|
||||
(p.catalogCode ?? p.productCode).includes(q),
|
||||
)
|
||||
}
|
||||
return list
|
||||
@@ -116,14 +119,14 @@ const filteredProducts = computed(() => {
|
||||
async function loadData() {
|
||||
loading.value = true
|
||||
try {
|
||||
const [productsData, catalogsData, brandsData, settings] = await Promise.all([
|
||||
const [productsData, companiesData, brandsData, settings] = await Promise.all([
|
||||
productsApi.list(),
|
||||
catalogsApi.list(),
|
||||
companiesApi.list(),
|
||||
brandsApi.list(),
|
||||
settingsApi.get().catch(() => null),
|
||||
])
|
||||
productList.value = productsData
|
||||
catalogs.value = catalogsData
|
||||
companies.value = companiesData
|
||||
brands.value = brandsData
|
||||
if (settings?.categoryDefsJson?.usage?.length) {
|
||||
usageOptions.value = [
|
||||
@@ -151,10 +154,6 @@ onMounted(() => {
|
||||
void loadData()
|
||||
})
|
||||
|
||||
function catalogMeta(catalogId: string) {
|
||||
return catalogs.value.find((c) => c.id === catalogId)
|
||||
}
|
||||
|
||||
function openAddModal() {
|
||||
modalMode.value = 'add'
|
||||
editingId.value = null
|
||||
@@ -162,10 +161,15 @@ function openAddModal() {
|
||||
formError.value = ''
|
||||
}
|
||||
|
||||
function openEditModal(product: Product) {
|
||||
async function openEditModal(product: Product) {
|
||||
modalMode.value = 'edit'
|
||||
editingId.value = product.id
|
||||
form.catalogId = product.catalogId
|
||||
try {
|
||||
product = await productsApi.getById(product.id)
|
||||
} catch {
|
||||
/* از ردیف جدول */
|
||||
}
|
||||
form.companyId = product.companyId ?? companies.value[0]?.id ?? ''
|
||||
form.brandId = product.brandId ?? ''
|
||||
form.name = product.name
|
||||
form.color = product.color
|
||||
@@ -182,36 +186,20 @@ function openEditModal(product: Product) {
|
||||
form.subtitle = (product as { subtitle?: string }).subtitle ?? ''
|
||||
form.rollMeters = (product as { rollMeters?: number }).rollMeters ?? 50
|
||||
form.isNew = (product as { isNew?: boolean }).isNew ?? false
|
||||
form.generalImages = [...(product.imageUrls ?? [])]
|
||||
const colors = product.colors ?? []
|
||||
const colorImages = product.colorImages ?? []
|
||||
const gallery = [...(product.imageUrls ?? [])]
|
||||
if (colors.length) {
|
||||
form.colorRows = colors.map((name, index) => ({
|
||||
id: crypto.randomUUID(),
|
||||
name,
|
||||
imageUrl: colorImages[index] || gallery[index] || '',
|
||||
}))
|
||||
const used = new Set(form.colorRows.map((row) => row.imageUrl).filter(Boolean))
|
||||
for (const url of gallery) {
|
||||
if (!used.has(url)) {
|
||||
form.colorRows.push({
|
||||
id: crypto.randomUUID(),
|
||||
name: `رنگ ${form.colorRows.length + 1}`,
|
||||
imageUrl: url,
|
||||
})
|
||||
used.add(url)
|
||||
form.colorRows = colors.map((name, index) => {
|
||||
const fromList = product.colorVariantImages?.[index]?.[0]
|
||||
const legacy = product.colorImages?.[index]
|
||||
return {
|
||||
id: crypto.randomUUID(),
|
||||
name,
|
||||
imageUrl: fromList || legacy || '',
|
||||
}
|
||||
}
|
||||
} else if (gallery.length) {
|
||||
form.colorRows = gallery.map((url, index) => ({
|
||||
id: crypto.randomUUID(),
|
||||
name: index === 0 ? product.color || '' : `رنگ ${index + 1}`,
|
||||
imageUrl: url,
|
||||
}))
|
||||
})
|
||||
} else {
|
||||
form.colorRows = [
|
||||
{ id: crypto.randomUUID(), name: product.color || '', imageUrl: '' },
|
||||
]
|
||||
form.colorRows = [{ id: crypto.randomUUID(), name: product.color || '', imageUrl: '' }]
|
||||
}
|
||||
formError.value = ''
|
||||
}
|
||||
@@ -222,23 +210,39 @@ function addColorRow() {
|
||||
|
||||
function removeColorRow(index: number) {
|
||||
if (form.colorRows.length <= 1) {
|
||||
form.colorRows[0] = { id: form.colorRows[0]?.id ?? crypto.randomUUID(), name: '', imageUrl: '' }
|
||||
form.colorRows[0] = {
|
||||
id: form.colorRows[0]?.id ?? crypto.randomUUID(),
|
||||
name: '',
|
||||
imageUrl: '',
|
||||
}
|
||||
return
|
||||
}
|
||||
form.colorRows.splice(index, 1)
|
||||
}
|
||||
|
||||
function buildProductMedia() {
|
||||
const colorEntries: Array<{ name: string; imageUrl?: string }> = []
|
||||
const imageUrls: string[] = []
|
||||
const seen = new Set<string>()
|
||||
function addGeneralImageSlot() {
|
||||
form.generalImages.push('')
|
||||
}
|
||||
|
||||
const pushImage = (url?: string) => {
|
||||
const trimmed = url?.trim()
|
||||
if (!trimmed || seen.has(trimmed)) return
|
||||
seen.add(trimmed)
|
||||
imageUrls.push(trimmed)
|
||||
function removeGeneralImage(index: number) {
|
||||
form.generalImages.splice(index, 1)
|
||||
}
|
||||
|
||||
function uniqueUrls(urls: string[]) {
|
||||
const out: string[] = []
|
||||
const seen = new Set<string>()
|
||||
for (const raw of urls) {
|
||||
const url = raw.trim()
|
||||
if (!url || seen.has(url)) continue
|
||||
seen.add(url)
|
||||
out.push(url)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
function buildProductMedia() {
|
||||
const imageUrls = uniqueUrls(form.generalImages)
|
||||
const colorEntries: Array<{ name: string; imageUrls: string[]; imageUrl?: string }> = []
|
||||
|
||||
form.colorRows.forEach((row, index) => {
|
||||
const imageUrl = row.imageUrl.trim() || undefined
|
||||
@@ -247,10 +251,12 @@ function buildProductMedia() {
|
||||
(index === 0 ? form.color.trim() : '') ||
|
||||
(imageUrl ? `رنگ ${index + 1}` : '')
|
||||
if (!name && !imageUrl) return
|
||||
if (name) {
|
||||
colorEntries.push({ name, imageUrl })
|
||||
}
|
||||
pushImage(imageUrl)
|
||||
if (!name) return
|
||||
colorEntries.push({
|
||||
name,
|
||||
imageUrls: imageUrl ? [imageUrl] : [],
|
||||
imageUrl,
|
||||
})
|
||||
})
|
||||
|
||||
return { colorEntries, imageUrls }
|
||||
@@ -264,13 +270,13 @@ function closeModal() {
|
||||
|
||||
async function submitProduct() {
|
||||
if (!isFormValid.value) {
|
||||
formError.value = 'نام محصول، کالیته و حداقل متراژ الزامی هستند.'
|
||||
formError.value = 'نام محصول، شرکت و حداقل متراژ الزامی هستند.'
|
||||
return
|
||||
}
|
||||
|
||||
const cat = catalogMeta(form.catalogId)
|
||||
if (!cat) {
|
||||
formError.value = 'کالیته معتبر انتخاب کنید.'
|
||||
const company = companies.value.find((c) => c.id === form.companyId)
|
||||
if (!company) {
|
||||
formError.value = 'شرکت معتبر انتخاب کنید.'
|
||||
return
|
||||
}
|
||||
|
||||
@@ -286,12 +292,11 @@ async function submitProduct() {
|
||||
colorsJson: colorEntries,
|
||||
imageUrlsJson: imageUrls,
|
||||
}
|
||||
const productCode = form.productCode.trim() || `${cat.code}-NEW`
|
||||
const productCode = form.productCode.trim() || `PRD-${Date.now()}`
|
||||
saving.value = true
|
||||
try {
|
||||
if (modalMode.value === 'edit' && editingId.value) {
|
||||
const updated = await productsApi.update(editingId.value, {
|
||||
catalogId: form.catalogId,
|
||||
await productsApi.update(editingId.value, {
|
||||
name: form.name.trim(),
|
||||
color: form.color.trim() || colorEntries[0]?.name || '—',
|
||||
code: productCode,
|
||||
@@ -301,16 +306,15 @@ async function submitProduct() {
|
||||
price: form.price,
|
||||
internalStock: form.internalStock,
|
||||
isActive: form.isActive,
|
||||
brandId: form.brandId || null,
|
||||
...catalogPayload,
|
||||
})
|
||||
const fresh = await productsApi.getById(editingId.value)
|
||||
const index = productList.value.findIndex((p) => p.id === editingId.value)
|
||||
if (index !== -1) productList.value[index] = { ...productList.value[index]!, ...updated }
|
||||
if (index !== -1) productList.value[index] = fresh
|
||||
toast.success('اطلاعات محصول بهروزرسانی شد.')
|
||||
} else {
|
||||
const created = await productsApi.create({
|
||||
companyId: cat.companyId,
|
||||
catalogId: form.catalogId,
|
||||
companyId: company.id,
|
||||
name: form.name.trim(),
|
||||
color: form.color.trim() || colorEntries[0]?.name || '—',
|
||||
code: productCode,
|
||||
@@ -343,7 +347,7 @@ async function persistActive(id: string, isActive: boolean) {
|
||||
|
||||
function clearFilters() {
|
||||
searchQuery.value = ''
|
||||
catalogFilter.value = 'all'
|
||||
companyFilter.value = 'all'
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -369,10 +373,10 @@ function clearFilters() {
|
||||
/>
|
||||
</div>
|
||||
<AdminSelect
|
||||
v-model="catalogFilter"
|
||||
v-model="companyFilter"
|
||||
class="products-page__catalog-filter"
|
||||
aria-label="فیلتر کالیته"
|
||||
:options="catalogFilterOptions"
|
||||
aria-label="فیلتر شرکت"
|
||||
:options="companyFilterOptions"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -406,11 +410,11 @@ function clearFilters() {
|
||||
<th>نام</th>
|
||||
<th>رنگ</th>
|
||||
<th>برند</th>
|
||||
<th>کالیته</th>
|
||||
<th>کد محصول</th>
|
||||
<th>شرکت</th>
|
||||
<th class="numeric">حداقل متراژ</th>
|
||||
<th class="numeric">ضریب</th>
|
||||
<th class="numeric">قیمت</th>
|
||||
<th class="numeric">قیمت هر متر</th>
|
||||
<th class="numeric">موجودی</th>
|
||||
<th class="status">وضعیت</th>
|
||||
<th class="actions">عملیات</th>
|
||||
@@ -429,11 +433,13 @@ function clearFilters() {
|
||||
<td>{{ product.name }}</td>
|
||||
<td>{{ product.color }}</td>
|
||||
<td>{{ product.brandName || '—' }}</td>
|
||||
<td>{{ product.catalogCode }}</td>
|
||||
<td dir="ltr">{{ product.productCode }}</td>
|
||||
<td>{{ product.companyName }}</td>
|
||||
<td class="numeric">{{ formatNumber(product.minMeterage) }} متر</td>
|
||||
<td class="numeric">{{ formatNumber(product.orderStep) }}</td>
|
||||
<td class="numeric">{{ product.price ? formatCurrency(product.price) : '—' }}</td>
|
||||
<td class="numeric">
|
||||
{{ product.price ? `${formatCurrency(product.price)} / متر` : '—' }}
|
||||
</td>
|
||||
<td class="numeric">{{ formatNumber(product.internalStock) }} متر</td>
|
||||
<td class="status">
|
||||
<ActiveSwitchCell
|
||||
@@ -475,8 +481,8 @@ function clearFilters() {
|
||||
<div class="admin-card-item__meta">
|
||||
<span>{{ product.productCode }}</span>
|
||||
<span>{{ product.color }}</span>
|
||||
<span>کالیته {{ product.catalogCode }}</span>
|
||||
<span>{{ product.price ? formatCurrency(product.price) : 'بدون قیمت' }}</span>
|
||||
<span dir="ltr">کد {{ product.productCode }}</span>
|
||||
<span>{{ product.price ? `${formatCurrency(product.price)} / متر` : 'بدون قیمت' }}</span>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
@@ -486,13 +492,13 @@ function clearFilters() {
|
||||
<p v-if="formError" class="admin-form__error" role="alert">{{ formError }}</p>
|
||||
|
||||
<div class="admin-form__field">
|
||||
<label>کالیته <span class="admin-form__required">*</span></label>
|
||||
<label>شرکت <span class="admin-form__required">*</span></label>
|
||||
<AdminSelect
|
||||
v-model="form.catalogId"
|
||||
v-model="form.companyId"
|
||||
block
|
||||
aria-label="انتخاب کالیته"
|
||||
placeholder="انتخاب کالیته"
|
||||
:options="catalogFormOptions"
|
||||
aria-label="انتخاب شرکت"
|
||||
placeholder="انتخاب شرکت"
|
||||
:options="companyFormOptions"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -536,8 +542,11 @@ function clearFilters() {
|
||||
|
||||
<div class="admin-form__row">
|
||||
<div class="admin-form__field">
|
||||
<label for="product-price">قیمت (تومان)</label>
|
||||
<AdminCurrencyInput id="product-price" v-model="form.price" />
|
||||
<label for="product-price">قیمت هر متر (تومان)</label>
|
||||
<AdminCurrencyInput id="product-price" v-model="form.price" placeholder="مثلاً ۲۵۰٬۰۰۰" />
|
||||
<p class="admin-form__hint">
|
||||
مبلغ بهازای هر متر پارچه؛ در سفارش با متراژ تأییدشده ضرب میشود.
|
||||
</p>
|
||||
</div>
|
||||
<div class="admin-form__field">
|
||||
<label for="product-stock">موجودی داخلی (متر)</label>
|
||||
@@ -587,15 +596,44 @@ function clearFilters() {
|
||||
</div>
|
||||
|
||||
<div class="admin-form__field">
|
||||
<label>رنگها و تصویر هر رنگ</label>
|
||||
<label>تصاویر عمومی محصول</label>
|
||||
<p class="color-variants__hint">
|
||||
برای هر رنگ نام و عکس بگذارید. اگر فقط عکس دارید، نام رنگ اصلی (بالا) یا «رنگ ۱» استفاده میشود.
|
||||
تصویر با زدن «ذخیره تغییرات» روی سرور ثبت میشود.
|
||||
فقط برای گالری اصلی در اپ کاربر (بدون وابستگی به رنگ). با «ذخیره تغییرات» ثبت میشود.
|
||||
</p>
|
||||
<div class="general-images">
|
||||
<div
|
||||
v-for="(url, gIdx) in form.generalImages"
|
||||
:key="`general-${gIdx}`"
|
||||
class="general-images__row"
|
||||
>
|
||||
<AdminImagePicker
|
||||
:model-value="url || null"
|
||||
@update:model-value="form.generalImages[gIdx] = $event ?? ''"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="admin-btn admin-btn--ghost admin-btn--xs"
|
||||
@click="removeGeneralImage(gIdx)"
|
||||
>
|
||||
حذف تصویر
|
||||
</button>
|
||||
</div>
|
||||
<button type="button" class="admin-btn admin-btn--outline" @click="addGeneralImageSlot">
|
||||
+ افزودن تصویر عمومی
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-form__field">
|
||||
<label>رنگبندیها</label>
|
||||
<p class="color-variants__hint">
|
||||
برای هر رنگ یک نام و یک تصویر بگذارید. تصویر رنگ در بخش رنگبندی اپ نمایش داده میشود، نه در گالری عمومی.
|
||||
</p>
|
||||
<div class="color-variants">
|
||||
<div v-for="(row, index) in form.colorRows" :key="row.id" class="color-variant">
|
||||
<AdminImagePicker
|
||||
:model-value="row.imageUrl || null"
|
||||
:show-remove="false"
|
||||
@update:model-value="row.imageUrl = $event ?? ''"
|
||||
/>
|
||||
<div class="color-variant__fields">
|
||||
@@ -666,6 +704,13 @@ function clearFilters() {
|
||||
width: min(260px, 100%);
|
||||
}
|
||||
|
||||
.admin-form__hint {
|
||||
margin: 6px 0 0;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.5;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.products-page__table {
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -695,6 +740,23 @@ function clearFilters() {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.general-images {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.general-images__row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 12px;
|
||||
background: var(--color-bg, #f7f8f7);
|
||||
}
|
||||
|
||||
.color-variant {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -204,7 +204,7 @@ async function sendBroadcast() {
|
||||
</label>
|
||||
|
||||
<div class="admin-form__field">
|
||||
<label for="agent-min-price">حداقل قیمت واحد واسطه (تومان)</label>
|
||||
<label for="agent-min-price">حداقل قیمت هر متر واسطه (تومان)</label>
|
||||
<input
|
||||
id="agent-min-price"
|
||||
v-model.number="settings.agentMinUnitPrice"
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import AdminPageSkeleton from '@/components/ui/AdminPageSkeleton.vue'
|
||||
import BaseEmptyState from '@/components/ui/BaseEmptyState.vue'
|
||||
import { stockAlertsApi, type StockAlert } from '@/services/api'
|
||||
import { ApiError } from '@/services/http'
|
||||
import { useToast } from '@/composables/useToast'
|
||||
|
||||
const list = ref<StockAlert[]>([])
|
||||
const loading = ref(true)
|
||||
const toast = useToast()
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
list.value = await stockAlertsApi.list()
|
||||
} catch (err) {
|
||||
toast.error(err instanceof ApiError ? err.message : 'بارگذاری ناموفق بود')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function notify(id: string) {
|
||||
try {
|
||||
await stockAlertsApi.notify(id)
|
||||
toast.success('اعلان موجودی ارسال شد')
|
||||
await load()
|
||||
} catch (err) {
|
||||
toast.error(err instanceof ApiError ? err.message : 'ارسال ناموفق بود')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void load()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="admin-page">
|
||||
<header class="admin-page__head">
|
||||
<div>
|
||||
<h1>درخواست خبر موجودی</h1>
|
||||
<p>مشتریانی که برای محصول ناموجود درخواست اطلاع دادهاند</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<AdminPageSkeleton v-if="loading" variant="table" />
|
||||
<BaseEmptyState v-else-if="!list.length" title="درخواستی فعال نیست" />
|
||||
|
||||
<table v-else class="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>مشتری</th>
|
||||
<th>محصول</th>
|
||||
<th>موجودی فعلی</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="row in list" :key="row.id">
|
||||
<td>
|
||||
{{ row.customerName }}
|
||||
<span class="muted" dir="ltr">{{ row.customerPhone }}</span>
|
||||
</td>
|
||||
<td>{{ row.productName }} <span class="muted" dir="ltr">({{ row.productCode }})</span></td>
|
||||
<td>{{ row.stock ?? '—' }}</td>
|
||||
<td>
|
||||
<button type="button" class="admin-btn admin-btn--primary admin-btn--sm" @click="notify(row.id)">ارسال اعلان</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.admin-page__head { margin-bottom: 20px; }
|
||||
.admin-page__head h1 { margin: 0 0 4px; font-size: 1.25rem; }
|
||||
.admin-page__head p { margin: 0; color: var(--color-text-muted); font-size: 0.875rem; }
|
||||
.admin-table { width: 100%; border-collapse: collapse; }
|
||||
.admin-table th, .admin-table td { text-align: right; padding: 10px 8px; border-bottom: 1px solid var(--color-border); }
|
||||
.muted { color: var(--color-text-muted); font-size: 0.75rem; margin-right: 6px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user