Skip to content

Commit e006317

Browse files
committed
feat: redesign Formatting page (formerly Enhancements) with improved UI/UX
- Rename Enhancements to Formatting for better user understanding - Modernize header with consistent styling across all pages - Display active model next to AI Models heading - Move AI Formatting toggle to header in card style - Remove redundant Enhancement Mode label - Clean up section headers by removing icons - Update model card selection to use background only (no border) - Replace X icon with 'Remove Key' button for clarity - Improve setup guide with better styling - Update default mode description to emphasize formatting
1 parent 53f8837 commit e006317

File tree

6 files changed

+90
-49
lines changed

6 files changed

+90
-49
lines changed

src/components/EnhancementModelCard.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ask } from '@tauri-apps/plugin-dialog';
2-
import { Key, X } from 'lucide-react';
2+
import { Key, Trash2 } from 'lucide-react';
33
import { Button } from './ui/button';
44
import { Card } from './ui/card';
55

@@ -37,9 +37,9 @@ export function EnhancementModelCard({
3737
return (
3838
<Card
3939
className={`py-2 px-4 transition-all ${
40-
hasApiKey ? 'cursor-pointer' : 'opacity-60'
40+
hasApiKey ? 'cursor-pointer hover:border-border' : 'opacity-60'
4141
} ${
42-
isSelected ? 'border-primary bg-primary/5' : ''
42+
isSelected ? 'bg-primary/5' : ''
4343
}`}
4444
onClick={() => hasApiKey && onSelect()}
4545
>
@@ -66,10 +66,11 @@ export function EnhancementModelCard({
6666
}
6767
}}
6868
variant="ghost"
69-
size="icon"
70-
className="h-8 w-8 text-muted-foreground hover:text-destructive"
69+
size="sm"
70+
className="text-muted-foreground hover:text-destructive"
7171
>
72-
<X className="w-4 h-4" />
72+
<Trash2 className="w-3.5 h-3.5" />
73+
Remove Key
7374
</Button>
7475
) : (
7576
<Button

src/components/EnhancementSettings.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ export function EnhancementSettings({ settings, onSettingsChange, disabled = fal
5353
<div className={`space-y-6 ${disabled ? 'opacity-50' : ''}`}>
5454
{/* Enhancement Mode */}
5555
<div className="space-y-3">
56-
<Label className="text-sm font-medium">Enhancement Mode</Label>
5756
<div className="flex flex-wrap gap-2">
5857
{presets.map((preset) => {
5958
const Icon = preset.icon;
@@ -77,7 +76,7 @@ export function EnhancementSettings({ settings, onSettingsChange, disabled = fal
7776

7877
{/* Mode description */}
7978
<p className="text-sm text-muted-foreground">
80-
{settings.preset === "Default" && "Clean transcription with grammar, spelling, and punctuation fixes"}
79+
{settings.preset === "Default" && "Format transcription with grammar, spelling, punctuation, and semantic corrections"}
8180
{settings.preset === "Prompts" && "Transform speech into clear, actionable AI prompts"}
8281
{settings.preset === "Email" && "Format as professional email with subject, greeting, and signature"}
8382
{settings.preset === "Commit" && "Create conventional commit message (feat, fix, docs, etc.)"}

src/components/Sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const mainSections = [
3232
{ id: "recordings", label: "History", icon: Clock },
3333
{ id: "general", label: "Settings", icon: Settings2 },
3434
{ id: "models", label: "Models", icon: Cpu },
35-
{ id: "enhancements", label: "Enhancements", icon: Sparkles },
35+
{ id: "formatting", label: "Formatting", icon: Sparkles },
3636
{ id: "account", label: "Account", icon: Key },
3737
];
3838

src/components/sections/EnhancementsSection.tsx

Lines changed: 78 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { EnhancementModelCard } from "@/components/EnhancementModelCard";
33
import { EnhancementSettings } from "@/components/EnhancementSettings";
44
import { ScrollArea } from "@/components/ui/scroll-area";
55
import { Switch } from "@/components/ui/switch";
6+
import { Label } from "@/components/ui/label";
67
import type { EnhancementOptions } from "@/types/ai";
78
import { fromBackendOptions, toBackendOptions } from "@/types/ai";
89
import { hasApiKey, removeApiKey, saveApiKey, getApiKey } from "@/utils/keyring";
@@ -11,6 +12,7 @@ import { invoke } from "@tauri-apps/api/core";
1112
import { listen } from "@tauri-apps/api/event";
1213
import { useEffect, useState, useCallback } from "react";
1314
import { toast } from "sonner";
15+
import { Sparkles, Info, Wand2 } from "lucide-react";
1416

1517
interface AIModel {
1618
id: string;
@@ -252,7 +254,7 @@ export function EnhancementsSection() {
252254
});
253255

254256
setAISettings(prev => ({ ...prev, enabled }));
255-
toast.success(enabled ? "AI enhancement enabled" : "AI enhancement disabled");
257+
toast.success(enabled ? "AI formatting enabled" : "AI formatting disabled");
256258
} catch (error) {
257259
toast.error(`Failed to update settings: ${error}`);
258260
}
@@ -331,40 +333,69 @@ export function EnhancementsSection() {
331333
const hasAnyApiKey = Object.values(providerApiKeys).some(v => v);
332334
const selectedModelProvider = models.find(m => m.id === aiSettings.model)?.provider;
333335
const hasSelectedModel = Boolean(aiSettings.model && selectedModelProvider && providerApiKeys[selectedModelProvider]);
336+
const selectedModelName = models.find(m => m.id === aiSettings.model)?.name;
334337

335338
return (
336-
<div className="h-full flex flex-col p-6">
337-
<div className="flex-shrink-0 space-y-4 mb-4">
339+
<div className="h-full flex flex-col">
340+
{/* Header */}
341+
<div className="px-6 py-4 border-b border-border/40">
338342
<div className="flex items-center justify-between">
339-
<h2 className="text-lg font-semibold">AI Enhancement</h2>
340-
<Switch
341-
id="ai-enhancement"
342-
checked={aiSettings.enabled}
343-
onCheckedChange={handleToggleEnabled}
344-
disabled={!hasAnyApiKey || !hasSelectedModel}
345-
/>
343+
<div>
344+
<h1 className="text-2xl font-semibold">Formatting</h1>
345+
<p className="text-sm text-muted-foreground mt-1">
346+
AI-powered text formatting and enhancement
347+
</p>
348+
</div>
349+
<div className="flex items-center gap-2 px-3 py-1.5 rounded-lg bg-card border border-border/50">
350+
<Label htmlFor="ai-formatting" className="text-sm font-medium cursor-pointer">
351+
AI Formatting
352+
</Label>
353+
<Switch
354+
id="ai-formatting"
355+
checked={aiSettings.enabled}
356+
onCheckedChange={handleToggleEnabled}
357+
disabled={!hasAnyApiKey || !hasSelectedModel}
358+
/>
359+
</div>
346360
</div>
347361
</div>
348362

349-
<ScrollArea className="flex-1 min-h-0">
350-
<div className="space-y-4">
351-
{/* Models */}
352-
<div className="space-y-3">
353-
{models.map((model) => (
354-
<EnhancementModelCard
355-
key={model.id}
356-
model={model}
357-
hasApiKey={providerApiKeys[model.provider] || false}
358-
isSelected={aiSettings.model === model.id && providerApiKeys[model.provider]}
359-
onSetupApiKey={() => handleSetupApiKey(model.provider)}
360-
onSelect={() => handleModelSelect(model.id, model.provider)}
361-
onRemoveApiKey={() => handleRemoveApiKey(model.provider)}
362-
/>
363-
))}
363+
<ScrollArea className="flex-1">
364+
<div className="p-6 space-y-6">
365+
{/* AI Models Section */}
366+
<div className="space-y-4">
367+
<div className="flex items-center gap-2">
368+
<h2 className="text-base font-semibold">AI Models</h2>
369+
<div className="h-px bg-border/50 flex-1" />
370+
{selectedModelName && (
371+
<span className="text-sm text-muted-foreground">
372+
Active: <span className="text-amber-600 dark:text-amber-500">{selectedModelName}</span>
373+
</span>
374+
)}
375+
</div>
376+
377+
<div className="grid gap-3">
378+
{models.map((model) => (
379+
<EnhancementModelCard
380+
key={model.id}
381+
model={model}
382+
hasApiKey={providerApiKeys[model.provider] || false}
383+
isSelected={aiSettings.model === model.id && providerApiKeys[model.provider]}
384+
onSetupApiKey={() => handleSetupApiKey(model.provider)}
385+
onSelect={() => handleModelSelect(model.id, model.provider)}
386+
onRemoveApiKey={() => handleRemoveApiKey(model.provider)}
387+
/>
388+
))}
389+
</div>
364390
</div>
365391

366-
{/* Enhancement Settings - Always visible, disabled when AI is off */}
367-
<div className="mt-4 pt-4">
392+
{/* Formatting Options */}
393+
<div className="space-y-4">
394+
<div className="flex items-center gap-2">
395+
<h2 className="text-base font-semibold">Formatting Options</h2>
396+
<div className="h-px bg-border/50 flex-1" />
397+
</div>
398+
368399
<div className={!aiSettings.enabled ? "opacity-50 pointer-events-none" : ""}>
369400
<EnhancementSettings
370401
settings={enhancementOptions}
@@ -373,17 +404,27 @@ export function EnhancementsSection() {
373404
</div>
374405
</div>
375406

376-
{/* Simple setup guide when AI is disabled */}
407+
{/* Setup Guide */}
377408
{!aiSettings.enabled && (
378-
<div className="bg-muted/50 rounded-lg p-4 space-y-3 mt-4">
379-
<h3 className="font-medium text-sm">Quick Setup Guide</h3>
380-
<ol className="text-sm text-muted-foreground space-y-2 list-decimal list-inside">
381-
<li>Click "Add Key" on a model above</li>
382-
<li>Visit the provider's website to get your API key</li>
383-
<li>Paste the API key and submit</li>
384-
<li>Select the model you want to use</li>
385-
<li>Toggle the switch above to enable AI enhancement</li>
386-
</ol>
409+
<div className="rounded-lg border border-border/50 bg-card p-4">
410+
<div className="flex items-start gap-3">
411+
<div className="p-1.5 rounded-md bg-amber-500/10">
412+
<Info className="h-4 w-4 text-amber-500" />
413+
</div>
414+
<div className="space-y-2 flex-1">
415+
<h3 className="font-medium text-sm">Quick Setup</h3>
416+
<ol className="text-sm text-muted-foreground space-y-1.5 list-decimal list-inside">
417+
<li>Click "Add Key" on a model above</li>
418+
<li>Get your API key from the provider's website</li>
419+
<li>Paste the API key and save</li>
420+
<li>Select the model you want to use</li>
421+
<li>Toggle AI Formatting on to enable</li>
422+
</ol>
423+
<p className="text-xs text-muted-foreground mt-3">
424+
AI formatting automatically improves your transcribed text with proper punctuation, capitalization, and style.
425+
</p>
426+
</div>
427+
</div>
387428
</div>
388429
)}
389430
</div>

src/components/tabs/EnhancementsTab.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function EnhancementsTab() {
1414
registerEvent("ai-enhancement-auth-error", (event) => {
1515
console.error("AI authentication error:", event.payload);
1616
toast.error(event.payload as string, {
17-
description: "Please update your API key in the Enhancements section",
17+
description: "Please update your API key in the Formatting section",
1818
action: {
1919
label: "Update API Key",
2020
onClick: () => {
@@ -29,7 +29,7 @@ export function EnhancementsTab() {
2929
});
3030

3131
registerEvent("ai-enhancement-error", (event) => {
32-
console.warn("AI enhancement error:", event.payload);
32+
console.warn("AI formatting error:", event.payload);
3333
toast.warning(event.payload as string);
3434
});
3535
} catch (error) {

src/components/tabs/TabContainer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export function TabContainer({ activeSection }: TabContainerProps) {
5757
case "advanced":
5858
return <AdvancedTab />;
5959

60-
case "enhancements":
60+
case "formatting":
6161
return <EnhancementsTab />;
6262

6363
case "account":

0 commit comments

Comments
 (0)