Skip to content

Commit 5a80446

Browse files
Merge pull request #33 from kucc1997/fix-archives
fix: make archive years dynamic and unify upload dir usage
2 parents 54244e1 + 13bf8c9 commit 5a80446

File tree

5 files changed

+77
-32
lines changed

5 files changed

+77
-32
lines changed

src/app/api/papers/post.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { eq } from "drizzle-orm";
44
import { customAlphabet } from "nanoid";
55
import path from "path";
66
import { writeFile, mkdir } from "fs/promises";
7+
import { getUploadDir, getUploadPublicBasePath } from "@/lib/upload-path";
78

8-
// Get upload directory from environment variable or use default
9-
const UPLOAD_DIR = process.env.UPLOAD_DIR || "public/uploads";
9+
const UPLOAD_DIR = getUploadDir();
10+
const UPLOAD_PUBLIC_BASE = getUploadPublicBasePath();
1011

1112
export default async function POST(req: Request) {
1213
const formData = await req.formData();
@@ -40,7 +41,7 @@ export default async function POST(req: Request) {
4041
title: data.title,
4142
abstract: data.abstract,
4243
keywords: data.keywords,
43-
fileUrl: `/uploads/papers/${paperID}.pdf`,
44+
fileUrl: `${UPLOAD_PUBLIC_BASE}/papers/${paperID}.pdf`,
4445
themeId: data.theme,
4546
trackType: data.trackType,
4647
authorId: authorFromDb[0].id,

src/app/api/registration/route.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import { customAlphabet } from "nanoid"
55
import path from "path"
66
import { writeFile, mkdir } from "fs/promises"
77
import { sendRegistrationEmail } from "@/lib/mail"
8+
import { getUploadDir, getUploadPublicBasePath } from "@/lib/upload-path"
89

9-
// Get upload directory from environment variable or use default
10-
const UPLOAD_DIR = process.env.UPLOAD_DIR || "public/uploads"
10+
const UPLOAD_DIR = getUploadDir()
11+
const UPLOAD_PUBLIC_BASE = getUploadPublicBasePath()
1112

1213
// Create a custom nanoid generator for registration IDs
1314
const generateRegistrationId = customAlphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 8)
@@ -94,7 +95,7 @@ export async function POST(req: Request) {
9495
paperSubmission,
9596
dietaryRestrictions: dietaryRestrictions || null,
9697
specialRequirements: specialRequirements || null,
97-
paymentVoucherPath: `/uploads/vouchers/${registrationId}.${fileExtension}`,
98+
paymentVoucherPath: `${UPLOAD_PUBLIC_BASE}/vouchers/${registrationId}.${fileExtension}`,
9899
status: "pending"
99100
}).returning()
100101

@@ -136,4 +137,3 @@ export async function GET() {
136137
const allRegs = await db.select().from(registrations);
137138
return NextResponse.json({ success: true, data: allRegs });
138139
}
139-

src/app/api/upload/route.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
import { writeFile } from "fs/promises";
1+
import { mkdir, writeFile } from "fs/promises";
22
import { NextRequest, NextResponse } from "next/server";
33
import path from "path";
44
import { auth } from "@/auth";
5+
import { getUploadDir, getUploadPublicBasePath } from "@/lib/upload-path";
6+
7+
const UPLOAD_DIR = getUploadDir();
8+
const UPLOAD_PUBLIC_BASE = getUploadPublicBasePath();
59

