import { JSX, createSignal, Show } from "solid-js"; export type CharacterPose = | "main" | "hello" | "laptop" | "sleep" | "lookup" | "success" | "like" | "walk" | "announcement" | "educate" | "happy_note" | "maintenance" | "sad" // New mascot poses | "time" | "flag" | "error" | "headphones" | "checkbox" | "coffee" | "coffe" | "angry_bulb" | "anoyed_lamp" // Grayscaled error states | "404" | "forbidden" | "connection_error" | "fixing"; interface BookraCharacterProps { pose: CharacterPose; size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl"; animate?: boolean; class?: string; alt?: string; } const sizeMap = { xs: "w-16 h-16", sm: "w-24 h-24", md: "w-32 h-32", lg: "w-48 h-48", xl: "w-64 h-64", "2xl": "w-80 h-80", }; const illustrationMap: Record = { main: "/bookra-illustrations/main.svg", hello: "/bookra-illustrations/hello.svg", laptop: "/bookra-illustrations/laptop.svg", sleep: "/bookra-illustrations/sleep.svg", lookup: "/bookra-illustrations/lookup.svg", success: "/bookra-illustrations/success.svg", like: "/bookra-illustrations/like.svg", walk: "/bookra-illustrations/walk.svg", announcement: "/bookra-illustrations/announcement.svg", educate: "/bookra-illustrations/educate.svg", happy_note: "/bookra-illustrations/happy-note.svg", maintenance: "/bookra-illustrations/maintenance.svg", sad: "/bookra-illustrations/sad.svg", time: "/bookra-illustrations/clock.svg", flag: "/bookra-illustrations/flag.svg", error: "/bookra-illustrations/sad.svg", headphones: "/bookra-illustrations/headphones.svg", checkbox: "/bookra-illustrations/happy-note.svg", coffee: "/bookra-illustrations/coffee.svg", coffe: "/bookra-illustrations/coffee.svg", angry_bulb: "/bookra-illustrations/angry-bulb.svg", anoyed_lamp: "/bookra-illustrations/angry-bulb.svg", "404": "/bookra-illustrations/404.svg", forbidden: "/bookra-illustrations/forbidden.svg", connection_error: "/bookra-illustrations/connection-error.svg", fixing: "/bookra-illustrations/maintenance.svg", }; export function BookraCharacter(props: BookraCharacterProps): JSX.Element { const [isLoaded, setIsLoaded] = createSignal(false); const [hasError, setHasError] = createSignal(false); const sizeClass = () => sizeMap[props.size || "md"]; const animationClass = () => props.animate !== false ? "animate-float" : ""; const characterPath = () => illustrationMap[props.pose]; const label = () => props.alt || `Bookra illustration - ${props.pose.replaceAll("_", " ")}`; return (
{label()} setIsLoaded(true)} onError={() => setHasError(true)} />
); } // Character with speech bubble for contextual messages interface CharacterMessageProps extends BookraCharacterProps { message: string; position?: "left" | "right" | "top" | "bottom"; } export function CharacterWithMessage(props: CharacterMessageProps): JSX.Element { const positionClass = () => { switch (props.position || "right") { case "left": return "flex-row-reverse"; case "right": return "flex-row"; case "top": return "flex-col-reverse"; case "bottom": return "flex-col"; } }; const bubblePosition = () => { switch (props.position || "right") { case "left": return "mr-4"; case "right": return "ml-4"; case "top": return "mb-3"; case "bottom": return "mt-3"; } }; return (

{props.message}

); } // Empty state with character interface CharacterEmptyStateProps { pose: CharacterPose; title: string; message: string; action?: { label: string; onClick: () => void; }; size?: "sm" | "md" | "lg"; } export function CharacterEmptyState(props: CharacterEmptyStateProps): JSX.Element { return (

{props.title}

{props.message}

{props.action && ( )}
); } // Success state with character celebration interface CharacterSuccessStateProps { title: string; message: string; action?: { label: string; onClick: () => void; }; } export function CharacterSuccessState(props: CharacterSuccessStateProps): JSX.Element { return (
✨

{props.title}

{props.message}

{props.action && ( )}
); }