fix: explicit prisma client installation and move prisma to devDependencies

This commit is contained in:
AyrisAI
2026-04-04 04:57:13 +03:00
parent 81709cdfff
commit 0f5c29e50f
13 changed files with 1297 additions and 4 deletions

84
docs/.PRD Normal file
View File

@@ -0,0 +1,84 @@
🏗️ Ürün Gereksinim Dokümanı (PRD): Utku Kırkan Web Projesi
1. Ürün Özeti
Utku Kırkan'ın inşaat mühendisliği ve müteahhitlik kimliğini modern, minimalist ve güven veren bir dijital kimlikle temsil eden, reklam odaklı bir Landing Page.
Hedef Kitle: Arsa sahipleri, yatırımcılar, konut arayanlar ve teknik danışmanlık ihtiyacı olanlar.
Temel Amaç: Güven inşa etmek ve hızlı iletişim (Lead Generation) sağlamak.
2. Teknik Stack
Senin uzmanlığın ve mevcut yapına en uygun, yüksek performanslı mimari:
Frontend: Next.js 15 (App Router).
Styling: Tailwind CSS + Framer Motion (Akışkan animasyonlar için).
Database: PostgreSQL (Coolify üzerinde self-hosted).
ORM: Drizzle ORM (Hız ve Tip güvenliği için).
Deployment: Coolify (Dockerized).
3. Sayfa Yapısı ve İçerik (Single Page Architecture)
3.1. Hero Section (İlk İzlenim)
Görsel: Yüksek çözünürlüklü, geniş açılı bir şantiye veya bitmiş proje fotoğrafı (Overlay ile karartılmış).
Metin: "Modern Mühendislik, Güçlü Yapılar: Utku Kırkan".
CTA (Eylem Butonu): "Projelerimizi Keşfedin" ve "Teklif Al".
3.2. Projeler (Dynamic Gallery)
Özellik: Veritabanından çekilen, kart tasarımlı proje listesi.
Detay: Her proje kartında; Proje Adı, Konum (Muğla/Menteşe vb.), Durum (Tamamlandı/Devam Ediyor).
Modern Dokunuş: Resimlerin üzerine gelindiğinde (hover) detayların belirmesi.
3.3. Hizmetler (Core Competencies)
Statik Proje ve Tasarım.
Müteahhitlik ve Anahtar Teslim İnşaat.
Teknik Danışmanlık ve Denetim.
3.4. Hakkında & Güven (Social Proof)
Utku Kırkan'ın kısa özgeçmişi ve "Mühendislik disipliniyle müteahhitlik" vurgusu.
(Varsa) Referans logoları veya çözüm ortakları.
3.5. İletişim (Conversion Zone)
Hızlı Erişim: Doğrudan WhatsApp yönlendirmesi.
Basit Form: Ad-Soyad, Telefon ve Kısa Not (Coolify DB'ye kaydedilecek ve belki sana bir bildirim düşecek).
Lokasyon: Google Haritalar entegrasyonu.
4. Teknik Gereksinimler & Fonksiyonel Özellikler
Özellik Açıklama
Hız (LCP) Next.js Image component ile optimize edilmiş görseller. Google PageSpeed puanı +90 olmalı.
SEO Muğla odaklı anahtar kelimeler (Muğla müteahhit, statik proje mühendisi vb.) meta tag entegrasyonu.
Responsive Mobil öncelikli tasarım. Şantiyede telefondan bakan müşteri için kusursuz deneyim.
Admin Paneli /admin altında Utku'nun (veya senin) yeni proje görseli ve metni ekleyebileceği şifreli, basit bir crud ekranı.
Analytics Reklam verimliliğini ölçmek için basit bir Google Analytics veya Vercel Analytics entegrasyonu.
5. Tasarım İlkeleri
Tipografi: Modern ve maskülen fontlar (Örn: Bebas Neue başlıklar için, Inter gövde metinleri için).
Renkler: * Primary: #111827 (Deep Charcoal)
Accent: #F59E0B (Amber/Construction Gold)
Background: #FFFFFF veya çok açık gri.
Animasyon: Sayfa aşağı kaydırıldığında (scroll) elementlerin yumuşakça belirmesi (Reveal effect).
6. Başarı Kriterleri (KPI)
Sitenin 1.5 saniyenin altında yüklenmesi.
Muğla yerel aramalarında ilk sayfada görünürlük.
Haftalık gelen WhatsApp/Form "lead" sayısı.

51
infographic.html Normal file
View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>contribution.usercontent.com - Coming Soon</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 12px;
padding: 60px 40px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
text-align: center;
max-width: 600px;
}
h1 {
color: #333;
font-size: 2.5em;
margin-bottom: 20px;
word-break: break-word;
}
p {
color: #666;
font-size: 1.2em;
line-height: 1.6;
}
.emoji {
font-size: 4em;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="emoji">🚀</div>
<h1>contribution.usercontent.com</h1>
<p>This domain is coming soon.</p>
</div>
</body>
</html>

BIN
infographic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

51
landing.html Normal file
View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>contribution.usercontent.com - Coming Soon</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 12px;
padding: 60px 40px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
text-align: center;
max-width: 600px;
}
h1 {
color: #333;
font-size: 2.5em;
margin-bottom: 20px;
word-break: break-word;
}
p {
color: #666;
font-size: 1.2em;
line-height: 1.6;
}
.emoji {
font-size: 4em;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="emoji">🚀</div>
<h1>contribution.usercontent.com</h1>
<p>This domain is coming soon.</p>
</div>
</body>
</html>

BIN
landing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

51
listings.html Normal file
View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>contribution.usercontent.com - Coming Soon</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 12px;
padding: 60px 40px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
text-align: center;
max-width: 600px;
}
h1 {
color: #333;
font-size: 2.5em;
margin-bottom: 20px;
word-break: break-word;
}
p {
color: #666;
font-size: 1.2em;
line-height: 1.6;
}
.emoji {
font-size: 4em;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="emoji">🚀</div>
<h1>contribution.usercontent.com</h1>
<p>This domain is coming soon.</p>
</div>
</body>
</html>

BIN
listings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

982
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,16 +10,22 @@
}, },
"dependencies": { "dependencies": {
"@base-ui/react": "^1.3.0", "@base-ui/react": "^1.3.0",
"@prisma/adapter-pg": "^7.6.0",
"@prisma/client": "^7.6.0",
"@prisma/config": "^7.6.0", "@prisma/config": "^7.6.0",
"@types/pg": "^8.20.0",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dotenv": "^17.4.0", "dotenv": "^17.4.0",
"framer-motion": "^12.38.0",
"lucide-react": "^1.7.0", "lucide-react": "^1.7.0",
"next": "16.2.2", "next": "16.2.2",
"pg": "^8.20.0",
"react": "19.2.4", "react": "19.2.4",
"react-dom": "19.2.4", "react-dom": "19.2.4",
"shadcn": "^4.1.2", "shadcn": "^4.1.2",
"tailwind-merge": "^3.5.0", "tailwind-merge": "^3.5.0",
"tailwindcss-animate": "^1.0.7",
"tw-animate-css": "^1.4.0" "tw-animate-css": "^1.4.0"
}, },
"devDependencies": { "devDependencies": {
@@ -29,6 +35,7 @@
"@types/react-dom": "^19", "@types/react-dom": "^19",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "16.2.2", "eslint-config-next": "16.2.2",
"prisma": "^7.6.0",
"tailwindcss": "^4", "tailwindcss": "^4",
"typescript": "^5" "typescript": "^5"
} }

