diff --git a/prisma/dev.db b/prisma/dev.db
index eeb0ec3..5b73134 100644
Binary files a/prisma/dev.db and b/prisma/dev.db differ
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index f983f60..423aca8 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -19,6 +19,7 @@ model Branch {
name String
address String?
phone String?
+ hallCount Int? @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
classes DanceClass[]
diff --git a/src/app/admin/branches/AddBranchForm.tsx b/src/app/admin/branches/AddBranchForm.tsx
index c3f66bb..b09d862 100644
--- a/src/app/admin/branches/AddBranchForm.tsx
+++ b/src/app/admin/branches/AddBranchForm.tsx
@@ -6,16 +6,20 @@ import styles from './branches.module.css';
export function AddBranchForm() {
const [name, setName] = useState('');
const [address, setAddress] = useState('');
+ const [phone, setPhone] = useState('');
+ const [hallCount, setHallCount] = useState('1');
const router = useRouter();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
await fetch('/api/branches', {
method: 'POST',
- body: JSON.stringify({ name, address }),
+ body: JSON.stringify({ name, address, phone, hallCount: parseInt(hallCount) }),
});
setName('');
setAddress('');
+ setPhone('');
+ setHallCount('1');
router.refresh();
};
@@ -25,10 +29,18 @@ export function AddBranchForm() {
setName(e.target.value)} className={styles.input} required />
+
+
+ setPhone(e.target.value)} className={styles.input} />
+
setAddress(e.target.value)} className={styles.input} />
+
+
+ setHallCount(e.target.value)} className={styles.input} />
+
);
diff --git a/src/app/admin/branches/BranchList.tsx b/src/app/admin/branches/BranchList.tsx
index dc83b0a..8295334 100644
--- a/src/app/admin/branches/BranchList.tsx
+++ b/src/app/admin/branches/BranchList.tsx
@@ -17,7 +17,8 @@ export function BranchList({ branches }: { branches: any[] }) {
{b.name}
-
{b.address}
+
{b.phone ? `Tel: ${b.phone}` : 'Telefon yok'} | {b.address || 'Adres yok'}
+
Salon Sayısı: {b.hallCount || 1}
diff --git a/src/app/api/branches/[id]/route.ts b/src/app/api/branches/[id]/route.ts
index 5a68415..5682546 100644
--- a/src/app/api/branches/[id]/route.ts
+++ b/src/app/api/branches/[id]/route.ts
@@ -25,7 +25,10 @@ export async function PUT(
const json = await request.json();
const branch = await prisma.branch.update({
where: { id },
- data: json,
+ data: {
+ ...json,
+ hallCount: json.hallCount ? parseInt(json.hallCount) : undefined
+ },
});
return NextResponse.json(branch);
} catch (error) {
diff --git a/src/app/api/branches/route.ts b/src/app/api/branches/route.ts
index 6055b85..6de689d 100644
--- a/src/app/api/branches/route.ts
+++ b/src/app/api/branches/route.ts
@@ -16,7 +16,8 @@ export async function POST(request: Request) {
data: {
name: json.name,
address: json.address,
- phone: json.phone
+ phone: json.phone,
+ hallCount: json.hallCount ? parseInt(json.hallCount) : undefined
}
});
return NextResponse.json(branch);
diff --git a/src/app/page.module.css b/src/app/page.module.css
index 59dea42..e370f6d 100644
--- a/src/app/page.module.css
+++ b/src/app/page.module.css
@@ -1,141 +1,101 @@
.page {
- --background: #fafafa;
- --foreground: #fff;
+ --primary: #b21f1f;
+ --secondary: #1a2a6c;
+ --accent: #fdbb2d;
+ --bg-gradient: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
+ --white: #ffffff;
+ --text: #333333;
+ --text-muted: #666666;
- --text-primary: #000;
- --text-secondary: #666;
-
- --button-primary-hover: #383838;
- --button-secondary-hover: #f2f2f2;
- --button-secondary-border: #ebebeb;
-
- display: flex;
min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background: var(--bg-gradient);
+ font-family: var(--font-outfit, 'Outfit', sans-serif);
+ color: var(--text);
+}
+
+.nav {
+ padding: 1.5rem 4rem;
+ display: flex;
+ justify-content: space-between;
align-items: center;
- justify-content: center;
- font-family: var(--font-geist-sans);
- background-color: var(--background);
+ background: rgba(255, 255, 255, 0.9);
+ backdrop-filter: blur(10px);
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
+ position: sticky;
+ top: 0;
+ z-index: 1000;
+}
+
+.logo {
+ font-size: 1.5rem;
+ font-weight: 800;
+ background: linear-gradient(to right, var(--secondary), var(--primary));
+ -webkit-background-clip: text;
+ background-clip: text;
+ -webkit-text-fill-color: transparent;
+ letter-spacing: -1px;
+}
+
+.adminLink {
+ padding: 0.6rem 1.2rem;
+ background: var(--secondary);
+ color: white;
+ border-radius: 8px;
+ text-decoration: none;
+ font-weight: 600;
+ transition: all 0.3s;
+}
+
+.adminLink:hover {
+ background: var(--primary);
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.main {
+ flex: 1;
+ padding: 4rem 2rem;
display: flex;
- min-height: 100vh;
- width: 100%;
+ flex-direction: column;
+ gap: 3rem;
+}
+
+.hero {
+ text-align: center;
max-width: 800px;
- flex-direction: column;
- align-items: flex-start;
- justify-content: space-between;
- background-color: var(--foreground);
- padding: 120px 60px;
+ margin: 0 auto;
}
-.intro {
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- text-align: left;
- gap: 24px;
+.hero h1 {
+ font-size: 3.5rem;
+ font-weight: 900;
+ margin-bottom: 1rem;
+ color: #111;
+ letter-spacing: -2px;
}
-.intro h1 {
- max-width: 320px;
- font-size: 40px;
- font-weight: 600;
- line-height: 48px;
- letter-spacing: -2.4px;
- text-wrap: balance;
- color: var(--text-primary);
+.hero p {
+ font-size: 1.25rem;
+ color: var(--text-muted);
}
-.intro p {
- max-width: 440px;
- font-size: 18px;
- line-height: 32px;
- text-wrap: balance;
- color: var(--text-secondary);
+.footer {
+ padding: 2rem;
+ text-align: center;
+ background: rgba(255, 255, 255, 0.5);
+ border-top: 1px solid rgba(0, 0, 0, 0.05);
+ color: var(--text-muted);
+ font-size: 0.9rem;
}
-.intro a {
- font-weight: 500;
- color: var(--text-primary);
-}
-
-.ctas {
- display: flex;
- flex-direction: row;
- width: 100%;
- max-width: 440px;
- gap: 16px;
- font-size: 14px;
-}
-
-.ctas a {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 40px;
- padding: 0 16px;
- border-radius: 128px;
- border: 1px solid transparent;
- transition: 0.2s;
- cursor: pointer;
- width: fit-content;
- font-weight: 500;
-}
-
-a.primary {
- background: var(--text-primary);
- color: var(--background);
- gap: 8px;
-}
-
-a.secondary {
- border-color: var(--button-secondary-border);
-}
-
-/* Enable hover only on non-touch devices */
-@media (hover: hover) and (pointer: fine) {
- a.primary:hover {
- background: var(--button-primary-hover);
- border-color: transparent;
+@media (max-width: 768px) {
+ .nav {
+ padding: 1rem 2rem;
}
- a.secondary:hover {
- background: var(--button-secondary-hover);
- border-color: transparent;
+ .hero h1 {
+ font-size: 2.5rem;
}
-}
-
-@media (max-width: 600px) {
- .main {
- padding: 48px 24px;
- }
-
- .intro {
- gap: 16px;
- }
-
- .intro h1 {
- font-size: 32px;
- line-height: 40px;
- letter-spacing: -1.92px;
- }
-}
-
-@media (prefers-color-scheme: dark) {
- .logo {
- filter: invert();
- }
-
- .page {
- --background: #000;
- --foreground: #000;
-
- --text-primary: #ededed;
- --text-secondary: #999;
-
- --button-primary-hover: #ccc;
- --button-secondary-hover: #1a1a1a;
- --button-secondary-border: #1a1a1a;
- }
-}
+}
\ No newline at end of file
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 7b947a2..cac642d 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,66 +1,57 @@
-import Image from "next/image";
+import { prisma } from "@/infrastructure/db/prisma";
+import { ScheduleCalendar } from "@/components/ScheduleCalendar";
+import Link from "next/link";
import styles from "./page.module.css";
-export default function Home() {
+export default async function Home() {
+ // Calculate start and end of current week
+ const now = new Date();
+ const dayOfWeek = now.getDay(); // 0 is Sunday
+ const diff = now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1); // Adjust to Monday
+ const startOfWeek = new Date(now.setDate(diff));
+ startOfWeek.setHours(0, 0, 0, 0);
+
+ const endOfWeek = new Date(startOfWeek);
+ endOfWeek.setDate(endOfWeek.getDate() + 7);
+
+ const lessons = await prisma.lesson.findMany({
+ where: {
+ startTime: {
+ gte: startOfWeek,
+ lt: endOfWeek,
+ },
+ },
+ include: {
+ instructor: true,
+ branch: true,
+ class: true,
+ },
+ orderBy: {
+ startTime: 'asc',
+ },
+ });
+
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.
-
-
-
+
+ Dansın Ritmini Keşfedin
+ Haftalık kurs programımızı aşağıdan takip edebilirsiniz.
+
+
+
+
+
);
}
diff --git a/src/components/ScheduleCalendar.module.css b/src/components/ScheduleCalendar.module.css
new file mode 100644
index 0000000..9011ebe
--- /dev/null
+++ b/src/components/ScheduleCalendar.module.css
@@ -0,0 +1,93 @@
+.container {
+ padding: 2rem;
+ max-width: 1200px;
+ margin: 0 auto;
+ font-family: var(--font-outfit, 'Outfit', sans-serif);
+}
+
+.title {
+ text-align: center;
+ margin-bottom: 2rem;
+ font-size: 2.5rem;
+ background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
+ -webkit-background-clip: text;
+ background-clip: text;
+ -webkit-text-fill-color: transparent;
+ font-weight: 800;
+}
+
+.calendar {
+ display: grid;
+ grid-template-columns: repeat(7, 1fr);
+ gap: 1rem;
+ background: rgba(255, 255, 255, 0.8);
+ backdrop-filter: blur(10px);
+ border-radius: 16px;
+ padding: 1.5rem;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+}
+
+.dayColumn {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.dayHeader {
+ text-align: center;
+ padding: 1rem;
+ background: #333;
+ color: white;
+ border-radius: 8px;
+ font-weight: 600;
+}
+
+.lessonCard {
+ background: white;
+ padding: 1rem;
+ border-radius: 8px;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
+ border-left: 4px solid #b21f1f;
+ transition: transform 0.2s, box-shadow 0.2s;
+ cursor: default;
+}
+
+.lessonCard:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
+}
+
+.lessonTime {
+ font-size: 0.85rem;
+ color: #666;
+ font-weight: 500;
+ display: block;
+ margin-bottom: 0.5rem;
+}
+
+.lessonName {
+ font-size: 1.1rem;
+ font-weight: 700;
+ color: #333;
+ margin-bottom: 0.5rem;
+}
+
+.lessonDetails {
+ font-size: 0.8rem;
+ color: #888;
+}
+
+.empty {
+ text-align: center;
+ padding: 2rem;
+ color: #aaa;
+ font-style: italic;
+ grid-column: span 7;
+}
+
+@media (max-width: 1024px) {
+ .calendar {
+ grid-template-columns: 1fr;
+ }
+}
\ No newline at end of file
diff --git a/src/components/ScheduleCalendar.tsx b/src/components/ScheduleCalendar.tsx
new file mode 100644
index 0000000..3567df1
--- /dev/null
+++ b/src/components/ScheduleCalendar.tsx
@@ -0,0 +1,80 @@
+'use client';
+import { useMemo } from 'react';
+import styles from './ScheduleCalendar.module.css';
+
+interface Lesson {
+ id: string;
+ name?: string | null;
+ startTime: Date | string;
+ endTime: Date | string;
+ type: string;
+ class?: { name: string } | null;
+ instructor: { name: string };
+ branch: { name: string };
+}
+
+export function ScheduleCalendar({ lessons }: { lessons: Lesson[] }) {
+ const days = ['Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi', 'Pazar'];
+
+ // Group lessons by day
+ const groupedLessons = useMemo(() => {
+ const groups: Record = {};
+ lessons.forEach(lesson => {
+ const date = new Date(lesson.startTime);
+ // JS getDay() returns 0 for Sunday, 1 for Monday etc.
+ // We want 0 for Monday, 6 for Sunday
+ let dayIndex = date.getDay() - 1;
+ if (dayIndex === -1) dayIndex = 6;
+
+ if (!groups[dayIndex]) groups[dayIndex] = [];
+ groups[dayIndex].push(lesson);
+ });
+
+ // Sort lessons by time in each day
+ Object.keys(groups).forEach(day => {
+ groups[parseInt(day)].sort((a, b) =>
+ new Date(a.startTime).getTime() - new Date(b.startTime).getTime()
+ );
+ });
+
+ return groups;
+ }, [lessons]);
+
+ const formatTime = (dateStr: string | Date) => {
+ const date = new Date(dateStr);
+ return date.toLocaleTimeString('tr-TR', { hour: '2-digit', minute: '2-digit', hour12: false });
+ };
+
+ return (
+
+
Haftalık Ders Programı
+
+ {days.map((day, index) => (
+
+
{day}
+ {groupedLessons[index]?.map(lesson => (
+
+
+ {formatTime(lesson.startTime)} - {formatTime(lesson.endTime)}
+
+
+ {lesson.class?.name || lesson.name || 'İsimsiz Ders'}
+
+
+
Eğitmen: {lesson.instructor.name}
+
Şube: {lesson.branch.name}
+
Tür: {lesson.type}
+
+
+ ))}
+ {(!groupedLessons[index] || groupedLessons[index].length === 0) && (
+
+ Ders yok
+
+ )}
+
+ ))}
+
+
+ );
+}