|
170 | 170 | </script> |
171 | 171 |
|
172 | 172 | <Dialog.Root {open} {onOpenChange}> |
173 | | - <Dialog.Content class="flex h-[64vh] flex-col" style="max-width: 48rem;"> |
174 | | - <Dialog.Header> |
175 | | - <Dialog.Title class="flex items-center gap-2"> |
176 | | - <Settings class="h-5 w-5" /> |
177 | | - Settings |
178 | | - </Dialog.Title> |
179 | | - </Dialog.Header> |
180 | | - |
| 173 | + <Dialog.Content class="flex h-[64vh] flex-col gap-0 p-0" style="max-width: 48rem;"> |
181 | 174 | <div class="flex flex-1 overflow-hidden"> |
182 | | - <div class="bg-muted/30 w-64 border-r p-4"> |
183 | | - <nav class="space-y-1"> |
| 175 | + <div class="w-64 border-r p-6"> |
| 176 | + <nav class="space-y-1 py-2"> |
| 177 | + <Dialog.Title class="mb-6 flex items-center gap-2">Settings</Dialog.Title> |
| 178 | + |
184 | 179 | {#each settingSections as section} |
185 | 180 | <button |
186 | 181 | class="hover:bg-accent flex w-full cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors {activeSection === |
|
196 | 191 | </nav> |
197 | 192 | </div> |
198 | 193 |
|
199 | | - <div class="flex flex-1 flex-col"> |
200 | | - <ScrollArea class="flex-1 p-6"> |
201 | | - <div class="space-y-6"> |
202 | | - <div class="flex items-center gap-2 border-b pb-2"> |
203 | | - <currentSection.icon class="h-5 w-5" /> |
204 | | - <h3 class="text-lg font-semibold">{currentSection.title}</h3> |
205 | | - </div> |
| 194 | + <ScrollArea class="flex-1"> |
| 195 | + <div class="space-y-6 p-6"> |
| 196 | + <div class="flex items-center gap-2 border-b pb-2"> |
| 197 | + <currentSection.icon class="h-5 w-5" /> |
| 198 | + <h3 class="text-lg font-semibold">{currentSection.title}</h3> |
| 199 | + </div> |
206 | 200 |
|
207 | | - <div class="space-y-6"> |
208 | | - {#each currentSection.fields as field} |
209 | | - <div class="space-y-2"> |
210 | | - {#if field.type === 'input'} |
211 | | - <label for={field.key} class="block text-sm font-medium"> |
212 | | - {field.label} |
213 | | - </label> |
| 201 | + <div class="space-y-6"> |
| 202 | + {#each currentSection.fields as field} |
| 203 | + <div class="space-y-2"> |
| 204 | + {#if field.type === 'input'} |
| 205 | + <label for={field.key} class="block text-sm font-medium"> |
| 206 | + {field.label} |
| 207 | + </label> |
214 | 208 |
|
215 | | - <Input |
216 | | - id={field.key} |
217 | | - value={String(config[field.key] || '')} |
218 | | - onchange={(e) => |
219 | | - (config[field.key] = e.currentTarget.value)} |
220 | | - placeholder={`Default: ${defaultConfig[field.key] || 'none'}`} |
221 | | - class="max-w-md" |
222 | | - /> |
223 | | - {#if field.help} |
224 | | - <p class="text-muted-foreground mt-1 text-xs"> |
225 | | - {field.help} |
226 | | - </p> |
227 | | - {/if} |
228 | | - {:else if field.type === 'textarea'} |
229 | | - <label for={field.key} class="block text-sm font-medium"> |
230 | | - {field.label} |
231 | | - </label> |
| 209 | + <Input |
| 210 | + id={field.key} |
| 211 | + value={String(config[field.key] || '')} |
| 212 | + onchange={(e) => |
| 213 | + (config[field.key] = e.currentTarget.value)} |
| 214 | + placeholder={`Default: ${defaultConfig[field.key] || 'none'}`} |
| 215 | + class="max-w-md" |
| 216 | + /> |
| 217 | + {#if field.help} |
| 218 | + <p class="text-muted-foreground mt-1 text-xs"> |
| 219 | + {field.help} |
| 220 | + </p> |
| 221 | + {/if} |
| 222 | + {:else if field.type === 'textarea'} |
| 223 | + <label for={field.key} class="block text-sm font-medium"> |
| 224 | + {field.label} |
| 225 | + </label> |
232 | 226 |
|
233 | | - <Textarea |
| 227 | + <Textarea |
| 228 | + id={field.key} |
| 229 | + value={String(config[field.key] || '')} |
| 230 | + onchange={(e) => |
| 231 | + (config[field.key] = e.currentTarget.value)} |
| 232 | + placeholder={`Default: ${defaultConfig[field.key] || 'none'}`} |
| 233 | + class="min-h-[100px] max-w-2xl" |
| 234 | + /> |
| 235 | + {#if field.help} |
| 236 | + <p class="text-muted-foreground mt-1 text-xs"> |
| 237 | + {field.help} |
| 238 | + </p> |
| 239 | + {/if} |
| 240 | + {:else if field.type === 'checkbox'} |
| 241 | + <div class="flex items-start space-x-3"> |
| 242 | + <Checkbox |
234 | 243 | id={field.key} |
235 | | - value={String(config[field.key] || '')} |
236 | | - onchange={(e) => |
237 | | - (config[field.key] = e.currentTarget.value)} |
238 | | - placeholder={`Default: ${defaultConfig[field.key] || 'none'}`} |
239 | | - class="min-h-[100px] max-w-2xl" |
| 244 | + checked={Boolean(config[field.key])} |
| 245 | + onCheckedChange={(checked) => |
| 246 | + (config[field.key] = checked)} |
| 247 | + class="mt-1" |
240 | 248 | /> |
241 | | - {#if field.help} |
242 | | - <p class="text-muted-foreground mt-1 text-xs"> |
243 | | - {field.help} |
244 | | - </p> |
245 | | - {/if} |
246 | | - {:else if field.type === 'checkbox'} |
247 | | - <div class="flex items-start space-x-3"> |
248 | | - <Checkbox |
249 | | - id={field.key} |
250 | | - checked={Boolean(config[field.key])} |
251 | | - onCheckedChange={(checked) => |
252 | | - (config[field.key] = checked)} |
253 | | - class="mt-1" |
254 | | - /> |
255 | 249 |
|
256 | | - <div class="space-y-1"> |
257 | | - <label |
258 | | - for={field.key} |
259 | | - class="cursor-pointer text-sm font-medium leading-none" |
260 | | - > |
261 | | - {field.label} |
262 | | - </label> |
| 250 | + <div class="space-y-1"> |
| 251 | + <label |
| 252 | + for={field.key} |
| 253 | + class="cursor-pointer text-sm font-medium leading-none" |
| 254 | + > |
| 255 | + {field.label} |
| 256 | + </label> |
263 | 257 |
|
264 | | - {#if field.help} |
265 | | - <p class="text-muted-foreground text-xs"> |
266 | | - {field.help} |
267 | | - </p> |
268 | | - {/if} |
269 | | - </div> |
| 258 | + {#if field.help} |
| 259 | + <p class="text-muted-foreground text-xs"> |
| 260 | + {field.help} |
| 261 | + </p> |
| 262 | + {/if} |
270 | 263 | </div> |
271 | | - {/if} |
272 | | - </div> |
273 | | - {/each} |
274 | | - </div> |
| 264 | + </div> |
| 265 | + {/if} |
| 266 | + </div> |
| 267 | + {/each} |
| 268 | + </div> |
275 | 269 |
|
276 | | - <div class="mt-8 border-t pt-6"> |
277 | | - <p class="text-muted-foreground text-xs"> |
278 | | - Settings are saved in browser's localStorage |
279 | | - </p> |
280 | | - </div> |
| 270 | + <div class="mt-8 border-t pt-6"> |
| 271 | + <p class="text-muted-foreground text-xs"> |
| 272 | + Settings are saved in browser's localStorage |
| 273 | + </p> |
281 | 274 | </div> |
282 | | - </ScrollArea> |
283 | | - </div> |
| 275 | + </div> |
| 276 | + </ScrollArea> |
284 | 277 | </div> |
285 | 278 |
|
286 | 279 | <div class="flex justify-between border-t p-6"> |
|
0 commit comments