610
export async function POST(request: NextRequest) {
711
try {
@@ -45,15 +49,13 @@ export async function POST(request: NextRequest) {
4549

4650
const buffer = Buffer.from(await file.arrayBuffer());
4751
const filename = `${Date.now()}-${file.name.replace(/\s+/g, "-")}`;
48-
const filepath = path.join(
49-
process.cwd(),
50-
"public/uploads/archive",
51-
filename
52-
);
52+
const uploadDir = path.join(process.cwd(), UPLOAD_DIR, "archive");
53+
const filepath = path.join(uploadDir, filename);
5354

55+
await mkdir(uploadDir, { recursive: true });
5456
await writeFile(filepath, buffer);
5557

56-
return NextResponse.json({ url: `/uploads/archive/${filename}` });
58+
return NextResponse.json({ url: `${UPLOAD_PUBLIC_BASE}/archive/${filename}` });
5759
} catch (error) {
5860
console.error("Upload error:", error);
5961
return NextResponse.json(
Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,45 @@
11
import Link from "next/link";
22
import Image from "next/image";
3-
import { db, archiveYears, archiveCategories, archiveContent, archivePapers } from "@/db/schema";
3+
import {
4+
db,
5+
archiveYears,
6+
archiveCategories,
7+
archiveContent,
8+
archivePapers,
9+
} from "@/db/schema";
410
import { eq, and } from "drizzle-orm";
511
import { notFound } from "next/navigation";
612

7-
export const dynamic = 'force-dynamic';
13+
export const dynamic = "force-dynamic";
14+
15+
export default async function ArchiveYearPage({
16+
params,
17+
}: {
18+
params: Promise<{ year: string }>;
19+
}) {
20+
const { year: yearStr } = await params;
21+
const yearNumber = Number.parseInt(yearStr, 10);
22+
23+
if (Number.isNaN(yearNumber)) {
24+
notFound();
25+
}
26+
27+
const yearData = await db
28+
.select()
29+
.from(archiveYears)
30+
.where(eq(archiveYears.year, yearNumber))
31+
.limit(1);
832

9-
export default async function Archive2025Page() {
10-
const yearData = await db.select().from(archiveYears).where(eq(archiveYears.year, 2025)).limit(1);
11-
1233
if (yearData.length === 0) {
1334
notFound();
1435
}
1536

1637
const year = yearData[0];
17-
const categories = await db.select().from(archiveCategories).orderBy(archiveCategories.displayOrder);
18-
38+
const categories = await db
39+
.select()
40+
.from(archiveCategories)
41+
.orderBy(archiveCategories.displayOrder);
42+
1943
const contentByCategory = new Map<string, typeof archiveContent.$inferSelect[]>();
2044
for (const category of categories) {
2145
const content = await db
@@ -35,17 +59,17 @@ export default async function Archive2025Page() {
3559
.select()
3660
.from(archivePapers)
3761
.where(
38-
and(
39-
eq(archivePapers.yearId, year.id),
40-
eq(archivePapers.isAccepted, true)
41-
)
62+
and(eq(archivePapers.yearId, year.id), eq(archivePapers.isAccepted, true))
4263
);
4364

4465
return (
4566
<div className="container mx-auto px-4 py-16">
4667
<div className="max-w-6xl mx-auto">
4768
<div className="mb-8">
48-
<Link href="/archive" className="text-sm text-muted-foreground hover:text-foreground">
69+
<Link
70+
href="/archive"
71+
className="text-sm text-muted-foreground hover:text-foreground"
72+
>
4973
← Back to Archives
5074
</Link>
5175
</div>
@@ -69,9 +93,7 @@ export default async function Archive2025Page() {
6993
{year.eventDate && <span>{year.eventDate}</span>}
7094
{year.location && <span>{year.location}</span>}
7195
</div>
72-
{year.description && (
73-
<p className="text-lg">{year.description}</p>
74-
)}
96+
{year.description && <p className="text-lg">{year.description}</p>}
7597
</div>
7698

7799
<div className="space-y-12">
@@ -85,7 +107,9 @@ export default async function Archive2025Page() {
85107
{papers.map((paper) => (
86108
<div key={paper.id} className="border rounded-lg p-6">
87109
<h3 className="text-xl font-semibold mb-2">{paper.title}</h3>
88-
<p className="text-sm text-muted-foreground mb-2">by {paper.authors}</p>
110+
<p className="text-sm text-muted-foreground mb-2">
111+
by {paper.authors}
112+
</p>
89113
{paper.trackType && (
90114
<span className="inline-block text-xs px-2 py-1 rounded bg-muted mb-3">
91115
{paper.trackType}
@@ -110,8 +134,8 @@ export default async function Archive2025Page() {
110134

111135
{categories.map((category) => {
112136
const items = contentByCategory.get(category.id) || [];
113-
if (items.length === 0 && category.slug !== 'abstract-book') return null;
114-
if (category.slug === 'papers') return null;
137+
if (items.length === 0 && category.slug !== "abstract-book") return null;
138+
if (category.slug === "papers") return null;
115139

116140
return (
117141
<section key={category.id} id={category.slug}>

src/lib/upload-path.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const DEFAULT_UPLOAD_DIR = "public/uploads";
2+
3+
export function getUploadDir() {
4+
return process.env.UPLOAD_DIR?.trim() || DEFAULT_UPLOAD_DIR;
5+
}
6+
7+
export function getUploadPublicBasePath() {
8+
const normalized = getUploadDir()
9+
.replace(/\\/g, "/")
10+
.replace(/^\.?\//, "")
11+
.replace(/\/+$/, "");
12+
13+
if (!normalized.startsWith("public/")) {
14+
return "/uploads";
15+
}
16+
17+
return `/${normalized.slice("public/".length)}`;
18+
}

0 commit comments

Comments
 (0)