This commit is contained in:
2026-09-13 15:36:48 +03:30
parent d6e424137d
commit d02c27fef4
98 changed files with 1886 additions and 234 deletions
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{A as e,D as t,I as n,J as r,L as i,N as a,R as o,Tt as s,X as c,_ as l,et as u,j as d,k as f,n as p,nt as m,pt as ee,t as h,xt as g}from"./BasicIcon-B6lR-mG3.js";import{i as te,n as ne}from"./format-BHJptHdF.js";import{t as re}from"./catalog-DNpqlweh.js";import{g as ie,n as _}from"./index-DDi4iM2C.js";import{t as ae}from"./PageHeader-COmjOmby.js";import{t as oe}from"./useRequirePricedOrder-CgVrKOPu.js";var v=o({__name:`IconSuccessCircle`,props:{size:{default:24},strokeWidth:{default:1.5},color:{default:null}},setup(e){return(t,n)=>(r(),d(h,{icon:`vuesax-linear:tick-circle`,size:e.size,"stroke-width":e.strokeWidth,color:e.color},null,8,[`size`,`stroke-width`,`color`]))}}),se={class:`page cash-mobile-page mobile-only`},ce={class:`cash-page__scroll page__scroll`},le={class:`cash-page__success cash-page__success--done`},ue={class:`cash-page__success-title`},y={class:`cash-page__success-subtitle`},b={class:`accounts-panel`},x={class:`accounts-panel__title`},S={class:`bank-card__head`},C={class:`bank-card__name`},w={class:`bank-card__icon`,"aria-hidden":`true`},T={class:`bank-card__field`},E={class:`bank-card__value`,dir:`ltr`},D={class:`bank-card__field`},O={class:`bank-card__value`,dir:`ltr`},k={class:`cash-page__footer`},A={class:`desktop-checkout-shell cash-desktop-page desktop-only`},j={class:`desktop-page__head`},M={class:`desktop-page__subtitle`},N={class:`cash-page__success cash-page__success--done`},P={class:`cash-page__success-title`},de={class:`accounts-panel`},F={class:`accounts-panel__title`},I={class:`desktop-grid-2`},L={class:`bank-card__head`},R={class:`bank-card__name`},z={class:`bank-card__icon`,"aria-hidden":`true`},B={class:`bank-card__field`},V={class:`bank-card__value`,dir:`ltr`},H={class:`bank-card__field`},fe={class:`bank-card__value`,dir:`ltr`},pe={class:`cash-desktop-page__actions`},U=p(o({__name:`CashSettlementView`,setup(o){let d=l(),p=ie(),h=re(),U=ee([]),{orderId:W,order:G}=oe(),K=f(()=>G.value?.companyName??``);u(W,async e=>{e&&!p.getOrderById(e)&&await p.fetchOrder(e)},{immediate:!0}),u(()=>G.value?.id,async e=>{if(!e||!G.value){U.value=[];return}h.companies.length||await h.loadCompanies(),U.value=await p.getBankAccountsForOrder(G.value)},{immediate:!0});let q=f(()=>G.value?.finalAmount?ne(G.value.finalAmount):`—`),J=f(()=>{let e=G.value?.cashInvoiceExpiresAt;return e?`مهلت پرداخت این فاکتور تا ${te(e)} است.`:`مبلغ فاکتور را به یکی از حساب‌های زیر واریز و رسید را ثبت کنید.`}),Y=f(()=>{let e=K.value.replace(/^شرکت\s+/u,``);return e?`شماره حساب‌های واریز — ${e}`:`شماره حساب‌های واریز`});function X(e){return e.replace(/\D/g,``).replace(/(\d{4})(?=\d)/g,`$1 `).trim()}function Z(e){return e.replace(/\s/g,``).toUpperCase().replace(/(.{4})/g,`$1 `).trim()}function Q(){d.replace(`/orders/${W.value}?track=1`)}function $(){d.replace(`/orders/${W.value}?track=1&receipt=1`)}return(o,l)=>(r(),a(t,null,[e(`div`,se,[i(ae,{title:`تسویه نقدی`,"show-back":``,centered:``,onBack:l[0]||=e=>g(d).push(`/orders/${g(W)}`)}),e(`div`,ce,[e(`div`,le,[i(v,{size:56}),e(`p`,ue,`مبلغ قابل پرداخت `+s(q.value),1),e(`p`,y,s(J.value),1)]),e(`section`,b,[e(`h2`,x,s(Y.value),1),(r(!0),a(t,null,c(U.value,t=>(r(),a(`article`,{key:t.id,class:`bank-card`},[e(`div`,S,[e(`span`,C,s(t.bankName),1),e(`span`,w,s(t.bankName.charAt(0)),1)]),e(`div`,T,[l[1]||=e(`span`,{class:`bank-card__label`},`شماره کارت`,-1),e(`strong`,E,s(X(t.cardNumber)),1)]),e(`div`,D,[l[2]||=e(`span`,{class:`bank-card__label`},`شماره شبا`,-1),e(`strong`,O,s(Z(t.iban)),1)])]))),128))])]),e(`div`,k,[i(_,{variant:`outline`,block:``,onClick:Q},{default:m(()=>[...l[3]||=[n(`مشاهده سفارش`,-1)]]),_:1}),i(_,{block:``,class:`cash-page__submit`,onClick:$},{default:m(()=>[...l[4]||=[n(` ثبت رسید پرداخت `,-1)]]),_:1})])]),e(`div`,A,[e(`header`,j,[l[5]||=e(`h1`,{class:`desktop-page__title`},`تسویه نقدی`,-1),e(`p`,M,s(J.value),1)]),e(`div`,N,[i(v,{size:56}),e(`p`,P,`مبلغ قابل پرداخت `+s(q.value),1)]),e(`section`,de,[e(`h2`,F,s(Y.value),1),e(`div`,I,[(r(!0),a(t,null,c(U.value,t=>(r(),a(`article`,{key:t.id,class:`bank-card`},[e(`div`,L,[e(`span`,R,s(t.bankName),1),e(`span`,z,s(t.bankName.charAt(0)),1)]),e(`div`,B,[l[6]||=e(`span`,{class:`bank-card__label`},`شماره کارت`,-1),e(`strong`,V,s(X(t.cardNumber)),1)]),e(`div`,H,[l[7]||=e(`span`,{class:`bank-card__label`},`شماره شبا`,-1),e(`strong`,fe,s(Z(t.iban)),1)])]))),128))])]),e(`div`,pe,[i(_,{variant:`outline`,class:`desktop-btn-compact`,onClick:Q},{default:m(()=>[...l[8]||=[n(` مشاهده سفارش `,-1)]]),_:1}),i(_,{class:`desktop-btn-compact`,onClick:$},{default:m(()=>[...l[9]||=[n(` ثبت رسید پرداخت `,-1)]]),_:1})])])],64))}}),[[`__scopeId`,`data-v-c299caf6`]]);export{U as default};
import{A as e,D as t,I as n,J as r,L as i,N as a,R as o,Tt as s,X as c,_ as l,et as u,j as d,k as f,n as p,nt as m,pt as ee,t as h,xt as g}from"./BasicIcon-B6lR-mG3.js";import{i as te,n as ne}from"./format-BHJptHdF.js";import{t as re}from"./catalog-DNpqlweh.js";import{g as ie,n as _}from"./index-DXso6ia7.js";import{t as ae}from"./PageHeader-Dzrx58_B.js";import{t as oe}from"./useRequirePricedOrder-BHwPSld8.js";var v=o({__name:`IconSuccessCircle`,props:{size:{default:24},strokeWidth:{default:1.5},color:{default:null}},setup(e){return(t,n)=>(r(),d(h,{icon:`vuesax-linear:tick-circle`,size:e.size,"stroke-width":e.strokeWidth,color:e.color},null,8,[`size`,`stroke-width`,`color`]))}}),se={class:`page cash-mobile-page mobile-only`},ce={class:`cash-page__scroll page__scroll`},le={class:`cash-page__success cash-page__success--done`},ue={class:`cash-page__success-title`},y={class:`cash-page__success-subtitle`},b={class:`accounts-panel`},x={class:`accounts-panel__title`},S={class:`bank-card__head`},C={class:`bank-card__name`},w={class:`bank-card__icon`,"aria-hidden":`true`},T={class:`bank-card__field`},E={class:`bank-card__value`,dir:`ltr`},D={class:`bank-card__field`},O={class:`bank-card__value`,dir:`ltr`},k={class:`cash-page__footer`},A={class:`desktop-checkout-shell cash-desktop-page desktop-only`},j={class:`desktop-page__head`},M={class:`desktop-page__subtitle`},N={class:`cash-page__success cash-page__success--done`},P={class:`cash-page__success-title`},de={class:`accounts-panel`},F={class:`accounts-panel__title`},I={class:`desktop-grid-2`},L={class:`bank-card__head`},R={class:`bank-card__name`},z={class:`bank-card__icon`,"aria-hidden":`true`},B={class:`bank-card__field`},V={class:`bank-card__value`,dir:`ltr`},H={class:`bank-card__field`},fe={class:`bank-card__value`,dir:`ltr`},pe={class:`cash-desktop-page__actions`},U=p(o({__name:`CashSettlementView`,setup(o){let d=l(),p=ie(),h=re(),U=ee([]),{orderId:W,order:G}=oe(),K=f(()=>G.value?.companyName??``);u(W,async e=>{e&&!p.getOrderById(e)&&await p.fetchOrder(e)},{immediate:!0}),u(()=>G.value?.id,async e=>{if(!e||!G.value){U.value=[];return}h.companies.length||await h.loadCompanies(),U.value=await p.getBankAccountsForOrder(G.value)},{immediate:!0});let q=f(()=>G.value?.finalAmount?ne(G.value.finalAmount):`—`),J=f(()=>{let e=G.value?.cashInvoiceExpiresAt;return e?`مهلت پرداخت این فاکتور تا ${te(e)} است.`:`مبلغ فاکتور را به یکی از حساب‌های زیر واریز و رسید را ثبت کنید.`}),Y=f(()=>{let e=K.value.replace(/^شرکت\s+/u,``);return e?`شماره حساب‌های واریز — ${e}`:`شماره حساب‌های واریز`});function X(e){return e.replace(/\D/g,``).replace(/(\d{4})(?=\d)/g,`$1 `).trim()}function Z(e){return e.replace(/\s/g,``).toUpperCase().replace(/(.{4})/g,`$1 `).trim()}function Q(){d.replace(`/orders/${W.value}?track=1`)}function $(){d.replace(`/orders/${W.value}?track=1&receipt=1`)}return(o,l)=>(r(),a(t,null,[e(`div`,se,[i(ae,{title:`تسویه نقدی`,"show-back":``,centered:``,onBack:l[0]||=e=>g(d).push(`/orders/${g(W)}`)}),e(`div`,ce,[e(`div`,le,[i(v,{size:56}),e(`p`,ue,`مبلغ قابل پرداخت `+s(q.value),1),e(`p`,y,s(J.value),1)]),e(`section`,b,[e(`h2`,x,s(Y.value),1),(r(!0),a(t,null,c(U.value,t=>(r(),a(`article`,{key:t.id,class:`bank-card`},[e(`div`,S,[e(`span`,C,s(t.bankName),1),e(`span`,w,s(t.bankName.charAt(0)),1)]),e(`div`,T,[l[1]||=e(`span`,{class:`bank-card__label`},`شماره کارت`,-1),e(`strong`,E,s(X(t.cardNumber)),1)]),e(`div`,D,[l[2]||=e(`span`,{class:`bank-card__label`},`شماره شبا`,-1),e(`strong`,O,s(Z(t.iban)),1)])]))),128))])]),e(`div`,k,[i(_,{variant:`outline`,block:``,onClick:Q},{default:m(()=>[...l[3]||=[n(`مشاهده سفارش`,-1)]]),_:1}),i(_,{block:``,class:`cash-page__submit`,onClick:$},{default:m(()=>[...l[4]||=[n(` ثبت رسید پرداخت `,-1)]]),_:1})])]),e(`div`,A,[e(`header`,j,[l[5]||=e(`h1`,{class:`desktop-page__title`},`تسویه نقدی`,-1),e(`p`,M,s(J.value),1)]),e(`div`,N,[i(v,{size:56}),e(`p`,P,`مبلغ قابل پرداخت `+s(q.value),1)]),e(`section`,de,[e(`h2`,F,s(Y.value),1),e(`div`,I,[(r(!0),a(t,null,c(U.value,t=>(r(),a(`article`,{key:t.id,class:`bank-card`},[e(`div`,L,[e(`span`,R,s(t.bankName),1),e(`span`,z,s(t.bankName.charAt(0)),1)]),e(`div`,B,[l[6]||=e(`span`,{class:`bank-card__label`},`شماره کارت`,-1),e(`strong`,V,s(X(t.cardNumber)),1)]),e(`div`,H,[l[7]||=e(`span`,{class:`bank-card__label`},`شماره شبا`,-1),e(`strong`,fe,s(Z(t.iban)),1)])]))),128))])]),e(`div`,pe,[i(_,{variant:`outline`,class:`desktop-btn-compact`,onClick:Q},{default:m(()=>[...l[8]||=[n(` مشاهده سفارش `,-1)]]),_:1}),i(_,{class:`desktop-btn-compact`,onClick:$},{default:m(()=>[...l[9]||=[n(` ثبت رسید پرداخت `,-1)]]),_:1})])])],64))}}),[[`__scopeId`,`data-v-c299caf6`]]);export{U as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{A as e,D as t,J as n,K as r,L as i,N as a,R as o,Tt as s,X as c,_ as l,et as u,g as d,j as f,k as p,n as m,pt as h,xt as g}from"./BasicIcon-B6lR-mG3.js";import{t as _}from"./catalog-DNpqlweh.js";import{x as v}from"./index-DXso6ia7.js";import{t as y}from"./EmptyState-C6UAJ5_3.js";import{t as b}from"./PageSkeleton-BImjuI6S.js";import{t as x}from"./PageHeader-Dzrx58_B.js";import{t as S}from"./SearchField-txVsGGXT.js";var C={class:`page catalog-mobile-page mobile-only`},w={class:`page__scroll page__scroll--with-nav catalog-mobile-scroll`},T={key:1,class:`catalog-mobile-list`},E=[`onClick`],D={class:`catalog-card__icon`},O={class:`catalog-card__info`},k={class:`catalog-card__count`},A={class:`desktop-page catalog-desktop-page desktop-only`},j={class:`desktop-page__head`},M={class:`desktop-page__title`},N={key:0,class:`desktop-grid-3`},P=[`onClick`],F={class:`catalog-card__icon`},I={class:`catalog-card__info`},L={class:`catalog-card__count`},R=m(o({__name:`CatalogListView`,setup(o){let m=d(),R=l(),z=_(),B=h(!0),V=p(()=>m.params.companyId),H=p(()=>z.getCompany(V.value)),U=h(``),W=p(()=>z.fetchCatalogs(V.value,U.value));async function G(){B.value=!0,z.getCompany(V.value)||await z.loadCompanies(),await z.loadCatalogs(V.value),B.value=!1}r(G),u(V,G);function K(e){R.push({name:`catalog-detail`,params:{catalogId:e}})}function q(e){let t=z.getCatalog(e);return t?.productCount==null?z.fetchProducts(e).length:t.productCount}return(r,o)=>(n(),a(t,null,[e(`div`,C,[i(x,{title:H.value?.name??`کالیته‌ها`,subtitle:`کالیته مورد نظر را انتخاب کنید`,"show-back":``,centered:``,onBack:o[0]||=e=>g(R).push(`/`)},null,8,[`title`]),i(S,{modelValue:U.value,"onUpdate:modelValue":o[1]||=e=>U.value=e,placeholder:`جستجو بر اساس کد یا نام کالیته...`,class:`catalog-page__search`},null,8,[`modelValue`]),e(`div`,w,[B.value?(n(),f(b,{key:0,variant:`cards`,rows:5})):W.value.length>0?(n(),a(`div`,T,[(n(!0),a(t,null,c(W.value,t=>(n(),a(`button`,{key:t.id,type:`button`,class:`catalog-card`,onClick:e=>K(t.id)},[e(`span`,D,[i(v,{size:22})]),e(`div`,O,[e(`h3`,null,`کالیته کد `+s(t.code),1),e(`p`,null,s(t.name),1)]),e(`span`,k,s(q(t.id))+` محصول`,1)],8,E))),128))])):(n(),f(y,{key:2,variant:U.value?`search`:`catalogs`,message:U.value?`با این جستجو کالیته‌ای پیدا نشد`:`برای این شرکت هنوز کالیته‌ای ثبت نشده است`},null,8,[`variant`,`message`]))])]),e(`div`,A,[e(`header`,j,[e(`h1`,M,s(H.value?.name??`کالیته‌ها`),1),o[3]||=e(`p`,{class:`desktop-page__subtitle`},`کالیته مورد نظر را انتخاب کنید`,-1)]),i(S,{modelValue:U.value,"onUpdate:modelValue":o[2]||=e=>U.value=e,placeholder:`جستجو بر اساس کد یا نام کالیته...`,class:`catalog-page__search`},null,8,[`modelValue`]),W.value.length>0?(n(),a(`div`,N,[(n(!0),a(t,null,c(W.value,t=>(n(),a(`button`,{key:t.id,type:`button`,class:`catalog-card catalog-card--desktop`,onClick:e=>K(t.id)},[e(`span`,F,[i(v,{size:24})]),e(`div`,I,[e(`h3`,null,`کالیته کد `+s(t.code),1),e(`p`,null,s(t.name),1)]),e(`span`,L,s(q(t.id))+` محصول`,1)],8,P))),128))])):(n(),f(y,{key:1,variant:U.value?`search`:`catalogs`,message:U.value?`با این جستجو کالیته‌ای پیدا نشد`:`برای این شرکت هنوز کالیته‌ای ثبت نشده است`},null,8,[`variant`,`message`]))])],64))}}),[[`__scopeId`,`data-v-986a9367`]]);export{R as default};
+1
View File
@@ -0,0 +1 @@
.catalog-mobile-page[data-v-986a9367]{background:var(--color-bg);color:var(--color-text);padding:12px 0 0}.catalog-page__search[data-v-986a9367]{margin-bottom:16px}.catalog-mobile-scroll[data-v-986a9367]{flex-direction:column;flex:1;min-height:0;display:flex}.catalog-mobile-list[data-v-986a9367]{flex-direction:column;gap:12px;display:flex}.catalog-card[data-v-986a9367]{border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-elevated);width:100%;box-shadow:var(--shadow-sm);color:var(--color-text);text-align:right;cursor:pointer;align-items:center;gap:12px;padding:14px 16px;display:flex}.catalog-card--desktop[data-v-986a9367]{flex-direction:column;align-items:flex-start;min-height:140px;padding:20px}.catalog-card[data-v-986a9367]:hover{border-color:var(--color-primary);box-shadow:var(--shadow-md)}.catalog-card__icon[data-v-986a9367]{background:var(--color-primary-light);border-radius:var(--radius-sm);width:40px;height:40px;color:var(--color-primary);justify-content:center;align-items:center;display:flex}.catalog-card__info[data-v-986a9367]{flex:1}.catalog-card__info h3[data-v-986a9367]{color:var(--color-text);margin:0 0 4px;font-size:.9375rem}.catalog-card__info p[data-v-986a9367]{color:var(--color-text-muted);margin:0;font-size:.8125rem}.catalog-card__count[data-v-986a9367]{color:var(--color-primary);font-size:.8125rem;font-weight:600}
-1
View File
@@ -1 +0,0 @@
import{A as e,D as t,J as n,K as r,L as i,N as a,R as o,Tt as s,X as c,_ as l,et as u,g as d,j as f,k as p,n as m,pt as h,xt as g}from"./BasicIcon-B6lR-mG3.js";import{t as _}from"./catalog-DNpqlweh.js";import{x as v}from"./index-DDi4iM2C.js";import{t as y}from"./EmptyState-C6UAJ5_3.js";import{t as b}from"./PageHeader-COmjOmby.js";import{t as x}from"./SearchField-txVsGGXT.js";import{t as S}from"./PageSkeleton-BImjuI6S.js";var C={class:`page catalog-mobile-page mobile-only`},w={class:`page__scroll page__scroll--with-nav catalog-mobile-scroll`},T={key:1,class:`catalog-mobile-list`},E=[`onClick`],D={class:`catalog-card__icon`},O={class:`catalog-card__info`},k={class:`catalog-card__count`},A={class:`desktop-page catalog-desktop-page desktop-only`},j={class:`desktop-page__head`},M={class:`desktop-page__title`},N={key:0,class:`desktop-grid-3`},P=[`onClick`],F={class:`catalog-card__icon`},I={class:`catalog-card__info`},L={class:`catalog-card__count`},R=m(o({__name:`CatalogListView`,setup(o){let m=d(),R=l(),z=_(),B=h(!0),V=p(()=>m.params.companyId),H=p(()=>z.getCompany(V.value)),U=h(``),W=p(()=>z.fetchCatalogs(V.value,U.value));async function G(){B.value=!0,z.getCompany(V.value)||await z.loadCompanies(),await z.loadCatalogs(V.value),B.value=!1}r(G),u(V,G);function K(e){R.push({path:`/products`,query:{catalogId:e,companyId:V.value}})}function q(e){let t=z.getCatalog(e);return t?.productCount==null?z.fetchProducts(e).length:t.productCount}return(r,o)=>(n(),a(t,null,[e(`div`,C,[i(b,{title:H.value?.name??`کالیته‌ها`,subtitle:`کالیته مورد نظر را انتخاب کنید`,"show-back":``,centered:``,onBack:o[0]||=e=>g(R).push(`/`)},null,8,[`title`]),i(x,{modelValue:U.value,"onUpdate:modelValue":o[1]||=e=>U.value=e,placeholder:`جستجو بر اساس کد یا نام کالیته...`,class:`catalog-page__search`},null,8,[`modelValue`]),e(`div`,w,[B.value?(n(),f(S,{key:0,variant:`cards`,rows:5})):W.value.length>0?(n(),a(`div`,T,[(n(!0),a(t,null,c(W.value,t=>(n(),a(`button`,{key:t.id,type:`button`,class:`catalog-card`,onClick:e=>K(t.id)},[e(`span`,D,[i(v,{size:22})]),e(`div`,O,[e(`h3`,null,`کالیته کد `+s(t.code),1),e(`p`,null,s(t.name),1)]),e(`span`,k,s(q(t.id))+` محصول`,1)],8,E))),128))])):(n(),f(y,{key:2,variant:U.value?`search`:`catalogs`,message:U.value?`با این جستجو کالیته‌ای پیدا نشد`:`برای این شرکت هنوز کالیته‌ای ثبت نشده است`},null,8,[`variant`,`message`]))])]),e(`div`,A,[e(`header`,j,[e(`h1`,M,s(H.value?.name??`کالیته‌ها`),1),o[3]||=e(`p`,{class:`desktop-page__subtitle`},`کالیته مورد نظر را انتخاب کنید`,-1)]),i(x,{modelValue:U.value,"onUpdate:modelValue":o[2]||=e=>U.value=e,placeholder:`جستجو بر اساس کد یا نام کالیته...`,class:`catalog-page__search`},null,8,[`modelValue`]),W.value.length>0?(n(),a(`div`,N,[(n(!0),a(t,null,c(W.value,t=>(n(),a(`button`,{key:t.id,type:`button`,class:`catalog-card catalog-card--desktop`,onClick:e=>K(t.id)},[e(`span`,F,[i(v,{size:24})]),e(`div`,I,[e(`h3`,null,`کالیته کد `+s(t.code),1),e(`p`,null,s(t.name),1)]),e(`span`,L,s(q(t.id))+` محصول`,1)],8,P))),128))])):(n(),f(y,{key:1,variant:U.value?`search`:`catalogs`,message:U.value?`با این جستجو کالیته‌ای پیدا نشد`:`برای این شرکت هنوز کالیته‌ای ثبت نشده است`},null,8,[`variant`,`message`]))])],64))}}),[[`__scopeId`,`data-v-fa6b4c3f`]]);export{R as default};
-1
View File
@@ -1 +0,0 @@
.catalog-mobile-page[data-v-fa6b4c3f]{background:var(--color-bg);color:var(--color-text);padding:12px 0 0}.catalog-page__search[data-v-fa6b4c3f]{margin-bottom:16px}.catalog-mobile-scroll[data-v-fa6b4c3f]{flex-direction:column;flex:1;min-height:0;display:flex}.catalog-mobile-list[data-v-fa6b4c3f]{flex-direction:column;gap:12px;display:flex}.catalog-card[data-v-fa6b4c3f]{border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-elevated);width:100%;box-shadow:var(--shadow-sm);color:var(--color-text);text-align:right;cursor:pointer;align-items:center;gap:12px;padding:14px 16px;display:flex}.catalog-card--desktop[data-v-fa6b4c3f]{flex-direction:column;align-items:flex-start;min-height:140px;padding:20px}.catalog-card[data-v-fa6b4c3f]:hover{border-color:var(--color-primary);box-shadow:var(--shadow-md)}.catalog-card__icon[data-v-fa6b4c3f]{background:var(--color-primary-light);border-radius:var(--radius-sm);width:40px;height:40px;color:var(--color-primary);justify-content:center;align-items:center;display:flex}.catalog-card__info[data-v-fa6b4c3f]{flex:1}.catalog-card__info h3[data-v-fa6b4c3f]{color:var(--color-text);margin:0 0 4px;font-size:.9375rem}.catalog-card__info p[data-v-fa6b4c3f]{color:var(--color-text-muted);margin:0;font-size:.8125rem}.catalog-card__count[data-v-fa6b4c3f]{color:var(--color-primary);font-size:.8125rem;font-weight:600}
+1
View File
@@ -0,0 +1 @@
.body[data-v-6bde0457]{padding:12px var(--page-padding) 24px;flex-direction:column;gap:10px;display:flex}.hint[data-v-6bde0457]{color:var(--color-text-muted);margin:0;font-size:.85rem}.error[data-v-6bde0457]{color:#b42318}.row[data-v-6bde0457]{background:var(--color-surface);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);justify-content:space-between;align-items:center;gap:12px;padding:12px;display:flex}.row--selected[data-v-6bde0457]{outline:2px solid var(--color-primary)}.row strong[data-v-6bde0457]{font-size:.9rem;display:block}.row span[data-v-6bde0457]{color:var(--color-text-muted);font-size:.78rem}.qty[data-v-6bde0457]{border:1px solid var(--color-border);text-align:center;width:64px;height:40px;font:inherit;background:var(--color-bg);color:var(--color-text);border-radius:10px}.note[data-v-6bde0457]{color:var(--color-text-muted);flex-direction:column;gap:6px;font-size:.85rem;display:flex}.note textarea[data-v-6bde0457]{border:1px solid var(--color-border);font:inherit;resize:vertical;background:var(--color-surface);color:var(--color-text);border-radius:12px;padding:10px 12px}.summary[data-v-6bde0457]{color:var(--color-text-muted);margin:4px 0 0;font-size:.85rem}.submit[data-v-6bde0457]{background:var(--color-primary);color:#fff;cursor:pointer;border:none;border-radius:12px;min-height:48px;font-weight:700}.submit[data-v-6bde0457]:disabled{opacity:.7}.linkish[data-v-6bde0457]{color:var(--color-primary);cursor:pointer;background:0 0;border:none;padding:8px;font-weight:700}
-1
View File
@@ -1 +0,0 @@
.body[data-v-74250a20]{padding:12px var(--page-padding) 24px;flex-direction:column;gap:10px;display:flex}.hint[data-v-74250a20]{color:var(--color-text-muted);margin:0;font-size:.85rem}.error[data-v-74250a20]{color:#b42318}.row[data-v-74250a20]{background:var(--color-surface);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);justify-content:space-between;align-items:center;gap:12px;padding:12px;display:flex}.row--selected[data-v-74250a20]{outline:2px solid var(--color-primary)}.row strong[data-v-74250a20]{font-size:.9rem;display:block}.row span[data-v-74250a20]{color:var(--color-text-muted);font-size:.78rem}.qty[data-v-74250a20]{border:1px solid var(--color-border);text-align:center;width:64px;height:40px;font:inherit;background:var(--color-bg);color:var(--color-text);border-radius:10px}.note[data-v-74250a20]{color:var(--color-text-muted);flex-direction:column;gap:6px;font-size:.85rem;display:flex}.note textarea[data-v-74250a20]{border:1px solid var(--color-border);font:inherit;resize:vertical;background:var(--color-surface);color:var(--color-text);border-radius:12px;padding:10px 12px}.summary[data-v-74250a20]{color:var(--color-text-muted);margin:4px 0 0;font-size:.85rem}.submit[data-v-74250a20]{background:var(--color-primary);color:#fff;cursor:pointer;border:none;border-radius:12px;min-height:48px;font-weight:700}.submit[data-v-74250a20]:disabled{opacity:.7}.linkish[data-v-74250a20]{color:var(--color-primary);cursor:pointer;background:0 0;border:none;padding:8px;font-weight:700}
-1
View File
@@ -1 +0,0 @@
import{A as e,C as t,D as n,I as r,J as i,K as a,L as o,N as s,R as c,St as l,Tt as u,X as d,_ as f,g as p,j as m,k as h,n as g,pt as _,rt as v,xt as y}from"./BasicIcon-B6lR-mG3.js";import{o as b}from"./format-BHJptHdF.js";import{t as x}from"./PageHeader-COmjOmby.js";import{t as S}from"./PageSkeleton-BImjuI6S.js";import{t as C}from"./crm-DbcoqKAF.js";import{t as w}from"./catalogRequests-4v_wDAbs.js";var T={class:`page`},E={class:`page__scroll page__scroll--with-nav body`},D={class:`hint`},O={key:1,class:`error`},k=[`value`,`onInput`],A={class:`note`},j={class:`summary`},M=[`disabled`],N=g(c({__name:`CatalogRequestView`,setup(c){let g=p(),N=f(),P=C(),F=w(),I=_(!0),L=_(!1),R=_(null),z=_(``),B=_([]),V=_({}),H=h(()=>String(g.query.productId??``)),U=h(()=>B.value.filter(e=>(V.value[e.id]??0)>0).map(e=>({productId:e.id,productName:e.name,productCode:e.code,quantity:V.value[e.id]??0})));a(async()=>{I.value=!0,R.value=null;try{let e=await P.loadBrowseProducts(),t=H.value;B.value=t?[...e].sort((e,n)=>Number(n.id===t)-Number(e.id===t)):e,t&&(V.value={...V.value,[t]:1})}catch(e){R.value=e instanceof Error?e.message:`بارگذاری محصولات ناموفق بود.`}finally{I.value=!1}});function W(e,t){V.value={...V.value,[e]:Math.max(0,Math.floor(t)||0)}}async function G(){L.value=!0,R.value=null;try{let e=await F.create({items:U.value,note:z.value});if(!e.success){R.value=e.message;return}N.push(`/catalog-requests`)}finally{L.value=!1}}return(a,c)=>(i(),s(`div`,T,[o(x,{title:`درخواست کالیته`,"show-back":``,centered:``,onBack:c[0]||=e=>y(N).back()}),e(`div`,E,[e(`p`,D,u(H.value?`این محصول برای درخواست کالیته انتخاب شده است. در صورت نیاز اقلام دیگر را هم اضافه کنید.`:`محصولات و تعداد اقلام موردنظر را مشخص کنید.`),1),I.value?(i(),m(S,{key:0,variant:`form`})):R.value?(i(),s(`p`,O,u(R.value),1)):(i(),s(n,{key:2},[(i(!0),s(n,null,d(B.value,t=>(i(),s(`article`,{key:t.id,class:l([`row`,{"row--selected":H.value===t.id}])},[e(`div`,null,[e(`strong`,null,u(t.name),1),e(`span`,null,`کد `+u(t.code),1)]),e(`input`,{class:`qty`,type:`number`,min:`0`,value:V.value[t.id]??0,onInput:e=>W(t.id,Number(e.target.value))},null,40,k)],2))),128)),e(`label`,A,[c[3]||=r(` توضیحات `,-1),v(e(`textarea`,{"onUpdate:modelValue":c[1]||=e=>z.value=e,rows:`3`,placeholder:`آدرس یا توضیحات اختیاری`},null,512),[[t,z.value]])]),e(`p`,j,`اقلام انتخاب‌شده: `+u(y(b)(U.value.length)),1),e(`button`,{type:`button`,class:`submit`,disabled:L.value,onClick:G},u(L.value?`در حال ثبت...`:`ثبت درخواست کالیته`),9,M),e(`button`,{type:`button`,class:`linkish`,onClick:c[2]||=e=>y(N).push(`/catalog-requests`)},` وضعیت درخواست‌های قبلی `)],64))])]))}}),[[`__scopeId`,`data-v-74250a20`]]);export{N as default};
+1
View File
@@ -0,0 +1 @@
import{A as e,C as t,D as n,I as r,J as i,K as a,L as o,N as s,R as c,St as l,Tt as u,X as d,_ as f,g as p,j as m,k as h,n as g,pt as _,rt as v,xt as y}from"./BasicIcon-B6lR-mG3.js";import{o as b}from"./format-BHJptHdF.js";import{t as x}from"./PageSkeleton-BImjuI6S.js";import{t as S}from"./crm-DbcoqKAF.js";import{t as C}from"./PageHeader-Dzrx58_B.js";import{t as w}from"./catalogRequests-4v_wDAbs.js";var T={class:`page`},E={class:`page__scroll page__scroll--with-nav body`},D={class:`hint`},O={key:1,class:`error`},k=[`value`,`onInput`],A={class:`note`},j={class:`summary`},M=[`disabled`],N=g(c({__name:`CatalogRequestView`,setup(c){let g=p(),N=f(),P=S(),F=w(),I=_(!0),L=_(!1),R=_(null),z=_(``),B=_([]),V=_({}),H=h(()=>String(g.query.productId??``)),U=h(()=>String(g.query.catalogId??``)),W=h(()=>B.value.filter(e=>(V.value[e.id]??0)>0).map(e=>({productId:e.id,productName:e.name,productCode:e.code,quantity:V.value[e.id]??0})));a(async()=>{I.value=!0,R.value=null;try{let e=await P.loadBrowseProducts(U.value?{catalogId:U.value}:void 0),t=H.value;B.value=t?[...e].sort((e,n)=>Number(n.id===t)-Number(e.id===t)):e,t&&(V.value={...V.value,[t]:1})}catch(e){R.value=e instanceof Error?e.message:`بارگذاری محصولات ناموفق بود.`}finally{I.value=!1}});function G(e,t){V.value={...V.value,[e]:Math.max(0,Math.floor(t)||0)}}async function K(){L.value=!0,R.value=null;try{let e=await F.create({items:W.value,note:z.value});if(!e.success){R.value=e.message;return}N.push(`/catalog-requests`)}finally{L.value=!1}}return(a,c)=>(i(),s(`div`,T,[o(C,{title:`درخواست کالیته`,"show-back":``,centered:``,onBack:c[0]||=e=>y(N).back()}),e(`div`,E,[e(`p`,D,u(H.value?`این محصول برای درخواست کالیته انتخاب شده است. در صورت نیاز اقلام دیگر را هم اضافه کنید.`:`محصولات و تعداد اقلام موردنظر را مشخص کنید.`),1),I.value?(i(),m(x,{key:0,variant:`form`})):R.value?(i(),s(`p`,O,u(R.value),1)):(i(),s(n,{key:2},[(i(!0),s(n,null,d(B.value,t=>(i(),s(`article`,{key:t.id,class:l([`row`,{"row--selected":H.value===t.id}])},[e(`div`,null,[e(`strong`,null,u(t.name),1),e(`span`,null,`کد `+u(t.code),1)]),e(`input`,{class:`qty`,type:`number`,min:`0`,value:V.value[t.id]??0,onInput:e=>G(t.id,Number(e.target.value))},null,40,k)],2))),128)),e(`label`,A,[c[3]||=r(` توضیحات `,-1),v(e(`textarea`,{"onUpdate:modelValue":c[1]||=e=>z.value=e,rows:`3`,placeholder:`آدرس یا توضیحات اختیاری`},null,512),[[t,z.value]])]),e(`p`,j,`اقلام انتخاب‌شده: `+u(y(b)(W.value.length)),1),e(`button`,{type:`button`,class:`submit`,disabled:L.value,onClick:K},u(L.value?`در حال ثبت...`:`ثبت درخواست کالیته`),9,M),e(`button`,{type:`button`,class:`linkish`,onClick:c[2]||=e=>y(N).push(`/catalog-requests`)},` وضعیت درخواست‌های قبلی `)],64))])]))}}),[[`__scopeId`,`data-v-6bde0457`]]);export{N as default};
@@ -1 +1 @@
import{A as e,D as t,J as n,K as r,L as i,M as a,N as o,R as s,Tt as c,X as l,_ as u,n as d,xt as f}from"./BasicIcon-B6lR-mG3.js";import{o as p}from"./format-BHJptHdF.js";import{t as m}from"./PageHeader-COmjOmby.js";import{t as h}from"./catalogRequests-4v_wDAbs.js";var g={class:`page`},_={class:`page__scroll page__scroll--with-nav body`},v={key:0,class:`empty`},y={class:`card__top`},b={class:`badge`},x={key:0,class:`note`},S=d(s({__name:`CatalogRequestsView`,setup(s){let d=u(),S=h();return r(()=>S.hydrate()),(r,s)=>(n(),o(`div`,g,[i(m,{title:`وضعیت کالیته‌ها`,"show-back":``,centered:``,onBack:s[0]||=e=>f(d).push(`/catalogs`)}),e(`div`,_,[e(`button`,{type:`button`,class:`new-btn`,onClick:s[1]||=e=>f(d).push(`/catalog-request`)},` درخواست کالیته جدید `),f(S).sorted.length?a(``,!0):(n(),o(`p`,v,`هنوز درخواستی ثبت نکرده‌اید.`)),(n(!0),o(t,null,l(f(S).sorted,r=>(n(),o(`article`,{key:r.id,class:`card`},[e(`div`,y,[e(`strong`,null,`درخواست `+c(r.id.slice(-6)),1),e(`span`,b,c(f(S).statusLabel(r.status)),1)]),e(`p`,null,c(r.createdAt.slice(0,10)),1),e(`p`,null,c(f(p)(r.items.length))+` قلم`,1),e(`ul`,null,[(n(!0),o(t,null,l(r.items,e=>(n(),o(`li`,{key:e.productId},c(e.productName)+` × `+c(f(p)(e.quantity)),1))),128))]),r.note?(n(),o(`p`,x,c(r.note),1)):a(``,!0)]))),128))])]))}}),[[`__scopeId`,`data-v-fc04181d`]]);export{S as default};
import{A as e,D as t,J as n,K as r,L as i,M as a,N as o,R as s,Tt as c,X as l,_ as u,n as d,xt as f}from"./BasicIcon-B6lR-mG3.js";import{o as p}from"./format-BHJptHdF.js";import{t as m}from"./PageHeader-Dzrx58_B.js";import{t as h}from"./catalogRequests-4v_wDAbs.js";var g={class:`page`},_={class:`page__scroll page__scroll--with-nav body`},v={key:0,class:`empty`},y={class:`card__top`},b={class:`badge`},x={key:0,class:`note`},S=d(s({__name:`CatalogRequestsView`,setup(s){let d=u(),S=h();return r(()=>S.hydrate()),(r,s)=>(n(),o(`div`,g,[i(m,{title:`وضعیت کالیته‌ها`,"show-back":``,centered:``,onBack:s[0]||=e=>f(d).push(`/catalogs`)}),e(`div`,_,[e(`button`,{type:`button`,class:`new-btn`,onClick:s[1]||=e=>f(d).push(`/catalog-request`)},` درخواست کالیته جدید `),f(S).sorted.length?a(``,!0):(n(),o(`p`,v,`هنوز درخواستی ثبت نکرده‌اید.`)),(n(!0),o(t,null,l(f(S).sorted,r=>(n(),o(`article`,{key:r.id,class:`card`},[e(`div`,y,[e(`strong`,null,`درخواست `+c(r.id.slice(-6)),1),e(`span`,b,c(f(S).statusLabel(r.status)),1)]),e(`p`,null,c(r.createdAt.slice(0,10)),1),e(`p`,null,c(f(p)(r.items.length))+` قلم`,1),e(`ul`,null,[(n(!0),o(t,null,l(r.items,e=>(n(),o(`li`,{key:e.productId},c(e.productName)+` × `+c(f(p)(e.quantity)),1))),128))]),r.note?(n(),o(`p`,x,c(r.note),1)):a(``,!0)]))),128))])]))}}),[[`__scopeId`,`data-v-fc04181d`]]);export{S as default};
-1
View File
@@ -1 +0,0 @@
import{A as e,D as t,J as n,K as r,L as i,M as a,N as o,R as s,St as c,Tt as l,W as u,X as d,_ as f,g as p,j as m,n as h,pt as g,xt as _}from"./BasicIcon-B6lR-mG3.js";import{t as v}from"./catalog-DNpqlweh.js";import{o as y}from"./index-DDi4iM2C.js";import{t as b}from"./PageHeader-COmjOmby.js";import{t as x}from"./PageSkeleton-BImjuI6S.js";var S={class:`page`},C={class:`page__scroll page__scroll--with-nav catalog-hub`},w={key:1},T=[`onClick`],E={class:`calite-item__text`},D={key:0,class:`empty-hint`},O=h(s({__name:`CatalogsHubView`,setup(s){let h=p(),O=f(),k=v(),A=g([]),j=g(!0),M=g(null);r(async()=>{try{let e=await k.loadCompanies(),t=await Promise.all(e.map(e=>k.loadCatalogs(e.id)));A.value=t.flat();let n=String(h.query.id??``);if(n){let e=A.value.find(e=>e.id===n);e&&(await u(),N(e))}}catch(e){M.value=e instanceof Error?e.message:`بارگذاری کالیته‌ها ناموفق بود.`}finally{j.value=!1}});function N(e){O.push({path:`/products`,query:{catalogId:e.id,companyId:e.companyId}})}function P(e){return k.getCompany(e)?.name??`برند`}return(r,s)=>(n(),o(`div`,S,[i(b,{title:`کالیته‌ها`,"show-back":``,centered:``,onBack:s[0]||=e=>_(O).push(`/`)}),e(`div`,C,[e(`button`,{type:`button`,class:`hub-card`,onClick:s[1]||=e=>_(O).push(`/catalog-request`)},[...s[5]||=[e(`strong`,null,`درخواست کالیته فیزیکی`,-1),e(`span`,null,`ثبت اقلام و پیگیری وضعیت`,-1)]]),e(`button`,{type:`button`,class:`hub-card`,onClick:s[2]||=e=>_(O).push(`/catalog-requests`)},[...s[6]||=[e(`strong`,null,`وضعیت درخواست‌ها`,-1),e(`span`,null,`پیگیری کالیته‌های ثبت‌شده`,-1)]]),e(`button`,{type:`button`,class:`hub-card`,onClick:s[3]||=e=>_(O).push(`/categories`)},[...s[7]||=[e(`strong`,null,`مشاهده دسته‌بندی‌ها`,-1),e(`span`,null,`انتخاب بر اساس کاربرد و فصل`,-1)]]),e(`button`,{type:`button`,class:`hub-card`,onClick:s[4]||=e=>_(O).push(`/products`)},[...s[8]||=[e(`strong`,null,`همه محصولات`,-1),e(`span`,null,`مشاهده کاتالوگ و ثبت سفارش`,-1)]]),j.value?(n(),m(x,{key:0,variant:`grid`})):M.value?(n(),o(`p`,w,l(M.value),1)):(n(),o(t,{key:2},[s[9]||=e(`h2`,{class:`section-title`},`کالیته‌های موجود`,-1),(n(!0),o(t,null,d(A.value,t=>(n(),o(`button`,{key:t.id,type:`button`,class:c([`calite-item`,{"calite-item--focus":String(_(h).query.id??``)===t.id}]),onClick:e=>N(t)},[e(`div`,E,[e(`strong`,null,l(t.name),1),e(`span`,null,`کد `+l(t.code),1),e(`em`,null,l(P(t.companyId)),1)]),i(y,{size:18,color:`#9aa3a0`})],10,T))),128)),A.value.length?a(``,!0):(n(),o(`p`,D,`کالیته‌ای یافت نشد.`))],64))])]))}}),[[`__scopeId`,`data-v-a452107a`]]);export{O as default};
+1
View File
@@ -0,0 +1 @@
import{A as e,D as t,J as n,K as r,L as i,M as a,N as o,R as s,St as c,Tt as l,X as u,_ as d,g as f,j as p,k as m,n as h,pt as g,wt as _,xt as v}from"./BasicIcon-B6lR-mG3.js";import{o as y}from"./format-BHJptHdF.js";import{t as b}from"./catalog-DNpqlweh.js";import{i as x}from"./index-DXso6ia7.js";import{t as S}from"./IconChevronBack-BXRfc2bX.js";import{t as C}from"./PageSkeleton-BImjuI6S.js";import{t as ee}from"./crm-DbcoqKAF.js";import{t as te}from"./useGoBack-yePcdjuj.js";import{a as w,n as T}from"./catalogGallery-sguYVy7M.js";import{t as E}from"./SearchField-txVsGGXT.js";import{t as D}from"./IconSearch-CQT-DmXF.js";var O={class:`page calite-hub`},k={class:`calite-hub__nav`},A={class:`calite-hub__nav-end`},j=[`aria-label`,`aria-pressed`],M={class:`page__scroll page__scroll--with-nav calite-hub__scroll`},N={class:`calite-hub__chips`,role:`tablist`,"aria-label":`مرتب‌سازی کالیته‌ها`},P=[`onClick`],F={key:2,class:`calite-hub__empty`},I={key:3,class:`calite-hub__list`},L=[`onClick`],R={key:0,class:`calite-card__badge`},z={class:`calite-card__copy`,dir:`rtl`},ne={class:`mr-4 text-white`},B={class:`text-lg font-bold`},V={class:`text-md`},H={class:`text-xs mt-4`},U=h(s({__name:`CatalogsHubView`,setup(s){let h=f(),U=d(),{goBack:W}=te(`/`),G=b(),K=ee(),q=g([]),J=g([]),Y=g(!0),X=g(!1),Z=g(``),Q=g(`all`),re=[{id:`all`,label:`همه`},{id:`newest`,label:`جدیدترین`},{id:`popular`,label:`محبوب‌ترین`},{id:`season`,label:`بر اساس فصل`}],ie=m(()=>T(q.value,J.value)),$=m(()=>w(ie.value,Q.value,Z.value));r(async()=>{try{let e=await G.loadCompanies(),[t,n]=await Promise.all([Promise.all(e.map(e=>G.loadCatalogs(e.id))),K.loadBrowseProducts().catch(()=>[])]);q.value=t.flat(),J.value=n;let r=String(h.query.id??``);r&&q.value.some(e=>e.id===r)&&U.replace({name:`catalog-detail`,params:{catalogId:r}})}catch{q.value=[]}finally{Y.value=!1}});function ae(e){U.push({name:`catalog-detail`,params:{catalogId:e}})}function oe(){X.value=!X.value,X.value||(Z.value=``)}function se(e){let t=e.season===`winter`?`مناسب زمستان`:e.season===`summer`?`مناسب تابستان`:`مناسب چهار فصل`;return`${y(e.patternCount)} طرح • ${t}`}return(r,s)=>(n(),o(`div`,O,[e(`header`,k,[e(`button`,{type:`button`,class:`icon-btn`,"aria-label":`بازگشت`,onClick:s[0]||=(...e)=>v(W)&&v(W)(...e)},[i(S,{size:20})]),s[2]||=e(`h1`,null,`کالیته‌ها`,-1),e(`div`,A,[i(x,{variant:`inline`,class:`mobile-only`}),e(`button`,{type:`button`,class:`icon-btn`,"aria-label":X.value?`بستن جستجو`:`جستجو`,"aria-pressed":X.value,onClick:oe},[i(D,{size:20})],8,j)])]),e(`div`,M,[s[4]||=e(`p`,{class:`calite-hub__lead`},`مجموعه‌ای از بهترین پارچه‌ها، در یک نگاه`,-1),X.value?(n(),p(E,{key:0,"model-value":Z.value,placeholder:`جستجوی نام کالیته...`,"onUpdate:modelValue":s[1]||=e=>Z.value=e},null,8,[`model-value`])):a(``,!0),e(`div`,N,[(n(),o(t,null,u(re,t=>e(`button`,{key:t.id,type:`button`,class:c([`calite-chip`,{"is-on":Q.value===t.id}]),onClick:e=>Q.value=t.id},l(t.label),11,P)),64))]),Y.value?(n(),p(C,{key:1,variant:`cards`,rows:4})):$.value.length?(n(),o(`div`,I,[(n(!0),o(t,null,u($.value,t=>(n(),o(`button`,{key:t.id,type:`button`,class:`calite-card`,dir:`ltr`,onClick:e=>ae(t.id)},[e(`span`,{class:`calite-card__photo`,style:_(t.imageUrl?{backgroundImage:`url(${t.imageUrl})`}:void 0)},null,4),t.badge?(n(),o(`span`,R,l(t.badge===`new`?`جدید`:`پرفروش`),1)):a(``,!0),e(`div`,z,[s[3]||=e(`svg`,{class:`calite-card__arrow`,width:`12`,height:`16`,viewBox:`0 0 8 12`,fill:`none`,"aria-hidden":`true`},[e(`path`,{d:`M1.5 1.5 6 6l-4.5 4.5`,stroke:`#fff`,"stroke-width":`1.4`,"stroke-linecap":`round`,"stroke-linejoin":`round`})],-1),e(`div`,ne,[e(`div`,B,l(t.title),1),e(`div`,V,l(t.subtitle),1),e(`div`,H,l(se(t)),1)])])],8,L))),128))])):(n(),o(`p`,F,`کالیته‌ای یافت نشد.`))])]))}}),[[`__scopeId`,`data-v-b8e1ce8b`]]);export{U as default};
+1
View File
@@ -0,0 +1 @@
.calite-hub[data-v-b8e1ce8b]{color:#2a2622;background:#f4f0ed}.calite-hub__nav[data-v-b8e1ce8b]{background:#f4f0ed;grid-template-columns:40px 1fr auto;align-items:center;padding:6px 12px 0;display:grid}.calite-hub__nav-end[data-v-b8e1ce8b]{align-items:center;display:flex}.calite-hub__nav h1[data-v-b8e1ce8b]{text-align:center;margin:0;font-size:1.125rem;font-weight:700}.calite-hub__scroll[data-v-b8e1ce8b]{flex-direction:column;gap:12px;padding:2px 16px 28px;display:flex}.calite-hub__lead[data-v-b8e1ce8b]{text-align:center;color:#8a847c;margin:0;font-size:.78rem;line-height:1.7}.icon-btn[data-v-b8e1ce8b]{width:40px;height:40px;color:inherit;cursor:pointer;background:0 0;border:none;place-items:center;display:grid}.calite-hub__chips[data-v-b8e1ce8b]{scrollbar-width:none;gap:8px;padding:2px 0 4px;display:flex}.calite-hub__chips[data-v-b8e1ce8b]::-webkit-scrollbar{display:none}.calite-chip[data-v-b8e1ce8b]{color:#615f5c;height:36px;font:inherit;cursor:pointer;background:#eae6e2;border:1px solid #eae6e2;border-radius:999px;flex-shrink:0;padding:0 16px;font-size:.78rem;font-weight:600}.calite-chip.is-on[data-v-b8e1ce8b]{border-color:var(--color-primary);background:var(--color-primary);color:#fff}.calite-hub__list[data-v-b8e1ce8b]{flex-direction:column;gap:12px;display:flex}.calite-card[data-v-b8e1ce8b]{cursor:pointer;text-align:start;color:#2c2824;background:#e7ddd4;border:none;border-radius:22px;width:100%;min-height:132px;padding:0;display:block;position:relative;overflow:hidden}.calite-card__photo[data-v-b8e1ce8b]{z-index:0;background:linear-gradient(160deg,#c4b7a8,#8a7b6c) 50%/cover;position:absolute;inset:0}.calite-card__photo[data-v-b8e1ce8b]:after{content:"";background:linear-gradient(90deg,#0000 28%,#e7ddd46b 58%,#e7ddd4e0 100%);position:absolute;inset:0}.calite-card__badge[data-v-b8e1ce8b]{z-index:2;color:#000;background:#e7ddd4;border-radius:999px;padding:5px 12px;font-size:1rem;font-weight:500;line-height:1.2;position:absolute;top:12px;left:12px}.calite-card__copy[data-v-b8e1ce8b]{z-index:1;align-items:center;gap:4px;min-height:132px;padding:16px 16px 16px 42%;display:flex;position:relative}.calite-card__copy strong[data-v-b8e1ce8b]{color:#2c2824;font-size:1.0625rem;font-weight:700;line-height:1.4}.calite-card__sub[data-v-b8e1ce8b]{color:#5c5752;justify-content:flex-start;align-items:center;gap:2px;display:flex}.calite-card__arrow[data-v-b8e1ce8b]{flex-shrink:0;display:block}.calite-card__copy em[data-v-b8e1ce8b]{color:#5c5752;font-size:.75rem;font-style:normal;font-weight:500;line-height:1.45}.calite-card__copy small[data-v-b8e1ce8b]{color:#7a746c;font-size:.6875rem;font-weight:500;line-height:1.45}.calite-hub__empty[data-v-b8e1ce8b]{text-align:center;color:#8a847c;margin:16px 0 0}html.dark .calite-hub[data-v-b8e1ce8b],html.dark .calite-hub__nav[data-v-b8e1ce8b]{color:#eef2f8;background:#0b0f14}html.dark .calite-hub__lead[data-v-b8e1ce8b],html.dark .calite-hub__empty[data-v-b8e1ce8b]{color:#9aa8bc}html.dark .calite-chip[data-v-b8e1ce8b]{color:#c5d0de;background:#1a2230;border-color:#2a3444}html.dark .calite-chip.is-on[data-v-b8e1ce8b]{color:#121821;background:#e8e4df;border-color:#e8e4df}html.dark .calite-card[data-v-b8e1ce8b]{color:#eef2f8;background:#1a2230}html.dark .calite-card__photo[data-v-b8e1ce8b]{background:linear-gradient(160deg,#3a4454,#151b24)}html.dark .calite-card__photo[data-v-b8e1ce8b]:after{background:linear-gradient(90deg,#0000 22%,#0b0f146b 55%,#0b0f14e0 100%)}html.dark .calite-card__badge[data-v-b8e1ce8b]{color:#121821;background:#e8e4df}html.dark .calite-card__copy strong[data-v-b8e1ce8b],html.dark .calite-card__sub[data-v-b8e1ce8b],html.dark .calite-card__copy em[data-v-b8e1ce8b],html.dark .calite-card__copy small[data-v-b8e1ce8b]{color:#eef2f8}html.dark .calite-card__copy small[data-v-b8e1ce8b]{color:#c5d0de}
-1
View File
@@ -1 +0,0 @@
.catalog-hub[data-v-a452107a]{padding:12px var(--page-padding) 24px;flex-direction:column;gap:10px;display:flex}.section-title[data-v-a452107a]{margin:8px 0 0;font-size:.95rem}.hub-card[data-v-a452107a],.calite-item[data-v-a452107a]{text-align:start;background:var(--color-surface);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);cursor:pointer;border:none;flex-direction:column;align-items:stretch;gap:4px;width:100%;padding:14px;display:flex}.calite-item[data-v-a452107a]{flex-direction:row;justify-content:space-between;align-items:center;gap:12px}.calite-item--focus[data-v-a452107a]{outline:2px solid var(--color-primary)}.calite-item__text[data-v-a452107a]{flex-direction:column;gap:4px;min-width:0;display:flex}.calite-item strong[data-v-a452107a]{color:var(--color-text);font-size:.95rem;font-weight:700;line-height:1.5;display:block}.hub-card span[data-v-a452107a],.calite-item span[data-v-a452107a],.calite-item em[data-v-a452107a]{color:var(--color-text-muted);font-size:.8rem;font-style:normal;line-height:1.5;display:block}.empty-hint[data-v-a452107a]{color:var(--color-text-muted);text-align:center;margin:12px 0 0}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{A as e,J as t,L as n,N as r,R as i,Tt as a,_ as o,et as s,k as c,n as l,xt as u}from"./BasicIcon-B6lR-mG3.js";import{n as d}from"./format-BHJptHdF.js";import{b as f,g as p}from"./index-DDi4iM2C.js";import{t as m}from"./IconEditPen-CppsBLM9.js";import{t as h}from"./PageHeader-COmjOmby.js";import{t as g}from"./useRequirePricedOrder-CgVrKOPu.js";var _={class:`page check-mode-page`},v={class:`page__scroll check-mode-page__scroll`},y={class:`check-mode-invoice`},b={class:`check-mode-invoice__value`},x={class:`mode-options`},S={class:`mode-card__icon`},C={class:`mode-card__icon`},w=l(i({__name:`CheckModeSelectView`,setup(i){let l=o(),w=p(),{orderId:T,order:E}=g(),D=c(()=>E.value?.finalAmount?d(E.value.finalAmount):`—`);s(T,async e=>{e&&(w.getOrderById(e)||await w.fetchOrder(e),w.draftOrderId!==e&&w.startCheckDraft(e))},{immediate:!0});function O(e){w.setCheckMode(e),l.push(`/orders/${T.value}/check-form`)}return(i,o)=>(t(),r(`div`,_,[n(h,{title:`تسویه چکی`,subtitle:`بر اساس مبلغ فاکتور، نحوه ثبت چک را انتخاب کنید`,"show-back":``,centered:``,onBack:o[0]||=e=>u(l).push(`/orders/${u(T)}`)}),e(`div`,v,[e(`div`,y,[o[3]||=e(`span`,{class:`check-mode-invoice__label`},`مبلغ فاکتور`,-1),e(`strong`,b,a(D.value),1)]),e(`div`,x,[e(`button`,{type:`button`,class:`mode-card`,onClick:o[1]||=e=>O(`full`)},[e(`span`,S,[n(f,{size:36})]),o[4]||=e(`h3`,{class:`mode-card__title`},`ثبت کامل (پیشنهادی)`,-1),o[5]||=e(`p`,{class:`mode-card__desc`},`وارد کردن همه اطلاعات چک`,-1)]),e(`button`,{type:`button`,class:`mode-card`,onClick:o[2]||=e=>O(`brief`)},[e(`span`,C,[n(m,{size:36})]),o[6]||=e(`h3`,{class:`mode-card__title`},`ثبت مختصر`,-1),o[7]||=e(`p`,{class:`mode-card__desc`},`وارد کردن حداقل اطلاعات`,-1)])])])]))}}),[[`__scopeId`,`data-v-680065b0`]]);export{w as default};
import{A as e,J as t,L as n,N as r,R as i,Tt as a,_ as o,et as s,k as c,n as l,xt as u}from"./BasicIcon-B6lR-mG3.js";import{n as d}from"./format-BHJptHdF.js";import{b as f,g as p}from"./index-DXso6ia7.js";import{t as m}from"./IconEditPen-CppsBLM9.js";import{t as h}from"./PageHeader-Dzrx58_B.js";import{t as g}from"./useRequirePricedOrder-BHwPSld8.js";var _={class:`page check-mode-page`},v={class:`page__scroll check-mode-page__scroll`},y={class:`check-mode-invoice`},b={class:`check-mode-invoice__value`},x={class:`mode-options`},S={class:`mode-card__icon`},C={class:`mode-card__icon`},w=l(i({__name:`CheckModeSelectView`,setup(i){let l=o(),w=p(),{orderId:T,order:E}=g(),D=c(()=>E.value?.finalAmount?d(E.value.finalAmount):`—`);s(T,async e=>{e&&(w.getOrderById(e)||await w.fetchOrder(e),w.draftOrderId!==e&&w.startCheckDraft(e))},{immediate:!0});function O(e){w.setCheckMode(e),l.push(`/orders/${T.value}/check-form`)}return(i,o)=>(t(),r(`div`,_,[n(h,{title:`تسویه چکی`,subtitle:`بر اساس مبلغ فاکتور، نحوه ثبت چک را انتخاب کنید`,"show-back":``,centered:``,onBack:o[0]||=e=>u(l).push(`/orders/${u(T)}`)}),e(`div`,v,[e(`div`,y,[o[3]||=e(`span`,{class:`check-mode-invoice__label`},`مبلغ فاکتور`,-1),e(`strong`,b,a(D.value),1)]),e(`div`,x,[e(`button`,{type:`button`,class:`mode-card`,onClick:o[1]||=e=>O(`full`)},[e(`span`,S,[n(f,{size:36})]),o[4]||=e(`h3`,{class:`mode-card__title`},`ثبت کامل (پیشنهادی)`,-1),o[5]||=e(`p`,{class:`mode-card__desc`},`وارد کردن همه اطلاعات چک`,-1)]),e(`button`,{type:`button`,class:`mode-card`,onClick:o[2]||=e=>O(`brief`)},[e(`span`,C,[n(m,{size:36})]),o[6]||=e(`h3`,{class:`mode-card__title`},`ثبت مختصر`,-1),o[7]||=e(`p`,{class:`mode-card__desc`},`وارد کردن حداقل اطلاعات`,-1)])])])]))}}),[[`__scopeId`,`data-v-680065b0`]]);export{w as default};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{A as e,I as t,J as n,L as r,N as i,R as a,_ as o,n as s,nt as c,pt as l,xt as u}from"./BasicIcon-B6lR-mG3.js";import{t as d}from"./http-CHgEV7QF.js";import{c as f}from"./format-BHJptHdF.js";import{a as p}from"./validation-BD7oi-2I.js";import{c as m,n as h}from"./index-DDi4iM2C.js";import{t as g}from"./FormErrorBanner-8PcsTbdO.js";import{n as _,r as v,t as y}from"./formErrors-DglFjYkZ.js";import{t as b}from"./PageHeader-COmjOmby.js";import{t as x}from"./crm-DbcoqKAF.js";import{t as S}from"./useGoBack-yePcdjuj.js";import{t as C}from"./BaseInput-9HB-GJGt.js";var w={class:`page customer-create-page`},T={class:`page__scroll customer-create-scroll`},E={class:`form-card`},D={class:`footer`},O=s(a({__name:`CustomerCreateView`,setup(a){let s=o(),O=m(),k=x(),{goBack:A}=S(`/customers`),j=l(``),M=l(``),N=l(``),P=l(``),F=l({}),I=l(``),L=l(!1);function R(e){F.value=_(F.value,e),v(F.value)||(I.value=``)}async function z(){if(F.value={},I.value=``,!O.isAgent){I.value=`فقط واسطه می‌تواند مشتری به لیست خود اضافه کند.`;return}let e=f(N.value),t={};if(j.value.trim()||(t.firstName=`نام الزامی است.`),M.value.trim()||(t.lastName=`نام خانوادگی الزامی است.`),p(e)||(t.phone=`شماره موبایل معتبر نیست.`),v(t)){F.value=t,I.value=y;return}L.value=!0;try{let t=await k.registerCustomer({firstName:j.value.trim(),lastName:M.value.trim(),phone:e,businessName:P.value.trim()||void 0});if(t?.id){await s.replace({path:`/customer`,query:{id:t.id}});return}await s.replace(`/customers`)}catch(e){I.value=e instanceof d||e instanceof Error?e.message:`ثبت مشتری ناموفق بود.`}finally{L.value=!1}}return(a,o)=>(n(),i(`div`,w,[r(b,{title:`افزودن مشتری`,"show-back":``,centered:``,onBack:u(A)},null,8,[`onBack`]),e(`div`,T,[o[7]||=e(`p`,{class:`intro`},` مشتری به لیست شما اضافه می‌شود و بعد از ورود با همین شماره، سفارش‌هایش به حساب شما وصل می‌ماند. `,-1),r(g,{message:I.value},null,8,[`message`]),e(`div`,E,[r(C,{modelValue:j.value,"onUpdate:modelValue":[o[0]||=e=>j.value=e,o[1]||=e=>R(`firstName`)],label:`نام`,placeholder:`نام مشتری`,error:F.value.firstName},null,8,[`modelValue`,`error`]),r(C,{modelValue:M.value,"onUpdate:modelValue":[o[2]||=e=>M.value=e,o[3]||=e=>R(`lastName`)],label:`نام خانوادگی`,placeholder:`نام خانوادگی`,error:F.value.lastName},null,8,[`modelValue`,`error`]),r(C,{modelValue:N.value,"onUpdate:modelValue":[o[4]||=e=>N.value=e,o[5]||=e=>R(`phone`)],label:`شماره موبایل`,type:`tel`,inputmode:`tel`,dir:`ltr`,placeholder:`۰۹۱۲۳۴۵۶۷۸۹`,error:F.value.phone},null,8,[`modelValue`,`error`]),r(C,{modelValue:P.value,"onUpdate:modelValue":o[6]||=e=>P.value=e,label:`نام فروشگاه یا برند (اختیاری)`,placeholder:`مثلاً بوتیک رز`},null,8,[`modelValue`])])]),e(`footer`,D,[r(h,{block:``,loading:L.value,disabled:L.value,onClick:z},{default:c(()=>[...o[8]||=[t(` ثبت مشتری `,-1)]]),_:1},8,[`loading`,`disabled`])])]))}}),[[`__scopeId`,`data-v-f29dd241`]]);export{O as default};
import{A as e,I as t,J as n,L as r,N as i,R as a,_ as o,n as s,nt as c,pt as l,xt as u}from"./BasicIcon-B6lR-mG3.js";import{t as d}from"./http-CHgEV7QF.js";import{c as f}from"./format-BHJptHdF.js";import{a as p}from"./validation-BD7oi-2I.js";import{c as m,n as h}from"./index-DXso6ia7.js";import{t as g}from"./FormErrorBanner-8PcsTbdO.js";import{n as _,r as v,t as y}from"./formErrors-DglFjYkZ.js";import{t as b}from"./crm-DbcoqKAF.js";import{t as x}from"./useGoBack-yePcdjuj.js";import{t as S}from"./PageHeader-Dzrx58_B.js";import{t as C}from"./BaseInput-9HB-GJGt.js";var w={class:`page customer-create-page`},T={class:`page__scroll customer-create-scroll`},E={class:`form-card`},D={class:`footer`},O=s(a({__name:`CustomerCreateView`,setup(a){let s=o(),O=m(),k=b(),{goBack:A}=x(`/customers`),j=l(``),M=l(``),N=l(``),P=l(``),F=l({}),I=l(``),L=l(!1);function R(e){F.value=_(F.value,e),v(F.value)||(I.value=``)}async function z(){if(F.value={},I.value=``,!O.isAgent){I.value=`فقط واسطه می‌تواند مشتری به لیست خود اضافه کند.`;return}let e=f(N.value),t={};if(j.value.trim()||(t.firstName=`نام الزامی است.`),M.value.trim()||(t.lastName=`نام خانوادگی الزامی است.`),p(e)||(t.phone=`شماره موبایل معتبر نیست.`),v(t)){F.value=t,I.value=y;return}L.value=!0;try{let t=await k.registerCustomer({firstName:j.value.trim(),lastName:M.value.trim(),phone:e,businessName:P.value.trim()||void 0});if(t?.id){await s.replace({path:`/customer`,query:{id:t.id}});return}await s.replace(`/customers`)}catch(e){I.value=e instanceof d||e instanceof Error?e.message:`ثبت مشتری ناموفق بود.`}finally{L.value=!1}}return(a,o)=>(n(),i(`div`,w,[r(S,{title:`افزودن مشتری`,"show-back":``,centered:``,onBack:u(A)},null,8,[`onBack`]),e(`div`,T,[o[7]||=e(`p`,{class:`intro`},` مشتری به لیست شما اضافه می‌شود و بعد از ورود با همین شماره، سفارش‌هایش به حساب شما وصل می‌ماند. `,-1),r(g,{message:I.value},null,8,[`message`]),e(`div`,E,[r(C,{modelValue:j.value,"onUpdate:modelValue":[o[0]||=e=>j.value=e,o[1]||=e=>R(`firstName`)],label:`نام`,placeholder:`نام مشتری`,error:F.value.firstName},null,8,[`modelValue`,`error`]),r(C,{modelValue:M.value,"onUpdate:modelValue":[o[2]||=e=>M.value=e,o[3]||=e=>R(`lastName`)],label:`نام خانوادگی`,placeholder:`نام خانوادگی`,error:F.value.lastName},null,8,[`modelValue`,`error`]),r(C,{modelValue:N.value,"onUpdate:modelValue":[o[4]||=e=>N.value=e,o[5]||=e=>R(`phone`)],label:`شماره موبایل`,type:`tel`,inputmode:`tel`,dir:`ltr`,placeholder:`۰۹۱۲۳۴۵۶۷۸۹`,error:F.value.phone},null,8,[`modelValue`,`error`]),r(C,{modelValue:P.value,"onUpdate:modelValue":o[6]||=e=>P.value=e,label:`نام فروشگاه یا برند (اختیاری)`,placeholder:`مثلاً بوتیک رز`},null,8,[`modelValue`])])]),e(`footer`,D,[r(h,{block:``,loading:L.value,disabled:L.value,onClick:z},{default:c(()=>[...o[8]||=[t(` ثبت مشتری `,-1)]]),_:1},8,[`loading`,`disabled`])])]))}}),[[`__scopeId`,`data-v-f29dd241`]]);export{O as default};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{A as e,D as t,J as n,K as r,L as i,M as a,N as o,R as s,St as c,Tt as l,X as u,_ as d,et as f,g as p,j as m,k as h,n as g,nt as _,pt as v,wt as y,xt as b}from"./BasicIcon-B6lR-mG3.js";import{o as x}from"./format-BHJptHdF.js";import{S as ee,o as te,y as S}from"./index-DDi4iM2C.js";import{t as C}from"./IconFilter-DJjJ9EAy.js";import{t as w}from"./PageHeader-COmjOmby.js";import{t as T}from"./SearchField-txVsGGXT.js";import{t as E}from"./PageSkeleton-BImjuI6S.js";import{t as D}from"./crm-DbcoqKAF.js";var O={class:`page customers-page`},k={class:`page__scroll page__scroll--with-nav customers-scroll`},A={class:`toolbar`},j={class:`summary-card`},M={class:`summary-card__icon`,"aria-hidden":`true`},N={class:`summary-card__cols`},P={class:`tabs`,role:`tablist`},F=[`aria-selected`,`onClick`],I={class:`tab__text`},ne={key:1},L=[`onClick`],R={class:`customer-card__body`},z={class:`customer-card__top`},B={dir:`ltr`},V=g(s({__name:`CustomersView`,setup(s){let g=p(),V=d(),H=D(),U=v(String(g.query.q??``)),W=h(()=>String(g.query.status??`all`)),G=v([]),K=v(!0),q=v(null),J=h(()=>G.value),Y=h(()=>G.value.filter(e=>e.status===`active`).length),X=h(()=>G.value.reduce((e,t)=>e+t.totalPurchaseToman,0)),Z=[{id:`all`,label:`همه`},{id:`active`,label:`فعال`},{id:`inactive`,label:`غیرفعال`},{id:`new`,label:`جدید`}];async function Q(){K.value=!0,q.value=null;try{G.value=await H.loadCustomers({q:U.value||void 0,status:W.value===`all`?void 0:W.value})}catch(e){q.value=e instanceof Error?e.message:`بارگذاری مشتریان ناموفق بود.`,G.value=[]}finally{K.value=!1}}r(Q),f([W,U],Q);function $(e){V.replace({path:`/customers`,query:{...e===`all`?{}:{status:e},...U.value?{q:U.value}:{}}})}function re(e){U.value=e,V.replace({path:`/customers`,query:{...W.value===`all`?{}:{status:W.value},...e?{q:e}:{}}})}function ie(e){return e===`active`?`فعال`:e===`inactive`?`غیرفعال`:`جدید`}function ae(){V.push(`/customers/new`)}function oe(){let e=[`all`,`active`,`inactive`,`new`],t=e.indexOf(W.value);$(e[(t<0?0:t+1)%e.length]??`all`)}return(r,s)=>(n(),o(`div`,O,[i(w,{title:`مشتریان من`,"show-back":``,centered:``,onBack:s[0]||=e=>b(V).back()},{trailing:_(()=>[e(`button`,{type:`button`,class:`nav-add-btn`,"aria-label":`ثبت مشتری`,onClick:ae},[i(S,{size:22})])]),_:1}),e(`div`,k,[e(`div`,A,[i(T,{"model-value":U.value,placeholder:`جستجو بر اساس نام یا موبایل...`,"onUpdate:modelValue":re},null,8,[`model-value`]),e(`button`,{type:`button`,class:`filter-btn`,"aria-label":`فیلتر وضعیت`,onClick:oe},[i(C,{size:18})])]),e(`section`,j,[e(`div`,M,[i(ee,{size:22,color:`#fff`})]),e(`div`,N,[e(`div`,null,[s[1]||=e(`span`,null,`تعداد مشتری فعال`,-1),e(`strong`,null,l(b(x)(Y.value)),1)]),s[4]||=e(`span`,{class:`summary-card__divider`,"aria-hidden":`true`},null,-1),e(`div`,null,[s[2]||=e(`span`,null,`مجموع خرید (ریال)`,-1),e(`strong`,null,l(b(x)(X.value)),1),s[3]||=e(`em`,null,`تومان`,-1)])])]),e(`div`,P,[(n(),o(t,null,u(Z,t=>e(`button`,{key:t.id,type:`button`,role:`tab`,class:c([`tab`,{"tab--active":W.value===t.id}]),"aria-selected":W.value===t.id,onClick:e=>$(t.id)},[e(`span`,I,l(t.label),1)],10,F)),64))]),K.value?(n(),m(E,{key:0,variant:`list`})):q.value?(n(),o(`p`,ne,l(q.value),1)):a(``,!0),(n(!0),o(t,null,u(J.value,t=>(n(),o(`button`,{key:t.id,type:`button`,class:`customer-card`,onClick:e=>b(V).push({path:`/customer`,query:{id:t.id}})},[e(`div`,{class:`customer-card__avatar`,style:y({background:t.avatarColor})},l(t.avatarLetter),5),e(`div`,R,[e(`div`,z,[e(`strong`,null,l(t.name),1),e(`span`,{class:c([`status`,t.status===`active`?`status--ok`:`status--muted`])},l(ie(t.status)),3)]),e(`p`,B,l(t.phone),1),e(`p`,null,`مجموع خرید: `+l(b(x)(t.totalPurchaseToman))+` تومان`,1)]),i(te,{size:18,class:`chevron`})],8,L))),128)),s[5]||=e(`section`,{class:`promo`},[e(`div`,null,[e(`strong`,null,`افزایش مشتریان = افزایش سطح شما`),e(`p`,null,`با جذب مشتریان بیشتر به سطح VIP برسید`)])],-1)])]))}}),[[`__scopeId`,`data-v-d0b58aa9`]]);export{V as default};
import{A as e,D as t,J as n,K as r,L as i,M as a,N as o,R as s,St as c,Tt as l,X as u,_ as d,et as f,g as p,j as m,k as h,n as g,nt as _,pt as v,wt as y,xt as b}from"./BasicIcon-B6lR-mG3.js";import{o as x}from"./format-BHJptHdF.js";import{S as ee,o as te,y as S}from"./index-DXso6ia7.js";import{t as C}from"./IconFilter-DJjJ9EAy.js";import{t as w}from"./PageSkeleton-BImjuI6S.js";import{t as T}from"./crm-DbcoqKAF.js";import{t as E}from"./PageHeader-Dzrx58_B.js";import{t as D}from"./SearchField-txVsGGXT.js";var O={class:`page customers-page`},k={class:`page__scroll page__scroll--with-nav customers-scroll`},A={class:`toolbar`},j={class:`summary-card`},M={class:`summary-card__icon`,"aria-hidden":`true`},N={class:`summary-card__cols`},P={class:`tabs`,role:`tablist`},F=[`aria-selected`,`onClick`],I={class:`tab__text`},ne={key:1},L=[`onClick`],R={class:`customer-card__body`},z={class:`customer-card__top`},B={dir:`ltr`},V=g(s({__name:`CustomersView`,setup(s){let g=p(),V=d(),H=T(),U=v(String(g.query.q??``)),W=h(()=>String(g.query.status??`all`)),G=v([]),K=v(!0),q=v(null),J=h(()=>G.value),Y=h(()=>G.value.filter(e=>e.status===`active`).length),X=h(()=>G.value.reduce((e,t)=>e+t.totalPurchaseToman,0)),Z=[{id:`all`,label:`همه`},{id:`active`,label:`فعال`},{id:`inactive`,label:`غیرفعال`},{id:`new`,label:`جدید`}];async function Q(){K.value=!0,q.value=null;try{G.value=await H.loadCustomers({q:U.value||void 0,status:W.value===`all`?void 0:W.value})}catch(e){q.value=e instanceof Error?e.message:`بارگذاری مشتریان ناموفق بود.`,G.value=[]}finally{K.value=!1}}r(Q),f([W,U],Q);function $(e){V.replace({path:`/customers`,query:{...e===`all`?{}:{status:e},...U.value?{q:U.value}:{}}})}function re(e){U.value=e,V.replace({path:`/customers`,query:{...W.value===`all`?{}:{status:W.value},...e?{q:e}:{}}})}function ie(e){return e===`active`?`فعال`:e===`inactive`?`غیرفعال`:`جدید`}function ae(){V.push(`/customers/new`)}function oe(){let e=[`all`,`active`,`inactive`,`new`],t=e.indexOf(W.value);$(e[(t<0?0:t+1)%e.length]??`all`)}return(r,s)=>(n(),o(`div`,O,[i(E,{title:`مشتریان من`,"show-back":``,centered:``,onBack:s[0]||=e=>b(V).back()},{trailing:_(()=>[e(`button`,{type:`button`,class:`nav-add-btn`,"aria-label":`ثبت مشتری`,onClick:ae},[i(S,{size:22})])]),_:1}),e(`div`,k,[e(`div`,A,[i(D,{"model-value":U.value,placeholder:`جستجو بر اساس نام یا موبایل...`,"onUpdate:modelValue":re},null,8,[`model-value`]),e(`button`,{type:`button`,class:`filter-btn`,"aria-label":`فیلتر وضعیت`,onClick:oe},[i(C,{size:18})])]),e(`section`,j,[e(`div`,M,[i(ee,{size:22,color:`#fff`})]),e(`div`,N,[e(`div`,null,[s[1]||=e(`span`,null,`تعداد مشتری فعال`,-1),e(`strong`,null,l(b(x)(Y.value)),1)]),s[4]||=e(`span`,{class:`summary-card__divider`,"aria-hidden":`true`},null,-1),e(`div`,null,[s[2]||=e(`span`,null,`مجموع خرید (ریال)`,-1),e(`strong`,null,l(b(x)(X.value)),1),s[3]||=e(`em`,null,`تومان`,-1)])])]),e(`div`,P,[(n(),o(t,null,u(Z,t=>e(`button`,{key:t.id,type:`button`,role:`tab`,class:c([`tab`,{"tab--active":W.value===t.id}]),"aria-selected":W.value===t.id,onClick:e=>$(t.id)},[e(`span`,I,l(t.label),1)],10,F)),64))]),K.value?(n(),m(w,{key:0,variant:`list`})):q.value?(n(),o(`p`,ne,l(q.value),1)):a(``,!0),(n(!0),o(t,null,u(J.value,t=>(n(),o(`button`,{key:t.id,type:`button`,class:`customer-card`,onClick:e=>b(V).push({path:`/customer`,query:{id:t.id}})},[e(`div`,{class:`customer-card__avatar`,style:y({background:t.avatarColor})},l(t.avatarLetter),5),e(`div`,R,[e(`div`,z,[e(`strong`,null,l(t.name),1),e(`span`,{class:c([`status`,t.status===`active`?`status--ok`:`status--muted`])},l(ie(t.status)),3)]),e(`p`,B,l(t.phone),1),e(`p`,null,`مجموع خرید: `+l(b(x)(t.totalPurchaseToman))+` تومان`,1)]),i(te,{size:18,class:`chevron`})],8,L))),128)),s[5]||=e(`section`,{class:`promo`},[e(`div`,null,[e(`strong`,null,`افزایش مشتریان = افزایش سطح شما`),e(`p`,null,`با جذب مشتریان بیشتر به سطح VIP برسید`)])],-1)])]))}}),[[`__scopeId`,`data-v-d0b58aa9`]]);export{V as default};
@@ -1 +1 @@
import{A as e,D as t,E as n,J as r,K as i,L as a,M as o,N as s,R as c,Tt as l,X as u,_ as d,j as f,n as p,pt as m,xt as h}from"./BasicIcon-B6lR-mG3.js";import{l as g,o as _}from"./index-DDi4iM2C.js";import{t as v}from"./PageHeader-COmjOmby.js";import{t as y}from"./PageSkeleton-BImjuI6S.js";import{t as b}from"./crm-DbcoqKAF.js";import{t as x}from"./IconHeart-DjMqqdO0.js";var S={class:`page`},C={class:`page__scroll page__scroll--with-nav body`},w={key:1},T={key:2,class:`empty`},E=[`onClick`],D={class:`row__body`},O=[`onClick`],k=p(c({__name:`FavoritesView`,setup(c){let p=d(),k=g(),A=b(),j=m([]),M=m(!0),N=m(null);i(async()=>{M.value=!0;try{await k.hydrate();let e=await A.loadBrowseProducts(),t=new Set(k.ids);j.value=e.filter(e=>t.has(e.id))}catch(e){N.value=e instanceof Error?e.message:`بارگذاری علاقه‌مندی‌ها ناموفق بود.`}finally{M.value=!1}});async function P(e){await k.toggle(e),j.value=j.value.filter(t=>t.id!==e)}return(i,c)=>(r(),s(`div`,S,[a(v,{title:`علاقه‌مندی‌ها`,"show-back":``,centered:``,onBack:c[0]||=e=>h(p).back()}),e(`div`,C,[M.value?(r(),f(y,{key:0,variant:`grid`})):N.value?(r(),s(`p`,w,l(N.value),1)):j.value.length?o(``,!0):(r(),s(`p`,T,`هنوز محصولی ذخیره نکرده‌اید.`)),(r(!0),s(t,null,u(j.value,t=>(r(),s(`article`,{key:t.id,class:`row`,onClick:e=>h(p).push({path:`/product`,query:{id:t.id}})},[e(`div`,D,[e(`strong`,null,l(t.name),1),e(`span`,null,`کد `+l(t.code),1)]),e(`button`,{type:`button`,class:`bookmark`,"aria-label":`حذف از نشان‌شده‌ها`,onClick:n(e=>P(t.id),[`stop`])},[a(x,{size:18,filled:``,color:`#0a353c`})],8,O),a(_,{size:16,color:`#9aa3a0`})],8,E))),128))])]))}}),[[`__scopeId`,`data-v-8e70f9c9`]]);export{k as default};
import{A as e,D as t,E as n,J as r,K as i,L as a,M as o,N as s,R as c,Tt as l,X as u,_ as d,j as f,n as p,pt as m,xt as h}from"./BasicIcon-B6lR-mG3.js";import{l as g,o as _}from"./index-DXso6ia7.js";import{t as v}from"./PageSkeleton-BImjuI6S.js";import{t as y}from"./crm-DbcoqKAF.js";import{t as b}from"./PageHeader-Dzrx58_B.js";import{t as x}from"./IconHeart-DjMqqdO0.js";var S={class:`page`},C={class:`page__scroll page__scroll--with-nav body`},w={key:1},T={key:2,class:`empty`},E=[`onClick`],D={class:`row__body`},O=[`onClick`],k=p(c({__name:`FavoritesView`,setup(c){let p=d(),k=g(),A=y(),j=m([]),M=m(!0),N=m(null);i(async()=>{M.value=!0;try{await k.hydrate();let e=await A.loadBrowseProducts(),t=new Set(k.ids);j.value=e.filter(e=>t.has(e.id))}catch(e){N.value=e instanceof Error?e.message:`بارگذاری علاقه‌مندی‌ها ناموفق بود.`}finally{M.value=!1}});async function P(e){await k.toggle(e),j.value=j.value.filter(t=>t.id!==e)}return(i,c)=>(r(),s(`div`,S,[a(b,{title:`علاقه‌مندی‌ها`,"show-back":``,centered:``,onBack:c[0]||=e=>h(p).back()}),e(`div`,C,[M.value?(r(),f(v,{key:0,variant:`grid`})):N.value?(r(),s(`p`,w,l(N.value),1)):j.value.length?o(``,!0):(r(),s(`p`,T,`هنوز محصولی ذخیره نکرده‌اید.`)),(r(!0),s(t,null,u(j.value,t=>(r(),s(`article`,{key:t.id,class:`row`,onClick:e=>h(p).push({path:`/product`,query:{id:t.id}})},[e(`div`,D,[e(`strong`,null,l(t.name),1),e(`span`,null,`کد `+l(t.code),1)]),e(`button`,{type:`button`,class:`bookmark`,"aria-label":`حذف از نشان‌شده‌ها`,onClick:n(e=>P(t.id),[`stop`])},[a(x,{size:18,filled:``,color:`#0a353c`})],8,O),a(_,{size:16,color:`#9aa3a0`})],8,E))),128))])]))}}),[[`__scopeId`,`data-v-8e70f9c9`]]);export{k as default};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{J as e,R as t,j as n,t as r}from"./BasicIcon-B6lR-mG3.js";var i=t({__name:`IconSearch`,props:{size:{default:24},strokeWidth:{default:1.5},color:{default:null}},setup(t){return(i,a)=>(e(),n(r,{icon:`vuesax-linear:search-normal`,size:t.size,"stroke-width":t.strokeWidth,color:t.color},null,8,[`size`,`stroke-width`,`color`]))}});export{i as t};
+1
View File
@@ -0,0 +1 @@
import{A as e,J as t,N as n,R as r}from"./BasicIcon-B6lR-mG3.js";var i=[`width`,`height`],a=[`stroke`],o=[`stroke`],s=[`stroke`],c=r({__name:`IconShare`,props:{size:{default:20},color:{default:`#9AA3AF`}},setup(r){return(c,l)=>(t(),n(`svg`,{width:r.size,height:r.size,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,"aria-hidden":`true`},[e(`path`,{d:`M12 3.5v11`,stroke:r.color,"stroke-width":`1.5`,"stroke-linecap":`round`},null,8,a),e(`path`,{d:`M8.25 7 12 3.25 15.75 7`,stroke:r.color,"stroke-width":`1.5`,"stroke-linecap":`round`,"stroke-linejoin":`round`},null,8,o),e(`path`,{d:`M6.5 11.5v7.25c0 .97.78 1.75 1.75 1.75h7.5c.97 0 1.75-.78 1.75-1.75V11.5`,stroke:r.color,"stroke-width":`1.5`,"stroke-linecap":`round`,"stroke-linejoin":`round`},null,8,s)],8,i))}});export{c as t};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{A as e,I as t,J as n,L as r,M as i,N as a,R as o,Tt as s,_ as c,g as l,k as u,n as d,nt as f,xt as p}from"./BasicIcon-B6lR-mG3.js";import{a as m}from"./format-BHJptHdF.js";import{g as h,n as g}from"./index-DDi4iM2C.js";import{t as _}from"./PageHeader-COmjOmby.js";import{t as v}from"./useGoBack-yePcdjuj.js";var y={class:`page success-page`},b={class:`page__scroll success-page__scroll`},x={key:0,class:`card mb-4`},S={class:`info-row`},C={class:`info-row`},w={class:`info-row`},T=d(o({__name:`OrderSuccessView`,setup(o){let d=l(),T=c(),{goBack:E}=v(`/orders`),D=h(),O=u(()=>D.getOrderById(d.params.id));return(o,c)=>(n(),a(`div`,y,[r(_,{title:`ثبت موفق`,"show-back":``,centered:``,onBack:p(E)},null,8,[`onBack`]),e(`div`,b,[c[8]||=e(`div`,{class:`success-icon`},`✓`,-1),c[9]||=e(`h1`,{class:`page-title text-center`},`سفارش ثبت شد`,-1),c[10]||=e(`p`,{class:`text-center text-muted mb-4`},` سفارش شما با موفقیت ثبت شد. کارشناسان ما سفارش را بررسی و قیمت‌گذاری می‌کنند و به‌محض صدور فاکتور، از طریق پیامک و پنل کاربری به شما اطلاع می‌دهیم تا روش تسویه را انتخاب کنید. `,-1),O.value?(n(),a(`div`,x,[e(`div`,S,[c[2]||=e(`span`,null,`شماره سفارش:`,-1),e(`strong`,null,s(O.value.orderNumber),1)]),e(`div`,C,[c[3]||=e(`span`,null,`شرکت:`,-1),e(`span`,null,s(O.value.companyName),1)]),e(`div`,w,[c[4]||=e(`span`,null,`متراژ:`,-1),e(`span`,null,s(p(m)(O.value.totalMeterage)),1)]),c[5]||=e(`div`,{class:`info-row`},[e(`span`,null,`وضعیت:`),e(`span`,null,`در انتظار قیمت‌گذاری`)],-1)])):i(``,!0),r(g,{block:``,onClick:c[0]||=e=>p(T).replace(`/orders/${O.value?.id}`)},{default:f(()=>[...c[6]||=[t(` مشاهده جزئیات سفارش `,-1)]]),_:1}),r(g,{block:``,variant:`outline`,class:`mt-2`,onClick:c[1]||=e=>p(T).replace(`/`)},{default:f(()=>[...c[7]||=[t(` بازگشت به خانه `,-1)]]),_:1})])]))}}),[[`__scopeId`,`data-v-3d172af9`]]);export{T as default};
import{A as e,I as t,J as n,L as r,M as i,N as a,R as o,Tt as s,_ as c,g as l,k as u,n as d,nt as f,xt as p}from"./BasicIcon-B6lR-mG3.js";import{a as m}from"./format-BHJptHdF.js";import{g as h,n as g}from"./index-DXso6ia7.js";import{t as _}from"./useGoBack-yePcdjuj.js";import{t as v}from"./PageHeader-Dzrx58_B.js";var y={class:`page success-page`},b={class:`page__scroll success-page__scroll`},x={key:0,class:`card mb-4`},S={class:`info-row`},C={class:`info-row`},w={class:`info-row`},T=d(o({__name:`OrderSuccessView`,setup(o){let d=l(),T=c(),{goBack:E}=_(`/orders`),D=h(),O=u(()=>D.getOrderById(d.params.id));return(o,c)=>(n(),a(`div`,y,[r(v,{title:`ثبت موفق`,"show-back":``,centered:``,onBack:p(E)},null,8,[`onBack`]),e(`div`,b,[c[8]||=e(`div`,{class:`success-icon`},`✓`,-1),c[9]||=e(`h1`,{class:`page-title text-center`},`سفارش ثبت شد`,-1),c[10]||=e(`p`,{class:`text-center text-muted mb-4`},` سفارش شما با موفقیت ثبت شد. کارشناسان ما سفارش را بررسی و قیمت‌گذاری می‌کنند و به‌محض صدور فاکتور، از طریق پیامک و پنل کاربری به شما اطلاع می‌دهیم تا روش تسویه را انتخاب کنید. `,-1),O.value?(n(),a(`div`,x,[e(`div`,S,[c[2]||=e(`span`,null,`شماره سفارش:`,-1),e(`strong`,null,s(O.value.orderNumber),1)]),e(`div`,C,[c[3]||=e(`span`,null,`شرکت:`,-1),e(`span`,null,s(O.value.companyName),1)]),e(`div`,w,[c[4]||=e(`span`,null,`متراژ:`,-1),e(`span`,null,s(p(m)(O.value.totalMeterage)),1)]),c[5]||=e(`div`,{class:`info-row`},[e(`span`,null,`وضعیت:`),e(`span`,null,`در انتظار قیمت‌گذاری`)],-1)])):i(``,!0),r(g,{block:``,onClick:c[0]||=e=>p(T).replace(`/orders/${O.value?.id}`)},{default:f(()=>[...c[6]||=[t(` مشاهده جزئیات سفارش `,-1)]]),_:1}),r(g,{block:``,variant:`outline`,class:`mt-2`,onClick:c[1]||=e=>p(T).replace(`/`)},{default:f(()=>[...c[7]||=[t(` بازگشت به خانه `,-1)]]),_:1})])]))}}),[[`__scopeId`,`data-v-3d172af9`]]);export{T as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
.otp-page[data-v-ae24a66d]{isolation:isolate;color:#f4ede4;background:#1a1612;height:100%;min-height:100%;position:relative;overflow:hidden}.otp-page__bg[data-v-ae24a66d]{z-index:0;object-fit:cover;object-position:center center;pointer-events:none;-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;inset:0}.otp-page__scroll[data-v-ae24a66d]{z-index:1;overscroll-behavior:contain;height:100%;position:relative;overflow:hidden auto}.otp-page__stage[data-v-ae24a66d]{width:100%;max-width:360px;min-height:100%;padding:calc(10px + env(safe-area-inset-top,0px)) 16px calc(14px + env(safe-area-inset-bottom,0px));flex-direction:column;margin-inline:auto;display:flex}.otp-top[data-v-ae24a66d]{justify-content:flex-end;align-items:center;min-height:36px;display:flex}.otp-top__back[data-v-ae24a66d]{color:#f3e6d6;cursor:pointer;background:#f4ede424;border:none;border-radius:999px;place-items:center;width:36px;height:36px;display:grid}.otp-brand[data-v-ae24a66d]{text-align:center;color:#f3e6d6;flex-direction:column;align-items:center;margin-top:18px;margin-bottom:18px;display:flex}.otp-brand__fa[data-v-ae24a66d]{margin:12px 0 0;font-size:1.625rem;font-weight:700;line-height:1.25}.otp-brand__en[data-v-ae24a66d]{letter-spacing:.28em;color:#ead7c0;margin:6px 0 0;font-size:.6875rem;font-weight:500}.otp-card[data-v-ae24a66d]{color:#2a2622;background:#f4f1ed;border:none;border-radius:28px;width:100%;margin:0;padding:22px 18px 18px;box-shadow:0 18px 40px #0c0a0838}.otp-card__title[data-v-ae24a66d]{text-align:center;color:#1c1b19;margin:0;font-size:1.0625rem;font-weight:700;line-height:1.5}.otp-card__lead[data-v-ae24a66d]{text-align:center;color:#8a847c;margin:6px 0 0;font-size:.75rem;line-height:1.7}.otp-card[data-v-ae24a66d] .form-error-banner{margin-top:14px;margin-bottom:0}.otp-row[data-v-ae24a66d]{justify-content:center;gap:10px;margin-top:18px;display:flex}.otp-box[data-v-ae24a66d]{color:#1c1b19;text-align:center;width:52px;height:56px;caret-color:var(--color-primary);background:#f7f5f1;border:1px solid #e4e0db;border-radius:16px;padding:0;font-family:inherit;font-size:1.25rem;font-weight:700;transition:border-color .15s}.otp-box[data-v-ae24a66d]:focus{border-color:var(--color-primary);background:#fff;outline:none}.otp-box--error[data-v-ae24a66d]{border-color:color-mix(in srgb, var(--color-danger) 55%, #e4e0db)}.otp-card__error[data-v-ae24a66d]{color:var(--color-danger);text-align:center;margin:8px 4px 0;font-size:.75rem}.otp-submit[data-v-ae24a66d]{background:var(--color-primary);color:#f7f4ef;cursor:pointer;border:none;border-radius:999px;justify-content:center;align-items:center;width:100%;height:48px;margin-top:16px;padding:0 44px;font-family:inherit;font-size:.9375rem;font-weight:600;transition:background .15s;display:flex;position:relative}.otp-submit[data-v-ae24a66d]:not(:disabled):hover,.otp-submit[data-v-ae24a66d]:not(:disabled):focus-visible{background:var(--color-primary-hover)}.otp-submit[data-v-ae24a66d]:disabled{opacity:.7;cursor:not-allowed}.otp-submit__chevron[data-v-ae24a66d]{place-items:center;display:grid;position:absolute;inset-inline-end:16px}.otp-submit__spinner[data-v-ae24a66d]{border:2px solid #ffffff47;border-top-color:#fff;border-radius:50%;width:16px;height:16px;animation:.6s linear infinite otp-spin-ae24a66d;position:absolute;inset-inline-start:16px}.otp-resend[data-v-ae24a66d]{color:#6f6b66;cursor:pointer;background:0 0;border:1px solid #d8d3cd;border-radius:999px;width:100%;height:48px;margin-top:10px;font-family:inherit;font-size:.875rem;font-weight:500}.otp-resend[data-v-ae24a66d]:disabled{opacity:.7;cursor:not-allowed}.otp-edit[data-v-ae24a66d]{color:#8a847c;cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;gap:6px;width:100%;margin-top:14px;font-family:inherit;font-size:.8125rem;display:flex}.otp-spacer[data-v-ae24a66d]{flex:auto;min-height:16px}.otp-watermark[data-v-ae24a66d]{color:#f4ede494;letter-spacing:.2em;text-align:left;direction:ltr;margin:0;padding-bottom:8px;font-size:.625rem;font-weight:600;line-height:1.35}@keyframes otp-spin-ae24a66d{to{transform:rotate(360deg)}}@media (width>=768px){.otp-page[data-v-ae24a66d]{max-width:none;height:100%;min-height:0;margin:0;padding:0;overflow:hidden}}
-1
View File
@@ -1 +0,0 @@
.otp-row[data-v-125d5e90]{gap:clamp(.25rem,1.8vw,.625rem)}.otp-box[data-v-125d5e90]{aspect-ratio:48/52;border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);width:0;min-width:0;max-width:48px;height:auto;color:var(--color-text);text-align:center;caret-color:var(--color-primary);flex:1 1 0;padding:0;font-size:clamp(.95rem,4.2vw,1.25rem);font-weight:600;transition:border-color .15s}.otp-box[data-v-125d5e90]:focus{border-color:var(--color-primary);outline:none}.otp-box--error[data-v-125d5e90]{border-color:var(--color-danger)}.input-error-text[data-v-125d5e90]{color:var(--color-danger);margin:4px 0 0;font-size:.8125rem}
@@ -1 +1 @@
import{A as e,D as t,J as n,L as r,M as i,N as a,R as o,Tt as s,Z as c,n as l}from"./BasicIcon-B6lR-mG3.js";import{i as u}from"./index-DDi4iM2C.js";import{t as d}from"./IconChevronBack-BXRfc2bX.js";var f={class:`page-nav`},p={key:1,class:`nav-btn`},m={class:`page-nav__title`},h={class:`page-nav__trailing`},g={key:0,class:`page-nav__subtitle`},_={key:1,class:`page-header`},v={class:`header-text`},y={class:`page-title`},b={key:0,class:`page-subtitle`},x={class:`page-header__trailing`},S=l(o({__name:`PageHeader`,props:{title:{},subtitle:{},showBack:{type:Boolean},centered:{type:Boolean}},emits:[`back`],setup(o){return(l,S)=>o.centered?(n(),a(t,{key:0},[e(`header`,f,[o.showBack?(n(),a(`button`,{key:0,type:`button`,class:`nav-btn`,"aria-label":`بازگشت`,onClick:S[0]||=e=>l.$emit(`back`)},[r(d,{size:20})])):(n(),a(`span`,p)),e(`h1`,m,s(o.title),1),e(`div`,h,[c(l.$slots,`trailing`,{},void 0,!0),r(u,{variant:`inline`,class:`mobile-only`})])]),o.subtitle?(n(),a(`p`,g,s(o.subtitle),1)):i(``,!0)],64)):(n(),a(`header`,_,[o.showBack?(n(),a(`button`,{key:0,type:`button`,class:`back-btn`,"aria-label":`بازگشت`,onClick:S[1]||=e=>l.$emit(`back`)},[r(d,{size:20})])):i(``,!0),e(`div`,v,[e(`h1`,y,s(o.title),1),o.subtitle?(n(),a(`p`,b,s(o.subtitle),1)):i(``,!0)]),e(`div`,x,[c(l.$slots,`trailing`,{},void 0,!0),r(u,{variant:`inline`,class:`mobile-only`})])]))}}),[[`__scopeId`,`data-v-dd86426f`]]);export{S as t};
import{A as e,D as t,J as n,L as r,M as i,N as a,R as o,Tt as s,Z as c,n as l}from"./BasicIcon-B6lR-mG3.js";import{i as u}from"./index-DXso6ia7.js";import{t as d}from"./IconChevronBack-BXRfc2bX.js";var f={class:`page-nav`},p={key:1,class:`nav-btn`},m={class:`page-nav__title`},h={class:`page-nav__trailing`},g={key:0,class:`page-nav__subtitle`},_={key:1,class:`page-header`},v={class:`header-text`},y={class:`page-title`},b={key:0,class:`page-subtitle`},x={class:`page-header__trailing`},S=l(o({__name:`PageHeader`,props:{title:{},subtitle:{},showBack:{type:Boolean},centered:{type:Boolean}},emits:[`back`],setup(o){return(l,S)=>o.centered?(n(),a(t,{key:0},[e(`header`,f,[o.showBack?(n(),a(`button`,{key:0,type:`button`,class:`nav-btn`,"aria-label":`بازگشت`,onClick:S[0]||=e=>l.$emit(`back`)},[r(d,{size:20})])):(n(),a(`span`,p)),e(`h1`,m,s(o.title),1),e(`div`,h,[c(l.$slots,`trailing`,{},void 0,!0),r(u,{variant:`inline`,class:`mobile-only`})])]),o.subtitle?(n(),a(`p`,g,s(o.subtitle),1)):i(``,!0)],64)):(n(),a(`header`,_,[o.showBack?(n(),a(`button`,{key:0,type:`button`,class:`back-btn`,"aria-label":`بازگشت`,onClick:S[1]||=e=>l.$emit(`back`)},[r(d,{size:20})])):i(``,!0),e(`div`,v,[e(`h1`,y,s(o.title),1),o.subtitle?(n(),a(`p`,b,s(o.subtitle),1)):i(``,!0)]),e(`div`,x,[c(l.$slots,`trailing`,{},void 0,!0),r(u,{variant:`inline`,class:`mobile-only`})])]))}}),[[`__scopeId`,`data-v-dd86426f`]]);export{S as t};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{t as e}from"./CheckListView-CRgU6JjM.js";import{J as t,R as n,j as r}from"./BasicIcon-B6lR-mG3.js";var i=n({__name:`ProfileChecksView`,setup(n){return(n,i)=>(t(),r(e))}});export{i as default};
import{t as e}from"./CheckListView-BjpVFz7J.js";import{J as t,R as n,j as r}from"./BasicIcon-B6lR-mG3.js";var i=n({__name:`ProfileChecksView`,setup(n){return(n,i)=>(t(),r(e))}});export{i as default};
@@ -1 +1 @@
import{A as e,D as t,I as n,J as r,L as i,M as a,N as o,R as s,St as c,Tt as l,X as u,_ as d,j as f,k as p,n as m,nt as h,pt as g,t as _,xt as v}from"./BasicIcon-B6lR-mG3.js";import{o as y}from"./dist-BEjUUhLz.js";import{a as b,c as x,g as S,n as C}from"./index-DDi4iM2C.js";import{t as w}from"./ProfileSubpageLayout-CHfCB62H.js";var T={class:`settings-page`},E={class:`settings-links`,"aria-label":`حساب کاربری`},D={class:`settings-link__icon`,"aria-hidden":`true`},O={class:`settings-link__icon`,"aria-hidden":`true`},k={class:`settings-link__label`},A={key:0},j={class:`display-fieldset`},M={class:`display-grid`,role:`radiogroup`,"aria-label":`حالت نمایش`},N=[`aria-checked`,`onClick`],P={class:`theme-card__icon`,"aria-hidden":`true`},F={class:`theme-card__body`},I={class:`theme-card__label`},L={class:`theme-card__desc`},R={class:`theme-card__check`,"aria-hidden":`true`},z={key:0,class:`display-saved`},B=m(s({__name:`ProfileDisplayView`,setup(s){let m=d(),B=x(),V=S(),H=b(),U=g(!1),{start:W}=y(()=>{U.value=!1},2e3),G=[{value:`light`,label:`روشن`,description:`پس‌زمینه روشن و کنتراست بالا`,icon:`vuesax-linear:sun-1`},{value:`dark`,label:`تاریک`,description:`مناسب استفاده در شب`,icon:`vuesax-linear:moon`},{value:`system`,label:`سیستم`,description:`هم‌تراز با تنظیمات دستگاه`,icon:`vuesax-linear:mobile`}],K=p(()=>V.draftChecks.length);function q(){U.value=!0,W()}function J(){B.logout(),m.replace(`/login`)}return(s,d)=>(r(),f(w,{title:`تنظیمات`,subtitle:`نمایش، حساب کاربری و خروج`},{default:h(()=>[e(`div`,T,[e(`nav`,E,[e(`button`,{type:`button`,class:`settings-link`,onClick:d[0]||=e=>v(m).push(`/profile/edit`)},[e(`span`,D,[i(_,{icon:`vuesax-linear:profile-circle`,size:20,"stroke-width":1.5})]),d[2]||=e(`span`,{class:`settings-link__label`},`اطلاعات کاربری`,-1),i(_,{class:`settings-link__chevron`,icon:`vuesax-linear:arrow-left-1`,size:16,"stroke-width":1.5})]),e(`button`,{type:`button`,class:`settings-link`,onClick:d[1]||=e=>v(m).push(`/profile/checks`)},[e(`span`,O,[i(_,{icon:`vuesax-linear:card`,size:20,"stroke-width":1.5})]),e(`span`,k,[d[3]||=n(` لیست چک‌ها `,-1),K.value?(r(),o(`em`,A,`(`+l(K.value)+`)`,1)):a(``,!0)]),i(_,{class:`settings-link__chevron`,icon:`vuesax-linear:arrow-left-1`,size:16,"stroke-width":1.5})])]),e(`fieldset`,j,[d[4]||=e(`legend`,{class:`display-fieldset__legend`},`حالت نمایش`,-1),e(`div`,M,[(r(),o(t,null,u(G,t=>e(`button`,{key:t.value,type:`button`,class:c([`theme-card`,{"theme-card--active":v(H).preference===t.value}]),role:`radio`,"aria-checked":v(H).preference===t.value,onClick:e=>v(H).preference=t.value},[e(`span`,P,[i(_,{icon:t.icon,size:26,"stroke-width":1.5},null,8,[`icon`])]),e(`span`,F,[e(`strong`,I,l(t.label),1),e(`span`,L,l(t.description),1)]),e(`span`,R,[v(H).preference===t.value?(r(),f(_,{key:0,icon:`vuesax-linear:tick-circle`,size:20,"stroke-width":1.75})):a(``,!0)])],10,N)),64))])]),i(C,{block:``,onClick:q},{default:h(()=>[...d[5]||=[n(`ذخیره تنظیمات`,-1)]]),_:1}),U.value?(r(),o(`p`,z,`تنظیمات نمایش ذخیره شد ✓`)):a(``,!0),e(`button`,{type:`button`,class:`settings-logout`,onClick:J},`خروج`)])]),_:1}))}}),[[`__scopeId`,`data-v-3187a788`]]);export{B as default};
import{A as e,D as t,I as n,J as r,L as i,M as a,N as o,R as s,St as c,Tt as l,X as u,_ as d,j as f,k as p,n as m,nt as h,pt as g,t as _,xt as v}from"./BasicIcon-B6lR-mG3.js";import{u as y}from"./dist-BcgVHqJQ.js";import{a as b,c as x,g as S,n as C}from"./index-DXso6ia7.js";import{t as w}from"./ProfileSubpageLayout-CHfCB62H.js";var T={class:`settings-page`},E={class:`settings-links`,"aria-label":`حساب کاربری`},D={class:`settings-link__icon`,"aria-hidden":`true`},O={class:`settings-link__icon`,"aria-hidden":`true`},k={class:`settings-link__label`},A={key:0},j={class:`display-fieldset`},M={class:`display-grid`,role:`radiogroup`,"aria-label":`حالت نمایش`},N=[`aria-checked`,`onClick`],P={class:`theme-card__icon`,"aria-hidden":`true`},F={class:`theme-card__body`},I={class:`theme-card__label`},L={class:`theme-card__desc`},R={class:`theme-card__check`,"aria-hidden":`true`},z={key:0,class:`display-saved`},B=m(s({__name:`ProfileDisplayView`,setup(s){let m=d(),B=x(),V=S(),H=b(),U=g(!1),{start:W}=y(()=>{U.value=!1},2e3),G=[{value:`light`,label:`روشن`,description:`پس‌زمینه روشن و کنتراست بالا`,icon:`vuesax-linear:sun-1`},{value:`dark`,label:`تاریک`,description:`مناسب استفاده در شب`,icon:`vuesax-linear:moon`},{value:`system`,label:`سیستم`,description:`هم‌تراز با تنظیمات دستگاه`,icon:`vuesax-linear:mobile`}],K=p(()=>V.draftChecks.length);function q(){U.value=!0,W()}function J(){B.logout(),m.replace(`/login`)}return(s,d)=>(r(),f(w,{title:`تنظیمات`,subtitle:`نمایش، حساب کاربری و خروج`},{default:h(()=>[e(`div`,T,[e(`nav`,E,[e(`button`,{type:`button`,class:`settings-link`,onClick:d[0]||=e=>v(m).push(`/profile/edit`)},[e(`span`,D,[i(_,{icon:`vuesax-linear:profile-circle`,size:20,"stroke-width":1.5})]),d[2]||=e(`span`,{class:`settings-link__label`},`اطلاعات کاربری`,-1),i(_,{class:`settings-link__chevron`,icon:`vuesax-linear:arrow-left-1`,size:16,"stroke-width":1.5})]),e(`button`,{type:`button`,class:`settings-link`,onClick:d[1]||=e=>v(m).push(`/profile/checks`)},[e(`span`,O,[i(_,{icon:`vuesax-linear:card`,size:20,"stroke-width":1.5})]),e(`span`,k,[d[3]||=n(` لیست چک‌ها `,-1),K.value?(r(),o(`em`,A,`(`+l(K.value)+`)`,1)):a(``,!0)]),i(_,{class:`settings-link__chevron`,icon:`vuesax-linear:arrow-left-1`,size:16,"stroke-width":1.5})])]),e(`fieldset`,j,[d[4]||=e(`legend`,{class:`display-fieldset__legend`},`حالت نمایش`,-1),e(`div`,M,[(r(),o(t,null,u(G,t=>e(`button`,{key:t.value,type:`button`,class:c([`theme-card`,{"theme-card--active":v(H).preference===t.value}]),role:`radio`,"aria-checked":v(H).preference===t.value,onClick:e=>v(H).preference=t.value},[e(`span`,P,[i(_,{icon:t.icon,size:26,"stroke-width":1.5},null,8,[`icon`])]),e(`span`,F,[e(`strong`,I,l(t.label),1),e(`span`,L,l(t.description),1)]),e(`span`,R,[v(H).preference===t.value?(r(),f(_,{key:0,icon:`vuesax-linear:tick-circle`,size:20,"stroke-width":1.75})):a(``,!0)])],10,N)),64))])]),i(C,{block:``,onClick:q},{default:h(()=>[...d[5]||=[n(`ذخیره تنظیمات`,-1)]]),_:1}),U.value?(r(),o(`p`,z,`تنظیمات نمایش ذخیره شد ✓`)):a(``,!0),e(`button`,{type:`button`,class:`settings-logout`,onClick:J},`خروج`)])]),_:1}))}}),[[`__scopeId`,`data-v-3187a788`]]);export{B as default};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{A as e,D as t,I as n,J as r,K as i,L as a,M as o,N as s,R as c,St as l,Tt as u,X as d,_ as f,j as p,k as m,n as h,nt as g,t as _,xt as v}from"./BasicIcon-B6lR-mG3.js";import{i as y}from"./format-BHJptHdF.js";import{n as b,u as x}from"./index-DDi4iM2C.js";import{t as S}from"./EmptyState-C6UAJ5_3.js";import{t as C}from"./ProfileSubpageLayout-CHfCB62H.js";var w={key:0,class:`notif-box`},T={class:`notif-box__head`},E={class:`notif-box__count`},D=[`onClick`],O={class:`notif-row__icon`,"aria-hidden":`true`},k={class:`notif-row__body`},A={class:`notif-row__title-row`},j={class:`notif-row__title`},M={key:0,class:`notif-row__dot`,"aria-label":`خوانده‌نشده`},N={class:`notif-row__text`},P={class:`notif-row__time`},F=h(c({__name:`ProfileNotificationsView`,setup(c){let h=f(),F=x(),I=m(()=>F.items),L=m(()=>F.hasUnread),R={info:`vuesax-linear:information`,success:`vuesax-linear:tick-circle`,warning:`vuesax-linear:timer`,danger:`vuesax-linear:close-circle`};i(()=>{F.hydrate()});async function z(e){await F.markRead(e.id),e.link&&h.push(e.link)}return(i,c)=>(r(),p(C,{title:`اعلان‌ها`,subtitle:`آخرین خبرهای سفارش‌های شما`},{default:g(()=>[I.value.length?(r(),s(`div`,w,[e(`div`,T,[e(`span`,E,u(L.value?`${v(F).unreadCount} اعلان خوانده‌نشده`:`همه خوانده شده`),1),L.value?(r(),p(b,{key:0,variant:`outline`,class:`notif-box__mark`,onClick:c[0]||=e=>v(F).markAllRead()},{default:g(()=>[...c[2]||=[n(` خواندن همه `,-1)]]),_:1})):o(``,!0)]),(r(!0),s(t,null,d(I.value,t=>(r(),s(`button`,{key:t.id,type:`button`,class:l([`notif-row`,[`notif-row--${t.tone}`,{"notif-row--unread":!t.isRead}]]),onClick:e=>z(t)},[e(`span`,O,[a(_,{icon:R[t.tone],size:22,"stroke-width":1.5},null,8,[`icon`])]),e(`span`,k,[e(`span`,A,[e(`strong`,j,u(t.title),1),t.isRead?o(``,!0):(r(),s(`span`,M))]),e(`span`,N,u(t.body),1),e(`span`,P,u(v(y)(t.sentAt)),1)])],10,D))),128))])):(r(),p(S,{key:1,icon:`vuesax-linear:notification-bing`,title:`اعلانی ندارید`,message:`وقتی فاکتور سفارشتان صادر شود یا وضعیت چک و پرداخت تغییر کند، همین‌جا خبردار می‌شوید.`},{default:g(()=>[a(b,{variant:`outline`,onClick:c[1]||=e=>v(h).push(`/orders`)},{default:g(()=>[...c[3]||=[n(`سفارش‌های من`,-1)]]),_:1})]),_:1}))]),_:1}))}}),[[`__scopeId`,`data-v-57190756`]]);export{F as default};
import{A as e,D as t,I as n,J as r,K as i,L as a,M as o,N as s,R as c,St as l,Tt as u,X as d,_ as f,j as p,k as m,n as h,nt as g,t as _,xt as v}from"./BasicIcon-B6lR-mG3.js";import{i as y}from"./format-BHJptHdF.js";import{n as b,u as x}from"./index-DXso6ia7.js";import{t as S}from"./EmptyState-C6UAJ5_3.js";import{t as C}from"./ProfileSubpageLayout-CHfCB62H.js";var w={key:0,class:`notif-box`},T={class:`notif-box__head`},E={class:`notif-box__count`},D=[`onClick`],O={class:`notif-row__icon`,"aria-hidden":`true`},k={class:`notif-row__body`},A={class:`notif-row__title-row`},j={class:`notif-row__title`},M={key:0,class:`notif-row__dot`,"aria-label":`خوانده‌نشده`},N={class:`notif-row__text`},P={class:`notif-row__time`},F=h(c({__name:`ProfileNotificationsView`,setup(c){let h=f(),F=x(),I=m(()=>F.items),L=m(()=>F.hasUnread),R={info:`vuesax-linear:information`,success:`vuesax-linear:tick-circle`,warning:`vuesax-linear:timer`,danger:`vuesax-linear:close-circle`};i(()=>{F.hydrate()});async function z(e){await F.markRead(e.id),e.link&&h.push(e.link)}return(i,c)=>(r(),p(C,{title:`اعلان‌ها`,subtitle:`آخرین خبرهای سفارش‌های شما`},{default:g(()=>[I.value.length?(r(),s(`div`,w,[e(`div`,T,[e(`span`,E,u(L.value?`${v(F).unreadCount} اعلان خوانده‌نشده`:`همه خوانده شده`),1),L.value?(r(),p(b,{key:0,variant:`outline`,class:`notif-box__mark`,onClick:c[0]||=e=>v(F).markAllRead()},{default:g(()=>[...c[2]||=[n(` خواندن همه `,-1)]]),_:1})):o(``,!0)]),(r(!0),s(t,null,d(I.value,t=>(r(),s(`button`,{key:t.id,type:`button`,class:l([`notif-row`,[`notif-row--${t.tone}`,{"notif-row--unread":!t.isRead}]]),onClick:e=>z(t)},[e(`span`,O,[a(_,{icon:R[t.tone],size:22,"stroke-width":1.5},null,8,[`icon`])]),e(`span`,k,[e(`span`,A,[e(`strong`,j,u(t.title),1),t.isRead?o(``,!0):(r(),s(`span`,M))]),e(`span`,N,u(t.body),1),e(`span`,P,u(v(y)(t.sentAt)),1)])],10,D))),128))])):(r(),p(S,{key:1,icon:`vuesax-linear:notification-bing`,title:`اعلانی ندارید`,message:`وقتی فاکتور سفارشتان صادر شود یا وضعیت چک و پرداخت تغییر کند، همین‌جا خبردار می‌شوید.`},{default:g(()=>[a(b,{variant:`outline`,onClick:c[1]||=e=>v(h).push(`/orders`)},{default:g(()=>[...c[3]||=[n(`سفارش‌های من`,-1)]]),_:1})]),_:1}))]),_:1}))}}),[[`__scopeId`,`data-v-57190756`]]);export{F as default};
@@ -1 +1 @@
import{A as e,I as t,J as n,L as r,M as i,N as a,R as o,j as s,n as c,nt as l,pt as u}from"./BasicIcon-B6lR-mG3.js";import{n as d}from"./index-DDi4iM2C.js";import{t as f}from"./FormErrorBanner-8PcsTbdO.js";import{n as p,r as m,t as h}from"./formErrors-DglFjYkZ.js";import{t as g}from"./BaseInput-9HB-GJGt.js";import{t as _}from"./ProfileSubpageLayout-CHfCB62H.js";var v={class:`settings-form`},y={key:0,class:`settings-form__saved`},b=c(o({__name:`ProfileSecurityView`,setup(o){let c=u(``),b=u(``),x=u(``),S=u({}),C=u(``),w=u(!1);function T(e){S.value=p(S.value,e),m(S.value)||(C.value=``)}function E(){S.value={},C.value=``,w.value=!1;let e={};if(c.value||(e.currentPassword=`رمز فعلی الزامی است.`),b.value.length<6&&(e.newPassword=`رمز جدید باید حداقل ۶ کاراکتر باشد.`),x.value!==b.value&&(e.confirmPassword=`تکرار رمز با رمز جدید یکسان نیست.`),m(e)){S.value=e,C.value=h;return}c.value=``,b.value=``,x.value=``,w.value=!0,setTimeout(()=>{w.value=!1},2e3)}return(o,u)=>(n(),s(_,{title:`امنیت حساب`,subtitle:`تغییر رمز عبور و تنظیمات ورود`},{default:l(()=>[r(f,{message:C.value},null,8,[`message`]),e(`div`,v,[r(g,{modelValue:c.value,"onUpdate:modelValue":[u[0]||=e=>c.value=e,u[1]||=e=>T(`currentPassword`)],type:`password`,label:`رمز عبور فعلی`,error:S.value.currentPassword},null,8,[`modelValue`,`error`]),r(g,{modelValue:b.value,"onUpdate:modelValue":[u[2]||=e=>b.value=e,u[3]||=e=>T(`newPassword`)],type:`password`,label:`رمز عبور جدید`,error:S.value.newPassword},null,8,[`modelValue`,`error`]),r(g,{modelValue:x.value,"onUpdate:modelValue":[u[4]||=e=>x.value=e,u[5]||=e=>T(`confirmPassword`)],type:`password`,label:`تکرار رمز عبور جدید`,error:S.value.confirmPassword},null,8,[`modelValue`,`error`]),r(d,{block:``,onClick:E},{default:l(()=>[...u[6]||=[t(`ذخیره رمز جدید`,-1)]]),_:1}),w.value?(n(),a(`p`,y,`رمز عبور با موفقیت تغییر کرد ✓`)):i(``,!0)])]),_:1}))}}),[[`__scopeId`,`data-v-074827a2`]]);export{b as default};
import{A as e,I as t,J as n,L as r,M as i,N as a,R as o,j as s,n as c,nt as l,pt as u}from"./BasicIcon-B6lR-mG3.js";import{n as d}from"./index-DXso6ia7.js";import{t as f}from"./FormErrorBanner-8PcsTbdO.js";import{n as p,r as m,t as h}from"./formErrors-DglFjYkZ.js";import{t as g}from"./BaseInput-9HB-GJGt.js";import{t as _}from"./ProfileSubpageLayout-CHfCB62H.js";var v={class:`settings-form`},y={key:0,class:`settings-form__saved`},b=c(o({__name:`ProfileSecurityView`,setup(o){let c=u(``),b=u(``),x=u(``),S=u({}),C=u(``),w=u(!1);function T(e){S.value=p(S.value,e),m(S.value)||(C.value=``)}function E(){S.value={},C.value=``,w.value=!1;let e={};if(c.value||(e.currentPassword=`رمز فعلی الزامی است.`),b.value.length<6&&(e.newPassword=`رمز جدید باید حداقل ۶ کاراکتر باشد.`),x.value!==b.value&&(e.confirmPassword=`تکرار رمز با رمز جدید یکسان نیست.`),m(e)){S.value=e,C.value=h;return}c.value=``,b.value=``,x.value=``,w.value=!0,setTimeout(()=>{w.value=!1},2e3)}return(o,u)=>(n(),s(_,{title:`امنیت حساب`,subtitle:`تغییر رمز عبور و تنظیمات ورود`},{default:l(()=>[r(f,{message:C.value},null,8,[`message`]),e(`div`,v,[r(g,{modelValue:c.value,"onUpdate:modelValue":[u[0]||=e=>c.value=e,u[1]||=e=>T(`currentPassword`)],type:`password`,label:`رمز عبور فعلی`,error:S.value.currentPassword},null,8,[`modelValue`,`error`]),r(g,{modelValue:b.value,"onUpdate:modelValue":[u[2]||=e=>b.value=e,u[3]||=e=>T(`newPassword`)],type:`password`,label:`رمز عبور جدید`,error:S.value.newPassword},null,8,[`modelValue`,`error`]),r(g,{modelValue:x.value,"onUpdate:modelValue":[u[4]||=e=>x.value=e,u[5]||=e=>T(`confirmPassword`)],type:`password`,label:`تکرار رمز عبور جدید`,error:S.value.confirmPassword},null,8,[`modelValue`,`error`]),r(d,{block:``,onClick:E},{default:l(()=>[...u[6]||=[t(`ذخیره رمز جدید`,-1)]]),_:1}),w.value?(n(),a(`p`,y,`رمز عبور با موفقیت تغییر کرد ✓`)):i(``,!0)])]),_:1}))}}),[[`__scopeId`,`data-v-074827a2`]]);export{b as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
var e={suit:`پارچه‌های کت‌وشلواری`,trousers:`پارچه‌های شلواری`,shirt:`پارچه‌های پیراهنی`},t={summer:`تابستانه`,winter:`زمستانه`,all_season:`چهار فصل`};function n(e){let t=e.trim();return t.includes(`کالیته`)?t:`کالیته ${t}`}function r(e){return e.description?.match(/[A-Za-z][A-Za-z0-9 .&-]{1,28}/)?.[0]?.trim()||(/^[A-Za-z]/.test(e.code)?e.code:``)}function i(e,t){if(!e.length)return t;let n=new Map;for(let t of e)n.set(t,(n.get(t)??0)+1);return[...n.entries()].sort((e,t)=>t[1]-e[1])[0]?.[0]??t}function a(e){let t=`${e.weaveType??``} ${e.tags.join(` `)} ${e.name}`;return/ملانژ|melange|mélange|heather/i.test(t)?`melange`:/طرح‌?دار|striped?|check|print|jacquard|pattern/i.test(t)?`patterned`:/ساده|plain|solid/i.test(t)?`plain`:`other`}function o(e){let t=new Map;for(let n of e){let e=n.name.trim()||n.code,r=t.get(e)??[];r.push(n),t.set(e,r)}return[...t.entries()].map(([,e])=>{let t=[...new Set(e.flatMap(e=>e.colors.length?e.colors:e.color?[e.color]:[]))];return{id:e[0].id,name:e[0].name,imageUrl:e.find(e=>e.imageUrl)?.imageUrl,colorCount:Math.max(t.length,e.length),colors:t.slice(0,5),kind:a(e[0]),items:e}})}function s(t,a){let s=new Map;for(let e of a){if(!e.catalogId)continue;let t=s.get(e.catalogId)??[];t.push(e),s.set(e.catalogId,t)}let c=t.map(e=>s.get(e.id)?.length??e.productCount??0),l=Math.max(4,[...c].sort((e,t)=>t-e)[Math.floor(t.length/3)]??4);return t.map(t=>{let a=s.get(t.id)??[],c=o(a).length||a.length||t.productCount||0,u=i(a.map(e=>e.categoryId),`suit`),d=i(a.map(e=>e.season),`all_season`),f=a.some(e=>e.isNew),p=c>=l;return{id:t.id,companyId:t.companyId,name:t.name,title:n(t.name),latinName:r(t),subtitle:t.description?.trim()||e[u]||`پارچه‌های منتخب`,imageUrl:t.imageUrl||a.find(e=>e.imageUrl)?.imageUrl,patternCount:c,badge:f?`new`:p?`popular`:void 0,season:d,isNew:f,isPopular:p}})}function c(e,t,n){let r=n.trim().toLowerCase(),i=e.filter(e=>!r||[e.title,e.name,e.latinName,e.subtitle].join(` `).toLowerCase().includes(r));if(t===`newest`)return i.sort((e,t)=>Number(t.isNew)-Number(e.isNew)||t.patternCount-e.patternCount);if(t===`popular`)return i.sort((e,t)=>Number(t.isPopular)-Number(e.isPopular)||t.patternCount-e.patternCount);if(t===`season`){let e=[`summer`,`winter`,`all_season`];return i.sort((t,n)=>e.indexOf(t.season)-e.indexOf(n.season)||t.title.localeCompare(n.title,`fa`))}return i}export{c as a,r as i,s as n,o,n as r,t};
Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

-1
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{H as e,K as t,U as n,W as r,bt as i,ct as a,et as o,ft as s,gt as c,ht as l,it as u,ot as d,pt as f,ut as p,vt as m,z as h}from"./BasicIcon-B6lR-mG3.js";function g(e,t){return d()?(p(e,t),!0):!1}var _=new WeakMap,v=(...t)=>{let r=t[0],i=h()?.proxy??d();if(i==null&&!e())throw Error(`injectLocal must be called in setup`);return i&&_.has(i)&&r in _.get(i)?_.get(i)[r]:n(...t)},y=typeof window<`u`&&typeof document<`u`;typeof WorkerGlobalScope<`u`&&globalThis instanceof WorkerGlobalScope;var b=Object.prototype.toString,x=e=>b.call(e)===`[object Object]`,S=()=>{},C=w();function w(){var e,t;return y&&!!((e=window)!=null&&(e=e.navigator)!=null&&e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((t=window)==null||(t=t.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window?.navigator.userAgent))}function T(...e){if(e.length!==1)return m(...e);let t=e[0];return typeof t==`function`?s(u(()=>({get:t,set:S}))):f(t)}function E(e,t){function n(...n){return new Promise((r,i)=>{Promise.resolve(e(()=>t.apply(this,n),{fn:t,thisArg:this,args:n})).then(r).catch(i)})}return`cancel`in e&&Object.assign(n,{cancel:e.cancel,flush:e.flush,isPending:e.isPending}),n}var D=e=>e();function O(e=D,t={}){let{initialState:n=`active`}=t,r=T(n===`active`);function i(){r.value=!1}function a(){r.value=!0}return{isActive:l(r),pause:i,resume:a,eventFilter:(...t)=>{r.value&&e(...t)}}}function k(e){return e.endsWith(`rem`)?Number.parseFloat(e)*16:Number.parseFloat(e)}function A(e){return Array.isArray(e)?e:[e]}function j(e){return e||h()}function M(e,t,n={}){let{eventFilter:r=D,...i}=n;return o(e,E(r,t),i)}function N(e,t,n={}){let{eventFilter:r,initialState:i=`active`,...a}=n,{eventFilter:o,pause:s,resume:c,isActive:l}=O(r,{initialState:i});return{stop:M(e,t,{...a,eventFilter:o}),pause:s,resume:c,isActive:l}}function P(e,n=!0,i){j(i)?t(e,i):n?e():r(e)}function F(e,t=1e3,n={}){let{immediate:r=!0,immediateCallback:s=!1}=n,u=null,d=c(!1);function f(){u&&=(clearInterval(u),null)}function p(){d.value=!1,f()}function m(){let n=i(t);n<=0||(d.value=!0,s&&e(),f(),d.value&&(u=setInterval(e,n)))}return r&&y&&m(),(a(t)||typeof t==`function`)&&g(o(t,()=>{d.value&&y&&m()})),g(p),{isActive:l(d),pause:p,resume:m}}function I(e,t,n={}){let{immediate:r=!0,immediateCallback:a=!1}=n,o=c(!1),s;function u(){s&&=(clearTimeout(s),void 0)}function d(){o.value=!1,u()}function f(...n){a&&e(),u(),o.value=!0,s=setTimeout(()=>{o.value=!1,s=void 0,e(...n)},i(t))}return r&&(o.value=!0,y&&f()),g(d),{isPending:l(o),start:f,stop:d}}function L(e,t,n){return o(e,t,{...n,immediate:!0})}export{S as a,P as c,L as d,N as f,x as i,F as l,y as n,k as o,C as r,A as s,v as t,I as u};
+1
View File
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

File diff suppressed because one or more lines are too long
-2
View File
File diff suppressed because one or more lines are too long
+2
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
var e=`/assets/login-fabric-CSZOoxR9.jpg`;export{e as t};
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

@@ -1 +1 @@
import{_ as e,et as t,g as n,k as r}from"./BasicIcon-B6lR-mG3.js";import{g as i}from"./index-DDi4iM2C.js";import{n as a}from"./orderInvoice-B0L1Aeuk.js";function o(){let o=n(),s=e(),c=i(),l=r(()=>o.params.id),u=r(()=>c.getOrderById(l.value)),d=r(()=>a(u.value));function f(e){e&&(a(e)||s.replace(`/orders/${e.id}`))}return t(l,async e=>{e&&f(c.getOrderById(e)??await c.fetchOrder(e))},{immediate:!0}),t(u,e=>{f(e)}),{orderId:l,order:u,invoiceReady:d}}export{o as t};
import{_ as e,et as t,g as n,k as r}from"./BasicIcon-B6lR-mG3.js";import{g as i}from"./index-DXso6ia7.js";import{n as a}from"./orderInvoice-B0L1Aeuk.js";function o(){let o=n(),s=e(),c=i(),l=r(()=>o.params.id),u=r(()=>c.getOrderById(l.value)),d=r(()=>a(u.value));function f(e){e&&(a(e)||s.replace(`/orders/${e.id}`))}return t(l,async e=>{e&&f(c.getOrderById(e)??await c.fetchOrder(e))},{immediate:!0}),t(u,e=>{f(e)}),{orderId:l,order:u,invoiceReady:d}}export{o as t};
+4 -3
View File
@@ -6,15 +6,16 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="theme-color" content="#17379f">
<title>سامانه سفارش عمده پارچه</title>
<script type="module" crossorigin src="/assets/index-DDi4iM2C.js"></script>
<script type="module" crossorigin src="/assets/index-DXso6ia7.js"></script>
<link rel="modulepreload" crossorigin href="/assets/BasicIcon-B6lR-mG3.js">
<link rel="modulepreload" crossorigin href="/assets/http-CHgEV7QF.js">
<link rel="modulepreload" crossorigin href="/assets/dist-BEjUUhLz.js">
<link rel="modulepreload" crossorigin href="/assets/dist-BcgVHqJQ.js">
<link rel="modulepreload" crossorigin href="/assets/dist-DwqEDRqq.js">
<link rel="modulepreload" crossorigin href="/assets/format-BHJptHdF.js">
<link rel="modulepreload" crossorigin href="/assets/validation-BD7oi-2I.js">
<link rel="modulepreload" crossorigin href="/assets/catalog-DNpqlweh.js">
<link rel="stylesheet" crossorigin href="/assets/BasicIcon-QF_b9Svq.css">
<link rel="stylesheet" crossorigin href="/assets/index-Db2rZFq1.css">
<link rel="stylesheet" crossorigin href="/assets/index-CREBAUB-.css">
</head>
<body>
<div id="app"></div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

+4 -4
View File
@@ -6,8 +6,8 @@
--color-primary-dark: #062428;
--color-primary-light: #e8f4f1;
--color-primary-rgb: 10, 53, 60;
--color-accent-navy: #1b223c;
--color-accent-navy-rgb: 27, 34, 60;
--color-accent-navy: #0a353c;
--color-accent-navy-rgb: 10, 53, 60;
--color-success: #1b8a5a;
--color-success-light: #eaf8f1;
--color-success-soft: #eaf8f1;
@@ -69,8 +69,8 @@ html.dark {
--color-primary-dark: #7ad0c5;
--color-primary-light: #14353a;
--color-primary-rgb: 94, 184, 173;
--color-accent-navy: #9bb0d0;
--color-accent-navy-rgb: 155, 176, 208;
--color-accent-navy: #5eb8ad;
--color-accent-navy-rgb: 94, 184, 173;
--color-success: #3dd68c;
--color-success-light: #123528;
--color-success-soft: #123528;
+134
View File
@@ -0,0 +1,134 @@
import milano from '@/assets/images/catalogs/milano.jpg'
import najran from '@/assets/images/catalogs/najran.jpg'
import payizeh from '@/assets/images/catalogs/payizeh.jpg'
import classic from '@/assets/images/catalogs/classic.jpg'
import tarhdar from '@/assets/images/catalogs/tarhdar.jpg'
import fastoni from '@/assets/images/catalogs/fastoni.jpg'
import type { CatalogGalleryCard } from '@/utils/catalogGallery'
import type { CatalogProductCard } from '@/types/crm'
export const CALITE_COVERS = [milano, najran, payizeh, classic, tarhdar, fastoni]
export const MOCK_CALITE_CARDS: CatalogGalleryCard[] = [
{
id: 'demo-milano',
companyId: '',
name: 'میلانو',
title: 'کالیته میلانو',
latinName: 'Milano',
subtitle: 'پارچه‌های کت‌وشلواری',
imageUrl: milano,
patternCount: 16,
badge: 'new',
season: 'all_season',
isNew: true,
isPopular: false,
},
{
id: 'demo-najran',
companyId: '',
name: 'نجران',
title: 'کالیته نجران',
latinName: 'Najran',
subtitle: 'پارچه‌های پیراهنی',
imageUrl: najran,
patternCount: 14,
season: 'all_season',
isNew: false,
isPopular: false,
},
{
id: 'demo-payizeh',
companyId: '',
name: 'پاییزه',
title: 'کالیته پاییزه',
latinName: 'Payizeh',
subtitle: 'پارچه‌های شلواری',
imageUrl: payizeh,
patternCount: 18,
season: 'all_season',
isNew: false,
isPopular: false,
},
{
id: 'demo-classic',
companyId: '',
name: 'کلاسیک',
title: 'کالیته کلاسیک',
latinName: 'Classic',
subtitle: 'پارچه‌های کت‌وشلواری',
imageUrl: classic,
patternCount: 16,
season: 'all_season',
isNew: false,
isPopular: false,
},
{
id: 'demo-tarhdar',
companyId: '',
name: 'طرح‌دار',
title: 'کالیته طرح‌دار',
latinName: 'Tarhdar',
subtitle: 'پارچه‌های مجلسی',
imageUrl: tarhdar,
patternCount: 20,
badge: 'popular',
season: 'winter',
isNew: false,
isPopular: true,
},
{
id: 'demo-fastoni',
companyId: '',
name: 'فاستونی',
title: 'کالیته فاستونی',
latinName: 'Fastoni',
subtitle: 'پارچه‌های مناسب چهار فصل',
imageUrl: fastoni,
patternCount: 20,
season: 'all_season',
isNew: false,
isPopular: false,
},
]
export function coverForIndex(index: number) {
return CALITE_COVERS[index % CALITE_COVERS.length]
}
export function seasonLine(card: CatalogGalleryCard) {
if (card.id === 'demo-classic') return 'مناسب چهار فصل'
if (card.season === 'winter') return 'مناسب زمستان'
if (card.season === 'summer') return 'مناسب تابستان'
return 'مناسب چهار فصل'
}
export function findMockCalite(id: string) {
return MOCK_CALITE_CARDS.find((card) => card.id === id)
}
export function demoProductsFor(card: CatalogGalleryCard): CatalogProductCard[] {
const names = [`${card.name} ۱۰۱`, `${card.name} ۱۰۲`, `${card.name} ۱۰۳`, `${card.name} ۱۰۴`]
const kinds = ['plain', 'melange', 'patterned', 'plain'] as const
return names.map((name, index) => ({
id: `${card.id}-${index + 1}`,
name,
code: `${card.latinName || card.name}-${101 + index}`,
categoryId: card.subtitle.includes('پیراهن')
? 'shirt'
: card.subtitle.includes('شلوار')
? 'trousers'
: 'suit',
season: card.season,
widthCm: 150,
composition: 'پشم و پلی‌استر',
weaveType: kinds[index] === 'plain' ? 'ساده' : kinds[index] === 'melange' ? 'ملانژ' : 'طرح‌دار',
colors: ['#111827', '#6b7280', '#d6d3d1', '#1e3a5f'].slice(0, 3 + (index % 2)),
tags: [kinds[index] === 'patterned' ? 'طرح‌دار' : kinds[index] === 'melange' ? 'ملانژ' : 'ساده'],
isNew: index === 0,
imageUrl: card.imageUrl,
subtitle: card.subtitle,
rollMeters: 50,
}))
}
+3 -1
View File
@@ -33,7 +33,9 @@ const isWideGuest = computed(() => {
return wideRoutes.includes(route.name as string)
})
const isImmersiveAuth = computed(() => route.name === 'login' || route.name === 'register')
const isImmersiveAuth = computed(
() => route.name === 'login' || route.name === 'register' || route.name === 'otp',
)
</script>
<template>
+6
View File
@@ -58,6 +58,12 @@ const router = createRouter({
component: () => import('@/views/catalogs/CatalogsHubView.vue'),
meta: { requiresAuth: true },
},
{
path: '/catalogs/:catalogId',
name: 'catalog-detail',
component: () => import('@/views/catalogs/CatalogDetailView.vue'),
meta: { requiresAuth: true },
},
{
path: '/catalog-request',
name: 'catalog-request',
+1
View File
@@ -79,6 +79,7 @@ export interface Catalog {
name: string
code: string
description?: string
imageUrl?: string
displayOrder: number
isActive: boolean
productCount?: number
+172
View File
@@ -0,0 +1,172 @@
import type { Catalog } from '@/types'
import type { CatalogProductCard, SeasonKind } from '@/types/crm'
export type CatalogGalleryFilter = 'all' | 'newest' | 'popular' | 'season'
export type PatternKind = 'plain' | 'melange' | 'patterned'
export interface CatalogGalleryCard {
id: string
companyId: string
name: string
title: string
latinName: string
subtitle: string
imageUrl?: string
patternCount: number
badge?: 'new' | 'popular'
season: SeasonKind
isNew: boolean
isPopular: boolean
}
export interface CatalogPatternCard {
id: string
name: string
imageUrl?: string
colorCount: number
colors: string[]
kind: PatternKind | 'other'
items: CatalogProductCard[]
}
const USAGE_SUBTITLE: Record<string, string> = {
suit: 'پارچه‌های کت‌وشلواری',
trousers: 'پارچه‌های شلواری',
shirt: 'پارچه‌های پیراهنی',
}
export const SEASON_LABEL: Record<SeasonKind, string> = {
summer: 'تابستانه',
winter: 'زمستانه',
all_season: 'چهار فصل',
}
export function catalogDisplayTitle(name: string) {
const trimmed = name.trim()
return trimmed.includes('کالیته') ? trimmed : `کالیته ${trimmed}`
}
export function catalogLatinName(catalog: Catalog) {
const fromDescription = catalog.description?.match(/[A-Za-z][A-Za-z0-9 .&-]{1,28}/)?.[0]?.trim()
if (fromDescription) return fromDescription
if (/^[A-Za-z]/.test(catalog.code)) return catalog.code
return ''
}
function majority<T extends string>(values: T[], fallback: T): T {
if (!values.length) return fallback
const counts = new Map<T, number>()
for (const value of values) {
counts.set(value, (counts.get(value) ?? 0) + 1)
}
return [...counts.entries()].sort((a, b) => b[1] - a[1])[0]?.[0] ?? fallback
}
export function patternKindOf(product: CatalogProductCard): PatternKind | 'other' {
const hay = `${product.weaveType ?? ''} ${product.tags.join(' ')} ${product.name}`
if (/ملانژ|melange|mélange|heather/i.test(hay)) return 'melange'
if (/طرح‌?دار|striped?|check|print|jacquard|pattern/i.test(hay)) return 'patterned'
if (/ساده|plain|solid/i.test(hay)) return 'plain'
return 'other'
}
export function groupCatalogPatterns(products: CatalogProductCard[]): CatalogPatternCard[] {
const groups = new Map<string, CatalogProductCard[]>()
for (const product of products) {
const key = product.name.trim() || product.code
const list = groups.get(key) ?? []
list.push(product)
groups.set(key, list)
}
return [...groups.entries()].map(([, items]) => {
const colors = [
...new Set(
items.flatMap((item) =>
item.colors.length ? item.colors : item.color ? [item.color] : [],
),
),
]
return {
id: items[0].id,
name: items[0].name,
imageUrl: items.find((item) => item.imageUrl)?.imageUrl,
colorCount: Math.max(colors.length, items.length),
colors: colors.slice(0, 5),
kind: patternKindOf(items[0]),
items,
}
})
}
export function buildCatalogGallery(
catalogs: Catalog[],
products: CatalogProductCard[],
): CatalogGalleryCard[] {
const byCatalog = new Map<string, CatalogProductCard[]>()
for (const product of products) {
if (!product.catalogId) continue
const list = byCatalog.get(product.catalogId) ?? []
list.push(product)
byCatalog.set(product.catalogId, list)
}
const counts = catalogs.map((catalog) => byCatalog.get(catalog.id)?.length ?? catalog.productCount ?? 0)
const popularThreshold = Math.max(4, [...counts].sort((a, b) => b - a)[Math.floor(catalogs.length / 3)] ?? 4)
return catalogs.map((catalog) => {
const items = byCatalog.get(catalog.id) ?? []
const patternCount = groupCatalogPatterns(items).length || items.length || catalog.productCount || 0
const usage = majority(
items.map((item) => item.categoryId),
'suit',
)
const season = majority(
items.map((item) => item.season),
'all_season',
)
const isNew = items.some((item) => item.isNew)
const isPopular = patternCount >= popularThreshold
return {
id: catalog.id,
companyId: catalog.companyId,
name: catalog.name,
title: catalogDisplayTitle(catalog.name),
latinName: catalogLatinName(catalog),
subtitle: catalog.description?.trim() || USAGE_SUBTITLE[usage] || 'پارچه‌های منتخب',
imageUrl: catalog.imageUrl || items.find((item) => item.imageUrl)?.imageUrl,
patternCount,
badge: isNew ? 'new' : isPopular ? 'popular' : undefined,
season,
isNew,
isPopular,
}
})
}
export function filterCatalogGallery(
cards: CatalogGalleryCard[],
filter: CatalogGalleryFilter,
query: string,
) {
const needle = query.trim().toLowerCase()
let list = cards.filter((card) => {
if (!needle) return true
return [card.title, card.name, card.latinName, card.subtitle]
.join(' ')
.toLowerCase()
.includes(needle)
})
if (filter === 'newest') {
return list.sort((a, b) => Number(b.isNew) - Number(a.isNew) || b.patternCount - a.patternCount)
}
if (filter === 'popular') {
return list.sort((a, b) => Number(b.isPopular) - Number(a.isPopular) || b.patternCount - a.patternCount)
}
if (filter === 'season') {
const order: SeasonKind[] = ['summer', 'winter', 'all_season']
return list.sort((a, b) => order.indexOf(a.season) - order.indexOf(b.season) || a.title.localeCompare(b.title, 'fa'))
}
return list
}
+3 -3
View File
@@ -393,7 +393,7 @@ onMounted(async () => {
padding: 0 44px;
border: none;
border-radius: 999px;
background: #1e4644;
background: var(--color-primary);
color: #f7f4ef;
font-family: inherit;
font-size: 0.9375rem;
@@ -404,7 +404,7 @@ onMounted(async () => {
.login-submit:not(:disabled):hover,
.login-submit:not(:disabled):focus-visible {
background: #173835;
background: var(--color-primary-hover);
}
.login-submit:focus-visible {
@@ -445,7 +445,7 @@ onMounted(async () => {
.login-register a {
font-weight: 700;
color: #1e4644;
color: var(--color-primary);
text-decoration: none;
}
+314 -61
View File
@@ -4,10 +4,10 @@ import { useRoute, useRouter } from 'vue-router'
import { useIntervalFn } from '@vueuse/core'
import { useAuthStore } from '@/stores/auth'
import FormErrorBanner from '@/components/ui/FormErrorBanner.vue'
import BaseButton from '@/components/ui/BaseButton.vue'
import AuthThemeToggle from '@/components/ui/AuthThemeToggle.vue'
import IconEditPen from '@/components/icons/IconEditPen.vue'
import IconChevronBack from '@/components/icons/IconChevronBack.vue'
import IconChevronLeft from '@/components/icons/IconChevronLeft.vue'
import IconQemashMark from '@/components/icons/IconQemashMark.vue'
import { toPersianDigits, extractNumericString, normalizePhone } from '@/utils/format'
import {
FORM_VALIDATION_SUMMARY,
@@ -16,6 +16,7 @@ import {
type FieldErrors,
} from '@/utils/formErrors'
import { getPendingRegister } from '@/utils/pendingRegister'
import fabricUrl from '@/assets/images/login-fabric.jpg'
const OTP_LENGTH = 4
const RESEND_SECONDS = 60
@@ -231,29 +232,40 @@ onMounted(() => {
</script>
<template>
<div class="page auth-page">
<header class="auth-top">
<button
type="button"
class="icon-btn"
aria-label="بازگشت"
@click="router.push(isRegister ? '/register' : '/login')"
>
<IconChevronBack :size="20" />
</button>
<h1 class="auth-top__title">تأیید موبایل</h1>
<AuthThemeToggle variant="inline" />
</header>
<div class="page otp-page">
<img class="otp-page__bg" :src="fabricUrl" alt="" />
<div class="page__scroll auth-body">
<p class="auth-lead">کد ارسال‌شده به {{ toPersianDigits(phone) }} را وارد کنید.</p>
<div class="otp-page__scroll">
<div class="otp-page__stage">
<header class="otp-top">
<button
type="button"
class="otp-top__back"
aria-label="بازگشت"
@click="router.push(isRegister ? '/register' : '/login')"
>
<IconChevronBack :size="20" />
</button>
</header>
<form class="card" @submit.prevent="submit">
<FormErrorBanner :message="formError" />
<div class="otp-brand">
<IconQemashMark :size="72" />
<h1 class="otp-brand__fa">نادمی تکس</h1>
<p class="otp-brand__en">NADEMITEX</p>
</div>
<form class="otp-card" @submit.prevent="submit">
<h2 class="otp-card__title">تأیید موبایل</h2>
<p class="otp-card__lead">
کد ارسال‌شده به
<span dir="ltr">{{ toPersianDigits(phone) }}</span>
را وارد کنید.
</p>
<FormErrorBanner :message="formError" />
<div class="form-group">
<div
class="otp-row flex w-full max-w-full justify-center ltr"
class="otp-row"
dir="ltr"
role="group"
aria-label="کد تأیید"
@@ -276,55 +288,178 @@ onMounted(() => {
@paste="onDigitPaste(index, $event)"
/>
</div>
<p v-if="fieldErrors.code" class="input-error-text">{{ fieldErrors.code }}</p>
</div>
<p v-if="fieldErrors.code" class="otp-card__error">{{ fieldErrors.code }}</p>
<BaseButton block type="submit" :loading="auth.loading">تأیید و ورود</BaseButton>
<BaseButton
block
variant="outline"
type="button"
class="mt-2"
:disabled="!canResend"
@click="resend"
>
<template v-if="canResend">ارسال مجدد کد</template>
<template v-else>ارسال مجدد کد ({{ timerLabel }})</template>
</BaseButton>
<button class="otp-submit" type="submit" :disabled="auth.loading">
<span v-if="auth.loading" class="otp-submit__spinner" aria-hidden="true" />
<span class="otp-submit__chevron" aria-hidden="true">
<IconChevronLeft :size="18" color="#F4EDE4" />
</span>
<span>تأیید و ورود</span>
</button>
<button
type="button"
class="mt-3 mx-auto flex items-center justify-center gap-1.5 border-0 bg-transparent p-0 text-sm text-muted cursor-pointer transition-colors hover:text-text"
@click="changePhone"
>
<span class="ltr tabular-nums" dir="ltr">{{ toPersianDigits(phone) }}</span>
<span>ویرایش شماره</span>
<IconEditPen :size="18" :stroke-width="1.5" />
</button>
</form>
<button
class="otp-resend"
type="button"
:disabled="!canResend"
@click="resend"
>
<template v-if="canResend">ارسال مجدد کد</template>
<template v-else>ارسال مجدد کد ({{ timerLabel }})</template>
</button>
<button type="button" class="otp-edit" @click="changePhone">
<span dir="ltr">{{ toPersianDigits(phone) }}</span>
<span>ویرایش شماره</span>
<IconEditPen :size="16" :stroke-width="1.5" />
</button>
</form>
<div class="otp-spacer" aria-hidden="true" />
<p class="otp-watermark">MORE<br />THAN<br />FABRIC</p>
</div>
</div>
</div>
</template>
<style scoped>
.otp-page {
position: relative;
isolation: isolate;
height: 100%;
min-height: 100%;
color: #f4ede4;
background: #1a1612;
overflow: hidden;
}
.otp-page__bg {
position: absolute;
inset: 0;
z-index: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center center;
pointer-events: none;
user-select: none;
}
.otp-page__scroll {
position: relative;
z-index: 1;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
}
.otp-page__stage {
display: flex;
flex-direction: column;
min-height: 100%;
width: 100%;
max-width: 360px;
margin-inline: auto;
padding: calc(10px + env(safe-area-inset-top, 0px)) 16px
calc(14px + env(safe-area-inset-bottom, 0px));
}
.otp-top {
display: flex;
align-items: center;
justify-content: flex-end;
min-height: 36px;
}
.otp-top__back {
width: 36px;
height: 36px;
border: none;
border-radius: 999px;
background: rgba(244, 237, 228, 0.14);
color: #f3e6d6;
display: grid;
place-items: center;
cursor: pointer;
}
.otp-brand {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
margin-top: 18px;
margin-bottom: 18px;
color: #f3e6d6;
}
.otp-brand__fa {
margin: 12px 0 0;
font-size: 1.625rem;
font-weight: 700;
line-height: 1.25;
}
.otp-brand__en {
margin: 6px 0 0;
font-size: 0.6875rem;
font-weight: 500;
letter-spacing: 0.28em;
color: #ead7c0;
}
.otp-card {
width: 100%;
margin: 0;
padding: 22px 18px 18px;
border: none;
border-radius: 28px;
background: #f4f1ed;
box-shadow: 0 18px 40px rgba(12, 10, 8, 0.22);
color: #2a2622;
}
.otp-card__title {
margin: 0;
text-align: center;
font-size: 1.0625rem;
font-weight: 700;
line-height: 1.5;
color: #1c1b19;
}
.otp-card__lead {
margin: 6px 0 0;
text-align: center;
font-size: 0.75rem;
line-height: 1.7;
color: #8a847c;
}
.otp-card :deep(.form-error-banner) {
margin-top: 14px;
margin-bottom: 0;
}
.otp-row {
gap: clamp(0.25rem, 1.8vw, 0.625rem);
display: flex;
justify-content: center;
gap: 10px;
margin-top: 18px;
}
.otp-box {
flex: 1 1 0;
width: 0;
min-width: 0;
max-width: 48px;
aspect-ratio: 48 / 52;
height: auto;
width: 52px;
height: 56px;
padding: 0;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: var(--color-surface);
color: var(--color-text);
font-size: clamp(0.95rem, 4.2vw, 1.25rem);
font-weight: 600;
border: 1px solid #e4e0db;
border-radius: 16px;
background: #f7f5f1;
color: #1c1b19;
font-family: inherit;
font-size: 1.25rem;
font-weight: 700;
text-align: center;
caret-color: var(--color-primary);
transition: border-color 0.15s;
@@ -333,15 +468,133 @@ onMounted(() => {
.otp-box:focus {
outline: none;
border-color: var(--color-primary);
background: #fff;
}
.otp-box--error {
border-color: var(--color-danger);
border-color: color-mix(in srgb, var(--color-danger) 55%, #e4e0db);
}
.input-error-text {
.otp-card__error {
margin: 8px 4px 0;
color: var(--color-danger);
font-size: 0.75rem;
text-align: center;
}
.otp-submit {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 48px;
margin-top: 16px;
padding: 0 44px;
border: none;
border-radius: 999px;
background: var(--color-primary);
color: #f7f4ef;
font-family: inherit;
font-size: 0.9375rem;
font-weight: 600;
cursor: pointer;
transition: background 0.15s ease;
}
.otp-submit:not(:disabled):hover,
.otp-submit:not(:disabled):focus-visible {
background: var(--color-primary-hover);
}
.otp-submit:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.otp-submit__chevron {
position: absolute;
inset-inline-end: 16px;
display: grid;
place-items: center;
}
.otp-submit__spinner {
position: absolute;
inset-inline-start: 16px;
width: 16px;
height: 16px;
border: 2px solid rgba(255, 255, 255, 0.28);
border-top-color: #fff;
border-radius: 50%;
animation: otp-spin 0.6s linear infinite;
}
.otp-resend {
width: 100%;
height: 48px;
margin-top: 10px;
border: 1px solid #d8d3cd;
border-radius: 999px;
background: transparent;
color: #6f6b66;
font-family: inherit;
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
}
.otp-resend:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.otp-edit {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
width: 100%;
margin-top: 14px;
border: none;
background: transparent;
color: #8a847c;
font-family: inherit;
font-size: 0.8125rem;
margin: 4px 0 0;
cursor: pointer;
}
.otp-spacer {
flex: 1 1 auto;
min-height: 16px;
}
.otp-watermark {
margin: 0;
padding-bottom: 8px;
color: rgba(244, 237, 228, 0.58);
font-size: 0.625rem;
font-weight: 600;
letter-spacing: 0.2em;
line-height: 1.35;
text-align: left;
direction: ltr;
}
@keyframes otp-spin {
to {
transform: rotate(360deg);
}
}
@media (min-width: 768px) {
.otp-page {
padding: 0;
max-width: none;
margin: 0;
height: 100%;
min-height: 0;
overflow: hidden;
}
}
</style>
+6 -6
View File
@@ -473,7 +473,7 @@ async function submit() {
}
.job-trigger.is-open {
border-color: #1e4644;
border-color: var(--color-primary);
}
.job-chevron {
@@ -517,7 +517,7 @@ async function submit() {
.job-option.is-active {
background: #e8f0ee;
color: #1e4644;
color: var(--color-primary);
font-weight: 600;
}
@@ -532,7 +532,7 @@ async function submit() {
padding: 0 44px;
border: none;
border-radius: 999px;
background: #1e4644;
background: var(--color-primary);
color: #f7f4ef;
font: inherit;
font-size: 0.9375rem;
@@ -543,7 +543,7 @@ async function submit() {
.register-submit:not(:disabled):hover,
.register-submit:not(:disabled):focus-visible {
background: #173835;
background: var(--color-primary-hover);
}
.register-submit:disabled {
@@ -605,8 +605,8 @@ async function submit() {
}
.register-terms__box.is-on {
border-color: #1e4644;
background: #1e4644;
border-color: var(--color-primary);
background: var(--color-primary);
}
.register-terms__box svg {
+830
View File
@@ -0,0 +1,830 @@
<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import PageSkeleton from '@/components/ui/PageSkeleton.vue'
import IconChevronBack from '@/components/icons/IconChevronBack.vue'
import IconChevronLeft from '@/components/icons/IconChevronLeft.vue'
import IconShare from '@/components/icons/IconShare.vue'
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
import { useCatalogStore } from '@/stores/catalog'
import { useCrmStore } from '@/stores/crm'
import { useCartStore } from '@/stores/cart'
import { useFavoritesStore } from '@/stores/favorites'
import { useGoBack } from '@/composables/useGoBack'
import type { Catalog } from '@/types'
import type { Product } from '@/types'
import type { CatalogProductCard } from '@/types/crm'
import {
SEASON_LABEL,
catalogDisplayTitle,
catalogLatinName,
groupCatalogPatterns,
type PatternKind,
} from '@/utils/catalogGallery'
import { formatNumber } from '@/utils/format'
import { demoProductsFor, findMockCalite } from '@/data/caliteCollections'
const route = useRoute()
const router = useRouter()
const { goBack } = useGoBack('/catalogs')
const catalogStore = useCatalogStore()
const crm = useCrmStore()
const cartStore = useCartStore()
const favorites = useFavoritesStore()
const catalogId = computed(() => String(route.params.catalogId ?? ''))
const catalog = ref<Catalog | null>(null)
const products = ref<CatalogProductCard[]>([])
const loading = ref(true)
const error = ref<string | null>(null)
const adding = ref(false)
const toast = ref('')
const tab = ref<'all' | PatternKind>('all')
const title = computed(() => catalogDisplayTitle(catalog.value?.name || 'کالیته'))
const heroImage = computed(
() =>
catalog.value?.imageUrl
|| (catalog.value ? findMockCalite(catalog.value.id)?.imageUrl : undefined)
|| products.value.find((item) => item.imageUrl)?.imageUrl,
)
const latinName = computed(() => {
const mock = catalog.value ? findMockCalite(catalog.value.id) : undefined
if (mock?.latinName) return mock.latinName
return catalog.value ? catalogLatinName(catalog.value) : ''
})
const usageLine = computed(() => {
const mock = catalog.value ? findMockCalite(catalog.value.id) : undefined
if (mock?.subtitle) return mock.subtitle
const id = products.value[0]?.categoryId
if (id === 'trousers') return 'پارچه‌های شلواری'
if (id === 'shirt') return 'پارچه‌های پیراهنی'
return 'پارچه‌های کت‌وشلواری'
})
const patterns = computed(() => groupCatalogPatterns(products.value))
const visiblePatterns = computed(() =>
tab.value === 'all' ? patterns.value : patterns.value.filter((item) => item.kind === tab.value),
)
const seasonLabel = computed(() => {
const mock = catalog.value ? findMockCalite(catalog.value.id) : undefined
if (mock) return SEASON_LABEL[mock.season]
const counts: Record<string, number> = {}
for (const product of products.value) {
counts[product.season] = (counts[product.season] ?? 0) + 1
}
const top = Object.entries(counts).sort((a, b) => b[1] - a[1])[0]?.[0] as keyof typeof SEASON_LABEL | undefined
return top ? SEASON_LABEL[top] : SEASON_LABEL.all_season
})
const tabs = computed(() => [
{ id: 'all' as const, label: 'همه طرح‌ها', count: patterns.value.length },
{
id: 'plain' as const,
label: 'ساده',
count: patterns.value.filter((item) => item.kind === 'plain').length,
},
{
id: 'melange' as const,
label: 'ملانژ',
count: patterns.value.filter((item) => item.kind === 'melange').length,
},
{
id: 'patterned' as const,
label: 'طرح‌دار',
count: patterns.value.filter((item) => item.kind === 'patterned').length,
},
])
async function load() {
loading.value = true
error.value = null
catalog.value = null
products.value = []
tab.value = 'all'
try {
const companies = await catalogStore.loadCompanies()
if (!catalogStore.getCatalog(catalogId.value)) {
await Promise.all(companies.map((company) => catalogStore.loadCatalogs(company.id)))
}
catalog.value = catalogStore.getCatalog(catalogId.value) ?? null
const mock = findMockCalite(catalogId.value)
if (!catalog.value && mock) {
catalog.value = {
id: mock.id,
companyId: '',
name: mock.name,
code: mock.latinName || mock.name,
description: 'ترکیبی از اصالت، کیفیت و استایل مدرن',
displayOrder: 0,
isActive: true,
}
products.value = demoProductsFor(mock)
return
}
if (!catalog.value) {
error.value = 'کالیته مورد نظر یافت نشد.'
return
}
products.value = await crm.loadBrowseProducts({
catalogId: catalog.value.id,
companyId: catalog.value.companyId,
})
if (!products.value.length && mock) {
products.value = demoProductsFor(mock)
}
} catch (e) {
error.value = e instanceof Error ? e.message : 'بارگذاری کالیته ناموفق بود.'
} finally {
loading.value = false
}
}
onMounted(async () => {
await favorites.hydrate()
await load()
})
watch(catalogId, load)
function openProduct(id: string) {
if (id.startsWith('demo-')) return
router.push({ path: '/product', query: { id } })
}
function toggleFavorite(id: string) {
void favorites.toggle(id)
}
function requestPhysical() {
router.push({
path: '/catalog-request',
query: { catalogId: catalogId.value },
})
}
function shareCatalog() {
const url = window.location.href
if (navigator.share) {
void navigator.share({ title: title.value, url }).catch(() => undefined)
return
}
void navigator.clipboard?.writeText(url)
}
function toCartProduct(item: CatalogProductCard): Product {
return {
id: item.id,
companyId: item.companyId || catalog.value?.companyId || '',
catalogId: item.catalogId || catalogId.value,
name: item.name,
code: item.code,
color: item.color || item.colors[0] || '—',
minMeterage: item.minMeterage ?? 30,
orderMultiplier: item.orderMultiplier ?? 10,
basePrice: item.basePrice,
isActive: true,
}
}
async function addAllToInquiry() {
if (!products.value.length || adding.value) return
adding.value = true
toast.value = ''
let added = 0
let failed = ''
try {
for (const item of products.value) {
const product = toCartProduct(item)
const result = await cartStore.addItem(
product,
catalog.value?.code || item.catalogCode || item.code,
product.minMeterage,
)
if (result.success) added += 1
else failed = result.message || failed
}
toast.value = added
? `${formatNumber(added)} طرح به سبد استعلام اضافه شد.`
: failed || 'افزودن به سبد ناموفق بود.'
if (added) {
window.setTimeout(() => router.push('/cart'), 650)
}
} finally {
adding.value = false
}
}
</script>
<template>
<div class="page calite-detail">
<div class="page__scroll page__scroll--with-nav calite-detail__scroll">
<section class="calite-hero">
<div
class="calite-hero__photo"
:style="heroImage ? { backgroundImage: `url(${heroImage})` } : undefined"
/>
<header class="calite-hero__nav">
<button type="button" class="icon-btn" aria-label="بازگشت" @click="goBack">
<IconChevronBack :size="22" color="#ffffff" />
</button>
<h1>{{ loading ? 'کالیته' : title }}</h1>
<button type="button" class="icon-btn" aria-label="اشتراک‌گذاری" @click="shareCatalog">
<IconShare :size="20" color="#ffffff" />
</button>
</header>
<div v-if="!loading && !error" class="calite-hero__copy">
<h2>{{ title }}</h2>
<p class="calite-hero__usage">{{ usageLine }}</p>
<strong v-if="latinName" class="calite-hero__latin">{{ latinName }}</strong>
<span class="calite-hero__tagline">{{
catalog?.description || 'ترکیبی از اصالت، کیفیت و استایل مدرن'
}}</span>
</div>
</section>
<div class="calite-detail__body">
<PageSkeleton v-if="loading" variant="cards" :rows="5" />
<p v-else-if="error" class="calite-detail__error">{{ error }}</p>
<template v-else>
<div class="attr-row">
<span class="attr">
<svg class="attr__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
{{ formatNumber(patterns.length) }} طرح
</span>
<span class="attr">
<svg class="attr__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<circle cx="12" cy="12" r="4" stroke="currentColor" stroke-width="1.5" />
<path
d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
/>
</svg>
{{ seasonLabel }}
</span>
<span class="attr">
<svg class="attr__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"
stroke="currentColor"
stroke-width="1.5"
stroke-linejoin="round"
/>
</svg>
پرطرفدار
</span>
<span class="attr">
<svg class="attr__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M2.7 10.3a2.41 2.41 0 0 0 0 3.41l7.59 7.59a2.41 2.41 0 0 0 3.41 0l7.59-7.59a2.41 2.41 0 0 0 0-3.41L13.7 2.71a2.41 2.41 0 0 0-3.41 0z"
stroke="currentColor"
stroke-width="1.5"
stroke-linejoin="round"
/>
</svg>
کیفیت ممتاز
</span>
</div>
<button type="button" class="physical-cta" @click="requestPhysical">
<span class="physical-cta__icon" aria-hidden="true">
<BasicIcon icon="vuesax-linear:truck-time" :size="20" color="#ffffff" />
</span>
درخواست دریافت فیزیکی کالیته
<span class="physical-cta__chevron" aria-hidden="true">
<IconChevronLeft :size="18" color="#ffffff" />
</span>
</button>
<div class="pattern-tabs" role="tablist" aria-label="نوع طرح">
<button
v-for="item in tabs"
:key="item.id"
type="button"
class="pattern-tab"
:class="{ 'is-on': tab === item.id }"
@click="tab = item.id"
>
{{ item.label }}<template v-if="item.id === 'all'"> ({{ formatNumber(item.count) }})</template>
</button>
</div>
<div class="pattern-grid">
<article
v-for="pattern in visiblePatterns"
:key="pattern.id"
class="pattern-card"
@click="openProduct(pattern.id)"
>
<div
class="pattern-card__photo"
:style="pattern.imageUrl ? { backgroundImage: `url(${pattern.imageUrl})` } : undefined"
>
<button
type="button"
class="pattern-card__fav"
:aria-pressed="favorites.isFavorite(pattern.id)"
:aria-label="
favorites.isFavorite(pattern.id) ? 'حذف از علاقه‌مندی‌ها' : 'افزودن به علاقه‌مندی‌ها'
"
@click.stop="toggleFavorite(pattern.id)"
>
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" aria-hidden="true">
<path
d="M12.1 20.3s-6.6-4.1-8.4-8.1c-1.4-3.1.1-6.7 3.4-7.5 1.9-.5 3.7.3 4.9 1.8 1.2-1.5 3-2.3 4.9-1.8 3.3.8 4.8 4.4 3.4 7.5-1.8 4-8.2 8.1-8.2 8.1Z"
:fill="favorites.isFavorite(pattern.id) ? 'var(--color-primary)' : 'none'"
stroke="var(--color-primary)"
stroke-width="1.5"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
<div class="pattern-card__meta">
<strong>{{ pattern.name }}</strong>
<div class="pattern-card__colors">
<span>{{ formatNumber(pattern.colorCount) }} رنگ</span>
<div class="swatches">
<i
v-for="(color, idx) in pattern.colors"
:key="idx"
:style="{ background: color }"
/>
</div>
</div>
</div>
</article>
</div>
<p v-if="!visiblePatterns.length" class="calite-detail__error">طرحی در این دسته نیست.</p>
</template>
</div>
</div>
<div v-if="!loading && products.length" class="sticky-footer">
<button type="button" class="inquiry-bar" :disabled="adding" @click="addAllToInquiry">
{{ adding ? 'در حال افزودن...' : 'افزودن همه به سبد استعلام' }}
<small>{{ formatNumber(patterns.length) }} طرح انتخاب می‌شود</small>
</button>
</div>
<p v-if="toast" class="toast">{{ toast }}</p>
</div>
</template>
<style scoped>
.calite-detail {
background: #f4f0ed;
color: #2a2622;
}
.calite-detail__nav,
.calite-hero__nav {
display: grid;
grid-template-columns: 44px 1fr 44px;
align-items: center;
padding: calc(6px + env(safe-area-inset-top, 0px)) 8px 2px;
}
.calite-hero__nav {
position: absolute;
inset-inline: 0;
top: 0;
z-index: 2;
background: transparent;
}
.calite-hero__nav h1 {
margin: 0;
text-align: center;
font-size: 1.0625rem;
font-weight: 700;
color: #fff;
}
.icon-btn {
width: 44px;
height: 44px;
border: none;
background: transparent;
color: #fff;
display: grid;
place-items: center;
cursor: pointer;
}
.calite-detail__scroll {
padding: 0 0 112px;
display: flex;
flex-direction: column;
gap: 0;
}
.calite-hero {
position: relative;
width: 100%;
min-height: 340px;
height: min(52vh, 440px);
overflow: hidden;
border-radius: 0;
color: #fff;
}
.calite-hero__photo {
position: absolute;
inset: 0;
background: linear-gradient(160deg, #3d4a55, #151b22);
background-size: cover;
background-position: center;
}
.calite-hero__photo::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(
180deg,
rgba(12, 10, 8, 0.28) 0%,
rgba(12, 10, 8, 0.08) 38%,
rgba(12, 10, 8, 0.55) 100%
);
}
.calite-hero__copy {
position: absolute;
inset-inline: 20px 20px;
bottom: 22px;
z-index: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-end;
gap: 2px;
min-height: 0;
padding: 0;
text-align: start;
}
.calite-hero__copy h2 {
margin: 0;
font-size: 1.5rem;
font-weight: 700;
line-height: 1.35;
text-shadow: 0 1px 8px rgba(0, 0, 0, 0.25);
}
.calite-hero__usage {
margin: 0;
font-size: 0.8125rem;
font-weight: 400;
opacity: 0.95;
}
.calite-hero__latin {
margin: 2px 0 0;
font-family: Georgia, "Times New Roman", serif;
font-size: 1.75rem;
font-style: italic;
font-weight: 400;
letter-spacing: 0.02em;
line-height: 1.2;
}
.calite-hero__tagline {
margin-top: 4px;
font-size: 0.75rem;
font-weight: 400;
opacity: 0.92;
}
.calite-detail__body {
padding: 8px 16px 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.attr-row {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 0;
padding: 4px 0 8px;
}
.attr {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
min-height: 0;
padding: 10px 8px;
border-radius: 0;
background: transparent;
color: #6f6b66;
font-size: 0.8125rem;
font-weight: 500;
text-align: center;
line-height: 1.4;
box-shadow: none;
}
.attr:not(:last-child)::after {
content: '';
position: absolute;
inset-inline-end: 0;
top: 16%;
bottom: 16%;
width: 1px;
background: #e4dfd8;
}
.attr__icon {
width: 26px;
height: 26px;
flex-shrink: 0;
}
.physical-cta {
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
min-height: 52px;
padding: 0 44px;
border: none;
border-radius: 999px;
background: var(--color-primary);
color: #fff;
font: inherit;
font-size: 0.875rem;
font-weight: 600;
cursor: pointer;
}
.physical-cta__icon {
display: grid;
place-items: center;
}
.physical-cta__chevron {
position: absolute;
inset-inline-end: 16px;
display: grid;
place-items: center;
color: #fff;
}
.pattern-tabs {
display: flex;
gap: 8px;
overflow-x: auto;
padding: 2px 0;
}
.pattern-tab {
flex-shrink: 0;
height: 34px;
padding: 0 14px;
border: none;
border-radius: 999px;
background: #ece8e2;
color: #6a645e;
font: inherit;
font-size: 0.8125rem;
font-weight: 500;
cursor: pointer;
}
.pattern-tab.is-on {
background: var(--color-primary);
color: #fff;
}
.pattern-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
.pattern-card {
display: flex;
flex-direction: column;
gap: 8px;
padding: 0 0 10px;
overflow: hidden;
border: none;
border-radius: 20px;
background: #fff;
text-align: start;
cursor: pointer;
color: #1c1c1c;
box-shadow: 0 1px 3px rgba(40, 32, 24, 0.05);
}
.pattern-card__photo {
position: relative;
width: 100%;
aspect-ratio: 1.08;
border-radius: 0;
background: linear-gradient(145deg, #2a3544, #111827);
background-size: cover;
background-position: center;
}
.pattern-card__fav {
position: absolute;
top: 8px;
left: 8px;
width: 28px;
height: 28px;
border: none;
background: transparent;
padding: 0;
display: grid;
place-items: center;
cursor: pointer;
}
.pattern-card__meta {
display: flex;
flex-direction: column;
gap: 4px;
padding: 0 10px 2px;
}
.pattern-card strong {
font-size: 0.875rem;
font-weight: 700;
line-height: 1.35;
}
.pattern-card__colors {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.pattern-card__colors span {
color: #8a847c;
font-size: 0.75rem;
}
.swatches {
display: flex;
gap: 4px;
}
.swatches i {
width: 10px;
height: 10px;
border-radius: 999px;
border: 1px solid rgba(0, 0, 0, 0.08);
}
.inquiry-bar {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2px;
width: 100%;
min-height: 56px;
border: none;
border-radius: 20px;
background: var(--color-primary);
color: #fff;
font: inherit;
font-size: 0.9375rem;
font-weight: 700;
cursor: pointer;
}
.inquiry-bar small {
font-size: 0.6875rem;
font-weight: 500;
opacity: 0.78;
}
.inquiry-bar:disabled {
opacity: 0.7;
}
.calite-detail__error {
margin: 8px 0 0;
text-align: center;
color: #8a847c;
}
.toast {
position: fixed;
left: 50%;
bottom: calc(var(--nav-height) + 84px);
z-index: 20;
transform: translateX(-50%);
padding: 8px 14px;
border-radius: 999px;
background: var(--color-primary);
color: #fff;
font-size: 0.75rem;
white-space: nowrap;
}
html.dark .calite-detail {
background: #0b0f14;
color: #eef2f8;
}
html.dark .calite-hero__nav h1,
html.dark .icon-btn {
color: #fff;
}
html.dark .attr {
background: transparent;
color: #c5d0de;
box-shadow: none;
}
html.dark .attr:not(:last-child)::after {
background: #2a3444;
}
html.dark .physical-cta {
background: var(--color-primary);
color: #fff;
}
html.dark .pattern-tab {
background: #1a2230;
color: #c5d0de;
}
html.dark .pattern-tab.is-on {
background: #e8e4df;
color: #121821;
}
html.dark .pattern-card {
background: #121821;
color: #eef2f8;
box-shadow: none;
}
html.dark .pattern-card__colors span,
html.dark .calite-detail__error {
color: #9aa8bc;
}
html.dark .inquiry-bar {
background: #5eb8ad;
color: #0b0f14;
}
@media (min-width: 768px) {
.calite-detail {
padding: 0;
max-width: none;
margin: 0;
overflow: hidden;
}
.calite-hero {
min-height: 380px;
height: min(48vh, 460px);
}
.toast {
bottom: 96px;
}
}
</style>
+1 -4
View File
@@ -32,10 +32,7 @@ onMounted(load)
watch(companyId, load)
function openCatalog(catalogId: string) {
router.push({
path: '/products',
query: { catalogId, companyId: companyId.value },
})
router.push({ name: 'catalog-detail', params: { catalogId } })
}
function getProductCount(catalogId: string) {
+4 -1
View File
@@ -21,6 +21,7 @@ const products = ref<CatalogProductCard[]>([])
const quantities = ref<Record<string, number>>({})
const preselectId = computed(() => String(route.query.productId ?? ''))
const catalogId = computed(() => String(route.query.catalogId ?? ''))
const selectedItems = computed(() =>
products.value
@@ -37,7 +38,9 @@ onMounted(async () => {
loading.value = true
error.value = null
try {
const list = await crm.loadBrowseProducts()
const list = await crm.loadBrowseProducts(
catalogId.value ? { catalogId: catalogId.value } : undefined,
)
const selected = preselectId.value
products.value = selected
? [...list].sort((a, b) => Number(b.id === selected) - Number(a.id === selected))
+349 -103
View File
@@ -1,165 +1,411 @@
<script setup lang="ts">
import { nextTick, onMounted, ref } from 'vue'
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import PageHeader from '@/components/layout/PageHeader.vue'
import SearchField from '@/components/ui/SearchField.vue'
import IconSearch from '@/components/icons/IconSearch.vue'
import IconChevronBack from '@/components/icons/IconChevronBack.vue'
import AuthThemeToggle from '@/components/ui/AuthThemeToggle.vue'
import PageSkeleton from '@/components/ui/PageSkeleton.vue'
import { useCatalogStore } from '@/stores/catalog'
import { useCrmStore } from '@/stores/crm'
import { useGoBack } from '@/composables/useGoBack'
import type { Catalog } from '@/types'
import IconChevronLeft from '@/components/icons/IconChevronLeft.vue'
import type { CatalogProductCard } from '@/types/crm'
import {
buildCatalogGallery,
filterCatalogGallery,
type CatalogGalleryFilter,
} from '@/utils/catalogGallery'
import { formatNumber } from '@/utils/format'
const route = useRoute()
const router = useRouter()
const { goBack } = useGoBack('/')
const catalogStore = useCatalogStore()
const crm = useCrmStore()
const catalogs = ref<Catalog[]>([])
const products = ref<CatalogProductCard[]>([])
const loading = ref(true)
const error = ref<string | null>(null)
const searchOpen = ref(false)
const search = ref('')
const filter = ref<CatalogGalleryFilter>('all')
const filters: { id: CatalogGalleryFilter; label: string }[] = [
{ id: 'all', label: 'همه' },
{ id: 'newest', label: 'جدیدترین' },
{ id: 'popular', label: 'محبوب‌ترین' },
{ id: 'season', label: 'بر اساس فصل' },
]
const gallery = computed(() => buildCatalogGallery(catalogs.value, products.value))
const cards = computed(() => filterCatalogGallery(gallery.value, filter.value, search.value))
onMounted(async () => {
try {
const companies = await catalogStore.loadCompanies()
const lists = await Promise.all(companies.map((c) => catalogStore.loadCatalogs(c.id)))
const [lists, browse] = await Promise.all([
Promise.all(companies.map((company) => catalogStore.loadCatalogs(company.id))),
crm.loadBrowseProducts().catch(() => [] as CatalogProductCard[]),
])
catalogs.value = lists.flat()
products.value = browse
const focusId = String(route.query.id ?? '')
if (focusId) {
const hit = catalogs.value.find((c) => c.id === focusId)
if (hit) {
await nextTick()
openCatalog(hit)
}
if (focusId && catalogs.value.some((item) => item.id === focusId)) {
router.replace({ name: 'catalog-detail', params: { catalogId: focusId } })
}
} catch (e) {
error.value = e instanceof Error ? e.message : 'بارگذاری کالیته‌ها ناموفق بود.'
} catch {
catalogs.value = []
} finally {
loading.value = false
}
})
function openCatalog(item: Catalog) {
router.push({
path: '/products',
query: { catalogId: item.id, companyId: item.companyId },
})
function openCatalog(id: string) {
router.push({ name: 'catalog-detail', params: { catalogId: id } })
}
function companyName(companyId: string) {
return catalogStore.getCompany(companyId)?.name ?? 'برند'
function toggleSearch() {
searchOpen.value = !searchOpen.value
if (!searchOpen.value) search.value = ''
}
function metaLine(card: (typeof gallery.value)[number]) {
const extra =
card.season === 'winter'
? 'مناسب زمستان'
: card.season === 'summer'
? 'مناسب تابستان'
: 'مناسب چهار فصل'
return `${formatNumber(card.patternCount)} طرح • ${extra}`
}
</script>
<template>
<div class="page">
<PageHeader title="کالیته‌ها" show-back centered @back="router.push('/')" />
<div class="page__scroll page__scroll--with-nav catalog-hub">
<button type="button" class="hub-card" @click="router.push('/catalog-request')">
<strong>درخواست کالیته فیزیکی</strong>
<span>ثبت اقلام و پیگیری وضعیت</span>
<div class="page calite-hub">
<header class="calite-hub__nav">
<button type="button" class="icon-btn" aria-label="بازگشت" @click="goBack">
<IconChevronBack :size="20" />
</button>
<button type="button" class="hub-card" @click="router.push('/catalog-requests')">
<strong>وضعیت درخواست‌ها</strong>
<span>پیگیری کالیته‌های ثبت‌شده</span>
</button>
<button type="button" class="hub-card" @click="router.push('/categories')">
<strong>مشاهده دسته‌بندی‌ها</strong>
<span>انتخاب بر اساس کاربرد و فصل</span>
</button>
<button type="button" class="hub-card" @click="router.push('/products')">
<strong>همه محصولات</strong>
<span>مشاهده کاتالوگ و ثبت سفارش</span>
</button>
<PageSkeleton v-if="loading" variant="grid" />
<p v-else-if="error">{{ error }}</p>
<template v-else>
<h2 class="section-title">کالیته‌های موجود</h2>
<h1>کالیته‌ها</h1>
<div class="calite-hub__nav-end">
<AuthThemeToggle variant="inline" class="mobile-only" />
<button
v-for="item in catalogs"
type="button"
class="icon-btn"
:aria-label="searchOpen ? 'بستن جستجو' : 'جستجو'"
:aria-pressed="searchOpen"
@click="toggleSearch"
>
<IconSearch :size="20" />
</button>
</div>
</header>
<div class="page__scroll page__scroll--with-nav calite-hub__scroll">
<p class="calite-hub__lead">مجموعه‌ای از بهترین پارچه‌ها، در یک نگاه</p>
<SearchField
v-if="searchOpen"
:model-value="search"
placeholder="جستجوی نام کالیته..."
@update:model-value="search = $event"
/>
<div class="calite-hub__chips" role="tablist" aria-label="مرتب‌سازی کالیته‌ها">
<button
v-for="item in filters"
:key="item.id"
type="button"
class="calite-item"
:class="{ 'calite-item--focus': String(route.query.id ?? '') === item.id }"
@click="openCatalog(item)"
class="calite-chip"
:class="{ 'is-on': filter === item.id }"
@click="filter = item.id"
>
<div class="calite-item__text">
<strong>{{ item.name }}</strong>
<span>کد {{ item.code }}</span>
<em>{{ companyName(item.companyId) }}</em>
</div>
<IconChevronLeft :size="18" color="#9aa3a0" />
{{ item.label }}
</button>
<p v-if="!catalogs.length" class="empty-hint">کالیته‌ای یافت نشد.</p>
</template>
</div>
<PageSkeleton v-if="loading" variant="cards" :rows="4" />
<p v-else-if="!cards.length" class="calite-hub__empty">کالیته‌ای یافت نشد.</p>
<div v-else class="calite-hub__list">
<button
v-for="card in cards"
:key="card.id"
type="button"
class="calite-card"
dir="ltr"
@click="openCatalog(card.id)"
>
<span
class="calite-card__photo"
:style="card.imageUrl ? { backgroundImage: `url(${card.imageUrl})` } : undefined"
/>
<span v-if="card.badge" class="calite-card__badge">
{{ card.badge === 'new' ? 'جدید' : 'پرفروش' }}
</span>
<div class="calite-card__copy" dir="rtl">
<svg class="calite-card__arrow" width="12" height="16" viewBox="0 0 8 12" fill="none"
aria-hidden="true">
<path
d="M1.5 1.5 6 6l-4.5 4.5"
stroke="#fff"
stroke-width="1.4"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<div class="mr-4 text-white">
<div class="text-lg font-bold">{{ card.title }}</div>
<div class="text-md">{{ card.subtitle }}</div>
<div class="text-xs mt-4">{{ metaLine(card) }}</div>
</div>
</div>
</button>
</div>
</div>
</div>
</template>
<style scoped>
.catalog-hub {
padding: 12px var(--page-padding) 24px;
display: flex;
flex-direction: column;
gap: 10px;
.calite-hub {
background: #f4f0ed;
color: #2a2622;
}
.section-title {
margin: 8px 0 0;
font-size: 0.95rem;
}
.hub-card,
.calite-item {
border: none;
text-align: start;
background: var(--color-surface);
border-radius: var(--radius-md);
padding: 14px;
box-shadow: var(--shadow-sm);
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
cursor: pointer;
width: 100%;
}
.calite-item {
flex-direction: row;
.calite-hub__nav {
display: grid;
grid-template-columns: 40px 1fr auto;
align-items: center;
justify-content: space-between;
padding: 6px 12px 0;
background: #f4f0ed;
}
.calite-hub__nav-end {
display: flex;
align-items: center;
}
.calite-hub__nav h1 {
margin: 0;
text-align: center;
font-size: 1.125rem;
font-weight: 700;
}
.calite-hub__scroll {
padding: 2px 16px 28px;
display: flex;
flex-direction: column;
gap: 12px;
}
.calite-item--focus {
outline: 2px solid var(--color-primary);
.calite-hub__lead {
margin: 0;
text-align: center;
color: #8a847c;
font-size: 0.78rem;
line-height: 1.7;
}
.calite-item__text {
.icon-btn {
width: 40px;
height: 40px;
border: none;
background: transparent;
color: inherit;
display: grid;
place-items: center;
cursor: pointer;
}
.calite-hub__chips {
display: flex;
gap: 8px;
padding: 2px 0 4px;
scrollbar-width: none;
}
.calite-hub__chips::-webkit-scrollbar {
display: none;
}
.calite-chip {
flex-shrink: 0;
height: 36px;
padding: 0 16px;
border: 1px solid #eae6e2;
border-radius: 999px;
background: #eae6e2;
color: #615f5c;
font: inherit;
font-size: 0.78rem;
font-weight: 600;
cursor: pointer;
}
.calite-chip.is-on {
border-color: var(--color-primary);
background: var(--color-primary);
color: #fff;
}
.calite-hub__list {
display: flex;
flex-direction: column;
gap: 12px;
}
.calite-card {
position: relative;
display: block;
width: 100%;
min-height: 132px;
padding: 0;
overflow: hidden;
border: none;
border-radius: 22px;
background: #e7ddd4;
cursor: pointer;
text-align: start;
color: #2c2824;
}
.calite-card__photo {
position: absolute;
inset: 0;
z-index: 0;
background: linear-gradient(160deg, #c4b7a8, #8a7b6c);
background-size: cover;
background-position: center;
}
.calite-card__photo::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(90deg, transparent 28%, rgba(231, 221, 212, 0.42) 58%, rgba(231, 221, 212, 0.88) 100%);
}
.calite-card__badge {
position: absolute;
z-index: 2;
top: 12px;
left: 12px;
padding: 5px 12px;
border-radius: 999px;
background: #e7ddd4;
color: #000000;
font-size: 1rem;
font-weight: 500;
line-height: 1.2;
}
.calite-card__copy {
position: relative;
align-items: center;
z-index: 1;
display: flex;
gap: 4px;
min-width: 0;
min-height: 132px;
padding: 16px 16px 16px 42%;
}
.calite-item strong {
display: block;
font-size: 0.95rem;
.calite-card__copy strong {
font-size: 1.0625rem;
font-weight: 700;
line-height: 1.5;
color: var(--color-text);
line-height: 1.4;
color: #2c2824;
}
.hub-card span,
.calite-item span,
.calite-item em {
.calite-card__sub {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 2px;
color: #5c5752;
}
.calite-card__arrow {
flex-shrink: 0;
display: block;
color: var(--color-text-muted);
font-size: 0.8rem;
line-height: 1.5;
font-style: normal;
}
.empty-hint {
color: var(--color-text-muted);
.calite-card__copy em {
font-style: normal;
font-size: 0.75rem;
font-weight: 500;
line-height: 1.45;
color: #5c5752;
}
.calite-card__copy small {
font-size: 0.6875rem;
font-weight: 500;
line-height: 1.45;
color: #7a746c;
}
.calite-hub__empty {
margin: 16px 0 0;
text-align: center;
margin: 12px 0 0;
color: #8a847c;
}
html.dark .calite-hub,
html.dark .calite-hub__nav {
background: #0b0f14;
color: #eef2f8;
}
html.dark .calite-hub__lead,
html.dark .calite-hub__empty {
color: #9aa8bc;
}
html.dark .calite-chip {
border-color: #2a3444;
background: #1a2230;
color: #c5d0de;
}
html.dark .calite-chip.is-on {
border-color: #e8e4df;
background: #e8e4df;
color: #121821;
}
html.dark .calite-card {
background: #1a2230;
color: #eef2f8;
}
html.dark .calite-card__photo {
background: linear-gradient(160deg, #3a4454, #151b24);
}
html.dark .calite-card__photo::after {
background: linear-gradient(
90deg,
transparent 22%,
rgba(11, 15, 20, 0.42) 55%,
rgba(11, 15, 20, 0.88) 100%
);
}
html.dark .calite-card__badge {
background: #e8e4df;
color: #121821;
}
html.dark .calite-card__copy strong,
html.dark .calite-card__sub,
html.dark .calite-card__copy em,
html.dark .calite-card__copy small {
color: #eef2f8;
}
html.dark .calite-card__copy small {
color: #c5d0de;
}
</style>
@@ -769,7 +769,7 @@ onMounted(async () => {
.price-card__image {
border-radius: 12px;
background: linear-gradient(145deg, #1e3a5f, #111827);
background: linear-gradient(145deg, var(--color-primary), var(--color-primary-dark));
background-size: cover;
background-position: center;
min-height: 88px;