Skip to content

Commit 4a06489

Browse files
committed
feat: split Account section into License and About sections
- Refactor AccountSection to focus only on license management - Create new AboutSection with app info and resources - Update navigation: tray menu "Settings" now opens Overview - Add About section to sidebar after License - Improve UI with cleaner cards and less redundant text - Resources section now uses horizontal layout with two cards
1 parent e006317 commit 4a06489

File tree

6 files changed

+261
-269
lines changed

6 files changed

+261
-269
lines changed

src/components/AppContainer.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export function AppContainer() {
8080
// Listen for navigate-to-settings event from tray menu
8181
registerEvent("navigate-to-settings", () => {
8282
console.log("Navigate to settings requested from tray menu");
83-
setActiveSection("recordings");
83+
setActiveSection("overview");
8484
});
8585

8686
// Listen for tray action errors
@@ -89,13 +89,13 @@ export function AppContainer() {
8989
toast.error(event.payload as string);
9090
});
9191

92-
// Listen for license-required event and navigate to Account section
92+
// Listen for license-required event and navigate to License section
9393
registerEvent<{ title: string; message: string; action?: string }>(
9494
"license-required",
9595
(data) => {
9696
console.log("License required event received in AppContainer:", data);
97-
// Navigate to Account section to show license management
98-
setActiveSection("account");
97+
// Navigate to License section to show license management
98+
setActiveSection("license");
9999
// Show a toast to inform the user
100100
toast.error(data.title || "License Required", {
101101
description: data.message || "Please purchase or restore a license to continue",

src/components/Sidebar.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
Cpu,
1616
HelpCircle,
1717
Home,
18+
Info,
1819
Key,
1920
Layers,
2021
Settings2,
@@ -33,7 +34,8 @@ const mainSections = [
3334
{ id: "general", label: "Settings", icon: Settings2 },
3435
{ id: "models", label: "Models", icon: Cpu },
3536
{ id: "formatting", label: "Formatting", icon: Sparkles },
36-
{ id: "account", label: "Account", icon: Key },
37+
{ id: "license", label: "License", icon: Key },
38+
{ id: "about", label: "About", icon: Info },
3739
];
3840

3941
const bottomSections = [{ id: "advanced", label: "Advanced", icon: Layers }];
Lines changed: 114 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
1-
import { XformerlyTwitter } from "@/assets/icon";
1+
import { Badge } from "@/components/ui/badge";
22
import { Button } from "@/components/ui/button";
3-
import { useSettings } from '@/contexts/SettingsContext';
4-
import { getVersion } from '@tauri-apps/api/app';
3+
import { ScrollArea } from "@/components/ui/scroll-area";
4+
import { check } from '@tauri-apps/plugin-updater';
55
import { open } from '@tauri-apps/plugin-shell';
6-
import { Mail } from "lucide-react";
6+
import { getVersion } from '@tauri-apps/api/app';
7+
import {
8+
ExternalLink,
9+
Globe,
10+
Info,
11+
RefreshCw,
12+
X
13+
} from "lucide-react";
714
import { useEffect, useState } from 'react';
815
import { toast } from 'sonner';
9-
import { updateService } from '@/services/updateService';
1016

1117
export function AboutSection() {
12-
const { updateSettings } = useSettings();
13-
const [checking, setChecking] = useState(false);
14-
const [resetting, setResetting] = useState(false);
15-
const [appVersion, setAppVersion] = useState<string>('Loading...');
18+
const [appVersion, setAppVersion] = useState<string>('');
19+
const [isCheckingUpdate, setIsCheckingUpdate] = useState(false);
1620

1721
useEffect(() => {
18-
getVersion().then(setAppVersion).catch(() => setAppVersion('Unknown'));
22+
const fetchVersion = async () => {
23+
try {
24+
const version = await getVersion();
25+
setAppVersion(version);
26+
} catch (error) {
27+
console.error('Failed to get app version:', error);
28+
setAppVersion('Unknown');
29+
}
30+
};
31+
32+
fetchVersion();
1933
}, []);
2034

21-
const handleResetOnboarding = async () => {
22-
setResetting(true);
35+
const handleCheckUpdate = async () => {
36+
setIsCheckingUpdate(true);
2337
try {
24-
// Update settings to set onboarding_completed to false
25-
await updateSettings({
26-
onboarding_completed: false,
27-
});
28-
29-
toast.success("Onboarding reset! Restarting the app.");
30-
31-
// Reload the window to trigger onboarding
32-
setTimeout(() => {
33-
window.location.reload();
34-
}, 1000);
38+
const update = await check();
39+
if (update?.available) {
40+
toast.info(`Update available: v${update.version}`);
41+
} else {
42+
toast.success('You are on the latest version');
43+
}
3544
} catch (error) {
36-
console.error('Failed to reset onboarding:', error);
37-
toast.error("Failed to reset onboarding");
38-
} finally {
39-
setResetting(false);
40-
}
41-
};
42-
43-
const handleCheckForUpdates = async () => {
44-
setChecking(true);
45-
try {
46-
await updateService.checkForUpdatesManually();
45+
console.error('Failed to check for updates:', error);
46+
toast.error('Failed to check for updates');
4747
} finally {
48-
setChecking(false);
48+
setIsCheckingUpdate(false);
4949
}
5050
};
5151

@@ -59,66 +59,90 @@ export function AboutSection() {
5959
};
6060

6161
return (
62-
<div className="p-6 h-full flex flex-col">
63-
<h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-6">About VoiceTypr</h2>
64-
65-
<div className="flex-1 space-y-6">
66-
{/* App Info Section */}
67-
<div className="space-y-4">
68-
{/* Version */}
69-
<div className="flex items-center gap-3">
70-
<p className="text-sm text-gray-600 dark:text-gray-400">Version</p>
71-
<p className="text-base font-medium">{appVersion}</p>
62+
<div className="h-full flex flex-col">
63+
{/* Header */}
64+
<div className="px-6 py-4 border-b border-border/40">
65+
<div className="flex items-center justify-between">
66+
<div>
67+
<h1 className="text-2xl font-semibold">About</h1>
68+
<p className="text-sm text-muted-foreground mt-1">
69+
App information and resources
70+
</p>
7271
</div>
7372
</div>
73+
</div>
7474

75-
{/* Links Section */}
76-
<div className="flex items-center gap-6 mt-8">
77-
<button
78-
onClick={() => {
79-
navigator.clipboard.writeText("support@voicetypr.com");
80-
toast.success("Support email copied to clipboard!");
81-
}}
82-
className="flex items-center gap-2 text-sm text-gray-900 dark:text-gray-100 hover:text-gray-600 dark:hover:text-gray-400 hover:underline underline-offset-4"
83-
>
84-
<Mail className="w-4 h-4" />
85-
support@voicetypr.com
86-
</button>
87-
<button
88-
onClick={() => openExternalLink("https://twitter.com/voicetypr")}
89-
className="flex items-center gap-2 text-sm text-gray-900 dark:text-gray-100 hover:text-gray-600 dark:hover:text-gray-400 hover:underline underline-offset-4"
90-
>
91-
<XformerlyTwitter className="w-4 h-4" />
92-
@voicetypr
93-
</button>
94-
</div>
75+
<ScrollArea className="flex-1">
76+
<div className="p-6 space-y-6">
77+
{/* App Information Section */}
78+
<div className="space-y-4">
79+
<h2 className="text-base font-semibold">App Information</h2>
80+
81+
<div className="rounded-lg border border-border/50 bg-card p-4 space-y-4">
82+
<div className="flex items-center justify-between">
83+
<div className="flex items-center gap-2">
84+
<Info className="h-4 w-4 text-muted-foreground" />
85+
<span className="text-sm text-muted-foreground">Version</span>
86+
</div>
87+
<Badge variant="secondary" className="font-mono">
88+
v{appVersion || 'Loading...'}
89+
</Badge>
90+
</div>
9591

96-
{/* Check for Updates Button */}
97-
<div className="mt-12 flex justify-center">
98-
<Button
99-
size="sm"
100-
variant="default"
101-
onClick={handleCheckForUpdates}
102-
className="h-8"
103-
disabled={checking}
104-
>
105-
{checking ? "Checking..." : "Check for Updates"}
106-
</Button>
107-
</div>
108-
</div>
92+
<div className="flex justify-center">
93+
<Button
94+
onClick={handleCheckUpdate}
95+
disabled={isCheckingUpdate}
96+
variant="ghost"
97+
size="sm"
98+
>
99+
<RefreshCw className={`h-3.5 w-3.5 mr-1.5 ${isCheckingUpdate ? 'animate-spin' : ''}`} />
100+
{isCheckingUpdate ? 'Checking...' : 'Check for Updates'}
101+
</Button>
102+
</div>
103+
</div>
104+
</div>
109105

110-
{/* Reset Onboarding at the absolute bottom */}
111-
<div className="flex justify-center mt-auto pt-6">
112-
<Button
113-
size="sm"
114-
variant="ghost"
115-
onClick={handleResetOnboarding}
116-
className="h-8 text-muted-foreground hover:text-foreground"
117-
disabled={resetting}
118-
>
119-
{resetting ? "Resetting..." : "Reset Onboarding"}
120-
</Button>
121-
</div>
106+
{/* Resources Section */}
107+
<div className="space-y-4">
108+
<h2 className="text-base font-semibold">Resources</h2>
109+
110+
<div className="flex gap-3">
111+
<button
112+
onClick={() => openExternalLink("https://voicetypr.com")}
113+
className="flex-1 rounded-lg border border-border/50 bg-card p-4 flex items-center justify-between hover:bg-accent/50 transition-colors group"
114+
>
115+
<div className="flex items-center gap-3">
116+
<div className="p-1.5 rounded-md bg-primary/10">
117+
<Globe className="h-4 w-4 text-primary" />
118+
</div>
119+
<div className="text-left">
120+
<p className="text-sm font-medium">Website</p>
121+
<p className="text-xs text-muted-foreground">Official site</p>
122+
</div>
123+
</div>
124+
<ExternalLink className="h-4 w-4 text-muted-foreground group-hover:text-foreground transition-colors" />
125+
</button>
126+
127+
<button
128+
onClick={() => openExternalLink("https://x.com/voicetypr")}
129+
className="flex-1 rounded-lg border border-border/50 bg-card p-4 flex items-center justify-between hover:bg-accent/50 transition-colors group"
130+
>
131+
<div className="flex items-center gap-3">
132+
<div className="p-1.5 rounded-md bg-accent">
133+
<X className="h-4 w-4 text-foreground" />
134+
</div>
135+
<div className="text-left">
136+
<p className="text-sm font-medium">X</p>
137+
<p className="text-xs text-muted-foreground">Follow for updates</p>
138+
</div>
139+
</div>
140+
<ExternalLink className="h-4 w-4 text-muted-foreground group-hover:text-foreground transition-colors" />
141+
</button>
142+
</div>
143+
</div>
144+
</div>
145+
</ScrollArea>
122146
</div>
123147
);
124148
}

0 commit comments

Comments
 (0)