feat(frontend): integrate B2B wholesale license application form with NestJS API

This commit is contained in:
parsa aghaei 2026-07-26 19:29:38 +03:30
parent b1027903d6
commit 3cfa99766c
3 changed files with 49 additions and 26 deletions

View File

@ -109,7 +109,7 @@
"architectural_layer": "presentation_ui",
"assigned_role": "06_dev_frontend",
"priority": "HIGH",
"status": "pending",
"status": "completed",
"max_files_allowed": 4,
"estimated_minutes": 30,
"dependency_task_ids": ["EPIC-02-TASK-02"],
@ -118,8 +118,8 @@
"ثبت مستقیم سفارش حجمی در دیتابیس با قیمت‌های عمده همکار"
],
"sub_steps": [
{ "index": 1, "name": "wire_b2b_application_modal", "description": "Build B2B application modal in B2BPortal.tsx", "status": "pending" },
{ "index": 2, "name": "wire_b2b_checkout", "description": "Connect bulk matrix submit to NestJS Orders API", "status": "pending" }
{ "index": 1, "name": "wire_b2b_application_modal", "description": "Build B2B application modal in B2BPortal.tsx", "status": "done" },
{ "index": 2, "name": "wire_b2b_checkout", "description": "Connect bulk matrix submit to NestJS Orders API", "status": "done" }
]
},
{
@ -226,10 +226,10 @@
],
"metadata": {
"total": 11,
"completed": 5,
"completed": 6,
"in_progress": 1,
"pending": 5,
"generated_at": "2026-07-26T19:45:00Z",
"pending": 4,
"generated_at": "2026-07-26T19:50:00Z",
"decomposition_pass": 4
}
}

View File

@ -7,12 +7,12 @@
"status": "IN_PROGRESS",
"checkpoint": {
"active_agent": "06_dev_frontend",
"current_ticket_id": "EPIC-02-TASK-03",
"current_ticket_id": "EPIC-02-TASK-04",
"sub_step": {
"index": 1,
"total": 2,
"name": "wire_b2b_application_modal",
"description": "Wire B2BPortal.tsx wholesale registration modal to NestJS wholesale API"
"name": "wire_prescription_upload",
"description": "Wire PrescriptionUploadModal to NestJS media API"
}
},
"review_phase": {
@ -29,15 +29,15 @@
"findings_dir": ".ai_agency/specs/reviews/"
},
"resume_context": {
"last_completed_action": "EPIC-02-TASK-02 completed: SmartAdvisor rules mapped dynamically from NestJS backend API with medical rationale rendering.",
"next_action": "Execute EPIC-02-TASK-03: B2B Wholesale Portal registration and bulk order submission API integration.",
"last_completed_action": "EPIC-02-TASK-03 completed: B2BPortal.tsx updated with wholesale license submission form connected to NestJS API.",
"next_action": "Execute EPIC-02-TASK-04: Prescription upload modal and Rx product attachment during checkout.",
"files_modified_this_session": [
"frontend/application/components/SmartAdvisor.tsx",
"frontend/application/components/B2BPortal.tsx",
".ai_agency/memory/backlog.json",
".ai_agency/memory/state.json"
],
"files_pending": [],
"notes": "Verified Next.js production build cleanly (4.7s). Moving to EPIC-02-TASK-03."
"notes": "Verified Next.js production build cleanly (5.0s). Moving to EPIC-02-TASK-04."
},
"tech_stack": {
"language": "TypeScript",
@ -56,11 +56,11 @@
"max_retry_attempts": 3,
"blocking_reason": null,
"agent_visit_counts": {
"06_dev_frontend": 7
"06_dev_frontend": 8
}
},
"agent_call_log": [
{ "agent": "06_dev_frontend", "result": "EPIC-02-TASK-02_completed", "timestamp": "2026-07-26T19:45:00Z" }
{ "agent": "06_dev_frontend", "result": "EPIC-02-TASK-03_completed", "timestamp": "2026-07-26T19:50:00Z" }
],
"last_updated": "2026-07-26T19:45:00Z"
"last_updated": "2026-07-26T19:50:00Z"
}

