feat: add classification-based filtering and fix company name display
- Added classification column to companies table - Created excluded_classifications setting (default: Tools Only) - Updated kiosk stats and activity APIs to filter by classification - Added comprehensive classification filtering UI with checkboxes - Support for common classifications (Tools Only, Wulff Consulting Client, Customer) - Allow custom classification entry - Fixed company name display in settings (convert string IDs properly) - Classification filtering works alongside company ID exclusions
This commit is contained in:
parent
62ec703f81
commit
1d99a8f659
4 changed files with 176 additions and 10 deletions
|
|
@ -12,6 +12,7 @@ interface Company {
|
|||
|
||||
interface KioskSettings {
|
||||
excluded_company_ids: number[];
|
||||
excluded_classifications: string[];
|
||||
cycle_interval: number;
|
||||
refresh_interval: number;
|
||||
show_rmm_alerts: boolean;
|
||||
|
|
@ -21,6 +22,7 @@ export default function KioskSettingsPage() {
|
|||
const router = useRouter();
|
||||
const [settings, setSettings] = useState<KioskSettings>({
|
||||
excluded_company_ids: [],
|
||||
excluded_classifications: [],
|
||||
cycle_interval: 7,
|
||||
refresh_interval: 60,
|
||||
show_rmm_alerts: false,
|
||||
|
|
@ -99,6 +101,14 @@ export default function KioskSettingsPage() {
|
|||
setting_value: settings.excluded_company_ids,
|
||||
}),
|
||||
}),
|
||||
fetch('/api/kiosk/settings', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
setting_key: 'excluded_classifications',
|
||||
setting_value: settings.excluded_classifications,
|
||||
}),
|
||||
}),
|
||||
fetch('/api/kiosk/settings', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
|
|
@ -135,7 +145,9 @@ export default function KioskSettingsPage() {
|
|||
};
|
||||
|
||||
const getCompanyName = (companyId: number) => {
|
||||
return companies.find(c => c.id === companyId)?.companyName || `Company ${companyId}`;
|
||||
// API returns id as string, settings stores as number - convert for comparison
|
||||
const idStr = companyId.toString();
|
||||
return companies.find(c => c.id.toString() === idStr)?.companyName || `Company ${companyId}`;
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
|
|
@ -232,6 +244,96 @@ export default function KioskSettingsPage() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* Excluded Classifications Section */}
|
||||
<div className="bg-gray-900 rounded-lg p-6 border border-gray-800">
|
||||
<h2 className="text-xl font-semibold mb-4">Excluded Company Classifications</h2>
|
||||
<p className="text-gray-400 mb-4">
|
||||
Tickets from companies with these classifications will not appear in the kiosk display.
|
||||
</p>
|
||||
|
||||
{/* Common Classifications */}
|
||||
<div className="space-y-2 mb-4">
|
||||
{['Tools Only', 'Wulff Consulting Client', 'Customer'].map(classification => (
|
||||
<label key={classification} className="flex items-center gap-3 bg-gray-800 rounded px-4 py-3 border border-gray-700 cursor-pointer hover:bg-gray-750">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.excluded_classifications.includes(classification)}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
setSettings({
|
||||
...settings,
|
||||
excluded_classifications: [...settings.excluded_classifications, classification],
|
||||
});
|
||||
} else {
|
||||
setSettings({
|
||||
...settings,
|
||||
excluded_classifications: settings.excluded_classifications.filter(c => c !== classification),
|
||||
});
|
||||
}
|
||||
}}
|
||||
className="w-5 h-5 rounded border-gray-600 text-blue-600 focus:ring-blue-500"
|
||||
/>
|
||||
<span className="flex-1">{classification}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Custom Classification Input */}
|
||||
<div className="mt-4">
|
||||
<label className="block text-sm font-medium mb-2 text-gray-400">
|
||||
Add custom classification:
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Enter classification name..."
|
||||
className="flex-1 bg-gray-800 border border-gray-700 rounded px-3 py-2 text-white"
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
const value = (e.target as HTMLInputElement).value.trim();
|
||||
if (value && !settings.excluded_classifications.includes(value)) {
|
||||
setSettings({
|
||||
...settings,
|
||||
excluded_classifications: [...settings.excluded_classifications, value],
|
||||
});
|
||||
(e.target as HTMLInputElement).value = '';
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 mt-1">Press Enter to add</p>
|
||||
</div>
|
||||
|
||||
{/* Custom Classifications List */}
|
||||
{settings.excluded_classifications.filter(c => !['Tools Only', 'Wulff Consulting Client', 'Customer'].includes(c)).length > 0 && (
|
||||
<div className="mt-4 space-y-2">
|
||||
<div className="text-sm font-medium text-gray-400">Custom classifications:</div>
|
||||
{settings.excluded_classifications
|
||||
.filter(c => !['Tools Only', 'Wulff Consulting Client', 'Customer'].includes(c))
|
||||
.map(classification => (
|
||||
<div
|
||||
key={classification}
|
||||
className="flex items-center justify-between bg-gray-800 rounded px-4 py-3 border border-gray-700"
|
||||
>
|
||||
<span>{classification}</span>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setSettings({
|
||||
...settings,
|
||||
excluded_classifications: settings.excluded_classifications.filter(c => c !== classification),
|
||||
})}
|
||||
className="text-red-400 hover:text-red-300 hover:bg-red-900/20"
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Display Settings */}
|
||||
<div className="bg-gray-900 rounded-lg p-6 border border-gray-800">
|
||||
<h2 className="text-xl font-semibold mb-4">Display Settings</h2>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue