feat: major UI/UX overhaul, snippets system, and performance fixes
Some checks failed
Dev Deployment (Zero Downtime) / deploy-dev (push) Failing after 9m26s

This commit is contained in:
2026-02-16 12:31:40 +01:00
parent 6f62b37c3a
commit a5dba298f3
41 changed files with 1610 additions and 499 deletions

View File

@@ -5,6 +5,7 @@ import { requireSessionAuth, checkRateLimit, getRateLimitHeaders, getClientIp }
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library';
import { generateUniqueSlug } from '@/lib/slug';
import { getProjects as getDirectusProjects } from '@/lib/directus';
import { ProjectListItem } from '@/app/_ui/ProjectsPageClient';
export async function GET(request: NextRequest) {
try {
@@ -41,17 +42,18 @@ export async function GET(request: NextRequest) {
const limit = Number.isFinite(limitRaw) && limitRaw > 0 && limitRaw <= 200 ? limitRaw : 50;
const category = searchParams.get('category');
const featured = searchParams.get('featured');
const published = searchParams.get('published');
const published = searchParams.get('published') === 'false' ? false : true; // Default to true if not specified
const difficulty = searchParams.get('difficulty');
const search = searchParams.get('search');
const locale = searchParams.get('locale') || 'en';
// Try Directus FIRST (Primary Source)
let directusProjects: any[] = [];
let directusProjects: ProjectListItem[] = [];
let directusSuccess = false;
try {
const fetched = await getDirectusProjects(locale, {
featured: featured === 'true' ? true : featured === 'false' ? false : undefined,
published: published === 'true' ? true : published === 'false' ? false : undefined,
published: published,
category: category || undefined,
difficulty: difficulty || undefined,
search: search || undefined,
@@ -59,29 +61,41 @@ export async function GET(request: NextRequest) {
});
if (fetched) {
directusProjects = fetched;
directusProjects = fetched.map(p => ({
id: typeof p.id === 'string' ? (parseInt(p.id) || 0) : p.id,
slug: p.slug,
title: p.title,
description: p.description,
tags: p.tags || [],
category: p.category || '',
date: p.created_at,
createdAt: p.created_at,
imageUrl: p.image_url,
}));
directusSuccess = true;
}
} catch (directusError) {
console.log('Directus error, continuing with PostgreSQL');
} catch {
console.log('Directus error, continuing with PostgreSQL fallback');
}
// Fallback 1: Try PostgreSQL
// If Directus returned projects, use them EXCLUSIVELY to avoid showing un-synced local data
if (directusSuccess && directusProjects.length > 0) {
return NextResponse.json({
projects: directusProjects,
total: directusProjects.length,
source: 'directus'
});
}
// Fallback 1: Try PostgreSQL only if Directus failed or is empty
try {
await prisma.$queryRaw`SELECT 1`;
} catch (dbError) {
} catch {
console.log('PostgreSQL not available');
if (directusProjects.length > 0) {
return NextResponse.json({
projects: directusProjects,
total: directusProjects.length,
source: 'directus'
});
}
return NextResponse.json({
projects: [],
total: 0,
source: 'fallback'
projects: directusProjects, // Might be empty
total: directusProjects.length,
source: 'directus-empty'
});
}
@@ -90,7 +104,7 @@ export async function GET(request: NextRequest) {
if (category) where.category = category;
if (featured !== null) where.featured = featured === 'true';
if (published !== null) where.published = published === 'true';
where.published = published;
if (difficulty) where.difficulty = difficulty;
if (search) {
@@ -113,7 +127,17 @@ export async function GET(request: NextRequest) {
// Merge logic
const dbSlugs = new Set(dbProjects.map(p => p.slug));
const mergedProjects = [...dbProjects];
const mergedProjects: ProjectListItem[] = dbProjects.map(p => ({
id: p.id,
slug: p.slug,
title: p.title,
description: p.description,
tags: p.tags,
category: p.category,
date: p.date,
createdAt: p.createdAt.toISOString(),
imageUrl: p.imageUrl,
}));
for (const dp of directusProjects) {
if (!dbSlugs.has(dp.slug)) {