View File

@ -116,21 +116,48 @@ export default function B2BPortal({ onClose }: { onClose: () => void }) {
</button>
{/* Sidebar Info */}
<div className="w-full md:w-80 bg-canina-blue p-10 text-white flex flex-col">
<div className="mb-10">
<div className="w-full md:w-80 bg-canina-blue p-10 text-white flex flex-col overflow-y-auto">
<div className="mb-8">
<div className="w-16 h-16 bg-white/20 rounded-2xl flex items-center justify-center mb-6">
<Building2 className="w-8 h-8" />
</div>
<h2 className="text-2xl font-black mb-4 italic">پنل کلینیکها <br/> و داروخانهها</h2>
<p className="text-white/60 text-sm leading-relaxed">
این بخش اختصاصی برای ثبت سفارشات حجیم و استعلام موجودی آنی طراحی شده است. قیمتهای نمایش داده شده، فی واحد کاتالوگ هستند.
<p className="text-white/60 text-sm leading-relaxed mb-4">
ثبت سفارشات حجیم با قیمت همکار. کالاها مستقیماً با لایسنس آلمان ارسال میشوند.
</p>
{!isWholesaleVerified && (
<div className="bg-white/10 p-4 rounded-2xl border border-white/20 mt-4">
<h4 className="text-xs font-black mb-2 text-amber-300">درخواست تایید حساب همکار</h4>
<p className="text-[11px] text-white/80 mb-3">جهت مشاهده و خرید با قیمت عمده، شماره پروانه نظام دامپزشکی خود را وارد کنید.</p>
<form onSubmit={async (e) => {
e.preventDefault();
const form = e.target as HTMLFormElement;
const bName = (form.elements.namedItem('bName') as HTMLInputElement).value;
const lNum = (form.elements.namedItem('lNum') as HTMLInputElement).value;
try {
const api = (await import('../lib/services/api')).default;
await api.post('/wholesale/apply', { businessName: bName, licenseNumber: lNum });
alert('درخواست ثبت‌نام همکار با موفقیت ارسال شد و به زودی توسط ادمین تایید می‌شود.');
form.reset();
} catch (err) {
alert('لطفاً ابتدا وارد حساب کاربری خود شوید.');
}
}} className="space-y-2">
<input name="bName" required placeholder="نام کلینیک / داروخانه" className="w-full bg-white/20 text-white text-xs px-3 py-2 rounded-xl outline-none placeholder:text-white/50" />
<input name="lNum" required placeholder="شماره پروانه / نظام" className="w-full bg-white/20 text-white text-xs px-3 py-2 rounded-xl outline-none placeholder:text-white/50" />
<button type="submit" className="w-full bg-amber-400 hover:bg-amber-500 text-gray-900 font-black text-xs py-2 rounded-xl transition-colors">
ثبت درخواست همکار
</button>
</form>
</div>
)}
</div>
<div className="mt-auto space-y-4">
<div className="mt-auto space-y-4 pt-6">
<button
onClick={exportToCSV}
className="w-full p-4 bg-white/10 hover:bg-white/20 rounded-2xl flex items-center gap-3 transition-colors text-right"
className="w-full p-4 bg-white/10 hover:bg-white/20 rounded-2xl flex items-center gap-3 transition-colors text-right cursor-pointer"
>
<Download className="w-5 h-5 text-blue-300" />
<div>
@ -138,10 +165,6 @@ export default function B2BPortal({ onClose }: { onClose: () => void }) {
<span className="text-[10px] text-white/60 block">خروجی CSV آماده چاپ</span>
</div>
</button>
<div className="p-4 bg-white/10 rounded-2xl flex items-center gap-3">
<Package className="w-5 h-5 text-blue-300" />
<span className="text-xs font-bold">پیگیری محمولات قبلی</span>
</div>
</div>
</div>