db connect

This commit is contained in:
2026-04-17 11:16:00 +03:00
parent b675fff437
commit 5a48605c35
25 changed files with 2607 additions and 298 deletions

View File

@@ -0,0 +1,88 @@
'use client'
import { motion, useScroll, useTransform } from 'framer-motion'
import Image from 'next/image'
import Link from 'next/link'
import { useState, useEffect } from 'react'
export default function ProjectsPageClient({ initialProjects }: { initialProjects: any[] }) {
const { scrollY } = useScroll()
const [isAtBottom, setIsAtBottom] = useState(false)
useEffect(() => {
const handleScroll = () => {
const windowHeight = window.innerHeight
const documentHeight = document.documentElement.scrollHeight
const scrollPosition = window.scrollY + windowHeight
setIsAtBottom(scrollPosition > documentHeight - 100)
}
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, [])
const cargoFontSize = useTransform(scrollY, [0, 300], ["10vw", "4vw"])
const archFontSize = useTransform(scrollY, [0, 300], ["8vw", "3vw"])
const bottomPadding = useTransform(scrollY, [0, 300], ["2.5rem", "1rem"])
return (
<main className="relative min-h-screen bg-white pt-32 pb-60 px-6 md:px-10">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 md:gap-8">
{initialProjects.map((project, idx) => (
<Link key={project.slug} href={`/projects/${project.slug}`}>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: idx * 0.05 }}
className="group cursor-pointer"
>
<div className="relative aspect-[4/3] overflow-hidden rounded-[1px] bg-zinc-100">
<Image
src={project.image}
alt={project.title}
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
className="object-cover grayscale group-hover:grayscale-0 transition-all duration-700 ease-in-out scale-105 group-hover:scale-100"
/>
</div>
<div className="mt-4 flex flex-col space-y-1 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<span className="text-[10px] font-bold text-black/60 uppercase tracking-wider">
{project.year} {project.location}
</span>
<div className="flex justify-between items-center">
<span className="text-[10px] font-bold text-black uppercase tracking-widest">
{project.title}
</span>
<span className="text-sm"></span>
</div>
</div>
</motion.div>
</Link>
))}
</div>
<motion.div
animate={{ opacity: isAtBottom ? 0 : 1 }}
transition={{ duration: 0.3 }}
className="fixed bottom-0 left-0 w-full pointer-events-none z-50 overflow-hidden pt-10"
>
<motion.div
style={{ padding: bottomPadding }}
className="flex justify-between items-end"
>
<motion.h1
style={{ fontSize: cargoFontSize }}
className="font-bebas leading-[0.8] text-black tracking-tighter"
>
A.N.T
</motion.h1>
<motion.h1
style={{ fontSize: archFontSize }}
className="font-bebas leading-[0.8] text-black tracking-tighter"
>
ARCHITECTURE
</motion.h1>
</motion.div>
</motion.div>
</main>
)
}

View File

