Files
ACVE/components/teacher/VideoUpload.tsx
2026-02-17 00:07:00 +00:00

95 lines
3.4 KiB
TypeScript

"use client";
import { useState } from "react";
import { createBrowserClient } from "@supabase/ssr";
import { toast } from "sonner"; // or use alert()
interface VideoUploadProps {
lessonId: string;
currentVideoUrl?: string | null;
onUploadComplete: (url: string) => void; // Callback to save to DB
}
export default function VideoUpload({ lessonId, currentVideoUrl, onUploadComplete }: VideoUploadProps) {
const [uploading, setUploading] = useState(false);
const [progress, setProgress] = useState(0);
const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
setUploading(true);
setProgress(0);
const supabase = createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
// Create a unique file path: lesson_id/timestamp_filename
const filePath = `${lessonId}/${Date.now()}_${file.name}`;
const { error } = await supabase.storage
.from("courses") // Make sure this bucket exists!
.upload(filePath, file, {
upsert: true,
});
if (error) {
toast.error("Upload failed: " + error.message);
setUploading(false);
return;
}
// Get Public URL
const { data: { publicUrl } } = supabase.storage
.from("courses")
.getPublicUrl(filePath);
onUploadComplete(publicUrl);
setUploading(false);
};
return (
<div className="border border-slate-200 rounded-lg p-6 bg-slate-50">
<h3 className="font-medium text-slate-900 mb-2">Video de la Lección</h3>
{currentVideoUrl ? (
<div className="mb-4 aspect-video bg-black rounded-md overflow-hidden relative group">
<video src={currentVideoUrl} controls className="w-full h-full" />
<div className="absolute inset-0 bg-black/50 hidden group-hover:flex items-center justify-center">
<p className="text-white text-sm">Subir otro para reemplazar</p>
</div>
</div>
) : (
<div className="mb-4 aspect-video bg-slate-200 rounded-md flex items-center justify-center text-slate-400">
Sin video
</div>
)}
<div className="flex flex-col gap-2">
<label className="block w-full">
<span className="sr-only">Choose video</span>
<input
type="file"
accept="video/*"
onChange={handleUpload}
disabled={uploading}
className="block w-full text-sm text-slate-500
file:mr-4 file:py-2 file:px-4
file:rounded-full file:border-0
file:text-sm file:font-semibold
file:bg-black file:text-white
hover:file:bg-slate-800
"
/>
</label>
{uploading && (
<div className="w-full bg-slate-200 rounded-full h-2 mt-2">
<div className="bg-black h-2 rounded-full transition-all" style={{ width: `${progress}%` }}></div>
</div>
)}
</div>
</div>
);
}