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.
- package/dist/index.cjs +227 -291
- package/dist/index.d.cts +15 -11
- package/dist/index.d.ts +15 -11
- package/dist/index.js +225 -287
- package/dist/registry.json +20 -22
- package/package.json +2 -4
- package/config/tailwind-preset.js +0 -106
- package/src/atoms/AccordionAtom.tsx +0 -44
- package/src/atoms/AlertAtom.tsx +0 -48
- package/src/atoms/AlertDialogAtom.tsx +0 -66
- package/src/atoms/AspectRatioAtom.tsx +0 -27
- package/src/atoms/AvatarAtom.tsx +0 -21
- package/src/atoms/BadgeAtom.tsx +0 -35
- package/src/atoms/BreadcrumbAtom.tsx +0 -36
- package/src/atoms/ButtonAtom.tsx +0 -65
- package/src/atoms/CalendarAtom.tsx +0 -24
- package/src/atoms/CardAtom.tsx +0 -66
- package/src/atoms/CarouselAtom.tsx +0 -40
- package/src/atoms/ChartAtom.tsx +0 -192
- package/src/atoms/CheckboxAtom.tsx +0 -33
- package/src/atoms/CollapsibleAtom.tsx +0 -44
- package/src/atoms/CommandAtom.tsx +0 -46
- package/src/atoms/ContextMenuAtom.tsx +0 -49
- package/src/atoms/DialogAtom.tsx +0 -68
- package/src/atoms/DrawerAtom.tsx +0 -49
- package/src/atoms/DropdownMenuAtom.tsx +0 -49
- package/src/atoms/FormInputAtom.tsx +0 -101
- package/src/atoms/FormSelectAtom.tsx +0 -110
- package/src/atoms/FormTextareaAtom.tsx +0 -93
- package/src/atoms/InputAtom.tsx +0 -216
- package/src/atoms/InputOTPAtom.tsx +0 -49
- package/src/atoms/KbdAtom.tsx +0 -25
- package/src/atoms/LabelAtom.tsx +0 -23
- package/src/atoms/LayoutAtom.tsx +0 -45
- package/src/atoms/PaginationAtom.tsx +0 -49
- package/src/atoms/PopoverAtom.tsx +0 -40
- package/src/atoms/ProgressAtom.tsx +0 -15
- package/src/atoms/RadioGroupAtom.tsx +0 -31
- package/src/atoms/RatingAtom.tsx +0 -37
- package/src/atoms/ResizableAtom.tsx +0 -51
- package/src/atoms/ScrollAreaAtom.tsx +0 -31
- package/src/atoms/SeparatorAtom.tsx +0 -16
- package/src/atoms/SheetAtom.tsx +0 -72
- package/src/atoms/SkeletonAtom.tsx +0 -22
- package/src/atoms/SliderAtom.tsx +0 -32
- package/src/atoms/SpinnerAtom.tsx +0 -26
- package/src/atoms/SwitchAtom.tsx +0 -32
- package/src/atoms/TableAtom.tsx +0 -60
- package/src/atoms/TabsAtom.tsx +0 -40
- package/src/atoms/TextAtom.tsx +0 -36
- package/src/atoms/TextareaAtom.tsx +0 -42
- package/src/atoms/TimelineAtom.tsx +0 -77
- package/src/atoms/ToggleAtom.tsx +0 -36
- package/src/atoms/TooltipAtom.tsx +0 -39
- package/src/atoms/VideoAtom.tsx +0 -34
- package/src/atoms/index.ts +0 -49
- package/src/components/index.ts +0 -178
- package/src/components/ui/accordion.tsx +0 -56
- package/src/components/ui/alert-dialog.tsx +0 -139
- package/src/components/ui/alert.tsx +0 -59
- package/src/components/ui/aspect-ratio.tsx +0 -5
- package/src/components/ui/avatar.tsx +0 -50
- package/src/components/ui/badge.tsx +0 -36
- package/src/components/ui/breadcrumb.tsx +0 -115
- package/src/components/ui/button-group.tsx +0 -83
- package/src/components/ui/button.tsx +0 -56
- package/src/components/ui/calendar.tsx +0 -213
- package/src/components/ui/card.tsx +0 -79
- package/src/components/ui/carousel.tsx +0 -260
- package/src/components/ui/chart.tsx +0 -367
- package/src/components/ui/checkbox.tsx +0 -28
- package/src/components/ui/collapsible.tsx +0 -11
- package/src/components/ui/command.tsx +0 -153
- package/src/components/ui/context-menu.tsx +0 -198
- package/src/components/ui/dialog.tsx +0 -122
- package/src/components/ui/drawer.tsx +0 -116
- package/src/components/ui/dropdown-menu.tsx +0 -200
- package/src/components/ui/empty.tsx +0 -104
- package/src/components/ui/field.tsx +0 -244
- package/src/components/ui/form.tsx +0 -176
- package/src/components/ui/hover-card.tsx +0 -27
- package/src/components/ui/index.ts +0 -54
- package/src/components/ui/input-group.tsx +0 -168
- package/src/components/ui/input-otp.tsx +0 -69
- package/src/components/ui/input.tsx +0 -22
- package/src/components/ui/item.tsx +0 -193
- package/src/components/ui/kbd.tsx +0 -28
- package/src/components/ui/label.tsx +0 -26
- package/src/components/ui/menubar.tsx +0 -254
- package/src/components/ui/navigation-menu.tsx +0 -128
- package/src/components/ui/pagination.tsx +0 -117
- package/src/components/ui/popover.tsx +0 -29
- package/src/components/ui/progress.tsx +0 -28
- package/src/components/ui/radio-group.tsx +0 -42
- package/src/components/ui/resizable.tsx +0 -44
- package/src/components/ui/scroll-area.tsx +0 -46
- package/src/components/ui/select.tsx +0 -160
- package/src/components/ui/separator.tsx +0 -29
- package/src/components/ui/sheet.tsx +0 -140
- package/src/components/ui/sidebar.tsx +0 -771
- package/src/components/ui/skeleton.tsx +0 -15
- package/src/components/ui/slider.tsx +0 -26
- package/src/components/ui/sonner.tsx +0 -45
- package/src/components/ui/spinner.tsx +0 -16
- package/src/components/ui/switch.tsx +0 -27
- package/src/components/ui/table.tsx +0 -117
- package/src/components/ui/tabs.tsx +0 -53
- package/src/components/ui/textarea.tsx +0 -22
- package/src/components/ui/toggle-group.tsx +0 -61
- package/src/components/ui/toggle.tsx +0 -43
- package/src/components/ui/tooltip.tsx +0 -30
- package/src/hooks/use-mobile.tsx +0 -19
- package/src/index.ts +0 -24
- package/src/lib/countries.ts +0 -203
- package/src/lib/index.ts +0 -2
- package/src/lib/utils.ts +0 -15
- package/src/lib/validators/index.ts +0 -1
- package/src/lib/validators/theme.ts +0 -148
- package/src/molecules/creator-discovery/AudienceDemographicsCard/AudienceDemographicsCard.tsx +0 -44
- package/src/molecules/creator-discovery/AudienceDemographicsCard/index.ts +0 -1
- package/src/molecules/creator-discovery/AudienceMetricCard/AudienceMetricCard.tsx +0 -50
- package/src/molecules/creator-discovery/AudienceMetricCard/index.ts +0 -1
- package/src/molecules/creator-discovery/BrandAffinityGroup/BrandAffinityGroup.tsx +0 -36
- package/src/molecules/creator-discovery/BrandAffinityGroup/index.ts +0 -1
- package/src/molecules/creator-discovery/CampaignSeedCard/CampaignSeedCard.tsx +0 -123
- package/src/molecules/creator-discovery/CampaignSeedCard/CampaignSeedCard.types.ts +0 -13
- package/src/molecules/creator-discovery/CampaignSeedCard/index.ts +0 -2
- package/src/molecules/creator-discovery/ContentPreviewGallery/ContentPreviewGallery.tsx +0 -41
- package/src/molecules/creator-discovery/ContentPreviewGallery/index.ts +0 -1
- package/src/molecules/creator-discovery/CreatorActionHeader/CreatorActionHeader.tsx +0 -77
- package/src/molecules/creator-discovery/CreatorActionHeader/index.ts +0 -1
- package/src/molecules/creator-discovery/CreatorGridCard/CreatorGridCard.tsx +0 -104
- package/src/molecules/creator-discovery/CreatorGridCard/index.ts +0 -1
- package/src/molecules/creator-discovery/CreatorProfileSummary/CreatorProfileSummary.tsx +0 -65
- package/src/molecules/creator-discovery/CreatorProfileSummary/index.ts +0 -1
- package/src/molecules/creator-discovery/GrowthChartCard/GrowthChartCard.tsx +0 -58
- package/src/molecules/creator-discovery/GrowthChartCard/index.ts +0 -1
- package/src/molecules/creator-discovery/MCQCard/MCQCard.tsx +0 -165
- package/src/molecules/creator-discovery/MCQCard/MCQCard.types.ts +0 -71
- package/src/molecules/creator-discovery/MCQCard/index.ts +0 -2
- package/src/molecules/creator-discovery/PlatformIconGroup/PlatformIconGroup.tsx +0 -72
- package/src/molecules/creator-discovery/PlatformIconGroup/index.ts +0 -1
- package/src/molecules/creator-discovery/SearchSpecCard/CustomFieldRenderers.tsx +0 -334
- package/src/molecules/creator-discovery/SearchSpecCard/SearchSpecCard.tsx +0 -111
- package/src/molecules/creator-discovery/SearchSpecCard/SearchSpecCard.types.ts +0 -18
- package/src/molecules/creator-discovery/SearchSpecCard/index.ts +0 -3
- package/src/molecules/creator-discovery/TopPostsGrid/TopPostsGrid.tsx +0 -49
- package/src/molecules/creator-discovery/TopPostsGrid/index.ts +0 -1
- package/src/molecules/creator-discovery/index.ts +0 -13
- package/src/molecules/generic/ActionButton/ActionButton.tsx +0 -137
- package/src/molecules/generic/ActionButton/ActionButton.types.ts +0 -68
- package/src/molecules/generic/ActionButton/index.ts +0 -2
- package/src/molecules/generic/DataGrid/DataGrid.tsx +0 -102
- package/src/molecules/generic/DataGrid/index.ts +0 -1
- package/src/molecules/generic/EditableField/EditableField.tsx +0 -229
- package/src/molecules/generic/EditableField/EditableField.types.ts +0 -73
- package/src/molecules/generic/EditableField/index.ts +0 -2
- package/src/molecules/generic/EmptyState/EmptyState.tsx +0 -61
- package/src/molecules/generic/EmptyState/index.ts +0 -1
- package/src/molecules/generic/FileUpload/FileUpload.tsx +0 -62
- package/src/molecules/generic/FileUpload/index.ts +0 -1
- package/src/molecules/generic/FilterBar/FilterBar.tsx +0 -54
- package/src/molecules/generic/FilterBar/index.ts +0 -1
- package/src/molecules/generic/FormCard/FormCard.tsx +0 -136
- package/src/molecules/generic/FormCard/FormCard.types.ts +0 -93
- package/src/molecules/generic/FormCard/index.ts +0 -2
- package/src/molecules/generic/LoadingOverlay/LoadingOverlay.tsx +0 -39
- package/src/molecules/generic/LoadingOverlay/index.ts +0 -1
- package/src/molecules/generic/NotificationList/NotificationList.tsx +0 -80
- package/src/molecules/generic/NotificationList/index.ts +0 -1
- package/src/molecules/generic/StatsGrid/StatsGrid.tsx +0 -80
- package/src/molecules/generic/StatsGrid/index.ts +0 -1
- package/src/molecules/generic/StepWizard/StepWizard.tsx +0 -67
- package/src/molecules/generic/StepWizard/index.ts +0 -1
- package/src/molecules/generic/TagCloud/TagCloud.tsx +0 -32
- package/src/molecules/generic/TagCloud/index.ts +0 -1
- package/src/molecules/generic/index.ts +0 -12
- package/src/molecules/index.ts +0 -2
- package/src/render/PXEngineRenderer.tsx +0 -458
- package/src/render/index.ts +0 -1
- package/src/styles/globals.css +0 -146
- package/src/types/atoms.ts +0 -450
- package/src/types/common.ts +0 -116
- package/src/types/index.ts +0 -3
- package/src/types/molecules.ts +0 -279
- package/src/types/schema.ts +0 -12
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { FormCardProps } from "./FormCard.types";
|
|
3
|
-
import {
|
|
4
|
-
Card,
|
|
5
|
-
CardContent,
|
|
6
|
-
CardHeader,
|
|
7
|
-
CardTitle,
|
|
8
|
-
CardFooter,
|
|
9
|
-
} from "@/components";
|
|
10
|
-
import { EditableField } from "../EditableField";
|
|
11
|
-
import { ActionButton } from "../ActionButton";
|
|
12
|
-
import { cn } from "@/lib/utils";
|
|
13
|
-
import { Copy } from "lucide-react";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* FormCard
|
|
17
|
-
*
|
|
18
|
-
* A high-level molecule that assembles EditableFields into a cohesive card unit.
|
|
19
|
-
* Features:
|
|
20
|
-
* - Dotted vertical timeline visual
|
|
21
|
-
* - Copy to clipboard functionality
|
|
22
|
-
* - Integrated ActionButton with countdown
|
|
23
|
-
* - Responsive layout
|
|
24
|
-
*/
|
|
25
|
-
export const FormCard = React.memo<FormCardProps>(
|
|
26
|
-
({
|
|
27
|
-
title,
|
|
28
|
-
fields,
|
|
29
|
-
data,
|
|
30
|
-
editingFields = {},
|
|
31
|
-
changedFields = {},
|
|
32
|
-
savingFields = {},
|
|
33
|
-
onFieldEdit,
|
|
34
|
-
onFieldSave,
|
|
35
|
-
onFieldCancel,
|
|
36
|
-
showTimeline = true,
|
|
37
|
-
proceedLabel,
|
|
38
|
-
countdown,
|
|
39
|
-
isPaused = false,
|
|
40
|
-
onPause,
|
|
41
|
-
onProceed,
|
|
42
|
-
className,
|
|
43
|
-
footer,
|
|
44
|
-
}) => {
|
|
45
|
-
const handleCopyAll = () => {
|
|
46
|
-
const text = fields
|
|
47
|
-
.map(
|
|
48
|
-
(f) =>
|
|
49
|
-
`${f.label}: ${typeof data[f.key] === "object" ? JSON.stringify(data[f.key]) : data[f.key]}`,
|
|
50
|
-
)
|
|
51
|
-
.join("\n");
|
|
52
|
-
navigator.clipboard.writeText(text);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<Card
|
|
57
|
-
className={cn(
|
|
58
|
-
"w-full rounded-[24px] border border-gray200 bg-white shadow-sm overflow-hidden",
|
|
59
|
-
className,
|
|
60
|
-
)}
|
|
61
|
-
>
|
|
62
|
-
<CardHeader className="flex flex-row items-center justify-between pb-2 space-y-0">
|
|
63
|
-
<CardTitle className="text-lg font-bold text-gray-900 tracking-tight">
|
|
64
|
-
{title}
|
|
65
|
-
</CardTitle>
|
|
66
|
-
<button
|
|
67
|
-
onClick={handleCopyAll}
|
|
68
|
-
className="p-1.5 rounded-md hover:bg-gray-100 text-gray-400 hover:text-gray-600 transition-colors"
|
|
69
|
-
title="Copy all details"
|
|
70
|
-
>
|
|
71
|
-
<Copy className="h-4 w-4" />
|
|
72
|
-
</button>
|
|
73
|
-
</CardHeader>
|
|
74
|
-
|
|
75
|
-
<CardContent className="pt-2 pb-6">
|
|
76
|
-
<div className="relative">
|
|
77
|
-
{/* Vertical Timeline Line */}
|
|
78
|
-
{showTimeline && (
|
|
79
|
-
<div className="absolute left-[7px] top-2 bottom-6 w-0.5 border-l-2 border-dotted border-gray200 pointer-events-none" />
|
|
80
|
-
)}
|
|
81
|
-
|
|
82
|
-
<div className="space-y-4">
|
|
83
|
-
{fields.map((field) => (
|
|
84
|
-
<div key={field.key} className="relative pl-6">
|
|
85
|
-
{/* Timeline Dot */}
|
|
86
|
-
{showTimeline && (
|
|
87
|
-
<div
|
|
88
|
-
className={cn(
|
|
89
|
-
"absolute left-0 top-[18px] w-[14px] h-[14px] -translate-x-1/2 rounded-full border-2 bg-white z-10",
|
|
90
|
-
changedFields[field.key]
|
|
91
|
-
? "border-amber-500"
|
|
92
|
-
: "border-gray-200",
|
|
93
|
-
)}
|
|
94
|
-
/>
|
|
95
|
-
)}
|
|
96
|
-
|
|
97
|
-
<EditableField
|
|
98
|
-
label={field.label}
|
|
99
|
-
value={data[field.key]}
|
|
100
|
-
type={field.type}
|
|
101
|
-
config={field}
|
|
102
|
-
isEditing={editingFields[field.key]}
|
|
103
|
-
isChanged={changedFields[field.key]}
|
|
104
|
-
isSaving={savingFields[field.key]}
|
|
105
|
-
onEdit={() => onFieldEdit?.(field.key)}
|
|
106
|
-
onSave={(val) => onFieldSave?.(field.key, val)}
|
|
107
|
-
onCancel={() => onFieldCancel?.(field.key)}
|
|
108
|
-
/>
|
|
109
|
-
</div>
|
|
110
|
-
))}
|
|
111
|
-
</div>
|
|
112
|
-
</div>
|
|
113
|
-
</CardContent>
|
|
114
|
-
|
|
115
|
-
{(onProceed || footer) && (
|
|
116
|
-
<CardFooter className="flex flex-col gap-4 pt-0 border-t border-gray-100/50 bg-gray-50/30 p-6">
|
|
117
|
-
{onProceed && proceedLabel && (
|
|
118
|
-
<div className="w-full flex justify-center">
|
|
119
|
-
<ActionButton
|
|
120
|
-
label={proceedLabel}
|
|
121
|
-
countdown={countdown}
|
|
122
|
-
isPaused={isPaused}
|
|
123
|
-
onPause={onPause}
|
|
124
|
-
onProceed={onProceed}
|
|
125
|
-
/>
|
|
126
|
-
</div>
|
|
127
|
-
)}
|
|
128
|
-
{footer}
|
|
129
|
-
</CardFooter>
|
|
130
|
-
)}
|
|
131
|
-
</Card>
|
|
132
|
-
);
|
|
133
|
-
},
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
FormCard.displayName = "FormCard";
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { FieldConfig } from "@/types/common";
|
|
2
|
-
|
|
3
|
-
export interface FormCardProps {
|
|
4
|
-
/**
|
|
5
|
-
* Unique identifier
|
|
6
|
-
*/
|
|
7
|
-
id?: string;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Title of the form card
|
|
11
|
-
*/
|
|
12
|
-
title: string;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Map of fields to render
|
|
16
|
-
*/
|
|
17
|
-
fields: FieldConfig[];
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Initial data for the form
|
|
21
|
-
*/
|
|
22
|
-
data: Record<string, any>;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Current editing states for each field
|
|
26
|
-
*/
|
|
27
|
-
editingFields?: Record<string, boolean>;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Fields that have been modified
|
|
31
|
-
*/
|
|
32
|
-
changedFields?: Record<string, boolean>;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Fields currently being saved
|
|
36
|
-
*/
|
|
37
|
-
savingFields?: Record<string, boolean>;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Triggered when a field starts editing
|
|
41
|
-
*/
|
|
42
|
-
onFieldEdit?: (key: string) => void;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Triggered when a field value is saved
|
|
46
|
-
*/
|
|
47
|
-
onFieldSave?: (key: string, newValue: any) => void;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Triggered when a field edit is cancelled
|
|
51
|
-
*/
|
|
52
|
-
onFieldCancel?: (key: string) => void;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Show a dotted timeline visual on the left
|
|
56
|
-
*/
|
|
57
|
-
showTimeline?: boolean;
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Label for the "Proceed" button
|
|
61
|
-
*/
|
|
62
|
-
proceedLabel?: string;
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Countdown for auto-proceed
|
|
66
|
-
*/
|
|
67
|
-
countdown?: number;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Whether the timer is paused
|
|
71
|
-
*/
|
|
72
|
-
isPaused?: boolean;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Pause/Resume handler
|
|
76
|
-
*/
|
|
77
|
-
onPause?: () => void;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Proceed handler
|
|
81
|
-
*/
|
|
82
|
-
onProceed?: () => void;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Custom className
|
|
86
|
-
*/
|
|
87
|
-
className?: string;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Footer content (optional)
|
|
91
|
-
*/
|
|
92
|
-
footer?: React.ReactNode;
|
|
93
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { SpinnerAtom } from "../../../atoms/SpinnerAtom";
|
|
3
|
-
import { TextAtom } from "../../../atoms/TextAtom";
|
|
4
|
-
import { LoadingOverlayMolecule } from "../../../types/molecules";
|
|
5
|
-
import { cn } from "@/lib/utils";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* LoadingOverlay
|
|
9
|
-
* A full-container overlay with a spinner and message.
|
|
10
|
-
*/
|
|
11
|
-
export const LoadingOverlay: React.FC<LoadingOverlayMolecule> = ({
|
|
12
|
-
message = "Loading...",
|
|
13
|
-
className,
|
|
14
|
-
}) => {
|
|
15
|
-
return (
|
|
16
|
-
<div
|
|
17
|
-
className={cn(
|
|
18
|
-
"absolute inset-0 z-50 flex flex-col items-center justify-center bg-white/60 backdrop-blur-[2px] rounded-inherit",
|
|
19
|
-
className,
|
|
20
|
-
)}
|
|
21
|
-
>
|
|
22
|
-
<div className="bg-white p-6 rounded-2xl shadow-xl flex flex-col items-center border border-purple-50">
|
|
23
|
-
<SpinnerAtom
|
|
24
|
-
id="loading-spinner"
|
|
25
|
-
type="spinner"
|
|
26
|
-
size="lg"
|
|
27
|
-
className="text-purple-600 mb-3"
|
|
28
|
-
/>
|
|
29
|
-
<TextAtom
|
|
30
|
-
id="loading-message"
|
|
31
|
-
type="text"
|
|
32
|
-
content={message}
|
|
33
|
-
variant="small"
|
|
34
|
-
className="font-semibold text-purple-900"
|
|
35
|
-
/>
|
|
36
|
-
</div>
|
|
37
|
-
</div>
|
|
38
|
-
);
|
|
39
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./LoadingOverlay";
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Info, CheckCircle2, AlertTriangle, AlertCircle } from "lucide-react";
|
|
3
|
-
import { NotificationListMolecule } from "../../../types/molecules";
|
|
4
|
-
import { cn } from "@/lib/utils";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* NotificationList
|
|
8
|
-
* A list of actionable notifications and activity logs.
|
|
9
|
-
*/
|
|
10
|
-
export const NotificationList: React.FC<NotificationListMolecule> = ({
|
|
11
|
-
notifications,
|
|
12
|
-
className,
|
|
13
|
-
}) => {
|
|
14
|
-
const getIcon = (type: string) => {
|
|
15
|
-
switch (type) {
|
|
16
|
-
case "success":
|
|
17
|
-
return <CheckCircle2 className="w-4 h-4 text-green-600" />;
|
|
18
|
-
case "warning":
|
|
19
|
-
return <AlertTriangle className="w-4 h-4 text-amber-600" />;
|
|
20
|
-
case "error":
|
|
21
|
-
return <AlertCircle className="w-4 h-4 text-red-600" />;
|
|
22
|
-
default:
|
|
23
|
-
return <Info className="w-4 h-4 text-blue-600" />;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const getBg = (type: string) => {
|
|
28
|
-
switch (type) {
|
|
29
|
-
case "success":
|
|
30
|
-
return "bg-green-50";
|
|
31
|
-
case "warning":
|
|
32
|
-
return "bg-amber-50";
|
|
33
|
-
case "error":
|
|
34
|
-
return "bg-red-50";
|
|
35
|
-
default:
|
|
36
|
-
return "bg-blue-50";
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<div className={cn("flex flex-col gap-2", className)}>
|
|
42
|
-
{notifications.map((n) => (
|
|
43
|
-
<div
|
|
44
|
-
key={n.id}
|
|
45
|
-
className={cn(
|
|
46
|
-
"p-3 rounded-2xl flex gap-3 transition-all hover:translate-x-1 border border-transparent hover:border-purple-50 bg-white shadow-[0_2px_10px_-4px_rgba(0,0,0,0.05)]",
|
|
47
|
-
!n.read && "border-purple-100 bg-purple-50/10",
|
|
48
|
-
)}
|
|
49
|
-
>
|
|
50
|
-
<div
|
|
51
|
-
className={cn(
|
|
52
|
-
"w-10 h-10 rounded-xl flex items-center justify-center shrink-0",
|
|
53
|
-
getBg(n.type),
|
|
54
|
-
)}
|
|
55
|
-
>
|
|
56
|
-
{getIcon(n.type)}
|
|
57
|
-
</div>
|
|
58
|
-
<div className="flex flex-col gap-0.5 flex-1 min-w-0">
|
|
59
|
-
<div className="flex items-center justify-between gap-2">
|
|
60
|
-
<h5 className="text-sm font-bold text-gray-900 truncate">
|
|
61
|
-
{n.title}
|
|
62
|
-
</h5>
|
|
63
|
-
{!n.read && (
|
|
64
|
-
<div className="w-2 h-2 rounded-full bg-purple-600 shrink-0" />
|
|
65
|
-
)}
|
|
66
|
-
</div>
|
|
67
|
-
{n.description && (
|
|
68
|
-
<p className="text-xs text-muted-foreground truncate">
|
|
69
|
-
{n.description}
|
|
70
|
-
</p>
|
|
71
|
-
)}
|
|
72
|
-
<span className="text-[10px] text-gray-400 mt-1">
|
|
73
|
-
{n.timestamp}
|
|
74
|
-
</span>
|
|
75
|
-
</div>
|
|
76
|
-
</div>
|
|
77
|
-
))}
|
|
78
|
-
</div>
|
|
79
|
-
);
|
|
80
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./NotificationList";
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Card, CardContent } from "@/components";
|
|
3
|
-
import { TextAtom } from "../../../atoms/TextAtom";
|
|
4
|
-
import { StatsGridMolecule } from "../../../types/molecules";
|
|
5
|
-
import { cn } from "@/lib/utils";
|
|
6
|
-
import * as Icons from "lucide-react";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* StatsGrid
|
|
10
|
-
* A grid of statistical cards with icons and trends.
|
|
11
|
-
*/
|
|
12
|
-
export const StatsGrid: React.FC<StatsGridMolecule> = ({
|
|
13
|
-
items,
|
|
14
|
-
className,
|
|
15
|
-
}) => {
|
|
16
|
-
return (
|
|
17
|
-
<div
|
|
18
|
-
className={cn(
|
|
19
|
-
"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4",
|
|
20
|
-
className,
|
|
21
|
-
)}
|
|
22
|
-
>
|
|
23
|
-
{items.map((item, index) => {
|
|
24
|
-
const Icon = item.icon ? (Icons as any)[item.icon] : null;
|
|
25
|
-
const trendColor =
|
|
26
|
-
item.trendDirection === "up"
|
|
27
|
-
? "text-green-600"
|
|
28
|
-
: item.trendDirection === "down"
|
|
29
|
-
? "text-red-600"
|
|
30
|
-
: "text-gray-500";
|
|
31
|
-
const TrendIcon =
|
|
32
|
-
item.trendDirection === "up"
|
|
33
|
-
? Icons.ArrowUpRight
|
|
34
|
-
: item.trendDirection === "down"
|
|
35
|
-
? Icons.ArrowDownRight
|
|
36
|
-
: null;
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<Card
|
|
40
|
-
key={index}
|
|
41
|
-
className="bg-white/60 backdrop-blur-sm border-purple-50 hover:shadow-md transition-all rounded-2xl overflow-hidden"
|
|
42
|
-
>
|
|
43
|
-
<CardContent className="p-4 flex flex-col gap-2">
|
|
44
|
-
<div className="flex items-center justify-between">
|
|
45
|
-
<TextAtom
|
|
46
|
-
id={`stat-label-${index}`}
|
|
47
|
-
type="text"
|
|
48
|
-
content={item.label}
|
|
49
|
-
variant="small"
|
|
50
|
-
className="text-muted-foreground font-medium"
|
|
51
|
-
/>
|
|
52
|
-
{Icon && <Icon className="w-4 h-4 text-purple-500" />}
|
|
53
|
-
</div>
|
|
54
|
-
<div className="flex items-baseline gap-2">
|
|
55
|
-
<TextAtom
|
|
56
|
-
id={`stat-value-${index}`}
|
|
57
|
-
type="text"
|
|
58
|
-
content={String(item.value)}
|
|
59
|
-
variant="h3"
|
|
60
|
-
className="font-bold text-gray-900"
|
|
61
|
-
/>
|
|
62
|
-
{item.trend && (
|
|
63
|
-
<div
|
|
64
|
-
className={cn(
|
|
65
|
-
"flex items-center text-xs font-bold",
|
|
66
|
-
trendColor,
|
|
67
|
-
)}
|
|
68
|
-
>
|
|
69
|
-
{TrendIcon && <TrendIcon className="w-3 h-3 mr-0.5" />}
|
|
70
|
-
{item.trend}
|
|
71
|
-
</div>
|
|
72
|
-
)}
|
|
73
|
-
</div>
|
|
74
|
-
</CardContent>
|
|
75
|
-
</Card>
|
|
76
|
-
);
|
|
77
|
-
})}
|
|
78
|
-
</div>
|
|
79
|
-
);
|
|
80
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./StatsGrid";
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { StepWizardMolecule } from "../../../types/molecules";
|
|
3
|
-
import { cn } from "@/lib/utils";
|
|
4
|
-
import { Check } from "lucide-react";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* StepWizard
|
|
8
|
-
* Horizontal step indicator for multi-part workflows.
|
|
9
|
-
*/
|
|
10
|
-
export const StepWizard: React.FC<StepWizardMolecule> = ({
|
|
11
|
-
steps,
|
|
12
|
-
currentStep,
|
|
13
|
-
className,
|
|
14
|
-
}) => {
|
|
15
|
-
return (
|
|
16
|
-
<div className={cn("flex items-center w-full", className)}>
|
|
17
|
-
{steps.map((step, i) => {
|
|
18
|
-
const isCompleted = i < currentStep;
|
|
19
|
-
const isActive = i === currentStep;
|
|
20
|
-
const isLast = i === steps.length - 1;
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<React.Fragment key={i}>
|
|
24
|
-
<div className="flex flex-col items-center relative group">
|
|
25
|
-
<div
|
|
26
|
-
className={cn(
|
|
27
|
-
"w-10 h-10 rounded-full flex items-center justify-center border-2 transition-all duration-300",
|
|
28
|
-
isCompleted
|
|
29
|
-
? "bg-purple-600 border-purple-600 text-white"
|
|
30
|
-
: isActive
|
|
31
|
-
? "bg-white border-purple-600 text-purple-600 ring-4 ring-purple-50"
|
|
32
|
-
: "bg-white border-gray-200 text-gray-400",
|
|
33
|
-
)}
|
|
34
|
-
>
|
|
35
|
-
{isCompleted ? (
|
|
36
|
-
<Check className="w-5 h-5" />
|
|
37
|
-
) : (
|
|
38
|
-
<span>{i + 1}</span>
|
|
39
|
-
)}
|
|
40
|
-
</div>
|
|
41
|
-
<div className="absolute -bottom-8 whitespace-nowrap text-center">
|
|
42
|
-
<span
|
|
43
|
-
className={cn(
|
|
44
|
-
"text-xs font-bold",
|
|
45
|
-
isActive ? "text-purple-700" : "text-gray-500",
|
|
46
|
-
)}
|
|
47
|
-
>
|
|
48
|
-
{step.title}
|
|
49
|
-
</span>
|
|
50
|
-
</div>
|
|
51
|
-
</div>
|
|
52
|
-
{!isLast && (
|
|
53
|
-
<div className="flex-1 mx-4 h-0.5 bg-gray-100 self-center mb-0 mt-0">
|
|
54
|
-
<div
|
|
55
|
-
className={cn(
|
|
56
|
-
"h-full bg-purple-600 transition-all duration-500",
|
|
57
|
-
isCompleted ? "w-full" : "w-0",
|
|
58
|
-
)}
|
|
59
|
-
/>
|
|
60
|
-
</div>
|
|
61
|
-
)}
|
|
62
|
-
</React.Fragment>
|
|
63
|
-
);
|
|
64
|
-
})}
|
|
65
|
-
</div>
|
|
66
|
-
);
|
|
67
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./StepWizard";
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Badge } from "@/components/ui/badge";
|
|
3
|
-
import { TagCloudMolecule } from "../../../types/molecules";
|
|
4
|
-
import { cn } from "@/lib/utils";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* TagCloud
|
|
8
|
-
* A cluster of clickable tags.
|
|
9
|
-
*/
|
|
10
|
-
export const TagCloud: React.FC<
|
|
11
|
-
TagCloudMolecule & { onTagClick?: (val: string) => void }
|
|
12
|
-
> = ({ tags, className, onTagClick }) => {
|
|
13
|
-
return (
|
|
14
|
-
<div className={cn("flex flex-wrap gap-2", className)}>
|
|
15
|
-
{tags.map((tag) => (
|
|
16
|
-
<Badge
|
|
17
|
-
key={tag.value}
|
|
18
|
-
variant="secondary"
|
|
19
|
-
className="cursor-pointer bg-white border border-purple-50 hover:bg-purple-50 hover:border-purple-200 text-gray-700 rounded-lg px-3 py-1.5 transition-all flex items-center gap-2 shadow-sm"
|
|
20
|
-
onClick={() => onTagClick?.(tag.value)}
|
|
21
|
-
>
|
|
22
|
-
<span>{tag.label}</span>
|
|
23
|
-
{tag.count !== undefined && (
|
|
24
|
-
<span className="text-[10px] font-bold bg-purple-100 text-purple-700 px-1.5 rounded-full">
|
|
25
|
-
{tag.count}
|
|
26
|
-
</span>
|
|
27
|
-
)}
|
|
28
|
-
</Badge>
|
|
29
|
-
))}
|
|
30
|
-
</div>
|
|
31
|
-
);
|
|
32
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./TagCloud";
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export * from "./EditableField";
|
|
2
|
-
export * from "./ActionButton";
|
|
3
|
-
export * from "./FormCard";
|
|
4
|
-
export * from "./StatsGrid";
|
|
5
|
-
export * from "./EmptyState";
|
|
6
|
-
export * from "./LoadingOverlay";
|
|
7
|
-
export * from "./FilterBar";
|
|
8
|
-
export * from "./FileUpload";
|
|
9
|
-
export * from "./TagCloud";
|
|
10
|
-
export * from "./DataGrid";
|
|
11
|
-
export * from "./StepWizard";
|
|
12
|
-
export * from "./NotificationList";
|
package/src/molecules/index.ts
DELETED