mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-18 14:20:42 -07:00
Initialize voicebox project with backend, frontend, and Tauri setup. Added configuration files, dependencies, and basic structure for components, hooks, and utilities. Included README and setup documentation for guidance.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
# Server settings and connection components
|
||||
@@ -0,0 +1,74 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import * as z from 'zod';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { useToast } from '@/components/ui/use-toast';
|
||||
import { useServerStore } from '@/stores/serverStore';
|
||||
|
||||
const connectionSchema = z.object({
|
||||
serverUrl: z.string().url('Please enter a valid URL'),
|
||||
});
|
||||
|
||||
type ConnectionFormValues = z.infer<typeof connectionSchema>;
|
||||
|
||||
export function ConnectionForm() {
|
||||
const serverUrl = useServerStore((state) => state.serverUrl);
|
||||
const setServerUrl = useServerStore((state) => state.setServerUrl);
|
||||
const { toast } = useToast();
|
||||
|
||||
const form = useForm<ConnectionFormValues>({
|
||||
resolver: zodResolver(connectionSchema),
|
||||
defaultValues: {
|
||||
serverUrl: serverUrl,
|
||||
},
|
||||
});
|
||||
|
||||
function onSubmit(data: ConnectionFormValues) {
|
||||
setServerUrl(data.serverUrl);
|
||||
toast({
|
||||
title: 'Server URL updated',
|
||||
description: `Connected to ${data.serverUrl}`,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Server Connection</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="serverUrl"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Server URL</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="http://localhost:8000" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>Enter the URL of your voicebox backend server</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Button type="submit">Update Connection</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { CheckCircle2, Loader2, XCircle } from 'lucide-react';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { useServerHealth } from '@/lib/hooks/useServer';
|
||||
import { useServerStore } from '@/stores/serverStore';
|
||||
|
||||
export function ServerStatus() {
|
||||
const { data: health, isLoading, error } = useServerHealth();
|
||||
const serverUrl = useServerStore((state) => state.serverUrl);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Server Status</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<div className="text-sm text-muted-foreground mb-1">Server URL</div>
|
||||
<div className="font-mono text-sm">{serverUrl}</div>
|
||||
</div>
|
||||
|
||||
{isLoading ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
<span className="text-sm">Checking connection...</span>
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<XCircle className="h-4 w-4 text-destructive" />
|
||||
<span className="text-sm text-destructive">Connection failed: {error.message}</span>
|
||||
</div>
|
||||
) : health ? (
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<CheckCircle2 className="h-4 w-4 text-green-500" />
|
||||
<span className="text-sm">Connected</span>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Badge variant={health.model_loaded ? 'default' : 'secondary'}>
|
||||
Model: {health.model_loaded ? 'Loaded' : 'Not Loaded'}
|
||||
</Badge>
|
||||
<Badge variant={health.gpu_available ? 'default' : 'secondary'}>
|
||||
GPU: {health.gpu_available ? 'Available' : 'Not Available'}
|
||||
</Badge>
|
||||
{health.vram_used_mb && (
|
||||
<Badge variant="outline">VRAM: {health.vram_used_mb.toFixed(0)} MB</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user