154 lines
4.5 KiB
TypeScript
154 lines
4.5 KiB
TypeScript
'use server';
|
|
|
|
import { prisma } from '@/lib/prisma';
|
|
import { auth } from '@/lib/auth';
|
|
import { headers } from 'next/headers';
|
|
import { revalidatePath } from 'next/cache';
|
|
import { redirect } from 'next/navigation';
|
|
import { z } from 'zod';
|
|
|
|
const VideoSchema = z.object({
|
|
title: z.string().min(1),
|
|
description: z.string().optional(),
|
|
videoUrl: z.string().min(1),
|
|
videoType: z.enum(['YOUTUBE', 'LOCAL']),
|
|
isPublic: z.boolean(),
|
|
menuId: z.string().optional(),
|
|
});
|
|
|
|
export async function createVideo(data: {
|
|
title: string;
|
|
description: string;
|
|
videoUrl: string;
|
|
videoType: 'YOUTUBE' | 'LOCAL';
|
|
isPublic: boolean;
|
|
menuId?: string;
|
|
}) {
|
|
const session = await auth.api.getSession({
|
|
headers: await headers()
|
|
});
|
|
|
|
if (!session?.user) {
|
|
throw new Error('Unauthorized');
|
|
}
|
|
|
|
// Get user profile
|
|
const userProfile = await prisma.userProfile.findUnique({
|
|
where: { userId: session.user.id },
|
|
});
|
|
|
|
if (!userProfile) {
|
|
throw new Error('User profile not found. Please complete your profile first.');
|
|
}
|
|
|
|
const validatedData = VideoSchema.parse(data);
|
|
|
|
let thumbnailUrl = null;
|
|
if (validatedData.videoType === 'YOUTUBE') {
|
|
const videoId = extractYoutubeId(validatedData.videoUrl);
|
|
if (videoId) {
|
|
thumbnailUrl = `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`;
|
|
}
|
|
}
|
|
|
|
await prisma.video.create({
|
|
data: {
|
|
...validatedData,
|
|
uploaderId: userProfile.id,
|
|
thumbnailUrl,
|
|
createdBy: session.user.id,
|
|
updatedBy: session.user.id,
|
|
},
|
|
});
|
|
|
|
revalidatePath('/dashboard/videos');
|
|
if (validatedData.menuId) {
|
|
// We need to find the slug to revalidate the page, but revalidating the layout might be enough or we can just revalidate the specific page if we fetch the menu.
|
|
// For now, let's revalidate the dashboard layout to be safe or just the videos page.
|
|
// Actually, we can fetch the menu to get the slug.
|
|
const menu = await prisma.menu.findUnique({ where: { id: validatedData.menuId } });
|
|
if (menu) {
|
|
revalidatePath(`/dashboard/pages/${menu.slug}`);
|
|
}
|
|
}
|
|
|
|
redirect('/dashboard/videos');
|
|
}
|
|
|
|
export async function updateVideo(id: string, data: {
|
|
title: string;
|
|
description: string;
|
|
videoUrl: string;
|
|
videoType: 'YOUTUBE' | 'LOCAL';
|
|
isPublic: boolean;
|
|
menuId?: string;
|
|
}) {
|
|
const session = await auth.api.getSession({
|
|
headers: await headers()
|
|
});
|
|
|
|
if (!session?.user) {
|
|
throw new Error('Unauthorized');
|
|
}
|
|
|
|
// Get user profile
|
|
const userProfile = await prisma.userProfile.findUnique({
|
|
where: { userId: session.user.id },
|
|
});
|
|
|
|
if (!userProfile) {
|
|
throw new Error('User profile not found. Please complete your profile first.');
|
|
}
|
|
|
|
// Check if user owns the video
|
|
const existingVideo = await prisma.video.findUnique({
|
|
where: { id },
|
|
});
|
|
|
|
if (!existingVideo || existingVideo.uploaderId !== userProfile.id) {
|
|
throw new Error('Video not found or you do not have permission to edit it');
|
|
}
|
|
|
|
const validatedData = VideoSchema.parse(data);
|
|
|
|
let thumbnailUrl = existingVideo.thumbnailUrl;
|
|
if (validatedData.videoType === 'YOUTUBE') {
|
|
const videoId = extractYoutubeId(validatedData.videoUrl);
|
|
if (videoId) {
|
|
thumbnailUrl = `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`;
|
|
}
|
|
}
|
|
|
|
await prisma.video.update({
|
|
where: { id },
|
|
data: {
|
|
...validatedData,
|
|
thumbnailUrl,
|
|
updatedBy: session.user.id,
|
|
},
|
|
});
|
|
|
|
revalidatePath('/dashboard/videos');
|
|
revalidatePath(`/dashboard/videos/${id}`);
|
|
if (validatedData.menuId) {
|
|
const menu = await prisma.menu.findUnique({ where: { id: validatedData.menuId } });
|
|
if (menu) {
|
|
revalidatePath(`/dashboard/pages/${menu.slug}`);
|
|
}
|
|
}
|
|
if (existingVideo.menuId && existingVideo.menuId !== validatedData.menuId) {
|
|
const oldMenu = await prisma.menu.findUnique({ where: { id: existingVideo.menuId } });
|
|
if (oldMenu) {
|
|
revalidatePath(`/dashboard/pages/${oldMenu.slug}`);
|
|
}
|
|
}
|
|
|
|
redirect(`/dashboard/videos/${id}`);
|
|
}
|
|
|
|
function extractYoutubeId(url: string) {
|
|
const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/;
|
|
const match = url.match(regExp);
|
|
return (match && match[2].length === 11) ? match[2] : null;
|
|
}
|