wulf-pulse/app/api/admin/display-settings/route.ts
lorentz 07067bef19 feat: Display Settings UI + Company Category/Type sync
- Add /admin/display-settings page with Kiosk and Mobile sections
- Company category checkbox filter + excluded companies searchable multi-select
- New DB tables: company_categories, company_types (migration 064)
- Sync COMPANY_CATEGORIES via CompanyCategories entity (id/name/isActive)
- Sync COMPANY_TYPES via Companies.companyType picklist
- Add to EntityType, ENTITY_DEPENDENCIES, sync-helpers, entity-mapper, entity-sync
- New API routes: /api/admin/display-settings (GET/POST), /api/data/company-categories, /api/data/companies-list
- Update all 4 routes (kiosk/stats, kiosk/activity, mobile/tickets, mobile/dashboard)
  to filter by kiosk_settings company_category_ids + excluded_company_ids
- Add Display Settings nav link (SlidersHorizontal icon) to Admin menu
- Seed kiosk_settings: kiosk_company_category_ids=1, mobile_company_category_ids=1
2026-04-06 09:03:19 -04:00

65 lines
2.4 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { postgresClient } from '@/lib/services/postgres-client';
const KIOSK_KEYS = ['kiosk_company_category_ids', 'kiosk_excluded_company_ids'];
const MOBILE_KEYS = ['mobile_company_category_ids', 'mobile_excluded_company_ids'];
const ALL_KEYS = [...KIOSK_KEYS, ...MOBILE_KEYS];
function parseIds(value: string | null): number[] {
if (!value) return [];
return value.split(',').map((s: string) => parseInt(s.trim(), 10)).filter((n: number) => !isNaN(n));
}
export async function GET() {
try {
const result = await postgresClient.query(
`SELECT setting_key, setting_value FROM kiosk_settings WHERE setting_key = ANY($1)`,
[ALL_KEYS]
);
const map: Record<string, string> = {};
result.rows.forEach((r: any) => { map[r.setting_key] = r.setting_value || ''; });
return NextResponse.json({
kiosk: {
company_category_ids: parseIds(map['kiosk_company_category_ids'] ?? '1'),
excluded_company_ids: parseIds(map['kiosk_excluded_company_ids'] ?? ''),
},
mobile: {
company_category_ids: parseIds(map['mobile_company_category_ids'] ?? '1'),
excluded_company_ids: parseIds(map['mobile_excluded_company_ids'] ?? ''),
},
});
} catch (error) {
console.error('Error fetching display settings:', error);
return NextResponse.json({ error: 'Failed to fetch display settings' }, { status: 500 });
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { setting_key, setting_value } = body;
if (!setting_key || !ALL_KEYS.includes(setting_key)) {
return NextResponse.json({ error: 'Invalid setting_key' }, { status: 400 });
}
const valueToStore = Array.isArray(setting_value)
? setting_value.join(',')
: String(setting_value ?? '');
await postgresClient.query(
`INSERT INTO kiosk_settings (setting_key, setting_value, updated_at)
VALUES ($1, $2, CURRENT_TIMESTAMP)
ON CONFLICT (setting_key)
DO UPDATE SET setting_value = EXCLUDED.setting_value, updated_at = CURRENT_TIMESTAMP`,
[setting_key, valueToStore]
);
return NextResponse.json({ success: true });
} catch (error) {
console.error('Error updating display settings:', error);
return NextResponse.json({ error: 'Failed to update display settings' }, { status: 500 });
}
}