View File

@@ -2,7 +2,6 @@ import { defineConfig } from '@prisma/config'
export default defineConfig({ export default defineConfig({
datasource: { datasource: {
adapter: 'postgresql',
url: "postgres://postgres:fsI47H3bbfpNCQD8GiCre2T97OOY8BwUJ02hUYzZfehYhutUJPO14BZgYsh0z3sG@65.109.236.58:3945/postgres" url: "postgres://postgres:fsI47H3bbfpNCQD8GiCre2T97OOY8BwUJ02hUYzZfehYhutUJPO14BZgYsh0z3sG@65.109.236.58:3945/postgres"
} }
}) })

51
services_code.html Normal file
View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>contribution.usercontent.com - Coming Soon</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 12px;
padding: 60px 40px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
text-align: center;
max-width: 600px;
}
h1 {
color: #333;
font-size: 2.5em;
margin-bottom: 20px;
word-break: break-word;
}
p {
color: #666;
font-size: 1.2em;
line-height: 1.6;
}
.emoji {
font-size: 4em;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="emoji">🚀</div>
<h1>contribution.usercontent.com</h1>
<p>This domain is coming soon.</p>
</div>
</body>
</html>

BIN
services_screen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

23
src/lib/prisma.ts Normal file
View File

@@ -0,0 +1,23 @@
import { PrismaClient } from "../generated/prisma";
import { PrismaPg } from "@prisma/adapter-pg";
import pg from "pg";
const globalForPrisma = global as unknown as { prisma: PrismaClient };
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);
export const prisma =
globalForPrisma.prisma ||
new PrismaClient({
adapter,
log: ["query"],
});
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;