Initial Commit

Commit pertama, memindahkan repository dari github ke gitea.
This commit is contained in:
dicky arya pratama committed 2026-11-04 17:18:53 +07:00
commit 13a47fbebf
41 files changed
+12327

No files matched your search

+121
View File
@@ -0,0 +1,121 @@
import { NextResponse } from "next/server";
import { query } from "@/lib/db";
import { isAuthenticated } from "@/lib/auth";
export interface DBProject {
id: string;
title: string;
category: "software" | "games" | "lab";
category_label: string;
tagline: string;
status: string;
status_type: "active" | "alpha" | "prototype" | "upcoming";
release_target: string;
description: string;
long_description: string;
features: string[] | string;
stack: string[] | string;
accent_gradient: string;
border_glow: string;
icon_name: string;
order_index?: number;
created_at?: string;
updated_at?: string;
}
export async function GET() {
try {
const rows = await query<DBProject[]>(
"SELECT * FROM projects ORDER BY order_index ASC, created_at DESC"
);
const formatted = rows.map((p) => ({
id: p.id,
title: p.title,
category: p.category,
categoryLabel: p.category_label,
tagline: p.tagline,
status: p.status,
statusType: p.status_type,
releaseTarget: p.release_target,
description: p.description,
longDescription: p.long_description,
features: typeof p.features === "string" ? JSON.parse(p.features) : p.features || [],
stack: typeof p.stack === "string" ? JSON.parse(p.stack) : p.stack || [],
accentGradient: p.accent_gradient,
borderGlow: p.border_glow,
iconName: p.icon_name,
orderIndex: p.order_index,
}));
return NextResponse.json({ success: true, data: formatted });
} catch (err: unknown) {
const message = err instanceof Error ? err.message : "Database query error";
return NextResponse.json({ error: message }, { status: 500 });
}
}
export async function POST(req: Request) {
try {
const authed = await isAuthenticated();
if (!authed) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const body = await req.json();
const id = (body.id || body.title.toLowerCase().replace(/[^a-z0-9]+/g, "-")).trim();
const title = body.title?.trim();
const category = body.category || "software";
const category_label = body.categoryLabel || body.category_label || "Original Software";
const tagline = body.tagline?.trim() || "";
const status = body.status?.trim() || "In Active Dev";
const status_type = body.statusType || body.status_type || "active";
const release_target = body.releaseTarget || body.release_target || "2027";
const description = body.description?.trim() || "";
const long_description = body.longDescription || body.long_description || "";
const features = JSON.stringify(Array.isArray(body.features) ? body.features : []);
const stack = JSON.stringify(Array.isArray(body.stack) ? body.stack : []);
const accent_gradient =
body.accentGradient ||
body.accent_gradient ||
"from-cyan-500/20 via-blue-600/10 to-transparent";
const border_glow =
body.borderGlow ||
body.border_glow ||
"hover:border-cyan-400/50 hover:shadow-[0_0_30px_rgba(56,189,248,0.25)]";
const icon_name = body.iconName || body.icon_name || "Terminal";
const order_index = Number(body.orderIndex ?? body.order_index ?? 0);
await query(
`INSERT INTO projects (
id, title, category, category_label, tagline, status, status_type,
release_target, description, long_description, features, stack,
accent_gradient, border_glow, icon_name, order_index
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
id,
title,
category,
category_label,
tagline,
status,
status_type,
release_target,
description,
long_description,
features,
stack,
accent_gradient,
border_glow,
icon_name,
order_index,
]
);
return NextResponse.json({ success: true, id });
} catch (err: unknown) {
const message = err instanceof Error ? err.message : "Database error";
return NextResponse.json({ error: message }, { status: 500 });
}
}