|
1 | 1 | import { type Filter } from "../filter"; |
2 | 2 | import { type Settings } from "../settings"; |
3 | 3 |
|
| 4 | +const DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; |
| 5 | + |
| 6 | +function formatStatus(status: Filter['status']): string { |
| 7 | + if (status === null) return 'None'; |
| 8 | + if (typeof status === 'number') return String(status); |
| 9 | + return status.map(([lo, hi]) => { |
| 10 | + if (lo === 200 && hi === 299) return '2xx'; |
| 11 | + if (lo === 300 && hi === 399) return '3xx'; |
| 12 | + if (lo === 400 && hi === 499) return '4xx'; |
| 13 | + if (lo === 500 && hi === 599) return '5xx'; |
| 14 | + return `${lo}–${hi}`; |
| 15 | + }).join(', '); |
| 16 | +} |
| 17 | + |
| 18 | +function filterPills(filter: Filter): { label: string; value: string; active: boolean }[] { |
| 19 | + return [ |
| 20 | + { label: 'Period', value: filter.period, active: true }, |
| 21 | + { label: 'Location', value: filter.location ?? 'None', active: filter.location !== null }, |
| 22 | + { label: 'Path', value: filter.path ?? 'None', active: filter.path !== null }, |
| 23 | + { label: 'Method', value: filter.method ?? 'None', active: filter.method !== null }, |
| 24 | + { label: 'Status', value: formatStatus(filter.status), active: filter.status !== null }, |
| 25 | + { label: 'Referrer', value: filter.referrer ?? 'None', active: filter.referrer !== null }, |
| 26 | + { label: 'Version', value: filter.version ?? 'None', active: filter.version !== null }, |
| 27 | + { label: 'Client', value: filter.client ?? 'None', active: filter.client !== null }, |
| 28 | + { label: 'OS', value: filter.os ?? 'None', active: filter.os !== null }, |
| 29 | + { label: 'Device', value: filter.deviceType ?? 'None', active: filter.deviceType !== null }, |
| 30 | + { label: 'Hour', value: filter.hour !== null ? `${String(filter.hour).padStart(2, '0')}:00` : 'None', active: filter.hour !== null }, |
| 31 | + { label: 'Day', value: filter.dayOfWeek !== null ? DAYS[filter.dayOfWeek] : 'None', active: filter.dayOfWeek !== null }, |
| 32 | + ]; |
| 33 | +} |
| 34 | + |
4 | 35 | export function Settings({ |
5 | 36 | settings, |
6 | 37 | setSettings, |
@@ -129,19 +160,20 @@ export function Settings({ |
129 | 160 |
|
130 | 161 | {/* Filters */} |
131 | 162 | <div className="space-y-3 mb-4"> |
132 | | - <h3 className="font-semibold text-md">Active Filters</h3> |
133 | | - <div className="bg-[rgba(26,240,115,0.1)] rounded p-4 space-y-2"> |
134 | | - {Object.entries(filter).map(([key, value]) => ( |
135 | | - value ? ( |
136 | | - <div key={key} className="flex items-center justify-between"> |
137 | | - <span className="capitalize font-medium mr-2">{key}:</span> |
138 | | - <span className="bg-[var(--highlight)] break-all text-[var(--background)] px-2 py-1 rounded text-sm">{value}</span> |
139 | | - </div> |
140 | | - ) : null |
| 163 | + <h3 className="font-semibold text-md">Filters</h3> |
| 164 | + <div className="flex flex-wrap gap-2"> |
| 165 | + {filterPills(filter).map(({ label, value, active }) => ( |
| 166 | + <div |
| 167 | + key={label} |
| 168 | + className={`border border-[var(--border-color)] rounded-[var(--border-radius)] text-[0.9em] px-3 py-1 transition-colors duration-50 ease-in-out ${ |
| 169 | + active |
| 170 | + ? 'bg-[var(--highlight)] !text-black' |
| 171 | + : 'text-[var(--text-muted3)] opacity-50' |
| 172 | + }`} |
| 173 | + > |
| 174 | + {label}: {value} |
| 175 | + </div> |
141 | 176 | ))} |
142 | | - {!Object.values(filter).some(Boolean) && ( |
143 | | - <p className="text-gray-500 dark:text-gray-400 text-sm italic">No active filters</p> |
144 | | - )} |
145 | 177 | </div> |
146 | 178 | </div> |
147 | 179 | </div> |
|
0 commit comments