Skip to content

Commit 153467d

Browse files
Copilothotlong
andcommitted
Add Contact and Opportunity detail view pages to CRM Storybook
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent e4e2679 commit 153467d

1 file changed

Lines changed: 293 additions & 1 deletion

File tree

packages/components/src/stories/CRMApp.stories.tsx

Lines changed: 293 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,26 @@ const ACCOUNTS_DATA = {
6363
]
6464
};
6565

66+
const CONTACT_DETAIL_DATA = {
67+
id: 1,
68+
name: "Alice Johnson",
69+
company: "TechCorp",
70+
email: "alice@techcorp.com",
71+
status: "Active"
72+
};
73+
74+
const OPPORTUNITY_DETAIL_DATA = {
75+
id: 101,
76+
name: "TechCorp License Renewal",
77+
amount: 50000,
78+
stage: "Proposal",
79+
probability: "60%",
80+
closeDate: "2026-02-28",
81+
contact: "Alice Johnson",
82+
expectedRevenue: 30000,
83+
daysToClose: 28
84+
};
85+
6686
/* --- SCHEMAS --- */
6787

6888
const dashboardSchema = {
@@ -156,9 +176,19 @@ const contactsSchema = {
156176
{ type: "button", props: { children: "New Contact" } }
157177
]
158178
},
179+
{
180+
type: "div",
181+
className: "flex gap-2 mt-4",
182+
children: [
183+
{ type: "button", props: { variant: "outline", size: "sm", children: "All Contacts" } },
184+
{ type: "button", props: { variant: "ghost", size: "sm", children: "Active" } },
185+
{ type: "button", props: { variant: "ghost", size: "sm", children: "Inactive" } },
186+
{ type: "button", props: { variant: "ghost", size: "sm", children: "Leads" } }
187+
]
188+
},
159189
{
160190
type: "page:card",
161-
className: "mt-6",
191+
className: "mt-4",
162192
children: [
163193
{
164194
type: "view:grid",
@@ -306,6 +336,241 @@ const accountsSchema = {
306336
]
307337
};
308338

339+
const contactDetailSchema = {
340+
type: "page",
341+
props: { title: "Contact Details" },
342+
children: [
343+
{
344+
type: "div",
345+
className: "flex items-center justify-between mb-6",
346+
children: [
347+
{
348+
type: "page:header",
349+
props: {
350+
title: "${data.name}",
351+
description: "${data.company} • ${data.email}"
352+
},
353+
className: "mb-0"
354+
},
355+
{
356+
type: "div",
357+
className: "flex gap-2",
358+
children: [
359+
{ type: "button", props: { variant: "outline", size: "sm", children: "Edit" } },
360+
{ type: "button", props: { variant: "outline", size: "sm", children: "Delete" } }
361+
]
362+
}
363+
]
364+
},
365+
{
366+
type: "grid",
367+
props: { cols: 3, gap: 6 },
368+
children: [
369+
{
370+
type: "page:card",
371+
props: { title: "Contact Information", className: "col-span-2" },
372+
children: [
373+
{
374+
type: "div",
375+
className: "grid grid-cols-2 gap-4",
376+
children: [
377+
{ type: "div", children: [
378+
{ type: "text", content: "Name", className: "text-sm font-medium text-muted-foreground block mb-1" },
379+
{ type: "text", content: "${data.name}", className: "text-base" }
380+
]},
381+
{ type: "div", children: [
382+
{ type: "text", content: "Email", className: "text-sm font-medium text-muted-foreground block mb-1" },
383+
{ type: "text", content: "${data.email}", className: "text-base" }
384+
]},
385+
{ type: "div", children: [
386+
{ type: "text", content: "Company", className: "text-sm font-medium text-muted-foreground block mb-1" },
387+
{ type: "text", content: "${data.company}", className: "text-base" }
388+
]},
389+
{ type: "div", children: [
390+
{ type: "text", content: "Status", className: "text-sm font-medium text-muted-foreground block mb-1" },
391+
{ type: "badge", props: { variant: "default" }, children: [{ type: "text", content: "${data.status}" }] }
392+
]}
393+
]
394+
}
395+
]
396+
},
397+
{
398+
type: "page:card",
399+
props: { title: "Quick Actions", className: "col-span-1" },
400+
children: [
401+
{
402+
type: "div",
403+
className: "flex flex-col gap-2",
404+
children: [
405+
{ type: "button", props: { variant: "outline", className: "justify-start", children: "Send Email" } },
406+
{ type: "button", props: { variant: "outline", className: "justify-start", children: "Schedule Call" } },
407+
{ type: "button", props: { variant: "outline", className: "justify-start", children: "Create Task" } }
408+
]
409+
}
410+
]
411+
}
412+
]
413+
},
414+
{
415+
type: "page:card",
416+
props: { title: "Recent Activities", className: "mt-6" },
417+
children: [
418+
{
419+
type: "div",
420+
className: "space-y-3",
421+
children: [
422+
{ type: "div", className: "flex items-start gap-3 py-2", children: [
423+
{ type: "div", className: "h-2 w-2 rounded-full bg-blue-500 mt-2" },
424+
{ type: "div", children: [
425+
{ type: "text", content: "Email sent", className: "font-medium block" },
426+
{ type: "text", content: "Sent product demo information", className: "text-sm text-muted-foreground block" },
427+
{ type: "text", content: "2 hours ago", className: "text-xs text-muted-foreground block mt-1" }
428+
]}
429+
]},
430+
{ type: "div", className: "flex items-start gap-3 py-2", children: [
431+
{ type: "div", className: "h-2 w-2 rounded-full bg-green-500 mt-2" },
432+
{ type: "div", children: [
433+
{ type: "text", content: "Meeting completed", className: "font-medium block" },
434+
{ type: "text", content: "Discussed Q1 requirements", className: "text-sm text-muted-foreground block" },
435+
{ type: "text", content: "1 day ago", className: "text-xs text-muted-foreground block mt-1" }
436+
]}
437+
]},
438+
{ type: "div", className: "flex items-start gap-3 py-2", children: [
439+
{ type: "div", className: "h-2 w-2 rounded-full bg-gray-400 mt-2" },
440+
{ type: "div", children: [
441+
{ type: "text", content: "Contact created", className: "font-medium block" },
442+
{ type: "text", content: "Added to CRM system", className: "text-sm text-muted-foreground block" },
443+
{ type: "text", content: "3 days ago", className: "text-xs text-muted-foreground block mt-1" }
444+
]}
445+
]}
446+
]
447+
}
448+
]
449+
}
450+
]
451+
};
452+
453+
const opportunityDetailSchema = {
454+
type: "page",
455+
props: { title: "Opportunity Details" },
456+
children: [
457+
{
458+
type: "div",
459+
className: "flex items-center justify-between mb-6",
460+
children: [
461+
{
462+
type: "page:header",
463+
props: {
464+
title: "${data.name}",
465+
description: "Stage: ${data.stage} • Close Date: ${data.closeDate}"
466+
},
467+
className: "mb-0"
468+
},
469+
{
470+
type: "div",
471+
className: "flex gap-2",
472+
children: [
473+
{ type: "button", props: { variant: "outline", size: "sm", children: "Edit" } },
474+
{ type: "button", props: { size: "sm", children: "Mark as Won" } }
475+
]
476+
}
477+
]
478+
},
479+
{
480+
type: "grid",
481+
props: { cols: 4, gap: 4, className: "mb-6" },
482+
children: [
483+
{
484+
type: "card",
485+
props: { title: "Deal Amount" },
486+
children: [{ type: "text", content: "$${data.amount}", className: "text-2xl font-bold" }]
487+
},
488+
{
489+
type: "card",
490+
props: { title: "Probability" },
491+
children: [{ type: "text", content: "${data.probability}", className: "text-2xl font-bold" }]
492+
},
493+
{
494+
type: "card",
495+
props: { title: "Expected Revenue" },
496+
children: [{ type: "text", content: "$${data.expectedRevenue}", className: "text-2xl font-bold" }]
497+
},
498+
{
499+
type: "card",
500+
props: { title: "Days to Close" },
501+
children: [{ type: "text", content: "${data.daysToClose}", className: "text-2xl font-bold" }]
502+
}
503+
]
504+
},
505+
{
506+
type: "grid",
507+
props: { cols: 3, gap: 6 },
508+
children: [
509+
{
510+
type: "page:card",
511+
props: { title: "Opportunity Details", className: "col-span-2" },
512+
children: [
513+
{
514+
type: "div",
515+
className: "grid grid-cols-2 gap-4",
516+
children: [
517+
{ type: "div", children: [
518+
{ type: "text", content: "Deal Name", className: "text-sm font-medium text-muted-foreground block mb-1" },
519+
{ type: "text", content: "${data.name}", className: "text-base" }
520+
]},
521+
{ type: "div", children: [
522+
{ type: "text", content: "Contact", className: "text-sm font-medium text-muted-foreground block mb-1" },
523+
{ type: "text", content: "${data.contact}", className: "text-base" }
524+
]},
525+
{ type: "div", children: [
526+
{ type: "text", content: "Stage", className: "text-sm font-medium text-muted-foreground block mb-1" },
527+
{ type: "badge", props: { variant: "default" }, children: [{ type: "text", content: "${data.stage}" }] }
528+
]},
529+
{ type: "div", children: [
530+
{ type: "text", content: "Close Date", className: "text-sm font-medium text-muted-foreground block mb-1" },
531+
{ type: "text", content: "${data.closeDate}", className: "text-base" }
532+
]}
533+
]
534+
}
535+
]
536+
},
537+
{
538+
type: "page:card",
539+
props: { title: "Stage Progress", className: "col-span-1" },
540+
children: [
541+
{
542+
type: "div",
543+
className: "space-y-2",
544+
children: [
545+
{ type: "div", className: "flex items-center justify-between", children: [
546+
{ type: "text", content: "Prospecting", className: "text-sm" },
547+
{ type: "text", content: "✓", className: "text-green-500" }
548+
]},
549+
{ type: "div", className: "flex items-center justify-between", children: [
550+
{ type: "text", content: "Qualified", className: "text-sm" },
551+
{ type: "text", content: "✓", className: "text-green-500" }
552+
]},
553+
{ type: "div", className: "flex items-center justify-between", children: [
554+
{ type: "text", content: "Proposal", className: "text-sm font-medium" },
555+
{ type: "text", content: "●", className: "text-blue-500" }
556+
]},
557+
{ type: "div", className: "flex items-center justify-between", children: [
558+
{ type: "text", content: "Negotiation", className: "text-sm text-muted-foreground" },
559+
{ type: "text", content: "○", className: "text-gray-300" }
560+
]},
561+
{ type: "div", className: "flex items-center justify-between", children: [
562+
{ type: "text", content: "Closed", className: "text-sm text-muted-foreground" },
563+
{ type: "text", content: "○", className: "text-gray-300" }
564+
]}
565+
]
566+
}
567+
]
568+
}
569+
]
570+
}
571+
]
572+
};
573+
309574
/* --- APP COMPONENT --- */
310575

311576
const CRMStoryApp = () => {
@@ -317,10 +582,14 @@ const CRMStoryApp = () => {
317582
return <SchemaRendererProvider dataSource={DASHBOARD_DATA}><SchemaRenderer schema={dashboardSchema} /></SchemaRendererProvider>;
318583
case "contacts":
319584
return <SchemaRendererProvider dataSource={CONTACTS_DATA}><SchemaRenderer schema={contactsSchema} /></SchemaRendererProvider>;
585+
case "contact-detail":
586+
return <SchemaRendererProvider dataSource={CONTACT_DETAIL_DATA}><SchemaRenderer schema={contactDetailSchema} /></SchemaRendererProvider>;
320587
case "accounts":
321588
return <SchemaRendererProvider dataSource={ACCOUNTS_DATA}><SchemaRenderer schema={accountsSchema} /></SchemaRendererProvider>;
322589
case "opportunities":
323590
return <SchemaRendererProvider dataSource={OPPORTUNITIES_DATA}><SchemaRenderer schema={opportunitiesSchema} /></SchemaRendererProvider>;
591+
case "opportunity-detail":
592+
return <SchemaRendererProvider dataSource={OPPORTUNITY_DETAIL_DATA}><SchemaRenderer schema={opportunityDetailSchema} /></SchemaRendererProvider>;
324593
case "settings":
325594
return <SchemaRendererProvider dataSource={SETTINGS_DATA}><SchemaRenderer schema={settingsSchema} /></SchemaRendererProvider>;
326595
default:
@@ -395,6 +664,29 @@ const CRMStoryApp = () => {
395664
</SidebarMenu>
396665
</SidebarGroupContent>
397666
</SidebarGroup>
667+
<SidebarGroup>
668+
<SidebarGroupLabel>Examples</SidebarGroupLabel>
669+
<SidebarGroupContent>
670+
<SidebarMenu>
671+
<SidebarMenuButton
672+
isActive={activePage === "contact-detail"}
673+
onClick={() => setActivePage("contact-detail")}
674+
tooltip="Contact Detail View"
675+
>
676+
<UserPlus />
677+
<span>Contact Detail</span>
678+
</SidebarMenuButton>
679+
<SidebarMenuButton
680+
isActive={activePage === "opportunity-detail"}
681+
onClick={() => setActivePage("opportunity-detail")}
682+
tooltip="Opportunity Detail View"
683+
>
684+
<FileText />
685+
<span>Deal Detail</span>
686+
</SidebarMenuButton>
687+
</SidebarMenu>
688+
</SidebarGroupContent>
689+
</SidebarGroup>
398690
</SidebarContent>
399691
</Sidebar>
400692

0 commit comments

Comments
 (0)