@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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/icons/index.tsx","../src/atoms/Avatar/Avatar.tsx","../src/atoms/Badge/Badge.tsx","../src/atoms/Button/Button.tsx","../src/atoms/Card/Card.tsx","../src/atoms/ProgressBar/ProgressBar.tsx","../src/atoms/Snackbar/Snackbar.tsx","../src/molecules/SegmentedTabs/SegmentedTabs.tsx","../src/molecules/NavItem/NavItem.tsx","../src/molecules/StatTile/StatTile.tsx","../src/molecules/DecisionFactorRow/DecisionFactorRow.tsx","../src/molecules/CompetitorRow/CompetitorRow.tsx","../src/molecules/PriceRangeSlider/PriceRangeSlider.tsx","../src/molecules/MiniMapCard/MiniMapCard.tsx","../src/organisms/Sidebar/Sidebar.tsx","../src/organisms/TopBar/TopBar.tsx","../src/organisms/ConfirmDialog/ConfirmDialog.tsx"],"sourcesContent":["import type { SVGProps } from \"react\";\n\n/**\n * Custom icon set, in plain SVG (no external library like\n * lucide-react/heroicons) - so packages/ui doesn't depend on anything but\n * React, and there's no separate icon package to install/update.\n *\n * NOTE ON DESIGN FIDELITY: the Figma design ships its own icons exported\n * as images; those assets live on Figma's servers and the URLs expire in\n * ~7 days, so they can't be \"committed\" as-is. These are an equivalent set\n * (same visual meaning - pin, arrow, check, etc.) redrawn by hand in SVG,\n * not an exact pixel-for-pixel copy of the original vector. If the exact\n * Figma set is wanted later on, it can be exported as SVG from the file\n * and used to replace these.\n *\n * All of them accept the standard SVG props (className, etc.) so size/color\n * can be controlled with Tailwind from wherever they're used.\n */\n\ntype IconProps = SVGProps<SVGSVGElement>;\n\nconst base = {\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n strokeWidth: 2,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n};\n\nexport function BoltIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M13 2 4 14h6l-1 8 9-12h-6l1-8Z\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n );\n}\n\nexport function MapPinIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M12 21s7-6.5 7-11.5A7 7 0 0 0 5 9.5C5 14.5 12 21 12 21Z\" />\n <circle cx=\"12\" cy=\"9.5\" r=\"2.25\" />\n </svg>\n );\n}\n\nexport function ChevronDownIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\nexport function ArrowUpIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M12 19V5\" />\n <path d=\"m6 11 6-6 6 6\" />\n </svg>\n );\n}\n\nexport function ArrowDownIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M12 5v14\" />\n <path d=\"m6 13 6 6 6-6\" />\n </svg>\n );\n}\n\nexport function RefreshIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M21 12a9 9 0 1 1-2.64-6.36\" />\n <path d=\"M21 3v6h-6\" />\n </svg>\n );\n}\n\nexport function UserCircleIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n <path d=\"M6.5 19a6 6 0 0 1 11 0\" />\n </svg>\n );\n}\n\nexport function LogOutIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <path d=\"m16 17 5-5-5-5\" />\n <path d=\"M21 12H9\" />\n </svg>\n );\n}\n\nexport function TagIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M20.59 13.41 12 22l-9-9V4a1 1 0 0 1 1-1h9l7.59 7.59a2 2 0 0 1 0 2.82Z\" />\n <circle cx=\"7.5\" cy=\"7.5\" r=\"1.25\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n );\n}\n\nexport function TargetIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n );\n}\n\nexport function TrendUpIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"m3 17 6-6 4 4 8-8\" />\n <path d=\"M15 7h6v6\" />\n </svg>\n );\n}\n\nexport function TrendDownIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"m3 7 6 6 4-4 8 8\" />\n <path d=\"M15 17h6v-6\" />\n </svg>\n );\n}\n\nexport function FuelIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M3 22V6a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16\" />\n <path d=\"M3 12h10\" />\n <path d=\"M13 7h2l3.5 3.5a1.5 1.5 0 0 1 .5 1.1V17a1.5 1.5 0 0 1-3 0v-1\" />\n <path d=\"M2 22h12\" />\n </svg>\n );\n}\n\nexport function WalletIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M3 7a2 2 0 0 1 2-2h13a1 1 0 0 1 1 1v3\" />\n <path d=\"M3 7v11a2 2 0 0 0 2 2h14a1 1 0 0 0 1-1v-4\" />\n <path d=\"M16 13h4a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-4a2 2 0 0 1 0-4Z\" />\n </svg>\n );\n}\n\nexport function CheckCircleIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m8.5 12.5 2.5 2.5 5-5\" />\n </svg>\n );\n}\n\nexport function XIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * Solid/filled icon set, exported directly from the \"Redinamic-tec\" Figma\n * file (the \"Gestion de Precios\" stat cards) - unlike the outline set\n * above, these are pixel-accurate copies of the Figma vectors, not\n * hand-redrawn equivalents. Each keeps its own natural viewBox/aspect\n * ratio instead of being forced into the outline set's 24x24 grid.\n */\n\nexport function FuelPumpSolidIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 33 36\" fill=\"currentColor\" {...props}>\n <path d=\"M0 36V4C0 2.9 0.391667 1.95833 1.175 1.175C1.95833 0.391667 2.9 0 4 0H16C17.1 0 18.0417 0.391667 18.825 1.175C19.6083 1.95833 20 2.9 20 4V18H22C23.1 18 24.0417 18.3917 24.825 19.175C25.6083 19.9583 26 20.9 26 22V31C26 31.5667 26.1917 32.0417 26.575 32.425C26.9583 32.8083 27.4333 33 28 33C28.5667 33 29.0417 32.8083 29.425 32.425C29.8083 32.0417 30 31.5667 30 31V16.6C29.7 16.7667 29.3833 16.875 29.05 16.925C28.7167 16.975 28.3667 17 28 17C26.6 17 25.4167 16.5167 24.45 15.55C23.4833 14.5833 23 13.4 23 12C23 10.9333 23.2917 9.975 23.875 9.125C24.4583 8.275 25.2333 7.66667 26.2 7.3L22 3.1L24.1 1L31.5 8.2C32 8.7 32.375 9.28333 32.625 9.95C32.875 10.6167 33 11.3 33 12V31C33 32.4 32.5167 33.5833 31.55 34.55C30.5833 35.5167 29.4 36 28 36C26.6 36 25.4167 35.5167 24.45 34.55C23.4833 33.5833 23 32.4 23 31V21H20V36H0ZM4 14H16V4H4V14ZM28 14C28.5667 14 29.0417 13.8083 29.425 13.425C29.8083 13.0417 30 12.5667 30 12C30 11.4333 29.8083 10.9583 29.425 10.575C29.0417 10.1917 28.5667 10 28 10C27.4333 10 26.9583 10.1917 26.575 10.575C26.1917 10.9583 26 11.4333 26 12C26 12.5667 26.1917 13.0417 26.575 13.425C26.9583 13.8083 27.4333 14 28 14Z\" />\n </svg>\n );\n}\n\nexport function WalletSolidIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 44 32\" fill=\"currentColor\" {...props}>\n <path d=\"M4 32C2.9 32 1.95833 31.6083 1.175 30.825C0.391667 30.0417 0 29.1 0 28V6H4V28H38V32H4ZM12 24C10.9 24 9.95833 23.6083 9.175 22.825C8.39167 22.0417 8 21.1 8 20V4C8 2.9 8.39167 1.95833 9.175 1.175C9.95833 0.391667 10.9 0 12 0H40C41.1 0 42.0417 0.391667 42.825 1.175C43.6083 1.95833 44 2.9 44 4V20C44 21.1 43.6083 22.0417 42.825 22.825C42.0417 23.6083 41.1 24 40 24H12ZM16 20C16 18.9 15.6083 17.9583 14.825 17.175C14.0417 16.3917 13.1 16 12 16V20H16ZM36 20H40V16C38.9 16 37.9583 16.3917 37.175 17.175C36.3917 17.9583 36 18.9 36 20ZM26 18C27.6667 18 29.0833 17.4167 30.25 16.25C31.4167 15.0833 32 13.6667 32 12C32 10.3333 31.4167 8.91667 30.25 7.75C29.0833 6.58333 27.6667 6 26 6C24.3333 6 22.9167 6.58333 21.75 7.75C20.5833 8.91667 20 10.3333 20 12C20 13.6667 20.5833 15.0833 21.75 16.25C22.9167 17.4167 24.3333 18 26 18ZM12 8C13.1 8 14.0417 7.60833 14.825 6.825C15.6083 6.04167 16 5.1 16 4H12V8ZM40 8V4H36C36 5.1 36.3917 6.04167 37.175 6.825C37.9583 7.60833 38.9 8 40 8Z\" />\n </svg>\n );\n}\n\nexport function TrendUpSolidIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 36 36\" fill=\"currentColor\" {...props}>\n <path d=\"M0 36V32L4 28V36H0ZM8 36V24L12 20V36H8ZM16 36V20L20 24.05V36H16ZM24 36V24.05L28 20.05V36H24ZM32 36V16L36 12V36H32ZM0 25.65V20L14 6L22 14L36 0V5.65L22 19.65L14 11.65L0 25.65Z\" />\n </svg>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport interface AvatarProps {\n /** letter or icon shown inside the circle */\n children: ReactNode;\n /** background color of the circle (hex or another Tailwind class via className) */\n className?: string;\n size?: \"sm\" | \"md\";\n}\n\nconst SIZE_CLASSES: Record<NonNullable<AvatarProps[\"size\"]>, string> = {\n sm: \"size-8 text-sm\",\n md: \"size-10 text-base\",\n};\n\n/**\n * Avatar/initials circle - used both by the session user (sidebar) and\n * each competitor in the \"Nearby Competitors\" list. It does not decide\n * the background OR text color: it receives them via className\n * (e.g. \"bg-danger-bg text-danger-dark\" or \"bg-success text-white\"), so\n * the same component works for any combination without having to touch it.\n */\nexport function Avatar({ children, className = \"\", size = \"md\" }: AvatarProps) {\n return (\n <div\n className={`flex shrink-0 items-center justify-center rounded-full font-bold ${SIZE_CLASSES[size]} ${className}`.trim()}\n >\n {children}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport type BadgeTone = \"success\" | \"danger\" | \"neutral\";\n\nexport interface BadgeProps {\n children: ReactNode;\n tone?: BadgeTone;\n className?: string;\n}\n\nconst TONE_CLASSES: Record<BadgeTone, string> = {\n success: \"bg-success-bg text-success-dark\",\n danger: \"bg-danger-bg text-danger-dark\",\n neutral: \"bg-surface-muted text-text-secondary\",\n};\n\n/**\n * Small pill for deltas (\"+0.7%\", \"-800L\") and status labels. The set of\n * variants (\"tone\") is the only extension point - adding a new tone\n * doesn't touch the rest of the component (Open/Closed).\n */\nexport function Badge({ children, tone = \"neutral\", className = \"\" }: BadgeProps) {\n return (\n <span\n className={`inline-flex items-center rounded-full px-2 py-0.5 text-sm font-semibold ${TONE_CLASSES[tone]} ${className}`.trim()}\n >\n {children}\n </span>\n );\n}\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\n\nexport type ButtonVariant = \"primary\" | \"ghost\" | \"text\";\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n children: ReactNode;\n variant?: ButtonVariant;\n icon?: ReactNode;\n}\n\nconst VARIANT_CLASSES: Record<ButtonVariant, string> = {\n primary:\n \"bg-brand-primary text-white shadow-card hover:bg-brand-sidebarHover disabled:opacity-50 disabled:cursor-not-allowed\",\n ghost:\n \"bg-surface-muted text-text-primary hover:bg-border disabled:opacity-50 disabled:cursor-not-allowed\",\n text: \"bg-transparent text-brand-primary hover:underline disabled:opacity-50 disabled:cursor-not-allowed p-0\",\n};\n\n/**\n * Single button with 3 variants (the ones that appear in the design: the\n * solid blue pill for \"Aplicar precio\"/\"Actualizar datos\", the text link\n * for \"Restablecer a Actual\", and a \"ghost\" variant for future cases).\n * Same as Badge: extending the set of variants doesn't require touching\n * the rest of the component.\n */\nexport function Button({\n children,\n variant = \"primary\",\n icon,\n className = \"\",\n ...rest\n}: ButtonProps) {\n const shape = variant === \"text\" ? \"\" : \"rounded-full px-6 py-2.5\";\n return (\n <button\n className={`inline-flex items-center justify-center gap-2 text-sm font-semibold tracking-[0.14px] transition-colors ${shape} ${VARIANT_CLASSES[variant]} ${className}`.trim()}\n {...rest}\n >\n {icon}\n {children}\n </button>\n );\n}\n","import type { HTMLAttributes, ReactNode } from \"react\";\n\nexport interface CardProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** removes the default padding, for when the content manages its own */\n noPadding?: boolean;\n}\n\n/**\n * Base white, rounded container with a soft shadow - the same pattern\n * that wraps every dashboard block in the design (Simulator Panel,\n * Decision Factors, Nearby Competitors, etc.). Anything specific to a\n * given block goes through composition (children), not new props here -\n * single responsibility principle: Card only knows how to be \"the white box\".\n */\nexport function Card({ children, className = \"\", noPadding = false, ...rest }: CardProps) {\n const padding = noPadding ? \"\" : \"p-6\";\n return (\n <div\n className={`bg-surface-card rounded-xl shadow-card ${padding} ${className}`.trim()}\n {...rest}\n >\n {children}\n </div>\n );\n}\n","export interface ProgressBarProps {\n /** 0 to 100 */\n value: number;\n /** color of the filled bar - Tailwind class, e.g. \"bg-info\" */\n fillClassName?: string;\n /** bar height in px (the design uses 4px in stat tiles and 6px in Decision Factors) */\n heightClassName?: string;\n /** number of equal segments the bar is divided into (the design uses 3 in \"Supply Cost\") */\n segments?: number;\n className?: string;\n}\n\n/**\n * Simple progress bar. It knows nothing about \"what\" it represents\n * (elasticity, margin, inventory...) - that's decided by whoever uses it\n * via `value` and `fillClassName`. Keeping it \"dumb\" is what allows it to\n * be reused in the stat tiles AND in the Decision Factors panel without\n * duplicating code.\n */\nexport function ProgressBar({\n value,\n fillClassName = \"bg-info\",\n heightClassName = \"h-1\",\n segments = 1,\n className = \"\",\n}: ProgressBarProps) {\n const clamped = Math.min(100, Math.max(0, value));\n\n if (segments > 1) {\n return (\n <div className={`flex w-full gap-0.5 overflow-hidden rounded-full bg-border ${heightClassName} ${className}`.trim()}>\n {Array.from({ length: segments }).map((_, i) => {\n const segmentStart = (i / segments) * 100;\n const filled = clamped > segmentStart;\n return (\n <div\n key={i}\n className={`h-full flex-1 ${filled ? fillClassName : \"opacity-20 \" + fillClassName}`}\n />\n );\n })}\n </div>\n );\n }\n\n return (\n <div className={`w-full overflow-hidden rounded-full bg-border ${heightClassName} ${className}`.trim()}>\n <div className={`h-full rounded-full ${fillClassName}`} style={{ width: `${clamped}%` }} />\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { CheckCircleIcon, XIcon } from \"../../icons\";\n\nexport type SnackbarTone = \"success\" | \"danger\" | \"neutral\";\n\nexport interface SnackbarProps {\n message: string;\n tone?: SnackbarTone;\n onClose?: () => void;\n className?: string;\n}\n\nconst TONE_CLASSES: Record<SnackbarTone, string> = {\n success: \"bg-success\",\n danger: \"bg-danger\",\n neutral: \"bg-text-secondary\",\n};\n\n// Same idea as TREND_ICON in CompetitorRow and DELTA_ICON in StatTile: the\n// leading icon is picked from `tone` via a Record, not a branch in the JSX\n// (Open/Closed) - \"neutral\" has no obvious icon, so it renders none.\nconst TONE_ICON: Record<SnackbarTone, ReactNode | null> = {\n success: <CheckCircleIcon className=\"size-5\" />,\n danger: <XIcon className=\"size-5\" />,\n neutral: null,\n};\n\n/**\n * Toast/confirmation bar (e.g. \"Datos de mercado actualizados\n * correctamente\" after a refresh). Fully controlled - it has no timer\n * or visibility state of its own; whoever uses it decides when it's on\n * screen (mount/unmount it, or drive a boolean) and for how long, same\n * philosophy as ConfirmDialog's `open`.\n */\nexport function Snackbar({ message, tone = \"success\", onClose, className = \"\" }: SnackbarProps) {\n return (\n <div\n role=\"status\"\n className={`flex w-full items-center gap-2 rounded-lg px-6 py-3 text-white shadow-card ${TONE_CLASSES[tone]} ${className}`.trim()}\n >\n {TONE_ICON[tone]}\n <p className=\"flex-1 text-sm font-semibold\">{message}</p>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Cerrar\"\n className=\"text-white/80 transition-colors hover:text-white\"\n >\n <XIcon className=\"size-4\" />\n </button>\n </div>\n );\n}\n","export interface SegmentedTabOption {\n value: string;\n label: string;\n}\n\nexport interface SegmentedTabsProps {\n options: SegmentedTabOption[];\n value: string;\n onChange: (value: string) => void;\n className?: string;\n}\n\n/**\n * The Simulator's \"Regular | Premium | Diesel\" control. It receives the\n * options via props instead of having them fixed - the same component\n * works for any list of tabs, in any future screen.\n */\nexport function SegmentedTabs({ options, value, onChange, className = \"\" }: SegmentedTabsProps) {\n return (\n <div\n role=\"tablist\"\n className={`inline-flex items-start gap-0 rounded-lg bg-surface-muted p-1 ${className}`.trim()}\n >\n {options.map((option) => {\n const active = option.value === value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => onChange(option.value)}\n className={`rounded-md px-4 py-1.5 text-sm font-medium transition-colors ${\n active\n ? \"bg-white text-text-primary shadow-tab\"\n : \"text-text-secondary hover:text-text-primary\"\n }`}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport interface NavItemProps {\n icon: ReactNode;\n label: string;\n active?: boolean;\n href?: string;\n}\n\n/**\n * A sidebar navigation link. `active` is the only variant -\n * the rest of the appearance (icon, text) is composed from outside.\n */\nexport function NavItem({ icon, label, active = false, href = \"#\" }: NavItemProps) {\n return (\n <a\n href={href}\n className={`flex w-full items-center gap-3 rounded-xl px-4 py-3 text-base font-bold transition-colors ${\n active ? \"bg-brand-accent text-white\" : \"text-white/70 hover:bg-white/5\"\n }`}\n >\n {icon}\n {label}\n </a>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Badge, type BadgeTone } from \"../../atoms/Badge/Badge\";\nimport { ProgressBar } from \"../../atoms/ProgressBar/ProgressBar\";\nimport { TrendUpIcon, TrendDownIcon } from \"../../icons\";\n\nexport interface StatTileProps {\n icon: ReactNode;\n label: string;\n value: string;\n /** unit suffix rendered next to `value` in a lighter/smaller style, e.g. \"L\" */\n unit?: string;\n /** delta badge text, e.g. \"+2.4% vs prom. diario\" */\n delta?: string;\n deltaTone?: BadgeTone;\n /** optional 0-100 value for the mini bar below (not every tile has one) */\n progressValue?: number;\n progressClassName?: string;\n}\n\n// Same idea as TREND_ICON in CompetitorRow: the icon is picked from the\n// tone via a Record, so adding/adjusting a tone doesn't touch the JSX\n// (Open/Closed) - \"neutral\" has no obvious up/down direction, so it\n// renders no icon, same as CompetitorRow's `stable: null`.\nconst DELTA_ICON: Record<BadgeTone, ReactNode | null> = {\n success: <TrendUpIcon className=\"size-4\" />,\n danger: <TrendDownIcon className=\"size-4\" />,\n neutral: null,\n};\n\n/**\n * One of the result cards (\"Volumen Proyectado\", \"Margen Bruto Proy.\",\n * \"Ganancia Proyectada\"). Purely presentational - it doesn't know where\n * the numbers come from, it just renders them (Dependency Inversion:\n * StatTile depends on props, not on the API or the model).\n */\nexport function StatTile({\n icon,\n label,\n value,\n unit,\n delta,\n deltaTone = \"success\",\n progressValue,\n progressClassName = \"bg-info\",\n}: StatTileProps) {\n return (\n <div className=\"relative flex flex-1 flex-col gap-4 overflow-hidden rounded-2xl bg-surface-card p-6 shadow-card\">\n <span className=\"pointer-events-none absolute right-5 top-5 text-border\">{icon}</span>\n <h3 className=\"max-w-[80%] text-lg font-semibold text-text-secondary\">{label}</h3>\n <p className=\"flex items-baseline gap-1.5\">\n <span className=\"text-4xl font-bold text-text-primary\">{value}</span>\n {unit && <span className=\"text-2xl font-medium text-text-tertiary\">{unit}</span>}\n </p>\n {delta && (\n <Badge tone={deltaTone} className=\"w-fit gap-1\">\n {DELTA_ICON[deltaTone]}\n {delta}\n </Badge>\n )}\n {progressValue !== undefined && (\n <ProgressBar value={progressValue} fillClassName={progressClassName} />\n )}\n </div>\n );\n}\n","import { ProgressBar } from \"../../atoms/ProgressBar/ProgressBar\";\n\nexport interface DecisionFactorRowProps {\n label: string;\n /** the short value on the right, e.g. \"Alta\", \"Estable\", \"65%\" */\n statusText: string;\n statusClassName?: string;\n /** 0-100, the weight/strength of this factor */\n value: number;\n fillClassName?: string;\n segments?: number;\n description: string;\n}\n\n/**\n * A row in the \"Decision Factors\" panel (Elasticity, Supply Cost,\n * Inventory...). Designed to be populated directly from the `factors`\n * array returned by the backend's POST /predict - each factor from the\n * API maps 1 to 1 to one of these rows.\n */\nexport function DecisionFactorRow({\n label,\n statusText,\n statusClassName = \"text-brand-primary\",\n value,\n fillClassName = \"bg-brand-primary\",\n segments = 1,\n description,\n}: DecisionFactorRowProps) {\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <div className=\"flex items-start justify-between\">\n <span className=\"text-sm font-semibold text-text-primary\">{label}</span>\n <span className={`text-sm font-semibold ${statusClassName}`}>{statusText}</span>\n </div>\n <ProgressBar value={value} fillClassName={fillClassName} heightClassName=\"h-1.5\" segments={segments} />\n <p className=\"text-xs leading-relaxed text-text-secondary\">{description}</p>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Avatar } from \"../../atoms/Avatar/Avatar\";\nimport { MapPinIcon, ArrowUpIcon, ArrowDownIcon } from \"../../icons\";\n\nexport type CompetitorTrend = \"up\" | \"down\" | \"stable\";\n\nexport interface CompetitorRowProps {\n name: string;\n /** initial shown in the avatar, e.g. \"O\" */\n avatarLetter: string;\n avatarBgClassName: string;\n avatarTextClassName: string;\n distanceKm: number;\n price: string;\n trend: CompetitorTrend;\n /** e.g. \"Hace 2h\" or \"Sin cambios (24h)\" */\n trendLabel: string;\n}\n\nconst TREND_ICON: Record<CompetitorTrend, ReactNode | null> = {\n up: <ArrowUpIcon className=\"size-4\" />,\n down: <ArrowDownIcon className=\"size-4\" />,\n stable: null,\n};\n\nconst TREND_TEXT_CLASS: Record<CompetitorTrend, string> = {\n up: \"text-success-dark\",\n down: \"text-danger\",\n stable: \"text-text-secondary\",\n};\n\n/**\n * A row in the \"Nearby Competitors\" panel. Designed to be populated\n * directly from the array returned by the backend's GET /competitors.\n */\nexport function CompetitorRow({\n name,\n avatarLetter,\n avatarBgClassName,\n avatarTextClassName,\n distanceKm,\n price,\n trend,\n trendLabel,\n}: CompetitorRowProps) {\n return (\n <div className=\"flex w-full items-center justify-between rounded-lg bg-surface-page p-4\">\n <div className=\"flex items-center gap-4\">\n <Avatar className={`${avatarBgClassName} ${avatarTextClassName}`}>{avatarLetter}</Avatar>\n <div>\n <p className=\"text-sm font-semibold text-text-primary\">{name}</p>\n <div className=\"flex items-center gap-1 text-text-secondary\">\n <MapPinIcon className=\"size-[18px]\" />\n <span className=\"text-xs font-medium tracking-wide\">{distanceKm} km</span>\n </div>\n </div>\n </div>\n <div className=\"text-right\">\n <p className=\"text-2xl font-semibold text-text-primary\">{price}</p>\n <div className={`flex items-center justify-end gap-1 text-xs font-medium ${TREND_TEXT_CLASS[trend]}`}>\n {TREND_ICON[trend]}\n <span>{trendLabel}</span>\n </div>\n </div>\n </div>\n );\n}\n","import type { ChangeEvent } from \"react\";\n\nexport interface PriceRangeSliderProps {\n min: number;\n max: number;\n step?: number;\n /** the value the user is currently dragging */\n value: number;\n onChange: (value: number) => void;\n /** reference \"current\" price, shown at the top left */\n currentPrice: number;\n /** price suggested by the model, shown at the top right */\n recommendedPrice: number;\n currencyFormatter: (value: number) => string;\n}\n\n/**\n * The Simulator's \"Adjust the price to evaluate the projected impact\"\n * slider. Fully controlled (value/onChange come from the parent) - it\n * holds no state of its own, so it doesn't need \"use client\" by itself:\n * it inherits it from the screen component that does manage the state.\n */\nexport function PriceRangeSlider({\n min,\n max,\n step = 0.01,\n value,\n onChange,\n currentPrice,\n recommendedPrice,\n currencyFormatter,\n}: PriceRangeSliderProps) {\n const percent = ((value - min) / (max - min)) * 100;\n\n return (\n <div className=\"relative h-[250px] w-full rounded-xl border border-border/30 bg-surface-page p-6 shadow-tab\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-text-secondary\">PRECIO ACTUAL</p>\n <p className=\"text-2xl font-semibold text-text-primary\">\n {currencyFormatter(currentPrice)}\n </p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm text-brand-primary\">RECOMENDADO</p>\n <p className=\"text-2xl font-semibold text-brand-primary\">\n {currencyFormatter(recommendedPrice)}\n </p>\n </div>\n </div>\n\n <div className=\"absolute left-6 right-6 top-[100px] flex h-24 items-center justify-center\">\n <div\n className=\"pointer-events-none absolute -top-16 -translate-x-1/2 rounded-lg bg-[#2b3134] px-4 py-2 text-sm font-semibold text-white shadow-tooltip\"\n style={{ left: `${percent}%` }}\n >\n {currencyFormatter(value)}\n <span className=\"absolute left-1/2 top-full h-0 w-0 -translate-x-1/2 border-x-8 border-t-8 border-x-transparent border-t-[#2b3134]\" />\n </div>\n\n <div className=\"relative h-2 w-full rounded-full bg-border\">\n <div\n className=\"h-full rounded-full bg-brand-primary\"\n style={{ width: `${percent}%` }}\n />\n <input\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => onChange(Number(event.target.value))}\n aria-label=\"Precio a evaluar\"\n className=\"range-thumb absolute inset-0 h-2 w-full cursor-pointer appearance-none bg-transparent\"\n />\n </div>\n </div>\n\n <div className=\"absolute bottom-6 left-6 right-6 flex items-start justify-between text-sm text-text-secondary\">\n <span>{currencyFormatter(min)}</span>\n <span>{currencyFormatter(max)}</span>\n </div>\n </div>\n );\n}\n","import { MapPinIcon } from \"../../icons\";\n\nexport interface MiniMapCardProps {\n overlayTitle: string;\n /** text already assembled with the count included, e.g. \"Basado en 3 competidores clave\" - don't repeat it in competitorCount. */\n overlayLinkLabel: string;\n /** used only for accessibility (aria-label), not rendered on screen again - overlayLinkLabel already has the number in the right place in the sentence. */\n competitorCount: number;\n}\n\n/**\n * The decorative map card below \"Decision Factors\".\n *\n * *** PLACEHOLDER ***: the design uses a screenshot of a real map; here an\n * abstract SVG map is drawn instead (no dependencies or API key) that\n * occupies the same space and keeps the text overlay identical. Once a\n * real integration (Google Maps / Mapbox) exists with the location and\n * geolocated competitors, this is the component that gets replaced -\n * the rest of the screen doesn't change because it only depends on this\n * interface.\n */\nexport function MiniMapCard({ overlayTitle, overlayLinkLabel, competitorCount }: MiniMapCardProps) {\n return (\n <div className=\"relative h-64 w-full overflow-hidden rounded-xl bg-white p-2 shadow-tab\">\n <div className=\"relative h-full w-full overflow-hidden rounded-lg bg-[#dbe9ee]\">\n <svg viewBox=\"0 0 320 220\" className=\"h-full w-full\" preserveAspectRatio=\"xMidYMid slice\">\n <rect width=\"320\" height=\"220\" fill=\"#dbe9ee\" />\n {Array.from({ length: 9 }).map((_, i) => (\n <line key={`v${i}`} x1={i * 40} y1=\"0\" x2={i * 40} y2=\"220\" stroke=\"#c5dbe2\" strokeWidth=\"1\" />\n ))}\n {Array.from({ length: 7 }).map((_, i) => (\n <line key={`h${i}`} x1=\"0\" y1={i * 36} x2=\"320\" y2={i * 36} stroke=\"#c5dbe2\" strokeWidth=\"1\" />\n ))}\n <circle cx=\"160\" cy=\"110\" r=\"10\" fill=\"#006395\" />\n <circle cx=\"100\" cy=\"70\" r=\"6\" fill=\"#404850\" />\n <circle cx=\"220\" cy=\"60\" r=\"6\" fill=\"#404850\" />\n <circle cx=\"235\" cy=\"150\" r=\"6\" fill=\"#404850\" />\n </svg>\n </div>\n\n <div className=\"absolute inset-x-4 bottom-4 flex flex-col gap-1 rounded-lg bg-surface-page/90 p-3 shadow-modal backdrop-blur-sm\">\n <div className=\"flex items-center gap-1 text-xs font-medium uppercase tracking-wider text-text-primary\">\n <MapPinIcon className=\"size-3.5\" />\n {overlayTitle}\n </div>\n <p className=\"text-sm font-semibold text-brand-primary\" aria-label={`${overlayLinkLabel} - ${competitorCount} en total`}>\n {overlayLinkLabel}\n </p>\n </div>\n </div>\n );\n}\n","import type { ReactNode, ChangeEvent } from \"react\";\nimport { NavItem } from \"../../molecules/NavItem/NavItem\";\nimport { Avatar } from \"../../atoms/Avatar/Avatar\";\nimport { BoltIcon, MapPinIcon, ChevronDownIcon, UserCircleIcon, LogOutIcon } from \"../../icons\";\n\nexport interface SidebarStation {\n id: string;\n label: string;\n}\n\nexport interface SidebarNavItem {\n key: string;\n label: string;\n icon: ReactNode;\n active?: boolean;\n href?: string;\n}\n\nexport interface SidebarUser {\n name: string;\n role: string;\n}\n\nexport interface SidebarProps {\n brandName?: string;\n stations: SidebarStation[];\n selectedStationId: string;\n onSelectStation: (stationId: string) => void;\n navItems: SidebarNavItem[];\n user: SidebarUser;\n onLogout?: () => void;\n}\n\n/**\n * The fixed 260px sidebar. It receives EVERYTHING via props - stations,\n * nav items, user - instead of having anything hardcoded (beyond the\n * default brand name). This is what lets it serve \"multiple users\":\n * whoever uses it decides which user/stations to show, this component\n * just knows how to render them. The station list currently uses a\n * native <select> instead of a custom dropdown - it's the simplest and\n * most accessible option; it can be replaced by a more elaborate menu\n * without touching the rest of the screen.\n */\nexport function Sidebar({\n brandName = \"Redinamic\",\n stations,\n selectedStationId,\n onSelectStation,\n navItems,\n user,\n onLogout,\n}: SidebarProps) {\n return (\n <aside className=\"fixed left-0 top-0 flex h-screen w-[260px] flex-col justify-between bg-brand-sidebar pb-2 pt-8\">\n <div className=\"flex flex-col gap-6 px-4 pb-6\">\n <div className=\"flex items-center gap-3 px-2\">\n <div className=\"flex size-8 items-center justify-center rounded bg-brand-logo\">\n <BoltIcon className=\"size-4 text-brand-sidebar\" />\n </div>\n <span className=\"text-2xl font-semibold tracking-tight text-white\">{brandName}</span>\n </div>\n\n <div className=\"relative\">\n <MapPinIcon className=\"pointer-events-none absolute left-4 top-1/2 size-4 -translate-y-1/2 text-white\" />\n <select\n value={selectedStationId}\n onChange={(event: ChangeEvent<HTMLSelectElement>) => onSelectStation(event.target.value)}\n 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\"\n >\n {stations.map((station) => (\n <option key={station.id} value={station.id} className=\"text-text-primary\">\n {station.label}\n </option>\n ))}\n </select>\n <ChevronDownIcon className=\"pointer-events-none absolute right-3 top-1/2 size-3 -translate-y-1/2 text-white\" />\n </div>\n </div>\n\n <nav className=\"flex flex-1 flex-col gap-1 px-4\">\n {navItems.map((item) => (\n <NavItem key={item.key} icon={item.icon} label={item.label} active={item.active} href={item.href} />\n ))}\n </nav>\n\n <div className=\"border-t border-white/10 px-4 pt-4\">\n <div className=\"flex items-center gap-3 px-4 py-3\">\n <Avatar className=\"bg-brand-primary text-white\">\n <UserCircleIcon className=\"size-4\" />\n </Avatar>\n <div>\n <p className=\"text-sm font-semibold text-white\">{user.name}</p>\n <p className=\"text-xs text-white/60\">{user.role}</p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onLogout}\n 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\"\n >\n <LogOutIcon className=\"size-4\" />\n Cerrar Sesión\n </button>\n </div>\n </aside>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Button } from \"../../atoms/Button/Button\";\nimport { Avatar } from \"../../atoms/Avatar/Avatar\";\nimport { MapPinIcon, RefreshIcon, UserCircleIcon } from \"../../icons\";\n\nexport interface TopBarProps {\n stationName: string;\n lastUpdatedLabel: string;\n onRefresh?: () => void;\n refreshing?: boolean;\n /** optional content rendered between the station info and the refresh button - e.g. product tabs. */\n middleContent?: ReactNode;\n}\n\n/**\n * The fixed top bar (80px, with blur), to the right of the sidebar.\n * It only knows the active station's name and the \"last updated\"\n * state - the concrete data comes from the screen that uses it.\n */\nexport function TopBar({\n stationName,\n lastUpdatedLabel,\n onRefresh,\n refreshing = false,\n middleContent,\n}: TopBarProps) {\n return (\n <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\">\n <div className=\"shrink-0\">\n <div className=\"flex items-center gap-2\">\n <MapPinIcon className=\"size-4 text-text-primary\" />\n <span className=\"text-sm font-semibold text-text-primary\">{stationName}</span>\n </div>\n <div className=\"mt-1 flex items-center gap-2\">\n <span className=\"size-2 rounded-full bg-success-dark\" />\n <span className=\"text-xs font-medium text-text-secondary\">{lastUpdatedLabel}</span>\n </div>\n </div>\n\n {middleContent}\n\n <div className=\"flex shrink-0 items-center gap-4\">\n <Button\n variant=\"primary\"\n icon={<RefreshIcon className={`size-4 ${refreshing ? \"animate-spin\" : \"\"}`} />}\n onClick={onRefresh}\n disabled={refreshing}\n >\n Actualizar datos\n </Button>\n <Avatar className=\"bg-brand-primary text-white\" size=\"sm\">\n <UserCircleIcon className=\"size-4\" />\n </Avatar>\n </div>\n </header>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Button } from \"../../atoms/Button/Button\";\nimport { WalletIcon, XIcon } from \"../../icons\";\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onClose: () => void;\n onConfirm: () => void;\n title: string;\n productLabel: string;\n description: ReactNode;\n currentPrice: string;\n newPrice: string;\n marginImpactLabel: string;\n volumeImpactLabel: string;\n confirming?: boolean;\n}\n\n/**\n * The \"Aplicar precio recomendado\" / \"Confirmar y aplicar\" modal. Fully\n * controlled by `open` - it has no state of its own, so the screen that\n * uses it decides when to show it (e.g. after a successful /simulate\n * response) and what happens on confirm (calling /prices/apply).\n */\nexport function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title,\n productLabel,\n description,\n currentPrice,\n newPrice,\n marginImpactLabel,\n volumeImpactLabel,\n confirming = false,\n}: ConfirmDialogProps) {\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\">\n <div className=\"w-full max-w-md overflow-hidden rounded-2xl bg-white shadow-modal\">\n <div className=\"relative flex items-center justify-center bg-gradient-to-r from-brand-primary to-info-dark py-8\">\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Cerrar\"\n className=\"absolute right-4 top-4 text-white/80 hover:text-white\"\n >\n <XIcon className=\"size-5\" />\n </button>\n <div className=\"flex size-14 items-center justify-center rounded-full bg-white text-brand-primary\">\n <WalletIcon className=\"size-6\" />\n </div>\n </div>\n\n <div className=\"flex flex-col items-center gap-3 px-8 py-6 text-center\">\n <h2 className=\"text-xl font-bold text-text-primary\">{title}</h2>\n <span className=\"rounded-full bg-surface-muted px-3 py-1 text-xs font-semibold text-text-secondary\">\n {productLabel}\n </span>\n <p className=\"text-sm text-text-secondary\">{description}</p>\n\n <div className=\"mt-2 flex w-full items-center justify-between rounded-xl bg-surface-subtle p-4\">\n <div className=\"text-left\">\n <p className=\"text-xs uppercase text-text-secondary\">Actual</p>\n <p className=\"text-lg font-semibold text-text-tertiary line-through\">{currentPrice}</p>\n </div>\n <span className=\"text-text-secondary\">→</span>\n <div className=\"text-right\">\n <p className=\"text-xs uppercase text-success-dark\">Recomendado</p>\n <p className=\"text-lg font-semibold text-brand-primary\">{newPrice}</p>\n </div>\n </div>\n\n <div className=\"flex w-full items-center justify-between text-sm\">\n <div className=\"text-left\">\n <p className=\"text-xs text-text-secondary\">Impacto en Margen</p>\n <p className=\"font-semibold text-success-dark\">{marginImpactLabel}</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-xs text-text-secondary\">Volumen Estimado</p>\n <p className=\"font-semibold text-success-dark\">{volumeImpactLabel}</p>\n </div>\n </div>\n </div>\n\n <div className=\"flex items-center justify-end gap-4 border-t border-border px-8 py-4\">\n <Button variant=\"text\" onClick={onClose}>\n Cancelar\n </Button>\n <Button variant=\"primary\" onClick={onConfirm} disabled={confirming}>\n {confirming ? \"Aplicando...\" : \"Confirmar y aplicar\"}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsxs","jsx","jsx","jsx","jsxs","TONE_CLASSES","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs"]}
1
+ {"version":3,"sources":["../src/icons/index.tsx","../src/atoms/Avatar/Avatar.tsx","../src/atoms/Badge/Badge.tsx","../src/atoms/Button/Button.tsx","../src/atoms/Card/Card.tsx","../src/atoms/ProgressBar/ProgressBar.tsx","../src/atoms/Snackbar/Snackbar.tsx","../src/molecules/SegmentedTabs/SegmentedTabs.tsx","../src/molecules/NavItem/NavItem.tsx","../src/molecules/StatTile/StatTile.tsx","../src/molecules/DecisionFactorRow/DecisionFactorRow.tsx","../src/molecules/CompetitorRow/CompetitorRow.tsx","../src/molecules/PriceRangeSlider/PriceRangeSlider.tsx","../src/molecules/MiniMapCard/MiniMapCard.tsx","../src/molecules/WeekdayPicker/WeekdayPicker.tsx","../src/molecules/SelectableCard/SelectableCard.tsx","../src/molecules/FileDropzone/FileDropzone.tsx","../src/organisms/Sidebar/Sidebar.tsx","../src/organisms/TopBar/TopBar.tsx","../src/organisms/ConfirmDialog/ConfirmDialog.tsx"],"sourcesContent":["import type { SVGProps } from \"react\";\n\n/**\n * Custom icon set, in plain SVG (no external library like\n * lucide-react/heroicons) - so packages/ui doesn't depend on anything but\n * React, and there's no separate icon package to install/update.\n *\n * NOTE ON DESIGN FIDELITY: the Figma design ships its own icons exported\n * as images; those assets live on Figma's servers and the URLs expire in\n * ~7 days, so they can't be \"committed\" as-is. These are an equivalent set\n * (same visual meaning - pin, arrow, check, etc.) redrawn by hand in SVG,\n * not an exact pixel-for-pixel copy of the original vector. If the exact\n * Figma set is wanted later on, it can be exported as SVG from the file\n * and used to replace these.\n *\n * All of them accept the standard SVG props (className, etc.) so size/color\n * can be controlled with Tailwind from wherever they're used.\n */\n\ntype IconProps = SVGProps<SVGSVGElement>;\n\nconst base = {\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n strokeWidth: 2,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n};\n\nexport function BoltIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M13 2 4 14h6l-1 8 9-12h-6l1-8Z\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n );\n}\n\nexport function MapPinIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M12 21s7-6.5 7-11.5A7 7 0 0 0 5 9.5C5 14.5 12 21 12 21Z\" />\n <circle cx=\"12\" cy=\"9.5\" r=\"2.25\" />\n </svg>\n );\n}\n\nexport function ChevronDownIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\nexport function ArrowUpIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M12 19V5\" />\n <path d=\"m6 11 6-6 6 6\" />\n </svg>\n );\n}\n\nexport function ArrowDownIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M12 5v14\" />\n <path d=\"m6 13 6 6 6-6\" />\n </svg>\n );\n}\n\nexport function RefreshIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M21 12a9 9 0 1 1-2.64-6.36\" />\n <path d=\"M21 3v6h-6\" />\n </svg>\n );\n}\n\nexport function UserCircleIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n <path d=\"M6.5 19a6 6 0 0 1 11 0\" />\n </svg>\n );\n}\n\nexport function LogOutIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <path d=\"m16 17 5-5-5-5\" />\n <path d=\"M21 12H9\" />\n </svg>\n );\n}\n\nexport function TagIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M20.59 13.41 12 22l-9-9V4a1 1 0 0 1 1-1h9l7.59 7.59a2 2 0 0 1 0 2.82Z\" />\n <circle cx=\"7.5\" cy=\"7.5\" r=\"1.25\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n );\n}\n\nexport function TargetIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n );\n}\n\nexport function TrendUpIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"m3 17 6-6 4 4 8-8\" />\n <path d=\"M15 7h6v6\" />\n </svg>\n );\n}\n\nexport function TrendDownIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"m3 7 6 6 4-4 8 8\" />\n <path d=\"M15 17h6v-6\" />\n </svg>\n );\n}\n\nexport function FuelIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M3 22V6a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16\" />\n <path d=\"M3 12h10\" />\n <path d=\"M13 7h2l3.5 3.5a1.5 1.5 0 0 1 .5 1.1V17a1.5 1.5 0 0 1-3 0v-1\" />\n <path d=\"M2 22h12\" />\n </svg>\n );\n}\n\nexport function WalletIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M3 7a2 2 0 0 1 2-2h13a1 1 0 0 1 1 1v3\" />\n <path d=\"M3 7v11a2 2 0 0 0 2 2h14a1 1 0 0 0 1-1v-4\" />\n <path d=\"M16 13h4a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-4a2 2 0 0 1 0-4Z\" />\n </svg>\n );\n}\n\nexport function CheckCircleIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m8.5 12.5 2.5 2.5 5-5\" />\n </svg>\n );\n}\n\nexport function CalendarIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" />\n <line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\" />\n <line x1=\"8\" y1=\"3\" x2=\"8\" y2=\"7\" />\n <line x1=\"16\" y1=\"3\" x2=\"16\" y2=\"7\" />\n </svg>\n );\n}\n\nexport function UploadIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M12 16V4\" />\n <path d=\"m7 9 5-5 5 5\" />\n <path d=\"M4 16v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3\" />\n </svg>\n );\n}\n\nexport function XIcon(props: IconProps) {\n return (\n <svg {...base} stroke=\"currentColor\" {...props}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * Solid/filled icon set, exported directly from the \"Redinamic-tec\" Figma\n * file (the \"Gestion de Precios\" stat cards) - unlike the outline set\n * above, these are pixel-accurate copies of the Figma vectors, not\n * hand-redrawn equivalents. Each keeps its own natural viewBox/aspect\n * ratio instead of being forced into the outline set's 24x24 grid.\n */\n\nexport function FuelPumpSolidIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 33 36\" fill=\"currentColor\" {...props}>\n <path d=\"M0 36V4C0 2.9 0.391667 1.95833 1.175 1.175C1.95833 0.391667 2.9 0 4 0H16C17.1 0 18.0417 0.391667 18.825 1.175C19.6083 1.95833 20 2.9 20 4V18H22C23.1 18 24.0417 18.3917 24.825 19.175C25.6083 19.9583 26 20.9 26 22V31C26 31.5667 26.1917 32.0417 26.575 32.425C26.9583 32.8083 27.4333 33 28 33C28.5667 33 29.0417 32.8083 29.425 32.425C29.8083 32.0417 30 31.5667 30 31V16.6C29.7 16.7667 29.3833 16.875 29.05 16.925C28.7167 16.975 28.3667 17 28 17C26.6 17 25.4167 16.5167 24.45 15.55C23.4833 14.5833 23 13.4 23 12C23 10.9333 23.2917 9.975 23.875 9.125C24.4583 8.275 25.2333 7.66667 26.2 7.3L22 3.1L24.1 1L31.5 8.2C32 8.7 32.375 9.28333 32.625 9.95C32.875 10.6167 33 11.3 33 12V31C33 32.4 32.5167 33.5833 31.55 34.55C30.5833 35.5167 29.4 36 28 36C26.6 36 25.4167 35.5167 24.45 34.55C23.4833 33.5833 23 32.4 23 31V21H20V36H0ZM4 14H16V4H4V14ZM28 14C28.5667 14 29.0417 13.8083 29.425 13.425C29.8083 13.0417 30 12.5667 30 12C30 11.4333 29.8083 10.9583 29.425 10.575C29.0417 10.1917 28.5667 10 28 10C27.4333 10 26.9583 10.1917 26.575 10.575C26.1917 10.9583 26 11.4333 26 12C26 12.5667 26.1917 13.0417 26.575 13.425C26.9583 13.8083 27.4333 14 28 14Z\" />\n </svg>\n );\n}\n\nexport function WalletSolidIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 44 32\" fill=\"currentColor\" {...props}>\n <path d=\"M4 32C2.9 32 1.95833 31.6083 1.175 30.825C0.391667 30.0417 0 29.1 0 28V6H4V28H38V32H4ZM12 24C10.9 24 9.95833 23.6083 9.175 22.825C8.39167 22.0417 8 21.1 8 20V4C8 2.9 8.39167 1.95833 9.175 1.175C9.95833 0.391667 10.9 0 12 0H40C41.1 0 42.0417 0.391667 42.825 1.175C43.6083 1.95833 44 2.9 44 4V20C44 21.1 43.6083 22.0417 42.825 22.825C42.0417 23.6083 41.1 24 40 24H12ZM16 20C16 18.9 15.6083 17.9583 14.825 17.175C14.0417 16.3917 13.1 16 12 16V20H16ZM36 20H40V16C38.9 16 37.9583 16.3917 37.175 17.175C36.3917 17.9583 36 18.9 36 20ZM26 18C27.6667 18 29.0833 17.4167 30.25 16.25C31.4167 15.0833 32 13.6667 32 12C32 10.3333 31.4167 8.91667 30.25 7.75C29.0833 6.58333 27.6667 6 26 6C24.3333 6 22.9167 6.58333 21.75 7.75C20.5833 8.91667 20 10.3333 20 12C20 13.6667 20.5833 15.0833 21.75 16.25C22.9167 17.4167 24.3333 18 26 18ZM12 8C13.1 8 14.0417 7.60833 14.825 6.825C15.6083 6.04167 16 5.1 16 4H12V8ZM40 8V4H36C36 5.1 36.3917 6.04167 37.175 6.825C37.9583 7.60833 38.9 8 40 8Z\" />\n </svg>\n );\n}\n\nexport function TrendUpSolidIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 36 36\" fill=\"currentColor\" {...props}>\n <path d=\"M0 36V32L4 28V36H0ZM8 36V24L12 20V36H8ZM16 36V20L20 24.05V36H16ZM24 36V24.05L28 20.05V36H24ZM32 36V16L36 12V36H32ZM0 25.65V20L14 6L22 14L36 0V5.65L22 19.65L14 11.65L0 25.65Z\" />\n </svg>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport interface AvatarProps {\n /** letter or icon shown inside the circle */\n children: ReactNode;\n /** background color of the circle (hex or another Tailwind class via className) */\n className?: string;\n size?: \"sm\" | \"md\";\n}\n\nconst SIZE_CLASSES: Record<NonNullable<AvatarProps[\"size\"]>, string> = {\n sm: \"size-8 text-sm\",\n md: \"size-10 text-base\",\n};\n\n/**\n * Avatar/initials circle - used both by the session user (sidebar) and\n * each competitor in the \"Nearby Competitors\" list. It does not decide\n * the background OR text color: it receives them via className\n * (e.g. \"bg-danger-bg text-danger-dark\" or \"bg-success text-white\"), so\n * the same component works for any combination without having to touch it.\n */\nexport function Avatar({ children, className = \"\", size = \"md\" }: AvatarProps) {\n return (\n <div\n className={`flex shrink-0 items-center justify-center rounded-full font-bold ${SIZE_CLASSES[size]} ${className}`.trim()}\n >\n {children}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport type BadgeTone = \"success\" | \"danger\" | \"neutral\";\n\nexport interface BadgeProps {\n children: ReactNode;\n tone?: BadgeTone;\n className?: string;\n}\n\nconst TONE_CLASSES: Record<BadgeTone, string> = {\n success: \"bg-success-bg text-success-dark\",\n danger: \"bg-danger-bg text-danger-dark\",\n neutral: \"bg-surface-muted text-text-secondary\",\n};\n\n/**\n * Small pill for deltas (\"+0.7%\", \"-800L\") and status labels. The set of\n * variants (\"tone\") is the only extension point - adding a new tone\n * doesn't touch the rest of the component (Open/Closed).\n */\nexport function Badge({ children, tone = \"neutral\", className = \"\" }: BadgeProps) {\n return (\n <span\n className={`inline-flex items-center rounded-full px-2 py-0.5 text-sm font-semibold ${TONE_CLASSES[tone]} ${className}`.trim()}\n >\n {children}\n </span>\n );\n}\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\n\nexport type ButtonVariant = \"primary\" | \"ghost\" | \"text\";\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n children: ReactNode;\n variant?: ButtonVariant;\n icon?: ReactNode;\n}\n\nconst VARIANT_CLASSES: Record<ButtonVariant, string> = {\n primary:\n \"bg-brand-primary text-white shadow-card hover:bg-brand-sidebarHover disabled:opacity-50 disabled:cursor-not-allowed\",\n ghost:\n \"bg-surface-muted text-text-primary hover:bg-border disabled:opacity-50 disabled:cursor-not-allowed\",\n text: \"bg-transparent text-brand-primary hover:underline disabled:opacity-50 disabled:cursor-not-allowed p-0\",\n};\n\n/**\n * Single button with 3 variants (the ones that appear in the design: the\n * solid blue pill for \"Aplicar precio\"/\"Actualizar datos\", the text link\n * for \"Restablecer a Actual\", and a \"ghost\" variant for future cases).\n * Same as Badge: extending the set of variants doesn't require touching\n * the rest of the component.\n */\nexport function Button({\n children,\n variant = \"primary\",\n icon,\n className = \"\",\n ...rest\n}: ButtonProps) {\n const shape = variant === \"text\" ? \"\" : \"rounded-full px-6 py-2.5\";\n return (\n <button\n className={`inline-flex items-center justify-center gap-2 text-sm font-semibold tracking-[0.14px] transition-colors ${shape} ${VARIANT_CLASSES[variant]} ${className}`.trim()}\n {...rest}\n >\n {icon}\n {children}\n </button>\n );\n}\n","import type { HTMLAttributes, ReactNode } from \"react\";\n\nexport interface CardProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n /** removes the default padding, for when the content manages its own */\n noPadding?: boolean;\n}\n\n/**\n * Base white, rounded container with a soft shadow - the same pattern\n * that wraps every dashboard block in the design (Simulator Panel,\n * Decision Factors, Nearby Competitors, etc.). Anything specific to a\n * given block goes through composition (children), not new props here -\n * single responsibility principle: Card only knows how to be \"the white box\".\n */\nexport function Card({ children, className = \"\", noPadding = false, ...rest }: CardProps) {\n const padding = noPadding ? \"\" : \"p-6\";\n return (\n <div\n className={`bg-surface-card rounded-xl shadow-card ${padding} ${className}`.trim()}\n {...rest}\n >\n {children}\n </div>\n );\n}\n","export interface ProgressBarProps {\n /** 0 to 100 */\n value: number;\n /** color of the filled bar - Tailwind class, e.g. \"bg-info\" */\n fillClassName?: string;\n /** bar height in px (the design uses 4px in stat tiles and 6px in Decision Factors) */\n heightClassName?: string;\n /** number of equal segments the bar is divided into (the design uses 3 in \"Supply Cost\") */\n segments?: number;\n className?: string;\n}\n\n/**\n * Simple progress bar. It knows nothing about \"what\" it represents\n * (elasticity, margin, inventory...) - that's decided by whoever uses it\n * via `value` and `fillClassName`. Keeping it \"dumb\" is what allows it to\n * be reused in the stat tiles AND in the Decision Factors panel without\n * duplicating code.\n */\nexport function ProgressBar({\n value,\n fillClassName = \"bg-info\",\n heightClassName = \"h-1\",\n segments = 1,\n className = \"\",\n}: ProgressBarProps) {\n const clamped = Math.min(100, Math.max(0, value));\n\n if (segments > 1) {\n return (\n <div className={`flex w-full gap-0.5 overflow-hidden rounded-full bg-border ${heightClassName} ${className}`.trim()}>\n {Array.from({ length: segments }).map((_, i) => {\n const segmentStart = (i / segments) * 100;\n const filled = clamped > segmentStart;\n return (\n <div\n key={i}\n className={`h-full flex-1 ${filled ? fillClassName : \"opacity-20 \" + fillClassName}`}\n />\n );\n })}\n </div>\n );\n }\n\n return (\n <div className={`w-full overflow-hidden rounded-full bg-border ${heightClassName} ${className}`.trim()}>\n <div className={`h-full rounded-full ${fillClassName}`} style={{ width: `${clamped}%` }} />\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { CheckCircleIcon, XIcon } from \"../../icons\";\n\nexport type SnackbarTone = \"success\" | \"danger\" | \"neutral\";\n\nexport interface SnackbarProps {\n message: string;\n tone?: SnackbarTone;\n onClose?: () => void;\n className?: string;\n}\n\nconst TONE_CLASSES: Record<SnackbarTone, string> = {\n success: \"bg-success\",\n danger: \"bg-danger\",\n neutral: \"bg-text-secondary\",\n};\n\n// Same idea as TREND_ICON in CompetitorRow and DELTA_ICON in StatTile: the\n// leading icon is picked from `tone` via a Record, not a branch in the JSX\n// (Open/Closed) - \"neutral\" has no obvious icon, so it renders none.\nconst TONE_ICON: Record<SnackbarTone, ReactNode | null> = {\n success: <CheckCircleIcon className=\"size-5\" />,\n danger: <XIcon className=\"size-5\" />,\n neutral: null,\n};\n\n/**\n * Toast/confirmation bar (e.g. \"Datos de mercado actualizados\n * correctamente\" after a refresh). Fully controlled - it has no timer\n * or visibility state of its own; whoever uses it decides when it's on\n * screen (mount/unmount it, or drive a boolean) and for how long, same\n * philosophy as ConfirmDialog's `open`.\n */\nexport function Snackbar({ message, tone = \"success\", onClose, className = \"\" }: SnackbarProps) {\n return (\n <div\n role=\"status\"\n className={`flex w-full items-center gap-2 rounded-lg px-6 py-3 text-white shadow-card ${TONE_CLASSES[tone]} ${className}`.trim()}\n >\n {TONE_ICON[tone]}\n <p className=\"flex-1 text-sm font-semibold\">{message}</p>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Cerrar\"\n className=\"text-white/80 transition-colors hover:text-white\"\n >\n <XIcon className=\"size-4\" />\n </button>\n </div>\n );\n}\n","export interface SegmentedTabOption {\n value: string;\n label: string;\n}\n\nexport interface SegmentedTabsProps {\n options: SegmentedTabOption[];\n value: string;\n onChange: (value: string) => void;\n className?: string;\n}\n\n/**\n * The Simulator's \"Regular | Premium | Diesel\" control. It receives the\n * options via props instead of having them fixed - the same component\n * works for any list of tabs, in any future screen.\n */\nexport function SegmentedTabs({ options, value, onChange, className = \"\" }: SegmentedTabsProps) {\n return (\n <div\n role=\"tablist\"\n className={`inline-flex items-start gap-0 rounded-lg bg-surface-muted p-1 ${className}`.trim()}\n >\n {options.map((option) => {\n const active = option.value === value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => onChange(option.value)}\n className={`rounded-md px-4 py-1.5 text-sm font-medium transition-colors ${\n active\n ? \"bg-white text-text-primary shadow-tab\"\n : \"text-text-secondary hover:text-text-primary\"\n }`}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport interface NavItemProps {\n icon: ReactNode;\n label: string;\n active?: boolean;\n href?: string;\n}\n\n/**\n * A sidebar navigation link. `active` is the only variant -\n * the rest of the appearance (icon, text) is composed from outside.\n */\nexport function NavItem({ icon, label, active = false, href = \"#\" }: NavItemProps) {\n return (\n <a\n href={href}\n className={`flex w-full items-center gap-3 rounded-xl px-4 py-3 text-base font-bold transition-colors ${\n active ? \"bg-brand-accent text-white\" : \"text-white/70 hover:bg-white/5\"\n }`}\n >\n {icon}\n {label}\n </a>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Badge, type BadgeTone } from \"../../atoms/Badge/Badge\";\nimport { ProgressBar } from \"../../atoms/ProgressBar/ProgressBar\";\nimport { TrendUpIcon, TrendDownIcon } from \"../../icons\";\n\nexport interface StatTileProps {\n icon: ReactNode;\n label: string;\n value: string;\n /** unit suffix rendered next to `value` in a lighter/smaller style, e.g. \"L\" */\n unit?: string;\n /** delta badge text, e.g. \"+2.4% vs prom. diario\" */\n delta?: string;\n deltaTone?: BadgeTone;\n /** optional 0-100 value for the mini bar below (not every tile has one) */\n progressValue?: number;\n progressClassName?: string;\n}\n\n// Same idea as TREND_ICON in CompetitorRow: the icon is picked from the\n// tone via a Record, so adding/adjusting a tone doesn't touch the JSX\n// (Open/Closed) - \"neutral\" has no obvious up/down direction, so it\n// renders no icon, same as CompetitorRow's `stable: null`.\nconst DELTA_ICON: Record<BadgeTone, ReactNode | null> = {\n success: <TrendUpIcon className=\"size-4\" />,\n danger: <TrendDownIcon className=\"size-4\" />,\n neutral: null,\n};\n\n/**\n * One of the result cards (\"Volumen Proyectado\", \"Margen Bruto Proy.\",\n * \"Ganancia Proyectada\"). Purely presentational - it doesn't know where\n * the numbers come from, it just renders them (Dependency Inversion:\n * StatTile depends on props, not on the API or the model).\n */\nexport function StatTile({\n icon,\n label,\n value,\n unit,\n delta,\n deltaTone = \"success\",\n progressValue,\n progressClassName = \"bg-info\",\n}: StatTileProps) {\n return (\n <div className=\"relative flex flex-1 flex-col gap-4 overflow-hidden rounded-2xl bg-surface-card p-6 shadow-card\">\n <span className=\"pointer-events-none absolute right-5 top-5 text-border\">{icon}</span>\n <h3 className=\"max-w-[80%] text-lg font-semibold text-text-secondary\">{label}</h3>\n <p className=\"flex items-baseline gap-1.5\">\n <span className=\"text-4xl font-bold text-text-primary\">{value}</span>\n {unit && <span className=\"text-2xl font-medium text-text-tertiary\">{unit}</span>}\n </p>\n {delta && (\n <Badge tone={deltaTone} className=\"w-fit gap-1\">\n {DELTA_ICON[deltaTone]}\n {delta}\n </Badge>\n )}\n {progressValue !== undefined && (\n <ProgressBar value={progressValue} fillClassName={progressClassName} />\n )}\n </div>\n );\n}\n","import { ProgressBar } from \"../../atoms/ProgressBar/ProgressBar\";\n\nexport interface DecisionFactorRowProps {\n label: string;\n /** the short value on the right, e.g. \"Alta\", \"Estable\", \"65%\" */\n statusText: string;\n statusClassName?: string;\n /** 0-100, the weight/strength of this factor */\n value: number;\n fillClassName?: string;\n segments?: number;\n description: string;\n}\n\n/**\n * A row in the \"Decision Factors\" panel (Elasticity, Supply Cost,\n * Inventory...). Designed to be populated directly from the `factors`\n * array returned by the backend's POST /predict - each factor from the\n * API maps 1 to 1 to one of these rows.\n */\nexport function DecisionFactorRow({\n label,\n statusText,\n statusClassName = \"text-brand-primary\",\n value,\n fillClassName = \"bg-brand-primary\",\n segments = 1,\n description,\n}: DecisionFactorRowProps) {\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <div className=\"flex items-start justify-between\">\n <span className=\"text-sm font-semibold text-text-primary\">{label}</span>\n <span className={`text-sm font-semibold ${statusClassName}`}>{statusText}</span>\n </div>\n <ProgressBar value={value} fillClassName={fillClassName} heightClassName=\"h-1.5\" segments={segments} />\n <p className=\"text-xs leading-relaxed text-text-secondary\">{description}</p>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Avatar } from \"../../atoms/Avatar/Avatar\";\nimport { MapPinIcon, ArrowUpIcon, ArrowDownIcon } from \"../../icons\";\n\nexport type CompetitorTrend = \"up\" | \"down\" | \"stable\";\n\nexport interface CompetitorRowProps {\n name: string;\n /** initial shown in the avatar, e.g. \"O\" */\n avatarLetter: string;\n avatarBgClassName: string;\n avatarTextClassName: string;\n distanceKm: number;\n price: string;\n trend: CompetitorTrend;\n /** e.g. \"Hace 2h\" or \"Sin cambios (24h)\" */\n trendLabel: string;\n}\n\nconst TREND_ICON: Record<CompetitorTrend, ReactNode | null> = {\n up: <ArrowUpIcon className=\"size-4\" />,\n down: <ArrowDownIcon className=\"size-4\" />,\n stable: null,\n};\n\nconst TREND_TEXT_CLASS: Record<CompetitorTrend, string> = {\n up: \"text-success-dark\",\n down: \"text-danger\",\n stable: \"text-text-secondary\",\n};\n\n/**\n * A row in the \"Nearby Competitors\" panel. Designed to be populated\n * directly from the array returned by the backend's GET /competitors.\n */\nexport function CompetitorRow({\n name,\n avatarLetter,\n avatarBgClassName,\n avatarTextClassName,\n distanceKm,\n price,\n trend,\n trendLabel,\n}: CompetitorRowProps) {\n return (\n <div className=\"flex w-full items-center justify-between rounded-lg bg-surface-page p-4\">\n <div className=\"flex items-center gap-4\">\n <Avatar className={`${avatarBgClassName} ${avatarTextClassName}`}>{avatarLetter}</Avatar>\n <div>\n <p className=\"text-sm font-semibold text-text-primary\">{name}</p>\n <div className=\"flex items-center gap-1 text-text-secondary\">\n <MapPinIcon className=\"size-[18px]\" />\n <span className=\"text-xs font-medium tracking-wide\">{distanceKm} km</span>\n </div>\n </div>\n </div>\n <div className=\"text-right\">\n <p className=\"text-2xl font-semibold text-text-primary\">{price}</p>\n <div className={`flex items-center justify-end gap-1 text-xs font-medium ${TREND_TEXT_CLASS[trend]}`}>\n {TREND_ICON[trend]}\n <span>{trendLabel}</span>\n </div>\n </div>\n </div>\n );\n}\n","import type { ChangeEvent } from \"react\";\n\nexport interface PriceRangeSliderProps {\n min: number;\n max: number;\n step?: number;\n /** the value the user is currently dragging */\n value: number;\n onChange: (value: number) => void;\n /** reference \"current\" price, shown at the top left */\n currentPrice: number;\n /** price suggested by the model, shown at the top right */\n recommendedPrice: number;\n currencyFormatter: (value: number) => string;\n}\n\n/**\n * The Simulator's \"Adjust the price to evaluate the projected impact\"\n * slider. Fully controlled (value/onChange come from the parent) - it\n * holds no state of its own, so it doesn't need \"use client\" by itself:\n * it inherits it from the screen component that does manage the state.\n */\nexport function PriceRangeSlider({\n min,\n max,\n step = 0.01,\n value,\n onChange,\n currentPrice,\n recommendedPrice,\n currencyFormatter,\n}: PriceRangeSliderProps) {\n const percent = ((value - min) / (max - min)) * 100;\n\n return (\n <div className=\"relative h-[250px] w-full rounded-xl border border-border/30 bg-surface-page p-6 shadow-tab\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-text-secondary\">PRECIO ACTUAL</p>\n <p className=\"text-2xl font-semibold text-text-primary\">\n {currencyFormatter(currentPrice)}\n </p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm text-brand-primary\">RECOMENDADO</p>\n <p className=\"text-2xl font-semibold text-brand-primary\">\n {currencyFormatter(recommendedPrice)}\n </p>\n </div>\n </div>\n\n <div className=\"absolute left-6 right-6 top-[100px] flex h-24 items-center justify-center\">\n <div\n className=\"pointer-events-none absolute -top-16 -translate-x-1/2 rounded-lg bg-[#2b3134] px-4 py-2 text-sm font-semibold text-white shadow-tooltip\"\n style={{ left: `${percent}%` }}\n >\n {currencyFormatter(value)}\n <span className=\"absolute left-1/2 top-full h-0 w-0 -translate-x-1/2 border-x-8 border-t-8 border-x-transparent border-t-[#2b3134]\" />\n </div>\n\n <div className=\"relative h-2 w-full rounded-full bg-border\">\n <div\n className=\"h-full rounded-full bg-brand-primary\"\n style={{ width: `${percent}%` }}\n />\n <input\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => onChange(Number(event.target.value))}\n aria-label=\"Precio a evaluar\"\n className=\"range-thumb absolute inset-0 h-2 w-full cursor-pointer appearance-none bg-transparent\"\n />\n </div>\n </div>\n\n <div className=\"absolute bottom-6 left-6 right-6 flex items-start justify-between text-sm text-text-secondary\">\n <span>{currencyFormatter(min)}</span>\n <span>{currencyFormatter(max)}</span>\n </div>\n </div>\n );\n}\n","import { MapPinIcon } from \"../../icons\";\n\nexport interface MiniMapCardProps {\n overlayTitle: string;\n /** text already assembled with the count included, e.g. \"Basado en 3 competidores clave\" - don't repeat it in competitorCount. */\n overlayLinkLabel: string;\n /** used only for accessibility (aria-label), not rendered on screen again - overlayLinkLabel already has the number in the right place in the sentence. */\n competitorCount: number;\n}\n\n/**\n * The decorative map card below \"Decision Factors\".\n *\n * *** PLACEHOLDER ***: the design uses a screenshot of a real map; here an\n * abstract SVG map is drawn instead (no dependencies or API key) that\n * occupies the same space and keeps the text overlay identical. Once a\n * real integration (Google Maps / Mapbox) exists with the location and\n * geolocated competitors, this is the component that gets replaced -\n * the rest of the screen doesn't change because it only depends on this\n * interface.\n */\nexport function MiniMapCard({ overlayTitle, overlayLinkLabel, competitorCount }: MiniMapCardProps) {\n return (\n <div className=\"relative h-64 w-full overflow-hidden rounded-xl bg-white p-2 shadow-tab\">\n <div className=\"relative h-full w-full overflow-hidden rounded-lg bg-[#dbe9ee]\">\n <svg viewBox=\"0 0 320 220\" className=\"h-full w-full\" preserveAspectRatio=\"xMidYMid slice\">\n <rect width=\"320\" height=\"220\" fill=\"#dbe9ee\" />\n {Array.from({ length: 9 }).map((_, i) => (\n <line key={`v${i}`} x1={i * 40} y1=\"0\" x2={i * 40} y2=\"220\" stroke=\"#c5dbe2\" strokeWidth=\"1\" />\n ))}\n {Array.from({ length: 7 }).map((_, i) => (\n <line key={`h${i}`} x1=\"0\" y1={i * 36} x2=\"320\" y2={i * 36} stroke=\"#c5dbe2\" strokeWidth=\"1\" />\n ))}\n <circle cx=\"160\" cy=\"110\" r=\"10\" fill=\"#006395\" />\n <circle cx=\"100\" cy=\"70\" r=\"6\" fill=\"#404850\" />\n <circle cx=\"220\" cy=\"60\" r=\"6\" fill=\"#404850\" />\n <circle cx=\"235\" cy=\"150\" r=\"6\" fill=\"#404850\" />\n </svg>\n </div>\n\n <div className=\"absolute inset-x-4 bottom-4 flex flex-col gap-1 rounded-lg bg-surface-page/90 p-3 shadow-modal backdrop-blur-sm\">\n <div className=\"flex items-center gap-1 text-xs font-medium uppercase tracking-wider text-text-primary\">\n <MapPinIcon className=\"size-3.5\" />\n {overlayTitle}\n </div>\n <p className=\"text-sm font-semibold text-brand-primary\" aria-label={`${overlayLinkLabel} - ${competitorCount} en total`}>\n {overlayLinkLabel}\n </p>\n </div>\n </div>\n );\n}\n","export interface WeekdayPickerProps {\n /** 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. */\n labels: readonly string[];\n /** Day indices currently toggled on. */\n selected: readonly number[];\n onToggle: (day: number) => void;\n className?: string;\n}\n\n/**\n * Circular day-of-week toggle row - previously hand-duplicated (with\n * slightly different styles) in redisplay-web's QuoteWizard and\n * RecurringPlansClient. Generic on purpose: the caller owns the labels\n * (language/order) and which days start selected.\n */\nexport function WeekdayPicker({ labels, selected, onToggle, className = \"\" }: WeekdayPickerProps) {\n return (\n <div role=\"group\" className={`flex flex-wrap gap-2 ${className}`.trim()}>\n {labels.map((label, day) => {\n const active = selected.includes(day);\n return (\n <button\n key={day}\n type=\"button\"\n aria-pressed={active}\n onClick={() => onToggle(day)}\n className={`flex h-10 w-10 items-center justify-center rounded-full border text-xs font-semibold transition-colors ${\n active ? \"border-brand-primary bg-brand-primary text-white\" : \"border-border text-text-secondary hover:bg-surface-subtle\"\n }`}\n >\n {label}\n </button>\n );\n })}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport interface SelectableCardProps {\n icon?: ReactNode;\n title: string;\n subtitle?: string;\n selected?: boolean;\n onClick: () => void;\n className?: string;\n}\n\n/**\n * Generic clickable \"pick one of these\" card: an icon chip, a title, an\n * optional subtitle, and a selected state. Not tied to any domain (not\n * \"StationCard\") - meant for any picker across the 3 apps (redisplay-web's\n * station picker today, any future list-of-options screen tomorrow).\n */\nexport function SelectableCard({ icon, title, subtitle, selected = false, onClick, className = \"\" }: SelectableCardProps) {\n return (\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={onClick}\n className={`flex w-full items-center gap-3 rounded-xl border p-4 text-left transition-colors ${\n selected ? \"border-brand-primary bg-brand-primary/5\" : \"border-border hover:bg-surface-subtle\"\n } ${className}`.trim()}\n >\n {icon && (\n <span\n className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-full ${\n selected ? \"bg-brand-primary text-white\" : \"bg-surface-muted text-text-secondary\"\n }`}\n >\n {icon}\n </span>\n )}\n <span className=\"flex flex-col\">\n <span className=\"font-medium text-text-primary\">{title}</span>\n {subtitle && <span className=\"text-sm text-text-tertiary\">{subtitle}</span>}\n </span>\n </button>\n );\n}\n","import { useRef, useState, type DragEvent, type KeyboardEvent } from \"react\";\nimport { UploadIcon } from \"../../icons\";\n\nexport interface FileDropzoneProps {\n accept?: string;\n onFileSelected: (file: File | null) => void;\n /** Name of the currently-selected file, if any - the caller owns the File itself, this component is stateless about it. */\n selectedFileName?: string | null;\n label?: string;\n hint?: string;\n className?: string;\n}\n\n/**\n * Restyled file picker: a dashed dropzone (click or drag-and-drop) instead\n * of a bare `<input type=\"file\">`. The native input still does the actual\n * work (hidden, triggered via the visible box) - this only changes how it\n * looks, not the underlying file-selection contract.\n */\nexport function FileDropzone({\n accept,\n onFileSelected,\n selectedFileName,\n label = \"Arrastra tu archivo aquí, o haz clic para elegirlo\",\n hint,\n className = \"\",\n}: FileDropzoneProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n const [dragActive, setDragActive] = useState(false);\n\n function openPicker() {\n inputRef.current?.click();\n }\n\n function handleKeyDown(e: KeyboardEvent<HTMLDivElement>) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n openPicker();\n }\n }\n\n function handleDrop(e: DragEvent<HTMLDivElement>) {\n e.preventDefault();\n setDragActive(false);\n onFileSelected(e.dataTransfer.files?.[0] ?? null);\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={openPicker}\n onKeyDown={handleKeyDown}\n onDragOver={(e) => {\n e.preventDefault();\n setDragActive(true);\n }}\n onDragLeave={() => setDragActive(false)}\n onDrop={handleDrop}\n 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 ${\n dragActive ? \"border-brand-primary bg-brand-primary/5\" : \"border-border hover:border-brand-primary/60\"\n } ${className}`.trim()}\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n className=\"hidden\"\n onChange={(e) => onFileSelected(e.target.files?.[0] ?? null)}\n />\n <UploadIcon className={`size-6 ${dragActive ? \"text-brand-primary\" : \"text-text-tertiary\"}`} />\n {selectedFileName ? (\n <p className=\"text-sm font-medium text-text-primary\">{selectedFileName}</p>\n ) : (\n <>\n <p className=\"text-sm font-medium text-text-primary\">{label}</p>\n {hint && <p className=\"text-xs text-text-tertiary\">{hint}</p>}\n </>\n )}\n </div>\n );\n}\n","import type { ReactNode, ChangeEvent } from \"react\";\nimport { NavItem } from \"../../molecules/NavItem/NavItem\";\nimport { Avatar } from \"../../atoms/Avatar/Avatar\";\nimport { BoltIcon, MapPinIcon, ChevronDownIcon, UserCircleIcon, LogOutIcon } from \"../../icons\";\n\nexport interface SidebarStation {\n id: string;\n label: string;\n}\n\nexport interface SidebarNavItem {\n key: string;\n label: string;\n icon: ReactNode;\n active?: boolean;\n href?: string;\n}\n\nexport interface SidebarUser {\n name: string;\n role: string;\n}\n\nexport interface SidebarProps {\n brandName?: string;\n stations: SidebarStation[];\n selectedStationId: string;\n onSelectStation: (stationId: string) => void;\n navItems: SidebarNavItem[];\n user: SidebarUser;\n onLogout?: () => void;\n}\n\n/**\n * The fixed 260px sidebar. It receives EVERYTHING via props - stations,\n * nav items, user - instead of having anything hardcoded (beyond the\n * default brand name). This is what lets it serve \"multiple users\":\n * whoever uses it decides which user/stations to show, this component\n * just knows how to render them. The station list currently uses a\n * native <select> instead of a custom dropdown - it's the simplest and\n * most accessible option; it can be replaced by a more elaborate menu\n * without touching the rest of the screen.\n */\nexport function Sidebar({\n brandName = \"Redinamic\",\n stations,\n selectedStationId,\n onSelectStation,\n navItems,\n user,\n onLogout,\n}: SidebarProps) {\n return (\n <aside className=\"fixed left-0 top-0 flex h-screen w-[260px] flex-col justify-between bg-brand-sidebar pb-2 pt-8\">\n <div className=\"flex flex-col gap-6 px-4 pb-6\">\n <div className=\"flex items-center gap-3 px-2\">\n <div className=\"flex size-8 items-center justify-center rounded bg-brand-logo\">\n <BoltIcon className=\"size-4 text-brand-sidebar\" />\n </div>\n <span className=\"text-2xl font-semibold tracking-tight text-white\">{brandName}</span>\n </div>\n\n <div className=\"relative\">\n <MapPinIcon className=\"pointer-events-none absolute left-4 top-1/2 size-4 -translate-y-1/2 text-white\" />\n <select\n value={selectedStationId}\n onChange={(event: ChangeEvent<HTMLSelectElement>) => onSelectStation(event.target.value)}\n 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\"\n >\n {stations.map((station) => (\n <option key={station.id} value={station.id} className=\"text-text-primary\">\n {station.label}\n </option>\n ))}\n </select>\n <ChevronDownIcon className=\"pointer-events-none absolute right-3 top-1/2 size-3 -translate-y-1/2 text-white\" />\n </div>\n </div>\n\n <nav className=\"flex flex-1 flex-col gap-1 px-4\">\n {navItems.map((item) => (\n <NavItem key={item.key} icon={item.icon} label={item.label} active={item.active} href={item.href} />\n ))}\n </nav>\n\n <div className=\"border-t border-white/10 px-4 pt-4\">\n <div className=\"flex items-center gap-3 px-4 py-3\">\n <Avatar className=\"bg-brand-primary text-white\">\n <UserCircleIcon className=\"size-4\" />\n </Avatar>\n <div>\n <p className=\"text-sm font-semibold text-white\">{user.name}</p>\n <p className=\"text-xs text-white/60\">{user.role}</p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onLogout}\n 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\"\n >\n <LogOutIcon className=\"size-4\" />\n Cerrar Sesión\n </button>\n </div>\n </aside>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Button } from \"../../atoms/Button/Button\";\nimport { Avatar } from \"../../atoms/Avatar/Avatar\";\nimport { MapPinIcon, RefreshIcon, UserCircleIcon } from \"../../icons\";\n\nexport interface TopBarProps {\n stationName: string;\n lastUpdatedLabel: string;\n onRefresh?: () => void;\n refreshing?: boolean;\n /** optional content rendered between the station info and the refresh button - e.g. product tabs. */\n middleContent?: ReactNode;\n}\n\n/**\n * The fixed top bar (80px, with blur), to the right of the sidebar.\n * It only knows the active station's name and the \"last updated\"\n * state - the concrete data comes from the screen that uses it.\n */\nexport function TopBar({\n stationName,\n lastUpdatedLabel,\n onRefresh,\n refreshing = false,\n middleContent,\n}: TopBarProps) {\n return (\n <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\">\n <div className=\"shrink-0\">\n <div className=\"flex items-center gap-2\">\n <MapPinIcon className=\"size-4 text-text-primary\" />\n <span className=\"text-sm font-semibold text-text-primary\">{stationName}</span>\n </div>\n <div className=\"mt-1 flex items-center gap-2\">\n <span className=\"size-2 rounded-full bg-success-dark\" />\n <span className=\"text-xs font-medium text-text-secondary\">{lastUpdatedLabel}</span>\n </div>\n </div>\n\n {middleContent}\n\n <div className=\"flex shrink-0 items-center gap-4\">\n <Button\n variant=\"primary\"\n icon={<RefreshIcon className={`size-4 ${refreshing ? \"animate-spin\" : \"\"}`} />}\n onClick={onRefresh}\n disabled={refreshing}\n >\n Actualizar datos\n </Button>\n <Avatar className=\"bg-brand-primary text-white\" size=\"sm\">\n <UserCircleIcon className=\"size-4\" />\n </Avatar>\n </div>\n </header>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Button } from \"../../atoms/Button/Button\";\nimport { WalletIcon, XIcon } from \"../../icons\";\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onClose: () => void;\n onConfirm: () => void;\n title: string;\n productLabel: string;\n description: ReactNode;\n currentPrice: string;\n newPrice: string;\n marginImpactLabel: string;\n volumeImpactLabel: string;\n confirming?: boolean;\n}\n\n/**\n * The \"Aplicar precio recomendado\" / \"Confirmar y aplicar\" modal. Fully\n * controlled by `open` - it has no state of its own, so the screen that\n * uses it decides when to show it (e.g. after a successful /simulate\n * response) and what happens on confirm (calling /prices/apply).\n */\nexport function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title,\n productLabel,\n description,\n currentPrice,\n newPrice,\n marginImpactLabel,\n volumeImpactLabel,\n confirming = false,\n}: ConfirmDialogProps) {\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\">\n <div className=\"w-full max-w-md overflow-hidden rounded-2xl bg-white shadow-modal\">\n <div className=\"relative flex items-center justify-center bg-gradient-to-r from-brand-primary to-info-dark py-8\">\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Cerrar\"\n className=\"absolute right-4 top-4 text-white/80 hover:text-white\"\n >\n <XIcon className=\"size-5\" />\n </button>\n <div className=\"flex size-14 items-center justify-center rounded-full bg-white text-brand-primary\">\n <WalletIcon className=\"size-6\" />\n </div>\n </div>\n\n <div className=\"flex flex-col items-center gap-3 px-8 py-6 text-center\">\n <h2 className=\"text-xl font-bold text-text-primary\">{title}</h2>\n <span className=\"rounded-full bg-surface-muted px-3 py-1 text-xs font-semibold text-text-secondary\">\n {productLabel}\n </span>\n <p className=\"text-sm text-text-secondary\">{description}</p>\n\n <div className=\"mt-2 flex w-full items-center justify-between rounded-xl bg-surface-subtle p-4\">\n <div className=\"text-left\">\n <p className=\"text-xs uppercase text-text-secondary\">Actual</p>\n <p className=\"text-lg font-semibold text-text-tertiary line-through\">{currentPrice}</p>\n </div>\n <span className=\"text-text-secondary\">→</span>\n <div className=\"text-right\">\n <p className=\"text-xs uppercase text-success-dark\">Recomendado</p>\n <p className=\"text-lg font-semibold text-brand-primary\">{newPrice}</p>\n </div>\n </div>\n\n <div className=\"flex w-full items-center justify-between text-sm\">\n <div className=\"text-left\">\n <p className=\"text-xs text-text-secondary\">Impacto en Margen</p>\n <p className=\"font-semibold text-success-dark\">{marginImpactLabel}</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-xs text-text-secondary\">Volumen Estimado</p>\n <p className=\"font-semibold text-success-dark\">{volumeImpactLabel}</p>\n </div>\n </div>\n </div>\n\n <div className=\"flex items-center justify-end gap-4 border-t border-border px-8 py-4\">\n <Button variant=\"text\" onClick={onClose}>\n Cancelar\n </Button>\n <Button variant=\"primary\" onClick={onConfirm} disabled={confirming}>\n {confirming ? \"Aplicando...\" : \"Confirmar y aplicar\"}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsxs","jsx","jsx","jsx","jsxs","TONE_CLASSES","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moeve-ui/ui",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Moeve UI component library - a base for future projects, not just this front end.",
5
5
  "repository": {
6
6
  "type": "git",