Files
tehran_taj/apps/user-app-v2/dist/assets/CartView-BIwq4R5f.js
T
s.esmaeiliandClaude Opus 5 5ad1083aee parity(apps+api): complete_profile in both apps [ref: henza_server Major/CustomerController::complete]
Ports "تکمیل پروفایل" end to end (D22).

API
- POST customer/me/complete-profile — three required document ids, the
  customer taken from the token, verification step set to the reference's
  LIVE value (approved outright; its `= 1` line is commented out at :83 in
  favour of `= 2` at :85). Both SMS messages byte-identical and non-blocking
  per D20.
- POST customer/me/documents — the reference let the app upload through the
  same file/create the admin used, inside its auth:api-customer group
  (routes/api.php:95); the target's copy is admin-guarded, so the page could
  not have uploaded at all. Reuses AdminUploadsService unchanged, so both
  paths share one size limit, MIME whitelist and naming scheme (UPL-01).
- PROFILE_ADMIN_MOBILES replaces the reference's four hardcoded personal
  numbers; blank means nobody is notified and the upload still succeeds.

Three reference behaviours deliberately NOT ported, all in ISSUES.md:
- SEC-14: `$customer->update($request->all())` mass-assigned the whole request
  body, letting the app write its own credit limit, making charge, gold debt,
  active flag or mobile. Replaced with a three-field whitelist.
- SEC-15: four real personal mobiles hardcoded in the source.
- APP-03: refresh()'s unterminated setInterval page reload.

Apps (both, template+script byte-identical, per-app styling only)
- CompleteProfileView + SingleImageUploader
- route /complete_profile, redirecting home once the documents are in, as the
  reference's guard did (router/index.ts:266)
- the entry point on the profile screen, shown only while they are missing
  (profile.vue:96-102)

Also (D23): JWT_CUSTOMER_SECRET now warns loudly at boot when unset. It falls
back to JWT_SECRET, which signs app and admin tokens with the same key and
leaves the `typ` check as the only barrier — and an expert's app token carries
their AdminUser id in `sub`. Warn rather than refuse to boot (D19, lowest
risk); DELIVERY.md lists it as the first pre-release step (REL-03).

Verified: build 5/5 · jest 45/45 · complete-profile 38/38 (new) ·
expert login 36/36 · apps smoke 43/43 · admin smoke 43/43 ·
B2B scan 34 ok/0 broken · typecheck clean on all four apps.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 01:42:07 +03:30

2 lines
7.9 KiB
JavaScript

