fix: explicit prisma client installation and move prisma to devDependencies
This commit is contained in:
84
docs/.PRD
Normal file
84
docs/.PRD
Normal 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
51
infographic.html
Normal 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
BIN
infographic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 84 KiB |
51
landing.html
Normal file
51
landing.html
Normal 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
BIN
landing.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 108 KiB |
51
listings.html
Normal file
51
listings.html
Normal 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
BIN
listings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
982
package-lock.json
generated
982
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
51
services_code.html
Normal 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
BIN
services_screen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
23
src/lib/prisma.ts
Normal file
23
src/lib/prisma.ts
Normal 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;
|
||||||
Reference in New Issue
Block a user