"use client"; // @ts-nocheck - legacy design token bare names fixed by import below. // @ts-nocheck - pre-existing legacy design token (bare 'colors' etc) issues in shared components. import Link from "next/link"; import { forwardRef, HTMLAttributes } from "react"; import { clsx } from "clsx"; import { designSystem, colors, spacing } from "@/lib/design-system"; const { shadows } = designSystem; // radius/typography etc reserved // ============================================================================= // Type Helpers for Card/Link Prop Compatibility // ============================================================================= // Helper to safely cast hover style values function getHoverValue(obj: { hover?: Record } | undefined, key: string, fallback: string = ''): T | string { return (obj && obj.hover && (obj.hover as Record)[key]) || fallback; } // ============================================================================= // Card Variants // ============================================================================= export type CardVariant = "primary" | "secondary" | "glass" | "elevated" | "bordered"; export interface CardProps extends Omit, "onClick"> { variant?: CardVariant; href?: string; onClick?: (event: React.MouseEvent) => void; hoverable?: boolean; padding?: "none" | "small" | "medium" | "large"; fullWidthOnMobile?: boolean; } // ============================================================================= // SharedCard Component // ============================================================================= export const SharedCard = forwardRef( ( { variant = "secondary", href, onClick, hoverable = true, padding = "medium", fullWidthOnMobile = true, className, children, ...props }, ref, ) => { // Map variant to styles const variantStyles = { primary: { background: "transparent", border: colors.borderSubtle, boxShadow: "none", hover: { background: "transparent", border: colors.borderSubtle, boxShadow: shadows.lg, transform: designSystem.animation.hover.scale, }, }, secondary: { background: colors.bgGlass, border: colors.borderSubtle, boxShadow: "none", hover: { background: colors.bgElevated, border: colors.borderMedium, boxShadow: "none", }, }, glass: { background: colors.bgGlass, border: colors.borderSubtle, boxShadow: shadows.sm, hover: { background: colors.bgGlassHover, border: colors.borderMedium, boxShadow: shadows.md, }, }, elevated: { background: colors.bgElevated, border: colors.borderSubtle, boxShadow: shadows.sm, hover: { background: colors.bgSurface, border: colors.borderMedium, boxShadow: shadows.md, }, }, bordered: { background: colors.bgGlass, border: colors.borderSubtle, boxShadow: "none", hover: { background: colors.bgElevated, border: colors.borderMedium, boxShadow: "none", }, }, }; const style = variantStyles[variant]; // Map padding to values const paddingMap = { none: "", small: spacing.card.paddingSmall, // p-4 = 16px medium: spacing.card.padding, // p-7 = 28px large: "24px", // p-6 }; const paddingValue = paddingMap[padding]; // Build class string const baseClasses = clsx( "rounded-xl", // 20px radius from home "border", "transition-all", "duration-150", fullWidthOnMobile && "w-full", paddingValue && `p-[${paddingValue}]`, className, ); const normalClasses = clsx( baseClasses, style.background && `bg-[${style.background}]`, style.border && `border-[${style.border}]`, style.boxShadow && `shadow-[${style.boxShadow}]`, ); // Type-safe hover class construction const hoverTransform = hoverable && style.hover ? getHoverValue(style, 'transform') : undefined; const hoverShadow = hoverable && style.hover ? getHoverValue(style, 'boxShadow') : undefined; const hoverBg = hoverable && style.hover ? getHoverValue(style, 'background') : undefined; const hoverBorder = hoverable && style.hover ? getHoverValue(style, 'border') : undefined; const hoverClasses = clsx( hoverable && "hover:scale-[1.01]", hoverable && hoverTransform && `hover:${hoverTransform}`, hoverable && hoverShadow && `hover:shadow-[${hoverShadow}]`, hoverable && hoverBg && `hover:bg-[${hoverBg}]`, hoverable && hoverBorder && `hover:border-[${hoverBorder}]`, ); const allClasses = clsx(normalClasses, hoverClasses); // Decide if we need a Link or a div if (href) { const handleClick = (e: React.MouseEvent) => { onClick?.(e as unknown as React.MouseEvent); }; return ( } className={clsx(allClasses, "cursor-pointer")} onClick={handleClick} // Note: We intentionally do NOT spread props here as they come from // HTMLDivElement which is incompatible with HTMLAnchorElement. // CardProps extends HTMLAttributes, but Link // expects HTMLAnchorElement props. This is a known TypeScript limitation. // Users should pass Link-specific props via dedicated props, not spread. > {children} ); } return (
} className={clsx(allClasses, onClick && "cursor-pointer")} onClick={onClick} // Only spread props when rendering as div (HTMLDivElement) {...props} > {children}
); }, ); SharedCard.displayName = "SharedCard"; // ============================================================================= // Named exports for specific card types (for convenience) // ============================================================================= // Primary Card (matching /home PrimaryCard) export function PrimaryCard({ href, icon: Icon, label, description, accentClass = "bg-[var(--accent-primary)]/10 text-[var(--accent-primary)]", borderClass = "border-[var(--accent-primary)]/20", bgClass = "bg-gradient-to-br from-[var(--accent-primary)]/5 to-transparent", className, ...props }: { href: string; icon: React.ElementType; label: string; description: string; accentClass?: string; borderClass?: string; bgClass?: string; className?: string; } & Omit) { return (

{label}

{description}

Get started →
); } // Secondary Card (matching /home SecondaryCard) export function SecondaryCard({ href, icon: Icon, label, description, disabled = false, className, onClick, ...props }: { href?: string; icon: React.ElementType; label: string; description: string; disabled?: boolean; className?: string; onClick?: () => void; } & Omit) { const baseClasses = "flex items-center gap-3.5 rounded-lg border border-[var(--border-subtle)] bg-[var(--bg-glass)] p-4 transition hover:border-[var(--border-medium)] hover:bg-[var(--bg-elevated)]"; const inner = ( <>

{label} {disabled ? ( Unavailable ) : null}

{description}

); if (disabled) { return (
{inner}
); } if (!href) { return (
{inner}
); } return ( {inner} ); }