feat: Hakkımızda sayfası yönetilebilir (site_settings + /admin/site)
Önce hard-coded olan tüm metinler artık /admin/site > 'Hakkımızda sayfası'
bölümünden düzenlenebilir.
site_settings'e 9 yeni alan eklendi:
- about_eyebrow, about_title, about_description (üst hero)
- about_values (string array JSON {title, description}) — 4 değer kartı
- about_hero_image (opsiyonel, boşsa logo gösterilir)
- about_team_eyebrow, about_team_title, about_team_description
- about_stats (string array JSON {value, label}) — alt navy bant
Mevcut WP değerleri default olarak seed edildi.
Hakkımızda sayfası (app/(site)/hakkimizda/page.tsx) artık:
- Tüm metinler settings'ten okunuyor (fallback default'lar var)
- Hero image varsa logo yerine onu gösteriyor
- Stats sıfırdan farklı sayıda olabilir (3 yerine 2/4)
Admin form (/admin/site):
- Yeni 'Hakkımızda sayfası' section
- 4 alt-bölüm: Üst hero / Değerler / Ekip / Stats
- MediaPicker ile hero image
- Markdown benzeri textarea'lar (--- ayırıcı, | seperator)
This commit is contained in:
@@ -12,6 +12,7 @@ import { getSiteSettings } from "@/lib/data";
|
||||
import { saveSiteSettings } from "@/lib/admin-actions";
|
||||
import { MediaPicker } from "@/components/admin/media-picker";
|
||||
import type {
|
||||
AboutValue,
|
||||
FaqItem,
|
||||
ProcessStep,
|
||||
StatItem,
|
||||
@@ -104,6 +105,21 @@ function faqToText(items?: string[] | null): string {
|
||||
return parsed.map((it) => `${it.q}\n${it.a}`).join("\n---\n");
|
||||
}
|
||||
|
||||
function aboutValuesToText(items?: string[] | null): string {
|
||||
if (!items) return "";
|
||||
const parsed: AboutValue[] = [];
|
||||
for (const raw of items) {
|
||||
try {
|
||||
const obj = JSON.parse(raw) as Partial<AboutValue>;
|
||||
if (obj.title && obj.description)
|
||||
parsed.push({ title: obj.title, description: obj.description });
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
return parsed.map((v) => `${v.title}\n${v.description}`).join("\n---\n");
|
||||
}
|
||||
|
||||
function Section({
|
||||
title,
|
||||
description,
|
||||
@@ -371,6 +387,96 @@ export default async function SiteSettingsPage() {
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<Section
|
||||
title="Hakkımızda sayfası"
|
||||
description="/hakkimizda sayfasındaki metinler ve görsel."
|
||||
>
|
||||
<div className="grid gap-5 md:grid-cols-2">
|
||||
<Field
|
||||
label="Eyebrow"
|
||||
name="about_eyebrow"
|
||||
defaultValue={s?.about_eyebrow}
|
||||
placeholder="Hakkımızda"
|
||||
/>
|
||||
<Field
|
||||
label="Başlık"
|
||||
name="about_title"
|
||||
defaultValue={s?.about_title}
|
||||
placeholder="Kocaeli'den dünyaya dijital ürünler"
|
||||
/>
|
||||
</div>
|
||||
<Textarea
|
||||
label="Açıklama paragrafı"
|
||||
name="about_description"
|
||||
rows={3}
|
||||
defaultValue={s?.about_description}
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
label="Değerler (4 madde önerilir)"
|
||||
name="about_values"
|
||||
rows={10}
|
||||
defaultValue={aboutValuesToText(s?.about_values)}
|
||||
placeholder={
|
||||
"Uçtan uca üretim\nFikir aşamasından lansmana, tek bir ekip.\n---\nÖlçülebilir sonuç\nHer projeyi metriklerle değerlendiriyoruz."
|
||||
}
|
||||
help='Her blok "---" ile ayrılır. İlk satır başlık, sonrası açıklama.'
|
||||
/>
|
||||
|
||||
<MediaPicker
|
||||
label="Hero görsel (opsiyonel)"
|
||||
name="about_hero_image"
|
||||
defaultValue={s?.about_hero_image}
|
||||
help="Boşsa logo gösterilir. Görsel eklersen logo yerine geçer."
|
||||
/>
|
||||
|
||||
<div className="border-t border-[var(--border)] pt-5">
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-[var(--muted)]">
|
||||
Ekip bölümü
|
||||
</p>
|
||||
<div className="mt-3 grid gap-5 md:grid-cols-3">
|
||||
<Field
|
||||
label="Ekip eyebrow"
|
||||
name="about_team_eyebrow"
|
||||
defaultValue={s?.about_team_eyebrow}
|
||||
placeholder="Ekibimiz"
|
||||
/>
|
||||
<Field
|
||||
label="Ekip başlığı"
|
||||
name="about_team_title"
|
||||
defaultValue={s?.about_team_title}
|
||||
placeholder="Projenizde Kimlerle Çalışırsınız?"
|
||||
/>
|
||||
<Field
|
||||
label="Ekip açıklaması"
|
||||
name="about_team_description"
|
||||
defaultValue={s?.about_team_description}
|
||||
/>
|
||||
</div>
|
||||
<p className="mt-2 text-xs text-[var(--muted)]">
|
||||
Ekip üyeleri /admin/ekip üzerinden yönetilir.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-[var(--border)] pt-5">
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-[var(--muted)]">
|
||||
İstatistikler (en altta navy bant)
|
||||
</p>
|
||||
<div className="mt-3">
|
||||
<Textarea
|
||||
label="Stats"
|
||||
name="about_stats"
|
||||
rows={4}
|
||||
defaultValue={statsToText(s?.about_stats)}
|
||||
placeholder={
|
||||
"50+ | Tamamlanan proje\n30+ | Mutlu müşteri\n10+ | Yıllık deneyim"
|
||||
}
|
||||
help='Her satır "değer | etiket" formatında.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section
|
||||
title="Conversion / reklam optimizasyonu"
|
||||
description="Trust bandı, mini lead form ve WhatsApp metni."
|
||||
|
||||
Reference in New Issue
Block a user