@@ -0,0 +1,108 @@
'use client'
import { motion } from 'framer-motion'
import Image from 'next/image'
import Link from 'next/link'
export default function ProjectDetailClient({ project }: { project: any }) {
return (
<main className="min-h-screen bg-white selection:bg-black selection:text-white">
{/* Navigation */}
<nav className="fixed top-0 left-0 w-full z-50 p-6 md:p-10 flex justify-between items-center mix-blend-difference text-white pointer-events-none">
<Link href="/" className="pointer-events-auto font-bebas text-2xl tracking-tighter hover:opacity-70 transition-opacity">
A.N.T
</Link>
<Link href="/projects" className="pointer-events-auto text-[10px] font-bold uppercase tracking-[0.2em] hover:opacity-70 transition-opacity">
Tüm Projeler
</Link>
</nav>
{/* Hero Section */}
<div className="flex flex-col md:flex-row min-h-screen">
<div className="w-full md:w-1/3 pt-32 pb-10 px-6 md:px-10 flex flex-col justify-between">
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.8 }}
>
<div className="text-[10px] font-bold text-black/40 uppercase tracking-[0.3em] mb-4">
{project.year} {project.location}
</div>
<h1 className="text-4xl md:text-6xl font-bebas text-black leading-none tracking-tighter uppercase mb-6">
{project.title}
</h1>
<div className="h-[1px] w-12 bg-black mb-6" />
<p className="text-sm text-black/60 leading-relaxed max-w-sm">
{project.description || `Bu proje, modern mimari prensipleri ve fonksiyonel tasarım anlayışıyla hayata geçirilmiştir. Fethiye merkezli A.N.T Architecture vizyonuyla şekillenen bu yapı, çevresel dokuyla uyumlu bir estetik sunar.`}
</p>
</motion.div>
<div className="mt-12">
<div className="text-[10px] font-bold text-black uppercase tracking-[0.2em] mb-2 opacity-40">Kategori</div>
<div className="text-sm font-bold text-black uppercase tracking-widest">{project.category || 'Architecture'}</div>
</div>
</div>
<div className="w-full md:w-2/3 h-[70vh] md:h-screen relative overflow-hidden bg-zinc-100">
<motion.div
initial={{ scale: 1.1, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 1.5, ease: [0.76, 0, 0.24, 1] }}
className="w-full h-full"
>
<Image
src={project.image}
alt={project.title}
fill
sizes="(max-width: 768px) 100vw, 80vw"
priority
className="object-cover"
/>
</motion.div>
</div>
</div>
{/* Gallery Section */}
{project.gallery && project.gallery.length > 0 && (
<section className="py-20 md:py-40 px-6 md:px-10 bg-[#f9f9f9]">
<div className="max-w-[1400px] mx-auto">
<div className="mb-20">
<h2 className="text-[10px] font-bold text-black/30 uppercase tracking-[0.5em] mb-4">PROJE GÖRSELLERİ</h2>
<div className="h-[1px] w-full bg-black/5" />
</div>
<div className="columns-1 md:columns-2 gap-10 space-y-10">
{project.gallery.map((img: string, i: number) => (
<motion.div
key={i}
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: "-100px" }}
transition={{ duration: 0.8, delay: i * 0.1 }}
className="relative group overflow-hidden bg-white"
>
<Image
src={img}
alt={`${project.title} Gallery ${i}`}
width={1200}
height={800}
className="w-full h-auto object-cover grayscale group-hover:grayscale-0 transition-all duration-1000"
/>
</motion.div>
))}
</div>
</div>
</section>
)}
{/* Back Link Footer */}
<footer className="py-20 flex flex-col items-center justify-center border-t border-black/5">
<Link href="/projects" className="group flex flex-col items-center gap-4">
<span className="text-[10px] font-bold uppercase tracking-[0.5em] text-black/40 group-hover:text-black transition-colors">SIRADAKİ PROJE</span>
<div className="w-px h-12 bg-black/10 group-hover:h-20 transition-all duration-700" />
</Link>
</footer>
</main>
)
}

View File

@@ -1,95 +1,28 @@
'use client'
import { useParams } from 'next/navigation'
import { projects } from '@/data/projects'
import { motion } from 'framer-motion'
import Image from 'next/image'
import Link from 'next/link'
import { prisma } from '@/lib/prisma'
import { notFound } from 'next/navigation'
import ProjectDetailClient from './ProjectDetailClient'
export default function ProjectDetailPage() {
const params = useParams()
const slug = params.slug as string
interface Props {
params: Promise<{ slug: string }>
}
export default async function ProjectDetailPage({ params }: Props) {
const { slug } = await params
const project = projects.find(p => p.slug === slug)
const project = await prisma.project.findUnique({
where: { slug }
})
if (!project) {
notFound()
}
return (
<main className="min-h-screen bg-white">
{/* Navigation */}
<nav className="fixed top-0 left-0 w-full z-50 p-6 md:p-10 flex justify-between items-center mix-blend-difference text-white pointer-events-none">
<Link href="/" className="pointer-events-auto font-bebas text-2xl tracking-tighter hover:opacity-70 transition-opacity">
A.N.T
</Link>
<Link href="/projects" className="pointer-events-auto text-[10px] font-bold uppercase tracking-[0.2em] hover:opacity-70 transition-opacity">
Tüm Projeler
</Link>
</nav>
// Serialize dates and gallery
const serializedProject = {
...project,
createdAt: project.createdAt.toISOString(),
updatedAt: project.updatedAt.toISOString(),
}
<div className="flex flex-col md:flex-row min-h-screen">
{/* Left Side: Info */}
<div className="w-full md:w-1/3 pt-32 pb-10 px-6 md:px-10 flex flex-col justify-between">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
>
<div className="text-[10px] font-bold text-black/40 uppercase tracking-[0.3em] mb-4">
{project.year} {project.location}
</div>
<h1 className="text-4xl md:text-6xl font-bebas text-black leading-none tracking-tighter uppercase mb-6">
{project.title}
</h1>
<div className="h-[1px] w-12 bg-black mb-6" />
<p className="text-sm text-black/60 leading-relaxed max-w-sm">
Bu proje, modern mimari prensipleri ve fonksiyonel tasarım anlayışıyla hayata geçirilmiştir.
Detaylar ve uygulama süreçleri hakkında daha fazla bilgi için bizimle iletişime geçebilirsiniz.
</p>
</motion.div>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.4, duration: 0.8 }}
className="hidden md:block"
>
<div className="text-[10px] font-bold text-black uppercase tracking-[0.2em]">
Kategori: {project.category || 'Belirtilmemiş'}
</div>
</motion.div>
</div>
{/* Right Side: Image */}
<div className="w-full md:w-2/3 h-[70vh] md:h-screen relative">
<motion.div
initial={{ opacity: 0, scale: 1.1 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 1.2, ease: [0.76, 0, 0.24, 1] }}
className="w-full h-full"
>
<Image
src={project.image}
alt={project.title}
fill
priority
className="object-cover"
/>
</motion.div>
{/* Subtle Overlay */}
<div className="absolute inset-0 bg-black/5 pointer-events-none" />
</div>
</div>
{/* Mobile Footer Info */}
<div className="md:hidden p-6 border-t border-black/5">
<div className="text-[10px] font-bold text-black uppercase tracking-[0.2em]">
Kategori: {project.category || 'Belirtilmemiş'}
</div>
</div>
</main>
)
return <ProjectDetailClient project={serializedProject} />
}

