pxengine 0.1.12 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/dist/index.cjs +227 -291
  2. package/dist/index.d.cts +15 -11
  3. package/dist/index.d.ts +15 -11
  4. package/dist/index.js +225 -287
  5. package/dist/registry.json +20 -22
  6. package/package.json +2 -4
  7. package/config/tailwind-preset.js +0 -106
  8. package/src/atoms/AccordionAtom.tsx +0 -44
  9. package/src/atoms/AlertAtom.tsx +0 -48
  10. package/src/atoms/AlertDialogAtom.tsx +0 -66
  11. package/src/atoms/AspectRatioAtom.tsx +0 -27
  12. package/src/atoms/AvatarAtom.tsx +0 -21
  13. package/src/atoms/BadgeAtom.tsx +0 -35
  14. package/src/atoms/BreadcrumbAtom.tsx +0 -36
  15. package/src/atoms/ButtonAtom.tsx +0 -65
  16. package/src/atoms/CalendarAtom.tsx +0 -24
  17. package/src/atoms/CardAtom.tsx +0 -66
  18. package/src/atoms/CarouselAtom.tsx +0 -40
  19. package/src/atoms/ChartAtom.tsx +0 -192
  20. package/src/atoms/CheckboxAtom.tsx +0 -33
  21. package/src/atoms/CollapsibleAtom.tsx +0 -44
  22. package/src/atoms/CommandAtom.tsx +0 -46
  23. package/src/atoms/ContextMenuAtom.tsx +0 -49
  24. package/src/atoms/DialogAtom.tsx +0 -68
  25. package/src/atoms/DrawerAtom.tsx +0 -49
  26. package/src/atoms/DropdownMenuAtom.tsx +0 -49
  27. package/src/atoms/FormInputAtom.tsx +0 -101
  28. package/src/atoms/FormSelectAtom.tsx +0 -110
  29. package/src/atoms/FormTextareaAtom.tsx +0 -93
  30. package/src/atoms/InputAtom.tsx +0 -216
  31. package/src/atoms/InputOTPAtom.tsx +0 -49
  32. package/src/atoms/KbdAtom.tsx +0 -25
  33. package/src/atoms/LabelAtom.tsx +0 -23
  34. package/src/atoms/LayoutAtom.tsx +0 -45
  35. package/src/atoms/PaginationAtom.tsx +0 -49
  36. package/src/atoms/PopoverAtom.tsx +0 -40
  37. package/src/atoms/ProgressAtom.tsx +0 -15
  38. package/src/atoms/RadioGroupAtom.tsx +0 -31
  39. package/src/atoms/RatingAtom.tsx +0 -37
  40. package/src/atoms/ResizableAtom.tsx +0 -51
  41. package/src/atoms/ScrollAreaAtom.tsx +0 -31
  42. package/src/atoms/SeparatorAtom.tsx +0 -16
  43. package/src/atoms/SheetAtom.tsx +0 -72
  44. package/src/atoms/SkeletonAtom.tsx +0 -22
  45. package/src/atoms/SliderAtom.tsx +0 -32
  46. package/src/atoms/SpinnerAtom.tsx +0 -26
  47. package/src/atoms/SwitchAtom.tsx +0 -32
  48. package/src/atoms/TableAtom.tsx +0 -60
  49. package/src/atoms/TabsAtom.tsx +0 -40
  50. package/src/atoms/TextAtom.tsx +0 -36
  51. package/src/atoms/TextareaAtom.tsx +0 -42
  52. package/src/atoms/TimelineAtom.tsx +0 -77
  53. package/src/atoms/ToggleAtom.tsx +0 -36
  54. package/src/atoms/TooltipAtom.tsx +0 -39
  55. package/src/atoms/VideoAtom.tsx +0 -34
  56. package/src/atoms/index.ts +0 -49
  57. package/src/components/index.ts +0 -178
  58. package/src/components/ui/accordion.tsx +0 -56
  59. package/src/components/ui/alert-dialog.tsx +0 -139
  60. package/src/components/ui/alert.tsx +0 -59
  61. package/src/components/ui/aspect-ratio.tsx +0 -5
  62. package/src/components/ui/avatar.tsx +0 -50
  63. package/src/components/ui/badge.tsx +0 -36
  64. package/src/components/ui/breadcrumb.tsx +0 -115
  65. package/src/components/ui/button-group.tsx +0 -83
  66. package/src/components/ui/button.tsx +0 -56
  67. package/src/components/ui/calendar.tsx +0 -213
  68. package/src/components/ui/card.tsx +0 -79
  69. package/src/components/ui/carousel.tsx +0 -260
  70. package/src/components/ui/chart.tsx +0 -367
  71. package/src/components/ui/checkbox.tsx +0 -28
  72. package/src/components/ui/collapsible.tsx +0 -11
  73. package/src/components/ui/command.tsx +0 -153
  74. package/src/components/ui/context-menu.tsx +0 -198
  75. package/src/components/ui/dialog.tsx +0 -122
  76. package/src/components/ui/drawer.tsx +0 -116
  77. package/src/components/ui/dropdown-menu.tsx +0 -200
  78. package/src/components/ui/empty.tsx +0 -104
  79. package/src/components/ui/field.tsx +0 -244
  80. package/src/components/ui/form.tsx +0 -176
  81. package/src/components/ui/hover-card.tsx +0 -27
  82. package/src/components/ui/index.ts +0 -54
  83. package/src/components/ui/input-group.tsx +0 -168
  84. package/src/components/ui/input-otp.tsx +0 -69
  85. package/src/components/ui/input.tsx +0 -22
  86. package/src/components/ui/item.tsx +0 -193
  87. package/src/components/ui/kbd.tsx +0 -28
  88. package/src/components/ui/label.tsx +0 -26
  89. package/src/components/ui/menubar.tsx +0 -254
  90. package/src/components/ui/navigation-menu.tsx +0 -128
  91. package/src/components/ui/pagination.tsx +0 -117
  92. package/src/components/ui/popover.tsx +0 -29
  93. package/src/components/ui/progress.tsx +0 -28
  94. package/src/components/ui/radio-group.tsx +0 -42
  95. package/src/components/ui/resizable.tsx +0 -44
  96. package/src/components/ui/scroll-area.tsx +0 -46
  97. package/src/components/ui/select.tsx +0 -160
  98. package/src/components/ui/separator.tsx +0 -29
  99. package/src/components/ui/sheet.tsx +0 -140
  100. package/src/components/ui/sidebar.tsx +0 -771
  101. package/src/components/ui/skeleton.tsx +0 -15
  102. package/src/components/ui/slider.tsx +0 -26
  103. package/src/components/ui/sonner.tsx +0 -45
  104. package/src/components/ui/spinner.tsx +0 -16
  105. package/src/components/ui/switch.tsx +0 -27
  106. package/src/components/ui/table.tsx +0 -117
  107. package/src/components/ui/tabs.tsx +0 -53
  108. package/src/components/ui/textarea.tsx +0 -22
  109. package/src/components/ui/toggle-group.tsx +0 -61
  110. package/src/components/ui/toggle.tsx +0 -43
  111. package/src/components/ui/tooltip.tsx +0 -30
  112. package/src/hooks/use-mobile.tsx +0 -19
  113. package/src/index.ts +0 -24
  114. package/src/lib/countries.ts +0 -203
  115. package/src/lib/index.ts +0 -2
  116. package/src/lib/utils.ts +0 -15
  117. package/src/lib/validators/index.ts +0 -1
  118. package/src/lib/validators/theme.ts +0 -148
  119. package/src/molecules/creator-discovery/AudienceDemographicsCard/AudienceDemographicsCard.tsx +0 -44
  120. package/src/molecules/creator-discovery/AudienceDemographicsCard/index.ts +0 -1
  121. package/src/molecules/creator-discovery/AudienceMetricCard/AudienceMetricCard.tsx +0 -50
  122. package/src/molecules/creator-discovery/AudienceMetricCard/index.ts +0 -1
  123. package/src/molecules/creator-discovery/BrandAffinityGroup/BrandAffinityGroup.tsx +0 -36
  124. package/src/molecules/creator-discovery/BrandAffinityGroup/index.ts +0 -1
  125. package/src/molecules/creator-discovery/CampaignSeedCard/CampaignSeedCard.tsx +0 -123
  126. package/src/molecules/creator-discovery/CampaignSeedCard/CampaignSeedCard.types.ts +0 -13
  127. package/src/molecules/creator-discovery/CampaignSeedCard/index.ts +0 -2
  128. package/src/molecules/creator-discovery/ContentPreviewGallery/ContentPreviewGallery.tsx +0 -41
  129. package/src/molecules/creator-discovery/ContentPreviewGallery/index.ts +0 -1
  130. package/src/molecules/creator-discovery/CreatorActionHeader/CreatorActionHeader.tsx +0 -77
  131. package/src/molecules/creator-discovery/CreatorActionHeader/index.ts +0 -1
  132. package/src/molecules/creator-discovery/CreatorGridCard/CreatorGridCard.tsx +0 -104
  133. package/src/molecules/creator-discovery/CreatorGridCard/index.ts +0 -1
  134. package/src/molecules/creator-discovery/CreatorProfileSummary/CreatorProfileSummary.tsx +0 -65
  135. package/src/molecules/creator-discovery/CreatorProfileSummary/index.ts +0 -1
  136. package/src/molecules/creator-discovery/GrowthChartCard/GrowthChartCard.tsx +0 -58
  137. package/src/molecules/creator-discovery/GrowthChartCard/index.ts +0 -1
  138. package/src/molecules/creator-discovery/MCQCard/MCQCard.tsx +0 -165
  139. package/src/molecules/creator-discovery/MCQCard/MCQCard.types.ts +0 -71
  140. package/src/molecules/creator-discovery/MCQCard/index.ts +0 -2
  141. package/src/molecules/creator-discovery/PlatformIconGroup/PlatformIconGroup.tsx +0 -72
  142. package/src/molecules/creator-discovery/PlatformIconGroup/index.ts +0 -1
  143. package/src/molecules/creator-discovery/SearchSpecCard/CustomFieldRenderers.tsx +0 -334
  144. package/src/molecules/creator-discovery/SearchSpecCard/SearchSpecCard.tsx +0 -111
  145. package/src/molecules/creator-discovery/SearchSpecCard/SearchSpecCard.types.ts +0 -18
  146. package/src/molecules/creator-discovery/SearchSpecCard/index.ts +0 -3
  147. package/src/molecules/creator-discovery/TopPostsGrid/TopPostsGrid.tsx +0 -49
  148. package/src/molecules/creator-discovery/TopPostsGrid/index.ts +0 -1
  149. package/src/molecules/creator-discovery/index.ts +0 -13
  150. package/src/molecules/generic/ActionButton/ActionButton.tsx +0 -137
  151. package/src/molecules/generic/ActionButton/ActionButton.types.ts +0 -68
  152. package/src/molecules/generic/ActionButton/index.ts +0 -2
  153. package/src/molecules/generic/DataGrid/DataGrid.tsx +0 -102
  154. package/src/molecules/generic/DataGrid/index.ts +0 -1
  155. package/src/molecules/generic/EditableField/EditableField.tsx +0 -229
  156. package/src/molecules/generic/EditableField/EditableField.types.ts +0 -73
  157. package/src/molecules/generic/EditableField/index.ts +0 -2
  158. package/src/molecules/generic/EmptyState/EmptyState.tsx +0 -61
  159. package/src/molecules/generic/EmptyState/index.ts +0 -1
  160. package/src/molecules/generic/FileUpload/FileUpload.tsx +0 -62
  161. package/src/molecules/generic/FileUpload/index.ts +0 -1
  162. package/src/molecules/generic/FilterBar/FilterBar.tsx +0 -54
  163. package/src/molecules/generic/FilterBar/index.ts +0 -1
  164. package/src/molecules/generic/FormCard/FormCard.tsx +0 -136
  165. package/src/molecules/generic/FormCard/FormCard.types.ts +0 -93
  166. package/src/molecules/generic/FormCard/index.ts +0 -2
  167. package/src/molecules/generic/LoadingOverlay/LoadingOverlay.tsx +0 -39
  168. package/src/molecules/generic/LoadingOverlay/index.ts +0 -1
  169. package/src/molecules/generic/NotificationList/NotificationList.tsx +0 -80
  170. package/src/molecules/generic/NotificationList/index.ts +0 -1
  171. package/src/molecules/generic/StatsGrid/StatsGrid.tsx +0 -80
  172. package/src/molecules/generic/StatsGrid/index.ts +0 -1
  173. package/src/molecules/generic/StepWizard/StepWizard.tsx +0 -67
  174. package/src/molecules/generic/StepWizard/index.ts +0 -1
  175. package/src/molecules/generic/TagCloud/TagCloud.tsx +0 -32
  176. package/src/molecules/generic/TagCloud/index.ts +0 -1
  177. package/src/molecules/generic/index.ts +0 -12
  178. package/src/molecules/index.ts +0 -2
  179. package/src/render/PXEngineRenderer.tsx +0 -458
  180. package/src/render/index.ts +0 -1
  181. package/src/styles/globals.css +0 -146
  182. package/src/types/atoms.ts +0 -450
  183. package/src/types/common.ts +0 -116
  184. package/src/types/index.ts +0 -3
  185. package/src/types/molecules.ts +0 -279
  186. package/src/types/schema.ts +0 -12
