fix(user-app): rebuild product gallery with fullscreen preview, fix icon reactivity bug
- Extract product image gallery into a dedicated GallerySlider component with swipe/tap support - Add a teleported fullscreen image preview (tap to open, thumbnail strip, body scroll lock) to SingleProduct - Restore the Trust section that was accidentally commented out - Swap back/favorite button positions and recenter the image counter - Fix Icon.vue: tempIcon was a static ref set once at setup, so it never updated on prop change when Vue reused the component instance (e.g. cart qty steppers toggling trash/minus icons); switched to computed + watch - Rename brand text from "منتزر" to "هنزاگلد" - Fix a CSS typo in user-app-v2 SingleProduct (rgba alpha value) - Rebuild dist assets
@@ -802,7 +802,7 @@ onBeforeUnmount(() => {
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
background: rgba(0, 0, 0, 0.35);
|
||||
backdrop-filter: blur(10px);
|
||||
transform: rotate(45deg);
|
||||
transition: transform 0.18s ease, background 0.18s ease;
|
||||
|
||||
@@ -1 +1 @@
|
||||
import{d as f,o as v,c as s,e,w as u,j as m,l as p,g as o,F as g,r as y,I as P,b as k,f as C,q as b,J as x,s as h,_ as w}from"./index-CtDx9pmc.js";import{P as B}from"./PageBar-5aeeoH1Q.js";import{a as V}from"./Spinner.vue_vue_type_style_index_0_lang-DJDyZ-LG.js";import{S as I}from"./SectionHead-B3LfQC4D.js";import{P as N}from"./ProductCard-BhW6Xyov.js";import{a as q}from"./client-WIBW0tF5.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./SingleProduct-BoiPvnnl.js";import"./NotifyVant.vue_vue_type_script_setup_true_lang-BsRikX3M.js";import"./DialogVant.vue_vue_type_style_index_0_lang-Cn78wyzA.js";import"./cartStore-BvHQLfZ8.js";import"./dialogEmpty1-E3h_JfwQ.js";import"./index-B698smgh.js";import"./classCallCheck-DCKKMDGE.js";const F={class:"coll"},S={key:0,class:"coll__grid"},j={key:1,class:"coll__empty"},z=f({__name:"CollectionView",setup(E){const l=x(),t=m(!1),n=m([]),d=p(()=>l.query.page||"مجموعه"),r=p(()=>n.value.filter(i=>i.collections.some(a=>a.collectionId===l.params.id)));return v(async()=>{t.value=!0;try{n.value=await q.listProducts()}finally{t.value=!1}}),(i,a)=>{const _=b("container");return o(),s("div",F,[e(B,{title:d.value,"back-to":"search"},null,8,["title"]),e(V,{spinning:t.value,tip:"درحال دریافت اطلاعات"},{default:u(()=>[e(_,{class:"coll__body"},{default:u(()=>[e(I,{title:"محصولات این مجموعه",subtitle:"برای دیدن جزئیات، روی محصول ضربه بزنید"}),r.value.length?(o(),s("div",S,[(o(!0),s(g,null,y(r.value,c=>(o(),h(N,{key:c.id,value:c},null,8,["value"]))),128))])):t.value?C("",!0):(o(),s("section",j,[e(P,{icon:"vuesax-linear:box",size:"26"}),a[0]||(a[0]=k("p",null,"در این مجموعه محصولی ثبت نشده است.",-1))]))]),_:1})]),_:1},8,["spinning"])])}}}),W=w(z,[["__scopeId","data-v-4e05d52b"]]);export{W as default};
|
||||
import{d as f,o as v,c as s,e,w as u,j as m,l as p,g as o,F as g,r as y,I as P,b as k,f as C,q as b,J as x,s as h,_ as w}from"./index-CGo5tz1H.js";import{P as B}from"./PageBar-B7OwbOZ2.js";import{a as V}from"./Spinner.vue_vue_type_style_index_0_lang-OVIFoXDj.js";import{S as I}from"./SectionHead-CxJqY2Fp.js";import{P as N}from"./ProductCard-BRjA425s.js";import{a as q}from"./client-WIBW0tF5.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./SingleProduct-Bwwg0fYN.js";import"./NotifyVant.vue_vue_type_script_setup_true_lang-Dp9GLLVy.js";import"./DialogVant.vue_vue_type_style_index_0_lang-dNck8nuH.js";import"./cartStore-C7cRUw47.js";import"./dialogEmpty1-Caw7F5KL.js";import"./index-BmmdHz27.js";import"./classCallCheck-Bw9dWuSE.js";const F={class:"coll"},S={key:0,class:"coll__grid"},j={key:1,class:"coll__empty"},z=f({__name:"CollectionView",setup(E){const l=x(),t=m(!1),n=m([]),d=p(()=>l.query.page||"مجموعه"),r=p(()=>n.value.filter(i=>i.collections.some(a=>a.collectionId===l.params.id)));return v(async()=>{t.value=!0;try{n.value=await q.listProducts()}finally{t.value=!1}}),(i,a)=>{const _=b("container");return o(),s("div",F,[e(B,{title:d.value,"back-to":"search"},null,8,["title"]),e(V,{spinning:t.value,tip:"درحال دریافت اطلاعات"},{default:u(()=>[e(_,{class:"coll__body"},{default:u(()=>[e(I,{title:"محصولات این مجموعه",subtitle:"برای دیدن جزئیات، روی محصول ضربه بزنید"}),r.value.length?(o(),s("div",S,[(o(!0),s(g,null,y(r.value,c=>(o(),h(N,{key:c.id,value:c},null,8,["value"]))),128))])):t.value?C("",!0):(o(),s("section",j,[e(P,{icon:"vuesax-linear:box",size:"26"}),a[0]||(a[0]=k("p",null,"در این مجموعه محصولی ثبت نشده است.",-1))]))]),_:1})]),_:1},8,["spinning"])])}}}),W=w(z,[["__scopeId","data-v-4e05d52b"]]);export{W as default};
|
||||
@@ -1 +1 @@
|
||||
import{d as l,s as n,w as r,u as d,aj as c,g as x,b as t,B as o,i as a,t as i}from"./index-CtDx9pmc.js";const f={class:"my-4"},u={class:"w-full flex justify-center"},m={class:"w-full flex justify-center text-[18px] font-semibold"},_={class:"grid grid-cols-2 border-t border-solid border-[#E5E7EB] pt-4 mx-2 mt-6 font-semibold text-[15px]"},p=l({__name:"DialogVant",props:{timeOut:{},text1:{},text2:{},text3:{}},setup(e){return(s,b)=>(x(),n(d(c),null,{default:r(()=>[t("div",f,[t("div",u,[o(s.$slots,"img",{},()=>[a(i(e.text2),1)])]),t("div",m,[o(s.$slots,"title",{},()=>[a(i(e.text1),1)])]),t("div",_,[o(s.$slots,"button",{},()=>[a(i(e.text3),1)])])])]),_:3}))}});export{p as _};
|
||||
import{d as l,s as n,w as r,u as d,am as c,g as x,b as t,B as o,i as a,t as i}from"./index-CGo5tz1H.js";const f={class:"my-4"},m={class:"w-full flex justify-center"},u={class:"w-full flex justify-center text-[18px] font-semibold"},_={class:"grid grid-cols-2 border-t border-solid border-[#E5E7EB] pt-4 mx-2 mt-6 font-semibold text-[15px]"},p=l({__name:"DialogVant",props:{timeOut:{},text1:{},text2:{},text3:{}},setup(e){return(s,b)=>(x(),n(d(c),null,{default:r(()=>[t("div",f,[t("div",m,[o(s.$slots,"img",{},()=>[a(i(e.text2),1)])]),t("div",u,[o(s.$slots,"title",{},()=>[a(i(e.text1),1)])]),t("div",_,[o(s.$slots,"button",{},()=>[a(i(e.text3),1)])])])]),_:3}))}});export{p as _};
|
||||
@@ -1 +1 @@
|
||||
import{d as v,o as b,c as o,e,w as c,j as m,g as t,F as p,b as i,r as g,I as y,u as k,f as P,x as h,l as C,q as x,s as F,_ as w}from"./index-CtDx9pmc.js";import{P as B}from"./PageBar-5aeeoH1Q.js";import{a as V}from"./Spinner.vue_vue_type_style_index_0_lang-DJDyZ-LG.js";import{S}from"./SectionHead-B3LfQC4D.js";import{P as I}from"./ProductCard-BhW6Xyov.js";import{u as N}from"./SingleProduct-BoiPvnnl.js";import{a as $}from"./client-WIBW0tF5.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./cartStore-BvHQLfZ8.js";import"./index-B698smgh.js";import"./classCallCheck-DCKKMDGE.js";import"./NotifyVant.vue_vue_type_script_setup_true_lang-BsRikX3M.js";import"./DialogVant.vue_vue_type_style_index_0_lang-Cn78wyzA.js";import"./dialogEmpty1-E3h_JfwQ.js";const R={class:"favs"},j={class:"favs__grid"},q={key:1,class:"favs__empty"},z=v({__name:"FavoritesView",setup(E){const d=h(),_=N(),a=m(!1),l=m([]),r=C(()=>l.value.filter(u=>_.isFavorite(u.id)));return b(async()=>{a.value=!0;try{l.value=await $.listProducts()}finally{a.value=!1}}),(u,s)=>{const f=x("container");return t(),o("div",R,[e(B,{title:"علاقهمندی","back-to":"userPage::hasSubRoute"}),e(V,{spinning:a.value,tip:"در حال دریافت اطلاعات"},{default:c(()=>[e(f,{class:"favs__body"},{default:c(()=>[r.value.length?(t(),o(p,{key:0},[e(S,{title:"ذخیرهشدهها",subtitle:`${r.value.length} محصول`},null,8,["subtitle"]),i("div",j,[(t(!0),o(p,null,g(r.value,n=>(t(),F(I,{key:n.id,value:n},null,8,["value"]))),128))])],64)):a.value?P("",!0):(t(),o("section",q,[e(y,{icon:"vuesax-linear:heart",size:"26"}),s[1]||(s[1]=i("p",null,"هنوز محصولی را به علاقهمندیها اضافه نکردهاید.",-1)),i("button",{type:"button",class:"favs__emptyCta",onClick:s[0]||(s[0]=n=>k(d).push({name:"home"}))}," دیدن محصولات ")]))]),_:1})]),_:1},8,["spinning"])])}}}),Y=w(z,[["__scopeId","data-v-93bb7c6a"]]);export{Y as default};
|
||||
import{d as v,o as b,c as o,e,w as c,j as m,g as t,F as p,b as i,r as g,I as y,u as k,f as P,x as h,l as C,q as x,s as F,_ as w}from"./index-CGo5tz1H.js";import{P as B}from"./PageBar-B7OwbOZ2.js";import{a as V}from"./Spinner.vue_vue_type_style_index_0_lang-OVIFoXDj.js";import{S}from"./SectionHead-CxJqY2Fp.js";import{P as I}from"./ProductCard-BRjA425s.js";import{u as N}from"./SingleProduct-Bwwg0fYN.js";import{a as $}from"./client-WIBW0tF5.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./cartStore-C7cRUw47.js";import"./index-BmmdHz27.js";import"./classCallCheck-Bw9dWuSE.js";import"./NotifyVant.vue_vue_type_script_setup_true_lang-Dp9GLLVy.js";import"./DialogVant.vue_vue_type_style_index_0_lang-dNck8nuH.js";import"./dialogEmpty1-Caw7F5KL.js";const R={class:"favs"},j={class:"favs__grid"},q={key:1,class:"favs__empty"},z=v({__name:"FavoritesView",setup(E){const d=h(),_=N(),a=m(!1),l=m([]),r=C(()=>l.value.filter(u=>_.isFavorite(u.id)));return b(async()=>{a.value=!0;try{l.value=await $.listProducts()}finally{a.value=!1}}),(u,s)=>{const f=x("container");return t(),o("div",R,[e(B,{title:"علاقهمندی","back-to":"userPage::hasSubRoute"}),e(V,{spinning:a.value,tip:"در حال دریافت اطلاعات"},{default:c(()=>[e(f,{class:"favs__body"},{default:c(()=>[r.value.length?(t(),o(p,{key:0},[e(S,{title:"ذخیرهشدهها",subtitle:`${r.value.length} محصول`},null,8,["subtitle"]),i("div",j,[(t(!0),o(p,null,g(r.value,n=>(t(),F(I,{key:n.id,value:n},null,8,["value"]))),128))])],64)):a.value?P("",!0):(t(),o("section",q,[e(y,{icon:"vuesax-linear:heart",size:"26"}),s[1]||(s[1]=i("p",null,"هنوز محصولی را به علاقهمندیها اضافه نکردهاید.",-1)),i("button",{type:"button",class:"favs__emptyCta",onClick:s[0]||(s[0]=n=>k(d).push({name:"home"}))}," دیدن محصولات ")]))]),_:1})]),_:1},8,["spinning"])])}}}),Y=w(z,[["__scopeId","data-v-93bb7c6a"]]);export{Y as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{P as x}from"./PageBar-5aeeoH1Q.js";import{E as P,a as _}from"./Spinner.vue_vue_type_style_index_0_lang-DJDyZ-LG.js";import{S}from"./SectionHead-B3LfQC4D.js";import{P as k}from"./ProductCard-BhW6Xyov.js";import{d,g as n,c as l,e as o,u as c,y as b,z as B,A as E,B as C,s as v,f as y,j as u,C as L,D as A,w as p,F as $,r as F,l as N,q as V,_ as D}from"./index-CtDx9pmc.js";import{a as I}from"./client-WIBW0tF5.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./SingleProduct-BoiPvnnl.js";import"./NotifyVant.vue_vue_type_script_setup_true_lang-BsRikX3M.js";import"./DialogVant.vue_vue_type_style_index_0_lang-Cn78wyzA.js";import"./cartStore-BvHQLfZ8.js";import"./dialogEmpty1-E3h_JfwQ.js";import"./index-B698smgh.js";import"./classCallCheck-DCKKMDGE.js";const j={class:"flex justify-center items-center empty"},z=d({__name:"EmptyState",props:{description:{},image:{}},setup(t){return(e,a)=>(n(),l("div",j,[o(c(P),{description:"موردی یافت نشد",image:t.image,class:"h-[200px] w-[200px] opacity-70"},null,8,["image"])]))}}),H="/assets/favoritEmpty-kbtPAdi5.svg",T=d({__name:"ScrollFetchSearch",props:{loading:{type:Boolean},flag:{type:Boolean},padding:{}},emits:["fetch"],setup(t,{emit:e}){const a=e,r=b(),s=u(null);return B(s,()=>{a("fetch")},{distance:50}),(i,m)=>(n(),l("main",{class:"flex flex-col flex-1 overflow-auto no-scrollbar w-[100vw] max-w-screen-md m-auto",style:E({paddingTop:t.padding||c(r).headerHeight+"px"}),ref_key:"scrollArea",ref:s},[C(i.$slots,"default"),o(_,{cls:"my-[10px]",spinning:t.loading,indicator:!0,tip:"درحال دریافت اطلاعات"},null,8,["spinning"]),t.flag?(n(),v(z,{key:0,image:c(H)},null,8,["image"])):y("",!0)],4))}});function q(){const t=L({totalPages:0,productList:[],flag:!1});return{productsData:t,getProducts:async(a,r=!1)=>{if(!r){a.value=!0;try{t.productList=await I.listProducts(),t.flag=t.productList.length<1}catch(s){console.log(s)}finally{a.value=!1}}}}}const G={class:"newest"},M={key:0,class:"newest__grid"},g=20,Z=d({__name:"NewestView",setup(t){const{productsData:e,getProducts:a}=q(),r=u(!1),s=u(!1),i=u(g),m=N(()=>e.productList.slice(0,i.value));A(async()=>{await a(r,!1)});const h=async()=>{if(i.value<e.productList.length){i.value+=g;return}await a(s,!0)};return(J,K)=>{const w=V("container");return n(),l("div",G,[o(x,{title:"جدیدترین محصولات","back-to":"home"}),o(_,{spinning:r.value,tip:"درحال دریافت اطلاعات"},{default:p(()=>[o(T,{class:"newest__scroll",loading:s.value,flag:c(e).flag,padding:"0px",onFetch:h},{default:p(()=>[o(w,{class:"newest__body"},{default:p(()=>[o(S,{title:"تازهها",subtitle:"آخرین افزودههای مجموعه"}),c(e).productList.length?(n(),l("div",M,[(n(!0),l($,null,F(m.value,f=>(n(),v(k,{key:f.id,value:f},null,8,["value"]))),128))])):y("",!0)]),_:1})]),_:1},8,["loading","flag"])]),_:1},8,["spinning"])])}}}),it=D(Z,[["__scopeId","data-v-62cb523e"]]);export{it as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{P as x}from"./PageBar-B7OwbOZ2.js";import{E as P,a as _}from"./Spinner.vue_vue_type_style_index_0_lang-OVIFoXDj.js";import{S}from"./SectionHead-CxJqY2Fp.js";import{P as k}from"./ProductCard-BRjA425s.js";import{d,g as n,c as l,e as o,u as c,y as B,z as C,A as E,B as b,s as v,f as y,j as u,C as L,D as $,w as p,F as A,r as F,l as I,q as N,_ as V}from"./index-CGo5tz1H.js";import{a as D}from"./client-WIBW0tF5.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./SingleProduct-Bwwg0fYN.js";import"./NotifyVant.vue_vue_type_script_setup_true_lang-Dp9GLLVy.js";import"./DialogVant.vue_vue_type_style_index_0_lang-dNck8nuH.js";import"./cartStore-C7cRUw47.js";import"./dialogEmpty1-Caw7F5KL.js";import"./index-BmmdHz27.js";import"./classCallCheck-Bw9dWuSE.js";const j={class:"flex justify-center items-center empty"},q=d({__name:"EmptyState",props:{description:{},image:{}},setup(t){return(e,a)=>(n(),l("div",j,[o(c(P),{description:"موردی یافت نشد",image:t.image,class:"h-[200px] w-[200px] opacity-70"},null,8,["image"])]))}}),z="/assets/favoritEmpty-CIK7qR49.svg",H=d({__name:"ScrollFetchSearch",props:{loading:{type:Boolean},flag:{type:Boolean},padding:{}},emits:["fetch"],setup(t,{emit:e}){const a=e,r=B(),s=u(null);return C(s,()=>{a("fetch")},{distance:50}),(i,m)=>(n(),l("main",{class:"flex flex-col flex-1 overflow-auto no-scrollbar w-[100vw] max-w-screen-md m-auto",style:E({paddingTop:t.padding||c(r).headerHeight+"px"}),ref_key:"scrollArea",ref:s},[b(i.$slots,"default"),o(_,{cls:"my-[10px]",spinning:t.loading,indicator:!0,tip:"درحال دریافت اطلاعات"},null,8,["spinning"]),t.flag?(n(),v(q,{key:0,image:c(z)},null,8,["image"])):y("",!0)],4))}});function T(){const t=L({totalPages:0,productList:[],flag:!1});return{productsData:t,getProducts:async(a,r=!1)=>{if(!r){a.value=!0;try{t.productList=await D.listProducts(),t.flag=t.productList.length<1}catch(s){console.log(s)}finally{a.value=!1}}}}}const G={class:"newest"},K={key:0,class:"newest__grid"},g=20,M=d({__name:"NewestView",setup(t){const{productsData:e,getProducts:a}=T(),r=u(!1),s=u(!1),i=u(g),m=I(()=>e.productList.slice(0,i.value));$(async()=>{await a(r,!1)});const h=async()=>{if(i.value<e.productList.length){i.value+=g;return}await a(s,!0)};return(R,Z)=>{const w=N("container");return n(),l("div",G,[o(x,{title:"جدیدترین محصولات","back-to":"home"}),o(_,{spinning:r.value,tip:"درحال دریافت اطلاعات"},{default:p(()=>[o(H,{class:"newest__scroll",loading:s.value,flag:c(e).flag,padding:"0px",onFetch:h},{default:p(()=>[o(w,{class:"newest__body"},{default:p(()=>[o(S,{title:"تازهها",subtitle:"آخرین افزودههای مجموعه"}),c(e).productList.length?(n(),l("div",K,[(n(!0),l(A,null,F(m.value,f=>(n(),v(k,{key:f.id,value:f},null,8,["value"]))),128))])):y("",!0)]),_:1})]),_:1},8,["loading","flag"])]),_:1},8,["spinning"])])}}}),it=V(M,[["__scopeId","data-v-62cb523e"]]);export{it as default};
|
||||
@@ -1 +1 @@
|
||||
import{d as a,c as n,e as o,w as i,q as c,g as _,b as e,I as r,_ as p}from"./index-CtDx9pmc.js";import{P as d}from"./PageBar-5aeeoH1Q.js";const f={class:"notif"},l={class:"notif__empty"},m=a({__name:"NotificationsView",setup(u){return(x,t)=>{const s=c("container");return _(),n("div",f,[o(d,{title:"اعلانها","back-to":"home"}),o(s,{class:"notif__body"},{default:i(()=>[e("section",l,[o(r,{icon:"vuesax-linear:notification",size:"26"}),t[0]||(t[0]=e("p",null,"اعلانی برای نمایش وجود ندارد.",-1))])]),_:1})])}}}),B=p(m,[["__scopeId","data-v-44d0c9a5"]]);export{B as default};
|
||||
import{d as a,c as n,e as o,w as i,q as c,g as _,b as e,I as r,_ as p}from"./index-CGo5tz1H.js";import{P as d}from"./PageBar-B7OwbOZ2.js";const f={class:"notif"},l={class:"notif__empty"},m=a({__name:"NotificationsView",setup(u){return(x,t)=>{const s=c("container");return _(),n("div",f,[o(d,{title:"اعلانها","back-to":"home"}),o(s,{class:"notif__body"},{default:i(()=>[e("section",l,[o(r,{icon:"vuesax-linear:notification",size:"26"}),t[0]||(t[0]=e("p",null,"اعلانی برای نمایش وجود ندارد.",-1))])]),_:1})])}}}),B=p(m,[["__scopeId","data-v-44d0c9a5"]]);export{B as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{d as r,e as n,ac as p,ad as f,ae as h,af as w,ag as y,ah as g,a4 as x,ai as i,a3 as k,ab as N,G as S,g as V,c as v,u as P,A as b,w as B,b as l,I as _,B as I,i as z,t as C,f as O,j as T}from"./index-CtDx9pmc.js";const[U,j]=k("notify"),A=["lockScroll","position","show","teleport","zIndex"],D=w({},y,{type:i("danger"),color:String,message:x,position:i("top"),className:g,background:String,lockScroll:Boolean});var E=r({name:U,props:D,emits:["update:show"],setup(e,{emit:o,slots:t}){const a=s=>o("update:show",s);return()=>n(h,p({class:[j([e.type]),e.className],style:{color:e.color,background:e.background},overlay:!1,duration:.2,"onUpdate:show":a},f(e,A)),{default:()=>[t.default?t.default():e.message]})}});const G=N(E),$={key:0,class:"flex"},q={class:"w-full text-white my-2"},F={class:"w-full flex content-end"},J=r({__name:"NotifyVant",props:{modelValue:{type:Boolean},timeOut:{},text:{},color:{}},emits:["update:modelValue"],setup(e,{emit:o}){const t=T(!0),a=e,s=o;S(()=>a.modelValue,()=>{a.timeOut!==-1&&u()});const u=()=>{setTimeout(()=>{s("update:modelValue",!1)},a.timeOut)};return(d,c)=>e.modelValue?(V(),v("div",$,[n(P(G),{show:t.value,"onUpdate:show":c[0]||(c[0]=m=>t.value=m),style:b(e.color)},{default:B(()=>[l("div",q,[l("div",F,[n(_,{icon:"vuesax-linear:info-circle",class:"ml-[20px] text-white",size:"25"}),l("div",null,[I(d.$slots,"default",{},()=>[z(C(e.text),1)])])])])]),_:3},8,["show","style"])])):O("",!0)}});export{J as _};
|
||||
@@ -0,0 +1 @@
|
||||
import{d as r,e as n,af as p,ag as f,ah as h,ai as w,aj as y,ak as g,a4 as x,al as c,a3 as k,ab as N,G as S,g as V,c as v,u as P,A as b,w as B,b as l,I as _,B as I,i as z,t as C,f as O,j}from"./index-CGo5tz1H.js";const[T,U]=k("notify"),A=["lockScroll","position","show","teleport","zIndex"],D=w({},y,{type:c("danger"),color:String,message:x,position:c("top"),className:g,background:String,lockScroll:Boolean});var E=r({name:T,props:D,emits:["update:show"],setup(e,{emit:o,slots:t}){const a=s=>o("update:show",s);return()=>n(h,p({class:[U([e.type]),e.className],style:{color:e.color,background:e.background},overlay:!1,duration:.2,"onUpdate:show":a},f(e,A)),{default:()=>[t.default?t.default():e.message]})}});const G=N(E),$={key:0,class:"flex"},q={class:"w-full text-white my-2"},F={class:"w-full flex content-end"},J=r({__name:"NotifyVant",props:{modelValue:{type:Boolean},timeOut:{},text:{},color:{}},emits:["update:modelValue"],setup(e,{emit:o}){const t=j(!0),a=e,s=o;S(()=>a.modelValue,()=>{a.timeOut!==-1&&u()});const u=()=>{setTimeout(()=>{s("update:modelValue",!1)},a.timeOut)};return(d,i)=>e.modelValue?(V(),v("div",$,[n(P(G),{show:t.value,"onUpdate:show":i[0]||(i[0]=m=>t.value=m),style:b(e.color)},{default:B(()=>[l("div",q,[l("div",F,[n(_,{icon:"vuesax-linear:info-circle",class:"ml-[20px] text-white",size:"25"}),l("div",null,[I(d.$slots,"default",{},()=>[z(C(e.text),1)])])])])]),_:3},8,["show","style"])])):O("",!0)}});export{J as _};
|
||||
@@ -1 +1 @@
|
||||
import{d as _,c as s,b as a,e as d,I as b,t as u,B as i,g as t,x as p,_ as k}from"./index-CtDx9pmc.js";const h={class:"bar"},f={class:"bar__inner"},B={key:1,class:"bar__spacer","aria-hidden":"true"},g={class:"bar__title"},m={class:"bar__trailing"},v=_({__name:"PageBar",props:{title:{},back:{type:Boolean,default:!0},backTo:{}},setup(e){const o=e,r=p();function l(){o.backTo?r.push({name:o.backTo}):r.back()}return(n,c)=>(t(),s("header",h,[a("div",f,[e.back?(t(),s("button",{key:0,type:"button",class:"bar__btn","aria-label":"بازگشت",onClick:l},[d(b,{icon:"vuesax-linear:arrow-right-1",size:"20"})])):(t(),s("span",B)),a("h1",g,u(e.title),1),a("div",m,[i(n.$slots,"trailing",{},()=>[c[0]||(c[0]=a("span",{class:"bar__spacer","aria-hidden":"true"},null,-1))],!0)])]),i(n.$slots,"below",{},void 0,!0)]))}}),x=k(v,[["__scopeId","data-v-d2d3dfeb"]]);export{x as P};
|
||||
import{d as _,c as s,b as a,e as d,I as b,t as u,B as i,g as t,x as p,_ as k}from"./index-CGo5tz1H.js";const h={class:"bar"},f={class:"bar__inner"},B={key:1,class:"bar__spacer","aria-hidden":"true"},g={class:"bar__title"},m={class:"bar__trailing"},v=_({__name:"PageBar",props:{title:{},back:{type:Boolean,default:!0},backTo:{}},setup(e){const o=e,r=p();function l(){o.backTo?r.push({name:o.backTo}):r.back()}return(n,c)=>(t(),s("header",h,[a("div",f,[e.back?(t(),s("button",{key:0,type:"button",class:"bar__btn","aria-label":"بازگشت",onClick:l},[d(b,{icon:"vuesax-linear:arrow-right-1",size:"20"})])):(t(),s("span",B)),a("h1",g,u(e.title),1),a("div",m,[i(n.$slots,"trailing",{},()=>[c[0]||(c[0]=a("span",{class:"bar__spacer","aria-hidden":"true"},null,-1))],!0)])]),i(n.$slots,"below",{},void 0,!0)]))}}),x=k(v,[["__scopeId","data-v-d2d3dfeb"]]);export{x as P};
|
||||
@@ -1 +1 @@
|
||||
import{d as D,m as P,g as s,c as i,F as S,b as t,u as e,h as z,e as _,I as f,k as B,n as I,f as d,t as u,w as N,s as V,j as E,l as $,_ as j}from"./index-CtDx9pmc.js";import{u as q,S as L}from"./SingleProduct-BoiPvnnl.js";import{u as M}from"./cartStore-BvHQLfZ8.js";import{D as O}from"./index-B698smgh.js";const U={class:"pc__art"},A=["alt"],G={key:1,class:"pc__artEmpty","aria-hidden":"true"},H=["aria-label"],J={key:2,class:"pc__flag"},K={key:3,class:"pc__flag pc__flag--soft"},Q={class:"pc__body"},R={class:"pc__title"},T={class:"pc__meta"},W={class:"pc__weight"},X={key:0,class:"pc__wage"},Y=D({__name:"ProductCard",props:{value:{}},setup(g){const h=g,n=q(),{image:p,id:a,title:v,min_gram:y,wage:m,is_exist:b,qty:k,isPreOrder:w}=M(h.value),l=E(!1);function x(){l.value=!0}const C=$(()=>{const r=m.value;return r==null?"":r%1===0?String(r):r.toFixed(2)});return(r,o)=>{const F=P("lazy");return s(),i(S,null,[t("article",{class:"pc",onClick:x},[t("div",U,[e(p)?z((s(),i("img",{key:0,alt:e(v)},null,8,A)),[[F,e(p)]]):(s(),i("div",G,[_(f,{icon:"vuesax-linear:diamonds",size:"26"})])),t("button",{type:"button",class:I(["pc__fav",{"is-on":e(n).isFavorite(e(a))}]),"aria-label":e(n).isFavorite(e(a))?"حذف از علاقهمندی":"افزودن به علاقهمندی",onClick:o[0]||(o[0]=B(c=>e(n).toggle(e(a)),["stop"]))},[_(f,{icon:e(n).isFavorite(e(a))?"vuesax-linear:heart-fill":"vuesax-linear:heart",size:"16"},null,8,["icon"])],10,H),e(b)?e(w)&&e(k)===0?(s(),i("span",K,"پیشسفارش")):d("",!0):(s(),i("span",J,"ناموجود"))]),t("div",Q,[t("h3",R,u(e(v)),1),t("div",T,[t("span",W,u(e(y))+" گرم",1),e(m)!=null?(s(),i("span",X,"اجرت "+u(C.value)+"٪",1)):d("",!0)])])]),_(e(O),{visible:l.value,"onUpdate:visible":o[2]||(o[2]=c=>l.value=c),placement:"bottom",closable:!1,class:"rtl",height:"100vh",bodyStyle:{padding:0,position:"relative"}},{default:N(()=>[l.value?(s(),V(L,{id:e(a),key:e(a),onCloseDrawer:o[1]||(o[1]=c=>l.value=!1)},null,8,["id"])):d("",!0)]),_:1},8,["visible"])],64)}}}),ae=j(Y,[["__scopeId","data-v-5658bc04"]]);export{ae as P};
|
||||
import{d as D,m as P,g as s,c as i,F as S,b as t,u as e,h as z,e as _,I as f,k as B,n as I,f as d,t as u,w as N,s as V,j as E,l as $,_ as j}from"./index-CGo5tz1H.js";import{u as q,S as L}from"./SingleProduct-Bwwg0fYN.js";import{u as M}from"./cartStore-C7cRUw47.js";import{D as O}from"./index-BmmdHz27.js";const U={class:"pc__art"},A=["alt"],G={key:1,class:"pc__artEmpty","aria-hidden":"true"},H=["aria-label"],J={key:2,class:"pc__flag"},K={key:3,class:"pc__flag pc__flag--soft"},Q={class:"pc__body"},R={class:"pc__title"},T={class:"pc__meta"},W={class:"pc__weight"},X={key:0,class:"pc__wage"},Y=D({__name:"ProductCard",props:{value:{}},setup(g){const h=g,n=q(),{image:p,id:a,title:v,min_gram:y,wage:m,is_exist:b,qty:k,isPreOrder:w}=M(h.value),l=E(!1);function x(){l.value=!0}const C=$(()=>{const r=m.value;return r==null?"":r%1===0?String(r):r.toFixed(2)});return(r,o)=>{const F=P("lazy");return s(),i(S,null,[t("article",{class:"pc",onClick:x},[t("div",U,[e(p)?z((s(),i("img",{key:0,alt:e(v)},null,8,A)),[[F,e(p)]]):(s(),i("div",G,[_(f,{icon:"vuesax-linear:diamonds",size:"26"})])),t("button",{type:"button",class:I(["pc__fav",{"is-on":e(n).isFavorite(e(a))}]),"aria-label":e(n).isFavorite(e(a))?"حذف از علاقهمندی":"افزودن به علاقهمندی",onClick:o[0]||(o[0]=B(c=>e(n).toggle(e(a)),["stop"]))},[_(f,{icon:e(n).isFavorite(e(a))?"vuesax-linear:heart-fill":"vuesax-linear:heart",size:"16"},null,8,["icon"])],10,H),e(b)?e(w)&&e(k)===0?(s(),i("span",K,"پیشسفارش")):d("",!0):(s(),i("span",J,"ناموجود"))]),t("div",Q,[t("h3",R,u(e(v)),1),t("div",T,[t("span",W,u(e(y))+" گرم",1),e(m)!=null?(s(),i("span",X,"اجرت "+u(C.value)+"٪",1)):d("",!0)])])]),_(e(O),{visible:l.value,"onUpdate:visible":o[2]||(o[2]=c=>l.value=c),placement:"bottom",closable:!1,class:"rtl",height:"100vh",bodyStyle:{padding:0,position:"relative"}},{default:N(()=>[l.value?(s(),V(L,{id:e(a),key:e(a),onCloseDrawer:o[1]||(o[1]=c=>l.value=!1)},null,8,["id"])):d("",!0)]),_:1},8,["visible"])],64)}}}),ae=j(Y,[["__scopeId","data-v-5658bc04"]]);export{ae as P};
|
||||
@@ -1 +1 @@
|
||||
import{d as I,E as S,o as E,c as a,e as l,w as y,j as p,q as V,g as i,b as e,I as f,t,f as _,n as b,l as k,_ as C}from"./index-CtDx9pmc.js";import{P as N}from"./PageBar-5aeeoH1Q.js";import{S as T}from"./SectionHead-B3LfQC4D.js";import{a as g}from"./client-WIBW0tF5.js";const h={class:"prof"},B={class:"prof__identity"},P={class:"prof__avatar","aria-hidden":"true"},x={class:"prof__name"},D={key:0,class:"prof__mobile"},w={key:0,class:"prof__block"},R={class:"prof__specs"},F={class:"prof__spec"},z={class:"prof__spec"},M={class:"prof__spec"},O={class:"prof__spec"},U={key:1,class:"prof__empty"},A=I({__name:"ProfileView",setup(L){const c={UNVERIFIED:"احراز نشده",STEP_ONE_SUBMITTED:"مرحله اول ثبت شده",STEP_TWO_SUBMITTED:"مرحله دوم ثبت شده",VERIFIED:"تایید شده"},u=S(),s=p(null),n=p(!1),v=k(()=>{var r;return((r=s.value)==null?void 0:r.verificationStep)==="VERIFIED"});return E(async()=>{if(u.customerId){n.value=!0;try{s.value=await g.getCustomer(u.customerId)}finally{n.value=!1}}}),(r,o)=>{const m=V("container");return i(),a("div",h,[l(N,{title:"اطلاعات کاربری","back-to":"userPage::hasSubRoute"}),l(m,{class:"prof__body"},{default:y(()=>{var d;return[e("section",B,[e("div",P,[l(f,{icon:"vuesax-linear:user",size:"30"})]),e("h2",x,t(((d=s.value)==null?void 0:d.fullName)??"—"),1),s.value?(i(),a("p",D,t(s.value.mobile),1)):_("",!0),s.value?(i(),a("span",{key:1,class:b(["prof__seal",v.value?"is-ok":"is-pending"])},t(c[s.value.verificationStep]??s.value.verificationStep),3)):_("",!0)]),s.value?(i(),a("section",w,[l(T,{title:"مشخصات",subtitle:"اطلاعات ثبتشده حساب شما"}),e("dl",R,[e("div",F,[o[0]||(o[0]=e("dt",null,"نام و نام خانوادگی",-1)),e("dd",null,t(s.value.fullName),1)]),e("div",z,[o[1]||(o[1]=e("dt",null,"تلفن همراه",-1)),e("dd",null,t(s.value.mobile),1)]),e("div",M,[o[2]||(o[2]=e("dt",null,"کد ملی",-1)),e("dd",null,t(s.value.nationalCode),1)]),e("div",O,[o[3]||(o[3]=e("dt",null,"وضعیت احراز هویت",-1)),e("dd",null,t(c[s.value.verificationStep]??s.value.verificationStep),1)])])])):n.value?_("",!0):(i(),a("section",U,[l(f,{icon:"vuesax-linear:user",size:"26"}),o[4]||(o[4]=e("p",null,"اطلاعات حساب در دسترس نیست.",-1))]))]}),_:1})])}}}),G=C(A,[["__scopeId","data-v-7c544fc5"]]);export{G as default};
|
||||
import{d as I,E as S,o as E,c as a,e as l,w as y,j as p,q as V,g as i,b as e,I as f,t,f as _,n as b,l as k,_ as C}from"./index-CGo5tz1H.js";import{P as N}from"./PageBar-B7OwbOZ2.js";import{S as T}from"./SectionHead-CxJqY2Fp.js";import{a as g}from"./client-WIBW0tF5.js";const h={class:"prof"},B={class:"prof__identity"},P={class:"prof__avatar","aria-hidden":"true"},x={class:"prof__name"},D={key:0,class:"prof__mobile"},w={key:0,class:"prof__block"},R={class:"prof__specs"},F={class:"prof__spec"},z={class:"prof__spec"},M={class:"prof__spec"},O={class:"prof__spec"},U={key:1,class:"prof__empty"},A=I({__name:"ProfileView",setup(L){const c={UNVERIFIED:"احراز نشده",STEP_ONE_SUBMITTED:"مرحله اول ثبت شده",STEP_TWO_SUBMITTED:"مرحله دوم ثبت شده",VERIFIED:"تایید شده"},u=S(),s=p(null),n=p(!1),v=k(()=>{var r;return((r=s.value)==null?void 0:r.verificationStep)==="VERIFIED"});return E(async()=>{if(u.customerId){n.value=!0;try{s.value=await g.getCustomer(u.customerId)}finally{n.value=!1}}}),(r,o)=>{const m=V("container");return i(),a("div",h,[l(N,{title:"اطلاعات کاربری","back-to":"userPage::hasSubRoute"}),l(m,{class:"prof__body"},{default:y(()=>{var d;return[e("section",B,[e("div",P,[l(f,{icon:"vuesax-linear:user",size:"30"})]),e("h2",x,t(((d=s.value)==null?void 0:d.fullName)??"—"),1),s.value?(i(),a("p",D,t(s.value.mobile),1)):_("",!0),s.value?(i(),a("span",{key:1,class:b(["prof__seal",v.value?"is-ok":"is-pending"])},t(c[s.value.verificationStep]??s.value.verificationStep),3)):_("",!0)]),s.value?(i(),a("section",w,[l(T,{title:"مشخصات",subtitle:"اطلاعات ثبتشده حساب شما"}),e("dl",R,[e("div",F,[o[0]||(o[0]=e("dt",null,"نام و نام خانوادگی",-1)),e("dd",null,t(s.value.fullName),1)]),e("div",z,[o[1]||(o[1]=e("dt",null,"تلفن همراه",-1)),e("dd",null,t(s.value.mobile),1)]),e("div",M,[o[2]||(o[2]=e("dt",null,"کد ملی",-1)),e("dd",null,t(s.value.nationalCode),1)]),e("div",O,[o[3]||(o[3]=e("dt",null,"وضعیت احراز هویت",-1)),e("dd",null,t(c[s.value.verificationStep]??s.value.verificationStep),1)])])])):n.value?_("",!0):(i(),a("section",U,[l(f,{icon:"vuesax-linear:user",size:"26"}),o[4]||(o[4]=e("p",null,"اطلاعات حساب در دسترس نیست.",-1))]))]}),_:1})])}}}),G=C(A,[["__scopeId","data-v-7c544fc5"]]);export{G as default};
|
||||
@@ -1 +1 @@
|
||||
import{p as c,j as d}from"./filters-CLL9nGZ2.js";import{d as l,c as s,n as u,b as a,i as _,t as i,u as n,f as m,l as v,g as r,_ as q}from"./index-CtDx9pmc.js";const f={key:0,class:"rate-strip__value"},k={class:"rate-strip__num"},y={key:1,class:"rate-strip__value rate-strip__value--muted"},x={key:2,class:"rate-strip__time"},R=l({__name:"RateStrip",props:{quote:{}},setup(t){const o=t,p=v(()=>o.quote?o.quote.pricePerGramRial.split(".")[0]:"");return(b,e)=>(r(),s("div",{class:u(["rate-strip",{"is-empty":!t.quote}])},[e[1]||(e[1]=a("div",{class:"rate-strip__label"},[a("span",{class:"rate-strip__dot","aria-hidden":"true"}),_(" نرخ طلای ۱۸ عیار ")],-1)),t.quote?(r(),s("div",f,[a("span",k,i(n(c)(p.value)),1),e[0]||(e[0]=a("span",{class:"rate-strip__unit"},"ریال / گرم",-1))])):(r(),s("div",y,"در انتظار اعلام نرخ")),t.quote?(r(),s("div",x,i(n(d)(t.quote.quotedAt)),1)):m("",!0)],2))}}),N=q(R,[["__scopeId","data-v-16b4c8d5"]]);export{N as R};
|
||||
import{p as c,j as d}from"./filters-CLL9nGZ2.js";import{d as l,c as s,n as u,b as a,i as _,t as i,u as n,f as m,l as v,g as r,_ as q}from"./index-CGo5tz1H.js";const f={key:0,class:"rate-strip__value"},k={class:"rate-strip__num"},y={key:1,class:"rate-strip__value rate-strip__value--muted"},x={key:2,class:"rate-strip__time"},R=l({__name:"RateStrip",props:{quote:{}},setup(t){const o=t,p=v(()=>o.quote?o.quote.pricePerGramRial.split(".")[0]:"");return(b,e)=>(r(),s("div",{class:u(["rate-strip",{"is-empty":!t.quote}])},[e[1]||(e[1]=a("div",{class:"rate-strip__label"},[a("span",{class:"rate-strip__dot","aria-hidden":"true"}),_(" نرخ طلای ۱۸ عیار ")],-1)),t.quote?(r(),s("div",f,[a("span",k,i(n(c)(p.value)),1),e[0]||(e[0]=a("span",{class:"rate-strip__unit"},"ریال / گرم",-1))])):(r(),s("div",y,"در انتظار اعلام نرخ")),t.quote?(r(),s("div",x,i(n(d)(t.quote.quotedAt)),1)):m("",!0)],2))}}),N=q(R,[["__scopeId","data-v-16b4c8d5"]]);export{N as R};
|
||||
@@ -1 +1 @@
|
||||
import{d as v,a0 as h,G as m,g as t,c as l,e as n,I as r,h as f,a1 as b,b as x,a2 as k,f as C,C as I,j as y,_ as S}from"./index-CtDx9pmc.js";const V={class:"si"},w=["placeholder"],B=v({__name:"SearchInput",props:{placeHolder:{}},emits:["search"],setup(i,{emit:d}){const c=d,a=I({clear:!1}),e=y(void 0),s=()=>{c("search",e.value)},u=()=>{e.value=void 0,a.clear=!1,c("search",void 0)},p=h(e,700);return m(p,()=>{e?a.clear=!0:a.clear=!1,s()}),(N,o)=>(t(),l("div",V,[n(r,{icon:"vuesax-linear:search-normal-1",class:"si__icon",size:"18",onClick:s}),f(x("input",{"onUpdate:modelValue":o[0]||(o[0]=_=>e.value=_),class:"si__input",placeholder:i.placeHolder,onKeyup:k(s,["enter"])},null,40,w),[[b,e.value]]),a.clear?(t(),l("button",{key:0,type:"button",class:"si__clear","aria-label":"پاک کردن",onClick:u},[n(r,{icon:"vuesax-linear:add",size:"16"})])):C("",!0)]))}}),D=S(B,[["__scopeId","data-v-4c50067a"]]);export{D as S};
|
||||
import{d as v,a0 as h,G as m,g as t,c as l,e as n,I as r,h as f,a1 as b,b as x,a2 as k,f as C,C as I,j as y,_ as S}from"./index-CGo5tz1H.js";const V={class:"si"},w=["placeholder"],B=v({__name:"SearchInput",props:{placeHolder:{}},emits:["search"],setup(i,{emit:d}){const c=d,a=I({clear:!1}),e=y(void 0),s=()=>{c("search",e.value)},u=()=>{e.value=void 0,a.clear=!1,c("search",void 0)},p=h(e,700);return m(p,()=>{e?a.clear=!0:a.clear=!1,s()}),(N,o)=>(t(),l("div",V,[n(r,{icon:"vuesax-linear:search-normal-1",class:"si__icon",size:"18",onClick:s}),f(x("input",{"onUpdate:modelValue":o[0]||(o[0]=_=>e.value=_),class:"si__input",placeholder:i.placeHolder,onKeyup:k(s,["enter"])},null,40,w),[[b,e.value]]),a.clear?(t(),l("button",{key:0,type:"button",class:"si__clear","aria-label":"پاک کردن",onClick:u},[n(r,{icon:"vuesax-linear:add",size:"16"})])):C("",!0)]))}}),D=S(B,[["__scopeId","data-v-4c50067a"]]);export{D as S};
|
||||
@@ -1 +1 @@
|
||||
import{d as r,c as t,b as o,t as s,f as n,i as _,e as d,I as u,g as a,_ as b}from"./index-CtDx9pmc.js";const m={class:"sec"},f={class:"sec__text"},x={class:"sec__title"},h={key:0,class:"sec__sub"},k=r({__name:"SectionHead",props:{title:{},subtitle:{},actionLabel:{}},emits:["action"],setup(e,{emit:i}){const l=i;return(p,c)=>(a(),t("header",m,[o("div",f,[o("h2",x,s(e.title),1),e.subtitle?(a(),t("p",h,s(e.subtitle),1)):n("",!0)]),e.actionLabel?(a(),t("button",{key:0,type:"button",class:"sec__action",onClick:c[0]||(c[0]=v=>l("action"))},[_(s(e.actionLabel)+" ",1),d(u,{icon:"vuesax-linear:arrow-left-2",size:"15"})])):n("",!0)]))}}),N=b(k,[["__scopeId","data-v-e5c65b7c"]]);export{N as S};
|
||||
import{d as r,c as t,b as o,t as s,f as n,i as _,e as d,I as u,g as a,_ as b}from"./index-CGo5tz1H.js";const m={class:"sec"},f={class:"sec__text"},x={class:"sec__title"},h={key:0,class:"sec__sub"},k=r({__name:"SectionHead",props:{title:{},subtitle:{},actionLabel:{}},emits:["action"],setup(e,{emit:i}){const l=i;return(p,c)=>(a(),t("header",m,[o("div",f,[o("h2",x,s(e.title),1),e.subtitle?(a(),t("p",h,s(e.subtitle),1)):n("",!0)]),e.actionLabel?(a(),t("button",{key:0,type:"button",class:"sec__action",onClick:c[0]||(c[0]=v=>l("action"))},[_(s(e.actionLabel)+" ",1),d(u,{icon:"vuesax-linear:arrow-left-2",size:"15"})])):n("",!0)]))}}),N=b(k,[["__scopeId","data-v-e5c65b7c"]]);export{N as S};
|
||||
@@ -1 +1 @@
|
||||
import{d as k,E as A,o as C,c as i,e as r,w as f,s as w,u as m,f as E,j as u,g as l,F as R,b as s,r as D,I as T,t as o,n as p,q as N,_ as L}from"./index-CtDx9pmc.js";import{P}from"./PageBar-5aeeoH1Q.js";import{a as M}from"./Spinner.vue_vue_type_style_index_0_lang-DJDyZ-LG.js";import{S as O}from"./SectionHead-B3LfQC4D.js";import{j as g,p as B}from"./filters-CLL9nGZ2.js";import{a as I}from"./client-WIBW0tF5.js";import{D as U}from"./index-B698smgh.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./classCallCheck-DCKKMDGE.js";const V={class:"tx"},$={class:"tx__list"},Y=["onClick"],j={class:"tx__main"},z={class:"tx__head"},F={class:"tx__kind"},G={key:0,class:"tx__note"},H={class:"tx__foot"},q={class:"tx__date"},J={key:1,class:"tx__empty"},K={class:"sheet"},Q={class:"sheet__specs"},W={class:"sheet__spec"},X={class:"sheet__spec"},Z={class:"sheet__spec"},ss={class:"sheet__spec"},es={class:"sheet__spec"},ts=k({__name:"TransactionsView",setup(os){const x={ORDER_STOCK:"سفارش",ORDER_PRE_ORDER:"سفارش ساخت",REPAYMENT_MELTED_GOLD:"طلای آبشده",REPAYMENT_TRANSFER:"حواله",REPAYMENT_CHEQUE:"چک",REPAYMENT_CASH:"پولی",WALLET_BONUS:"پاداش",ADJUSTMENT:"اصلاحیه"},h=A(),_=u(!1),d=u([]),v=u(!1),n=u(null),c=a=>a.direction==="CREDIT",y=a=>a.currency==="GOLD_GRAM"?`${a.amount} گرم`:`${B(a.amount)} ریال`,S=a=>{n.value=a,v.value=!0};return C(async()=>{if(h.customerId){_.value=!0;try{d.value=await I.getLedgerEntries(h.customerId)}finally{_.value=!1}}}),(a,e)=>{const b=N("container");return l(),i("div",V,[r(P,{title:"اسناد","back-to":"userPage::hasSubRoute"}),r(M,{spinning:_.value,tip:"درحال دریافت اطلاعات"},{default:f(()=>[r(b,{class:"tx__body"},{default:f(()=>[d.value.length?(l(),i(R,{key:0},[r(O,{title:"گردش حساب",subtitle:`${d.value.length} سند`},null,8,["subtitle"]),s("div",$,[(l(!0),i(R,null,D(d.value,t=>(l(),i("article",{key:t.id,class:"tx__row",onClick:ns=>S(t)},[s("span",{class:p(["tx__mark",c(t)?"is-in":"is-out"]),"aria-hidden":"true"},[r(T,{icon:c(t)?"vuesax-linear:arrow-down":"vuesax-linear:arrow-up",size:"16"},null,8,["icon"])],2),s("div",j,[s("div",z,[s("h3",F,o(x[t.sourceType]??t.sourceType),1),s("span",{class:p(["tx__amount",c(t)?"is-in":"is-out"])},o(y(t)),3)]),t.note?(l(),i("p",G,o(t.note),1)):E("",!0),s("div",H,[s("span",q,o(m(g)(t.createdAt)),1),s("span",{class:p(["tx__state",{"is-pending":!t.confirmed}])},o(t.confirmed?"تایید شده":"در انتظار تایید"),3)])])],8,Y))),128))])],64)):_.value?E("",!0):(l(),i("section",J,[r(T,{icon:"vuesax-linear:receipt-text",size:"26"}),e[1]||(e[1]=s("p",null,"سندی برای حساب شما ثبت نشده است.",-1))]))]),_:1})]),_:1},8,["spinning"]),n.value?(l(),w(m(U),{key:0,visible:v.value,"onUpdate:visible":e[0]||(e[0]=t=>v.value=t),placement:"bottom",closable:!1,height:"420px",class:"rtl",bodyStyle:{padding:0}},{default:f(()=>[s("div",K,[e[7]||(e[7]=s("h3",{class:"sheet__title"},"جزئیات سند",-1)),s("dl",Q,[s("div",W,[e[2]||(e[2]=s("dt",null,"نوع سند",-1)),s("dd",null,o(x[n.value.sourceType]??n.value.sourceType),1)]),s("div",X,[e[3]||(e[3]=s("dt",null,"مبلغ",-1)),s("dd",{class:p(c(n.value)?"is-in":"is-out")},o(y(n.value)),3)]),s("div",Z,[e[4]||(e[4]=s("dt",null,"وضعیت",-1)),s("dd",null,o(n.value.confirmed?"تایید شده":"در انتظار تایید"),1)]),s("div",ss,[e[5]||(e[5]=s("dt",null,"تاریخ",-1)),s("dd",null,o(m(g)(n.value.createdAt)),1)]),s("div",es,[e[6]||(e[6]=s("dt",null,"توضیحات",-1)),s("dd",null,o(n.value.note||"—"),1)])])])]),_:1},8,["visible"])):E("",!0)])}}}),vs=L(ts,[["__scopeId","data-v-83b037a9"]]);export{vs as default};
|
||||
import{d as k,E as A,o as C,c as i,e as r,w as f,s as w,u as m,f as E,j as u,g as l,F as R,b as s,r as D,I as T,t as o,n as p,q as N,_ as L}from"./index-CGo5tz1H.js";import{P}from"./PageBar-B7OwbOZ2.js";import{a as M}from"./Spinner.vue_vue_type_style_index_0_lang-OVIFoXDj.js";import{S as O}from"./SectionHead-CxJqY2Fp.js";import{j as g,p as B}from"./filters-CLL9nGZ2.js";import{a as I}from"./client-WIBW0tF5.js";import{D as U}from"./index-BmmdHz27.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./classCallCheck-Bw9dWuSE.js";const V={class:"tx"},$={class:"tx__list"},Y=["onClick"],j={class:"tx__main"},z={class:"tx__head"},F={class:"tx__kind"},G={key:0,class:"tx__note"},H={class:"tx__foot"},q={class:"tx__date"},J={key:1,class:"tx__empty"},K={class:"sheet"},Q={class:"sheet__specs"},W={class:"sheet__spec"},X={class:"sheet__spec"},Z={class:"sheet__spec"},ss={class:"sheet__spec"},es={class:"sheet__spec"},ts=k({__name:"TransactionsView",setup(os){const x={ORDER_STOCK:"سفارش",ORDER_PRE_ORDER:"سفارش ساخت",REPAYMENT_MELTED_GOLD:"طلای آبشده",REPAYMENT_TRANSFER:"حواله",REPAYMENT_CHEQUE:"چک",REPAYMENT_CASH:"پولی",WALLET_BONUS:"پاداش",ADJUSTMENT:"اصلاحیه"},h=A(),_=u(!1),d=u([]),v=u(!1),n=u(null),c=a=>a.direction==="CREDIT",y=a=>a.currency==="GOLD_GRAM"?`${a.amount} گرم`:`${B(a.amount)} ریال`,S=a=>{n.value=a,v.value=!0};return C(async()=>{if(h.customerId){_.value=!0;try{d.value=await I.getLedgerEntries(h.customerId)}finally{_.value=!1}}}),(a,e)=>{const b=N("container");return l(),i("div",V,[r(P,{title:"اسناد","back-to":"userPage::hasSubRoute"}),r(M,{spinning:_.value,tip:"درحال دریافت اطلاعات"},{default:f(()=>[r(b,{class:"tx__body"},{default:f(()=>[d.value.length?(l(),i(R,{key:0},[r(O,{title:"گردش حساب",subtitle:`${d.value.length} سند`},null,8,["subtitle"]),s("div",$,[(l(!0),i(R,null,D(d.value,t=>(l(),i("article",{key:t.id,class:"tx__row",onClick:ns=>S(t)},[s("span",{class:p(["tx__mark",c(t)?"is-in":"is-out"]),"aria-hidden":"true"},[r(T,{icon:c(t)?"vuesax-linear:arrow-down":"vuesax-linear:arrow-up",size:"16"},null,8,["icon"])],2),s("div",j,[s("div",z,[s("h3",F,o(x[t.sourceType]??t.sourceType),1),s("span",{class:p(["tx__amount",c(t)?"is-in":"is-out"])},o(y(t)),3)]),t.note?(l(),i("p",G,o(t.note),1)):E("",!0),s("div",H,[s("span",q,o(m(g)(t.createdAt)),1),s("span",{class:p(["tx__state",{"is-pending":!t.confirmed}])},o(t.confirmed?"تایید شده":"در انتظار تایید"),3)])])],8,Y))),128))])],64)):_.value?E("",!0):(l(),i("section",J,[r(T,{icon:"vuesax-linear:receipt-text",size:"26"}),e[1]||(e[1]=s("p",null,"سندی برای حساب شما ثبت نشده است.",-1))]))]),_:1})]),_:1},8,["spinning"]),n.value?(l(),w(m(U),{key:0,visible:v.value,"onUpdate:visible":e[0]||(e[0]=t=>v.value=t),placement:"bottom",closable:!1,height:"420px",class:"rtl",bodyStyle:{padding:0}},{default:f(()=>[s("div",K,[e[7]||(e[7]=s("h3",{class:"sheet__title"},"جزئیات سند",-1)),s("dl",Q,[s("div",W,[e[2]||(e[2]=s("dt",null,"نوع سند",-1)),s("dd",null,o(x[n.value.sourceType]??n.value.sourceType),1)]),s("div",X,[e[3]||(e[3]=s("dt",null,"مبلغ",-1)),s("dd",{class:p(c(n.value)?"is-in":"is-out")},o(y(n.value)),3)]),s("div",Z,[e[4]||(e[4]=s("dt",null,"وضعیت",-1)),s("dd",null,o(n.value.confirmed?"تایید شده":"در انتظار تایید"),1)]),s("div",ss,[e[5]||(e[5]=s("dt",null,"تاریخ",-1)),s("dd",null,o(m(g)(n.value.createdAt)),1)]),s("div",es,[e[6]||(e[6]=s("dt",null,"توضیحات",-1)),s("dd",null,o(n.value.note||"—"),1)])])])]),_:1},8,["visible"])):E("",!0)])}}}),vs=L(ts,[["__scopeId","data-v-83b037a9"]]);export{vs as default};
|
||||
@@ -1 +1 @@
|
||||
import{j as d,u as F,l as i,p as S}from"./index-CtDx9pmc.js";import{a as P}from"./client-WIBW0tF5.js";function W(t){return!t||t.length===0?null:t.reduce((e,s)=>parseFloat(s.defaultWagePercent)<parseFloat(e.defaultWagePercent)?s:e)}function I(t,e){const s=d(t),r=i(()=>{var n,p;return(p=(n=s.value.images)==null?void 0:n[0])==null?void 0:p.url}),o=i(()=>s.value.id),u=i(()=>s.value.title),l=i(()=>s.value.variants),a=d(e??W(F(l))),v=i(()=>a.value?parseFloat(a.value.rashWeightGrams):0),g=i(()=>a.value?parseFloat(a.value.defaultWagePercent):null),x=d(null),f=i(()=>{var n;return((n=a.value)==null?void 0:n.qty)??0}),h=i(()=>{var n;return((n=a.value)==null?void 0:n.isPreOrder)??!1}),y=i(()=>f.value>0||h.value),_=i(()=>s.value.productCode??null),C=d(!1);return{product:s,image:r,id:o,title:u,productCode:_,variants:l,selectedVariant:a,min_gram:v,wage:g,hasDiscountWage:x,qty:f,isPreOrder:h,is_exist:y,has_warranty:C}}const m="appCart";function q(){try{const t=localStorage.getItem(m);return t?JSON.parse(t):[]}catch{return[]}}function c(t){localStorage.setItem(m,JSON.stringify(t))}const G=S("cart",{state:()=>({items:q()}),actions:{async init(){try{const t=await P.listProducts(),e=[];for(const s of this.items){const r=t.find(u=>u.id===s.pid),o=r==null?void 0:r.variants.find(u=>u.id===s.vid);r&&o&&e.push({...s,product:r})}this.items=e,c(this.items)}catch(t){console.log(t)}},addToCart(t){const e=this.find_index(t);e===-1?this.items.push(t):(this.items[e].product=t.product,this.items[e].qty=t.qty),c(this.items)},remove(t){const e=this.find_index(t);e>-1&&this.items.splice(e,1),c(this.items)},updateFeild(t,e,s,r){if(!this.isInCart(s))return!1;const o=e??this.find_index(s);return this.items[o][r]=t,c(this.items),!0},find_index(t){return this.items.findIndex(e=>e.pid===t.pid&&e.vid===t.vid)},isInCart(t){return this.find_index(t)>-1},variant(t){return t.product.variants.find(e=>e.id===t.vid)},total(){return this.items.reduce((t,e)=>{const s=this.variant(e);return t+(s?parseFloat(s.rashWeightGrams)*e.qty:0)},0).toFixed(2)},clear(){this.items=[],c(this.items)}}});export{G as a,I as u};
|
||||
import{j as d,u as F,l as i,p as S}from"./index-CGo5tz1H.js";import{a as P}from"./client-WIBW0tF5.js";function W(t){return!t||t.length===0?null:t.reduce((e,s)=>parseFloat(s.defaultWagePercent)<parseFloat(e.defaultWagePercent)?s:e)}function I(t,e){const s=d(t),r=i(()=>{var n,p;return(p=(n=s.value.images)==null?void 0:n[0])==null?void 0:p.url}),o=i(()=>s.value.id),u=i(()=>s.value.title),l=i(()=>s.value.variants),a=d(e??W(F(l))),v=i(()=>a.value?parseFloat(a.value.rashWeightGrams):0),g=i(()=>a.value?parseFloat(a.value.defaultWagePercent):null),x=d(null),f=i(()=>{var n;return((n=a.value)==null?void 0:n.qty)??0}),h=i(()=>{var n;return((n=a.value)==null?void 0:n.isPreOrder)??!1}),y=i(()=>f.value>0||h.value),_=i(()=>s.value.productCode??null),C=d(!1);return{product:s,image:r,id:o,title:u,productCode:_,variants:l,selectedVariant:a,min_gram:v,wage:g,hasDiscountWage:x,qty:f,isPreOrder:h,is_exist:y,has_warranty:C}}const m="appCart";function q(){try{const t=localStorage.getItem(m);return t?JSON.parse(t):[]}catch{return[]}}function c(t){localStorage.setItem(m,JSON.stringify(t))}const G=S("cart",{state:()=>({items:q()}),actions:{async init(){try{const t=await P.listProducts(),e=[];for(const s of this.items){const r=t.find(u=>u.id===s.pid),o=r==null?void 0:r.variants.find(u=>u.id===s.vid);r&&o&&e.push({...s,product:r})}this.items=e,c(this.items)}catch(t){console.log(t)}},addToCart(t){const e=this.find_index(t);e===-1?this.items.push(t):(this.items[e].product=t.product,this.items[e].qty=t.qty),c(this.items)},remove(t){const e=this.find_index(t);e>-1&&this.items.splice(e,1),c(this.items)},updateFeild(t,e,s,r){if(!this.isInCart(s))return!1;const o=e??this.find_index(s);return this.items[o][r]=t,c(this.items),!0},find_index(t){return this.items.findIndex(e=>e.pid===t.pid&&e.vid===t.vid)},isInCart(t){return this.find_index(t)>-1},variant(t){return t.product.variants.find(e=>e.id===t.vid)},total(){return this.items.reduce((t,e)=>{const s=this.variant(e);return t+(s?parseFloat(s.rashWeightGrams)*e.qty:0)},0).toFixed(2)},clear(){this.items=[],c(this.items)}}});export{G as a,I as u};
|
||||
@@ -1 +1 @@
|
||||
import{c as l}from"./Spinner.vue_vue_type_style_index_0_lang-DJDyZ-LG.js";var f=function(n){return setTimeout(n,16)},c=function(n){return clearTimeout(n)};typeof window<"u"&&"requestAnimationFrame"in window&&(f=function(n){return window.requestAnimationFrame(n)},c=function(n){return window.cancelAnimationFrame(n)});var i=0,o=new Map;function u(e){o.delete(e)}function w(e){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:1;i+=1;var r=i;function a(t){if(t===0)u(r),e();else{var s=f(function(){a(t-1)});o.set(r,s)}}return a(n),r}w.cancel=function(e){var n=o.get(e);return u(n),c(n)};function m(e,n){for(var r=l({},e),a=0;a<n.length;a+=1){var t=n[a];delete r[t]}return r}function p(e,n,r){return Object.defineProperty(e,"prototype",{writable:!1}),e}function v(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}export{p as _,v as a,m as o,w};
|
||||
import{c as l}from"./Spinner.vue_vue_type_style_index_0_lang-OVIFoXDj.js";var f=function(n){return setTimeout(n,16)},c=function(n){return clearTimeout(n)};typeof window<"u"&&"requestAnimationFrame"in window&&(f=function(n){return window.requestAnimationFrame(n)},c=function(n){return window.cancelAnimationFrame(n)});var i=0,o=new Map;function u(e){o.delete(e)}function w(e){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:1;i+=1;var r=i;function a(t){if(t===0)u(r),e();else{var s=f(function(){a(t-1)});o.set(r,s)}}return a(n),r}w.cancel=function(e){var n=o.get(e);return u(n),c(n)};function m(e,n){for(var r=l({},e),a=0;a<n.length;a+=1){var t=n[a];delete r[t]}return r}function p(e,n,r){return Object.defineProperty(e,"prototype",{writable:!1}),e}function v(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}export{p as _,v as a,m as o,w};
|
||||
@@ -0,0 +1 @@
|
||||
const s="/assets/dialogEmpty1-DRc_s2oB.svg";export{s as l};
|
||||
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
@@ -1 +0,0 @@
|
||||
const s="/assets/dialogEmpty1-B2m57R6G.svg";export{s as l};
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -1 +0,0 @@
|
||||
import{p as e}from"./index-CtDx9pmc.js";const t={colors:[],brands:[],ciny_id:[],limit_percent:[],limit_gram:[],has_discount:!1,text:void 0,cats:void 0,page:0},i=e("filters",{state:()=>({query:{...t}}),actions:{reset(){this.query={...t}}}});export{i as u};
|
||||
@@ -1 +1 @@
|
||||
import{a3 as y,d as L,a4 as $,a5 as w,G as A,a6 as N,e as c,j as D,C as p,L as B,a7 as C,K as G,a8 as f,a9 as I,aa as M,ab as R}from"./index-CtDx9pmc.js";const[U,r,Y]=y("pull-refresh"),x=50,j=["pulling","loosing","success"],F={disabled:Boolean,modelValue:Boolean,headHeight:f(x),successText:String,pullingText:String,loosingText:String,loadingText:String,pullDistance:$,successDuration:f(500),animationDuration:f(300)};var K=L({name:U,props:F,emits:["change","refresh","update:modelValue"],setup(s,{emit:d,slots:o}){let u;const g=D(),T=D(),H=w(g),e=p({status:"normal",distance:0,duration:0}),i=M(),P=()=>{if(s.headHeight!==x)return{height:`${s.headHeight}px`}},h=()=>e.status!=="loading"&&e.status!=="success"&&!s.disabled,k=t=>{const a=+(s.pullDistance||s.headHeight);return t>a&&(t<a*2?t=a+(t-a)/2:t=a*1.5+(t-a*2)/4),Math.round(t)},n=(t,a)=>{const l=+(s.pullDistance||s.headHeight);e.distance=t,a?e.status="loading":t===0?e.status="normal":t<l?e.status="pulling":e.status="loosing",d("change",{status:e.status,distance:t})},m=()=>{const{status:t}=e;return t==="normal"?"":s[`${t}Text`]||Y(t)},E=()=>{const{status:t,distance:a}=e;if(o[t])return o[t]({distance:a});const l=[];return j.includes(t)&&l.push(c("div",{class:r("text")},[m()])),t==="loading"&&l.push(c(B,{class:r("loading")},{default:m})),l},V=()=>{e.status="success",setTimeout(()=>{n(0)},+s.successDuration)},v=t=>{u=I(H.value)===0,u&&(e.duration=0,i.start(t))},b=t=>{h()&&v(t)},_=t=>{if(h()){u||v(t);const{deltaY:a}=i;i.move(t),u&&a.value>=0&&i.isVertical()&&(C(t),n(k(a.value)))}},S=()=>{u&&i.deltaY.value&&h()&&(e.duration=+s.animationDuration,e.status==="loosing"?(n(+s.headHeight,!0),d("update:modelValue",!0),G(()=>d("refresh"))):n(0))};return A(()=>s.modelValue,t=>{e.duration=+s.animationDuration,t?n(+s.headHeight,!0):o.success||s.successText?V():n(0,!1)}),N("touchmove",_,{target:T}),()=>{var t;const a={transitionDuration:`${e.duration}ms`,transform:e.distance?`translate3d(0,${e.distance}px, 0)`:""};return c("div",{ref:g,class:r()},[c("div",{ref:T,class:r("track"),style:a,onTouchstartPassive:b,onTouchend:S,onTouchcancel:S},[c("div",{class:r("head"),style:P()},[E()]),(t=o.default)==null?void 0:t.call(o)])])}}});const q=R(K);export{q as P};
|
||||
import{a3 as y,d as L,a4 as $,a5 as w,G as A,a6 as N,e as c,j as D,C as p,L as B,a7 as C,K as G,a8 as f,a9 as I,aa as M,ab as R}from"./index-CGo5tz1H.js";const[U,r,Y]=y("pull-refresh"),x=50,j=["pulling","loosing","success"],F={disabled:Boolean,modelValue:Boolean,headHeight:f(x),successText:String,pullingText:String,loosingText:String,loadingText:String,pullDistance:$,successDuration:f(500),animationDuration:f(300)};var K=L({name:U,props:F,emits:["change","refresh","update:modelValue"],setup(s,{emit:d,slots:o}){let u;const g=D(),T=D(),H=w(g),e=p({status:"normal",distance:0,duration:0}),i=M(),P=()=>{if(s.headHeight!==x)return{height:`${s.headHeight}px`}},h=()=>e.status!=="loading"&&e.status!=="success"&&!s.disabled,k=t=>{const a=+(s.pullDistance||s.headHeight);return t>a&&(t<a*2?t=a+(t-a)/2:t=a*1.5+(t-a*2)/4),Math.round(t)},n=(t,a)=>{const l=+(s.pullDistance||s.headHeight);e.distance=t,a?e.status="loading":t===0?e.status="normal":t<l?e.status="pulling":e.status="loosing",d("change",{status:e.status,distance:t})},m=()=>{const{status:t}=e;return t==="normal"?"":s[`${t}Text`]||Y(t)},E=()=>{const{status:t,distance:a}=e;if(o[t])return o[t]({distance:a});const l=[];return j.includes(t)&&l.push(c("div",{class:r("text")},[m()])),t==="loading"&&l.push(c(B,{class:r("loading")},{default:m})),l},V=()=>{e.status="success",setTimeout(()=>{n(0)},+s.successDuration)},v=t=>{u=I(H.value)===0,u&&(e.duration=0,i.start(t))},b=t=>{h()&&v(t)},_=t=>{if(h()){u||v(t);const{deltaY:a}=i;i.move(t),u&&a.value>=0&&i.isVertical()&&(C(t),n(k(a.value)))}},S=()=>{u&&i.deltaY.value&&h()&&(e.duration=+s.animationDuration,e.status==="loosing"?(n(+s.headHeight,!0),d("update:modelValue",!0),G(()=>d("refresh"))):n(0))};return A(()=>s.modelValue,t=>{e.duration=+s.animationDuration,t?n(+s.headHeight,!0):o.success||s.successText?V():n(0,!1)}),N("touchmove",_,{target:T}),()=>{var t;const a={transitionDuration:`${e.duration}ms`,transform:e.distance?`translate3d(0,${e.distance}px, 0)`:""};return c("div",{ref:g,class:r()},[c("div",{ref:T,class:r("track"),style:a,onTouchstartPassive:b,onTouchend:S,onTouchcancel:S},[c("div",{class:r("head"),style:P()},[E()]),(t=o.default)==null?void 0:t.call(o)])])}}});const q=R(K);export{q as P};
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -9,8 +9,8 @@
|
||||
<meta name="background-color" content="#1C2D56" />
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport" />
|
||||
<title>طلای منتزر</title>
|
||||
<script type="module" crossorigin src="/assets/index-CtDx9pmc.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-8vi5Klr2.css">
|
||||
<script type="module" crossorigin src="/assets/index-CGo5tz1H.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-Bio3zTgc.css">
|
||||
<link rel="manifest" href="/manifest.webmanifest"></head>
|
||||
<body style="background-color: #1C2D56">
|
||||
<div class="bg-white w-screen h-screen fixed"></div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import icons from './icons.json'
|
||||
|
||||
interface Props {
|
||||
@@ -14,17 +14,37 @@ interface Props {
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
color: null,
|
||||
})
|
||||
const tempIcon = ref<string>()
|
||||
const refIcon = ref<HTMLSpanElement>()
|
||||
tempIcon.value = (icons as Record<string, string>)[`${props.icon}`]
|
||||
|
||||
onMounted(() => {
|
||||
if (props.size) {
|
||||
const svg = refIcon.value?.children[0] as SVGElement
|
||||
svg.setAttribute('width', props.size as string)
|
||||
svg.setAttribute('height', props.size as string)
|
||||
}
|
||||
})
|
||||
// FIXED: this used to be a plain ref, assigned once at setup —
|
||||
// tempIcon.value = icons[props.icon]
|
||||
// — instead of a computed. Vue reuses the same component instance across
|
||||
// re-renders when an `Icon` sits in the same template position (which every
|
||||
// caller in this app does; none pass a `:key` keyed to the icon name), so
|
||||
// setup only runs once per mount and that assignment never ran again. Any
|
||||
// caller that swaps `icon` on an already-mounted instance — the exact pattern
|
||||
// the cart quantity steppers use, `:icon="qty === 1 ? 'trash' : 'minus'"` —
|
||||
// had its SVG freeze on whichever icon happened to render first and silently
|
||||
// stop tracking the prop after that: incrementing a cart line past 1 never
|
||||
// swapped the frozen trash glyph back to minus, and the reverse (decrementing
|
||||
// back down to 1) never swapped a frozen minus back to trash either. A
|
||||
// computed re-evaluates on every `icon` change, so the markup — and, via the
|
||||
// watcher below, the width/height attributes size() sets on it — now actually
|
||||
// track the prop instead of only reading it once.
|
||||
const tempIcon = computed(() => (icons as Record<string, string>)[`${props.icon}`])
|
||||
|
||||
function applySize() {
|
||||
if (!props.size) return
|
||||
const svg = refIcon.value?.children[0] as SVGElement | undefined
|
||||
svg?.setAttribute('width', props.size as string)
|
||||
svg?.setAttribute('height', props.size as string)
|
||||
}
|
||||
|
||||
// v-html replaces refIcon's children synchronously with the DOM update, but
|
||||
// that update itself is queued — nextTick() waits for it so applySize() finds
|
||||
// the new <svg> already in the DOM rather than the previous one (or none, on
|
||||
// the very first render).
|
||||
watch(tempIcon, () => nextTick(applySize), { immediate: true })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
<!--
|
||||
Swipeable image slider — a from-scratch rewrite of the gallery/preview
|
||||
carousel that used to live inline in SingleProduct.vue.
|
||||
|
||||
WHY A REWRITE, NOT A PATCH: the old slider swiped correctly by feel but
|
||||
visibly jumped mid-gesture, in both the inline gallery and the full-screen
|
||||
preview. The root cause was structural, not a tunable number:
|
||||
|
||||
- The whole app sets `direction: rtl !important` on #app (see
|
||||
src/App.vue). Under RTL, a flex row lays its children right-to-left —
|
||||
slide 0 sits at the visual RIGHT edge, not the left.
|
||||
- `transform: translate3d(X%, 0, 0)` is direction-agnostic: a positive X
|
||||
always moves content toward the visual right, in RTL exactly as in LTR.
|
||||
- The old track combined `translate3d(index * 100%, 0, 0)` with the page's
|
||||
ambient RTL flex order. Those two systems don't agree on which way
|
||||
"forward" is, so the settle position after a drag did not line up with
|
||||
where the flex box had actually placed that slide — the visual result
|
||||
was the image overshooting and snapping back, i.e. the reported "jump".
|
||||
|
||||
THE FIX: this component's slider track is an isolated `direction: ltr`
|
||||
subtree (see .gs__track below). Once inside that subtree, slide order,
|
||||
pointer-delta sign and `translateX` sign are all plain, ordinary LTR
|
||||
arithmetic — index 0 first, positive X moves right, done — regardless of
|
||||
what direction the rest of the page is in. The component's own controls
|
||||
(dots, drag gesture) still read as natural "swipe right for previous
|
||||
image" to an RTL user because the *gesture* is still interpreted in screen
|
||||
space; only the slider's internal layout is pinned to LTR so its own maths
|
||||
is self-consistent.
|
||||
|
||||
A few other correctness fixes bundled into the same rewrite, since they were
|
||||
entangled with the same code:
|
||||
- Pointer Events instead of Touch Events: one code path for touch, mouse
|
||||
and pen, with proper pointer capture so a drag that leaves the element
|
||||
(finger sliding off the edge) is still tracked to completion instead of
|
||||
silently stopping — the old touch-only handlers dropped the gesture the
|
||||
moment the finger crossed the element boundary.
|
||||
- Position is settled against the track's OWN measured width
|
||||
(getBoundingClientRect), not against `%` of an assumed-100%-per-slide
|
||||
layout — immune to any box-sizing/padding mismatch between the measured
|
||||
width and the CSS `flex: 0 0 100%` cell width.
|
||||
- One component, two instances (the inline stage and the full-screen
|
||||
preview both render a <GallerySlider>) instead of one set of drag state
|
||||
manually re-entered for two different DOM subtrees via a `source` tag.
|
||||
They stay in sync through `v-model:index`, a plain reactive prop/emit
|
||||
binding — not shared mutable drag variables, which is what the "does a
|
||||
drag started on A leak into B" bug class was ultimately rooted in.
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
ref="root"
|
||||
class="gs"
|
||||
:class="{ 'is-dragging': dragging }"
|
||||
@pointerdown="onPointerDown"
|
||||
@pointermove="onPointerMove"
|
||||
@pointerup="onPointerUp"
|
||||
@pointercancel="onPointerCancel"
|
||||
@click="onClick"
|
||||
>
|
||||
<div class="gs__track" :style="trackStyle">
|
||||
<div v-for="src in slides" :key="src" class="gs__cell">
|
||||
<img :src="src" :alt="alt" class="gs__img" :class="fitClass" draggable="false" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showCounter && slides.length > 1" class="gs__counter">{{ index + 1 }}/{{ slides.length }}</div>
|
||||
|
||||
<slot name="dots" :index="index" :go="go" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, ref } from 'vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
slides: string[]
|
||||
alt: string
|
||||
/** `cover` (the inline stage's default) or `contain` (the preview's). */
|
||||
fit?: 'cover' | 'contain'
|
||||
/** Show the built-in "n/N" pill, bottom-start of the slider.
|
||||
*
|
||||
* Off by default. FIXED: both call sites in SingleProduct.vue already
|
||||
* draw their own overlay chrome in that same corner — the inline stage
|
||||
* has .pd__expand there, and the preview has its own top-centre
|
||||
* .pd__previewCounter — so this component's counter used to render on
|
||||
* top of .pd__expand unconditionally, the two pieces of UI visibly
|
||||
* overlapping into illegible stacked text/icons. Neither caller wants
|
||||
* this counter today; a future bare usage that does can opt in. */
|
||||
showCounter?: boolean
|
||||
}>(),
|
||||
{ fit: 'cover', showCounter: false },
|
||||
)
|
||||
|
||||
const index = defineModel<number>('index', { default: 0 })
|
||||
|
||||
const emit = defineEmits<{
|
||||
/** A plain tap — press and release without a real drag. Distinct from a
|
||||
* native `click`, which a touch sequence also fires synthetically on
|
||||
* release even after a drag; consumers that want "open on tap only"
|
||||
* should use this instead of listening for `click` themselves. */
|
||||
(e: 'tap'): void
|
||||
}>()
|
||||
|
||||
const fitClass = computed(() => (props.fit === 'contain' ? 'gs__img--contain' : 'gs__img--cover'))
|
||||
|
||||
const root = ref<HTMLElement | null>(null)
|
||||
|
||||
// ── Drag state ────────────────────────────────────────────────
|
||||
// All local to one instance — the inline stage and the full-screen preview
|
||||
// each mount their own GallerySlider and so each get their own root, dragX,
|
||||
// dragging, etc. Nothing here is shared across instances; only `index` is,
|
||||
// via v-model, which is exactly the one thing that SHOULD stay in sync.
|
||||
const dragging = ref(false)
|
||||
const dragX = ref(0)
|
||||
let pointerId: number | null = null
|
||||
let startX = 0
|
||||
let trackWidth = 0
|
||||
|
||||
// Past this many pixels of travel, the drag counts as a swipe rather than a
|
||||
// tap — used both to decide whether to commit to the next/previous slide and
|
||||
// to suppress the `tap` event so a swipe never also opens the preview.
|
||||
const DRAG_COMMIT_RATIO = 0.18 // fraction of the track's own width
|
||||
const TAP_MAX_PX = 6
|
||||
|
||||
function onPointerDown(e: PointerEvent) {
|
||||
if (props.slides.length < 2 || pointerId !== null) return
|
||||
const el = root.value
|
||||
if (!el) return
|
||||
pointerId = e.pointerId
|
||||
startX = e.clientX
|
||||
trackWidth = el.getBoundingClientRect().width || 1
|
||||
dragX.value = 0
|
||||
dragging.value = true
|
||||
// Pointer capture keeps delivering move/up events to this element even once
|
||||
// the pointer leaves it — the touch-events version of this component lost
|
||||
// the gesture the instant a fast swipe crossed the element's edge.
|
||||
el.setPointerCapture?.(e.pointerId)
|
||||
}
|
||||
|
||||
function onPointerMove(e: PointerEvent) {
|
||||
if (!dragging.value || e.pointerId !== pointerId) return
|
||||
dragX.value = e.clientX - startX
|
||||
}
|
||||
|
||||
function endDrag() {
|
||||
if (!dragging.value) return
|
||||
const dx = dragX.value
|
||||
const ratio = dx / trackWidth
|
||||
|
||||
dragging.value = false
|
||||
pointerId = null
|
||||
dragX.value = 0
|
||||
|
||||
// Screen-space drag direction, translated to an index step. This is the one
|
||||
// place RTL vs. LTR actually matters for *behaviour* (not layout): dragging
|
||||
// a finger to the left (negative dx) is "next image" regardless of the
|
||||
// track's own internal LTR layout, because that is what the gesture means
|
||||
// to the person doing it, in either reading direction.
|
||||
if (ratio <= -DRAG_COMMIT_RATIO && index.value < props.slides.length - 1) index.value++
|
||||
else if (ratio >= DRAG_COMMIT_RATIO && index.value > 0) index.value--
|
||||
|
||||
if (Math.abs(dx) <= TAP_MAX_PX) emit('tap')
|
||||
}
|
||||
|
||||
function onPointerUp(e: PointerEvent) {
|
||||
if (e.pointerId !== pointerId) return
|
||||
endDrag()
|
||||
}
|
||||
|
||||
function onPointerCancel(e: PointerEvent) {
|
||||
if (e.pointerId !== pointerId) return
|
||||
// A cancelled gesture (e.g. the OS takes over for a system swipe) snaps back
|
||||
// to the current slide rather than committing a possibly-partial drag.
|
||||
dragging.value = false
|
||||
pointerId = null
|
||||
dragX.value = 0
|
||||
}
|
||||
|
||||
// A touch sequence still fires a native `click` on release. `onPointerUp`
|
||||
// already emits `tap` for a real tap and has already run by the time `click`
|
||||
// fires, so this handler only needs to swallow the click's default double-
|
||||
// firing — nothing further to do here, but the listener stays as documentation
|
||||
// that `click` is deliberately NOT used for the tap-to-preview affordance
|
||||
// (`tap` is) precisely because `click` also fires after a swipe.
|
||||
function onClick() {
|
||||
/* intentionally empty — see comment above */
|
||||
}
|
||||
|
||||
function go(i: number) {
|
||||
index.value = i
|
||||
}
|
||||
|
||||
// ── Track position ───────────────────────────────────────────
|
||||
// The whole point of isolating this in its own `direction: ltr` subtree (see
|
||||
// .gs__track in <style>): inside it, "index 0 is first" and "positive X moves
|
||||
// right" are both just true, with no page-level RTL to reconcile against.
|
||||
const trackStyle = computed(() => {
|
||||
const base = -index.value * 100
|
||||
const dragPercent = trackWidth ? (dragX.value / trackWidth) * 100 : 0
|
||||
return {
|
||||
transform: `translate3d(${base + dragPercent}%, 0, 0)`,
|
||||
transition: dragging.value ? 'none' : undefined,
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (pointerId !== null && root.value) {
|
||||
try {
|
||||
root.value.releasePointerCapture(pointerId)
|
||||
} catch {
|
||||
/* element may already be detached */
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.gs {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
touch-action: pan-y;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
// Isolated from the page's `direction: rtl` — see the file header. Everything
|
||||
// under this node uses plain LTR layout and LTR-signed transforms.
|
||||
.gs__track {
|
||||
direction: ltr;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
transition: transform 0.42s cubic-bezier(0.22, 0.61, 0.36, 1);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.gs.is-dragging .gs__track {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.gs__cell {
|
||||
flex: 0 0 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gs__img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
-webkit-user-drag: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.gs__img--cover {
|
||||
// The inline stage's own padding/background is supplied by the caller
|
||||
// (.pd__stage); this component only sets the fit mode.
|
||||
object-fit: contain;
|
||||
padding: 46px 20px 20px;
|
||||
}
|
||||
|
||||
.gs__img--contain {
|
||||
object-fit: contain;
|
||||
padding: 20px 22px;
|
||||
}
|
||||
|
||||
.gs__counter {
|
||||
position: absolute;
|
||||
bottom: 14px;
|
||||
// Placed with a logical property (so it sits at the trailing edge in the
|
||||
// page's own RTL reading order) — this is UI chrome layered on top of the
|
||||
// slider, not part of the isolated LTR track, so it should still follow the
|
||||
// page's direction like everything else in the app.
|
||||
inset-inline-start: 14px;
|
||||
padding: 4px 9px;
|
||||
border-radius: 999px;
|
||||
font-size: 10.5px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
background: rgba(20, 22, 26, 0.45);
|
||||
backdrop-filter: blur(4px);
|
||||
direction: ltr;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
@@ -42,21 +42,29 @@
|
||||
<Icon :icon="favorites.isFavorite(id) ? 'vuesax-linear:heart-fill' : 'vuesax-linear:heart'" size="19" />
|
||||
</button>
|
||||
|
||||
<div v-if="hasImages" class="pd__stage">
|
||||
<img :src="slides[imageIndex]" :alt="title" class="pd__art" />
|
||||
<div v-if="slides.length > 1" class="pd__counter">{{ imageIndex + 1 }}/{{ slides.length }}</div>
|
||||
<div v-if="slides.length > 1" class="pd__dots">
|
||||
<button
|
||||
v-for="(s, i) in slides"
|
||||
:key="s"
|
||||
type="button"
|
||||
class="pd__dot"
|
||||
:class="{ 'is-on': i === imageIndex }"
|
||||
:aria-label="`تصویر ${i + 1}`"
|
||||
@click="imageIndex = i"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<GallerySlider
|
||||
v-if="hasImages"
|
||||
v-model:index="imageIndex"
|
||||
:slides="slides"
|
||||
:alt="title"
|
||||
class="pd__stage"
|
||||
@tap="openPreview"
|
||||
>
|
||||
<template #dots="{ index, go }">
|
||||
<div v-if="slides.length > 1" class="pd__counter">{{ index + 1 }}/{{ slides.length }}</div>
|
||||
<div v-if="slides.length > 1" class="pd__dots">
|
||||
<button
|
||||
v-for="(s, i) in slides"
|
||||
:key="s"
|
||||
type="button"
|
||||
class="pd__dot"
|
||||
:class="{ 'is-on': i === index }"
|
||||
:aria-label="`تصویر ${i + 1}`"
|
||||
@click.stop="go(i)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</GallerySlider>
|
||||
<div v-else class="pd__stage pd__stage--empty">
|
||||
<Icon icon="vuesax-linear:diamonds" size="46" />
|
||||
</div>
|
||||
@@ -148,12 +156,11 @@
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<!-- Trust (hidden for now)
|
||||
<!-- Trust -->
|
||||
<div class="pd__trust">
|
||||
<span><Icon icon="vuesax-linear:shield-tick" size="16" /> خرید امن</span>
|
||||
<span><Icon icon="vuesax-linear:verify" size="16" /> اصالت کالا</span>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<!-- Action bar -->
|
||||
@@ -190,6 +197,43 @@
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<!-- Full-screen image preview, teleported to <body> so it is never
|
||||
clipped by this component's own scroll/overflow context (the drawer
|
||||
mount, in particular). Opened by tapping the inline gallery. -->
|
||||
<Teleport to="body">
|
||||
<Transition name="pd-preview">
|
||||
<div v-if="previewOpen" class="pd__preview" @click.self="closePreview">
|
||||
<button type="button" class="pd__previewClose" aria-label="بستن" @click="closePreview">
|
||||
<Icon icon="vuesax-linear:add" size="20" />
|
||||
</button>
|
||||
|
||||
<div v-if="slides.length > 1" class="pd__previewCounter">{{ imageIndex + 1 }} / {{ slides.length }}</div>
|
||||
|
||||
<GallerySlider
|
||||
v-model:index="imageIndex"
|
||||
:slides="slides"
|
||||
:alt="title"
|
||||
class="pd__previewStage"
|
||||
fit="contain"
|
||||
/>
|
||||
|
||||
<div v-if="slides.length > 1" class="pd__previewThumbs no-scrollbar">
|
||||
<button
|
||||
v-for="(s, i) in slides"
|
||||
:key="s"
|
||||
type="button"
|
||||
class="pd__previewThumb"
|
||||
:class="{ 'is-on': i === imageIndex }"
|
||||
:aria-label="`تصویر ${i + 1}`"
|
||||
@click="imageIndex = i"
|
||||
>
|
||||
<img :src="s" :alt="`${title} ${i + 1}`" draggable="false" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
|
||||
<NotifyVant :timeOut="3000" v-model="notify" :color="'background-color: #14161A'">
|
||||
<div class="font-bold text-right mb-2">ثبت سفارش</div>
|
||||
<div>محصول با موفقیت به سبد خرید افزوده شد</div>
|
||||
@@ -201,7 +245,7 @@
|
||||
</template>
|
||||
<template v-slot:title>
|
||||
<div class="p-8 text-justify">
|
||||
برای دسترسی به تمامی امکانات نرم افزار منتزر، ابتدا گزینه ورود/ثبت نام را لمس کنید و در صورت نداشتن حساب کاربری، ثبت نام نمایید.
|
||||
برای دسترسی به تمامی امکانات نرم افزار هنزاگلد، ابتدا گزینه ورود/ثبت نام را لمس کنید و در صورت نداشتن حساب کاربری، ثبت نام نمایید.
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:button>
|
||||
@@ -213,9 +257,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeMount, ref, watch } from 'vue'
|
||||
import { computed, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import Icon from '../icon/Icon.vue'
|
||||
import GallerySlider from './GallerySlider.vue'
|
||||
import Spinner from '../Spinner.vue'
|
||||
import NotifyVant from '../NotifyVant.vue'
|
||||
import DialogVant from '../DialogVant.vue'
|
||||
@@ -291,6 +336,26 @@ watch(slides, (list) => {
|
||||
if (imageIndex.value > list.length - 1) imageIndex.value = 0
|
||||
})
|
||||
|
||||
// ── Full-screen preview ─────────────────────────────────────────
|
||||
// Tapping the inline gallery (a plain tap, not a swipe — GallerySlider tells
|
||||
// the two apart itself and only emits `tap` for the former) opens a
|
||||
// full-screen viewer teleported to <body>, with its own GallerySlider kept in
|
||||
// lockstep via the shared `imageIndex` v-model.
|
||||
const previewOpen = ref(false)
|
||||
|
||||
function openPreview() {
|
||||
if (!hasImages.value) return
|
||||
previewOpen.value = true
|
||||
// Teleported to <body>, so without this the page (or the Drawer) would
|
||||
// still scroll behind the preview.
|
||||
document.body.style.overflow = 'hidden'
|
||||
}
|
||||
|
||||
function closePreview() {
|
||||
previewOpen.value = false
|
||||
document.body.style.overflow = ''
|
||||
}
|
||||
|
||||
const wageLabel = computed(() => {
|
||||
const w = wage.value
|
||||
if (w == null) return ''
|
||||
@@ -342,6 +407,13 @@ const toggleFav = (e: Event) => {
|
||||
onBeforeMount(async () => {
|
||||
await productDetail.load()
|
||||
})
|
||||
|
||||
// If the preview is left open when this instance goes away — the drawer is
|
||||
// closed, or the routed page is navigated away from — the body scroll lock it
|
||||
// set would otherwise outlive it and leave the rest of the app unscrollable.
|
||||
onBeforeUnmount(() => {
|
||||
if (previewOpen.value) document.body.style.overflow = ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -399,10 +471,10 @@ onBeforeMount(async () => {
|
||||
transform: scale(0.92);
|
||||
}
|
||||
.pd__round--back {
|
||||
inset-inline-end: 16px;
|
||||
inset-inline-start: 16px;
|
||||
}
|
||||
.pd__round--fav {
|
||||
inset-inline-start: 16px;
|
||||
inset-inline-end: 16px;
|
||||
}
|
||||
.pd__round--fav.is-on {
|
||||
color: @wine;
|
||||
@@ -410,8 +482,9 @@ onBeforeMount(async () => {
|
||||
|
||||
.pd__counter {
|
||||
position: absolute;
|
||||
bottom: 14px;
|
||||
inset-inline-start: 14px;
|
||||
top: 16px;
|
||||
inset-inline-start: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 4px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
@@ -735,4 +808,112 @@ onBeforeMount(async () => {
|
||||
background: @canvas;
|
||||
border: 1px solid @ink;
|
||||
}
|
||||
|
||||
/* ── Full-screen preview ─────────────────────────────────── */
|
||||
/* Teleported to <body>, so it sits outside .pd entirely — see the template
|
||||
comment on why. z-index cleared well above ant-design-vue's own Drawer
|
||||
layer (@zindex-modal) so the preview is unconditionally topmost regardless
|
||||
of which Teleport happens to mount last. */
|
||||
.pd__preview {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 2000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: rgba(10, 10, 12, 0.55);
|
||||
backdrop-filter: blur(28px) saturate(140%);
|
||||
}
|
||||
|
||||
.pd__previewClose {
|
||||
position: absolute;
|
||||
top: calc(14px + env(safe-area-inset-top, 0px));
|
||||
inset-inline-end: 14px;
|
||||
z-index: 2;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
background: rgba(0, 0, 0, 0.35);
|
||||
backdrop-filter: blur(10px);
|
||||
transform: rotate(45deg);
|
||||
transition: transform 0.18s ease, background 0.18s ease;
|
||||
}
|
||||
.pd__previewClose:active {
|
||||
transform: rotate(45deg) scale(0.92);
|
||||
}
|
||||
|
||||
.pd__previewCounter {
|
||||
position: absolute;
|
||||
top: calc(24px + env(safe-area-inset-top, 0px));
|
||||
inset-inline-start: 0;
|
||||
inset-inline-end: 0;
|
||||
z-index: 2;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
direction: ltr;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.pd__previewStage {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.pd__previewThumbs {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
overflow-x: auto;
|
||||
scroll-snap-type: x proximity;
|
||||
padding: 10px 16px calc(18px + env(safe-area-inset-bottom, 0px));
|
||||
}
|
||||
|
||||
.pd__previewThumb {
|
||||
scroll-snap-align: center;
|
||||
flex: 0 0 auto;
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
padding: 6px;
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
opacity: 0.65;
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
transition: opacity 0.2s ease, outline-color 0.2s ease, transform 0.18s ease;
|
||||
}
|
||||
.pd__previewThumb:active {
|
||||
transform: scale(0.94);
|
||||
}
|
||||
.pd__previewThumb.is-on {
|
||||
opacity: 1;
|
||||
outline-color: #fff;
|
||||
}
|
||||
|
||||
.pd__previewThumb img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
-webkit-user-drag: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.pd-preview-enter-active,
|
||||
.pd-preview-leave-active {
|
||||
transition: opacity 0.24s ease;
|
||||
}
|
||||
.pd-preview-enter-from,
|
||||
.pd-preview-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||