Felix Zieger
larger models again
47fea40
import { useState, useEffect, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { motion } from "framer-motion";
import { useTranslation } from "@/hooks/useTranslation";
import { useContext } from "react";
import { LanguageContext } from "@/contexts/LanguageContext";
import { ArrowLeft } from "lucide-react";
type Theme = "standard" | "technology" | "sports" | "food" | "custom";
interface ThemeSelectorProps {
onThemeSelect: (theme: string) => void;
onBack: () => void;
}
export const ThemeSelector = ({ onThemeSelect, onBack }: ThemeSelectorProps) => {
const [selectedTheme, setSelectedTheme] = useState<Theme>("standard");
const [customTheme, setCustomTheme] = useState("");
const [isGenerating, setIsGenerating] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const t = useTranslation();
const { language } = useContext(LanguageContext);
useEffect(() => {
const handleKeyPress = (e: KeyboardEvent) => {
if (e.target instanceof HTMLInputElement) return;
switch(e.key.toLowerCase()) {
case 'a':
setSelectedTheme("standard");
break;
case 'b':
setSelectedTheme("sports");
break;
case 'c':
setSelectedTheme("food");
break;
case 'd':
e.preventDefault();
setSelectedTheme("custom");
break;
case 'enter':
if (selectedTheme !== "custom" || customTheme.trim()) {
handleSubmit();
}
break;
case 'backspace':
e.preventDefault();
onBack();
break;
}
};
window.addEventListener('keydown', handleKeyPress);
return () => window.removeEventListener('keydown', handleKeyPress);
}, [selectedTheme, customTheme, language, onBack]);
useEffect(() => {
if (selectedTheme === "custom") {
setTimeout(() => {
inputRef.current?.focus();
}, 100);
}
}, [selectedTheme]);
const handleSubmit = async () => {
if (selectedTheme === "custom" && !customTheme.trim()) return;
setIsGenerating(true);
try {
await onThemeSelect(selectedTheme === "custom" ? customTheme : selectedTheme);
} finally {
setIsGenerating(false);
}
};
const handleInputKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter' && customTheme.trim()) {
handleSubmit();
}
};
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
className="space-y-6"
>
<div className="flex items-center justify-between mb-4">
<Button
variant="ghost"
size="icon"
onClick={onBack}
className="hover:bg-gray-100"
>
<ArrowLeft className="h-4 w-4" />
</Button>
<h2 className="text-2xl font-bold text-gray-900">{t.themes.title}</h2>
<div className="w-8" /> {/* Spacer for centering */}
</div>
<p className="text-gray-600 text-center">{t.themes.subtitle}</p>
<div className="space-y-4">
<Button
variant={selectedTheme === "standard" ? "default" : "outline"}
className="w-full justify-between"
onClick={() => setSelectedTheme("standard")}
>
{t.themes.standard} <span className="text-sm opacity-50">{t.themes.pressKey} A</span>
</Button>
<Button
variant={selectedTheme === "sports" ? "default" : "outline"}
className="w-full justify-between"
onClick={() => setSelectedTheme("sports")}
>
{t.themes.sports} <span className="text-sm opacity-50">{t.themes.pressKey} B</span>
</Button>
<Button
variant={selectedTheme === "food" ? "default" : "outline"}
className="w-full justify-between"
onClick={() => setSelectedTheme("food")}
>
{t.themes.food} <span className="text-sm opacity-50">{t.themes.pressKey} C</span>
</Button>
<Button
variant={selectedTheme === "custom" ? "default" : "outline"}
className="w-full justify-between"
onClick={() => setSelectedTheme("custom")}
>
{t.themes.custom} <span className="text-sm opacity-50">{t.themes.pressKey} D</span>
</Button>
{selectedTheme === "custom" && (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: "auto" }}
exit={{ opacity: 0, height: 0 }}
transition={{ duration: 0.2 }}
>
<Input
ref={inputRef}
type="text"
placeholder={t.themes.customPlaceholder}
value={customTheme}
onChange={(e) => setCustomTheme(e.target.value)}
onKeyPress={handleInputKeyPress}
className="w-full"
/>
</motion.div>
)}
</div>
<Button
onClick={handleSubmit}
className="w-full"
disabled={selectedTheme === "custom" && !customTheme.trim() || isGenerating}
>
{isGenerating ? t.themes.generating : `${t.themes.continue} ⏎`}
</Button>
</motion.div>
);
};