This commit is contained in:
Dennis Konkol
2025-09-02 23:46:36 +00:00
parent ded873e6b4
commit 203a332306
22 changed files with 3886 additions and 194 deletions

View File

@@ -0,0 +1,74 @@
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
export async function GET(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const id = parseInt(params.id);
const project = await prisma.project.findUnique({
where: { id }
});
if (!project) {
return NextResponse.json(
{ error: 'Project not found' },
{ status: 404 }
);
}
return NextResponse.json(project);
} catch (error) {
console.error('Error fetching project:', error);
return NextResponse.json(
{ error: 'Failed to fetch project' },
{ status: 500 }
);
}
}
export async function PUT(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const id = parseInt(params.id);
const data = await request.json();
const project = await prisma.project.update({
where: { id },
data: { ...data, updatedAt: new Date() }
});
return NextResponse.json(project);
} catch (error) {
console.error('Error updating project:', error);
return NextResponse.json(
{ error: 'Failed to update project' },
{ status: 500 }
);
}
}
export async function DELETE(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const id = parseInt(params.id);
await prisma.project.delete({
where: { id }
});
return NextResponse.json({ success: true });
} catch (error) {
console.error('Error deleting project:', error);
return NextResponse.json(
{ error: 'Failed to delete project' },
{ status: 500 }
);
}
}

78
app/api/projects/route.ts Normal file
View File

@@ -0,0 +1,78 @@
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const page = parseInt(searchParams.get('page') || '1');
const limit = parseInt(searchParams.get('limit') || '50');
const category = searchParams.get('category');
const featured = searchParams.get('featured');
const published = searchParams.get('published');
const difficulty = searchParams.get('difficulty');
const search = searchParams.get('search');
const skip = (page - 1) * limit;
const where: any = {};
if (category) where.category = category;
if (featured !== null) where.featured = featured === 'true';
if (published !== null) where.published = published === 'true';
if (difficulty) where.difficulty = difficulty;
if (search) {
where.OR = [
{ title: { contains: search, mode: 'insensitive' } },
{ description: { contains: search, mode: 'insensitive' } },
{ tags: { hasSome: [search] } },
{ content: { contains: search, mode: 'insensitive' } }
];
}
const [projects, total] = await Promise.all([
prisma.project.findMany({
where,
orderBy: { createdAt: 'desc' },
skip,
take: limit
}),
prisma.project.count({ where })
]);
return NextResponse.json({
projects,
total,
pages: Math.ceil(total / limit),
currentPage: page
});
} catch (error) {
console.error('Error fetching projects:', error);
return NextResponse.json(
{ error: 'Failed to fetch projects' },
{ status: 500 }
);
}
}
export async function POST(request: NextRequest) {
try {
const data = await request.json();
const project = await prisma.project.create({
data: {
...data,
performance: data.performance || { lighthouse: 90, bundleSize: '50KB', loadTime: '1.5s' },
analytics: data.analytics || { views: 0, likes: 0, shares: 0 }
}
});
return NextResponse.json(project);
} catch (error) {
console.error('Error creating project:', error);
return NextResponse.json(
{ error: 'Failed to create project' },
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,81 @@
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const slug = searchParams.get('slug');
const search = searchParams.get('search');
const category = searchParams.get('category');
if (slug) {
// Search by slug (convert title to slug format)
const projects = await prisma.project.findMany({
where: {
published: true
},
orderBy: { createdAt: 'desc' }
});
// Find exact match by converting titles to slugs
const foundProject = projects.find(project => {
const projectSlug = project.title.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '');
return projectSlug === slug;
});
if (foundProject) {
return NextResponse.json({ projects: [foundProject] });
}
// If no exact match, return empty array
return NextResponse.json({ projects: [] });
}
if (search) {
// General search
const projects = await prisma.project.findMany({
where: {
published: true,
OR: [
{ title: { contains: search, mode: 'insensitive' } },
{ description: { contains: search, mode: 'insensitive' } },
{ tags: { hasSome: [search] } },
{ content: { contains: search, mode: 'insensitive' } }
]
},
orderBy: { createdAt: 'desc' }
});
return NextResponse.json({ projects });
}
if (category && category !== 'All') {
// Filter by category
const projects = await prisma.project.findMany({
where: {
published: true,
category: category
},
orderBy: { createdAt: 'desc' }
});
return NextResponse.json({ projects });
}
// Return all published projects if no specific search
const projects = await prisma.project.findMany({
where: { published: true },
orderBy: { createdAt: 'desc' }
});
return NextResponse.json({ projects });
} catch (error) {
console.error('Error searching projects:', error);
return NextResponse.json(
{ error: 'Failed to search projects' },
{ status: 500 }
);
}
}