@@ -1,41 +0,0 @@
1
- import React from "react";
2
- import { ContentPreviewGalleryMolecule } from "../../../types/molecules";
3
- import { cn } from "@/lib/utils";
4
- import { Play } from "lucide-react";
5
-
6
- /**
7
- * ContentPreviewGallery
8
- * Grid/Gallery of thumbnail previews.
9
- */
10
- export const ContentPreviewGallery: React.FC<ContentPreviewGalleryMolecule> = ({
11
- items,
12
- className,
13
- }) => {
14
- return (
15
- <div className={cn("grid grid-cols-2 gap-2", className)}>
16
- {items.map((item, i) => (
17
- <a
18
- key={i}
19
- href={item.url || "#"}
20
- target="_blank"
21
- rel="noopener noreferrer"
22
- className="group relative aspect-square overflow-hidden rounded-2xl bg-gray-100"
23
- >
24
- <img
25
- src={item.thumbnail}
26
- alt="Content preview"
27
- className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-110"
28
- />
29
- {item.type === "video" && (
30
- <div className="absolute inset-0 flex items-center justify-center bg-black/10 group-hover:bg-black/20 transition-colors">
31
- <div className="rounded-full bg-white/30 backdrop-blur-md p-3 text-white ring-1 ring-white/50">
32
- <Play className="h-6 w-6 fill-white" />
33
- </div>
34
- </div>
35
- )}
36
- <div className="absolute inset-0 ring-1 ring-inset ring-black/10 rounded-2xl" />
37
- </a>
38
- ))}
39
- </div>
40
- );
41
- };
@@ -1 +0,0 @@
1
- export * from "./ContentPreviewGallery";
@@ -1,77 +0,0 @@
1
- import React from "react";
2
- import { Button } from "@/components/ui/button";
3
- import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
4
- import { CreatorActionHeaderMolecule } from "../../../types/molecules";
5
- import { cn } from "@/lib/utils";
6
-
7
- /**
8
- * CreatorActionHeader
9
- * A premium header for profile views with banner and sticky actions.
10
- */
11
- export const CreatorActionHeader: React.FC<CreatorActionHeaderMolecule> = ({
12
- bannerSrc,
13
- avatarSrc,
14
- name,
15
- handle,
16
- actions,
17
- className,
18
- }) => {
19
- return (
20
- <div
21
- className={cn(
22
- "relative w-full rounded-[40px] overflow-hidden bg-white border border-purple-50 shadow-sm",
23
- className,
24
- )}
25
- >
26
- {/* Banner */}
27
- <div className="h-48 w-full bg-gradient-to-r from-purple-100 to-indigo-100 relative">
28
- {bannerSrc && (
29
- <img
30
- src={bannerSrc}
31
- className="h-full w-full object-cover"
32
- alt="Banner"
33
- />
34
- )}
35
- <div className="absolute inset-0 bg-black/5" />
36
- </div>
37
-
38
- {/* Profile Info & Actions */}
39
- <div className="px-8 pb-8 flex flex-col md:flex-row md:items-end justify-between gap-6 -mt-12 relative z-10">
40
- <div className="flex flex-col md:flex-row items-start md:items-end gap-6">
41
- <div className="p-2 bg-white rounded-[32px] shadow-lg">
42
- <Avatar className="h-32 w-32 rounded-[24px] border-4 border-white">
43
- <AvatarImage src={avatarSrc} className="rounded-[24px]" />
44
- <AvatarFallback className="rounded-[24px] bg-purple-50 text-purple-600 text-3xl font-bold">
45
- {name.charAt(0)}
46
- </AvatarFallback>
47
- </Avatar>
48
- </div>
49
- <div className="mb-2">
50
- <h1 className="text-3xl font-bold text-gray-900 tracking-tight">
51
- {name}
52
- </h1>
53
- <p className="text-purple-600 font-medium tracking-wide">
54
- @{handle}
55
- </p>
56
- </div>
57
- </div>
58
-
59
- <div className="flex items-center gap-3 mb-2">
60
- {actions.map((action, i) => (
61
- <Button
62
- key={i}
63
- variant={(action.variant as any) || "default"}
64
- className={cn(
65
- "rounded-2xl px-6 h-11 font-bold transition-all",
66
- action.variant === "default" &&
67
- "bg-purple-600 hover:bg-purple-700 shadow-md hover:shadow-purple-200",
68
- )}
69
- >
70
- {action.label}
71
- </Button>
72
- ))}
73
- </div>
74
- </div>
75
- </div>
76
- );
77
- };
@@ -1 +0,0 @@
1
- export * from "./CreatorActionHeader";
@@ -1,104 +0,0 @@
1
- import React from "react";
2
- import { Card, CardContent } from "@/components/ui/card";
3
- import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
4
- import { CreatorGridCardMolecule } from "../../../types/molecules";
5
- import { cn } from "@/lib/utils";
6
- import { Instagram, Youtube, Video, Twitter } from "lucide-react";
7
-
8
- const TikTokIcon = ({ className }: { className?: string }) => (
9
- <Video className={className} /> // Placeholder
10
- );
11
-
12
- /**
13
- * CreatorGridCard
14
- * A visually rich card for discovery grids.
15
- */
16
- export const CreatorGridCard: React.FC<CreatorGridCardMolecule> = ({
17
- bannerSrc,
18
- avatarSrc,
19
- name,
20
- handle,
21
- metrics,
22
- platforms,
23
- className,
24
- }) => {
25
- const getIcon = (p: string) => {
26
- switch (p.toLowerCase()) {
27
- case "instagram":
28
- return Instagram;
29
- case "tiktok":
30
- return TikTokIcon;
31
- case "youtube":
32
- return Youtube;
33
- case "twitter":
34
- return Twitter;
35
- default:
36
- return null;
37
- }
38
- };
39
-
40
- return (
41
- <Card
42
- className={cn(
43
- "group overflow-hidden rounded-[32px] border-none bg-white shadow-sm hover:shadow-xl transition-all duration-300",
44
- className,
45
- )}
46
- >
47
- <div className="relative h-32 w-full overflow-hidden">
48
- {bannerSrc ? (
49
- <img
50
- src={bannerSrc}
51
- alt={name}
52
- className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-110"
53
- />
54
- ) : (
55
- <div className="h-full w-full bg-gradient-to-br from-purple-500 to-indigo-600" />
56
- )}
57
- <div className="absolute inset-x-0 bottom-0 h-1/2 bg-gradient-to-t from-black/20 to-transparent" />
58
- </div>
59
-
60
- <CardContent className="relative pt-0 px-5 pb-6">
61
- <div className="absolute -top-10 left-5">
62
- <Avatar className="h-20 w-20 border-4 border-white shadow-lg ring-2 ring-purple-100">
63
- <AvatarImage src={avatarSrc} alt={name} />
64
- <AvatarFallback className="bg-purple-50 text-purple-700 font-bold text-xl">
65
- {name.charAt(0)}
66
- </AvatarFallback>
67
- </Avatar>
68
- </div>
69
-
70
- <div className="mt-12 flex flex-col gap-1">
71
- <h3 className="text-xl font-bold text-gray-900 truncate">{name}</h3>
72
- <p className="text-sm text-muted-foreground font-medium">@{handle}</p>
73
- </div>
74
-
75
- <div className="mt-4 flex gap-2">
76
- {platforms.map((p) => {
77
- const Icon = getIcon(p);
78
- return Icon ? (
79
- <div
80
- key={p}
81
- className="p-1.5 rounded-lg bg-gray-50 text-gray-600 hover:text-purple-600 hover:bg-purple-50 transition-colors"
82
- >
83
- <Icon className="h-4 w-4" />
84
- </div>
85
- ) : null;
86
- })}
87
- </div>
88
-
89
- <div className="mt-6 grid grid-cols-2 gap-4 border-t border-gray-50 pt-4">
90
- {metrics.map((m, i) => (
91
- <div key={i} className="flex flex-col">
92
- <span className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground">
93
- {m.label}
94
- </span>
95
- <span className="text-sm font-bold text-purple-700">
96
- {m.value}
97
- </span>
98
- </div>
99
- ))}
100
- </div>
101
- </CardContent>
102
- </Card>
103
- );
104
- };
@@ -1 +0,0 @@
1
- export * from "./CreatorGridCard";
@@ -1,65 +0,0 @@
1
- import React from "react";
2
- import { AvatarAtom } from "../../../atoms/AvatarAtom";
3
- import { TextAtom } from "../../../atoms/TextAtom";
4
- import { CreatorProfileSummaryMolecule } from "../../../types/molecules";
5
- import { cn } from "@/lib/utils";
6
-
7
- /**
8
- * CreatorProfileSummary
9
- * A compact row showing avatar, name, and key metrics.
10
- */
11
- export const CreatorProfileSummary: React.FC<CreatorProfileSummaryMolecule> = ({
12
- avatarSrc,
13
- name,
14
- followerCount,
15
- engagementRate,
16
- className,
17
- }) => {
18
- return (
19
- <div
20
- className={cn(
21
- "flex items-center gap-4 p-3 rounded-2xl bg-white/40 border border-purple-50 shadow-sm",
22
- className,
23
- )}
24
- >
25
- <AvatarAtom
26
- id={`avatar-${name}`}
27
- type="avatar"
28
- src={avatarSrc}
29
- fallback={name.charAt(0)}
30
- className="w-12 h-12 ring-2 ring-purple-100"
31
- />
32
- <div className="flex flex-col flex-1">
33
- <TextAtom
34
- id={`name-${name}`}
35
- type="text"
36
- content={name}
37
- variant="h4"
38
- className="text-gray-900 leading-tight"
39
- />
40
- <div className="flex gap-3 mt-1">
41
- {followerCount && (
42
- <div className="flex flex-col">
43
- <span className="text-[10px] uppercase tracking-wider text-muted-foreground font-bold">
44
- Followers
45
- </span>
46
- <span className="text-xs font-semibold text-purple-700">
47
- {followerCount}
48
- </span>
49
- </div>
50
- )}
51
- {engagementRate && (
52
- <div className="flex flex-col border-l border-purple-100 pl-3">
53
- <span className="text-[10px] uppercase tracking-wider text-muted-foreground font-bold">
54
- Engagement
55
- </span>
56
- <span className="text-xs font-semibold text-indigo-600">
57
- {engagementRate}
58
- </span>
59
- </div>
60
- )}
61
- </div>
62
- </div>
63
- </div>
64
- );
65
- };
@@ -1 +0,0 @@
1
- export * from "./CreatorProfileSummary";
@@ -1,58 +0,0 @@
1
- import React from "react";
2
- import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
3
- import { ChartAtom } from "../../../atoms/ChartAtom";
4
- import { GrowthChartCardMolecule } from "../../../types/molecules";
5
- import { cn } from "@/lib/utils";
6
- import { TrendingUp } from "lucide-react";
7
-
8
- /**
9
- * GrowthChartCard
10
- * Visualizes time-series growth data for follower and engagement metrics.
11
- */
12
- export const GrowthChartCard: React.FC<GrowthChartCardMolecule> = ({
13
- title,
14
- data,
15
- config,
16
- metric,
17
- period,
18
- className,
19
- }) => {
20
- return (
21
- <Card
22
- className={cn(
23
- "rounded-[32px] border-purple-50 shadow-sm overflow-hidden",
24
- className,
25
- )}
26
- >
27
- <CardHeader className="flex flex-row items-center justify-between pb-2 space-y-0">
28
- <div>
29
- <CardTitle className="text-lg font-bold text-gray-900">
30
- {title}
31
- </CardTitle>
32
- <p className="text-xs text-muted-foreground">{period}</p>
33
- </div>
34
- <div className="bg-green-50 p-2 rounded-xl">
35
- <TrendingUp className="w-4 h-4 text-green-600" />
36
- </div>
37
- </CardHeader>
38
- <CardContent>
39
- <div className="h-[200px] w-full mt-4">
40
- <ChartAtom
41
- type="chart"
42
- id="growth-trend"
43
- chartType="area"
44
- data={data}
45
- config={config}
46
- XAxisKey="date"
47
- showTooltip={true}
48
- showLegend={false}
49
- />
50
- </div>
51
- <div className="mt-4 flex items-center justify-between">
52
- <span className="text-sm font-medium text-gray-500">{metric}</span>
53
- <span className="text-sm font-bold text-purple-600">+12.5%</span>
54
- </div>
55
- </CardContent>
56
- </Card>
57
- );
58
- };
@@ -1 +0,0 @@
1
- export * from "./GrowthChartCard";
@@ -1,165 +0,0 @@
1
- import React from "react";
2
- import { MCQCardProps } from "./MCQCard.types";
3
- import {
4
- Card,
5
- CardContent,
6
- CardHeader,
7
- CardTitle,
8
- CardFooter,
9
- Badge,
10
- } from "@/components";
11
- import { ActionButton } from "../../generic/ActionButton";
12
- import { cn } from "@/lib/utils";
13
- import { CheckCircle2, Sparkles } from "lucide-react";
14
-
15
- /**
16
- * MCQCard
17
- *
18
- * A molecule for Multiple Choice Questions.
19
- * Supports:
20
- * - Recommended options with styling
21
- * - Radio-style selection
22
- * - Integrated ActionButton with countdown
23
- * - Peer/Agent approval labels
24
- * - Premium aesthetics
25
- */
26
- export const MCQCard = React.memo<MCQCardProps>(
27
- ({
28
- question,
29
- options,
30
- recommended,
31
- selectedOption,
32
- onSelect,
33
- onProceed,
34
- isLatestMessage = true,
35
- countdown,
36
- isPaused = false,
37
- onPause,
38
- isLoading = false,
39
- className,
40
- selectionStatus,
41
- }) => {
42
- const handleOptionClick = (key: string) => {
43
- if (isLatestMessage && !isLoading) {
44
- onSelect?.(key);
45
- }
46
- };
47
-
48
- const handleProceed = () => {
49
- if (selectedOption || recommended) {
50
- onProceed?.(selectedOption || recommended || "");
51
- }
52
- };
53
-
54
- return (
55
- <Card
56
- className={cn(
57
- "w-full rounded-[24px] border border-gray200 bg-white shadow-sm overflow-hidden",
58
- className,
59
- )}
60
- >
61
- <CardHeader className="pb-2">
62
- <CardTitle className="text-lg font-bold text-gray-900 tracking-tight leading-snug">
63
- {question}
64
- </CardTitle>
65
- </CardHeader>
66
-
67
- <CardContent className="space-y-3 pb-6">
68
- {Object.entries(options).map(([key, label]) => {
69
- const isSelected = selectedOption === key;
70
- const isRecommended = key === recommended;
71
-
72
- return (
73
- <div
74
- key={key}
75
- onClick={() => handleOptionClick(key)}
76
- className={cn(
77
- "group relative flex items-start gap-4 p-4 rounded-2xl border transition-all duration-200 cursor-pointer",
78
- isSelected
79
- ? "border-purple500 bg-purple50/30"
80
- : "border-gray-100 bg-gray-50/30 hover:border-gray-300 hover:bg-gray-50",
81
- isLoading && "opacity-50 cursor-not-allowed",
82
- )}
83
- >
84
- {/* Radio Circle */}
85
- <div
86
- className={cn(
87
- "mt-1 w-5 h-5 rounded-full border-2 flex items-center justify-center transition-colors",
88
- isSelected
89
- ? "border-purple500 bg-purple500"
90
- : "border-gray-300 bg-white group-hover:border-gray-400",
91
- )}
92
- >
93
- {isSelected && (
94
- <div className="w-1.5 h-1.5 rounded-full bg-white" />
95
- )}
96
- </div>
97
-
98
- <div className="flex-1 space-y-1.5">
99
- <div className="flex items-center gap-2 flex-wrap">
100
- <span
101
- className={cn(
102
- "text-sm font-semibold transition-colors",
103
- isSelected ? "text-purple900" : "text-gray700",
104
- )}
105
- >
106
- {label}
107
- </span>
108
-
109
- {isRecommended && (
110
- <Badge
111
- variant="outline"
112
- className="bg-green-50 text-green-700 border-green-100 flex items-center gap-1 text-[10px] py-0 h-5"
113
- >
114
- <Sparkles className="h-3 w-3" />
115
- Recommended
116
- </Badge>
117
- )}
118
-
119
- {isSelected && !isLatestMessage && (
120
- <Badge
121
- variant="outline"
122
- className="bg-purple-50 text-purple-700 border-purple-100 text-[10px] py-0 h-5"
123
- >
124
- Selected
125
- </Badge>
126
- )}
127
- </div>
128
- </div>
129
- </div>
130
- );
131
- })}
132
- </CardContent>
133
-
134
- <CardFooter className="flex flex-col gap-4 pt-0 border-t border-gray-100/50 bg-gray-50/30 p-6">
135
- {isLatestMessage ? (
136
- <div className="w-full flex justify-center">
137
- <ActionButton
138
- label={
139
- selectedOption ? "Continue" : "Proceed with Recommendation"
140
- }
141
- countdown={countdown}
142
- isPaused={isPaused}
143
- onPause={onPause}
144
- onProceed={handleProceed}
145
- isLoading={isLoading}
146
- disabled={!selectedOption && !recommended}
147
- />
148
- </div>
149
- ) : (
150
- <div className="w-full flex justify-end items-center gap-1.5 text-green-600 text-xs font-semibold">
151
- <CheckCircle2 className="h-4 w-4" />
152
- <span>
153
- {selectionStatus === "agent"
154
- ? "Suggested by Agent, Approved by You"
155
- : "Selected by You"}
156
- </span>
157
- </div>
158
- )}
159
- </CardFooter>
160
- </Card>
161
- );
162
- },
163
- );
164
-
165
- MCQCard.displayName = "MCQCard";
@@ -1,71 +0,0 @@
1
- export interface MCQOption {
2
- key: string;
3
- label: string;
4
- }
5
-
6
- export interface MCQCardProps {
7
- /**
8
- * The question being asked
9
- */
10
- question: string;
11
-
12
- /**
13
- * The options to choose from
14
- */
15
- options: Record<string, string>;
16
-
17
- /**
18
- * The key of the recommended option
19
- */
20
- recommended?: string;
21
-
22
- /**
23
- * The currently selected option key
24
- */
25
- selectedOption?: string;
26
-
27
- /**
28
- * Triggered when an option is selected
29
- */
30
- onSelect?: (key: string) => void;
31
-
32
- /**
33
- * Triggered when the user clicks continue
34
- */
35
- onProceed?: (key: string) => void;
36
-
37
- /**
38
- * Whether the message is the latest
39
- */
40
- isLatestMessage?: boolean;
41
-
42
- /**
43
- * Countdown in seconds
44
- */
45
- countdown?: number;
46
-
47
- /**
48
- * Whether the countdown is paused
49
- */
50
- isPaused?: boolean;
51
-
52
- /**
53
- * Pause/Resume handler
54
- */
55
- onPause?: () => void;
56
-
57
- /**
58
- * Loading state during submission
59
- */
60
- isLoading?: boolean;
61
-
62
- /**
63
- * Custom className
64
- */
65
- className?: string;
66
-
67
- /**
68
- * Who made the final selection (for historical view)
69
- */
70
- selectionStatus?: "user" | "agent";
71
- }
@@ -1,2 +0,0 @@
1
- export * from "./MCQCard";
2
- export * from "./MCQCard.types";
@@ -1,72 +0,0 @@
1
- import React from "react";
2
- import { PlatformIconGroupMolecule } from "../../../types/molecules";
3
- import { cn } from "@/lib/utils";
4
- import { Instagram, Youtube, Twitter, Video } from "lucide-react";
5
-
6
- const TikTokIcon = ({ className }: { className?: string }) => (
7
- <Video className={className} /> // Placeholder for TikTok
8
- );
9
-
10
- /**
11
- * PlatformIconGroup
12
- * Displays a horizontal list of active social platform icons.
13
- */
14
- export const PlatformIconGroup: React.FC<PlatformIconGroupMolecule> = ({
15
- platforms,
16
- className,
17
- }) => {
18
- const getIcon = (platform: string) => {
19
- switch (platform) {
20
- case "instagram":
21
- return Instagram;
22
- case "tiktok":
23
- return TikTokIcon;
24
- case "youtube":
25
- return Youtube;
26
- case "twitter":
27
- return Twitter;
28
- default:
29
- return null;
30
- }
31
- };
32
-
33
- const getColors = (platform: string) => {
34
- switch (platform) {
35
- case "instagram":
36
- return "text-pink-600 bg-pink-50 hover:bg-pink-100 border-pink-100";
37
- case "tiktok":
38
- return "text-zinc-900 bg-zinc-100 hover:bg-zinc-200 border-zinc-200";
39
- case "youtube":
40
- return "text-red-600 bg-red-50 hover:bg-red-100 border-red-100";
41
- case "twitter":
42
- return "text-sky-500 bg-sky-50 hover:bg-sky-100 border-sky-100";
43
- default:
44
- return "text-gray-500 bg-gray-50 border-gray-100";
45
- }
46
- };
47
-
48
- return (
49
- <div className={cn("flex gap-2", className)}>
50
- {platforms.map((p, i) => {
51
- const Icon = getIcon(p.platform);
52
- if (!Icon) return null;
53
-
54
- return (
55
- <a
56
- key={i}
57
- href={p.url || "#"}
58
- target="_blank"
59
- rel="noopener noreferrer"
60
- title={p.handle || p.platform}
61
- className={cn(
62
- "p-1.5 rounded-lg border transition-colors flex items-center justify-center",
63
- getColors(p.platform),
64
- )}
65
- >
66
- <Icon className="w-4 h-4" />
67
- </a>
68
- );
69
- })}
70
- </div>
71
- );
72
- };
@@ -1 +0,0 @@
1
- export * from "./PlatformIconGroup";