b
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
"use server";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function updateAboutSection(prevState: any, formData: FormData) {
|
||||
try {
|
||||
const lang = formData.get("lang") as string;
|
||||
const badge = formData.get("badge") as string;
|
||||
const titleLine1 = formData.get("titleLine1") as string;
|
||||
const titleLine2 = formData.get("titleLine2") as string;
|
||||
const titleHighlight = formData.get("titleHighlight") as string;
|
||||
const description1 = formData.get("description1") as string;
|
||||
const description2 = formData.get("description2") as string;
|
||||
const image = formData.get("image") as string;
|
||||
const statsGuestCount = formData.get("statsGuestCount") as string;
|
||||
const statsGuestLabel = formData.get("statsGuestLabel") as string;
|
||||
const statsYearCount = formData.get("statsYearCount") as string;
|
||||
const statsYearLabel = formData.get("statsYearLabel") as string;
|
||||
const badgeIkoTitle = formData.get("badgeIkoTitle") as string;
|
||||
const badgeIkoLabel = formData.get("badgeIkoLabel") as string;
|
||||
|
||||
await prisma.aboutSection.upsert({
|
||||
where: { lang },
|
||||
update: {
|
||||
badge,
|
||||
titleLine1,
|
||||
titleLine2,
|
||||
titleHighlight,
|
||||
description1,
|
||||
description2,
|
||||
image,
|
||||
statsGuestCount,
|
||||
statsGuestLabel,
|
||||
statsYearCount,
|
||||
statsYearLabel,
|
||||
badgeIkoTitle,
|
||||
badgeIkoLabel
|
||||
},
|
||||
create: {
|
||||
lang,
|
||||
badge,
|
||||
titleLine1,
|
||||
titleLine2,
|
||||
titleHighlight,
|
||||
description1,
|
||||
description2,
|
||||
image,
|
||||
statsGuestCount,
|
||||
statsGuestLabel,
|
||||
statsYearCount,
|
||||
statsYearLabel,
|
||||
badgeIkoTitle,
|
||||
badgeIkoLabel
|
||||
}
|
||||
});
|
||||
|
||||
revalidatePath('/admin/about');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
|
||||
return { success: true, message: "Hakkımızda bölümü başarıyla güncellendi." };
|
||||
} catch (error) {
|
||||
return { error: "Güncellenirken bir hata oluştu." };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
"use server";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function loadMockActivities() {
|
||||
await prisma.activity.deleteMany({});
|
||||
|
||||
const mockActivities = [
|
||||
{
|
||||
lang: "tr",
|
||||
title: "Kitesurf",
|
||||
description: "Başlangıçtan ileri seviyeye. Akyaka'nın ünlü termik rüzgarında uçun.",
|
||||
price: "₺2.000/Saat",
|
||||
image: "https://images.unsplash.com/photo-1526367790999-0150786686a2?q=80&w=2940&auto=format&fit=crop",
|
||||
badge: "IKO Sertifikalı",
|
||||
order: 1
|
||||
},
|
||||
{
|
||||
lang: "en",
|
||||
title: "Kitesurf",
|
||||
description: "From beginner to advanced. Fly in Akyaka's famous thermal wind.",
|
||||
price: "₺2.000/Hour",
|
||||
image: "https://images.unsplash.com/photo-1526367790999-0150786686a2?q=80&w=2940&auto=format&fit=crop",
|
||||
badge: "IKO Certified",
|
||||
order: 1
|
||||
},
|
||||
{
|
||||
lang: "tr",
|
||||
title: "Yoga",
|
||||
description: "Güne nehir kenarında huzur dolu bir yoga seansıyla başlayın.",
|
||||
price: "₺400/Seans",
|
||||
image: "https://images.unsplash.com/photo-1544367567-0f2fcb009e0b?q=80&w=2940&auto=format&fit=crop",
|
||||
badge: null,
|
||||
order: 2
|
||||
},
|
||||
{
|
||||
lang: "en",
|
||||
title: "Yoga",
|
||||
description: "Start the day with a peaceful yoga session by the river.",
|
||||
price: "₺400/Session",
|
||||
image: "https://images.unsplash.com/photo-1544367567-0f2fcb009e0b?q=80&w=2940&auto=format&fit=crop",
|
||||
badge: null,
|
||||
order: 2
|
||||
},
|
||||
{
|
||||
lang: "tr",
|
||||
title: "Stand-Up Paddle",
|
||||
description: "Azmak nehrinin berrak sularında eşsiz bir keşif.",
|
||||
price: "₺300/Saat",
|
||||
image: "https://images.unsplash.com/photo-1522883392419-7d8cb2435728?q=80&w=2924&auto=format&fit=crop",
|
||||
badge: null,
|
||||
order: 3
|
||||
},
|
||||
{
|
||||
lang: "en",
|
||||
title: "Stand-Up Paddle",
|
||||
description: "A unique discovery in the crystal clear waters of Azmak River.",
|
||||
price: "₺300/Hour",
|
||||
image: "https://images.unsplash.com/photo-1522883392419-7d8cb2435728?q=80&w=2924&auto=format&fit=crop",
|
||||
badge: null,
|
||||
order: 3
|
||||
},
|
||||
{
|
||||
lang: "tr",
|
||||
title: "Bisiklet Kiralama",
|
||||
description: "Akyaka Köy Turu ile doğanın tadını çıkarın.",
|
||||
price: "₺250/Gün",
|
||||
image: "https://images.unsplash.com/photo-1511994298241-608e28f14fde?q=80&w=2940&auto=format&fit=crop",
|
||||
badge: null,
|
||||
order: 4
|
||||
},
|
||||
{
|
||||
lang: "en",
|
||||
title: "Bicycle Rental",
|
||||
description: "Enjoy nature with an Akyaka Village Tour.",
|
||||
price: "₺250/Day",
|
||||
image: "https://images.unsplash.com/photo-1511994298241-608e28f14fde?q=80&w=2940&auto=format&fit=crop",
|
||||
badge: null,
|
||||
order: 4
|
||||
}
|
||||
];
|
||||
|
||||
await prisma.activity.createMany({ data: mockActivities });
|
||||
|
||||
revalidatePath('/admin/activities');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
}
|
||||
|
||||
export async function addActivity(prevState: any, formData: FormData) {
|
||||
try {
|
||||
const data = {
|
||||
lang: formData.get("lang") as string,
|
||||
title: formData.get("title") as string,
|
||||
description: formData.get("description") as string,
|
||||
price: formData.get("price") as string,
|
||||
image: formData.get("image") as string,
|
||||
badge: formData.get("badge") as string || null,
|
||||
order: parseInt(formData.get("order") as string || "0", 10),
|
||||
};
|
||||
|
||||
await prisma.activity.create({ data });
|
||||
|
||||
revalidatePath('/admin/activities');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
|
||||
return { success: true, message: "Aktivite başarıyla eklendi." };
|
||||
} catch (error) {
|
||||
return { error: "Aktivite eklenirken bir hata oluştu." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateActivity(prevState: any, formData: FormData) {
|
||||
try {
|
||||
const id = parseInt(formData.get("id") as string, 10);
|
||||
const data = {
|
||||
lang: formData.get("lang") as string,
|
||||
title: formData.get("title") as string,
|
||||
description: formData.get("description") as string,
|
||||
price: formData.get("price") as string,
|
||||
image: formData.get("image") as string,
|
||||
badge: formData.get("badge") as string || null,
|
||||
order: parseInt(formData.get("order") as string || "0", 10),
|
||||
};
|
||||
|
||||
await prisma.activity.update({
|
||||
where: { id },
|
||||
data
|
||||
});
|
||||
|
||||
revalidatePath('/admin/activities');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
|
||||
return { success: true, message: "Aktivite başarıyla güncellendi." };
|
||||
} catch (error) {
|
||||
return { error: "Aktivite güncellenirken bir hata oluştu." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteActivity(id: number) {
|
||||
try {
|
||||
await prisma.activity.delete({ where: { id } });
|
||||
revalidatePath('/admin/activities');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
return { success: true, message: "Aktivite silindi." };
|
||||
} catch (error) {
|
||||
return { error: "Silme işlemi başarısız." };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
"use server";
|
||||
|
||||
import { cookies } from "next/headers";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export type ActionState = { error: string } | null;
|
||||
|
||||
export async function login(prevState: ActionState, formData: FormData): Promise<ActionState> {
|
||||
const username = formData.get("username");
|
||||
const password = formData.get("password");
|
||||
|
||||
if (
|
||||
username === process.env.ADMIN_USERNAME &&
|
||||
password === process.env.ADMIN_PASSWORD
|
||||
) {
|
||||
const cookieStore = await cookies();
|
||||
cookieStore.set("admin_session", "true", {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
maxAge: 60 * 60 * 24 * 7, // 1 week
|
||||
path: "/",
|
||||
});
|
||||
} else {
|
||||
return { error: "Geçersiz kullanıcı adı veya şifre" };
|
||||
}
|
||||
|
||||
redirect("/admin");
|
||||
}
|
||||
|
||||
export async function logout() {
|
||||
const cookieStore = await cookies();
|
||||
cookieStore.delete("admin_session");
|
||||
redirect("/admin/login");
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
"use server";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function loadMockEvents() {
|
||||
await prisma.event.deleteMany({});
|
||||
|
||||
const mockEvents = [
|
||||
{
|
||||
lang: "tr",
|
||||
title: "Mahmut Orhan - Sunset Session",
|
||||
description: "Dünyaca ünlü DJ Mahmut Orhan, unutulmaz bir gün batımı performansı için Kite Beach Akyaka'da! Ege'nin muhteşem manzarasına karşı elektronik müziğin ritmini hissedeceğiniz bu özel geceyi kaçırmayın.",
|
||||
date: "15 Ağustos 2026",
|
||||
time: "18:00",
|
||||
location: "Beach Club",
|
||||
image: "https://images.unsplash.com/photo-1516450360452-9312f5e86fc7?q=80&w=2832&auto=format&fit=crop",
|
||||
badge: "Yaklaşan Etkinlik"
|
||||
},
|
||||
{
|
||||
lang: "en",
|
||||
title: "Mahmut Orhan - Sunset Session",
|
||||
description: "World famous DJ Mahmut Orhan is at Kite Beach Akyaka for an unforgettable sunset performance! Do not miss this special night where you will feel the rhythm of electronic music against the magnificent view of the Aegean.",
|
||||
date: "15 August 2026",
|
||||
time: "18:00",
|
||||
location: "Beach Club",
|
||||
image: "https://images.unsplash.com/photo-1516450360452-9312f5e86fc7?q=80&w=2832&auto=format&fit=crop",
|
||||
badge: "Upcoming Event"
|
||||
}
|
||||
];
|
||||
|
||||
await prisma.event.createMany({ data: mockEvents });
|
||||
|
||||
revalidatePath('/admin/events');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
}
|
||||
|
||||
export async function addEvent(prevState: any, formData: FormData) {
|
||||
try {
|
||||
const data = {
|
||||
lang: formData.get("lang") as string,
|
||||
title: formData.get("title") as string,
|
||||
description: formData.get("description") as string,
|
||||
date: formData.get("date") as string,
|
||||
time: formData.get("time") as string,
|
||||
location: formData.get("location") as string,
|
||||
image: formData.get("image") as string,
|
||||
badge: formData.get("badge") as string || null,
|
||||
};
|
||||
|
||||
await prisma.event.create({ data });
|
||||
|
||||
revalidatePath('/admin/events');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
|
||||
return { success: true, message: "Etkinlik başarıyla eklendi." };
|
||||
} catch (error) {
|
||||
return { error: "Etkinlik eklenirken bir hata oluştu." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateEvent(prevState: any, formData: FormData) {
|
||||
try {
|
||||
const id = parseInt(formData.get("id") as string, 10);
|
||||
const data = {
|
||||
lang: formData.get("lang") as string,
|
||||
title: formData.get("title") as string,
|
||||
description: formData.get("description") as string,
|
||||
date: formData.get("date") as string,
|
||||
time: formData.get("time") as string,
|
||||
location: formData.get("location") as string,
|
||||
image: formData.get("image") as string,
|
||||
badge: formData.get("badge") as string || null,
|
||||
};
|
||||
|
||||
await prisma.event.update({
|
||||
where: { id },
|
||||
data
|
||||
});
|
||||
|
||||
revalidatePath('/admin/events');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
|
||||
return { success: true, message: "Etkinlik başarıyla güncellendi." };
|
||||
} catch (error) {
|
||||
return { error: "Etkinlik güncellenirken bir hata oluştu." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteEvent(id: number) {
|
||||
try {
|
||||
await prisma.event.delete({ where: { id } });
|
||||
revalidatePath('/admin/events');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
return { success: true, message: "Etkinlik silindi." };
|
||||
} catch (error) {
|
||||
return { error: "Silme işlemi başarısız." };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
"use server";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function loadMockFeatures() {
|
||||
await prisma.feature.deleteMany({});
|
||||
|
||||
const mockFeatures = [
|
||||
{ lang: "tr", icon: "Wind", label: "Kitesurf Okulu", sub: "IKO Sertifikalı", order: 1 },
|
||||
{ lang: "en", icon: "Wind", label: "Kitesurf School", sub: "IKO Certified", order: 1 },
|
||||
{ lang: "tr", icon: "Anchor", label: "Yoga Platformu", sub: "Nehir Kenarı", order: 2 },
|
||||
{ lang: "en", icon: "Anchor", label: "Yoga Platform", sub: "Riverside", order: 2 },
|
||||
{ lang: "tr", icon: "Utensils", label: "Restoran & Bar", sub: "Ege Mutfağı", order: 3 },
|
||||
{ lang: "en", icon: "Utensils", label: "Restaurant & Bar", sub: "Aegean Cuisine", order: 3 },
|
||||
{ lang: "tr", icon: "BedDouble", label: "Butik Odalar", sub: "3 Tip Konaklama", order: 4 },
|
||||
{ lang: "en", icon: "BedDouble", label: "Boutique Rooms", sub: "3 Types of Stay", order: 4 },
|
||||
{ lang: "tr", icon: "Sun", label: "Gün Batımı Terası", sub: "Gökova Manzarası", order: 5 },
|
||||
{ lang: "en", icon: "Sun", label: "Sunset Terrace", sub: "Gokova View", order: 5 },
|
||||
];
|
||||
|
||||
await prisma.feature.createMany({ data: mockFeatures });
|
||||
|
||||
revalidatePath('/admin/features');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
}
|
||||
|
||||
export async function addFeature(prevState: any, formData: FormData) {
|
||||
try {
|
||||
const data = {
|
||||
lang: formData.get("lang") as string,
|
||||
icon: formData.get("icon") as string,
|
||||
label: formData.get("label") as string,
|
||||
sub: formData.get("sub") as string,
|
||||
order: parseInt(formData.get("order") as string || "0", 10),
|
||||
};
|
||||
|
||||
await prisma.feature.create({ data });
|
||||
|
||||
revalidatePath('/admin/features');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
|
||||
return { success: true, message: "Özellik başarıyla eklendi." };
|
||||
} catch (error) {
|
||||
return { error: "Özellik eklenirken bir hata oluştu." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateFeature(prevState: any, formData: FormData) {
|
||||
try {
|
||||
const id = parseInt(formData.get("id") as string, 10);
|
||||
const data = {
|
||||
lang: formData.get("lang") as string,
|
||||
icon: formData.get("icon") as string,
|
||||
label: formData.get("label") as string,
|
||||
sub: formData.get("sub") as string,
|
||||
order: parseInt(formData.get("order") as string || "0", 10),
|
||||
};
|
||||
|
||||
await prisma.feature.update({
|
||||
where: { id },
|
||||
data
|
||||
});
|
||||
|
||||
revalidatePath('/admin/features');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
|
||||
return { success: true, message: "Özellik başarıyla güncellendi." };
|
||||
} catch (error) {
|
||||
return { error: "Özellik güncellenirken bir hata oluştu." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteFeature(id: number) {
|
||||
try {
|
||||
await prisma.feature.delete({ where: { id } });
|
||||
revalidatePath('/admin/features');
|
||||
revalidatePath('/tr');
|
||||
revalidatePath('/en');
|
||||
return { success: true, message: "Özellik silindi." };
|
||||
} catch (error) {
|
||||
return { error: "Silme işlemi başarısız." };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export type HeroActionState = {
|
||||
success?: boolean;
|
||||
message?: string;
|
||||
} | null;
|
||||
|
||||
export async function updateHero(prevState: HeroActionState, formData: FormData): Promise<HeroActionState> {
|
||||
const lang = formData.get("lang") as string;
|
||||
const location = formData.get("location") as string;
|
||||
const welcome = formData.get("welcome") as string;
|
||||
const title = formData.get("title") as string;
|
||||
const subtitle = formData.get("subtitle") as string;
|
||||
const bookNow = formData.get("bookNow") as string;
|
||||
const exploreActivities = formData.get("exploreActivities") as string;
|
||||
const scroll = formData.get("scroll") as string;
|
||||
|
||||
if (!lang) {
|
||||
return { success: false, message: "Dil seçimi eksik." };
|
||||
}
|
||||
|
||||
await prisma.heroSection.upsert({
|
||||
where: { lang },
|
||||
update: { location, welcome, title, subtitle, bookNow, exploreActivities, scroll },
|
||||
create: {
|
||||
lang,
|
||||
location,
|
||||
welcome,
|
||||
title,
|
||||
subtitle,
|
||||
bookNow,
|
||||
exploreActivities,
|
||||
scroll
|
||||
}
|
||||
});
|
||||
|
||||
revalidatePath('/admin/hero');
|
||||
revalidatePath(`/${lang}`);
|
||||
revalidatePath('/');
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `${lang.toUpperCase()} Hero ayarları başarıyla kaydedildi!`
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export type SettingsActionState = {
|
||||
success?: boolean;
|
||||
message?: string;
|
||||
} | null;
|
||||
|
||||
export async function updateSettings(prevState: SettingsActionState, formData: FormData): Promise<SettingsActionState> {
|
||||
const title = formData.get("title") as string;
|
||||
const email = formData.get("email") as string;
|
||||
const phone = formData.get("phone") as string;
|
||||
const address = formData.get("address") as string;
|
||||
const instagram = formData.get("instagram") as string;
|
||||
|
||||
await prisma.siteSettings.upsert({
|
||||
where: { id: 1 },
|
||||
update: { title, email, phone, address, instagram },
|
||||
create: {
|
||||
id: 1,
|
||||
title,
|
||||
email,
|
||||
phone,
|
||||
address,
|
||||
instagram
|
||||
}
|
||||
});
|
||||
|
||||
revalidatePath('/admin/settings');
|
||||
revalidatePath('/');
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "Ayarlar başarıyla veritabanına kaydedildi!"
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user