wulf-pulse/app/api/kiosk/activity/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

77 lines
2.8 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { postgresClient } from '@/lib/services/postgres-client';
async function getKioskCompanyFilter(): Promise<string> {
try {
const result = await postgresClient.query(
`SELECT setting_key, setting_value FROM kiosk_settings WHERE setting_key IN ('kiosk_company_category_ids', 'kiosk_excluded_company_ids')`
);
const map: Record<string, string> = {};
result.rows.forEach((r: any) => { map[r.setting_key] = r.setting_value || ''; });
const catIds = (map['kiosk_company_category_ids'] || '1')
.split(',').map((s: string) => parseInt(s.trim(), 10)).filter((n: number) => !isNaN(n));
const exclIds = (map['kiosk_excluded_company_ids'] || '')
.split(',').map((s: string) => parseInt(s.trim(), 10)).filter((n: number) => !isNaN(n));
const catFilter = catIds.length > 0
? `t.company_id IN (SELECT id FROM companies WHERE company_category_id IN (${catIds.join(',')}))`
: 'true';
const exclFilter = exclIds.length > 0
? `t.company_id NOT IN (${exclIds.join(',')})`
: '';
return [catFilter, exclFilter].filter(Boolean).join(' AND ');
} catch (error) {
console.error('Error fetching kiosk company filter:', error);
return 't.company_id IN (SELECT id FROM companies WHERE company_category_id = 1)';
}
}
export async function GET(request: NextRequest) {
try {
const companyFilter = await getKioskCompanyFilter();
const excludeCompanyFilter = `AND (${companyFilter})`;
// Get recent ticket activity for ticker feed - exclude RMM alerts (source = 8), co-managed clients, and excluded classifications
const activityResult = await postgresClient.query(
`SELECT
t.ticket_number,
t.title,
t.priority,
t.status,
t.create_date,
t.last_activity_date,
c.company_name,
s.label as status_label
FROM tickets t
LEFT JOIN companies c ON t.company_id = c.id
LEFT JOIN statuses s ON t.status = s.value
WHERE t.completed_date IS NULL
AND t.is_deleted = false
AND (t.source IS NULL OR t.source != 8)
${excludeCompanyFilter}
ORDER BY t.last_activity_date DESC NULLS LAST
LIMIT 50`
);
const activities = activityResult.rows.map((row: any) => ({
ticketNumber: row.ticket_number,
title: row.title,
priority: row.priority,
status: row.status,
statusLabel: row.status_label,
companyName: row.company_name,
createDate: row.create_date,
lastActivityDate: row.last_activity_date,
}));
return NextResponse.json({ activities });
} catch (error) {
console.error('Error fetching kiosk activity:', error);
return NextResponse.json(
{ error: 'Failed to fetch kiosk activity' },
{ status: 500 }
);
}
}