- 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
90 lines
3.3 KiB
TypeScript
90 lines
3.3 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { postgresClient } from '@/lib/services/postgres-client';
|
|
|
|
async function getMobileCompanyFilter(): Promise<{ join: string; condition: string }> {
|
|
try {
|
|
const result = await postgresClient.query(
|
|
`SELECT setting_key, setting_value FROM kiosk_settings WHERE setting_key IN ('mobile_company_category_ids', 'mobile_excluded_company_ids')`
|
|
);
|
|
const map: Record<string, string> = {};
|
|
result.rows.forEach((r: any) => { map[r.setting_key] = r.setting_value || ''; });
|
|
|
|
const catIds = (map['mobile_company_category_ids'] || '1')
|
|
.split(',').map((s: string) => parseInt(s.trim(), 10)).filter((n: number) => !isNaN(n));
|
|
const exclIds = (map['mobile_excluded_company_ids'] || '')
|
|
.split(',').map((s: string) => parseInt(s.trim(), 10)).filter((n: number) => !isNaN(n));
|
|
|
|
const catCond = catIds.length > 0 ? `c.company_category_id IN (${catIds.join(',')})` : 'true';
|
|
const exclCond = exclIds.length > 0 ? `c.id NOT IN (${exclIds.join(',')})` : '';
|
|
const condition = [catCond, exclCond].filter(Boolean).join(' AND ');
|
|
|
|
return { join: 'INNER JOIN companies c ON c.id = t.company_id', condition };
|
|
} catch (error) {
|
|
console.error('Error fetching mobile company filter:', error);
|
|
return { join: 'INNER JOIN companies c ON c.id = t.company_id', condition: 'c.company_category_id = 1' };
|
|
}
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const { searchParams } = request.nextUrl;
|
|
const search = searchParams.get('q') ?? '';
|
|
const queue = searchParams.get('queue') ?? '';
|
|
const priority = searchParams.get('priority') ?? '';
|
|
const page = Math.max(1, parseInt(searchParams.get('page') ?? '1'));
|
|
const limit = 30;
|
|
const offset = (page - 1) * limit;
|
|
|
|
const { condition: companyCondition } = await getMobileCompanyFilter();
|
|
|
|
const conditions: string[] = [
|
|
't.status != 5',
|
|
't.is_deleted = false',
|
|
companyCondition,
|
|
];
|
|
const params: unknown[] = [];
|
|
|
|
if (search) {
|
|
params.push(`%${search}%`);
|
|
conditions.push(`(t.title ILIKE $${params.length} OR t.ticket_number ILIKE $${params.length} OR c.company_name ILIKE $${params.length})`);
|
|
}
|
|
if (queue) {
|
|
params.push(parseInt(queue));
|
|
conditions.push(`t.queue_id = $${params.length}`);
|
|
}
|
|
if (priority) {
|
|
params.push(parseInt(priority));
|
|
conditions.push(`t.priority = $${params.length}`);
|
|
}
|
|
|
|
const where = conditions.join(' AND ');
|
|
|
|
const [rows, countRow] = await Promise.all([
|
|
postgresClient.query(`
|
|
SELECT t.id, t.ticket_number, t.title, t.status, t.priority,
|
|
t.create_date, t.last_activity_date, t.due_date_time,
|
|
t.queue_id, q.label as queue_label,
|
|
c.company_name,
|
|
r.first_name || ' ' || r.last_name as assigned_to
|
|
FROM tickets t
|
|
INNER JOIN companies c ON c.id = t.company_id
|
|
LEFT JOIN queues q ON q.value = t.queue_id
|
|
LEFT JOIN resources r ON r.id = t.assigned_resource_id
|
|
WHERE ${where}
|
|
ORDER BY t.last_activity_date DESC NULLS LAST
|
|
LIMIT ${limit} OFFSET ${offset}
|
|
`, params),
|
|
postgresClient.query(`
|
|
SELECT COUNT(*) as total
|
|
FROM tickets t
|
|
INNER JOIN companies c ON c.id = t.company_id
|
|
WHERE ${where}
|
|
`, params),
|
|
]);
|
|
|
|
return NextResponse.json({
|
|
tickets: rows.rows,
|
|
total: parseInt(countRow.rows[0]?.total ?? '0'),
|
|
page,
|
|
limit,
|
|
});
|
|
}
|