View File

@@ -1,89 +1,17 @@
'use client'
import { prisma } from '@/lib/prisma'
import ProjectsPageClient from './ProjectsPageClient'
import { motion, useScroll, useTransform } from 'framer-motion'
import Image from 'next/image'
import Link from 'next/link'
import { projects } from '@/data/projects'
import { useState, useEffect } from 'react'
export default async function ProjectsPage() {
const projects = await prisma.project.findMany({
orderBy: { createdAt: 'desc' }
})
export default function ProjectsPage() {
const { scrollY } = useScroll()
const [isAtBottom, setIsAtBottom] = useState(false)
// Normalize data for client (Prisma returns Dates, Client expects standard objects if needed)
const serializedProjects = projects.map(p => ({
...p,
createdAt: p.createdAt.toISOString(),
updatedAt: p.updatedAt.toISOString(),
}))
useEffect(() => {
const handleScroll = () => {
const windowHeight = window.innerHeight
const documentHeight = document.documentElement.scrollHeight
const scrollPosition = window.scrollY + windowHeight
setIsAtBottom(scrollPosition > documentHeight - 100)
}
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, [])
const cargoFontSize = useTransform(scrollY, [0, 300], ["10vw", "4vw"])
const archFontSize = useTransform(scrollY, [0, 300], ["8vw", "3vw"])
const bottomPadding = useTransform(scrollY, [0, 300], ["2.5rem", "1rem"])
return (
<main className="relative min-h-screen bg-white pt-32 pb-60 px-6 md:px-10">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 md:gap-8">
{projects.map((project, idx) => (
<Link key={project.slug} href={`/projects/${project.slug}`}>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: idx * 0.05 }}
className="group cursor-pointer"
>
<div className="relative aspect-[4/3] overflow-hidden rounded-[1px] bg-zinc-100">
<Image
src={project.image}
alt={project.title}
fill
className="object-cover grayscale group-hover:grayscale-0 transition-all duration-700 ease-in-out scale-105 group-hover:scale-100"
/>
</div>
<div className="mt-4 flex flex-col space-y-1 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<span className="text-[10px] font-bold text-black/60 uppercase tracking-wider">
{project.year} {project.location}
</span>
<div className="flex justify-between items-center">
<span className="text-[10px] font-bold text-black uppercase tracking-widest">
{project.title}
</span>
<span className="text-sm"></span>
</div>
</div>
</motion.div>
</Link>
))}
</div>
<motion.div
animate={{ opacity: isAtBottom ? 0 : 1 }}
transition={{ duration: 0.3 }}
className="fixed bottom-0 left-0 w-full pointer-events-none z-50 overflow-hidden pt-10"
>
<motion.div
style={{ padding: bottomPadding }}
className="flex justify-between items-end"
>
<motion.h1
style={{ fontSize: cargoFontSize }}
className="font-bebas leading-[0.8] text-black tracking-tighter"
>
A.N.T
</motion.h1>
<motion.h1
style={{ fontSize: archFontSize }}
className="font-bebas leading-[0.8] text-black tracking-tighter"
>
ARCHITECTURE
</motion.h1>
</motion.div>
</motion.div>
</main>
)
return <ProjectsPageClient initialProjects={serializedProjects} />
}