diff --git a/app/[locale]/admin/blog/page.tsx b/app/[locale]/admin/blog/page.tsx index c44cd8f..46c805f 100644 --- a/app/[locale]/admin/blog/page.tsx +++ b/app/[locale]/admin/blog/page.tsx @@ -1,6 +1,7 @@ import { mockDb } from '@/lib/mockDb' import { deleteBlogPostAction } from '@/app/actions' import { Link } from '@/i18n/routing' +import DeleteButton from '@/components/DeleteButton' import { Edit, Trash, Plus, FileText, CheckCircle, XCircle } from 'lucide-react' export default async function AdminBlogPage() { @@ -97,17 +98,11 @@ export default async function AdminBlogPage() { -
{ + { 'use server' await deleteBlogPostAction(post.id) }}> - + @@ -118,6 +113,14 @@ export default async function AdminBlogPage() { + + + + Yeni Yazı Ekle + ) diff --git a/app/[locale]/admin/categories/[id]/page.tsx b/app/[locale]/admin/categories/[id]/page.tsx index b4ab390..f01801f 100644 --- a/app/[locale]/admin/categories/[id]/page.tsx +++ b/app/[locale]/admin/categories/[id]/page.tsx @@ -30,7 +30,7 @@ export default async function CategoryFormPage({ params }: { params: Promise<{ i
-
+
diff --git a/app/[locale]/admin/categories/page.tsx b/app/[locale]/admin/categories/page.tsx index 5583704..49ecc42 100644 --- a/app/[locale]/admin/categories/page.tsx +++ b/app/[locale]/admin/categories/page.tsx @@ -53,7 +53,7 @@ export default async function AdminCategoriesPage() { > - + diff --git a/app/[locale]/admin/neighborhoods/[id]/page.tsx b/app/[locale]/admin/neighborhoods/[id]/page.tsx index 267eda4..d85c416 100644 --- a/app/[locale]/admin/neighborhoods/[id]/page.tsx +++ b/app/[locale]/admin/neighborhoods/[id]/page.tsx @@ -30,7 +30,7 @@ export default async function NeighborhoodFormPage({ params }: { params: Promise
-
+
diff --git a/app/actions.ts b/app/actions.ts index b8d3d70..151a56a 100644 --- a/app/actions.ts +++ b/app/actions.ts @@ -46,7 +46,7 @@ export async function submitBusinessAction(formData: FormData) { }) revalidatePath('/admin/submissions') - return { success: true } + return { success: true, error: undefined } } export async function submitContactMessageAction(formData: FormData) { @@ -67,7 +67,7 @@ export async function submitContactMessageAction(formData: FormData) { }) revalidatePath('/admin/messages') - return { success: true } + return { success: true, error: undefined } } export async function approveSubmissionAction(id: string) { @@ -105,13 +105,13 @@ export async function approveSubmissionAction(id: string) { revalidatePath('/restaurants') revalidatePath('/aparts') revalidatePath('/businesses') - return { success: true } + return { success: true, error: undefined } } export async function rejectSubmissionAction(id: string) { await mockDb.updateSubmissionStatus(id, 'REJECTED') revalidatePath('/admin/submissions') - return { success: true } + return { success: true, error: undefined } } export async function deleteListingAction(id: string) { @@ -120,21 +120,21 @@ export async function deleteListingAction(id: string) { revalidatePath('/restaurants') revalidatePath('/aparts') revalidatePath('/businesses') - return { success: true } + return { success: true, error: undefined } } export async function restoreListingAction(id: string) { await mockDb.restoreListing(id) revalidatePath('/admin/trash') revalidatePath('/admin/listings') - return { success: true } + return { success: true, error: undefined } } export async function hardDeleteListingAction(id: string) { try { await mockDb.hardDeleteListing(id) revalidatePath('/admin/trash') - return { success: true } + return { success: true, error: undefined } } catch (err: any) { if (err.message?.includes('RESTRICT') || err.message?.includes('Foreign key constraint')) { return { success: false, error: 'Silme başarısız: Bu mekana bağlı etkinlik (Event) veya kayıtlar var.' } @@ -146,7 +146,7 @@ export async function hardDeleteListingAction(id: string) { export async function markMessageReadAction(id: string) { await mockDb.markMessageAsRead(id) revalidatePath('/admin/messages') - return { success: true } + return { success: true, error: undefined } } export async function createOrUpdateListingAction(formData: FormData) { @@ -250,7 +250,7 @@ export async function createOrUpdateListingAction(formData: FormData) { revalidatePath('/restaurants') revalidatePath('/aparts') revalidatePath('/businesses') - return { success: true } + return { success: true, error: undefined } } catch (err: any) { return { success: false, error: err.message || 'Mekan kaydedilemedi.' } } @@ -261,7 +261,7 @@ export async function deleteBlogPostAction(id: string) { await mockDb.deleteBlogPost(id) revalidatePath('/admin/blog') revalidatePath('/blog') - return { success: true } + return { success: true, error: undefined } } export async function createOrUpdateBlogPostAction(formData: FormData) { @@ -319,7 +319,7 @@ export async function createOrUpdateBlogPostAction(formData: FormData) { revalidatePath('/admin/blog') revalidatePath('/blog') revalidatePath(`/blog/${slug}`) - return { success: true } + return { success: true, error: undefined } } catch (err: any) { return { success: false, error: err.message || 'Yazı kaydedilemedi.' } } @@ -330,7 +330,7 @@ export async function deleteCollectionAction(id: string) { await mockDb.deleteCollection(id) revalidatePath('/admin/collections') revalidatePath('/collections') - return { success: true } + return { success: true, error: undefined } } export async function createOrUpdateCollectionAction(formData: FormData) { @@ -380,7 +380,7 @@ export async function createOrUpdateCollectionAction(formData: FormData) { revalidatePath('/admin/collections') revalidatePath('/collections') revalidatePath(`/collection/${slug}`) - return { success: true } + return { success: true, error: undefined } } catch (err: any) { return { success: false, error: err.message || 'Koleksiyon kaydedilemedi.' } } @@ -391,7 +391,7 @@ export async function deleteEventAction(id: string) { await mockDb.deleteEvent(id) revalidatePath('/admin/events') revalidatePath('/events') - return { success: true } + return { success: true, error: undefined } } export async function createOrUpdateEventAction(formData: FormData) { @@ -449,7 +449,7 @@ export async function createOrUpdateEventAction(formData: FormData) { revalidatePath('/admin/events') revalidatePath('/events') revalidatePath(`/event/${slug}`) - return { success: true } + return { success: true, error: undefined } } catch (err: any) { return { success: false, error: err.message || 'Etkinlik kaydedilemedi.' } } @@ -464,7 +464,7 @@ export async function deleteNeighborhoodAction(id: string) { await mockDb.deleteNeighborhood(id) revalidatePath('/admin/neighborhoods') - return { success: true } + return { success: true, error: undefined } } catch (err: any) { if (err.message?.includes('RESTRICT') || err.message?.includes('Foreign key constraint')) { return { success: false, error: 'Silme başarısız: Bu mahalleye bağlı gizli (silinmiş veya arşivlenmiş) mekanlar veya etkinlikler var.' } @@ -498,7 +498,7 @@ export async function createOrUpdateNeighborhoodAction(formData: FormData) { await mockDb.createNeighborhood(data) } revalidatePath('/admin/neighborhoods') - return { success: true } + return { success: true, error: undefined } } catch (err: any) { return { success: false, error: err.message || 'Mahalle kaydedilemedi.' } } @@ -606,3 +606,60 @@ export async function deleteCategoryAction(formData: FormData) { await mockDb.deleteCategory(id) revalidatePath('/admin/categories') } + +export async function deleteSubmissionAction(id: string) { + await mockDb.deleteSubmission(id) + revalidatePath('/admin/submissions') + return { success: true, error: undefined } +} + +export async function deleteMessageAction(id: string) { + await mockDb.deleteMessage(id) + revalidatePath('/admin/messages') + return { success: true, error: undefined } +} + +export async function searchListingsAction(query: string) { + if (!query || query.length < 2) return [] + + const allListings = await mockDb.getListings() + const q = query.toLowerCase() + + const results = allListings.filter(l => + !l.deletedAt && ( + l.nameTr.toLowerCase().includes(q) || + l.nameEn?.toLowerCase().includes(q) || + l.nameRu?.toLowerCase().includes(q) + ) + ).slice(0, 5) // Return max 5 suggestions + + return results.map(l => ({ + id: l.id, + nameTr: l.nameTr, + nameEn: l.nameEn, + nameRu: l.nameRu, + slug: l.slug, + categorySlug: l.category?.slug || 'restoran' + })) +} + +export async function saveWidgetPartnerAction(formData: FormData) { + const id = formData.get('id') as string | null + const name = formData.get('name') as string + const logoUrl = formData.get('logoUrl') as string + const websiteUrl = formData.get('websiteUrl') as string + const widgetType = formData.get('widgetType') as string + + if (!name || !logoUrl || !websiteUrl) { + return { error: 'Lütfen zorunlu alanları doldurun.' } + } + + if (id) { + await mockDb.updateWidgetPartner(id, { name, logoUrl, websiteUrl, widgetType }) + } else { + await mockDb.createWidgetPartner({ name, logoUrl, websiteUrl, widgetType }) + } + + revalidatePath('/admin/widget-partners') + return { success: true, error: undefined } +} diff --git a/package.json b/package.json index 40dbad0..69e03b4 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,5 @@ "tailwindcss": "^4", "tsx": "^4.23.0", "typescript": "^5" - }, - "prisma": { - "seed": "tsx prisma/seed.ts" } } diff --git a/prisma.config.ts b/prisma.config.ts new file mode 100644 index 0000000..046f5ca --- /dev/null +++ b/prisma.config.ts @@ -0,0 +1,5 @@ +import { defineConfig } from '@prisma/config' + +export default defineConfig({ + seed: 'tsx prisma/seed.ts' +})