Frontend start to use backend CRUD api

This commit is contained in:
Xin Wang
2026-02-08 15:08:18 +08:00
parent b9a315177a
commit 86744f0842
12 changed files with 768 additions and 154 deletions

View File

@@ -1,12 +1,13 @@
import React, { useState, useRef } from 'react';
import React, { useEffect, useState, useRef } from 'react';
import { Search, Mic2, Play, Pause, Upload, X, Filter, Plus, Volume2, Sparkles, Wand2, ChevronDown } from 'lucide-react';
import { Button, Input, TableHeader, TableRow, TableHead, TableCell, Dialog, Badge } from '../components/UI';
import { mockVoices } from '../services/mockData';
import { Voice } from '../types';
import { fetchVoices } from '../services/backendApi';
export const VoiceLibraryPage: React.FC = () => {
const [voices, setVoices] = useState<Voice[]>(mockVoices);
const [voices, setVoices] = useState<Voice[]>([]);
const [searchTerm, setSearchTerm] = useState('');
const [vendorFilter, setVendorFilter] = useState<'all' | 'Ali' | 'Volcano' | 'Minimax' | '硅基流动'>('all');
const [genderFilter, setGenderFilter] = useState<'all' | 'Male' | 'Female'>('all');
@@ -15,6 +16,24 @@ export const VoiceLibraryPage: React.FC = () => {
const [playingVoiceId, setPlayingVoiceId] = useState<string | null>(null);
const [isCloneModalOpen, setIsCloneModalOpen] = useState(false);
const [isAddModalOpen, setIsAddModalOpen] = useState(false);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const loadVoices = async () => {
setIsLoading(true);
try {
const list = await fetchVoices();
setVoices(list.length > 0 ? list : mockVoices);
} catch (error) {
console.error(error);
setVoices(mockVoices);
} finally {
setIsLoading(false);
}
};
loadVoices();
}, []);
const filteredVoices = voices.filter(voice => {
const matchesSearch = voice.name.toLowerCase().includes(searchTerm.toLowerCase());
@@ -116,7 +135,7 @@ export const VoiceLibraryPage: React.FC = () => {
</TableRow>
</TableHeader>
<tbody>
{filteredVoices.map(voice => (
{!isLoading && filteredVoices.map(voice => (
<TableRow key={voice.id}>
<TableCell className="font-medium">
<div className="flex flex-col">
@@ -144,11 +163,16 @@ export const VoiceLibraryPage: React.FC = () => {
</TableCell>
</TableRow>
))}
{filteredVoices.length === 0 && (
{!isLoading && filteredVoices.length === 0 && (
<TableRow>
<TableCell colSpan={5} className="text-center py-6 text-muted-foreground"></TableCell>
</TableRow>
)}
{isLoading && (
<TableRow>
<TableCell colSpan={5} className="text-center py-6 text-muted-foreground">...</TableCell>
</TableRow>
)}
</tbody>
</table>
</div>