Files
nextjs-boilerplate/app/[locale]/admin/tutorials/actions.ts
T

144 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use server'
import { revalidatePath } from 'next/cache'
import { auth } from '@/lib/auth'
import { supabaseAdmin } from '@/lib/supabaseAdmin'
import { extractYoutubeId } from './utils'
async function requireAdmin() {
const session = await auth()
if (!session || (session.user as any)?.role !== 'ADMIN') {
throw new Error('Yetkisiz erişim')
}
}
export async function createTutorialAction(formData: FormData) {
await requireAdmin()
const title = String(formData.get('title') || '').trim()
const description = String(formData.get('description') || '').trim()
const category = String(formData.get('category') || 'basics').trim()
const categoryLabel = String(formData.get('category_label') || '🚀 Hızlı Başlangıç').trim()
const duration = String(formData.get('duration') || '03:00').trim()
const rawYoutube = String(formData.get('youtube_id') || '').trim()
const youtubeId = extractYoutubeId(rawYoutube)
const targetView = String(formData.get('target_view') || '').trim() || null
const targetViewLabel = String(formData.get('target_view_label') || '').trim() || null
const highlightsRaw = String(formData.get('highlights') || '').trim()
const sortOrder = parseInt(String(formData.get('sort_order') || '0'), 10) || 0
const isActive = formData.get('is_active') === 'on' || formData.get('is_active') === 'true'
const highlights = highlightsRaw
? highlightsRaw.split('\n').map((s) => s.trim()).filter(Boolean)
: []
if (!title) throw new Error('Video başlığı zorunludur')
if (!youtubeId) throw new Error('Geçerli bir YouTube video linki veya ID giriniz')
const { error } = await supabaseAdmin.from('tutorials').insert({
title,
description,
category,
category_label: categoryLabel,
duration,
youtube_id: youtubeId,
target_view: targetView,
target_view_label: targetViewLabel,
highlights,
sort_order: sortOrder,
is_active: isActive,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
})
if (error) {
throw new Error(`Kayıt hatası: ${error.message}`)
}
revalidatePath('/admin/tutorials')
return { success: true }
}
export async function updateTutorialAction(formData: FormData) {
await requireAdmin()
const id = String(formData.get('id') || '').trim()
if (!id) throw new Error('Video ID eksik')
const title = String(formData.get('title') || '').trim()
const description = String(formData.get('description') || '').trim()
const category = String(formData.get('category') || 'basics').trim()
const categoryLabel = String(formData.get('category_label') || '🚀 Hızlı Başlangıç').trim()
const duration = String(formData.get('duration') || '03:00').trim()
const rawYoutube = String(formData.get('youtube_id') || '').trim()
const youtubeId = extractYoutubeId(rawYoutube)
const targetView = String(formData.get('target_view') || '').trim() || null
const targetViewLabel = String(formData.get('target_view_label') || '').trim() || null
const highlightsRaw = String(formData.get('highlights') || '').trim()
const sortOrder = parseInt(String(formData.get('sort_order') || '0'), 10) || 0
const isActive = formData.get('is_active') === 'on' || formData.get('is_active') === 'true'
const highlights = highlightsRaw
? highlightsRaw.split('\n').map((s) => s.trim()).filter(Boolean)
: []
if (!title) throw new Error('Video başlığı zorunludur')
if (!youtubeId) throw new Error('Geçerli bir YouTube video linki veya ID giriniz')
const { error } = await supabaseAdmin
.from('tutorials')
.update({
title,
description,
category,
category_label: categoryLabel,
duration,
youtube_id: youtubeId,
target_view: targetView,
target_view_label: targetViewLabel,
highlights,
sort_order: sortOrder,
is_active: isActive,
updated_at: new Date().toISOString(),
})
.eq('id', id)
if (error) {
throw new Error(`Güncelleme hatası: ${error.message}`)
}
revalidatePath('/admin/tutorials')
return { success: true }
}
export async function deleteTutorialAction(id: string) {
await requireAdmin()
if (!id) throw new Error('Video ID eksik')
const { error } = await supabaseAdmin.from('tutorials').delete().eq('id', id)
if (error) {
throw new Error(`Silme hatası: ${error.message}`)
}
revalidatePath('/admin/tutorials')
return { success: true }
}
export async function toggleTutorialStatusAction(id: string, newStatus: boolean) {
await requireAdmin()
const { error } = await supabaseAdmin
.from('tutorials')
.update({ is_active: newStatus, updated_at: new Date().toISOString() })
.eq('id', id)
if (error) {
throw new Error(`Durum güncelleme hatası: ${error.message}`)
}
revalidatePath('/admin/tutorials')
return { success: true }
}