Files
tehran_tala/apps/user-app-v2/dist/assets/DashboardView-Bc-VC3t8.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.4 KiB
JavaScript

import{d as E,E as F,o as M,q as P,c,b as s,u as n,l as t,e as I,s as l,g as h,B as U,p as $,f,i as N,n as b,t as p,D as T,I as o,F as q,L as C,x as B,h as k,v as G,_ as j}from"./index-D7u32dbn.js";import{R as W}from"./RateStrip-BlU2EbWJ.js";import{_ as L}from"./DialogVant.vue_vue_type_style_index_0_lang-CVN0TLHx.js";import{l as H}from"./dialogEmpty1-Caw7F5KL.js";import{p as J}from"./filters-CLL9nGZ2.js";import{P as K}from"./index-B7hk2Rd_.js";import"./_commonjsHelpers-Cpj98o6Y.js";const Q="/assets/dialogEmpty5-DWebUDaI.svg",X={class:"dash"},Y={class:"dash__bar"},Z={class:"dash__barInner"},ss={class:"dash__heroTop"},es={class:"dash__heroIdentity"},ts={class:"dash__heroName"},as={class:"dash__heroMobile"},os={class:"dash__heroFigure"},ns={class:"dash__heroNum"},ls={class:"dash__heroUnit"},is={class:"dash__heroDebt"},rs={class:"dash__inviteIcon","aria-hidden":"true"},us={class:"dash__rowIcon","aria-hidden":"true"},ds={class:"dash__rowIcon","aria-hidden":"true"},_s={class:"dash__rowIcon","aria-hidden":"true"},vs={class:"dash__rowIcon","aria-hidden":"true"},ps={class:"dash__rowIcon","aria-hidden":"true"},cs={class:"dash__rowIcon","aria-hidden":"true"},fs=["src"],ms=["src"],hs=70,bs=E({__name:"DashboardView",setup(ys){const i=B(),_=F(),d=h(null),y=h(null),g=h(!1),x=k(()=>d.value?parseFloat(d.value.goldDebtGrams)>0:!1),V=k(()=>x.value?"بدهکار":"بستانکار"),S=k(()=>d.value?Math.abs(parseFloat(d.value.goldDebtGrams)):0),r=U({notify:!1,loginNotify:!1});function v(u){if(!_.isLoggedIn){r.loginNotify=!0;return}u===0&&i.push({name:"ordersList"}),u===1&&i.push({name:"transactionsList"}),u===2&&i.push({name:"profileData"}),u===3&&i.push({name:"favoritesList"}),u===4&&i.push({name:"ChildOrder"}),u===5&&i.push({name:"customerChoice"})}function A(){_.logout(),r.notify=!1,i.push({name:"home"})}async function z(){_.isLoggedIn&&(d.value=await $.getMe());try{y.value=await $.getLatestGoldPrice()}catch{y.value=null}}async function O(){await z(),g.value=!1}let D=!1;const w=h(D);function m(u){return{"--reveal-delay":`${u*hs}ms`}}return M(async()=>{await z(),!w.value&&(await P(),requestAnimationFrame(()=>{w.value=!0,D=!0}))}),(u,e)=>{const R=G("container");return f(),c("div",X,[s("header",Y,[s("div",Z,[e[14]||(e[14]=s("span",{class:"dash__brand"},"میز کار",-1)),n(_).isLoggedIn?(f(),c("button",{key:0,type:"button",class:"dash__exit","aria-label":"خروج",onClick:e[0]||(e[0]=a=>r.notify=!0)},[t(o,{icon:"vuesax-linear:logout",size:"18"})])):I("",!0)])]),t(n(K),{modelValue:g.value,"onUpdate:modelValue":e[8]||(e[8]=a=>g.value=a),onRefresh:O},{pulling:l(()=>[t(n(C),{size:"18"})]),loosing:l(()=>[t(n(C),{size:"18"})]),loading:l(()=>[t(n(C),{size:"18"})]),success:l(()=>[...e[15]||(e[15]=[s("span",null,null,-1)])]),default:l(()=>[t(R,{class:N(["dash__body",{"is-revealed":w.value}])},{default:l(()=>[d.value?(f(),c("section",{key:0,class:"dash__hero dash__reveal",style:b(m(0))},[s("div",ss,[s("div",es,[s("span",ts,p(d.value.fullName),1),s("span",as,p(n(_).mobile),1)]),s("span",{class:N(["dash__heroSeal",x.value?"is-debtor":"is-creditor"])},p(x.value?"بدهکار":"بستانکار"),3)]),s("div",os,[s("span",ns,p(S.value),1),s("span",ls,"گرم "+p(V.value),1)]),s("div",is,[e[17]||(e[17]=s("span",null,"بدهی ریالی",-1)),s("b",null,[T(p(n(J)(d.value.fiatDebtRial))+" ",1),e[16]||(e[16]=s("i",null,"ریال",-1))])])],4)):(f(),c("section",{key:1,class:"dash__invite dash__reveal",style:b(m(0))},[s("div",rs,[t(o,{icon:"vuesax-linear:security-user",size:"22",color:"#fff"})]),e[18]||(e[18]=s("h3",null,"حساب گرمی شما",-1)),e[19]||(e[19]=s("p",null,"برای دیدن موجودی، سفارش‌ها و اسناد خود وارد شوید.",-1)),s("button",{type:"button",class:"dash__inviteCta",onClick:e[1]||(e[1]=a=>n(i).push({name:"login"}))}," ورود / ثبت‌نام ")],4)),s("section",{class:"dash__rows dash__reveal",style:b(m(1))},[s("button",{type:"button",class:"dash__row",onClick:e[2]||(e[2]=a=>v(0))},[s("span",us,[t(o,{icon:"vuesax-linear:box",size:"18"})]),e[20]||(e[20]=s("span",{class:"dash__rowText"},[s("b",null,"سفارشات"),s("small",null,"پیگیری سفارش‌های شما")],-1)),t(o,{icon:"vuesax-linear:arrow-left-2",size:"16",color:"#8A909C"})]),s("button",{type:"button",class:"dash__row",onClick:e[3]||(e[3]=a=>v(1))},[s("span",ds,[t(o,{icon:"vuesax-linear:receipt-text",size:"18"})]),e[21]||(e[21]=s("span",{class:"dash__rowText"},[s("b",null,"اسناد"),s("small",null,"تراکنش‌ها و رسیدهای حساب")],-1)),t(o,{icon:"vuesax-linear:arrow-left-2",size:"16",color:"#8A909C"})]),s("button",{type:"button",class:"dash__row",onClick:e[4]||(e[4]=a=>v(2))},[s("span",_s,[t(o,{icon:"vuesax-linear:user",size:"18"})]),e[22]||(e[22]=s("span",{class:"dash__rowText"},[s("b",null,"پروفایل"),s("small",null,"اطلاعات و تنظیمات حساب")],-1)),t(o,{icon:"vuesax-linear:arrow-left-2",size:"16",color:"#8A909C"})]),s("button",{type:"button",class:"dash__row",onClick:e[5]||(e[5]=a=>v(3))},[s("span",vs,[t(o,{icon:"vuesax-linear:heart",size:"18"})]),e[23]||(e[23]=s("span",{class:"dash__rowText"},[s("b",null,"علاقمندی"),s("small",null,"محصولات ذخیره‌شده شما")],-1)),t(o,{icon:"vuesax-linear:arrow-left-2",size:"16",color:"#8A909C"})]),n(_).isSalesExpert?(f(),c(q,{key:0},[s("button",{type:"button",class:"dash__row",onClick:e[6]||(e[6]=a=>v(4))},[s("span",ps,[t(o,{icon:"vuesax-linear:box-tick",size:"18"})]),e[24]||(e[24]=s("span",{class:"dash__rowText"},[s("b",null,"سفارش مشتریان"),s("small",null,"سفارش‌های مشتریان معرفی‌شده شما")],-1)),t(o,{icon:"vuesax-linear:arrow-left-2",size:"16",color:"#8A909C"})]),s("button",{type:"button",class:"dash__row",onClick:e[7]||(e[7]=a=>v(5))},[s("span",cs,[t(o,{icon:"vuesax-linear:profile-2user",size:"18"})]),e[25]||(e[25]=s("span",{class:"dash__rowText"},[s("b",null,"مشتریان من"),s("small",null,"فهرست مشتریان معرفی‌شده شما")],-1)),t(o,{icon:"vuesax-linear:arrow-left-2",size:"16",color:"#8A909C"})])],64)):I("",!0)],4),t(W,{quote:y.value,class:"dash__rate dash__reveal",style:b(m(2))},null,8,["quote","style"])]),_:1},8,["class"])]),_:1},8,["modelValue"]),t(L,{timeOut:-1,show:r.notify,"onUpdate:show":e[10]||(e[10]=a=>r.notify=a),closeOnClickOverlay:!0},{img:l(()=>[s("img",{src:n(Q),alt:"",class:"opacity-70 mb-8"},null,8,fs)]),title:l(()=>[...e[26]||(e[26]=[T("آیا می خواهید از برنامه خارج شوید؟",-1)])]),button:l(()=>[s("div",{class:"text-center text-[#1C2D56]",onClick:A},"بله"),s("div",{class:"text-center text-[#6b7280]",onClick:e[9]||(e[9]=a=>r.notify=!1)},"بی خیال")]),_:1},8,["show"]),t(L,{timeOut:-1,show:r.loginNotify,"onUpdate:show":e[13]||(e[13]=a=>r.loginNotify=a),closeOnClickOverlay:!0},{img:l(()=>[s("img",{src:n(H),alt:"",class:"opacity-80"},null,8,ms)]),title:l(()=>[...e[27]||(e[27]=[s("div",{class:"p-8 text-justify"}," برای دسترسی به تمامی امکانات نرم افزار منتزر، ابتدا گزینه ورود/ثبت نام را لمس کنید و در صورت نداشتن حساب کاربری، ثبت نام نمایید. ",-1)])]),button:l(()=>[s("div",{class:"text-center text-[#1C2D56]",onClick:e[11]||(e[11]=a=>n(i).push({name:"login"}))},"ورود/ثبت نام"),s("div",{class:"text-center text-danger",onClick:e[12]||(e[12]=a=>r.loginNotify=!1)},"بیخیال")]),_:1},8,["show"])])}}}),Is=j(bs,[["__scopeId","data-v-7f911406"]]);export{Is as default};