@moeve-ui/ui 0.1.0 → 0.2.0
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.d.mts +52 -1
- package/dist/index.d.ts +52 -1
- package/dist/index.js +194 -61
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +189 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -85,6 +85,8 @@ declare function TrendDownIcon(props: IconProps): react.JSX.Element;
|
|
|
85
85
|
declare function FuelIcon(props: IconProps): react.JSX.Element;
|
|
86
86
|
declare function WalletIcon(props: IconProps): react.JSX.Element;
|
|
87
87
|
declare function CheckCircleIcon(props: IconProps): react.JSX.Element;
|
|
88
|
+
declare function CalendarIcon(props: IconProps): react.JSX.Element;
|
|
89
|
+
declare function UploadIcon(props: IconProps): react.JSX.Element;
|
|
88
90
|
declare function XIcon(props: IconProps): react.JSX.Element;
|
|
89
91
|
/**
|
|
90
92
|
* Solid/filled icon set, exported directly from the "Redinamic-tec" Figma
|
|
@@ -320,6 +322,55 @@ interface MiniMapCardProps {
|
|
|
320
322
|
*/
|
|
321
323
|
declare function MiniMapCard({ overlayTitle, overlayLinkLabel, competitorCount }: MiniMapCardProps): react.JSX.Element;
|
|
322
324
|
|
|
325
|
+
interface WeekdayPickerProps {
|
|
326
|
+
/** Exactly 7 short labels, in whatever order/language the caller uses (e.g. ["Lun", ..., "Dom"]). The index is the day value passed to onToggle/selected. */
|
|
327
|
+
labels: readonly string[];
|
|
328
|
+
/** Day indices currently toggled on. */
|
|
329
|
+
selected: readonly number[];
|
|
330
|
+
onToggle: (day: number) => void;
|
|
331
|
+
className?: string;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Circular day-of-week toggle row - previously hand-duplicated (with
|
|
335
|
+
* slightly different styles) in redisplay-web's QuoteWizard and
|
|
336
|
+
* RecurringPlansClient. Generic on purpose: the caller owns the labels
|
|
337
|
+
* (language/order) and which days start selected.
|
|
338
|
+
*/
|
|
339
|
+
declare function WeekdayPicker({ labels, selected, onToggle, className }: WeekdayPickerProps): react.JSX.Element;
|
|
340
|
+
|
|
341
|
+
interface SelectableCardProps {
|
|
342
|
+
icon?: ReactNode;
|
|
343
|
+
title: string;
|
|
344
|
+
subtitle?: string;
|
|
345
|
+
selected?: boolean;
|
|
346
|
+
onClick: () => void;
|
|
347
|
+
className?: string;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Generic clickable "pick one of these" card: an icon chip, a title, an
|
|
351
|
+
* optional subtitle, and a selected state. Not tied to any domain (not
|
|
352
|
+
* "StationCard") - meant for any picker across the 3 apps (redisplay-web's
|
|
353
|
+
* station picker today, any future list-of-options screen tomorrow).
|
|
354
|
+
*/
|
|
355
|
+
declare function SelectableCard({ icon, title, subtitle, selected, onClick, className }: SelectableCardProps): react.JSX.Element;
|
|
356
|
+
|
|
357
|
+
interface FileDropzoneProps {
|
|
358
|
+
accept?: string;
|
|
359
|
+
onFileSelected: (file: File | null) => void;
|
|
360
|
+
/** Name of the currently-selected file, if any - the caller owns the File itself, this component is stateless about it. */
|
|
361
|
+
selectedFileName?: string | null;
|
|
362
|
+
label?: string;
|
|
363
|
+
hint?: string;
|
|
364
|
+
className?: string;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Restyled file picker: a dashed dropzone (click or drag-and-drop) instead
|
|
368
|
+
* of a bare `<input type="file">`. The native input still does the actual
|
|
369
|
+
* work (hidden, triggered via the visible box) - this only changes how it
|
|
370
|
+
* looks, not the underlying file-selection contract.
|
|
371
|
+
*/
|
|
372
|
+
declare function FileDropzone({ accept, onFileSelected, selectedFileName, label, hint, className, }: FileDropzoneProps): react.JSX.Element;
|
|
373
|
+
|
|
323
374
|
interface SidebarStation {
|
|
324
375
|
id: string;
|
|
325
376
|
label: string;
|
|
@@ -392,4 +443,4 @@ interface ConfirmDialogProps {
|
|
|
392
443
|
*/
|
|
393
444
|
declare function ConfirmDialog({ open, onClose, onConfirm, title, productLabel, description, currentPrice, newPrice, marginImpactLabel, volumeImpactLabel, confirming, }: ConfirmDialogProps): react.JSX.Element | null;
|
|
394
445
|
|
|
395
|
-
export { ArrowDownIcon, ArrowUpIcon, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeTone, BoltIcon, Button, type ButtonProps, type ButtonVariant, Card, type CardProps, CheckCircleIcon, ChevronDownIcon, type ColorTokens, CompetitorRow, type CompetitorRowProps, type CompetitorTrend, ConfirmDialog, type ConfirmDialogProps, DecisionFactorRow, type DecisionFactorRowProps, FuelIcon, FuelPumpSolidIcon, LogOutIcon, MapPinIcon, MiniMapCard, type MiniMapCardProps, NavItem, type NavItemProps, PriceRangeSlider, type PriceRangeSliderProps, ProgressBar, type ProgressBarProps, RefreshIcon, type SegmentedTabOption, SegmentedTabs, type SegmentedTabsProps, Sidebar, type SidebarNavItem, type SidebarProps, type SidebarStation, type SidebarUser, Snackbar, type SnackbarProps, type SnackbarTone, StatTile, type StatTileProps, TagIcon, TargetIcon, TopBar, type TopBarProps, TrendDownIcon, TrendUpIcon, TrendUpSolidIcon, UserCircleIcon, WalletIcon, WalletSolidIcon, XIcon, colors };
|
|
446
|
+
export { ArrowDownIcon, ArrowUpIcon, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeTone, BoltIcon, Button, type ButtonProps, type ButtonVariant, CalendarIcon, Card, type CardProps, CheckCircleIcon, ChevronDownIcon, type ColorTokens, CompetitorRow, type CompetitorRowProps, type CompetitorTrend, ConfirmDialog, type ConfirmDialogProps, DecisionFactorRow, type DecisionFactorRowProps, FileDropzone, type FileDropzoneProps, FuelIcon, FuelPumpSolidIcon, LogOutIcon, MapPinIcon, MiniMapCard, type MiniMapCardProps, NavItem, type NavItemProps, PriceRangeSlider, type PriceRangeSliderProps, ProgressBar, type ProgressBarProps, RefreshIcon, type SegmentedTabOption, SegmentedTabs, type SegmentedTabsProps, SelectableCard, type SelectableCardProps, Sidebar, type SidebarNavItem, type SidebarProps, type SidebarStation, type SidebarUser, Snackbar, type SnackbarProps, type SnackbarTone, StatTile, type StatTileProps, TagIcon, TargetIcon, TopBar, type TopBarProps, TrendDownIcon, TrendUpIcon, TrendUpSolidIcon, UploadIcon, UserCircleIcon, WalletIcon, WalletSolidIcon, WeekdayPicker, type WeekdayPickerProps, XIcon, colors };
|
package/dist/index.d.ts
CHANGED
|
@@ -85,6 +85,8 @@ declare function TrendDownIcon(props: IconProps): react.JSX.Element;
|
|
|
85
85
|
declare function FuelIcon(props: IconProps): react.JSX.Element;
|
|
86
86
|
declare function WalletIcon(props: IconProps): react.JSX.Element;
|
|
87
87
|
declare function CheckCircleIcon(props: IconProps): react.JSX.Element;
|
|
88
|
+
declare function CalendarIcon(props: IconProps): react.JSX.Element;
|
|
89
|
+
declare function UploadIcon(props: IconProps): react.JSX.Element;
|
|
88
90
|
declare function XIcon(props: IconProps): react.JSX.Element;
|
|
89
91
|
/**
|
|
90
92
|
* Solid/filled icon set, exported directly from the "Redinamic-tec" Figma
|
|
@@ -320,6 +322,55 @@ interface MiniMapCardProps {
|
|
|
320
322
|
*/
|
|
321
323
|
declare function MiniMapCard({ overlayTitle, overlayLinkLabel, competitorCount }: MiniMapCardProps): react.JSX.Element;
|
|
322
324
|
|
|
325
|
+
interface WeekdayPickerProps {
|
|
326
|
+
/** Exactly 7 short labels, in whatever order/language the caller uses (e.g. ["Lun", ..., "Dom"]). The index is the day value passed to onToggle/selected. */
|
|
327
|
+
labels: readonly string[];
|
|
328
|
+
/** Day indices currently toggled on. */
|
|
329
|
+
selected: readonly number[];
|
|
330
|
+
onToggle: (day: number) => void;
|
|
331
|
+
className?: string;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Circular day-of-week toggle row - previously hand-duplicated (with
|
|
335
|
+
* slightly different styles) in redisplay-web's QuoteWizard and
|
|
336
|
+
* RecurringPlansClient. Generic on purpose: the caller owns the labels
|
|
337
|
+
* (language/order) and which days start selected.
|
|
338
|
+
*/
|
|
339
|
+
declare function WeekdayPicker({ labels, selected, onToggle, className }: WeekdayPickerProps): react.JSX.Element;
|
|
340
|
+
|
|
341
|
+
interface SelectableCardProps {
|
|
342
|
+
icon?: ReactNode;
|
|
343
|
+
title: string;
|
|
344
|
+
subtitle?: string;
|
|
345
|
+
selected?: boolean;
|
|
346
|
+
onClick: () => void;
|
|
347
|
+
className?: string;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Generic clickable "pick one of these" card: an icon chip, a title, an
|
|
351
|
+
* optional subtitle, and a selected state. Not tied to any domain (not
|
|
352
|
+
* "StationCard") - meant for any picker across the 3 apps (redisplay-web's
|
|
353
|
+
* station picker today, any future list-of-options screen tomorrow).
|
|
354
|
+
*/
|
|
355
|
+
declare function SelectableCard({ icon, title, subtitle, selected, onClick, className }: SelectableCardProps): react.JSX.Element;
|
|
356
|
+
|
|
357
|
+
interface FileDropzoneProps {
|
|
358
|
+
accept?: string;
|
|
359
|
+
onFileSelected: (file: File | null) => void;
|
|
360
|
+
/** Name of the currently-selected file, if any - the caller owns the File itself, this component is stateless about it. */
|
|
361
|
+
selectedFileName?: string | null;
|
|
362
|
+
label?: string;
|
|
363
|
+
hint?: string;
|
|
364
|
+
className?: string;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Restyled file picker: a dashed dropzone (click or drag-and-drop) instead
|
|
368
|
+
* of a bare `<input type="file">`. The native input still does the actual
|
|
369
|
+
* work (hidden, triggered via the visible box) - this only changes how it
|
|
370
|
+
* looks, not the underlying file-selection contract.
|
|
371
|
+
*/
|
|
372
|
+
declare function FileDropzone({ accept, onFileSelected, selectedFileName, label, hint, className, }: FileDropzoneProps): react.JSX.Element;
|
|
373
|
+
|
|
323
374
|
interface SidebarStation {
|
|
324
375
|
id: string;
|
|
325
376
|
label: string;
|
|
@@ -392,4 +443,4 @@ interface ConfirmDialogProps {
|
|
|
392
443
|
*/
|
|
393
444
|
declare function ConfirmDialog({ open, onClose, onConfirm, title, productLabel, description, currentPrice, newPrice, marginImpactLabel, volumeImpactLabel, confirming, }: ConfirmDialogProps): react.JSX.Element | null;
|
|
394
445
|
|
|
395
|
-
export { ArrowDownIcon, ArrowUpIcon, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeTone, BoltIcon, Button, type ButtonProps, type ButtonVariant, Card, type CardProps, CheckCircleIcon, ChevronDownIcon, type ColorTokens, CompetitorRow, type CompetitorRowProps, type CompetitorTrend, ConfirmDialog, type ConfirmDialogProps, DecisionFactorRow, type DecisionFactorRowProps, FuelIcon, FuelPumpSolidIcon, LogOutIcon, MapPinIcon, MiniMapCard, type MiniMapCardProps, NavItem, type NavItemProps, PriceRangeSlider, type PriceRangeSliderProps, ProgressBar, type ProgressBarProps, RefreshIcon, type SegmentedTabOption, SegmentedTabs, type SegmentedTabsProps, Sidebar, type SidebarNavItem, type SidebarProps, type SidebarStation, type SidebarUser, Snackbar, type SnackbarProps, type SnackbarTone, StatTile, type StatTileProps, TagIcon, TargetIcon, TopBar, type TopBarProps, TrendDownIcon, TrendUpIcon, TrendUpSolidIcon, UserCircleIcon, WalletIcon, WalletSolidIcon, XIcon, colors };
|
|
446
|
+
export { ArrowDownIcon, ArrowUpIcon, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeTone, BoltIcon, Button, type ButtonProps, type ButtonVariant, CalendarIcon, Card, type CardProps, CheckCircleIcon, ChevronDownIcon, type ColorTokens, CompetitorRow, type CompetitorRowProps, type CompetitorTrend, ConfirmDialog, type ConfirmDialogProps, DecisionFactorRow, type DecisionFactorRowProps, FileDropzone, type FileDropzoneProps, FuelIcon, FuelPumpSolidIcon, LogOutIcon, MapPinIcon, MiniMapCard, type MiniMapCardProps, NavItem, type NavItemProps, PriceRangeSlider, type PriceRangeSliderProps, ProgressBar, type ProgressBarProps, RefreshIcon, type SegmentedTabOption, SegmentedTabs, type SegmentedTabsProps, SelectableCard, type SelectableCardProps, Sidebar, type SidebarNavItem, type SidebarProps, type SidebarStation, type SidebarUser, Snackbar, type SnackbarProps, type SnackbarTone, StatTile, type StatTileProps, TagIcon, TargetIcon, TopBar, type TopBarProps, TrendDownIcon, TrendUpIcon, TrendUpSolidIcon, UploadIcon, UserCircleIcon, WalletIcon, WalletSolidIcon, WeekdayPicker, type WeekdayPickerProps, XIcon, colors };
|
package/dist/index.js
CHANGED
|
@@ -26,12 +26,14 @@ __export(src_exports, {
|
|
|
26
26
|
Badge: () => Badge,
|
|
27
27
|
BoltIcon: () => BoltIcon,
|
|
28
28
|
Button: () => Button,
|
|
29
|
+
CalendarIcon: () => CalendarIcon,
|
|
29
30
|
Card: () => Card,
|
|
30
31
|
CheckCircleIcon: () => CheckCircleIcon,
|
|
31
32
|
ChevronDownIcon: () => ChevronDownIcon,
|
|
32
33
|
CompetitorRow: () => CompetitorRow,
|
|
33
34
|
ConfirmDialog: () => ConfirmDialog,
|
|
34
35
|
DecisionFactorRow: () => DecisionFactorRow,
|
|
36
|
+
FileDropzone: () => FileDropzone,
|
|
35
37
|
FuelIcon: () => FuelIcon,
|
|
36
38
|
FuelPumpSolidIcon: () => FuelPumpSolidIcon,
|
|
37
39
|
LogOutIcon: () => LogOutIcon,
|
|
@@ -42,6 +44,7 @@ __export(src_exports, {
|
|
|
42
44
|
ProgressBar: () => ProgressBar,
|
|
43
45
|
RefreshIcon: () => RefreshIcon,
|
|
44
46
|
SegmentedTabs: () => SegmentedTabs,
|
|
47
|
+
SelectableCard: () => SelectableCard,
|
|
45
48
|
Sidebar: () => Sidebar,
|
|
46
49
|
Snackbar: () => Snackbar,
|
|
47
50
|
StatTile: () => StatTile,
|
|
@@ -51,9 +54,11 @@ __export(src_exports, {
|
|
|
51
54
|
TrendDownIcon: () => TrendDownIcon,
|
|
52
55
|
TrendUpIcon: () => TrendUpIcon,
|
|
53
56
|
TrendUpSolidIcon: () => TrendUpSolidIcon,
|
|
57
|
+
UploadIcon: () => UploadIcon,
|
|
54
58
|
UserCircleIcon: () => UserCircleIcon,
|
|
55
59
|
WalletIcon: () => WalletIcon,
|
|
56
60
|
WalletSolidIcon: () => WalletSolidIcon,
|
|
61
|
+
WeekdayPicker: () => WeekdayPicker,
|
|
57
62
|
XIcon: () => XIcon,
|
|
58
63
|
colors: () => colors
|
|
59
64
|
});
|
|
@@ -200,6 +205,21 @@ function CheckCircleIcon(props) {
|
|
|
200
205
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m8.5 12.5 2.5 2.5 5-5" })
|
|
201
206
|
] });
|
|
202
207
|
}
|
|
208
|
+
function CalendarIcon(props) {
|
|
209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...base, stroke: "currentColor", ...props, children: [
|
|
210
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "3", y: "5", width: "18", height: "16", rx: "2" }),
|
|
211
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "3", y1: "10", x2: "21", y2: "10" }),
|
|
212
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "8", y1: "3", x2: "8", y2: "7" }),
|
|
213
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "16", y1: "3", x2: "16", y2: "7" })
|
|
214
|
+
] });
|
|
215
|
+
}
|
|
216
|
+
function UploadIcon(props) {
|
|
217
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...base, stroke: "currentColor", ...props, children: [
|
|
218
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 16V4" }),
|
|
219
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m7 9 5-5 5 5" }),
|
|
220
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4 16v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3" })
|
|
221
|
+
] });
|
|
222
|
+
}
|
|
203
223
|
function XIcon(props) {
|
|
204
224
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...base, stroke: "currentColor", ...props, children: [
|
|
205
225
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 6 6 18" }),
|
|
@@ -584,8 +604,116 @@ function MiniMapCard({ overlayTitle, overlayLinkLabel, competitorCount }) {
|
|
|
584
604
|
] });
|
|
585
605
|
}
|
|
586
606
|
|
|
587
|
-
// src/
|
|
607
|
+
// src/molecules/WeekdayPicker/WeekdayPicker.tsx
|
|
588
608
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
609
|
+
function WeekdayPicker({ labels, selected, onToggle, className = "" }) {
|
|
610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { role: "group", className: `flex flex-wrap gap-2 ${className}`.trim(), children: labels.map((label, day) => {
|
|
611
|
+
const active = selected.includes(day);
|
|
612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
613
|
+
"button",
|
|
614
|
+
{
|
|
615
|
+
type: "button",
|
|
616
|
+
"aria-pressed": active,
|
|
617
|
+
onClick: () => onToggle(day),
|
|
618
|
+
className: `flex h-10 w-10 items-center justify-center rounded-full border text-xs font-semibold transition-colors ${active ? "border-brand-primary bg-brand-primary text-white" : "border-border text-text-secondary hover:bg-surface-subtle"}`,
|
|
619
|
+
children: label
|
|
620
|
+
},
|
|
621
|
+
day
|
|
622
|
+
);
|
|
623
|
+
}) });
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// src/molecules/SelectableCard/SelectableCard.tsx
|
|
627
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
628
|
+
function SelectableCard({ icon, title, subtitle, selected = false, onClick, className = "" }) {
|
|
629
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
630
|
+
"button",
|
|
631
|
+
{
|
|
632
|
+
type: "button",
|
|
633
|
+
"aria-pressed": selected,
|
|
634
|
+
onClick,
|
|
635
|
+
className: `flex w-full items-center gap-3 rounded-xl border p-4 text-left transition-colors ${selected ? "border-brand-primary bg-brand-primary/5" : "border-border hover:bg-surface-subtle"} ${className}`.trim(),
|
|
636
|
+
children: [
|
|
637
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
638
|
+
"span",
|
|
639
|
+
{
|
|
640
|
+
className: `flex h-10 w-10 shrink-0 items-center justify-center rounded-full ${selected ? "bg-brand-primary text-white" : "bg-surface-muted text-text-secondary"}`,
|
|
641
|
+
children: icon
|
|
642
|
+
}
|
|
643
|
+
),
|
|
644
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col", children: [
|
|
645
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-medium text-text-primary", children: title }),
|
|
646
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-sm text-text-tertiary", children: subtitle })
|
|
647
|
+
] })
|
|
648
|
+
]
|
|
649
|
+
}
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// src/molecules/FileDropzone/FileDropzone.tsx
|
|
654
|
+
var import_react = require("react");
|
|
655
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
656
|
+
function FileDropzone({
|
|
657
|
+
accept,
|
|
658
|
+
onFileSelected,
|
|
659
|
+
selectedFileName,
|
|
660
|
+
label = "Arrastra tu archivo aqu\xED, o haz clic para elegirlo",
|
|
661
|
+
hint,
|
|
662
|
+
className = ""
|
|
663
|
+
}) {
|
|
664
|
+
const inputRef = (0, import_react.useRef)(null);
|
|
665
|
+
const [dragActive, setDragActive] = (0, import_react.useState)(false);
|
|
666
|
+
function openPicker() {
|
|
667
|
+
inputRef.current?.click();
|
|
668
|
+
}
|
|
669
|
+
function handleKeyDown(e) {
|
|
670
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
671
|
+
e.preventDefault();
|
|
672
|
+
openPicker();
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
function handleDrop(e) {
|
|
676
|
+
e.preventDefault();
|
|
677
|
+
setDragActive(false);
|
|
678
|
+
onFileSelected(e.dataTransfer.files?.[0] ?? null);
|
|
679
|
+
}
|
|
680
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
681
|
+
"div",
|
|
682
|
+
{
|
|
683
|
+
role: "button",
|
|
684
|
+
tabIndex: 0,
|
|
685
|
+
onClick: openPicker,
|
|
686
|
+
onKeyDown: handleKeyDown,
|
|
687
|
+
onDragOver: (e) => {
|
|
688
|
+
e.preventDefault();
|
|
689
|
+
setDragActive(true);
|
|
690
|
+
},
|
|
691
|
+
onDragLeave: () => setDragActive(false),
|
|
692
|
+
onDrop: handleDrop,
|
|
693
|
+
className: `flex cursor-pointer flex-col items-center justify-center gap-2 rounded-xl border-2 border-dashed px-6 py-8 text-center transition-colors ${dragActive ? "border-brand-primary bg-brand-primary/5" : "border-border hover:border-brand-primary/60"} ${className}`.trim(),
|
|
694
|
+
children: [
|
|
695
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
696
|
+
"input",
|
|
697
|
+
{
|
|
698
|
+
ref: inputRef,
|
|
699
|
+
type: "file",
|
|
700
|
+
accept,
|
|
701
|
+
className: "hidden",
|
|
702
|
+
onChange: (e) => onFileSelected(e.target.files?.[0] ?? null)
|
|
703
|
+
}
|
|
704
|
+
),
|
|
705
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(UploadIcon, { className: `size-6 ${dragActive ? "text-brand-primary" : "text-text-tertiary"}` }),
|
|
706
|
+
selectedFileName ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-medium text-text-primary", children: selectedFileName }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
707
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-medium text-text-primary", children: label }),
|
|
708
|
+
hint && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-xs text-text-tertiary", children: hint })
|
|
709
|
+
] })
|
|
710
|
+
]
|
|
711
|
+
}
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// src/organisms/Sidebar/Sidebar.tsx
|
|
716
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
589
717
|
function Sidebar({
|
|
590
718
|
brandName = "Redinamic",
|
|
591
719
|
stations,
|
|
@@ -595,43 +723,43 @@ function Sidebar({
|
|
|
595
723
|
user,
|
|
596
724
|
onLogout
|
|
597
725
|
}) {
|
|
598
|
-
return /* @__PURE__ */ (0,
|
|
599
|
-
/* @__PURE__ */ (0,
|
|
600
|
-
/* @__PURE__ */ (0,
|
|
601
|
-
/* @__PURE__ */ (0,
|
|
602
|
-
/* @__PURE__ */ (0,
|
|
726
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("aside", { className: "fixed left-0 top-0 flex h-screen w-[260px] flex-col justify-between bg-brand-sidebar pb-2 pt-8", children: [
|
|
727
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col gap-6 px-4 pb-6", children: [
|
|
728
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-3 px-2", children: [
|
|
729
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex size-8 items-center justify-center rounded bg-brand-logo", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(BoltIcon, { className: "size-4 text-brand-sidebar" }) }),
|
|
730
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-2xl font-semibold tracking-tight text-white", children: brandName })
|
|
603
731
|
] }),
|
|
604
|
-
/* @__PURE__ */ (0,
|
|
605
|
-
/* @__PURE__ */ (0,
|
|
606
|
-
/* @__PURE__ */ (0,
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "relative", children: [
|
|
733
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(MapPinIcon, { className: "pointer-events-none absolute left-4 top-1/2 size-4 -translate-y-1/2 text-white" }),
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
607
735
|
"select",
|
|
608
736
|
{
|
|
609
737
|
value: selectedStationId,
|
|
610
738
|
onChange: (event) => onSelectStation(event.target.value),
|
|
611
739
|
className: "w-full appearance-none rounded-xl border border-white/10 bg-white/10 py-2.5 pl-10 pr-9 text-sm font-semibold text-white outline-none",
|
|
612
|
-
children: stations.map((station) => /* @__PURE__ */ (0,
|
|
740
|
+
children: stations.map((station) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: station.id, className: "text-text-primary", children: station.label }, station.id))
|
|
613
741
|
}
|
|
614
742
|
),
|
|
615
|
-
/* @__PURE__ */ (0,
|
|
743
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChevronDownIcon, { className: "pointer-events-none absolute right-3 top-1/2 size-3 -translate-y-1/2 text-white" })
|
|
616
744
|
] })
|
|
617
745
|
] }),
|
|
618
|
-
/* @__PURE__ */ (0,
|
|
619
|
-
/* @__PURE__ */ (0,
|
|
620
|
-
/* @__PURE__ */ (0,
|
|
621
|
-
/* @__PURE__ */ (0,
|
|
622
|
-
/* @__PURE__ */ (0,
|
|
623
|
-
/* @__PURE__ */ (0,
|
|
624
|
-
/* @__PURE__ */ (0,
|
|
746
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("nav", { className: "flex flex-1 flex-col gap-1 px-4", children: navItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NavItem, { icon: item.icon, label: item.label, active: item.active, href: item.href }, item.key)) }),
|
|
747
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "border-t border-white/10 px-4 pt-4", children: [
|
|
748
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-3 px-4 py-3", children: [
|
|
749
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Avatar, { className: "bg-brand-primary text-white", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(UserCircleIcon, { className: "size-4" }) }),
|
|
750
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
|
|
751
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-semibold text-white", children: user.name }),
|
|
752
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-xs text-white/60", children: user.role })
|
|
625
753
|
] })
|
|
626
754
|
] }),
|
|
627
|
-
/* @__PURE__ */ (0,
|
|
755
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
628
756
|
"button",
|
|
629
757
|
{
|
|
630
758
|
type: "button",
|
|
631
759
|
onClick: onLogout,
|
|
632
760
|
className: "flex w-full items-center gap-3 rounded-lg px-4 py-2 text-sm font-semibold text-white/50 transition-colors hover:text-white/80",
|
|
633
761
|
children: [
|
|
634
|
-
/* @__PURE__ */ (0,
|
|
762
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(LogOutIcon, { className: "size-4" }),
|
|
635
763
|
"Cerrar Sesi\xF3n"
|
|
636
764
|
]
|
|
637
765
|
}
|
|
@@ -641,7 +769,7 @@ function Sidebar({
|
|
|
641
769
|
}
|
|
642
770
|
|
|
643
771
|
// src/organisms/TopBar/TopBar.tsx
|
|
644
|
-
var
|
|
772
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
645
773
|
function TopBar({
|
|
646
774
|
stationName,
|
|
647
775
|
lastUpdatedLabel,
|
|
@@ -649,36 +777,36 @@ function TopBar({
|
|
|
649
777
|
refreshing = false,
|
|
650
778
|
middleContent
|
|
651
779
|
}) {
|
|
652
|
-
return /* @__PURE__ */ (0,
|
|
653
|
-
/* @__PURE__ */ (0,
|
|
654
|
-
/* @__PURE__ */ (0,
|
|
655
|
-
/* @__PURE__ */ (0,
|
|
656
|
-
/* @__PURE__ */ (0,
|
|
780
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("header", { className: "fixed left-[260px] right-0 top-0 z-10 flex h-20 items-center justify-between gap-4 bg-surface-page/80 px-6 shadow-header backdrop-blur-md", children: [
|
|
781
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "shrink-0", children: [
|
|
782
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
783
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MapPinIcon, { className: "size-4 text-text-primary" }),
|
|
784
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-sm font-semibold text-text-primary", children: stationName })
|
|
657
785
|
] }),
|
|
658
|
-
/* @__PURE__ */ (0,
|
|
659
|
-
/* @__PURE__ */ (0,
|
|
660
|
-
/* @__PURE__ */ (0,
|
|
786
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "mt-1 flex items-center gap-2", children: [
|
|
787
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "size-2 rounded-full bg-success-dark" }),
|
|
788
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs font-medium text-text-secondary", children: lastUpdatedLabel })
|
|
661
789
|
] })
|
|
662
790
|
] }),
|
|
663
791
|
middleContent,
|
|
664
|
-
/* @__PURE__ */ (0,
|
|
665
|
-
/* @__PURE__ */ (0,
|
|
792
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex shrink-0 items-center gap-4", children: [
|
|
793
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
666
794
|
Button,
|
|
667
795
|
{
|
|
668
796
|
variant: "primary",
|
|
669
|
-
icon: /* @__PURE__ */ (0,
|
|
797
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefreshIcon, { className: `size-4 ${refreshing ? "animate-spin" : ""}` }),
|
|
670
798
|
onClick: onRefresh,
|
|
671
799
|
disabled: refreshing,
|
|
672
800
|
children: "Actualizar datos"
|
|
673
801
|
}
|
|
674
802
|
),
|
|
675
|
-
/* @__PURE__ */ (0,
|
|
803
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Avatar, { className: "bg-brand-primary text-white", size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(UserCircleIcon, { className: "size-4" }) })
|
|
676
804
|
] })
|
|
677
805
|
] });
|
|
678
806
|
}
|
|
679
807
|
|
|
680
808
|
// src/organisms/ConfirmDialog/ConfirmDialog.tsx
|
|
681
|
-
var
|
|
809
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
682
810
|
function ConfirmDialog({
|
|
683
811
|
open,
|
|
684
812
|
onClose,
|
|
@@ -693,49 +821,49 @@ function ConfirmDialog({
|
|
|
693
821
|
confirming = false
|
|
694
822
|
}) {
|
|
695
823
|
if (!open) return null;
|
|
696
|
-
return /* @__PURE__ */ (0,
|
|
697
|
-
/* @__PURE__ */ (0,
|
|
698
|
-
/* @__PURE__ */ (0,
|
|
824
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "w-full max-w-md overflow-hidden rounded-2xl bg-white shadow-modal", children: [
|
|
825
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "relative flex items-center justify-center bg-gradient-to-r from-brand-primary to-info-dark py-8", children: [
|
|
826
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
699
827
|
"button",
|
|
700
828
|
{
|
|
701
829
|
type: "button",
|
|
702
830
|
onClick: onClose,
|
|
703
831
|
"aria-label": "Cerrar",
|
|
704
832
|
className: "absolute right-4 top-4 text-white/80 hover:text-white",
|
|
705
|
-
children: /* @__PURE__ */ (0,
|
|
833
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(XIcon, { className: "size-5" })
|
|
706
834
|
}
|
|
707
835
|
),
|
|
708
|
-
/* @__PURE__ */ (0,
|
|
836
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex size-14 items-center justify-center rounded-full bg-white text-brand-primary", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(WalletIcon, { className: "size-6" }) })
|
|
709
837
|
] }),
|
|
710
|
-
/* @__PURE__ */ (0,
|
|
711
|
-
/* @__PURE__ */ (0,
|
|
712
|
-
/* @__PURE__ */ (0,
|
|
713
|
-
/* @__PURE__ */ (0,
|
|
714
|
-
/* @__PURE__ */ (0,
|
|
715
|
-
/* @__PURE__ */ (0,
|
|
716
|
-
/* @__PURE__ */ (0,
|
|
717
|
-
/* @__PURE__ */ (0,
|
|
838
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-3 px-8 py-6 text-center", children: [
|
|
839
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h2", { className: "text-xl font-bold text-text-primary", children: title }),
|
|
840
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "rounded-full bg-surface-muted px-3 py-1 text-xs font-semibold text-text-secondary", children: productLabel }),
|
|
841
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-text-secondary", children: description }),
|
|
842
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mt-2 flex w-full items-center justify-between rounded-xl bg-surface-subtle p-4", children: [
|
|
843
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "text-left", children: [
|
|
844
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-xs uppercase text-text-secondary", children: "Actual" }),
|
|
845
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-lg font-semibold text-text-tertiary line-through", children: currentPrice })
|
|
718
846
|
] }),
|
|
719
|
-
/* @__PURE__ */ (0,
|
|
720
|
-
/* @__PURE__ */ (0,
|
|
721
|
-
/* @__PURE__ */ (0,
|
|
722
|
-
/* @__PURE__ */ (0,
|
|
847
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-text-secondary", children: "\u2192" }),
|
|
848
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "text-right", children: [
|
|
849
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-xs uppercase text-success-dark", children: "Recomendado" }),
|
|
850
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-lg font-semibold text-brand-primary", children: newPrice })
|
|
723
851
|
] })
|
|
724
852
|
] }),
|
|
725
|
-
/* @__PURE__ */ (0,
|
|
726
|
-
/* @__PURE__ */ (0,
|
|
727
|
-
/* @__PURE__ */ (0,
|
|
728
|
-
/* @__PURE__ */ (0,
|
|
853
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex w-full items-center justify-between text-sm", children: [
|
|
854
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "text-left", children: [
|
|
855
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-xs text-text-secondary", children: "Impacto en Margen" }),
|
|
856
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "font-semibold text-success-dark", children: marginImpactLabel })
|
|
729
857
|
] }),
|
|
730
|
-
/* @__PURE__ */ (0,
|
|
731
|
-
/* @__PURE__ */ (0,
|
|
732
|
-
/* @__PURE__ */ (0,
|
|
858
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "text-right", children: [
|
|
859
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-xs text-text-secondary", children: "Volumen Estimado" }),
|
|
860
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "font-semibold text-success-dark", children: volumeImpactLabel })
|
|
733
861
|
] })
|
|
734
862
|
] })
|
|
735
863
|
] }),
|
|
736
|
-
/* @__PURE__ */ (0,
|
|
737
|
-
/* @__PURE__ */ (0,
|
|
738
|
-
/* @__PURE__ */ (0,
|
|
864
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-end gap-4 border-t border-border px-8 py-4", children: [
|
|
865
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { variant: "text", onClick: onClose, children: "Cancelar" }),
|
|
866
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { variant: "primary", onClick: onConfirm, disabled: confirming, children: confirming ? "Aplicando..." : "Confirmar y aplicar" })
|
|
739
867
|
] })
|
|
740
868
|
] }) });
|
|
741
869
|
}
|
|
@@ -747,12 +875,14 @@ function ConfirmDialog({
|
|
|
747
875
|
Badge,
|
|
748
876
|
BoltIcon,
|
|
749
877
|
Button,
|
|
878
|
+
CalendarIcon,
|
|
750
879
|
Card,
|
|
751
880
|
CheckCircleIcon,
|
|
752
881
|
ChevronDownIcon,
|
|
753
882
|
CompetitorRow,
|
|
754
883
|
ConfirmDialog,
|
|
755
884
|
DecisionFactorRow,
|
|
885
|
+
FileDropzone,
|
|
756
886
|
FuelIcon,
|
|
757
887
|
FuelPumpSolidIcon,
|
|
758
888
|
LogOutIcon,
|
|
@@ -763,6 +893,7 @@ function ConfirmDialog({
|
|
|
763
893
|
ProgressBar,
|
|
764
894
|
RefreshIcon,
|
|
765
895
|
SegmentedTabs,
|
|
896
|
+
SelectableCard,
|
|
766
897
|
Sidebar,
|
|
767
898
|
Snackbar,
|
|
768
899
|
StatTile,
|
|
@@ -772,9 +903,11 @@ function ConfirmDialog({
|
|
|
772
903
|
TrendDownIcon,
|
|
773
904
|
TrendUpIcon,
|
|
774
905
|
TrendUpSolidIcon,
|
|
906
|
+
UploadIcon,
|
|
775
907
|
UserCircleIcon,
|
|
776
908
|
WalletIcon,
|
|
777
909
|
WalletSolidIcon,
|
|
910
|
+
WeekdayPicker,
|
|
778
911
|
XIcon,
|
|
779
912
|
colors
|
|
780
913
|
});
|