Initial commit
This commit is contained in:
159
app/dashboard/page.tsx
Normal file
159
app/dashboard/page.tsx
Normal file
@ -0,0 +1,159 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Header from "@/components/Header";
|
||||
import AudioRecorder from "@/components/AudioRecorder";
|
||||
import RecordingList from "@/components/RecordingList";
|
||||
import LoadingSpinner from "@/components/LoadingSpinner";
|
||||
|
||||
interface Recording {
|
||||
id: string;
|
||||
title: string;
|
||||
duration: number;
|
||||
createdAt: string;
|
||||
audioUrl: string;
|
||||
}
|
||||
|
||||
export default function DashboardPage() {
|
||||
const { data: session, status } = useSession();
|
||||
const router = useRouter();
|
||||
const [recordings, setRecordings] = useState<Recording[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
// 处理录音更新
|
||||
const handleRecordingUpdated = useCallback((updatedRecording: Recording) => {
|
||||
setRecordings((prevRecordings) =>
|
||||
prevRecordings.map((recording) =>
|
||||
recording.id === updatedRecording.id ? updatedRecording : recording
|
||||
)
|
||||
);
|
||||
}, []);
|
||||
|
||||
// 获取录音列表
|
||||
const fetchRecordings = useCallback(async () => {
|
||||
try {
|
||||
const response = await fetch("/api/recordings");
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
if (result.success && Array.isArray(result.data)) {
|
||||
setRecordings(result.data);
|
||||
} else {
|
||||
console.error("API 返回数据格式错误:", result);
|
||||
setRecordings([]);
|
||||
}
|
||||
} else {
|
||||
console.error("获取录音列表失败:", response.status);
|
||||
setRecordings([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取录音列表失败:", error);
|
||||
setRecordings([]);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 监听录音上传和删除事件
|
||||
useEffect(() => {
|
||||
const handleRecordingUploaded = () => {
|
||||
// 延迟一点时间确保服务器处理完成
|
||||
setTimeout(() => {
|
||||
fetchRecordings();
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const handleRecordingDeleted = () => {
|
||||
// 延迟一点时间确保服务器处理完成
|
||||
setTimeout(() => {
|
||||
fetchRecordings();
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const handleRecordingRenamed = () => {
|
||||
// 立即清除可能的缓存
|
||||
// 延迟一点时间确保服务器处理完成
|
||||
setTimeout(() => {
|
||||
fetchRecordings();
|
||||
}, 100); // 减少延迟时间
|
||||
};
|
||||
|
||||
window.addEventListener("recording-uploaded", handleRecordingUploaded);
|
||||
window.addEventListener("recording-deleted", handleRecordingDeleted);
|
||||
window.addEventListener("recording-renamed", handleRecordingRenamed);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("recording-uploaded", handleRecordingUploaded);
|
||||
window.removeEventListener("recording-deleted", handleRecordingDeleted);
|
||||
window.removeEventListener("recording-renamed", handleRecordingRenamed);
|
||||
};
|
||||
}, [fetchRecordings]);
|
||||
|
||||
// 初始加载录音列表
|
||||
useEffect(() => {
|
||||
if (status === "authenticated") {
|
||||
fetchRecordings();
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
// 检查认证状态
|
||||
if (status === "loading") {
|
||||
return (
|
||||
<div className="flex justify-center items-center min-h-screen">
|
||||
<LoadingSpinner size="lg" color="blue" text="加载中..." />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (status === "unauthenticated") {
|
||||
router.push("/login");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!session?.user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 dark:bg-gray-900">
|
||||
<Header />
|
||||
|
||||
<main className="container mx-auto p-4 md:p-8 max-w-6xl">
|
||||
<div className="mb-12">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
你好, {session.user.name || session.user.email}!
|
||||
</h2>
|
||||
<p className="text-gray-600 dark:text-gray-400 text-lg">
|
||||
准备好录制你的下一个杰作了吗?点击下方按钮开始。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-16">
|
||||
<AudioRecorder />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h3 className="text-2xl md:text-3xl font-semibold text-gray-900 dark:text-white">
|
||||
我的录音
|
||||
</h3>
|
||||
<button
|
||||
onClick={fetchRecordings}
|
||||
className="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
|
||||
>
|
||||
刷新列表
|
||||
</button>
|
||||
</div>
|
||||
{isLoading ? (
|
||||
<div className="text-center py-12">
|
||||
<LoadingSpinner size="lg" color="blue" text="加载录音中..." />
|
||||
</div>
|
||||
) : (
|
||||
<RecordingList recordings={recordings} />
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user