This commit is contained in:
2026-06-09 15:15:40 +03:00
parent f6b4acb760
commit d908d83ca5
58 changed files with 4320 additions and 419 deletions
+169
View File
@@ -0,0 +1,169 @@
"use client";
import { useActionState, useState } from "react";
import { updateHero } from "@/app/actions/hero";
import { Save, CheckCircle2 } from "lucide-react";
import { HeroSection } from "@prisma/client";
export default function HeroForm({ trData, enData }: { trData: HeroSection | null, enData: HeroSection | null }) {
const [state, formAction, isPending] = useActionState(updateHero, null);
const [activeTab, setActiveTab] = useState<"tr" | "en">("tr");
const fallbacks = {
tr: {
lang: "tr",
location: "Akyaka, Gökova",
welcome: "Kite Beach'e Hoş Geldiniz",
title: "Rüzgarı Hisset, Özgürlüğe Uç",
subtitle: "Türkiye'nin en iyi kitesurf noktasında unutulmaz bir deneyim yaşayın. Profesyonel eğitmenler, mükemmel rüzgar ve eşsiz doğa sizi bekliyor.",
bookNow: "Hemen Rezervasyon Yap",
exploreActivities: "Aktiviteleri Keşfet",
scroll: "Aşağı Kaydır"
},
en: {
lang: "en",
location: "Akyaka, Gokova",
welcome: "Welcome to Kite Beach",
title: "Feel the Wind, Fly to Freedom",
subtitle: "Experience an unforgettable adventure at Turkey's best kitesurfing spot. Professional instructors, perfect wind, and unique nature await you.",
bookNow: "Book Now",
exploreActivities: "Explore Activities",
scroll: "Scroll Down"
}
};
const currentData = activeTab === "tr" ? (trData || fallbacks.tr) : (enData || fallbacks.en);
return (
<>
{state?.success && (
<div className="mb-6 p-4 bg-green-50 border border-green-200 rounded-xl flex items-center gap-3 text-green-800 animate-fade-in">
<CheckCircle2 className="w-5 h-5 text-green-600" />
<p className="font-medium">{state.message}</p>
</div>
)}
<div className="bg-white rounded-3xl shadow-xl border border-gray-100 overflow-hidden relative">
{/* Tabs */}
<div className="flex border-b border-gray-200">
<button
type="button"
onClick={() => setActiveTab("tr")}
className={`flex-1 py-5 text-center font-bold tracking-wide uppercase text-sm transition-all ${activeTab === "tr" ? "text-dark border-b-2 border-dark bg-gray-50" : "text-gray-400 hover:text-gray-600 hover:bg-gray-50/50"}`}
>
🇹🇷 Türkçe
</button>
<button
type="button"
onClick={() => setActiveTab("en")}
className={`flex-1 py-5 text-center font-bold tracking-wide uppercase text-sm transition-all ${activeTab === "en" ? "text-dark border-b-2 border-dark bg-gray-50" : "text-gray-400 hover:text-gray-600 hover:bg-gray-50/50"}`}
>
🇬🇧 English
</button>
</div>
<form action={formAction} className="p-8 md:p-10">
<input type="hidden" name="lang" value={activeTab} />
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<div className="col-span-1 md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1">Karşılama / Konum (Location)</label>
<input
type="text"
name="location"
defaultValue={currentData.location}
required
className="w-full px-5 py-3.5 bg-gray-50 border border-gray-200 text-dark rounded-xl focus:ring-4 focus:ring-primary/20 focus:border-primary outline-none transition-all hover:border-gray-300"
/>
</div>
<div className="col-span-1 md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1">Karşılama Metni (Welcome)</label>
<input
type="text"
name="welcome"
defaultValue={currentData.welcome}
required
className="w-full px-5 py-3.5 bg-gray-50 border border-gray-200 text-dark rounded-xl focus:ring-4 focus:ring-primary/20 focus:border-primary outline-none transition-all hover:border-gray-300"
/>
</div>
<div className="col-span-1 md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1">Ana Başlık (Title)</label>
<input
type="text"
name="title"
defaultValue={currentData.title}
required
className="w-full px-5 py-3.5 bg-gray-50 border border-gray-200 text-dark rounded-xl focus:ring-4 focus:ring-primary/20 focus:border-primary outline-none transition-all hover:border-gray-300"
/>
</div>
<div className="col-span-1 md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1">Alt Başlık (Subtitle)</label>
<textarea
name="subtitle"
defaultValue={currentData.subtitle}
required
rows={3}
className="w-full px-5 py-3.5 bg-gray-50 border border-gray-200 text-dark rounded-xl focus:ring-4 focus:ring-primary/20 focus:border-primary outline-none transition-all hover:border-gray-300 resize-none"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Rezervasyon Butonu (Book Now)</label>
<input
type="text"
name="bookNow"
defaultValue={currentData.bookNow}
required
className="w-full px-5 py-3.5 bg-gray-50 border border-gray-200 text-dark rounded-xl focus:ring-4 focus:ring-primary/20 focus:border-primary outline-none transition-all hover:border-gray-300"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Aktiviteler Butonu (Explore)</label>
<input
type="text"
name="exploreActivities"
defaultValue={currentData.exploreActivities}
required
className="w-full px-5 py-3.5 bg-gray-50 border border-gray-200 text-dark rounded-xl focus:ring-4 focus:ring-primary/20 focus:border-primary outline-none transition-all hover:border-gray-300"
/>
</div>
<div className="col-span-1 md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1">Aşağı Kaydır Yazısı (Scroll)</label>
<input
type="text"
name="scroll"
defaultValue={currentData.scroll}
required
className="w-full px-5 py-3.5 bg-gray-50 border border-gray-200 text-dark rounded-xl focus:ring-4 focus:ring-primary/20 focus:border-primary outline-none transition-all hover:border-gray-300"
/>
</div>
</div>
<div className="flex justify-end border-t border-gray-100 pt-6">
<button
type="submit"
disabled={isPending}
className="flex items-center justify-center gap-3 bg-accent text-white font-bold tracking-widest uppercase py-4 px-10 rounded-xl hover:bg-accent/90 transition-all disabled:opacity-70 disabled:cursor-not-allowed shadow-lg shadow-accent/20"
>
{isPending ? (
<>Kaydediliyor...</>
) : (
<>
<Save className="w-5 h-5" />
{activeTab.toUpperCase()} Ayarlarını Kaydet
</>
)}
</button>
</div>
</form>
</div>
</>
);
}
+14
View File
@@ -0,0 +1,14 @@
import prisma from "@/lib/prisma";
import HeroForm from "./HeroForm";
export default async function HeroPage() {
const trData = await prisma.heroSection.findUnique({ where: { lang: "tr" } });
const enData = await prisma.heroSection.findUnique({ where: { lang: "en" } });
return (
<div className="max-w-4xl mx-auto w-full">
<h1 className="text-3xl font-bold font-serif mb-6 text-dark">Hero Bölümü</h1>
<HeroForm trData={trData} enData={enData} />
</div>
);
}