feat: add social media fields to cms, improve gallery video thumbnails and add navigation buttons
This commit is contained in:
@@ -10,9 +10,23 @@ export default async function ContentPage() {
|
|||||||
.select('*')
|
.select('*')
|
||||||
.order('key')
|
.order('key')
|
||||||
|
|
||||||
// CMS migration script creates default keys.
|
// Define default contents that should exist
|
||||||
// If table is empty, we might want to seed it or just show empty.
|
const DEFAULT_CONTENTS: SiteContent[] = [
|
||||||
// Assuming migration ran, we have data.
|
{ key: 'social_instagram', value: '', type: 'text', section: 'contact' },
|
||||||
|
{ key: 'social_facebook', value: '', type: 'text', section: 'contact' },
|
||||||
|
{ key: 'social_twitter', value: '', type: 'text', section: 'contact' },
|
||||||
|
{ key: 'contact_map_embed', value: '', type: 'html', section: 'contact' },
|
||||||
|
]
|
||||||
|
|
||||||
|
// Merge default contents with existing contents
|
||||||
|
const mergedContents = [...(contents as SiteContent[] || [])]
|
||||||
|
const existingKeys = new Set(mergedContents.map(c => c.key))
|
||||||
|
|
||||||
|
DEFAULT_CONTENTS.forEach(item => {
|
||||||
|
if (!existingKeys.has(item.key)) {
|
||||||
|
mergedContents.push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
@@ -22,7 +36,7 @@ export default async function ContentPage() {
|
|||||||
Site başlığı, sloganlar, iletişim bilgileri ve logoları buradan yönetebilirsiniz.
|
Site başlığı, sloganlar, iletişim bilgileri ve logoları buradan yönetebilirsiniz.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<ContentForm initialContent={(contents as SiteContent[]) || []} />
|
<ContentForm initialContent={mergedContents} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { UserNav } from "@/components/user-nav"
|
|||||||
import { Building } from "lucide-react"
|
import { Building } from "lucide-react"
|
||||||
import { MobileSidebar } from "@/components/mobile-sidebar"
|
import { MobileSidebar } from "@/components/mobile-sidebar"
|
||||||
import { createClient } from "@/lib/supabase/server"
|
import { createClient } from "@/lib/supabase/server"
|
||||||
|
import { NavigationButtons } from "@/components/navigation-buttons"
|
||||||
|
|
||||||
export default async function DashboardLayout({
|
export default async function DashboardLayout({
|
||||||
children,
|
children,
|
||||||
@@ -28,12 +29,15 @@ export default async function DashboardLayout({
|
|||||||
<div className="flex-1 md:ml-72 flex flex-col min-h-screen">
|
<div className="flex-1 md:ml-72 flex flex-col min-h-screen">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<header className="sticky top-0 z-40 h-16 glass border-b px-4 md:px-6 flex items-center justify-between">
|
<header className="sticky top-0 z-40 h-16 glass border-b px-4 md:px-6 flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2 md:hidden">
|
<div className="flex items-center gap-4">
|
||||||
<MobileSidebar user={userData} />
|
<div className="flex items-center gap-2 md:hidden">
|
||||||
<div className="flex items-center font-bold text-lg">
|
<MobileSidebar user={userData} />
|
||||||
<Building className="mr-2 h-5 w-5 text-primary" />
|
<div className="flex items-center font-bold text-lg">
|
||||||
WeddingOS
|
<Building className="mr-2 h-5 w-5 text-primary" />
|
||||||
|
WeddingOS
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<NavigationButtons />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="ml-auto flex items-center space-x-4">
|
<div className="ml-auto flex items-center space-x-4">
|
||||||
|
|||||||
32
src/components/navigation-buttons.tsx
Normal file
32
src/components/navigation-buttons.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { ChevronLeft, ChevronRight } from "lucide-react"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
|
||||||
|
export function NavigationButtons() {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center gap-1 h-8">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
className="h-8 w-8 text-muted-foreground hover:text-primary"
|
||||||
|
onClick={() => router.back()}
|
||||||
|
title="Geri"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="h-5 w-5" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
className="h-8 w-8 text-muted-foreground hover:text-primary"
|
||||||
|
onClick={() => router.forward()}
|
||||||
|
title="İleri"
|
||||||
|
>
|
||||||
|
<ChevronRight className="h-5 w-5" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -51,7 +51,7 @@ export function GalleryGrid({ items }: GalleryGridProps) {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{displayImage && (
|
{displayImage ? (
|
||||||
<Image
|
<Image
|
||||||
src={displayImage}
|
src={displayImage}
|
||||||
alt={item.caption || 'Gallery Image'}
|
alt={item.caption || 'Gallery Image'}
|
||||||
@@ -59,6 +59,10 @@ export function GalleryGrid({ items }: GalleryGridProps) {
|
|||||||
className="object-cover transition-transform duration-700 group-hover:scale-110"
|
className="object-cover transition-transform duration-700 group-hover:scale-110"
|
||||||
sizes="(max-width: 768px) 50vw, 25vw"
|
sizes="(max-width: 768px) 50vw, 25vw"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-slate-800 flex items-center justify-center bg-gradient-to-br from-slate-800 to-slate-900 group-hover:from-slate-700 group-hover:to-slate-800 transition-colors">
|
||||||
|
{/* Fallback for video without generic thumbnail */}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex flex-col items-center justify-center space-y-2">
|
<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex flex-col items-center justify-center space-y-2">
|
||||||
{item.video_url && (
|
{item.video_url && (
|
||||||
|
|||||||
Reference in New Issue
Block a user