diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..0b7098b
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,58 @@
+# 1. Base image
+FROM node:20-alpine AS base
+
+# 2. Dependencies
+FROM base AS deps
+RUN apk add --no-cache libc6-compat
+WORKDIR /app
+
+# Install dependencies based on the preferred package manager
+COPY package.json package-lock.json* ./
+RUN npm ci --legacy-peer-deps
+
+
+# 3. Builder
+FROM base AS builder
+WORKDIR /app
+COPY --from=deps /app/node_modules ./node_modules
+COPY . .
+
+# Environment variables must be present at build time for Next.js
+# Coolify will provide these, but we can set defaults
+ENV NEXT_TELEMETRY_DISABLED=1
+
+# Generate Prisma Client
+RUN npx prisma generate
+
+RUN npm run build
+
+# 4. Runner
+FROM base AS runner
+WORKDIR /app
+
+ENV NODE_ENV=production
+ENV NEXT_TELEMETRY_DISABLED=1
+
+RUN addgroup --system --gid 1001 nodejs
+RUN adduser --system --uid 1001 nextjs
+
+COPY --from=builder /app/public ./public
+
+# Set the correct permission for prerender cache
+RUN mkdir .next
+RUN chown nextjs:nodejs .next
+
+# Automatically leverage output traces to reduce image size
+# https://nextjs.org/docs/advanced-features/output-file-tracing
+COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
+COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
+
+USER nextjs
+
+EXPOSE 3000
+
+ENV PORT=3000
+# set hostname to localhost
+ENV HOSTNAME="0.0.0.0"
+
+CMD ["node", "server.js"]
diff --git a/next.config.ts b/next.config.ts
index e9ffa30..126c66b 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -1,7 +1,15 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
- /* config options here */
+ output: 'standalone',
+ images: {
+ remotePatterns: [
+ {
+ protocol: 'https',
+ hostname: 'images.unsplash.com',
+ },
+ ],
+ },
};
export default nextConfig;
diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx
new file mode 100644
index 0000000..7388699
--- /dev/null
+++ b/src/app/(main)/layout.tsx
@@ -0,0 +1,18 @@
+import { Navbar } from "@/components/navbar";
+import { Footer } from "@/components/footer";
+
+export default function MainLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
+ return (
+ <>
+
+
+ {children}
+
+
+ >
+ );
+}
diff --git a/src/app/(main)/page.tsx b/src/app/(main)/page.tsx
new file mode 100644
index 0000000..8ad272c
--- /dev/null
+++ b/src/app/(main)/page.tsx
@@ -0,0 +1,12 @@
+import { prisma } from "@/lib/prisma";
+import { LandingPage } from "@/components/landing-page";
+
+// Next.js 15+ allows server components by default
+export default async function Home() {
+ const projects = await prisma.project.findMany({
+ orderBy: { createdAt: 'desc' },
+ take: 6 // Sadece en güncel 6 projeyi ana sayfada gösterelim
+ });
+
+ return ;
+}
diff --git a/src/app/(main)/projeler/[id]/page.tsx b/src/app/(main)/projeler/[id]/page.tsx
new file mode 100644
index 0000000..8a309cb
--- /dev/null
+++ b/src/app/(main)/projeler/[id]/page.tsx
@@ -0,0 +1,143 @@
+import { prisma } from "@/lib/prisma";
+import Image from "next/image";
+import { notFound } from "next/navigation";
+import { ArrowLeft, Maximize2, Layers, CheckCircle2, Ruler } from "lucide-react";
+import Link from "next/link";
+
+export default async function ProjectDetailPage({ params }: { params: Promise<{ id: string }> }) {
+ const { id } = await params;
+ const project = await prisma.project.findUnique({
+ where: { id }
+ });
+
+ if (!project) {
+ notFound();
+ }
+
+ return (
+
+
+ {/* Back Link */}
+
+
+ Geri Dön
+
+
+ {/* Hero Header */}
+
+
+
{project.status}
+
+ {project.title}
+
+
+
+
+
+
Konum
+
Menteşe, Muğla
+
+
+
+
+
+
+ {/* Main Image */}
+
+
+
+
+ {/* Info Grid */}
+
+
+
+
+
+
Toplam Alan
+
{project.m2} m²
+
+
+
+
Oda Sayısı
+
{project.rooms}
+
+
+
+
+
+
+ Mühendislik Kapsamı
+
+
+
+
+ Statik Proje Tasarımı
+
+
+
+ Temel Güçlendirme Analizi
+
+
+
+ Müşavirlik & Denetim
+
+
+
+
+
+
+
+
+
+
+
Mimari Vizyon
+
+ {project.description}
+
+
+
+
+
+
+
+
+
+ {/* CTA */}
+
+ Sıradaki Proje Sizinki Olabilir
+ Benzer Bir Vizyonun Varmı?
+ Bize Ulaşın
+
+
+
+ );
+}
diff --git a/src/app/(main)/projeler/page.tsx b/src/app/(main)/projeler/page.tsx
new file mode 100644
index 0000000..ab08929
--- /dev/null
+++ b/src/app/(main)/projeler/page.tsx
@@ -0,0 +1,62 @@
+import { prisma } from "@/lib/prisma";
+import Image from "next/image";
+import { ArrowUpRight } from "lucide-react";
+import Link from "next/link";
+
+export default async function ProjelerPage() {
+ const projects = await prisma.project.findMany({
+ orderBy: { createdAt: 'desc' }
+ });
+
+ return (
+
+
+
+ Portfolyo Koleksiyonu
+
+ PROJELER
+
+
+
+
+ {projects.map((p, i) => (
+
+
+
+
+
+
+
{p.status}
+
{p.title}
+
+ {p.m2} m² Alan
+ Muğla / Menteşe
+
+
+
+
+
+ ))}
+
+
+ {projects.length === 0 && (
+
+
Henüz proje eklenmemiş.
+
+ )}
+
+
+ );
+}
diff --git a/src/app/(main)/surec/page.tsx b/src/app/(main)/surec/page.tsx
new file mode 100644
index 0000000..c800c22
--- /dev/null
+++ b/src/app/(main)/surec/page.tsx
@@ -0,0 +1,113 @@
+import { HardHat, Compass, Ruler, Building2, Key, CheckCircle2 } from "lucide-react";
+import Image from "next/image";
+
+export default function SurecPage() {
+ const steps = [
+ {
+ id: "01",
+ title: "Keşif ve Analiz",
+ desc: "Müşteri beklentileri, arsa ve çevre koşullarının teknik analizi ile sürecin ilk taşını koyuyoruz.",
+ icon: Compass,
+ img: "https://images.unsplash.com/photo-1503387762-592deb58ef4e?q=80&w=2062",
+ accent: "İhtiyaç Analizi"
+ },
+ {
+ id: "02",
+ title: "Mühendislik Tasarımı",
+ desc: "İleri düzey statik hesaplamalar ve 3D modellemelerle yapının teknik iskeletini oluşturuyoruz.",
+ icon: Ruler,
+ img: "https://images.unsplash.com/photo-1503387762-592deb58ef4e?q=80&w=2062",
+ accent: "Statik Proje"
+ },
+ {
+ id: "03",
+ title: "Ruhsat ve İzinler",
+ desc: "Yasal mevzuat ve yerel yönetmeliklere tam uyum için tüm resmi süreçlerin takibi.",
+ icon: HardHat,
+ img: "https://images.unsplash.com/photo-1589829545856-d10d557cf95f?q=80&w=2070",
+ accent: "Belediye Onayı"
+ },
+ {
+ id: "04",
+ title: "İnşaat Uygulama",
+ desc: "Kendi ekip ve ekipmanlarımızla, mühendislik denetimi altında titiz inşaat süreci.",
+ icon: Building2,
+ img: "https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=2070",
+ accent: "Şantiye Yönetimi"
+ },
+ {
+ id: "05",
+ title: "Teslimat ve Sonuç",
+ desc: "Sıfır hata prensibi ve tüm testlerin ardından hayallerin anahtarla buluştuğu an.",
+ icon: Key,
+ img: "https://images.unsplash.com/photo-1600585154340-be6161a56a0c?q=80&w=2070",
+ accent: "Anahtar Teslim"
+ }
+ ];
+
+ return (
+
+ {/* Hero */}
+
+
+
+
Mühendislik Disiplini
+
+ İnşaat
+ Süreci
+
+
+
+
+ Her adımda şeffaflık, mühendislik hassasiyeti ve sarsılmaz bir iş disiplini. Utku Kırkan ile süreciniz her an kontrol altındadır.
+
+
+
+
+
+ {/* The Infographic List */}
+
+
+ {steps.map((s, i) => (
+
+
+
+
{s.id}
+
{s.accent}
+
{s.title}
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ {/* Call to Action */}
+
+
+ );
+}
diff --git a/src/app/actions.ts b/src/app/actions.ts
new file mode 100644
index 0000000..2f974b1
--- /dev/null
+++ b/src/app/actions.ts
@@ -0,0 +1,32 @@
+import { prisma } from "@/lib/prisma";
+import { revalidatePath } from "next/cache";
+
+export async function createProject(formData: FormData) {
+ "use server";
+ const title = formData.get("title") as string;
+ const description = formData.get("description") as string;
+ const m2 = parseInt(formData.get("m2") as string);
+ const rooms = formData.get("rooms") as string;
+ const status = formData.get("status") as string;
+ const imageUrl = formData.get("imageUrl") as string;
+
+ await prisma.project.create({
+ data: {
+ title,
+ description,
+ m2,
+ rooms,
+ status,
+ images: imageUrl ? [imageUrl] : []
+ },
+ });
+
+ revalidatePath("/admin");
+ revalidatePath("/");
+}
+
+export async function deleteProject(id: string) {
+ "use server";
+ await prisma.project.delete({ where: { id } });
+ revalidatePath("/admin");
+}
diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
new file mode 100644
index 0000000..231538b
--- /dev/null
+++ b/src/app/admin/page.tsx
@@ -0,0 +1,129 @@
+import { prisma } from "@/lib/prisma";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { Button } from "@/components/ui/button";
+import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
+import { Input } from "@/components/ui/input";
+import { Textarea } from "@/components/ui/textarea";
+import { deleteProject, createProject } from "@/app/actions";
+import { Plus, Trash2, MapPin, Square, Image as ImageIcon } from "lucide-react";
+import Image from "next/image";
+
+export default async function AdminPage() {
+ const projects = await prisma.project.findMany({
+ orderBy: { createdAt: 'desc' }
+ });
+
+ return (
+
+
+
+
+
+ PROJE YÖNETİMİ
+
+
Utku Kırkan Portfolyo Yönetim Paneli
+
+
+
+ Yeni Proje Ekle} />
+
+
+ Yeni Proje Girişi
+
+
+
+
+
+
+
+ {projects.map((p) => (
+
+
+ {p.images[0] ? (
+
+ ) : (
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+ {p.title}
+
+
+
+
+ {p.status}
+
+ "{p.description}"
+
+
+ ))}
+
+ {projects.length === 0 && (
+
+
+ Henüz Proje Eklenmemiş
+ Başlamak için sağ üstten yeni bir proje girişi yapın.
+
+ )}
+
+
+
+ );
+}
diff --git a/src/app/globals.css b/src/app/globals.css
index c56032b..dcb4d10 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,130 +1,79 @@
@import "tailwindcss";
-@import "tw-animate-css";
-@import "shadcn/tailwind.css";
+@source "../../src/**/*.{ts,tsx}";
-@custom-variant dark (&:is(.dark *));
+@theme {
+ --color-background: #F9F9F9;
+ --color-foreground: #1A1C1C;
-@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-sans);
- --font-mono: var(--font-geist-mono);
- --font-heading: var(--font-sans);
- --color-sidebar-ring: var(--sidebar-ring);
- --color-sidebar-border: var(--sidebar-border);
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
- --color-sidebar-accent: var(--sidebar-accent);
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
- --color-sidebar-primary: var(--sidebar-primary);
- --color-sidebar-foreground: var(--sidebar-foreground);
- --color-sidebar: var(--sidebar);
- --color-chart-5: var(--chart-5);
- --color-chart-4: var(--chart-4);
- --color-chart-3: var(--chart-3);
- --color-chart-2: var(--chart-2);
- --color-chart-1: var(--chart-1);
- --color-ring: var(--ring);
- --color-input: var(--input);
- --color-border: var(--border);
- --color-destructive: var(--destructive);
- --color-accent-foreground: var(--accent-foreground);
- --color-accent: var(--accent);
- --color-muted-foreground: var(--muted-foreground);
- --color-muted: var(--muted);
- --color-secondary-foreground: var(--secondary-foreground);
- --color-secondary: var(--secondary);
- --color-primary-foreground: var(--primary-foreground);
- --color-primary: var(--primary);
- --color-popover-foreground: var(--popover-foreground);
- --color-popover: var(--popover);
- --color-card-foreground: var(--card-foreground);
- --color-card: var(--card);
- --radius-sm: calc(var(--radius) * 0.6);
- --radius-md: calc(var(--radius) * 0.8);
- --radius-lg: var(--radius);
- --radius-xl: calc(var(--radius) * 1.4);
- --radius-2xl: calc(var(--radius) * 1.8);
- --radius-3xl: calc(var(--radius) * 2.2);
- --radius-4xl: calc(var(--radius) * 2.6);
-}
+ --color-card: #FFFFFF;
+ --color-card-foreground: #1A1C1C;
-:root {
- --background: oklch(1 0 0);
- --foreground: oklch(0.145 0 0);
- --card: oklch(1 0 0);
- --card-foreground: oklch(0.145 0 0);
- --popover: oklch(1 0 0);
- --popover-foreground: oklch(0.145 0 0);
- --primary: oklch(0.205 0 0);
- --primary-foreground: oklch(0.985 0 0);
- --secondary: oklch(0.97 0 0);
- --secondary-foreground: oklch(0.205 0 0);
- --muted: oklch(0.97 0 0);
- --muted-foreground: oklch(0.556 0 0);
- --accent: oklch(0.97 0 0);
- --accent-foreground: oklch(0.205 0 0);
- --destructive: oklch(0.577 0.245 27.325);
- --border: oklch(0.922 0 0);
- --input: oklch(0.922 0 0);
- --ring: oklch(0.708 0 0);
- --chart-1: oklch(0.87 0 0);
- --chart-2: oklch(0.556 0 0);
- --chart-3: oklch(0.439 0 0);
- --chart-4: oklch(0.371 0 0);
- --chart-5: oklch(0.269 0 0);
- --radius: 0.625rem;
- --sidebar: oklch(0.985 0 0);
- --sidebar-foreground: oklch(0.145 0 0);
- --sidebar-primary: oklch(0.205 0 0);
- --sidebar-primary-foreground: oklch(0.985 0 0);
- --sidebar-accent: oklch(0.97 0 0);
- --sidebar-accent-foreground: oklch(0.205 0 0);
- --sidebar-border: oklch(0.922 0 0);
- --sidebar-ring: oklch(0.708 0 0);
-}
+ --color-popover: #FFFFFF;
+ --color-popover-foreground: #1A1C1C;
-.dark {
- --background: oklch(0.145 0 0);
- --foreground: oklch(0.985 0 0);
- --card: oklch(0.205 0 0);
- --card-foreground: oklch(0.985 0 0);
- --popover: oklch(0.205 0 0);
- --popover-foreground: oklch(0.985 0 0);
- --primary: oklch(0.922 0 0);
- --primary-foreground: oklch(0.205 0 0);
- --secondary: oklch(0.269 0 0);
- --secondary-foreground: oklch(0.985 0 0);
- --muted: oklch(0.269 0 0);
- --muted-foreground: oklch(0.708 0 0);
- --accent: oklch(0.269 0 0);
- --accent-foreground: oklch(0.985 0 0);
- --destructive: oklch(0.704 0.191 22.216);
- --border: oklch(1 0 0 / 10%);
- --input: oklch(1 0 0 / 15%);
- --ring: oklch(0.556 0 0);
- --chart-1: oklch(0.87 0 0);
- --chart-2: oklch(0.556 0 0);
- --chart-3: oklch(0.439 0 0);
- --chart-4: oklch(0.371 0 0);
- --chart-5: oklch(0.269 0 0);
- --sidebar: oklch(0.205 0 0);
- --sidebar-foreground: oklch(0.985 0 0);
- --sidebar-primary: oklch(0.488 0.243 264.376);
- --sidebar-primary-foreground: oklch(0.985 0 0);
- --sidebar-accent: oklch(0.269 0 0);
- --sidebar-accent-foreground: oklch(0.985 0 0);
- --sidebar-border: oklch(1 0 0 / 10%);
- --sidebar-ring: oklch(0.556 0 0);
+ --color-primary: #5F5E5E;
+ --color-primary-foreground: #FFFFFF;
+
+ --color-secondary: #F3F3F3;
+ --color-secondary-foreground: #1A1C1C;
+
+ --color-muted: #F3F3F3;
+ --color-muted-foreground: #6D6D6D;
+
+ --color-accent: #FFBF00;
+ --color-accent-foreground: #1A1C1C;
+
+ --color-destructive: #EE4444;
+ --color-destructive-foreground: #F9F9F9;
+
+ --color-border: rgba(0, 0, 0, 0.05);
+ --color-input: rgba(0, 0, 0, 0.05);
+ --color-ring: #FFBF00;
+
+ --font-inter: var(--inter-font), sans-serif;
+ --font-manrope: var(--manrope-font), sans-serif;
+ --font-bebas-neue: var(--bebas-font), sans-serif;
+
+ --radius-sm: 0.125rem;
+ --radius-md: 0.25rem;
+ --radius-lg: 0.5rem;
}
@layer base {
+ :root {
+ --background: #F9F9F9;
+ --foreground: #1A1C1C;
+ --primary: #5F5E5E;
+ --accent: #FFBF00;
+ }
+
* {
- @apply border-border outline-ring/50;
+ border-color: var(--color-border);
}
+
body {
- @apply bg-background text-foreground;
+ background-color: var(--color-background);
+ color: var(--color-foreground);
+ font-family: var(--font-manrope), sans-serif;
+ -webkit-font-smoothing: antialiased;
+ min-height: 100vh;
+ margin: 0;
}
- html {
- @apply font-sans;
+}
+
+@layer utilities {
+ .label-editorial {
+ font-family: var(--font-manrope), sans-serif;
+ text-transform: uppercase;
+ letter-spacing: 0.15em;
+ font-weight: 600;
+ font-size: 0.75rem;
+ }
+
+ .glass-nav {
+ background-color: rgba(255, 255, 255, 0.85);
+ backdrop-filter: blur(24px);
+ -webkit-backdrop-filter: blur(24px);
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
}
\ No newline at end of file
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 976eb90..f01d084 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,20 +1,27 @@
import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
+import { Bebas_Neue, Inter, Manrope } from "next/font/google";
import "./globals.css";
-const geistSans = Geist({
- variable: "--font-geist-sans",
+const bebasNeue = Bebas_Neue({
+ weight: "400",
+ variable: "--bebas-font",
subsets: ["latin"],
});
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
+const inter = Inter({
+ variable: "--inter-font",
+ subsets: ["latin"],
+ weight: ["700", "800", "900"],
+});
+
+const manrope = Manrope({
+ variable: "--manrope-font",
subsets: ["latin"],
});
export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+ title: "Utku Kırkan | Engineering Excellence",
+ description: "Modern Mühendislik, Güçlü Yapılar. Muğla'da Güvenilir Mühendislik ve İnşaat Hizmetleri.",
};
export default function RootLayout({
@@ -24,10 +31,13 @@ export default function RootLayout({
}>) {
return (
- {children}
+
+ {children}
+
);
}
diff --git a/src/app/page.tsx b/src/app/page.tsx
deleted file mode 100644
index 3f36f7c..0000000
--- a/src/app/page.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import Image from "next/image";
-
-export default function Home() {
- return (
-
-
-
-
-
- To get started, edit the page.tsx file.
-
-
- Looking for a starting point or more instructions? Head over to{" "}
-
- Templates
- {" "}
- or the{" "}
-
- Learning
- {" "}
- center.
-
-
-
-
-
- );
-}
diff --git a/src/components/footer.tsx b/src/components/footer.tsx
new file mode 100644
index 0000000..76cc029
--- /dev/null
+++ b/src/components/footer.tsx
@@ -0,0 +1,44 @@
+"use client";
+
+import { motion } from "framer-motion";
+
+export function Footer() {
+ return (
+
+ );
+}
diff --git a/src/components/landing-page.tsx b/src/components/landing-page.tsx
new file mode 100644
index 0000000..1b1c02f
--- /dev/null
+++ b/src/components/landing-page.tsx
@@ -0,0 +1,288 @@
+"use client";
+
+import Image from "next/image";
+import { motion } from "framer-motion";
+import {
+ Phone,
+ MessageSquare,
+ ArrowUpRight
+} from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Textarea } from "@/components/ui/textarea";
+import Link from "next/link";
+
+const fadeInUp = {
+ initial: { opacity: 0, y: 30 },
+ whileInView: { opacity: 1, y: 0 },
+ viewport: { once: true },
+ transition: { duration: 0.8, ease: "easeOut" as const }
+};
+
+interface Project {
+ id: string;
+ title: string;
+ description: string;
+ m2: number;
+ rooms: string;
+ images: string[];
+ status: string;
+}
+
+export function LandingPage({ projects }: { projects: Project[] }) {
+ return (
+
+ {/* Hero Section - The Curated Monolith */}
+
+
+
+
+
+ Muğla • Mühendislik & Müteahhitlik
+
+ Modern
+ Mühendislik
+ Güçlü Yapılar
+
+
+
+
+
+
+ {/* Services Section - Architectural Excellence */}
+
+
+
+
+ Uzmanlık Alanlarımız
+
+ Mimari
+ Mükemmeliyet
+
+
+ Sadece bina inşa etmiyoruz; mühendislik disipliniyle şekillendirilmiş, Muğla'nın dokusuna uyumlu yaşam alanları tasarlıyoruz.
+
+
+
+
+ {[
+ {
+ id: "01",
+ title: "Statik Proje Tasarımı",
+ desc: "Maksimum dayanıklılık için ileri düzey mühendislik hesaplamaları ve deprem yönetmeliğine tam uyumlu taşıyıcı sistem analizleri.",
+ img: "https://images.unsplash.com/photo-1503387762-592deb58ef4e?q=80&w=2062"
+ },
+ {
+ id: "02",
+ title: "Müteahhitlik Hizmetleri",
+ desc: "A'dan Z'ye anahtar teslim inşaat süreçleri. Kaliteli malzeme ve usta işçiliği mühendislik denetimiyle birleştiriyoruz.",
+ img: "https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=2070"
+ },
+ {
+ id: "03",
+ title: "Teknik Danışmanlık",
+ desc: "İnşaat yatırım süreçlerinizde risk yönetimi, bütçe optimizasyonu ve yasal mevzuat uyumu konusunda profesyonel destek.",
+ img: "https://images.unsplash.com/photo-1497366754035-f200968a6e72?q=80&w=1974"
+ }
+ ].map((s, i) => (
+
+
+
+ ))}
+
+
+
+
+
+ {/* Projects Section - Horizontal Monolith */}
+
+
+
+
+ PROJELER
+
+
+ 2023 - 2024 Koleksiyonu
+
+
+
+ {projects.length > 0 ? projects.map((p, i) => (
+
+
+
+ {p.status}
+ {p.title}
+
+ {p.m2} m²
+ Muğla, Menteşe
+
+
+
+ )) : (
+ [
+ "https://images.unsplash.com/photo-1600585154340-be6161a56a0c?q=80&w=2070",
+ "https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=2070",
+ "https://images.unsplash.com/photo-1497366754035-f200968a6e72?q=80&w=1974"
+ ].map((url, i) => (
+
+
+
+ ))
+ )}
+
+
+
+
+ {/* About Section */}
+
+
+
+
+
+
+
+
+
+ Kurumsal Vizyon
+
+ Disiplinli
+ İnşaat Kültürü
+
+
+
+ İnşaat mühendisliği her şeyden önce bir disiplin, yapı güvenliği ise bir haktır. Utku Kırkan olarak, Muğla'nın mimari zenginliğini koruyarak geleceğin sağlam temellerini bugün atıyoruz.
+
+
+ Analitik çözümleme ve estetik kaygıyı bir dengede tutarak, "The Curated Monolith" anlayışıyla zamansız yapılar inşa ediyoruz. Her detayda titizlik, her projede sürdürebilirlik sözü veriyoruz.
+
+
+
+
+
+
+ {/* Contact Section */}
+
+
+
+
+ İletişim & Randevu
+
+ Projeyi
+ Konuşalım
+
+
+
+
+
+
Telefon Hattı
+
+90 5XX XXX XX XX
+
+
+
+
+
+
+
+ Ücretsiz Teklif Formu
+
+
+ Ad Soyad
+
+
+
+ Tel / E-posta
+
+
+
+ Proje Detayları
+
+
+
+ Formu Gönder
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx
new file mode 100644
index 0000000..4a6b9f6
--- /dev/null
+++ b/src/components/navbar.tsx
@@ -0,0 +1,21 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { ArrowUpRight } from "lucide-react";
+
+export function Navbar() {
+ return (
+
+
+
+
+ );
+}
diff --git a/src/seed.ts b/src/seed.ts
new file mode 100644
index 0000000..636477c
--- /dev/null
+++ b/src/seed.ts
@@ -0,0 +1,71 @@
+import { PrismaClient } from "./generated/prisma";
+import { PrismaPg } from "@prisma/adapter-pg";
+import pg from "pg";
+import * as dotenv from "dotenv";
+
+dotenv.config();
+
+const connectionString = process.env.DATABASE_URL;
+if (!connectionString) throw new Error("DATABASE_URL is not set");
+
+const pool = new pg.Pool({ connectionString });
+const adapter = new PrismaPg(pool);
+const prisma = new PrismaClient({ adapter });
+
+async function main() {
+ console.log("Seeding projects...");
+
+ const projects = [
+ {
+ title: "VILLA AURELIAN",
+ description: "Menteşe'nin kalbinde, modern mimariyle doğanın buluştuğu lüks villa projesi. Brütalist dokunuşlar ve geniş cam yüzeyler ile ferah bir yaşam alanı.",
+ m2: 450,
+ rooms: "5+1",
+ status: "TAMAMLANDI",
+ images: [
+ "https://images.unsplash.com/photo-1600585154340-be6161a56a0c?q=80&w=2070",
+ "https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?q=80&w=2075"
+ ]
+ },
+ {
+ title: "ZENITH APARTMANI",
+ description: "Şehir merkezinde yüksek mühendislik standartlarıyla inşa edilen, deprem güvenliği öncelikli modern konut projesi.",
+ m2: 1200,
+ rooms: "3+1 / 4+1",
+ status: "DEVAM EDİYOR",
+ images: [
+ "https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=2070",
+ "https://images.unsplash.com/photo-1497366754035-f200968a6e72?q=80&w=1974"
+ ]
+ },
+ {
+ title: "MİLAS REZİDANS",
+ description: "Muğla'nın tarihi dokusuna uyumlu, sürdürülebilir enerji çözümleriyle donatılmış ekolojik konut kompleksi.",
+ m2: 3200,
+ rooms: "Stüdyo / 2+1",
+ status: "PLANLANIYOR",
+ images: [
+ "https://images.unsplash.com/photo-1503387762-592deb58ef4e?q=80&w=2062",
+ "https://images.unsplash.com/photo-1503387762-592deb58ef4e?q=80&w=2062"
+ ]
+ }
+ ];
+
+ for (const project of projects) {
+ await prisma.project.create({
+ data: project
+ });
+ }
+
+ console.log("Seeding complete!");
+}
+
+main()
+ .catch((e) => {
+ console.error(e);
+ process.exit(1);
+ })
+ .finally(async () => {
+ await prisma.$disconnect();
+ await pool.end();
+ });