fix persistence for storing profiles in backend db

This commit is contained in:
rishikanthc
2025-08-27 09:09:40 -07:00
parent f8659303c7
commit 69b514fbfd
16 changed files with 107 additions and 59 deletions

File diff suppressed because one or more lines are too long

View File

@@ -8,7 +8,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Noto+Sans:ital,wght@0,100..900;1,100..900&family=Fira+Code:wght@300..700&family=Poiret+One&display=swap" rel="stylesheet">
<script type="module" crossorigin src="/assets/index-DBj5_qOk.js"></script>
<script type="module" crossorigin src="/assets/index-VWpE_J4S.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BPHlT-EN.css">
</head>
<body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

View File

@@ -2,6 +2,7 @@ import { useState, useCallback } from "react";
import { Button } from "./ui/button";
import { ProfilesTable } from "./ProfilesTable";
import { TranscriptionConfigDialog, type WhisperXParams } from "./TranscriptionConfigDialog";
import { useAuth } from "../contexts/AuthContext";
interface TranscriptionProfile {
id: string;
@@ -17,6 +18,7 @@ export function ProfileSettings() {
const [profileDialogOpen, setProfileDialogOpen] = useState(false);
const [editingProfile, setEditingProfile] = useState<TranscriptionProfile | null>(null);
const [refreshTrigger, setRefreshTrigger] = useState(0);
const { getAuthHeaders } = useAuth();
const handleCreateProfile = useCallback(() => {
setEditingProfile(null);
@@ -28,13 +30,56 @@ export function ProfileSettings() {
setProfileDialogOpen(true);
}, []);
const handleProfileSaved = useCallback(async (_params: WhisperXParams & { profileName?: string; profileDescription?: string }) => {
// Profile saving logic would go here
// For now, just close the dialog and refresh
setRefreshTrigger((prev) => prev + 1);
setProfileDialogOpen(false);
setEditingProfile(null);
}, []);
const handleProfileSaved = useCallback(async (payload: WhisperXParams & { profileName?: string; profileDescription?: string }) => {
try {
const name = (payload.profileName || "").trim();
const description = (payload.profileDescription || "").trim();
if (!name) {
alert("Profile name is required");
return;
}
const { profileName: _pn, profileDescription: _pd, ...paramRest } = payload as any;
const body = {
name,
description: description || undefined,
parameters: paramRest as WhisperXParams,
};
let res: Response;
if (editingProfile) {
// Preserve current default flag unless changed elsewhere
res = await fetch(`/api/v1/profiles/${editingProfile.id}`, {
method: "PUT",
headers: { "Content-Type": "application/json", ...getAuthHeaders() },
body: JSON.stringify({
...body,
id: editingProfile.id,
is_default: editingProfile.is_default,
}),
});
} else {
res = await fetch(`/api/v1/profiles`, {
method: "POST",
headers: { "Content-Type": "application/json", ...getAuthHeaders() },
body: JSON.stringify(body),
});
}
if (!res.ok) {
const text = await res.text();
alert(`Failed to save profile: ${res.status} ${text}`);
return;
}
setRefreshTrigger((prev) => prev + 1);
setProfileDialogOpen(false);
setEditingProfile(null);
} catch (e) {
console.error("Failed to save profile", e);
alert("Failed to save profile");
}
}, [editingProfile, getAuthHeaders]);
const handleProfileChange = useCallback(() => {
setRefreshTrigger((prev) => prev + 1);
@@ -64,6 +109,7 @@ export function ProfileSettings() {
refreshTrigger={refreshTrigger}
onProfileChange={handleProfileChange}
onEditProfile={handleEditProfile}
onCreateProfile={handleCreateProfile}
/>
</div>

View File

@@ -27,15 +27,17 @@ interface TranscriptionProfile {
}
interface ProfilesTableProps {
refreshTrigger: number;
onProfileChange: () => void;
onEditProfile: (profile: TranscriptionProfile) => void;
refreshTrigger: number;
onProfileChange: () => void;
onEditProfile: (profile: TranscriptionProfile) => void;
onCreateProfile?: () => void;
}
export function ProfilesTable({
refreshTrigger,
onProfileChange,
onEditProfile,
refreshTrigger,
onProfileChange,
onEditProfile,
onCreateProfile,
}: ProfilesTableProps) {
const { getAuthHeaders } = useAuth();
const [profiles, setProfiles] = useState<TranscriptionProfile[]>([]);
@@ -148,13 +150,13 @@ export function ProfilesTable({
Create your first transcription profile to save and reuse your
preferred settings.
</p>
<Button
onClick={() => {}}
variant="outline"
className="border-gray-300 dark:border-gray-600 text-gray-600 dark:text-gray-400"
>
Create Profile
</Button>
<Button
onClick={() => onCreateProfile?.()}
variant="outline"
className="border-gray-300 dark:border-gray-600 text-gray-600 dark:text-gray-400"
>
Create Profile
</Button>
</div>
);
}