- API: `pnpm build` bundles dist/ into apps/api/.output (esbuild), with Linux musl native packages for sharp and argon2 kept alongside - docker/api.Dockerfile copies that output; no pnpm install on the server - add dist/migrate.js (prisma migrate deploy equivalent, same _prisma_migrations table and lock) so the Prisma CLI is not needed at runtime - pnpm-workspace: supportedArchitectures for linux/x64/musl - admin: apps/admin/.env.production sets VITE_SITE_URL for the production build - drop NPM_REGISTRY / SITE_URL build args from compose and .env.example - gitignore: anchor node_modules rules so pre-built node_modules are committed - README: describe the pre-built deploy flow Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
1 line
13 KiB
JavaScript
1 line
13 KiB
JavaScript
import{i as e,t}from"./VuesaxIcon-B2OgulS6.js";import{Bt as n,Ct as ee,Dt as r,It as i,Lt as a,Nt as o,Rt as s,Tt as c,_t as l,ct as u,dt as d,ft as te,gt as f,ht as p,i as m,kt as h,lt as g,n as _,ot as v,pt as y,t as b,ut as x,zt as ne}from"./index-BuGK6ptM.js";import{a as S,n as re,r as C}from"./format-B9MYDQJN.js";import{t as w}from"./PageHeader-3Ryvg2HD.js";var T={class:`flex items-center gap-2`},E={class:`grid grid-cols-2 gap-3 lg:gap-4 lg:grid-cols-5`},D={class:`flex items-center justify-between`},O={class:`flex size-10 items-center justify-center rounded-xl bg-orange-50 text-orange-600`},k={class:`mt-2 text-xs text-gray-400`},A={class:`flex items-center justify-between`},j={class:`flex size-10 items-center justify-center rounded-xl bg-amber-50 text-amber-600`},M={class:`flex items-center justify-between`},N={class:`flex size-10 items-center justify-center rounded-xl bg-blue-50 text-blue-600`},P={class:`flex items-center justify-between`},F={class:`mt-2 text-xs text-gray-400`},I={class:`flex items-center justify-between`},L={class:`flex size-10 items-center justify-center rounded-xl bg-purple-50 text-purple-600`},R={class:`mt-6 grid gap-6 lg:grid-cols-12`},z={class:`grid grid-cols-2 gap-3 sm:grid-cols-4`},B={class:`flex flex-col items-center justify-center rounded-xl border border-gray-100 bg-gray-50/70 p-4 text-center transition-all hover:border-orange-200 hover:bg-orange-50/50 hover:shadow-sm`},V={class:`mb-2 flex size-11 items-center justify-center rounded-full bg-white text-orange-600 shadow-sm`},H={class:`flex flex-col items-center justify-center rounded-xl border border-gray-100 bg-gray-50/70 p-4 text-center transition-all hover:border-blue-200 hover:bg-blue-50/50 hover:shadow-sm`},U={class:`mb-2 flex size-11 items-center justify-center rounded-full bg-white text-blue-600 shadow-sm`},W={class:`flex flex-col items-center justify-center rounded-xl border border-gray-100 bg-gray-50/70 p-4 text-center transition-all hover:border-emerald-200 hover:bg-emerald-50/50 hover:shadow-sm`},G={class:`mb-2 flex size-11 items-center justify-center rounded-full bg-white text-emerald-600 shadow-sm`},K={class:`flex flex-col items-center justify-center rounded-xl border border-gray-100 bg-gray-50/70 p-4 text-center transition-all hover:border-purple-200 hover:bg-purple-50/50 hover:shadow-sm`},q={class:`mb-2 flex size-11 items-center justify-center rounded-full bg-white text-purple-600 shadow-sm`},J={class:`flex items-center gap-4`},Y={class:`space-y-1.5 text-xs`},X={class:`font-bold text-gray-800`},ie={class:`text-gray-500`},ae={key:0,class:`text-emerald-600 font-medium`},oe={key:1,class:`text-amber-600 font-medium`},se={class:`mt-6 grid gap-6 lg:grid-cols-12`},ce={key:0,class:`py-8`},le={key:1,class:`space-y-3.5 pt-1`},ue={class:`flex items-center justify-between text-xs font-medium`},de={class:`text-gray-700`},fe={class:`font-mono text-gray-500`},pe={class:`grid grid-cols-3 gap-2 text-center`},me={class:`rounded-lg bg-orange-50 p-2.5`},he={class:`text-lg font-black text-orange-600`},ge={class:`rounded-lg bg-blue-50 p-2.5`},_e={class:`text-lg font-black text-blue-600`},ve={class:`rounded-lg bg-gray-50 p-2.5`},ye={class:`text-lg font-black text-gray-600`},be={class:`mt-5 border-t border-gray-100 pt-4`},xe={class:`flex h-28 items-end justify-between gap-1.5 sm:gap-2 pt-4`},Se={key:0,class:`text-[9px] font-bold text-orange-600 mb-0.5`},Ce={key:1,class:`text-[9px] text-transparent mb-0.5 select-none`},we={class:`relative flex w-full justify-center`},Te={class:`text-[10px] text-gray-400 truncate max-w-[36px]`},Ee={class:`mt-6 grid gap-6 lg:grid-cols-2`},De={class:`text-left text-xs text-gray-400`},Oe={class:`mt-1 font-mono text-[11px]`},ke={class:`text-sm`},Ae={key:0,class:`text-gray-600`},je={class:`mt-0.5 text-xs text-gray-400`},Z=l({__name:`DashboardPage`,setup(l){b();let Z=i(null),Q=i(!0),Me=g(()=>Z.value?.categoryStats?.length?Math.max(...Z.value.categoryStats.map(e=>e.count),1):1),Ne=g(()=>Z.value?.trend?.length?Math.max(...Z.value.trend.map(e=>e.messages),1):1),Pe=g(()=>Z.value?.sectionsSummary?.total?Math.round(Z.value.sectionsSummary.visible/Z.value.sectionsSummary.total*100):100);return ee(async()=>{Q.value=!0;try{Z.value=await _(`/admin/dashboard`)}catch(e){v.error(m(e))}finally{Q.value=!1}}),(ee,i)=>{let l=h(`a-button`),m=h(`RouterLink`),g=h(`a-statistic`),_=h(`a-card`),v=h(`a-progress`),b=h(`a-empty`),Fe=h(`a-tooltip`),Ie=h(`a-list-item-meta`),Le=h(`a-tag`),$=h(`a-list-item`),Re=h(`a-list`),ze=h(`a-timeline-item`),Be=h(`a-timeline`),Ve=h(`a-spin`);return c(),y(u,null,[f(w,{title:`داشبورد مدیریت`,subtitle:`نمای کلی آمار، نمودارها، پیامها و فعالیتهای اخیر سامانه`},{default:o(()=>[x(`div`,T,[f(m,{to:{name:`sections`}},{default:o(()=>[f(l,null,{icon:o(()=>[f(t,{name:`row-vertical`,size:16})]),default:o(()=>[i[0]||=p(` مدیریت بخشها `,-1)]),_:1})]),_:1}),f(m,{to:{name:`product-new`}},{default:o(()=>[f(l,{type:`primary`},{icon:o(()=>[f(t,{name:`add`,size:16})]),default:o(()=>[i[1]||=p(` محصول جدید `,-1)]),_:1})]),_:1})])]),_:1}),f(Ve,{spinning:Q.value},{default:o(()=>[x(`div`,E,[f(m,{to:{name:`products`},class:`active:scale-[0.98] transition-transform`},{default:o(()=>[f(_,{hoverable:``,class:`h-full`,"body-style":{padding:`14px`}},{default:o(()=>[x(`div`,D,[f(g,{title:`کل محصولات`,value:a(C)(Z.value?.products??0)},null,8,[`value`]),x(`div`,O,[f(t,{name:`bag-2`,size:20})])]),x(`div`,k,n(a(C)((Z.value?.products??0)-(Z.value?.draftProducts??0)))+` محصول فعال روی سایت `,1)]),_:1})]),_:1}),f(m,{to:{name:`products`,query:{status:`draft`}},class:`active:scale-[0.98] transition-transform`},{default:o(()=>[f(_,{hoverable:``,class:`h-full`,"body-style":{padding:`14px`}},{default:o(()=>[x(`div`,A,[f(g,{title:`پیشنویسها`,value:a(C)(Z.value?.draftProducts??0)},null,8,[`value`]),x(`div`,j,[f(t,{name:`document-text`,size:20})])]),i[2]||=x(`div`,{class:`mt-2 text-xs text-gray-400`},`نیاز به بازبینی و انتشار`,-1)]),_:1})]),_:1}),f(m,{to:{name:`categories`},class:`active:scale-[0.98] transition-transform`},{default:o(()=>[f(_,{hoverable:``,class:`h-full`,"body-style":{padding:`14px`}},{default:o(()=>[x(`div`,M,[f(g,{title:`دستهبندیها`,value:a(C)(Z.value?.categories??0)},null,8,[`value`]),x(`div`,N,[f(t,{name:`category`,size:20})])]),i[3]||=x(`div`,{class:`mt-2 text-xs text-gray-400`},`شاخههای تجهیزات ایمنی`,-1)]),_:1})]),_:1}),f(m,{to:{name:`messages`,query:{status:`NEW`}},class:`active:scale-[0.98] transition-transform`},{default:o(()=>[f(_,{hoverable:``,class:`h-full`,"body-style":{padding:`14px`}},{default:o(()=>[x(`div`,P,[f(g,{title:`پیامهای جدید`,value:a(C)(Z.value?.newMessages??0),"value-style":Z.value?.newMessages?{color:`#ff5a00`,fontWeight:`bold`}:void 0},null,8,[`value`,`value-style`]),x(`div`,{class:s([`flex size-10 items-center justify-center rounded-xl`,Z.value?.newMessages?`bg-orange-100 text-orange-600 animate-pulse`:`bg-gray-100 text-gray-500`])},[f(t,{name:`sms`,size:20})],2)]),x(`div`,F,` از مجموع `+n(a(C)(Z.value?.messageBreakdown?.total??0))+` پیام `,1)]),_:1})]),_:1}),f(m,{to:{name:`media`},class:`max-lg:col-span-2 active:scale-[0.98] transition-transform`},{default:o(()=>[f(_,{hoverable:``,class:`h-full`,"body-style":{padding:`14px`}},{default:o(()=>[x(`div`,I,[f(g,{title:`رسانهها و تصاویر`,value:a(C)(Z.value?.media??0)},null,8,[`value`]),x(`div`,L,[f(t,{name:`gallery`,size:20})])]),i[4]||=x(`div`,{class:`mt-2 text-xs text-gray-400`},`تصاویر بهینهشده WebP`,-1)]),_:1})]),_:1})]),x(`div`,R,[f(_,{title:`دسترسیهای سریع`,class:`lg:col-span-8`},{default:o(()=>[x(`div`,z,[f(m,{to:{name:`product-new`},class:`block`},{default:o(()=>[x(`div`,B,[x(`div`,V,[f(t,{name:`add`,size:22})]),i[5]||=x(`span`,{class:`text-xs font-bold text-gray-800`},`افزودن محصول`,-1),i[6]||=x(`span`,{class:`mt-1 text-[11px] text-gray-400`},`کالای ایمنی جدید`,-1)])]),_:1}),f(m,{to:{name:`category-new`},class:`block`},{default:o(()=>[x(`div`,H,[x(`div`,U,[f(t,{name:`folder-add`,size:22})]),i[7]||=x(`span`,{class:`text-xs font-bold text-gray-800`},`دستهبندی جدید`,-1),i[8]||=x(`span`,{class:`mt-1 text-[11px] text-gray-400`},`گروه محصولات`,-1)])]),_:1}),f(m,{to:{name:`sections`},class:`block`},{default:o(()=>[x(`div`,W,[x(`div`,G,[f(t,{name:`row-vertical`,size:22})]),i[9]||=x(`span`,{class:`text-xs font-bold text-gray-800`},`بخشهای سایت`,-1),i[10]||=x(`span`,{class:`mt-1 text-[11px] text-gray-400`},`نمایش یا مخفیسازی`,-1)])]),_:1}),f(m,{to:{name:`media`},class:`block`},{default:o(()=>[x(`div`,K,[x(`div`,q,[f(t,{name:`gallery-add`,size:22})]),i[11]||=x(`span`,{class:`text-xs font-bold text-gray-800`},`آپلود رسانه`,-1),i[12]||=x(`span`,{class:`mt-1 text-[11px] text-gray-400`},`تصاویر و اسناد`,-1)])]),_:1})])]),_:1}),f(_,{title:`وضعیت بخشهای صفحه اصلی`,class:`lg:col-span-4`},{extra:o(()=>[f(m,{to:{name:`sections`},class:`text-xs text-orange-600 hover:underline`},{default:o(()=>[...i[13]||=[p(` مدیریت `,-1)]]),_:1})]),default:o(()=>[x(`div`,J,[f(v,{type:`circle`,percent:Pe.value,size:72,"stroke-color":{"0%":`#ff8a3d`,"100%":`#ff5a00`}},null,8,[`percent`]),x(`div`,Y,[x(`div`,X,n(a(C)(Z.value?.sectionsSummary?.visible??0))+` بخش از `+n(a(C)(Z.value?.sectionsSummary?.total??12))+` فعال `,1),x(`div`,ie,[(Z.value?.sectionsSummary?.hidden??0)===0?(c(),y(`span`,ae,` تمامی بخشهای سایت در حال نمایش هستند `)):(c(),y(`span`,oe,n(a(C)(Z.value?.sectionsSummary?.hidden??0))+` بخش غیرفعال / مخفی `,1))]),i[14]||=x(`div`,{class:`text-[11px] text-gray-400`},` تغییر وضعیت آنی از منوی بخشهای سایت `,-1)])])]),_:1})]),x(`div`,se,[f(_,{title:`نمودار توزیع محصولات بر اساس دستهبندی`,class:`lg:col-span-7`},{default:o(()=>[Z.value?.categoryStats?.length?(c(),y(`div`,le,[(c(!0),y(u,null,r(Z.value.categoryStats,e=>(c(),y(`div`,{key:e.id,class:`space-y-1`},[x(`div`,ue,[x(`span`,de,n(e.name),1),x(`span`,fe,n(a(C)(e.count))+` محصول`,1)]),f(v,{percent:Math.round(e.count/Me.value*100),"show-info":!1,"stroke-color":{"0%":`#ffd0b5`,"100%":`#ff5a00`},size:`small`},null,8,[`percent`])]))),128))])):(c(),y(`div`,ce,[f(b,{description:`دادهای موجود نیست`})]))]),_:1}),f(_,{title:`تحلیل پیامهای تماس دریافتی`,class:`lg:col-span-5`},{default:o(()=>[x(`div`,pe,[x(`div`,me,[x(`div`,he,n(a(C)(Z.value?.messageBreakdown?.new??0)),1),i[15]||=x(`div`,{class:`text-[11px] font-medium text-gray-600`},`جدید`,-1)]),x(`div`,ge,[x(`div`,_e,n(a(C)(Z.value?.messageBreakdown?.read??0)),1),i[16]||=x(`div`,{class:`text-[11px] font-medium text-gray-600`},`خواندهشده`,-1)]),x(`div`,ve,[x(`div`,ye,n(a(C)(Z.value?.messageBreakdown?.archived??0)),1),i[17]||=x(`div`,{class:`text-[11px] font-medium text-gray-600`},`بایگانی`,-1)])]),x(`div`,be,[i[18]||=x(`div`,{class:`mb-3 flex items-center justify-between text-xs`},[x(`span`,{class:`font-bold text-gray-700`},`روند پیامها در ۷ روز اخیر`),x(`span`,{class:`text-gray-400`},`نمودار روزانه`)],-1),x(`div`,xe,[(c(!0),y(u,null,r(Z.value?.trend??[],e=>(c(),y(`div`,{key:e.date,class:`flex flex-1 flex-col items-center gap-1`},[e.messages>0?(c(),y(`span`,Se,n(a(C)(e.messages)),1)):(c(),y(`span`,Ce,`-`)),f(Fe,{title:`${e.dayName}: ${a(C)(e.messages)} پیام`},{default:o(()=>[x(`div`,we,[x(`div`,{class:s([`w-full max-w-[24px] rounded-t-md transition-all duration-300`,e.messages>0?`bg-orange-500 hover:bg-orange-600`:`bg-gray-100`]),style:ne({height:`${Math.max(Math.round(e.messages/Ne.value*72),6)}px`})},null,6)])]),_:2},1032,[`title`]),x(`span`,Te,n(e.dayName),1)]))),128))])])]),_:1})]),x(`div`,Ee,[f(_,{title:`آخرین پیامهای تماس`},{extra:o(()=>[f(m,{to:{name:`messages`},class:`text-xs text-orange-600 hover:underline`},{default:o(()=>[...i[19]||=[p(` مشاهده همه ← `,-1)]]),_:1})]),default:o(()=>[Z.value?.recentMessages.length?(c(),d(Re,{key:1,"data-source":Z.value.recentMessages,"item-layout":`horizontal`},{renderItem:o(({item:t})=>[f($,null,{default:o(()=>[f(Ie,{title:`${t.name} — ${t.org}`,description:t.message||t.phone},null,8,[`title`,`description`]),x(`div`,De,[f(Le,{color:t.status===`NEW`?`orange`:t.status===`READ`?`blue`:`default`},{default:o(()=>[p(n(a(e)[t.status]),1)]),_:2},1032,[`color`]),x(`div`,Oe,n(a(S)(t.createdAt)),1)])]),_:2},1024)]),_:1},8,[`data-source`])):(c(),d(b,{key:0,description:`پیامی ثبت نشده است`}))]),_:1}),f(_,{title:`آخرین فعالیتها و رویدادهای سیستم`},{default:o(()=>[Z.value?.recentActivity.length?(c(),d(Be,{key:1,class:`!mt-2 max-h-[360px] overflow-y-auto pe-2`},{default:o(()=>[(c(!0),y(u,null,r(Z.value.recentActivity,e=>(c(),d(ze,{key:e.id,color:e.action===`delete`?`red`:e.action===`create`?`green`:`blue`},{default:o(()=>[x(`div`,ke,[x(`b`,null,n(a(re)(e.action,e.entity)),1),e.summary?(c(),y(`span`,Ae,` — `+n(e.summary),1)):te(``,!0)]),x(`div`,je,n(e.user??`سیستم`)+` · `+n(a(S)(e.createdAt)),1)]),_:2},1032,[`color`]))),128))]),_:1})):(c(),d(b,{key:0,description:`فعالیتی ثبت نشده است`}))]),_:1})])]),_:1},8,[`spinning`])],64)}}});export{Z as default}; |