134 lines
4.5 KiB
TypeScript
134 lines
4.5 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { prisma } from '@/lib/db'
|
|
import { getSession } from '@/lib/auth'
|
|
|
|
export async function GET() {
|
|
try {
|
|
const user = await getSession()
|
|
const tenantId = user?.tenantId
|
|
|
|
/* ─── 1. Global library (legacy IconAsset) ─── */
|
|
const categoryWhere: any = tenantId
|
|
? { OR: [{ tenantId: null }, { tenantId }] }
|
|
: {}
|
|
|
|
const categories = await (prisma as any).iconCategory.findMany({
|
|
where: categoryWhere,
|
|
orderBy: { sortOrder: 'asc' },
|
|
include: {
|
|
icons: {
|
|
where: tenantId
|
|
? { isActive: true, OR: [{ tenantId: null }, { tenantId }] }
|
|
: { isActive: true, tenantId: null },
|
|
orderBy: { name: 'asc' },
|
|
},
|
|
},
|
|
})
|
|
|
|
let hiddenIconIds: string[] = []
|
|
if (tenantId) {
|
|
const tenant = await (prisma as any).tenant.findUnique({
|
|
where: { id: tenantId },
|
|
select: { hiddenIconIds: true },
|
|
})
|
|
hiddenIconIds = tenant?.hiddenIconIds || []
|
|
}
|
|
|
|
const categoriesWithUrls = categories.map((cat: any) => ({
|
|
...cat,
|
|
icons: cat.icons
|
|
.filter((icon: any) => !hiddenIconIds.includes(icon.id))
|
|
.map((icon: any) => ({
|
|
...icon,
|
|
url: `/api/icons/${icon.id}/image`,
|
|
})),
|
|
}))
|
|
|
|
/* ─── 2. Tenant symbols (Phase 1 architecture) ─── */
|
|
let tenantSymbolGroups: any[] = []
|
|
let flatTenantSymbols: any[] = []
|
|
|
|
if (tenantId) {
|
|
const tenantSymbols = await (prisma as any).tenantSymbol.findMany({
|
|
where: { tenantId },
|
|
include: { category: true },
|
|
orderBy: [{ category: { sortOrder: 'asc' } }, { sortOrder: 'asc' }],
|
|
})
|
|
|
|
flatTenantSymbols = tenantSymbols.map((ts: any) => ({
|
|
id: ts.id,
|
|
name: ts.customName || ts.name,
|
|
customName: ts.customName,
|
|
categoryId: ts.categoryId,
|
|
categoryName: ts.category?.name || null,
|
|
isUploaded: ts.isUploaded,
|
|
migratedFromIconId: ts.migratedFromIconId,
|
|
imageUrl: ts.isUploaded
|
|
? `/api/tenant/symbols/${ts.id}/image`
|
|
: ts.migratedFromIconId
|
|
? `/api/icons/${ts.migratedFromIconId}/image`
|
|
: `/api/icons/${ts.id}/image`,
|
|
}))
|
|
|
|
// Group by category for sidebar display
|
|
const groups = new Map<string | null, any[]>()
|
|
for (const sym of flatTenantSymbols) {
|
|
const key = sym.categoryId || null
|
|
if (!groups.has(key)) groups.set(key, [])
|
|
groups.get(key)!.push(sym)
|
|
}
|
|
|
|
// Fetch categories that have symbols but may not be in the symbol list (empty ones are omitted)
|
|
const catIds = Array.from(groups.keys()).filter(Boolean) as string[]
|
|
const tenantCategories = catIds.length
|
|
? await (prisma as any).tenantCategory.findMany({
|
|
where: { id: { in: catIds }, tenantId },
|
|
orderBy: { sortOrder: 'asc' },
|
|
})
|
|
: []
|
|
|
|
const catMap = new Map(tenantCategories.map((c: any) => [c.id, c]))
|
|
|
|
tenantSymbolGroups = Array.from(groups.entries()).map(([catId, symbols]) => {
|
|
const cat = catId ? catMap.get(catId) : null
|
|
return {
|
|
categoryId: catId,
|
|
categoryName: cat ? (cat as any).name || 'Kategorie' : 'Ohne Kategorie',
|
|
sortOrder: cat ? (cat as any).sortOrder ?? 999 : 999,
|
|
symbols,
|
|
}
|
|
})
|
|
tenantSymbolGroups.sort((a, b) => a.sortOrder - b.sortOrder)
|
|
}
|
|
|
|
/* ─── 3. Legacy mySymbols (keep for old clients during transition) ─── */
|
|
let mySymbolsLegacy: any[] = []
|
|
if (tenantId) {
|
|
const legacy = await (prisma as any).tenantSymbol.findMany({
|
|
where: { tenantId, iconId: { not: null } },
|
|
include: { icon: { select: { id: true, name: true, mimeType: true, iconType: true } } },
|
|
orderBy: { sortOrder: 'asc' },
|
|
})
|
|
mySymbolsLegacy = legacy.map((ts: any) => ({
|
|
id: ts.icon.id,
|
|
tenantSymbolId: ts.id,
|
|
name: ts.customName || ts.icon.name,
|
|
customName: ts.customName,
|
|
mimeType: ts.icon.mimeType,
|
|
iconType: ts.icon.iconType,
|
|
url: `/api/icons/${ts.icon.id}/image`,
|
|
}))
|
|
}
|
|
|
|
return NextResponse.json({
|
|
categories: categoriesWithUrls,
|
|
mySymbols: mySymbolsLegacy, // legacy shape for old clients
|
|
tenantSymbols: flatTenantSymbols, // new flat list
|
|
tenantSymbolGroups, // grouped by TenantCategory
|
|
})
|
|
} catch (error) {
|
|
console.error('Error fetching icons:', error)
|
|
return NextResponse.json({ error: 'Serverfehler' }, { status: 500 })
|
|
}
|
|
}
|