[dyad] Added an account page to manage clips - wrote 3 file(s), executed 1 SQL queries
This commit is contained in:
82
src/app/account/page.tsx
Normal file
82
src/app/account/page.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { Loader2, Video } from 'lucide-react';
|
||||
import { UserClips } from '@/components/user-clips';
|
||||
import Link from 'next/link';
|
||||
import { Button } from '@/components/ui/button';
|
||||
|
||||
export type Clip = {
|
||||
id: string;
|
||||
short_id: string;
|
||||
title: string;
|
||||
storage_path: string;
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
export default function AccountPage() {
|
||||
const router = useRouter();
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [clips, setClips] = useState<Clip[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchUserAndClips = async () => {
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
if (!user) {
|
||||
router.push('/login');
|
||||
return;
|
||||
}
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('clips')
|
||||
.select('id, short_id, title, storage_path, created_at')
|
||||
.eq('user_id', user.id)
|
||||
.order('created_at', { ascending: false });
|
||||
|
||||
if (error) {
|
||||
console.error('Error fetching clips:', error);
|
||||
} else {
|
||||
setClips(data as Clip[]);
|
||||
}
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
fetchUserAndClips();
|
||||
}, [router]);
|
||||
|
||||
const onClipDeleted = (clipId: string) => {
|
||||
setClips(prevClips => prevClips.filter(clip => clip.id !== clipId));
|
||||
};
|
||||
|
||||
const onClipUpdated = (updatedClip: Clip) => {
|
||||
setClips(prevClips => prevClips.map(clip => clip.id === updatedClip.id ? updatedClip : clip));
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<Loader2 className="w-12 h-12 animate-spin text-primary" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container mx-auto max-w-5xl py-24 px-4">
|
||||
<h1 className="text-4xl font-bold tracking-tight mb-8">My Clips</h1>
|
||||
{clips.length > 0 ? (
|
||||
<UserClips clips={clips} onClipDeleted={onClipDeleted} onClipUpdated={onClipUpdated} />
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center text-center py-16 px-6 border-2 border-dashed rounded-lg">
|
||||
<Video className="w-16 h-16 mb-4 text-muted-foreground" />
|
||||
<h2 className="text-2xl font-semibold mb-2">No clips yet</h2>
|
||||
<p className="text-muted-foreground mb-6">You haven't created any clips. Go ahead and make your first one!</p>
|
||||
<Button asChild>
|
||||
<Link href="/">Create a Clip</Link>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user