130 lines
3.7 KiB
TypeScript
130 lines
3.7 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import Header from '../components/Header';
|
|
import Sidebar from '../components/Sidebar';
|
|
import RecordButton from '../components/RecordButton';
|
|
import WakeWordIndicator from '../components/WakeWordIndicator';
|
|
import RecordingList from '../components/RecordingList';
|
|
import type { User, Recording } from '@/types';
|
|
|
|
export default function DashboardPage() {
|
|
const [user, setUser] = useState<User | null>(null);
|
|
const [recordings, setRecordings] = useState<Recording[]>([]);
|
|
const [isRecording, setIsRecording] = useState(false);
|
|
const [isListening, setIsListening] = useState(true);
|
|
const [currentRecording, setCurrentRecording] = useState<Recording | null>(null);
|
|
const router = useRouter();
|
|
|
|
useEffect(() => {
|
|
// Fetch current user
|
|
fetch('/api/auth/me')
|
|
.then(res => {
|
|
if (!res.ok) {
|
|
router.push('/login');
|
|
return null;
|
|
}
|
|
return res.json();
|
|
})
|
|
.then(data => {
|
|
if (data) setUser(data);
|
|
})
|
|
.catch(() => router.push('/login'));
|
|
|
|
// Fetch recordings
|
|
fetch('/api/recordings')
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.recordings) {
|
|
setRecordings(data.recordings);
|
|
}
|
|
})
|
|
.catch(console.error);
|
|
}, [router]);
|
|
|
|
const handleStartRecording = () => {
|
|
setIsRecording(true);
|
|
};
|
|
|
|
const handleStopRecording = async (audioBlob: Blob) => {
|
|
setIsRecording(false);
|
|
|
|
// Upload recording
|
|
const formData = new FormData();
|
|
formData.append('audio', audioBlob);
|
|
formData.append('duration', '60'); // Placeholder duration
|
|
|
|
try {
|
|
const response = await fetch('/api/recordings', {
|
|
method: 'POST',
|
|
body: formData,
|
|
});
|
|
|
|
if (response.ok) {
|
|
const newRecording = await response.json();
|
|
setRecordings([newRecording, ...recordings]);
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to upload recording:', error);
|
|
}
|
|
};
|
|
|
|
const handleSelectRecording = (id: string) => {
|
|
router.push(`/recordings/${id}`);
|
|
};
|
|
|
|
const handleDeleteRecording = async (id: string) => {
|
|
try {
|
|
const response = await fetch(`/api/recordings/${id}`, {
|
|
method: 'DELETE',
|
|
});
|
|
|
|
if (response.ok) {
|
|
setRecordings(recordings.filter(r => r.id !== id));
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to delete recording:', error);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="flex min-h-screen bg-gray-50">
|
|
<Sidebar activePath="/dashboard" />
|
|
<div className="flex-1">
|
|
<Header user={user} />
|
|
<main className="p-6">
|
|
<div className="max-w-4xl mx-auto">
|
|
<h1 className="text-3xl font-bold text-gray-900 mb-8">Dashboard</h1>
|
|
|
|
<div className="bg-white border rounded-lg p-8 mb-8 text-center">
|
|
<div className="mb-6">
|
|
<RecordButton
|
|
isRecording={isRecording}
|
|
onStartRecording={handleStartRecording}
|
|
onStopRecording={handleStopRecording}
|
|
/>
|
|
</div>
|
|
<WakeWordIndicator
|
|
isListening={isListening}
|
|
wakeWord="create an app"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<h2 className="text-xl font-semibold text-gray-900 mb-4">
|
|
Recent Recordings
|
|
</h2>
|
|
<RecordingList
|
|
recordings={recordings.slice(0, 5)}
|
|
onSelectRecording={handleSelectRecording}
|
|
onDeleteRecording={handleDeleteRecording}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|