import{d as S,k as T,f as l,c,b as e,u as o,w as M,l as n,I as f,t as p,e as I,D as $,h as D,_ as N,E as j,o as A,q as Q,s as i,j as R,g as V,B,i as W,F as G,r as H,L as F,x as X,p as J,v as K,n as Y}from"./index-D7u32dbn.js";import{l as Z}from"./dialogEmpty1-Caw7F5KL.js";import{P as tt}from"./PageBar-CihrRnwd.js";import{a as et}from"./Spinner.vue_vue_type_style_index_0_lang-Ce4r_sA4.js";import{_ as U}from"./DialogVant.vue_vue_type_style_index_0_lang-CVN0TLHx.js";import{a as O,u as st}from"./cartStore-B3Iy7abs.js";import{D as ot}from"./index-CGMkzVe8.js";import{P as at}from"./index-B7hk2Rd_.js";import{F as nt,T as it,a as lt}from"./index-Byj54e9o.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./classCallCheck-BIPEroH2.js";import"./FormItemContext-7CalZ13j.js";const rt="/assets/dialogEmpty4-Bh_UXocp.svg",ct={class:"ci"},dt={class:"ci__art"},ut=["alt"],_t={key:1,class:"ci__artEmpty","aria-hidden":"true"},mt={class:"ci__main"},vt={class:"ci__title"},pt={class:"ci__meta"},yt={class:"ci__weight"},ft={key:0,class:"ci__wage"},gt={class:"ci__row"},bt={class:"ci__qty"},wt=["disabled"],xt={class:"ci__qtyValue"},kt={key:0,class:"ci__noteText"},ht=S({__name:"CartItem",props:{value:{}},emits:["note"],setup(_,{emit:k}){const r=_,d=k,m=O(),y=m.find_index(r.value),g=D(()=>m.maxQty(r.value)),b=D(()=>g.value===null||r.value.qty<g.value),q=()=>{b.value&&m.updateFeild(r.value.qty+1,y,r.value,"qty")},s=()=>{m.updateFeild(r.value.qty-1,y,r.value,"qty")},{image:v,title:h,selectedVariant:P,wage:C}=st(r.value.product,m.variant(r.value)),z=D(()=>{const u=C.value;return u==null?"":u%1===0?String(u):u.toFixed(2)});return(u,t)=>{var x;const w=T("lazy");return l(),c("article",ct,[e("div",dt,[o(v)?M((l(),c("img",{key:0,alt:o(h)},null,8,ut)),[[w,o(v)]]):(l(),c("div",_t,[n(f,{icon:"vuesax-linear:diamonds",size:"20"})]))]),e("div",mt,[e("h3",vt,p(o(h)),1),e("div",pt,[e("span",yt,p((x=o(P))==null?void 0:x.rashWeightGrams)+" گرم",1),o(C)!=null?(l(),c("span",ft,"اجرت "+p(z.value)+"٪",1)):I("",!0)]),e("div",gt,[e("div",bt,[e("button",{type:"button",class:"ci__qtyBtn","aria-label":"افزودن",disabled:!b.value,onClick:q},[n(f,{icon:"vuesax-linear:add",size:"16"})],8,wt),e("span",xt,p(_.value.qty),1),_.value.qty===1?(l(),c("button",{key:0,type:"button",class:"ci__qtyBtn ci__qtyBtn--danger","aria-label":"حذف",onClick:t[0]||(t[0]=a=>o(m).remove(_.value))},[n(f,{icon:"vuesax-linear:trash",size:"16"})])):(l(),c("button",{key:1,type:"button",class:"ci__qtyBtn","aria-label":"کاهش",onClick:s},[n(f,{icon:"vuesax-linear:minus",size:"16"})]))]),e("button",{type:"button",class:"ci__note",onClick:t[1]||(t[1]=a=>d("note",o(y)))},[n(f,{icon:"vuesax-linear:note-text",size:"15"}),$(" "+p(!_.value.note||_.value.note===""?"توضیحات":"ویرایش توضیحات"),1)])]),_.value.note?(l(),c("p",kt,p(_.value.note),1)):I("",!0)])])}}}),Ct=N(ht,[["__scopeId","data-v-b125dde9"]]),$t={class:"cart"},It={key:1,class:"cart__empty"},qt={key:1,class:"cart__done"},Pt={class:"cart__doneIcon","aria-hidden":"true"},zt={class:"cart__doneSub"},Dt={key:0,class:"cart__bar"},Rt={class:"cart__barInner"},Vt={class:"cart__total"},Ft={class:"cart__totalValue"},Bt={class:"sheet"},Ut={class:"sheet__title"},St=["src"],Nt=["src"],Ot=60,Et=S({__name:"CartView",setup(_){let k=!1;const r=X(),d=O(),m=j(),y=V(!1),g=V(!1),b=V(k);function q(u){return{"--reveal-delay":`${u*Ot}ms`}}const s=B({loadingPage:!1,showPopUp:!1,step:1,notify:!1,orderID:"",tempRowIndex:-1,tempRow:{product:void 0}}),v=B({note:void 0}),h=()=>{d.updateFeild(v.note,s.tempRowIndex,s.tempRow,"note"),s.showPopUp=!1,v.note=void 0,s.tempRow={product:void 0}},P=async()=>{await r.push({name:"ordersList"}),s.step=1},C=async()=>{if(s.notify=!1,!m.isLoggedIn){y.value=!0;return}try{s.loadingPage=!0;const u=await J.createOrder({customerId:m.customerId??void 0,items:d.items.map(t=>{const w=d.variant(t);return{productVariantId:t.vid,quantity:t.qty,wagePercent:w?parseFloat(w.defaultWagePercent):0}})});s.orderID=u.orderNumber,s.step=2,d.clear()}catch(u){console.log(u)}finally{s.loadingPage=!1}};async function z(){await d.init(),g.value=!1}return A(async()=>{await d.init(),!b.value&&(await Q(),requestAnimationFrame(()=>{b.value=!0,k=!0}))}),(u,t)=>{var x;const w=K("container");return l(),c("div",$t,[n(tt,{title:"سبد خرید","back-to":"home"}),n(et,{spinning:s.loadingPage,tip:"درحال دریافت اطلاعات"},{default:i(()=>[n(w,{class:"cart__body"},{default:i(()=>[s.step===1?(l(),R(o(at),{key:0,modelValue:g.value,"onUpdate:modelValue":t[1]||(t[1]=a=>g.value=a),onRefresh:z},{pulling:i(()=>[n(o(F),{size:"18"})]),loosing:i(()=>[n(o(F),{size:"18"})]),loading:i(()=>[n(o(F),{size:"18"})]),success:i(()=>[...t[10]||(t[10]=[e("span",null,null,-1)])]),default:i(()=>[o(d).items.length?(l(),c("div",{key:0,class:W(["cart__items",{"is-revealed":b.value}])},[(l(!0),c(G,null,H(o(d).items,(a,E)=>(l(),R(Ct,{key:a.pid+a.vid,value:a,class:"cart__row",style:Y(q(E)),onNote:L=>{s.tempRow=a,s.showPopUp=!0,s.tempRowIndex=L,v.note=a.note??void 0}},null,8,["value","style","onNote"]))),128))],2)):(l(),c("section",It,[n(f,{icon:"vuesax-linear:bag-2",size:"26"}),t[11]||(t[11]=e("p",null,"سبد خرید شما خالی است.",-1)),e("button",{type:"button",class:"cart__emptyCta",onClick:t[0]||(t[0]=a=>o(r).push({name:"home"}))}," دیدن محصولات ")]))]),_:1},8,["modelValue"])):(l(),c("section",qt,[e("div",Pt,[n(f,{icon:"vuesax-linear:tick-circle",size:"30"})]),t[13]||(t[13]=e("h2",{class:"cart__doneTitle"},"سفارش شما ثبت شد",-1)),e("p",zt,[t[12]||(t[12]=$(" شماره سفارش ",-1)),e("b",null,p(s.orderID),1)]),t[14]||(t[14]=e("p",{class:"cart__doneHint"},"برای پیگیری وضعیت، به فهرست سفارش‌ها مراجعه کنید.",-1)),e("button",{type:"button",class:"cart__doneCta",onClick:P},"فهرست سفارش‌ها")]))]),_:1})]),_:1},8,["spinning"]),o(d).items.length>0&&s.step===1?(l(),c("div",Dt,[e("div",Rt,[e("div",Vt,[t[16]||(t[16]=e("span",{class:"cart__totalLabel"},"جمع وزن",-1)),e("span",Ft,[$(p(o(d).total())+" ",1),t[15]||(t[15]=e("i",null,"گرم",-1))])]),e("button",{type:"button",class:"cart__submit",onClick:t[2]||(t[2]=a=>s.notify=!0)},"ثبت نهایی سفارش")])])):I("",!0),(x=s.tempRow)!=null&&x.product?(l(),R(o(ot),{key:1,visible:s.showPopUp,"onUpdate:visible":t[4]||(t[4]=a=>s.showPopUp=a),placement:"bottom",closable:!1,height:"300px",class:"rtl",bodyStyle:{padding:0}},{default:i(()=>[e("div",Bt,[e("h3",Ut,"توضیح برای "+p(s.tempRow.product.title),1),n(o(lt),{model:v,name:"noteForm",layout:"vertical",autocomplete:"off",onFinish:h},{default:i(()=>[n(o(nt),{"has-feedback":"",name:"note"},{default:i(()=>[n(o(it),{value:v.note,"onUpdate:value":t[3]||(t[3]=a=>v.note=a),rows:4,placeholder:"مثلاً سایز یا جزئیات سفارش"},null,8,["value"])]),_:1}),t[17]||(t[17]=e("button",{type:"submit",class:"sheet__cta"},"ثبت توضیحات",-1))]),_:1},8,["model"])])]),_:1},8,["visible"])):I("",!0),n(U,{timeOut:-1,show:s.notify,"onUpdate:show":t[6]||(t[6]=a=>s.notify=a),closeOnClickOverlay:!0},{img:i(()=>[e("img",{src:o(rt),alt:"",class:"opacity-70"},null,8,St)]),title:i(()=>[...t[18]||(t[18]=[$("آیا مطمئن به ثبت سفارش هستید ؟",-1)])]),button:i(()=>[e("div",{class:"text-center text-[#1C2D56]",onClick:C},"بله"),e("div",{class:"text-center text-[#6b7280]",onClick:t[5]||(t[5]=a=>s.notify=!1)},"بی خیال")]),_:1},8,["show"]),n(U,{timeOut:-1,show:y.value,"onUpdate:show":t[9]||(t[9]=a=>y.value=a),closeOnClickOverlay:!0},{img:i(()=>[e("img",{src:o(Z),alt:"",class:"opacity-80"},null,8,Nt)]),title:i(()=>[...t[19]||(t[19]=[e("div",{class:"p-8 text-justify"},"برای ثبت سفارش ابتدا باید وارد حساب کاربری خود شوید.",-1)])]),button:i(()=>[e("div",{class:"text-center text-[#1C2D56]",onClick:t[7]||(t[7]=a=>o(r).push({name:"login"}))},"ورود/ثبت نام"),e("div",{class:"text-center text-danger",onClick:t[8]||(t[8]=a=>y.value=!1)},"بیخیال")]),_:1},8,["show"])])}}}),Yt=N(Et,[["__scopeId","data-v-4c6bfe05"]]);export{Yt as default};