'use server'; import { db } from '@/lib/db'; import { revalidatePath } from 'next/cache'; function extractYoutubeId(url: string): string { if (!url) return 'dQw4w9WgXcQ'; const trimmed = url.trim(); if (trimmed.includes('v=')) { return trimmed.split('v=')[1].split('&')[0]; } if (trimmed.includes('youtu.be/')) { return trimmed.split('youtu.be/')[1].split('?')[0]; } if (trimmed.includes('embed/')) { return trimmed.split('embed/')[1].split('?')[0]; } if (trimmed.length === 11) { return trimmed; } return 'dQw4w9WgXcQ'; } export async function getLessons(options?: { query?: string; category?: string }) { try { const { query, category } = options || {}; const where: any = {}; if (category) { where.category = category; } if (query && query.trim() !== '') { const q = query.trim(); where.OR = [ { title: { contains: q, mode: 'insensitive' } }, { summary: { contains: q, mode: 'insensitive' } }, { tags: { hasSome: [q] } }, ]; } const lessons = await db.lesson.findMany({ where, include: { codeSnippets: true, downloads: true, chapters: true, }, orderBy: { createdAt: 'desc', }, }); return lessons; } catch (error) { console.error('Error fetching lessons:', error); return []; } } export async function getLessonBySlug(slug: string) { try { const lesson = await db.lesson.findUnique({ where: { slug }, include: { codeSnippets: true, downloads: true, chapters: { orderBy: { seconds: 'asc' }, }, }, }); if (lesson) { await db.lesson.update({ where: { id: lesson.id }, data: { viewsCount: { increment: 1 } }, }).catch(err => console.error('Failed to increment view count:', err)); } return lesson; } catch (error) { console.error('Error fetching lesson by slug:', error); return null; } } export async function getDashboardStats() { try { const [totalLessons, aggregate, totalMessages] = await Promise.all([ db.lesson.count(), db.lesson.aggregate({ _sum: { viewsCount: true, downloadCount: true, }, }), db.contactMessage.count(), ]); return { totalLessons, totalViews: aggregate._sum.viewsCount || 0, totalDownloads: aggregate._sum.downloadCount || 0, totalMessages, }; } catch (error) { console.error('Error fetching dashboard stats:', error); return { totalLessons: 0, totalViews: 0, totalDownloads: 0, totalMessages: 0, }; } } export async function createLesson(data: { title: string; youtubeUrl: string; category: string; summary: string; duration?: string; notesMarkdown?: string[]; codeSnippets?: { fileName: string; language: string; code: string }[]; downloads?: { title: string; type: string; url: string; size?: string }[]; chapters?: { time: string; seconds: number; title: string }[]; }) { try { const slug = data.title .toLowerCase() .trim() .replace(/[^\w\s-]/g, '') .replace(/[\s_-]+/g, '-') .replace(/^-+|-+$/g, '') + '-' + Date.now().toString().slice(-4); const youtubeId = extractYoutubeId(data.youtubeUrl); const thumbnailUrl = `https://img.youtube.com/vi/${youtubeId}/hqdefault.jpg`; const codeSnippets = data.codeSnippets || []; const downloads = data.downloads || []; const chapters = data.chapters || []; const notesMarkdown = data.notesMarkdown || []; const newLesson = await db.lesson.create({ data: { title: data.title, slug, youtubeId, youtubeUrl: data.youtubeUrl || `https://www.youtube.com/watch?v=${youtubeId}`, thumbnailUrl, duration: data.duration || '15:00', category: data.category, tags: [data.category, 'Tutorial', 'Source Code'], summary: data.summary || data.title, notesMarkdown, codeSnippets: { create: codeSnippets.map((snip) => ({ fileName: snip.fileName || 'app/page.tsx', language: snip.language || 'typescript', code: snip.code, })), }, downloads: { create: downloads.map((dl) => ({ title: dl.title, type: dl.type || 'zip', url: dl.url || '#', size: dl.size || '1.0 MB', })), }, chapters: { create: chapters.map((chap) => ({ time: chap.time, seconds: chap.seconds || 0, title: chap.title, })), }, }, }); revalidatePath('/[locale]'); revalidatePath('/[locale]/lessons'); return { success: true, lesson: newLesson }; } catch (error: any) { console.error('Error creating lesson:', error); return { success: false, error: error.message || 'Failed to create lesson in database' }; } } export async function updateLesson(id: string, data: { title: string; youtubeUrl: string; category: string; summary: string; duration?: string; notesMarkdown?: string[]; codeSnippets?: { fileName: string; language: string; code: string }[]; downloads?: { title: string; type: string; url: string; size?: string }[]; chapters?: { time: string; seconds: number; title: string }[]; }) { try { const youtubeId = extractYoutubeId(data.youtubeUrl); const thumbnailUrl = `https://img.youtube.com/vi/${youtubeId}/hqdefault.jpg`; const codeSnippets = data.codeSnippets || []; const downloads = data.downloads || []; const chapters = data.chapters || []; const notesMarkdown = data.notesMarkdown || []; // Delete existing sub-models and recreate await Promise.all([ db.codeSnippet.deleteMany({ where: { lessonId: id } }), db.resourceDownload.deleteMany({ where: { lessonId: id } }), db.videoChapter.deleteMany({ where: { lessonId: id } }), ]); const updatedLesson = await db.lesson.update({ where: { id }, data: { title: data.title, youtubeId, youtubeUrl: data.youtubeUrl, thumbnailUrl, duration: data.duration || '15:00', category: data.category, summary: data.summary, notesMarkdown, codeSnippets: { create: codeSnippets.map((snip) => ({ fileName: snip.fileName || 'app/page.tsx', language: snip.language || 'typescript', code: snip.code, })), }, downloads: { create: downloads.map((dl) => ({ title: dl.title, type: dl.type || 'zip', url: dl.url || '#', size: dl.size || '1.0 MB', })), }, chapters: { create: chapters.map((chap) => ({ time: chap.time, seconds: chap.seconds || 0, title: chap.title, })), }, }, }); revalidatePath('/[locale]'); revalidatePath('/[locale]/lessons'); return { success: true, lesson: updatedLesson }; } catch (error: any) { console.error('Error updating lesson:', error); return { success: false, error: error.message || 'Failed to update lesson' }; } } export async function deleteLesson(id: string) { try { await db.lesson.delete({ where: { id } }); revalidatePath('/[locale]'); revalidatePath('/[locale]/lessons'); return { success: true }; } catch (error) { console.error('Error deleting lesson:', error); return { success: false }; } } export async function incrementDownloadCount(lessonId: string) { try { await db.lesson.update({ where: { id: lessonId }, data: { downloadCount: { increment: 1 } }, }); revalidatePath('/[locale]/dersler'); return { success: true }; } catch (error) { console.error('Error incrementing download count:', error); return { success: false }; } }