Skip to content

Commit 83208f8

Browse files
Merge pull request #1 from ft4bhi/main
data entry
2 parents d60869a + 9515ee6 commit 83208f8

File tree

14 files changed

+191
-84
lines changed

14 files changed

+191
-84
lines changed

drizzle.config.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ import type { Config } from "drizzle-kit";
22
import * as dotenv from "dotenv";
33
import { resolve } from "path";
44

5-
// 🔥 Explicitly load .env.local
5+
// Load your env file explicitly
66
dotenv.config({ path: resolve(__dirname, ".env.local") });
77

88
export default {
9-
schema: "./src/lib/db/schema.ts", // adjust if you use a different path
9+
schema: "./src/lib/db/schema.ts",
1010
out: "./drizzle/migrations",
11-
dialect: "postgresql",
11+
dialect: "postgresql", // 👈 REQUIRED and must be a literal
1212
dbCredentials: {
13-
url: process.env.DATABASE_URL!,
13+
url: process.env.DATABASE_URL!, // 👈 Make sure this exists
1414
},
1515
strict: true,
16+
schemaFilter: ["public"], // optional, just to scope schema
1617
} satisfies Config;

drizzle/migrations/0000_puzzling_sally_floyd.sql renamed to drizzle/migrations/0000_ordinary_doctor_faustus.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CREATE TABLE "events" (
66
"venue" varchar(255) NOT NULL,
77
"date" timestamp NOT NULL,
88
"time" varchar(50),
9-
"image" varchar(500) NOT NULL,
9+
"image" "bytea",
1010
"created_at" timestamp DEFAULT now() NOT NULL,
1111
"updated_at" timestamp DEFAULT now() NOT NULL,
1212
CONSTRAINT "events_slug_unique" UNIQUE("slug")

drizzle/migrations/meta/0000_snapshot.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"id": "a0ee70f6-983a-423a-b947-b21e3ef07c49",
2+
"id": "4518ee12-206e-490c-ade5-179ba41f07e6",
33
"prevId": "00000000-0000-0000-0000-000000000000",
44
"version": "7",
55
"dialect": "postgresql",
@@ -53,9 +53,9 @@
5353
},
5454
"image": {
5555
"name": "image",
56-
"type": "varchar(500)",
56+
"type": "bytea",
5757
"primaryKey": false,
58-
"notNull": true
58+
"notNull": false
5959
},
6060
"created_at": {
6161
"name": "created_at",

drizzle/migrations/meta/_journal.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
{
66
"idx": 0,
77
"version": "7",
8-
"when": 1756925082563,
9-
"tag": "0000_puzzling_sally_floyd",
8+
"when": 1758033961329,
9+
"tag": "0000_ordinary_doctor_faustus",
1010
"breakpoints": true
1111
}
1212
]

package-lock.json

Lines changed: 23 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"Docker-run": "docker run -p 3000:3000 nextjs_tempalate"
2424
},
2525
"dependencies": {
26+
"@neondatabase/serverless": "^1.0.1",
2627
"date-fns": "^4.1.0",
2728
"dotenv": "^17.2.2",
2829
"drizzle-kit": "^0.31.4",

src/app/api/events/[id]/route.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ import { db } from "@/lib/db";
33
import { events } from "@/lib/db/schema";
44
import { eq } from "drizzle-orm";
55

6+
7+
// GET one event
8+
export async function GET(_: Request, { params }: { params: { id: string } }) {
9+
const result = await db.select().from(events).where(eq(events.id, params.id));
10+
if (!result[0]) {
11+
return NextResponse.json({ error: "Not found" }, { status: 404 });
12+
}
13+
return NextResponse.json(result[0]);
14+
}
15+
616
// Update event
717
export async function PUT(req: Request, { params }: { params: { id: string } }) {
818
const data = await req.json();

src/app/api/events/route.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { db } from "@/lib/db";
22
import { events } from "@/lib/db/schema";
3-
import { eq } from "drizzle-orm";
43
import { NextResponse } from "next/server";
54

65
export async function GET() {
@@ -9,8 +8,37 @@ export async function GET() {
98
}
109

1110
export async function POST(req: Request) {
12-
const data = await req.json();
13-
const slug = data.title.toLowerCase().replace(/\s+/g, "-");
14-
const created = await db.insert(events).values({ ...data, slug }).returning();
11+
const formData = await req.formData();
12+
13+
const title = formData.get("title") as string;
14+
const description = formData.get("description") as string;
15+
const venue = formData.get("venue") as string;
16+
const date = formData.get("date") as string;
17+
const time = formData.get("time") as string | null;
18+
19+
// image may or may not exist
20+
const imageFile = formData.get("image") as File | null;
21+
let imageBuffer: Buffer | null = null;
22+
23+
if (imageFile) {
24+
const arrayBuffer = await imageFile.arrayBuffer();
25+
imageBuffer = Buffer.from(arrayBuffer);
26+
}
27+
28+
const slug = title.toLowerCase().replace(/\s+/g, "-");
29+
30+
const created = await db
31+
.insert(events)
32+
.values({
33+
slug,
34+
title,
35+
description,
36+
venue,
37+
date: new Date(date), // timestamp
38+
time: time ?? null,
39+
image: imageBuffer, // store blob
40+
})
41+
.returning();
42+
1543
return NextResponse.json(created[0], { status: 201 });
1644
}

src/app/events/[id]/edit/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// New Event Page - src/app/events/[id]/edit/page.tsx
12
"use client";
23

34
import { useState } from "react";

src/app/events/[id]/page.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { notFound } from "next/navigation";
2+
3+
export default async function EventDetailPage({
4+
params,
5+
}: {
6+
params: { id: string };
7+
}) {
8+
const { id } = params;
9+
10+
const baseUrl =
11+
process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000";
12+
13+
const res = await fetch(`${baseUrl}/api/events/${id}`, {
14+
cache: "no-store",
15+
});
16+
17+
if (!res.ok) return notFound();
18+
19+
const event = await res.json();
20+
21+
return (
22+
<div className="max-w-2xl mx-auto p-6 space-y-4">
23+
<h1 className="text-3xl font-bold">{event.title}</h1>
24+
<p className="text-gray-600">{event.venue}</p>
25+
<p className="text-gray-500">
26+
{new Date(event.date).toLocaleDateString()} at {event.time}
27+
</p>
28+
{event.image && (
29+
<img
30+
src={event.image}
31+
alt={event.title}
32+
className="w-full rounded-lg shadow"
33+
/>
34+
)}
35+
<p className="mt-4 whitespace-pre-line">{event.description}</p>
36+
</div>
37+
);
38+
}
39+

0 commit comments

Comments
 (0)