| 1 | "use client"; |
| 2 | |
| 3 | import { Edit2, Heart } from "lucide-react"; |
| 4 | import { useState } from "react"; |
| 5 | import { Controller, useWatch, type Control } from "react-hook-form"; |
| 6 | |
| 7 | import { type ThemeColors } from "@/lib/presentation/themes"; |
| 8 | import { cn } from "@/lib/utils"; |
| 9 | import { type ColorKey, type ThemeFormValues } from "../types"; |
| 10 | import { ColorSettingsPanel } from "./ColorSettingsPanel"; |
| 11 | import { ColorThemeGrid } from "./ColorThemeGrid"; |
| 12 | import { colorThemes } from "./create-theme-types"; |
| 13 | |
| 14 | interface ColorsStepProps { |
| 15 | control: Control<ThemeFormValues>; |
| 16 | selectedColorTheme: string; |
| 17 | onColorChange: (key: ColorKey, value: string) => void; |
| 18 | onSelectColorTheme: (themeId: string) => void; |
| 19 | defaultColors?: Partial<ThemeColors>; |
| 20 | } |
| 21 | |
| 22 | export function ColorsStep({ |
| 23 | control, |
| 24 | selectedColorTheme, |
| 25 | onColorChange, |
| 26 | onSelectColorTheme, |
| 27 | defaultColors, |
| 28 | }: ColorsStepProps) { |
| 29 | // Use useWatch to properly subscribe to form changes |
| 30 | const watchColors = useWatch({ control, name: "colors" }); |
| 31 | const [mode, setMode] = useState<"curated" | "customize">( |
| 32 | selectedColorTheme === "custom-theme" ? "customize" : "curated", |
| 33 | ); |
| 34 | |
| 35 | return ( |
| 36 | <div className="flex h-full flex-1 flex-col"> |
| 37 | <div className="border-b border-border p-6"> |
| 38 | <p className="mb-4 text-center text-sm text-muted-foreground"> |
| 39 | Choose your theme and background colors |
| 40 | </p> |
| 41 | <div className="flex gap-2"> |
| 42 | <button |
| 43 | onClick={() => setMode("curated")} |
| 44 | className={cn( |
| 45 | "flex flex-1 items-center justify-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors", |
| 46 | mode === "curated" |
| 47 | ? "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300" |
| 48 | : "text-muted-foreground hover:bg-muted hover:text-foreground", |
| 49 | )} |
| 50 | > |
| 51 | <Heart className="h-4 w-4" /> |
| 52 | ALLWEONE® |
| 53 | </button> |
| 54 | <button |
| 55 | onClick={() => setMode("customize")} |
| 56 | className={cn( |
| 57 | "flex flex-1 items-center justify-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors", |
| 58 | mode === "customize" |
| 59 | ? "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300" |
| 60 | : "text-muted-foreground hover:bg-muted hover:text-foreground", |
| 61 | )} |
| 62 | > |
| 63 | <Edit2 className="h-4 w-4" /> |
| 64 | Customize |
| 65 | </button> |
| 66 | </div> |
| 67 | </div> |
| 68 | |
| 69 | <div className="flex-1 overflow-y-auto p-6"> |
| 70 | {mode === "curated" ? ( |
| 71 | <ColorThemeGrid |
| 72 | themes={colorThemes} |
| 73 | selectedTheme={selectedColorTheme} |
| 74 | onSelectTheme={onSelectColorTheme} |
| 75 | /> |
| 76 | ) : ( |
| 77 | <div className="space-y-6"> |
| 78 | <Controller |
| 79 | name="background" |
| 80 | control={control} |
| 81 | defaultValue={undefined} |
| 82 | render={({ field }) => ( |
| 83 | <ColorSettingsPanel |
| 84 | colors={watchColors} |
| 85 | onColorChange={onColorChange} |
| 86 | defaultColors={defaultColors} |
| 87 | background={field.value} |
| 88 | onBackgroundChange={(value) => { |
| 89 | field.onChange(value); |
| 90 | }} |
| 91 | /> |
| 92 | )} |
| 93 | /> |
| 94 | </div> |
| 95 | )} |
| 96 | </div> |
| 97 | </div> |
| 98 | ); |
| 99 | } |
| 100 |