返回 presentation-ai
PresentationCustomizer.tsx
根目录 / src / components / notebook / presentation / components / theme / PresentationCustomizer.tsx
1 "use client";
2
3 import { List } from "lucide-react";
4
5 import {
6 Select,
7 SelectContent,
8 SelectItem,
9 SelectTrigger,
10 SelectValue,
11 } from "@/components/ui/select";
12 import { usePresentationState } from "@/states/presentation-state";
13
14 const CONTENT_OPTIONS = [
15 { id: "minimal", label: "Minimal", lines: 2 },
16 { id: "concise", label: "Concise", lines: 3 },
17 { id: "detailed", label: "Detailed", lines: 3 },
18 { id: "extensive", label: "Extensive", lines: 3 },
19 ] as const;
20
21 const TONE_OPTIONS = [
22 { id: "auto", label: "Auto" },
23 { id: "general", label: "General" },
24 { id: "persuasive", label: "Persuasive" },
25 { id: "inspiring", label: "Inspiring" },
26 { id: "instructive", label: "Instructive" },
27 { id: "engaging", label: "Engaging" },
28 ] as const;
29
30 const AUDIENCE_OPTIONS = [
31 { id: "auto", label: "Auto" },
32 { id: "general", label: "General" },
33 { id: "business", label: "Business" },
34 { id: "investor", label: "Investor" },
35 { id: "teacher", label: "Teacher" },
36 { id: "student", label: "Student" },
37 ] as const;
38
39 const SCENARIO_OPTIONS = [
40 { id: "auto", label: "Auto" },
41 { id: "general", label: "General" },
42 { id: "analysis-report", label: "Analysis Report" },
43 { id: "teaching-training", label: "Teaching" },
44 { id: "promotional-materials", label: "Promotional" },
45 { id: "public-speeches", label: "Public Speeches" },
46 ] as const;
47
48 export function PresentationCustomizer() {
49 const {
50 textContent,
51 setTextContent,
52 tone,
53 setTone,
54 audience,
55 setAudience,
56 scenario,
57 setScenario,
58 } = usePresentationState();
59
60 return (
61 <div className="space-y-4 rounded-xl border bg-muted/40">
62 {/* Text Content Section */}
63 <div className="border-0 p-6 shadow">
64 <div className="mb-4 flex items-center gap-2">
65 <List className="size-5 text-primary" />
66 <h2 className="text-xl font-semibold text-foreground">
67 Text Content
68 </h2>
69 </div>
70
71 <p className="mb-4 text-sm text-muted-foreground">
72 Amount of text per card
73 </p>
74
75 <div className="grid grid-cols-2 gap-3 md:grid-cols-4">
76 {CONTENT_OPTIONS.map((option) => (
77 <button
78 type="button"
79 key={option.id}
80 onClick={() => setTextContent(option.id)}
81 className={`flex flex-col items-center gap-3 rounded-lg border-2 p-4 transition-all ${
82 textContent === option.id
83 ? "border-primary bg-primary/10"
84 : "border-border bg-background hover:border-accent"
85 }`}
86 >
87 <div className="flex h-12 w-full flex-col items-center justify-center gap-1">
88 {Array.from({ length: option.lines }).map((_, i) => (
89 <div
90 key={i}
91 className={`h-1 rounded-full ${textContent === option.id ? "bg-primary" : "bg-muted-foreground"}`}
92 style={{
93 width: i === option.lines - 1 ? "60%" : "80%",
94 }}
95 />
96 ))}
97 </div>
98 <span
99 className={`text-sm font-medium ${textContent === option.id ? "text-primary" : "text-foreground"}`}
100 >
101 {option.label}
102 </span>
103 </button>
104 ))}
105 </div>
106
107 <div className="mt-8 grid grid-cols-1 gap-6 md:grid-cols-3">
108 {/* Tone Select */}
109 <div>
110 <label
111 htmlFor="presentation-tone"
112 className="mb-3 block text-sm font-medium text-foreground"
113 >
114 Tone
115 </label>
116 <Select value={tone} onValueChange={setTone}>
117 <SelectTrigger id="presentation-tone">
118 <SelectValue placeholder="Select tone" />
119 </SelectTrigger>
120 <SelectContent>
121 {TONE_OPTIONS.map((option) => (
122 <SelectItem key={option.id} value={option.id}>
123 {option.label}
124 </SelectItem>
125 ))}
126 </SelectContent>
127 </Select>
128 </div>
129
130 {/* Audience Select */}
131 <div>
132 <label
133 htmlFor="presentation-audience"
134 className="mb-3 block text-sm font-medium text-foreground"
135 >
136 Audience
137 </label>
138 <Select value={audience} onValueChange={setAudience}>
139 <SelectTrigger id="presentation-audience">
140 <SelectValue placeholder="Select audience" />
141 </SelectTrigger>
142 <SelectContent>
143 {AUDIENCE_OPTIONS.map((option) => (
144 <SelectItem key={option.id} value={option.id}>
145 {option.label}
146 </SelectItem>
147 ))}
148 </SelectContent>
149 </Select>
150 </div>
151
152 {/* Scenario Select */}
153 <div>
154 <label
155 htmlFor="presentation-scenario"
156 className="mb-3 block text-sm font-medium text-foreground"
157 >
158 Scenario
159 </label>
160 <Select value={scenario} onValueChange={setScenario}>
161 <SelectTrigger id="presentation-scenario">
162 <SelectValue placeholder="Select scenario" />
163 </SelectTrigger>
164 <SelectContent>
165 {SCENARIO_OPTIONS.map((option) => (
166 <SelectItem key={option.id} value={option.id}>
167 {option.label}
168 </SelectItem>
169 ))}
170 </SelectContent>
171 </Select>
172 </div>
173 </div>
174 </div>
175 </div>
176 );
177 }
178
178 lines Plain Text