1import { 2 PROBLEM_REPORT_CATEGORIES, 3 PROBLEM_REPORT_STATUSES, 4 PROBLEM_SEVERITIES, 5 ProblemReportStateService 6} from "./chunk-AFCLXHHF.js"; 7import { 8 buildAdminBreadcrumbs 9} from "./chunk-B57R6CYU.js"; 10import { 11 RigaDateTimeService 12} from "./chunk-RAL4KSWL.js"; 13import { 14 BreadcrumbNavigationComponent 15} from "./chunk-C5APCOMN.js"; 16import { 17 accessibilityOutline, 18 addIcons, 19 alertCircleOutline, 20 buildOutline, 21 checkmarkOutline, 22 chevronDownOutline, 23 chevronUpOutline, 24 closeOutline, 25 documentTextOutline, 26 filterOutline, 27 flashOutline, 28 helpCircleOutline, 29 homeOutline, 30 imageOutline, 31 locationOutline, 32 navigateOutline, 33 refreshOutline, 34 sparklesOutline, 35 syncOutline, 36 trashOutline, 37 warningOutline, 38 waterOutline 39} from "./chunk-5VZGNM5O.js"; 40import { 41 ApiService 42} from "./chunk-UN7A4OF7.js"; 43import "./chunk-K52XM66R.js"; 44import "./chunk-PYYASMRY.js"; 45import { 46 UserCampusService 47} from "./chunk-63DLEHZF.js"; 48import "./chunk-PFRFKH6U.js"; 49import "./chunk-UZKEIBGO.js"; 50import "./chunk-2E4THSOE.js"; 51import "./chunk-JISY7VJD.js"; 52import "./chunk-KP4RHBP7.js"; 53import "./chunk-QI7JV4VS.js"; 54import "./chunk-OTQ6GTAJ.js"; 55import "./chunk-RLZ522BW.js"; 56import "./chunk-RLJCY5HS.js"; 57import { 58 TranslateModule, 59 TranslatePipe, 60 TranslateService 61} from "./chunk-O5XYYQCR.js"; 62import "./chunk-QGEJYSW7.js"; 63import { 64 ApiUrlService 65} from "./chunk-MAIAEXGG.js"; 66import "./chunk-L4O6SE3A.js"; 67import { 68 AlertController, 69 IonBadge, 70 IonButton, 71 IonCard, 72 IonCardContent, 73 IonCardHeader, 74 IonContent, 75 IonIcon, 76 IonList, 77 IonRefresher, 78 IonRefresherContent, 79 IonSelect, 80 IonSelectOption, 81 IonSpinner, 82 IonicModule, 83 LoadingController, 84 SelectValueAccessorDirective, 85 ToastController 86} from "./chunk-INK5THDW.js"; 87import "./chunk-GMPIA5L4.js"; 88import { 89 ActivatedRoute, 90 CommonModule, 91 Component, 92 FormsModule, 93 NgControlStatus, 94 NgModel, 95 Subject, 96 finalize, 97 setClassMetadata, 98 takeUntil, 99 ɵsetClassDebugInfo, 100 ɵɵadvance, 101 ɵɵattribute, 102 ɵɵclassMap, 103 ɵɵclassProp, 104 ɵɵconditional, 105 ɵɵdefineComponent, 106 ɵɵdirectiveInject, 107 ɵɵelement, 108 ɵɵelementEnd, 109 ɵɵelementStart, 110 ɵɵgetCurrentView, 111 ɵɵlistener, 112 ɵɵnextContext, 113 ɵɵpipe, 114 ɵɵpipeBind1, 115 ɵɵpipeBind2, 116 ɵɵproperty, 117 ɵɵpureFunction1, 118 ɵɵrepeater, 119 ɵɵrepeaterCreate, 120 ɵɵresetView, 121 ɵɵrestoreView, 122 ɵɵsanitizeUrl, 123 ɵɵtemplate, 124 ɵɵtext, 125 ɵɵtextInterpolate, 126 ɵɵtextInterpolate1, 127 ɵɵtwoWayBindingSet, 128 ɵɵtwoWayListener, 129 ɵɵtwoWayProperty 130} from "./chunk-UQ6LLOJ6.js"; 131import "./chunk-BD3NMR2S.js"; 132import "./chunk-6HPUB4U6.js"; 133import "./chunk-JTG2GCS6.js"; 134import "./chunk-WGFJL45C.js"; 135import "./chunk-7WVISTDL.js"; 136import "./chunk-2S57T3GS.js"; 137import "./chunk-R4QHACMO.js"; 138import "./chunk-4MEJEBWM.js"; 139import "./chunk-RIBVNXHQ.js"; 140import "./chunk-Z42OVMMO.js"; 141import "./chunk-O5S42IXR.js"; 142import "./chunk-QBR2RTFG.js"; 143import "./chunk-MIOLVGSM.js"; 144import "./chunk-V3YFOG6Q.js"; 145import "./chunk-LPMBLWVS.js"; 146import "./chunk-5LKHIIQE.js"; 147import "./chunk-ITE2OHLM.js"; 148import "./chunk-C46CB72A.js"; 149import "./chunk-SRPSML5O.js"; 150import "./chunk-NRSVX4KN.js"; 151import "./chunk-T4GYAOTA.js"; 152import "./chunk-2VHYZHLL.js"; 153import "./chunk-S6LHOZ5A.js"; 154import "./chunk-Y6HZOH3Q.js"; 155import "./chunk-TWQHADEW.js"; 156import "./chunk-3J4L7S6G.js"; 157import "./chunk-IL42VKT6.js"; 158import "./chunk-LONO5O5R.js"; 159import "./chunk-KFBF5L4X.js"; 160import "./chunk-PWC4K6CW.js"; 161import "./chunk-R6JLIESI.js"; 162import "./chunk-UG6K57PI.js"; 163import "./chunk-UR6VIRNL.js"; 164import "./chunk-OJO5RD3M.js"; 165import { 166 __async 167} from "./chunk-CO64IJQE.js"; 168 169// src/app/pages/admin/problem-reports/problem-reports.page.ts 170var _c0 = (a0) => ({ count: a0 }); 171var _forTrack0 = ($index, $item) => $item.value; 172var _forTrack1 = ($index, $item) => $item.id; 173function ProblemReportsPage_Conditional_22_For_11_Template(rf, ctx) { 174 if (rf & 1) { 175 \u0275\u0275elementStart(0, "ion-select-option", 22); 176 \u0275\u0275text(1); 177 \u0275\u0275pipe(2, "translate"); 178 \u0275\u0275elementEnd(); 179 } 180 if (rf & 2) { 181 const status_r3 = ctx.$implicit; 182 \u0275\u0275property("value", status_r3.value); 183 \u0275\u0275advance(); 184 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(2, 2, status_r3.labelKey)); 185 } 186} 187function ProblemReportsPage_Conditional_22_For_21_Template(rf, ctx) { 188 if (rf & 1) { 189 \u0275\u0275elementStart(0, "ion-select-option", 22); 190 \u0275\u0275text(1); 191 \u0275\u0275pipe(2, "translate"); 192 \u0275\u0275elementEnd(); 193 } 194 if (rf & 2) { 195 const cat_r4 = ctx.$implicit; 196 \u0275\u0275property("value", cat_r4.value); 197 \u0275\u0275advance(); 198 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(2, 2, cat_r4.labelKey)); 199 } 200} 201function ProblemReportsPage_Conditional_22_For_31_Template(rf, ctx) { 202 if (rf & 1) { 203 \u0275\u0275elementStart(0, "ion-select-option", 22); 204 \u0275\u0275text(1); 205 \u0275\u0275pipe(2, "translate"); 206 \u0275\u0275elementEnd(); 207 } 208 if (rf & 2) { 209 const sev_r5 = ctx.$implicit; 210 \u0275\u0275property("value", sev_r5.value); 211 \u0275\u0275advance(); 212 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(2, 2, sev_r5.labelKey)); 213 } 214} 215function ProblemReportsPage_Conditional_22_For_41_Template(rf, ctx) { 216 if (rf & 1) { 217 \u0275\u0275elementStart(0, "ion-select-option", 22); 218 \u0275\u0275text(1); 219 \u0275\u0275elementEnd(); 220 } 221 if (rf & 2) { 222 const campus_r6 = ctx.$implicit; 223 \u0275\u0275property("value", campus_r6.id); 224 \u0275\u0275advance(); 225 \u0275\u0275textInterpolate(campus_r6.name); 226 } 227} 228function ProblemReportsPage_Conditional_22_Template(rf, ctx) { 229 if (rf & 1) { 230 const _r1 = \u0275\u0275getCurrentView(); 231 \u0275\u0275elementStart(0, "div", 14)(1, "div", 18)(2, "div", 19)(3, "label"); 232 \u0275\u0275text(4); 233 \u0275\u0275pipe(5, "translate"); 234 \u0275\u0275elementEnd(); 235 \u0275\u0275elementStart(6, "ion-select", 20); 236 \u0275\u0275twoWayListener("ngModelChange", function ProblemReportsPage_Conditional_22_Template_ion_select_ngModelChange_6_listener($event) { 237 \u0275\u0275restoreView(_r1); 238 const ctx_r1 = \u0275\u0275nextContext(); 239 \u0275\u0275twoWayBindingSet(ctx_r1.filterStatus, $event) || (ctx_r1.filterStatus = $event);
240 return \u0275\u0275resetView($event); 241 }); 242 \u0275\u0275elementStart(7, "ion-select-option", 21); 243 \u0275\u0275text(8); 244 \u0275\u0275pipe(9, "translate"); 245 \u0275\u0275elementEnd(); 246 \u0275\u0275repeaterCreate(10, ProblemReportsPage_Conditional_22_For_11_Template, 3, 4, "ion-select-option", 22, _forTrack0); 247 \u0275\u0275elementEnd()(); 248 \u0275\u0275elementStart(12, "div", 19)(13, "label"); 249 \u0275\u0275text(14); 250 \u0275\u0275pipe(15, "translate"); 251 \u0275\u0275elementEnd(); 252 \u0275\u0275elementStart(16, "ion-select", 20); 253 \u0275\u0275twoWayListener("ngModelChange", function ProblemReportsPage_Conditional_22_Template_ion_select_ngModelChange_16_listener($event) { 254 \u0275\u0275restoreView(_r1); 255 const ctx_r1 = \u0275\u0275nextContext(); 256 \u0275\u0275twoWayBindingSet(ctx_r1.filterCategory, $event) || (ctx_r1.filterCategory = $event); 257 return \u0275\u0275resetView($event); 258 }); 259 \u0275\u0275elementStart(17, "ion-select-option", 21); 260 \u0275\u0275text(18); 261 \u0275\u0275pipe(19, "translate"); 262 \u0275\u0275elementEnd(); 263 \u0275\u0275repeaterCreate(20, ProblemReportsPage_Conditional_22_For_21_Template, 3, 4, "ion-select-option", 22, _forTrack0); 264 \u0275\u0275elementEnd()(); 265 \u0275\u0275elementStart(22, "div", 19)(23, "label"); 266 \u0275\u0275text(24); 267 \u0275\u0275pipe(25, "translate"); 268 \u0275\u0275elementEnd(); 269 \u0275\u0275elementStart(26, "ion-select", 20); 270 \u0275\u0275twoWayListener("ngModelChange", function ProblemReportsPage_Conditional_22_Template_ion_select_ngModelChange_26_listener($event) { 271 \u0275\u0275restoreView(_r1); 272 const ctx_r1 = \u0275\u0275nextContext(); 273 \u0275\u0275twoWayBindingSet(ctx_r1.filterSeverity, $event) || (ctx_r1.filterSeverity = $event); 274 return \u0275\u0275resetView($event); 275 }); 276 \u0275\u0275elementStart(27, "ion-select-option", 21); 277 \u0275\u0275text(28); 278 \u0275\u0275pipe(29, "translate"); 279 \u0275\u0275elementEnd(); 280 \u0275\u0275repeaterCreate(30, ProblemReportsPage_Conditional_22_For_31_Template, 3, 4, "ion-select-option", 22, _forTrack0); 281 \u0275\u0275elementEnd()(); 282 \u0275\u0275elementStart(32, "div", 19)(33, "label"); 283 \u0275\u0275text(34); 284 \u0275\u0275pipe(35, "translate"); 285 \u0275\u0275elementEnd(); 286 \u0275\u0275elementStart(36, "ion-select", 20); 287 \u0275\u0275twoWayListener("ngModelChange", function ProblemReportsPage_Conditional_22_Template_ion_select_ngModelChange_36_listener($event) { 288 \u0275\u0275restoreView(_r1); 289 const ctx_r1 = \u0275\u0275nextContext(); 290 \u0275\u0275twoWayBindingSet(ctx_r1.selectedCampusId, $event) || (ctx_r1.selectedCampusId = $event); 291 return \u0275\u0275resetView($event); 292 }); 293 \u0275\u0275elementStart(37, "ion-select-option", 21); 294 \u0275\u0275text(38); 295 \u0275\u0275pipe(39, "translate"); 296 \u0275\u0275elementEnd(); 297 \u0275\u0275repeaterCreate(40, ProblemReportsPage_Conditional_22_For_41_Template, 2, 2, "ion-select-option", 22, _forTrack1); 298 \u0275\u0275elementEnd()(); 299 \u0275\u0275elementStart(42, "div", 23)(43, "ion-button", 24); 300 \u0275\u0275listener("click", function ProblemReportsPage_Conditional_22_Template_ion_button_click_43_listener() { 301 \u0275\u0275restoreView(_r1); 302 const ctx_r1 = \u0275\u0275nextContext(); 303 return \u0275\u0275resetView(ctx_r1.clearFilters()); 304 }); 305 \u0275\u0275text(44); 306 \u0275\u0275pipe(45, "translate"); 307 \u0275\u0275elementEnd(); 308 \u0275\u0275elementStart(46, "ion-button", 25); 309 \u0275\u0275listener("click", function ProblemReportsPage_Conditional_22_Template_ion_button_click_46_listener() { 310 \u0275\u0275restoreView(_r1); 311 const ctx_r1 = \u0275\u0275nextContext(); 312 return \u0275\u0275resetView(ctx_r1.applyFilters()); 313 }); 314 \u0275\u0275text(47); 315 \u0275\u0275pipe(48, "translate"); 316 \u0275\u0275elementEnd()()()(); 317 } 318 if (rf & 2) { 319 const ctx_r1 = \u0275\u0275nextContext(); 320 \u0275\u0275advance(4); 321 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(5, 14, "problemReport.admin.filterStatus")); 322 \u0275\u0275advance(2); 323 \u0275\u0275twoWayProperty("ngModel", ctx_r1.filterStatus); 324 \u0275\u0275advance(2); 325 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(9, 16, "common.all")); 326 \u0275\u0275advance(2); 327 \u0275\u0275repeater(ctx_r1.statuses); 328 \u0275\u0275advance(4); 329 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(15, 18, "problemReport.admin.filterCategory")); 330 \u0275\u0275advance(2); 331 \u0275\u0275twoWayProperty("ngModel", ctx_r1.filterCategory); 332 \u0275\u0275advance(2); 333 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(19, 20, "common.all")); 334 \u0275\u0275advance(2); 335 \u0275\u0275repeater(ctx_r1.categories); 336 \u0275\u0275advance(4); 337 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(25, 22, "problemReport.admin.filterSeverity")); 338 \u0275\u0275advance(2); 339 \u0275\u0275twoWayProperty("ngModel", ctx_r1.filterSeverity); 340 \u0275\u0275advance(2); 341 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(29, 24, "common.all")); 342 \u0275\u0275advance(2); 343 \u0275\u0275repeater(ctx_r1.severities); 344 \u0275\u0275advance(4); 345 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(35, 26, "admin.users.campusFilter")); 346 \u0275\u0275advance(2); 347 \u0275\u0275twoWayProperty("ngModel", ctx_r1.selectedCampusId); 348 \u0275\u0275advance(2); 349 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(39, 28, "admin.users.allCampuses")); 350 \u0275\u0275advance(2); 351 \u0275\u0275repeater(ctx_r1.accessibleCampuses); 352 \u0275\u0275advance(4); 353 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(45, 30, "common.clear"), " "); 354 \u0275\u0275advance(3); 355 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(48, 32, "common.apply"), " "); 356 } 357} 358function ProblemReportsPage_Conditional_23_Template(rf, ctx) { 359 if (rf & 1) { 360 const _r7 = \u0275\u0275getCurrentView(); 361 \u0275\u0275elementStart(0, "div", 15)(1, "div", 26); 362 \u0275\u0275element(2, "ion-icon", 6); 363 \u0275\u0275elementEnd(); 364 \u0275\u0275elementStart(3, "h3"); 365 \u0275\u0275text(4); 366 \u0275\u0275pipe(5, "translate"); 367 \u0275\u0275elementEnd(); 368 \u0275\u0275elementStart(6, "p"); 369 \u0275\u0275text(7); 370 \u0275\u0275elementEnd(); 371 \u0275\u0275elementStart(8, "ion-button", 27); 372 \u0275\u0275listener("click", function ProblemReportsPage_Conditional_23_Template_ion_button_click_8_listener() { 373 \u0275\u0275restoreView(_r7); 374 const ctx_r1 = \u0275\u0275nextContext();
375 return \u0275\u0275resetView(ctx_r1.refresh()); 376 }); 377 \u0275\u0275element(9, "ion-icon", 28); 378 \u0275\u0275text(10); 379 \u0275\u0275pipe(11, "translate"); 380 \u0275\u0275elementEnd()(); 381 } 382 if (rf & 2) { 383 const ctx_r1 = \u0275\u0275nextContext(); 384 \u0275\u0275advance(4); 385 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(5, 3, "problemReport.admin.connectionFailed")); 386 \u0275\u0275advance(3); 387 \u0275\u0275textInterpolate(ctx_r1.error); 388 \u0275\u0275advance(3); 389 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(11, 5, "common.retry"), " "); 390 } 391} 392function ProblemReportsPage_Conditional_24_Template(rf, ctx) { 393 if (rf & 1) { 394 \u0275\u0275elementStart(0, "div", 16); 395 \u0275\u0275element(1, "ion-spinner"); 396 \u0275\u0275elementStart(2, "p"); 397 \u0275\u0275text(3, "Fetching reports..."); 398 \u0275\u0275elementEnd()(); 399 } 400} 401function ProblemReportsPage_Conditional_25_Conditional_8_Template(rf, ctx) { 402 if (rf & 1) { 403 const _r8 = \u0275\u0275getCurrentView(); 404 \u0275\u0275elementStart(0, "ion-button", 27); 405 \u0275\u0275listener("click", function ProblemReportsPage_Conditional_25_Conditional_8_Template_ion_button_click_0_listener() { 406 \u0275\u0275restoreView(_r8); 407 const ctx_r1 = \u0275\u0275nextContext(2); 408 return \u0275\u0275resetView(ctx_r1.clearFilters()); 409 }); 410 \u0275\u0275element(1, "ion-icon", 31); 411 \u0275\u0275text(2, " Clear Filters "); 412 \u0275\u0275elementEnd(); 413 } 414} 415function ProblemReportsPage_Conditional_25_Template(rf, ctx) { 416 if (rf & 1) { 417 \u0275\u0275elementStart(0, "div", 17)(1, "div", 29)(2, "div", 30); 418 \u0275\u0275element(3, "ion-icon", 6); 419 \u0275\u0275elementEnd(); 420 \u0275\u0275elementStart(4, "h3"); 421 \u0275\u0275text(5, "No Reports Found"); 422 \u0275\u0275elementEnd(); 423 \u0275\u0275elementStart(6, "p"); 424 \u0275\u0275text(7, "All systems operational or no matching reports."); 425 \u0275\u0275elementEnd(); 426 \u0275\u0275template(8, ProblemReportsPage_Conditional_25_Conditional_8_Template, 3, 0, "ion-button"); 427 \u0275\u0275elementEnd()(); 428 } 429 if (rf & 2) { 430 const ctx_r1 = \u0275\u0275nextContext(); 431 \u0275\u0275advance(8); 432 \u0275\u0275conditional(ctx_r1.hasActiveFilters() ? 8 : -1); 433 } 434} 435function ProblemReportsPage_Conditional_26_For_2_Conditional_22_Template(rf, ctx) { 436 if (rf & 1) { 437 \u0275\u0275elementStart(0, "span", 47); 438 \u0275\u0275element(1, "ion-icon", 52); 439 \u0275\u0275text(2); 440 \u0275\u0275elementEnd(); 441 } 442 if (rf & 2) { 443 const report_r10 = \u0275\u0275nextContext().$implicit; 444 \u0275\u0275advance(2); 445 \u0275\u0275textInterpolate1(" ", report_r10.buildingName, " "); 446 } 447} 448function ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_1_Template(rf, ctx) { 449 if (rf & 1) { 450 \u0275\u0275elementStart(0, "div", 53)(1, "h4"); 451 \u0275\u0275element(2, "ion-icon", 67); 452 \u0275\u0275text(3, " Reported Image "); 453 \u0275\u0275elementEnd(); 454 \u0275\u0275element(4, "img", 68); 455 \u0275\u0275elementEnd(); 456 } 457 if (rf & 2) { 458 const report_r10 = \u0275\u0275nextContext(2).$implicit; 459 const ctx_r1 = \u0275\u0275nextContext(2); 460 \u0275\u0275advance(4); 461 \u0275\u0275property("src", ctx_r1.getPhotoUrl(report_r10), \u0275\u0275sanitizeUrl); 462 } 463} 464function ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_2_Template(rf, ctx) { 465 if (rf & 1) { 466 \u0275\u0275elementStart(0, "div", 54)(1, "h4"); 467 \u0275\u0275element(2, "ion-icon", 69); 468 \u0275\u0275text(3, " Description "); 469 \u0275\u0275elementEnd(); 470 \u0275\u0275elementStart(4, "p"); 471 \u0275\u0275text(5); 472 \u0275\u0275elementEnd()(); 473 } 474 if (rf & 2) { 475 const report_r10 = \u0275\u0275nextContext(2).$implicit; 476 \u0275\u0275advance(5); 477 \u0275\u0275textInterpolate(report_r10.description); 478 } 479} 480function ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_21_Template(rf, ctx) { 481 if (rf & 1) { 482 \u0275\u0275elementStart(0, "div", 58)(1, "span", 59); 483 \u0275\u0275text(2); 484 \u0275\u0275pipe(3, "translate"); 485 \u0275\u0275elementEnd(); 486 \u0275\u0275elementStart(4, "span", 70); 487 \u0275\u0275text(5); 488 \u0275\u0275elementEnd()(); 489 } 490 if (rf & 2) { 491 const report_r10 = \u0275\u0275nextContext(2).$implicit; 492 const ctx_r1 = \u0275\u0275nextContext(2); 493 \u0275\u0275advance(2); 494 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(3, 2, "problemReport.admin.indoorCoords")); 495 \u0275\u0275advance(3); 496 \u0275\u0275textInterpolate(ctx_r1.formatIndoorCoords(report_r10.locationX, report_r10.locationY)); 497 } 498} 499function ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_22_Template(rf, ctx) { 500 if (rf & 1) { 501 \u0275\u0275elementStart(0, "div", 58)(1, "span", 59); 502 \u0275\u0275text(2); 503 \u0275\u0275pipe(3, "translate"); 504 \u0275\u0275elementEnd(); 505 \u0275\u0275elementStart(4, "span", 70); 506 \u0275\u0275text(5); 507 \u0275\u0275elementEnd()(); 508 } 509 if (rf & 2) { 510 const report_r10 = \u0275\u0275nextContext(2).$implicit; 511 const ctx_r1 = \u0275\u0275nextContext(2); 512 \u0275\u0275advance(2); 513 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(3, 2, "problemReport.admin.gpsCoords")); 514 \u0275\u0275advance(3); 515 \u0275\u0275textInterpolate(ctx_r1.formatGpsCoords(report_r10.gpsLatitude, report_r10.gpsLongitude)); 516 } 517} 518function ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_23_Template(rf, ctx) { 519 if (rf & 1) { 520 \u0275\u0275elementStart(0, "div", 61)(1, "span", 59); 521 \u0275\u0275text(2); 522 \u0275\u0275pipe(3, "translate"); 523 \u0275\u0275elementEnd(); 524 \u0275\u0275elementStart(4, "span", 60); 525 \u0275\u0275text(5); 526 \u0275\u0275elementEnd()(); 527 } 528 if (rf & 2) { 529 const report_r10 = \u0275\u0275nextContext(2).$implicit; 530 \u0275\u0275advance(2); 531 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(3, 2, "problemReport.admin.nearestPoint")); 532 \u0275\u0275advance(3); 533 \u0275\u0275textInterpolate(report_r10.locationDescription); 534 } 535} 536function ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_24_Template(rf, ctx) { 537 if (rf & 1) { 538 \u0275\u0275elementStart(0, "div", 62)(1, "h4"); 539 \u0275\u0275element(2, "ion-icon", 69); 540 \u0275\u0275text(3, " Admin Notes "); 541 \u0275\u0275elementEnd(); 542 \u0275\u0275elementStart(4, "p", 71); 543 \u0275\u0275text(5); 544 \u0275\u0275elementEnd()(); 545 } 546 if (rf & 2) { 547 const report_r10 = \u0275\u0275nextContext(2).$implicit; 548 \u0275\u0275advance(5); 549 \u0275\u0275textInterpolate(report_r10.adminNotes); 550 } 551} 552function ProblemReportsPage_Conditional_26_For_2_Conditional_27_Template(rf, ctx) { 553 if (rf & 1) { 554 const _r11 = \u0275\u0275getCurrentView(); 555 \u0275\u0275elementStart(0, "ion-card-content", 51); 556 \u0275\u0275template(1, ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_1_Template, 5, 1, "div", 53)(2, ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_2_Template, 6, 1, "div", 54); 557 \u0275\u0275elementStart(3, "div", 55)(4, "h4"); 558 \u0275\u0275element(5, "ion-icon", 56); 559 \u0275\u0275text(6); 560 \u0275\u0275pipe(7, "translate"); 561 \u0275\u0275elementEnd(); 562 \u0275\u0275elementStart(8, "div", 57)(9, "div", 58)(10, "span", 59); 563 \u0275\u0275text(11); 564 \u0275\u0275pipe(12, "translate"); 565 \u0275\u0275elementEnd(); 566 \u0275\u0275elementStart(13, "span", 60); 567 \u0275\u0275text(14); 568 \u0275\u0275elementEnd()(); 569 \u0275\u0275elementStart(15, "div", 58)(16, "span", 59); 570 \u0275\u0275text(17); 571 \u0275\u0275pipe(18, "translate"); 572 \u0275\u0275elementEnd(); 573 \u0275\u0275elementStart(19, "span", 60); 574 \u0275\u0275text(20); 575 \u0275\u0275elementEnd()(); 576 \u0275\u0275template(21, ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_21_Template, 6, 4, "div", 58)(22, ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_22_Template, 6, 4, "div", 58)(23, ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_23_Template, 6, 4, "div", 61); 577 \u0275\u0275elementEnd()(); 578 \u0275\u0275template(24, ProblemReportsPage_Conditional_26_For_2_Conditional_27_Conditional_24_Template, 6, 1, "div", 62); 579 \u0275\u0275elementStart(25, "div", 63)(26, "ion-button", 24); 580 \u0275\u0275listener("click", function ProblemReportsPage_Conditional_26_For_2_Conditional_27_Template_ion_button_click_26_listener() { 581 \u0275\u0275restoreView(_r11); 582 const report_r10 = \u0275\u0275nextContext().$implicit; 583 const ctx_r1 = \u0275\u0275nextContext(2);
584 return \u0275\u0275resetView(ctx_r1.updateStatus(report_r10)); 585 }); 586 \u0275\u0275element(27, "ion-icon", 64); 587 \u0275\u0275text(28, " Change Status "); 588 \u0275\u0275elementEnd(); 589 \u0275\u0275elementStart(29, "ion-button", 65); 590 \u0275\u0275listener("click", function ProblemReportsPage_Conditional_26_For_2_Conditional_27_Template_ion_button_click_29_listener() { 591 \u0275\u0275restoreView(_r11); 592 const report_r10 = \u0275\u0275nextContext().$implicit; 593 const ctx_r1 = \u0275\u0275nextContext(2); 594 return \u0275\u0275resetView(ctx_r1.confirmDelete(report_r10)); 595 }); 596 \u0275\u0275element(30, "ion-icon", 66); 597 \u0275\u0275text(31, " Delete "); 598 \u0275\u0275elementEnd()()(); 599 } 600 if (rf & 2) { 601 const report_r10 = \u0275\u0275nextContext().$implicit; 602 const ctx_r1 = \u0275\u0275nextContext(2); 603 \u0275\u0275advance(); 604 \u0275\u0275conditional(report_r10.photoUploadId ? 1 : -1); 605 \u0275\u0275advance(); 606 \u0275\u0275conditional(report_r10.description ? 2 : -1); 607 \u0275\u0275advance(4); 608 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(7, 11, "problemReport.admin.location"), " "); 609 \u0275\u0275advance(5); 610 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(12, 13, "problemReport.admin.building")); 611 \u0275\u0275advance(3); 612 \u0275\u0275textInterpolate(report_r10.buildingName || "-"); 613 \u0275\u0275advance(3); 614 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(18, 15, "problemReport.admin.floor")); 615 \u0275\u0275advance(3); 616 \u0275\u0275textInterpolate(ctx_r1.formatFloor(report_r10.floorName, report_r10.floorLevel)); 617 \u0275\u0275advance(); 618 \u0275\u0275conditional(report_r10.locationX != null && report_r10.locationY != null ? 21 : -1); 619 \u0275\u0275advance(); 620 \u0275\u0275conditional(report_r10.gpsLatitude != null && report_r10.gpsLongitude != null ? 22 : -1); 621 \u0275\u0275advance(); 622 \u0275\u0275conditional(report_r10.locationDescription ? 23 : -1); 623 \u0275\u0275advance(); 624 \u0275\u0275conditional(report_r10.adminNotes ? 24 : -1); 625 } 626} 627function ProblemReportsPage_Conditional_26_For_2_Template(rf, ctx) { 628 if (rf & 1) { 629 const _r9 = \u0275\u0275getCurrentView(); 630 \u0275\u0275elementStart(0, "ion-card", 35)(1, "ion-card-header", 36); 631 \u0275\u0275listener("click", function ProblemReportsPage_Conditional_26_For_2_Template_ion_card_header_click_1_listener() { 632 const report_r10 = \u0275\u0275restoreView(_r9).$implicit; 633 const ctx_r1 = \u0275\u0275nextContext(2); 634 return \u0275\u0275resetView(ctx_r1.toggleReport(report_r10.id)); 635 }); 636 \u0275\u0275elementStart(2, "div", 37)(3, "div", 38); 637 \u0275\u0275element(4, "ion-icon", 39); 638 \u0275\u0275elementEnd(); 639 \u0275\u0275elementStart(5, "div", 40)(6, "div", 41)(7, "ion-badge", 42); 640 \u0275\u0275text(8); 641 \u0275\u0275pipe(9, "translate"); 642 \u0275\u0275elementEnd(); 643 \u0275\u0275elementStart(10, "ion-badge", 43); 644 \u0275\u0275text(11); 645 \u0275\u0275pipe(12, "translate"); 646 \u0275\u0275elementEnd(); 647 \u0275\u0275elementStart(13, "span", 44); 648 \u0275\u0275text(14); 649 \u0275\u0275elementEnd()(); 650 \u0275\u0275elementStart(15, "h3", 45); 651 \u0275\u0275text(16); 652 \u0275\u0275elementEnd(); 653 \u0275\u0275elementStart(17, "div", 46)(18, "span", 47); 654 \u0275\u0275element(19, "ion-icon", 48); 655 \u0275\u0275text(20); 656 \u0275\u0275pipe(21, "translate"); 657 \u0275\u0275elementEnd(); 658 \u0275\u0275template(22, ProblemReportsPage_Conditional_26_For_2_Conditional_22_Template, 3, 1, "span", 47); 659 \u0275\u0275elementStart(23, "span", 49); 660 \u0275\u0275text(24); 661 \u0275\u0275pipe(25, "translate"); 662 \u0275\u0275elementEnd()()(); 663 \u0275\u0275element(26, "ion-icon", 50); 664 \u0275\u0275elementEnd()(); 665 \u0275\u0275template(27, ProblemReportsPage_Conditional_26_For_2_Conditional_27_Template, 32, 17, "ion-card-content", 51); 666 \u0275\u0275elementEnd(); 667 } 668 if (rf & 2) { 669 const report_r10 = ctx.$implicit; 670 const ctx_r1 = \u0275\u0275nextContext(2); 671 \u0275\u0275classProp("expanded", ctx_r1.isExpanded(report_r10.id))("severity-low", report_r10.severity === "low")("severity-medium", report_r10.severity === "medium")("severity-high", report_r10.severity === "high"); 672 \u0275\u0275advance(3); 673 \u0275\u0275classMap(ctx_r1.getSeverityClass(report_r10.severity)
673); 674 \u0275\u0275advance(); 675 \u0275\u0275property("name", ctx_r1.getCategoryIcon(report_r10.category)); 676 \u0275\u0275advance(3); 677 \u0275\u0275property("color", ctx_r1.getStatusColor(report_r10.status)); 678 \u0275\u0275advance(); 679 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(9, 22, "problemReport.status." + report_r10.status), " "); 680 \u0275\u0275advance(2); 681 \u0275\u0275property("color", ctx_r1.getSeverityColor(report_r10.severity)); 682 \u0275\u0275advance(); 683 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(12, 24, "problemReport.severity." + report_r10.severity), " "); 684 \u0275\u0275advance(3); 685 \u0275\u0275textInterpolate(ctx_r1.formatDate(report_r10.createdAt)); 686 \u0275\u0275advance(2); 687 \u0275\u0275textInterpolate(report_r10.title); 688 \u0275\u0275advance(4); 689 \u0275\u0275textInterpolate1(" ", report_r10.campusName || \u0275\u0275pipeBind1(21, 26, "common.unknown"), " "); 690 \u0275\u0275advance(2); 691 \u0275\u0275conditional(report_r10.buildingName ? 22 : -1); 692 \u0275\u0275advance(2); 693 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(25, 28, "problemReport.category." + report_r10.category), " "); 694 \u0275\u0275advance(2); 695 \u0275\u0275property("name", ctx_r1.isExpanded(report_r10.id) ? "chevron-up-outline" : "chevron-down-outline"); 696 \u0275\u0275advance(); 697 \u0275\u0275conditional(ctx_r1.isExpanded(report_r10.id) ? 27 : -1); 698 } 699} 700function ProblemReportsPage_Conditional_26_Conditional_3_Conditional_2_Template(rf, ctx) { 701 if (rf & 1) { 702 \u0275\u0275element(0, "ion-spinner", 73); 703 } 704} 705function ProblemReportsPage_Conditional_26_Conditional_3_Conditional_3_Template(rf, ctx) { 706 if (rf & 1) { 707 \u0275\u0275element(0, "ion-icon", 74); 708 \u0275\u0275text(1, " Load More "); 709 } 710} 711function ProblemReportsPage_Conditional_26_Conditional_3_Template(rf, ctx) { 712 if (rf & 1) { 713 const _r12 = \u0275\u0275getCurrentView(); 714 \u0275\u0275elementStart(0, "div", 34)(1, "ion-button", 72); 715 \u0275\u0275listener("click", function ProblemReportsPage_Conditional_26_Conditional_3_Template_ion_button_click_1_listener($event) { 716 \u0275\u0275restoreView(_r12); 717 const ctx_r1 = \u0275\u0275nextContext(2); 718 return \u0275\u0275resetView(ctx_r1.loadMore($event)); 719 }); 720 \u0275\u0275template(2, ProblemReportsPage_Conditional_26_Conditional_3_Conditional_2_Template, 1, 0, "ion-spinner", 73)(3, ProblemReportsPage_Conditional_26_Conditional_3_Conditional_3_Template, 2, 0); 721 \u0275\u0275elementEnd()(); 722 } 723 if (rf & 2) { 724 const ctx_r1 = \u0275\u0275nextContext(2); 725 \u0275\u0275advance(); 726 \u0275\u0275property("disabled", ctx_r1.isLoadingMore); 727 \u0275\u0275advance(); 728 \u0275\u0275conditional(ctx_r1.isLoadingMore ? 2 : 3); 729 } 730} 731function ProblemReportsPage_Conditional_26_Template(rf, ctx) { 732 if (rf & 1) { 733 \u0275\u0275elementStart(0, "ion-list", 32); 734 \u0275\u0275repeaterCreate(1, ProblemReportsPage_Conditional_26_For_2_Template, 28, 30, "ion-card", 33, _forTrack1); 735 \u0275\u0275elementEnd(); 736 \u0275\u0275template(3, ProblemReportsPage_Conditional_26_Conditional_3_Template, 4, 2, "div", 34); 737 } 738 if (rf & 2) { 739 const ctx_r1 = \u0275\u0275nextContext(); 740 \u0275\u0275advance(); 741 \u0275\u0275repeater(ctx_r1.reports); 742 \u0275\u0275advance(2); 743 \u0275\u0275conditional(ctx_r1.hasMore ? 3 : -1); 744 } 745} 746var _ProblemReportsPage = class _ProblemReportsPage { 747 constructor(apiService, stateService, apiUrlService, alertController, loadingController, toastController, translate, userCampusService, activatedRoute) { 748 this.apiService = apiService; 749 this.stateService = stateService; 750 this.apiUrlService = apiUrlService; 751 this.alertController = alertController; 752 this.loadingController = loadingController; 753 this.toastController = toastController; 754 this.translate = translate; 755 this.userCampusService = userCampusService; 756 this.activatedRoute = activatedRoute; 757 this.breadcrumbItems = buildAdminBreadcrumbs("problem-reports"); 758 this.destroy$ = new Subject(); 759 this.reports = []; 760 this.totalCount = 0; 761 this.currentPage = 1; 762 this.pageSize = 20; 763 this.hasMore = false;
764 this.isLoading = false; 765 this.isLoadingMore = false; 766 this.error = null; 767 this.filterStatus = ""; 768 this.filterCategory = ""; 769 this.filterSeverity = ""; 770 this.selectedCampusId = ""; 771 this.accessibleCampuses = []; 772 this.showFilters = false; 773 this.expandedReportIds = /* @__PURE__ */ new Set(); 774 this.categories = PROBLEM_REPORT_CATEGORIES; 775 this.severities = PROBLEM_SEVERITIES; 776 this.statuses = PROBLEM_REPORT_STATUSES; 777 addIcons({ 778 refreshOutline, 779 filterOutline, 780 imageOutline, 781 chevronDownOutline, 782 chevronUpOutline, 783 trashOutline, 784 alertCircleOutline, 785 closeOutline, 786 locationOutline, 787 checkmarkOutline, 788 warningOutline, 789 buildOutline, 790 flashOutline, 791 waterOutline, 792 accessibilityOutline, 793 sparklesOutline, 794 helpCircleOutline, 795 documentTextOutline, 796 syncOutline, 797 homeOutline, 798 navigateOutline 799 }); 800 this.apiBaseUrl = this.apiUrlService.getSelectedUrl(); 801 } 802 ngOnInit() { 803 this.selectedCampusId = this.activatedRoute.snapshot.queryParamMap.get("campus") || ""; 804 this.userCampusService.getMyAccessibleCampuses().pipe(takeUntil(this.destroy$)).subscribe({ 805 next: (response) => { 806 this.accessibleCampuses = response.campuses || []; 807 if (this.selectedCampusId && !this.accessibleCampuses.some((campus) => campus.id === this.selectedCampusId)) { 808 this.selectedCampusId = ""; 809 } 810 this.loadReports(); 811 }, 812 error: () => this.loadReports() 813 }); 814 this.stateService.refreshTrigger.pipe(takeUntil(this.destroy$)).subscribe(() => { 815 this.refresh(); 816 }); 817 } 818 ngOnDestroy() { 819 this.destroy$.next(); 820 this.destroy$.complete(); 821 } 822 loadReports(loadMore = false) { 823 if (loadMore) { 824 this.isLoadingMore = true; 825 this.currentPage++; 826 } else { 827 this.isLoading = true; 828 this.currentPage = 1; 829 this.reports = []; 830 } 831 this.error = null; 832 this.apiService.getProblemReportList({ 833 status: this.filterStatus || void 0, 834 category: this.filterCategory || void 0, 835 severity: this.filterSeverity || void 0, 836 campusId: this.selectedCampusId || void 0, 837 page: this.currentPage, 838 pageSize: this.pageSize 839 }).pipe(takeUntil(this.destroy$), finalize(() => { 840 this.isLoading = false; 841 this.isLoadingMore = false; 842 })).subscribe({ 843 next: (response) => { 844 const reports = response.reports || []; 845 if (loadMore) { 846 this.reports = [...this.reports, ...reports]; 847 } else { 848 this.reports = reports; 849 } 850 this.totalCount = response.totalCount || 0; 851 this.hasMore = response.hasMore || false; 852 }, 853 error: (err) => { 854 console.error("Failed to load problem reports:", err); 855 this.error = this.translate.instant("problemReport.admin.loadError"); 856 } 857 }); 858 } 859 refresh(event) { 860 this.loadReports(); 861 if (event) { 862 setTimeout(() => event.target.complete(), 500); 863 } 864 } 865 loadMore(event) { 866 this.loadReports(true); 867 setTimeout(() => event.target.complete(), 500); 868 } 869 toggleFilters() { 870 this.showFilters = !this.showFilters; 871 } 872 applyFilters() { 873 this.loadReports(); 874 } 875 clearFilters() { 876 this.filterStatus = ""; 877 this.filterCategory = ""; 878 this.filterSeverity = ""; 879 this.selectedCampusId = ""; 880 this.loadReports(); 881 } 882 toggleReport(reportId) { 883 if (this.expandedReportIds.has(reportId)) { 884 this.expandedReportIds.delete(reportId); 885 } else { 886 this.expandedReportIds.add(reportId); 887 } 888 } 889 isExpanded(reportId) { 890 return this.expandedReportIds.has(reportId); 891 } 892 getPhotoUrl(report) { 893 if (!report.photoUploadId) 894 return null; 895 return `${this.apiBaseUrl}/api/v1/media/${report.photoUploadId}`; 896 } 897 getCategoryIcon(category) { 898 if (!category) 899 return "help-circle-outline"; 900 const icons = { 901 electrical: "flash-outline", 902 plumbing: "water-outline", 903 structural: "build-outline", 904 accessibility: "accessibility-outline", 905 safety: "warning-outline", 906 cleanliness: "sparkles-outline", 907 other: "help-circle-outline" 908 }; 909 return icons[category] || "help-circle-outline"; 910 } 911 getSeverityColor(severity) { 912 if (!severity) 913 return "medium"; 914 const colors = { 915 low: "success", 916 medium: "warning", 917 high: "danger", 918 critical: "danger" 919 }; 920 return colors[severity] || "medium"; 921 } 922 getStatusColor(status) { 923 if (!status) 924 return "medium"; 925 const colors = { 926 new: "primary", 927 acknowledged: "secondary", 928 in_progress: "warning", 929 resolved: "success", 930 closed: "medium" 931 }; 932 return colors[status] || "medium"; 933 } 934 updateStatus(report) { 935 return __async(this, null, function* () { 936 const alert = yield this.alertController.create({ 937 header: this.translate.instant("problemReport.admin.updateStatus"), 938 inputs: this.statuses.map((status) => ({ 939 name: "status", 940 type: "radio", 941 label: this.translate.instant(status.labelKey), 942 value: status.value, 943 checked: report.status === status.value 944 })), 945 buttons: [ 946 { 947 text: this.translate.instant("common.cancel"), 948 role: "cancel" 949 }, 950 { 951 text: this.translate.instant("common.save"), 952 handler: (data) => __async(this, null, function* () { 953 if (data && data !== report.status) { 954 yield this.saveStatus(report, data); 955 } 956 }) 957 } 958 ] 959 }); 960 yield alert.present(); 961 }); 962 } 963 saveStatus(report, newStatus) { 964 return __async(this, null, function* () { 965 const loading = yield this.loadingController.create({ 966 message: this.translate.instant("common.saving") 967 }); 968 yield loading.present(); 969 this.apiService.updateProblemReportStatus(report.id, newStatus, report.adminNotes || void 0).pipe(takeUntil(this.destroy$), finalize(() => loading.dismiss())).subscribe({ 970 next: (updated) => { 971 const index = this.reports.findIndex((r) => r.id === report.id); 972 if (index >= 0) { 973 this.reports[index] = updated; 974 } 975 this.showToast(this.translate.instant("problemReport.admin.statusUpdated"), "success"); 976 }, 977 error: (err) => { 978 console.error("Failed to update status:", err); 979 this.showToast(this.translate.instant("problemReport.admin.statusUpdateError"), "danger"); 980 } 981 }); 982 }); 983 } 984 confirmDelete(report) { 985 return __async(this, null, function* () { 986 const alert = yield this.alertController.create({ 987 header: this.translate.instant("problemReport.admin.deleteConfirmTitle"), 988 message: this.translate.instant("problemReport.admin.deleteConfirmMessage"), 989 buttons: [ 990 { 991 text: this.translate.instant("common.cancel"), 992 role: "cancel" 993 }, 994 { 995 text: this.translate.instant("common.delete"), 996 role: "destructive", 997 handler: () => this.deleteReport(report) 998 } 999 ] 1000 }); 1001 yield alert.present(); 1002 }); 1003 } 1004 deleteReport(report) { 1005 return __async(this, null, function* () { 1006 const loading = yield this.loadingController.create({ 1007 message: this.translate.instant("common.deleting") 1008 }); 1009 yield loading.present(); 1010 this.apiService.deleteProblemReport(report.id).pipe(takeUntil(this.destroy$), finalize(() => loading.dismiss())).subscribe({ 1011 next: () => { 1012 this.reports = this.reports.filter((r) => r.id !== report.id); 1013 this.totalCount--; 1014 this.showToast(this.translate.instant("problemReport.admin.deleted"), "success"); 1015 }, 1016 error: (err) => { 1017 console.error("Failed to delete report:", err); 1018 this.showToast(this.translate.instant("problemReport.admin.deleteError"), "danger"); 1019 } 1020 }); 1021 }); 1022 } 1023 showToast(message, color) { 1024 return __async(this, null, function* () { 1025 const toast = yield this.toastController.create({ 1026 message, 1027 duration: 2500, 1028 color, 1029 position: "bottom" 1030 }); 1031 yield toast.present(); 1032 }); 1033 } 1034 formatDate(date) { 1035 if (!date) 1036 return "--"; 1037 return RigaDateTimeService.formatInRiga(date, { 1038 year: "numeric", 1039 month: "short", 1040 day: "numeric", 1041 hour: "2-digit", 1042 minute: "2-digit" 1043 }); 1044 } 1045 hasActiveFilters() { 1046 return this.filterStatus !== "" || this.filterCategory !== "" || this.filterSeverity !== "" || this.selectedCampusId !== ""; 1047 } 1048 getSeverityClass(severity) { 1049 if (!severity) 1050 return "severity-unknown"; 1051 return `severity-${severity}`; 1052 } 1053 formatIndoorCoords(x, y) { 1054 if (x == null || y == null) 1055 return "-"; 1056 return `${x}, ${y}`; 1057 } 1058 formatGpsCoords(lat, lng) { 1059 if (lat == null || lng == null) 1060 return "-"; 1061 return `${Number(lat).toFixed(6)}, ${Number(lng).toFixed(6)}`; 1062 } 1063 formatFloor(name, level) { 1064 if (!name) 1065 return "-"; 1066 if (level != null) { 1067 const levelStr = level === 1 ? "G" : level > 1 ? `L${level}` : `B${Math.abs(level - 1)}`; 1068 return `${name} (${levelStr})`; 1069 } 1070 return name; 1071 } 1072}; 1073_ProblemReportsPage.\u0275fac = function ProblemReportsPage_Factory(__ngFactoryType__) { 1074 return new (__ngFactoryType__ || _ProblemReportsPage)(\u0275\u0275directiveInject(ApiService), \u0275\u0275directiveInject(ProblemReportStateService), \u0275\u0275directiveInject(ApiUrlService), \u0275\u0275directiveInject(AlertController), \u0275\u0275directiveInject(LoadingController), \u0275\u0275directiveInject(ToastController), \u0275\u0275directiveInject(TranslateService), \u0275\u0275directiveInject(UserCampusService), \u0275\u0275directiveInject(ActivatedRoute)); 1075}; 1076_ProblemReportsPage.\u0275cmp = /* @__PURE__ */ \u0275\u0275defineComponent({ type: _ProblemReportsPage, selectors: [["app-problem-reports"]
1076], decls: 27, vars: 24, consts: [[3, "fullscreen"], [1, "admin-navigation", 3, "items"], ["slot", "fixed", 3, "ionRefresh"], [1, "admin-content"], [1, "stats-bar"], [1, "stats-icon-wrapper"], ["name", "alert-circle-outline"], [1, "stats-info"], [1, "stats-label"], [1, "stats-value"], [1, "admin-page-actions"], ["fill", "clear", 3, "click"], ["slot", "icon-only", "name", "filter-outline"], ["slot", "icon-only", "name", "refresh-outline"], [1, "filter-toolbar"], [1, "error-container"], [1, "loading-container"], [1, "empty-state"], [1, "filter-container"], [1, "filter-group"], ["interface", "popover", 1, "filter-select", 3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], [1, "filter-actions"], ["fill", "outline", "size", "small", 3, "click"], ["size", "small", 3, "click"], [1, "error-icon-wrapper"], [3, "click"], ["slot", "start", "name", "refresh-outline"], [1, "empty-state-card"], [1, "empty-icon-wrapper"], ["slot", "start", "name", "close-outline"], [1, "report-list"], [1, "report-card", 3, "expanded", "severity-low", "severity-medium", "severity-high"], [1, "load-more"], [1, "report-card"], [1, "report-header", 3, "click"], [1, "report-header-inner"], [1, "report-icon-wrapper"], [3, "name"], [1, "report-header-content"], [1, "report-status-row"], [1, "status-badge", 3, "color"], [1, "severity-badge", 3, "color"], [1, "report-time"], [1, "report-title"], [1, "report-meta"], [1, "meta-item"], ["name", "business-outline"], [1, "meta-item", "category-tag"], [1, "expand-icon", 3, "name"], [1, "report-details"], ["name", "home-outline"], [1, "detail-section", "photo-section"], [1, "detail-section", "description-section"], [1, "detail-section", "location-details-section"], ["name", "location-outline"], [1, "location-grid"], [1, "location-item"], [1, "location-label"], [1, "location-value"], [1, "location-item", "full-width"], [1, "detail-section", "admin-notes-section"], [1, "actions-row"], ["slot", "start", "name", "sync-outline"], ["fill", "outline", "size", "small", "color", "danger", 3, "click"], ["slot", "start", "name", "trash-outline"], ["name", "image-outline"], ["alt", "Problem photo", 1, "report-photo", 3, "src"], ["name", "document-text-outline"], [1, "location-value", "monospace"], [1, "admin-notes"], ["fill", "outline", 3, "click", "disabled"], ["name", "crescent"], ["slot", "start", "name", "chevron-down-outline"]], template: function ProblemReportsPage_Template(rf, ctx) { 1077 if (rf & 1) { 1078 \u0275\u0275elementStart(0, "ion-content", 0); 1079 \u0275\u0275element(1, "app-breadcrumb-navigation", 1); 1080 \u0275\u0275elementStart(2, "ion-refresher", 2); 1081 \u0275\u0275listener("ionRefresh", function ProblemReportsPage_Template_ion_refresher_ionRefresh_2_listener($event) { 1082 return ctx.refresh($event); 1083 }); 1084 \u0275\u0275element(3, "ion-refresher-content"); 1085 \u0275\u0275elementEnd(); 1086 \u0275\u0275elementStart(4, "div", 3)(5, "div", 4)(6, "div", 5); 1087 \u0275\u0275element(7, "ion-icon", 6); 1088 \u0275\u0275elementEnd(); 1089 \u0275\u0275elementStart(8, "div", 7)(9, "span", 8); 1090 \u0275\u0275text(10); 1091 \u0275\u0275pipe(11, "translate"); 1092 \u0275\u0275elementEnd(); 1093 \u0275\u0275elementStart(12, "span", 9); 1094 \u0275\u0275text(13); 1095 \u0275\u0275pipe(14, "translate"); 1096 \u0275\u0275elementEnd()(); 1097 \u0275\u0275elementStart(15, "div", 10)(16, "ion-button", 11); 1098 \u0275\u0275pipe(17, "translate"); 1099 \u0275\u0275listener("click", function ProblemReportsPage_Template_ion_button_click_16_listener() { 1100 return ctx.toggleFilters(); 1101 }); 1102 \u0275\u0275element(18, "ion-icon", 12); 1103 \u0275\u0275elementEnd(); 1104 \u0275\u0275elementStart(19, "ion-button", 11); 1105 \u0275\u0275pipe(20, "translate"); 1106 \u0275\u0275listener("click", function ProblemReportsPage_Template_ion_button_click_19_listener() { 1107 return ctx.refresh(); 1108 }); 1109 \u0275\u0275element(21, "ion-icon", 13); 1110 \u0275\u0275elementEnd()()(); 1111 \u0275\u0275template(22, ProblemReportsPage_Conditional_22_Template, 49, 34, "div", 14)(23, ProblemReportsPage_Conditional_23_Template, 12, 7, "div", 15)(24, ProblemReportsPage_Conditional_24_Template, 4, 0, "div", 16)(25, ProblemReportsPage_Conditional_25_Template, 9, 1, "div", 17)(26, ProblemReportsPage_Conditional_26_Template, 4, 1); 1112 \u0275\u0275elementEnd()(); 1113 } 1114 if (rf & 2) { 1115 \u0275\u0275property("fullscreen", true); 1116 \u0275\u0275advance(); 1117 \u0275\u0275property("items", ctx.breadcrumbItems); 1118 \u0275\u0275advance(9); 1119 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(11, 13, "problemReport.admin.title")); 1120 \u0275\u0275advance(3); 1121 \u0275\u0275textInterpolate(\u0275\u0275pipeBind2(14, 15, "problemReport.admin.tracked", \u0275\u0275pureFunction1(22, _c0, ctx.totalCount))); 1122 \u0275\u0275advance(3); 1123 \u0275\u0275classProp("active", ctx.showFilters); 1124 \u0275\u0275attribute("aria-label", \u0275\u0275pipeBind1(17, 18, "problemReport.admin.toggleFilters")); 1125 \u0275\u0275advance(3); 1126 \u0275\u0275attribute("aria-label", \u0275\u0275pipeBind1(20, 20, "problemReport.admin.refresh")); 1127 \u0275\u0275advance(3); 1128 \u0275\u0275conditional(ctx.showFilters ? 22 : -1); 1129 \u0275\u0275advance(); 1130 \u0275\u0275conditional(ctx.error ? 23 : -1); 1131 \u0275\u0275advance(); 1132 \u0275\u0275conditional(ctx.isLoading && !ctx.error ? 24 : -1); 1133 \u0275\u0275advance(); 1134 \u0275\u0275conditional(!ctx.isLoading && !ctx.error && ctx.reports.length === 0 ? 25 : -1); 1135 \u0275\u0275advance(); 1136 \u0275\u0275conditional(!ctx.isLoading && !ctx.error && ctx.reports.length > 0 ? 26 : -1); 1137 } 1138}, dependencies: [ 1139 CommonModule, 1140 FormsModule, 1141 NgControlStatus, 1142 NgModel, 1143 IonicModule, 1144 IonBadge, 1145 IonButton, 1146 IonCard,
1147 IonCardContent, 1148 IonCardHeader, 1149 IonContent, 1150 IonIcon, 1151 IonList, 1152 IonRefresher, 1153 IonRefresherContent, 1154 IonSelect, 1155 IonSelectOption, 1156 IonSpinner, 1157 SelectValueAccessorDirective, 1158 TranslateModule, 1159 TranslatePipe, 1160 BreadcrumbNavigationComponent 1161], styles: ['\n\n.admin-navigation[_ngcontent-%COMP%] {\n position: sticky;\n top: 0;\n z-index: 20;\n display: block;\n}\n.admin-page-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n margin-left: auto;\n flex-shrink: 0;\n}\n.admin-container[_ngcontent-%COMP%] {\n min-height: 100%;\n background: var(--ion-background-color);\n padding-top: constant(safe-area-inset-top);\n padding-top: env(safe-area-inset-top);\n padding-top: var(--safe-area-inset-top, 0px);\n}\n.admin-content[_ngcontent-%COMP%] {\n padding: 1rem;\n max-width: 900px;\n margin: 0 auto;\n}\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n padding: 2rem;\n}\n.loading-container[_ngcontent-%COMP%] ion-spinner[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n width: 48px;\n height: 48px;\n --color: var(--ion-color-primary);\n}\n.loading-container[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: var(--ion-color-medium);\n font-size: 0.95rem;\n margin: 0;\n}\n.error-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 3rem 2rem;\n text-align: center;\n}\n.error-container[_ngcontent-%COMP%] .error-icon-wrapper[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.15) 0%,\n rgba(239, 68, 68, 0.05) 100%);\n border-radius: 50%;\n margin-bottom: 1.5rem;\n}\n.error-container[_ngcontent-%COMP%] .error-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 40px;\n color: #ef4444;\n}\n.error-container[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n margin: 0 0 0.5rem;\n color: var(--ion-text-color);\n}\n.error-container[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: var(--ion-color-medium);\n margin: 0 0 1.5rem;\n font-size: 0.95rem;\n}\n.error-container[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n --box-shadow: 0 4px 12px rgba(var(--ion-color-primary-rgb), 0.3);\n}\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: calc(100vh - 350px);\n padding: 2rem;\n}\n.empty-state-card[_ngcontent-%COMP%] {\n text-align: center;\n max-width: 400px;\n}\n.empty-state-card[_ngcontent-%COMP%] .empty-icon-wrapper[_ngcontent-%COMP%] {\n width: 100px;\n height: 100px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-medium-rgb), 0.1) 0%,\n rgba(var(--ion-color-medium-rgb), 0.05) 100%);\n border-radius: 24px;\n margin: 0 auto 1.5rem;\n}\n.empty-state-card[_ngcontent-%COMP%] .empty-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--ion-color-medium);\n opacity: 0.6;\n}\n.empty-state-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--ion-text-color);\n margin: 0 0 0.5rem;\n}\n.empty-state-card[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--ion-color-medium);\n margin: 0 0 2rem;\n line-height: 1.5;\n}\n.empty-state-card[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n --box-shadow: 0 4px 12px rgba(var(--ion-color-primary-rgb), 0.3);\n --padding-start: 20px;\n --padding-end: 24px;\n --padding-top: 12px;\n --padding-bottom: 12px;\n font-weight: 600;\n font-size: 1rem;\n}\n.empty-state-card[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);
1161\n --box-shadow: 0 6px 20px rgba(var(--ion-color-primary-rgb), 0.4);\n}\n.nav-card[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n border-radius: 16px;\n overflow: hidden;\n box-shadow: 0 4px 16px var(--shadow-color-light);\n cursor: pointer;\n transition: all 0.3s ease;\n}\n.nav-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 24px var(--shadow-color-light);\n}\n.nav-card[_ngcontent-%COMP%]:hover .nav-icon-wrapper[_ngcontent-%COMP%] {\n transform: scale(1.05);\n}\n.nav-card[_ngcontent-%COMP%] ion-card-content[_ngcontent-%COMP%] {\n padding: 0;\n}\n.nav-card-inner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1.25rem;\n}\n.nav-icon-wrapper[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n var(--ion-color-primary),\n var(--ion-color-primary-shade));\n border-radius: 14px;\n flex-shrink: 0;\n transition: transform 0.3s ease;\n}\n.nav-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 28px;\n color: white;\n}\n.nav-card-text[_ngcontent-%COMP%] {\n flex: 1;\n}\n.nav-card-text[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 4px;\n font-size: 1.1rem;\n font-weight: 600;\n color: var(--ion-text-color);\n}\n.nav-card-text[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.9rem;\n color: var(--ion-color-medium);\n line-height: 1.4;\n}\n.nav-arrow[_ngcontent-%COMP%] {\n color: var(--ion-color-medium);\n opacity: 0.5;\n font-size: 1.5rem;\n transition: transform 0.2s ease;\n}\n.nav-card[_ngcontent-%COMP%]:hover .nav-arrow[_ngcontent-%COMP%] {\n transform: translateX(4px);\n opacity: 0.8;\n}\n.section-card[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n border-radius: 16px;\n overflow: hidden;\n box-shadow: 0 4px 16px var(--shadow-color-light);\n}\n.section-card[_ngcontent-%COMP%] ion-card-header[_ngcontent-%COMP%] {\n padding: 1.25rem;\n background: var(--ion-item-background);\n}\n.section-card[_ngcontent-%COMP%] ion-card-content[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem 1.25rem;\n}\n.section-header-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 1rem;\n flex-wrap: wrap;\n}\n.section-header-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 200px;\n}\n.section-header-info[_ngcontent-%COMP%] ion-card-title[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 700;\n margin-bottom: 0.25rem;\n}\n.section-header-info[_ngcontent-%COMP%] ion-card-subtitle[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n color: var(--ion-color-medium);\n}\n.section-header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n.section-header-actions[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n --box-shadow: 0 2px 8px rgba(var(--ion-color-primary-rgb), 0.25);\n font-weight: 600;\n}\n.section-header-actions[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%]:hover {\n --box-shadow: 0 4px 12px rgba(var(--ion-color-primary-rgb), 0.35);\n}\n.info-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n margin-bottom: 1rem;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-primary-rgb), 0.12) 0%,\n rgba(var(--ion-color-primary-rgb), 0.06) 100%);\n border-radius: 12px;\n border-left: 4px solid var(--ion-color-primary);\n}\n.info-notice[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 1.5rem;\n color: var(--ion-color-primary);\n}\n.info-notice[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n color: var(--ion-text-color);\n line-height: 1.4;\n}\n.custom-searchbar[_ngcontent-%COMP%] {\n --background: var(--ion-item-background);\n --box-shadow: 0 2px 12px var(--shadow-color-light);\n --border-radius: 12px;\n --placeholder-opacity: 0.6;\n margin-bottom: 1rem;\n padding: 0;\n}\n.custom-searchbar.searchbar-has-value[_ngcontent-%COMP%] {\n --clear-button-color: var(--ion-color-medium);\n}\n.list-section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin: 1.5rem 0 1rem;\n}\n.list-section-header[_ngcontent-%COMP%]:first-child {\n margin-top: 0;\n}\n.list-section-header[_ngcontent-%COMP%] .section-icon[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n color: var(--ion-color-primary);\n}\n.list-section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n flex: 1;\n margin: 0;\n font-size: 1.1rem;\n font-weight: 600;\n color: var(--ion-text-color);\n}\n.list-section-header[_ngcontent-%COMP%] .count-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 32px;\n height: 28px;\n padding: 0 12px;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-primary-rgb), 0.15) 0%,\n rgba(var(--ion-color-primary-rgb), 0.08) 100%);\n color: var(--ion-color-primary);\n font-size: 0.85rem;\n font-weight: 600;\n border-radius: 14px;\n}\n.entity-list[_ngcontent-%COMP%] {\n background: transparent;\n margin-bottom: 1rem;\n padding: 0;\n}\n.entity-list[_ngcontent-%COMP%] ion-item[_ngcontent-%COMP%] {\n margin-bottom: 0.75rem;\n border-radius: 14px;\n overflow: hidden;\n box-shadow: 0 2px 12px var(--shadow-color-light);\n}\n.entity-item[_ngcontent-%COMP%] {\n --background: var(--ion-item-background);\n --padding-start: 1rem;\n --padding-end: 1rem;\n --inner-padding-end: 0;\n --min-height: 84px;\n --transition: all 0.2s ease;\n --border-color: transparent;\n position: relative;\n}\n.entity-item[_ngcontent-%COMP%]::part(native) {\n border-radius: 14px;\n}\n.entity-item[_ngcontent-%COMP%]:hover {\n --background: var(--ion-color-step-50);\n}\n.entity-item[_ngcontent-%COMP%]:hover .entity-icon-wrapper[_ngcontent-%COMP%] {\n transform: scale(1.05);\n}\n.entity-item[_ngcontent-%COMP%]:hover .entity-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n transform: scale(1.1);\n}\n.entity-item[_ngcontent-%COMP%] ion-label[_ngcontent-%COMP%] {\n margin: 0.75rem 0;\n}\n.entity-item[_ngcontent-%COMP%] ion-label[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 1.05rem;\n font-weight: 600;\n color: var(--ion-text-color);\n margin-bottom: 0.25rem;\n}\n.entity-item[_ngcontent-%COMP%] ion-label[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n color: var(--ion-color-medium);\n margin: 0.2rem 0;\n line-height: 1.4;\n}\n.entity-icon-wrapper[_ngcontent-%COMP%] {\n --icon-color: var(--ion-color-primary);\n --icon-rgb: var(--ion-color-primary-rgb);\n width: 56px;\n height: 56px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--icon-rgb), 0.15) 0%,\n rgba(var(--icon-rgb), 0.06) 100%);\n border-radius: 14px;\n margin-right: 1rem;\n flex-shrink: 0;\n transition: all 0.3s ease;\n}\n.entity-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n color: var(--icon-color);\n transition: transform 0.3s ease;\n}\n.entity-icon-wrapper.role-superadmin[_ngcontent-%COMP%] {\n --icon-color: #6030ff;\n --icon-rgb:\n 96,\n 48,\n 255;\n}\n.entity-icon-wrapper.role-admin[_ngcontent-%COMP%] {\n --icon-color: #c5000f;\n --icon-rgb:\n 197,\n 0,\n 15;\n}
1161\n.entity-icon-wrapper.role-moderator[_ngcontent-%COMP%] {\n --icon-color: #f59e0b;\n --icon-rgb:\n 245,\n 158,\n 11;\n}\n.entity-icon-wrapper.role-user[_ngcontent-%COMP%] {\n --icon-color: var(--ion-color-primary);\n --icon-rgb: var(--ion-color-primary-rgb);\n}\n.role-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n.role-badge.role-superadmin[_ngcontent-%COMP%] {\n background: rgba(96, 48, 255, 0.15);\n color: #6030ff;\n}\n.role-badge.role-admin[_ngcontent-%COMP%] {\n background: rgba(197, 0, 15, 0.15);\n color: #c5000f;\n}\n.role-badge.role-moderator[_ngcontent-%COMP%] {\n background: rgba(245, 158, 11, 0.15);\n color: #f59e0b;\n}\n.role-badge.role-user[_ngcontent-%COMP%] {\n background: rgba(var(--ion-color-primary-rgb), 0.15);\n color: var(--ion-color-primary);\n}\n.meta-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 0.5rem;\n font-size: 0.85rem;\n color: var(--ion-color-medium);\n}\n.meta-info[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1rem;\n opacity: 0.7;\n}\n.action-buttons[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n.action-buttons[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n --padding-start: 10px;\n --padding-end: 10px;\n --padding-top: 10px;\n --padding-bottom: 10px;\n margin: 0;\n}\n.action-buttons[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n}\n.action-buttons[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%]:hover {\n --background-hover: var(--ion-color-light);\n}\n.action-buttons[_ngcontent-%COMP%] .desktop-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n.action-buttons[_ngcontent-%COMP%] .mobile-menu-button[_ngcontent-%COMP%] {\n display: none;\n}\n.edit-form-card[_ngcontent-%COMP%] {\n border-radius: 16px;\n overflow: hidden;\n box-shadow: 0 4px 20px var(--shadow-color-light);\n}\n.edit-form-card[_ngcontent-%COMP%] ion-card-header[_ngcontent-%COMP%] {\n padding: 1.25rem;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-primary-rgb), 0.08) 0%,\n rgba(var(--ion-color-primary-rgb), 0.02) 100%);\n border-bottom: 1px solid var(--ion-border-color);\n}\n.edit-form-card[_ngcontent-%COMP%] ion-card-content[_ngcontent-%COMP%] {\n padding: 1.5rem;\n}\n.edit-form-card[_ngcontent-%COMP%] ion-item[_ngcontent-%COMP%] {\n --background: transparent;\n --border-color: var(--ion-border-color);\n margin-bottom: 1rem;\n}\n.edit-form-card[_ngcontent-%COMP%] ion-item[_ngcontent-%COMP%]:last-of-type {\n margin-bottom: 0;\n}\n.form-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 1rem;\n padding-top: 1.5rem;\n margin-top: 1.5rem;\n border-top: 1px solid var(--ion-border-color);\n}\n.form-actions[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n min-width: 120px;\n}\n@keyframes _ngcontent-%COMP%_slideIn {\n from {\n opacity: 0;\n transform: translateX(-12px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.entity-item[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_slideIn 0.35s ease-out;\n animation-fill-mode: both;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(1) {\n animation-delay: 0.04s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(2) {\n animation-delay: 0.08s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(3) {\n animation-delay: 0.12s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(4) {\n animation-delay: 0.16s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(5) {\n animation-delay: 0.2s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(6) {\n animation-delay: 0.24s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(7) {\n animation-delay: 0.28s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(8) {\n animation-delay: 0.32s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(9) {\n animation-delay: 0.36s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(10) {\n animation-delay: 0.4s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(11) {\n animation-delay: 0.44s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(12) {\n animation-delay: 0.48s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(13) {\n animation-delay: 0.52s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(14) {\n animation-delay: 0.56s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(15) {\n animation-delay: 0.6s;\n}
1161\n.entity-item[_ngcontent-%COMP%]:nth-child(16) {\n animation-delay: 0.64s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(17) {\n animation-delay: 0.68s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(18) {\n animation-delay: 0.72s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(19) {\n animation-delay: 0.76s;\n}\n.entity-item[_ngcontent-%COMP%]:nth-child(20) {\n animation-delay: 0.8s;\n}\n.nav-card[_ngcontent-%COMP%], \n.section-card[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.4s ease-out;\n}\n@media (max-width: 768px) {\n .admin-content[_ngcontent-%COMP%] {\n padding: 0.75rem;\n }\n .section-header-row[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n gap: 0.75rem;\n }\n .section-header-actions[_ngcontent-%COMP%] {\n justify-content: flex-end;\n }\n .entity-item[_ngcontent-%COMP%] {\n --min-height: 76px;\n --padding-start: 0.75rem;\n --padding-end: 0.75rem;\n }\n .entity-icon-wrapper[_ngcontent-%COMP%] {\n width: 46px;\n height: 46px;\n margin-right: 0.75rem;\n border-radius: 12px;\n }\n .entity-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n }\n .action-buttons[_ngcontent-%COMP%] {\n gap: 0;\n }\n .action-buttons[_ngcontent-%COMP%] .desktop-actions[_ngcontent-%COMP%] {\n display: none;\n }\n .action-buttons[_ngcontent-%COMP%] .mobile-menu-button[_ngcontent-%COMP%] {\n display: flex;\n }\n ion-label[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 1rem;\n }\n ion-label[_ngcontent-%COMP%] .meta-info[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n gap: 4px;\n }\n ion-label[_ngcontent-%COMP%] .meta-info[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n }\n .nav-card-inner[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n .nav-icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n }\n .nav-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 24px;\n }\n}\n@media (prefers-color-scheme: dark) {\n .nav-card[_ngcontent-%COMP%], \n .section-card[_ngcontent-%COMP%], \n .entity-list[_ngcontent-%COMP%] ion-item[_ngcontent-%COMP%] {\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);\n }\n .info-notice[_ngcontent-%COMP%] {\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-primary-rgb), 0.2) 0%,\n rgba(var(--ion-color-primary-rgb), 0.1) 100%);\n }\n}\n.filter-toolbar[_ngcontent-%COMP%] {\n background: var(--ion-item-background, var(--ion-background-color, #ffffff));\n padding: 0.75rem 1rem;\n border: 1px solid var(--ion-border-color, var(--ion-color-step-200, #e2e8f0));\n border-radius: 12px;\n margin-bottom: 1rem;\n}\n.filter-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n padding: 0;\n flex-wrap: wrap;\n align-items: flex-end;\n}\n.filter-group[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 140px;\n display: flex;\n flex-direction: column;\n gap: 0.35rem;\n}\n.filter-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--ion-color-medium);\n margin-left: 0.25rem;\n}\n.filter-select[_ngcontent-%COMP%] {\n --padding-start: 12px;\n font-size: 14px;\n background: var(--ion-background-color);\n border-radius: 10px;\n border: 1px solid var(--ion-border-color);\n}\n.filter-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.stats-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem 1.25rem;\n background: var(--ion-item-background);\n border-radius: 14px;\n margin: 0 0 1rem;\n box-shadow: 0 2px 12px var(--shadow-color-light);\n}\n.stats-icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.06));\n border-radius: 12px;\n}\n.stats-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n color: #ef4444;\n}\n.stats-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.stats-label[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--ion-color-medium);\n}\n.stats-value[_ngcontent-%COMP%] {\n font-size: 0.95rem;\n color: var(--ion-text-color);\n}\n.report-list[_ngcontent-%COMP%] {\n background: transparent;\n padding: 0.5rem;\n}\n.report-card[_ngcontent-%COMP%] {\n margin: 0 0 0.75rem;\n border-radius: 14px;\n overflow: hidden;\n box-shadow: 0 2px 12px var(--shadow-color-light);\n transition: all 0.3s ease;\n animation: _ngcontent-%COMP%_fadeSlideIn 0.35s ease-out;\n animation-fill-mode: both;\n}\n.report-card.severity-low[_ngcontent-%COMP%] {\n border-left: 4px solid #22c55e;\n}
1161\n.report-card.severity-medium[_ngcontent-%COMP%] {\n border-left: 4px solid #f59e0b;\n}\n.report-card.severity-high[_ngcontent-%COMP%] {\n border-left: 4px solid #ef4444;\n}\n.report-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 4px 20px var(--shadow-color-light);\n}\n.report-card.expanded[_ngcontent-%COMP%] {\n box-shadow: 0 6px 24px var(--shadow-color-light);\n}\n.report-card[_ngcontent-%COMP%]:nth-child(1) {\n animation-delay: 0.04s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(2) {\n animation-delay: 0.08s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(3) {\n animation-delay: 0.12s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(4) {\n animation-delay: 0.16s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(5) {\n animation-delay: 0.2s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(6) {\n animation-delay: 0.24s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(7) {\n animation-delay: 0.28s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(8) {\n animation-delay: 0.32s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(9) {\n animation-delay: 0.36s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(10) {\n animation-delay: 0.4s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(11) {\n animation-delay: 0.44s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(12) {\n animation-delay: 0.48s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(13) {\n animation-delay: 0.52s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(14) {\n animation-delay: 0.56s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(15) {\n animation-delay: 0.6s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(16) {\n animation-delay: 0.64s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(17) {\n animation-delay: 0.68s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(18) {\n animation-delay: 0.72s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(19) {\n animation-delay: 0.76s;\n}\n.report-card[_ngcontent-%COMP%]:nth-child(20) {\n animation-delay: 0.8s;\n}\n@keyframes _ngcontent-%COMP%_fadeSlideIn {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.report-header[_ngcontent-%COMP%] {\n cursor: pointer;\n padding: 1rem 1.25rem;\n transition: background 0.2s ease;\n}\n.report-header[_ngcontent-%COMP%]:hover {\n background: var(--ion-color-step-50);\n}\n.report-header-inner[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 1rem;\n}\n.report-icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n flex-shrink: 0;\n transition: transform 0.3s ease;\n}\n.report-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n transition: transform 0.3s ease;\n}\n.report-header[_ngcontent-%COMP%]:hover .report-icon-wrapper[_ngcontent-%COMP%] {\n transform: scale(1.05);\n}\n.report-header[_ngcontent-%COMP%]:hover .report-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n transform: scale(1.1);\n}\n.report-icon-wrapper.severity-low[_ngcontent-%COMP%] {\n background:\n linear-gradient(\n 135deg,\n rgba(34, 197, 94, 0.15),\n rgba(34, 197, 94, 0.06));\n}\n.report-icon-wrapper.severity-low[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n color: #22c55e;\n}\n.report-icon-wrapper.severity-medium[_ngcontent-%COMP%] {\n background:\n linear-gradient(\n 135deg,\n rgba(245, 158, 11, 0.15),\n rgba(245, 158, 11, 0.06));\n}\n.report-icon-wrapper.severity-medium[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n.report-icon-wrapper.severity-high[_ngcontent-%COMP%] {\n background:\n linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.06));\n}\n.report-icon-wrapper.severity-high[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n color: #ef4444;\n}\n.report-header-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.report-status-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n margin-bottom: 8px;\n}\n.status-badge[_ngcontent-%COMP%], \n.severity-badge[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n padding: 4px 10px;\n}
1161\n.report-time[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--ion-color-medium);\n margin-left: auto;\n}\n.report-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--ion-text-color);\n margin: 0 0 0.75rem;\n line-height: 1.4;\n}\n.report-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n align-items: center;\n}\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 0.8rem;\n color: var(--ion-color-medium);\n}\n.meta-item[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1rem;\n opacity: 0.7;\n}\n.meta-item.category-tag[_ngcontent-%COMP%] {\n padding: 3px 8px;\n background: var(--ion-color-light);\n border-radius: 4px;\n font-weight: 600;\n font-size: 0.75rem;\n}\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n color: var(--ion-color-medium);\n opacity: 0.6;\n transition: transform 0.2s ease;\n flex-shrink: 0;\n margin-top: 4px;\n}\n.report-card.expanded[_ngcontent-%COMP%] .expand-icon[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n.report-details[_ngcontent-%COMP%] {\n border-top: 1px solid var(--ion-border-color);\n padding: 1.25rem;\n background: var(--ion-color-step-50);\n animation: _ngcontent-%COMP%_expandIn 0.3s ease-out;\n}\n@keyframes _ngcontent-%COMP%_expandIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.detail-section[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n.detail-section[_ngcontent-%COMP%]:last-of-type {\n margin-bottom: 0;\n}\n.detail-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 0.8rem;\n font-weight: 600;\n color: var(--ion-color-medium);\n margin: 0 0 12px;\n text-transform: uppercase;\n}\n.detail-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n opacity: 0.8;\n}\n.detail-section[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 0.95rem;\n line-height: 1.5;\n color: var(--ion-text-color);\n margin: 0;\n white-space: pre-wrap;\n}\n.photo-section[_ngcontent-%COMP%] .report-photo[_ngcontent-%COMP%] {\n width: 100%;\n max-height: 350px;\n object-fit: contain;\n border-radius: 12px;\n border: 1px solid var(--ion-border-color);\n box-shadow: 0 2px 12px var(--shadow-color-light);\n}\n.location-details-section[_ngcontent-%COMP%] {\n padding: 1rem;\n background: var(--ion-color-light);\n border-radius: 10px;\n border: 1px solid var(--ion-border-color);\n}\n.location-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n}\n@media (max-width: 768px) {\n .location-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n.location-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.location-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1/-1;\n}\n.location-label[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--ion-color-medium);\n}\n.location-value[_ngcontent-%COMP%] {\n font-size: 0.95rem;\n color: var(--ion-text-color);\n}\n.location-value.monospace[_ngcontent-%COMP%] {\n font-family:\n "SF Mono",\n Monaco,\n "Inconsolata",\n monospace;\n font-size: 0.85rem;\n}\n.admin-notes-section[_ngcontent-%COMP%] .admin-notes[_ngcontent-%COMP%] {\n padding: 1rem;\n background: var(--ion-item-background);\n border-radius: 10px;\n border: 1px solid var(--ion-border-color);\n color: var(--ion-text-color);\n font-size: 0.95rem;\n line-height: 1.5;\n margin: 0;\n}\n.actions-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n padding-top: 1rem;\n margin-top: 1.5rem;\n border-top: 1px solid var(--ion-border-color);\n}\n.actions-row[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n --border-radius: 10px;\n font-weight: 500;\n}\n.load-more[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 1.5rem;\n}\n.load-more[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n --border-radius: 12px;\n font-weight: 500;\n}\n.loading-container[_ngcontent-%COMP%], \n.error-container[_ngcontent-%COMP%], \n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n text-align: center;\n animation: _ngcontent-%COMP%_fadeIn 0.4s ease-out;\n}\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.loading-container[_ngcontent-%COMP%] ion-spinner[_ngcontent-%COMP%] {\n color: var(--ion-color-primary);\n margin-bottom: 1rem;\n}\n.loading-container[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: var(--ion-color-medium);\n}\n.error-container[_ngcontent-%COMP%] .error-icon-wrapper[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.05));\n border-radius: 50%;\n margin-bottom: 1.5rem;\n}\n.error-container[_ngcontent-%COMP%] .error-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n color: #ef4444;\n}\n.error-container[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 700;\n color: #ef4444;\n margin-bottom: 0.5rem;\n text-transform: uppercase;\n}\n.error-container[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: var(--ion-color-medium);\n margin-bottom: 1.5rem;\n}\n.empty-state[_ngcontent-%COMP%] .empty-state-card[_ngcontent-%COMP%] {\n max-width: 400px;\n padding: 2rem;\n background: var(--ion-item-background);\n border-radius: 16px;\n border: 1px solid var(--ion-border-color);\n}\n.empty-state[_ngcontent-%COMP%] .empty-state-card[_ngcontent-%COMP%] .empty-icon-wrapper[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-medium-rgb), 0.15),\n rgba(var(--ion-color-medium-rgb), 0.05)
1161);\n border-radius: 50%;\n margin: 0 auto 1.5rem;\n}\n.empty-state[_ngcontent-%COMP%] .empty-state-card[_ngcontent-%COMP%] .empty-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n color: var(--ion-color-medium);\n}\n.empty-state[_ngcontent-%COMP%] .empty-state-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 700;\n color: var(--ion-text-color);\n margin-bottom: 0.5rem;\n text-transform: uppercase;\n}\n.empty-state[_ngcontent-%COMP%] .empty-state-card[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: var(--ion-color-medium);\n margin-bottom: 1.5rem;\n}\n@media (max-width: 768px) {\n .filter-container[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n .filter-group[_ngcontent-%COMP%] {\n min-width: 100%;\n }\n .stats-bar[_ngcontent-%COMP%] {\n margin: 0 0 0.75rem;\n padding: 0.875rem 1rem;\n }\n .stats-bar[_ngcontent-%COMP%] .stats-icon-wrapper[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n }\n .stats-bar[_ngcontent-%COMP%] .stats-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n }\n .report-header[_ngcontent-%COMP%] {\n padding: 0.875rem 1rem;\n }\n .report-icon-wrapper[_ngcontent-%COMP%] {\n width: 42px;\n height: 42px;\n }\n .report-icon-wrapper[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n }\n .report-title[_ngcontent-%COMP%] {\n font-size: 0.95rem;\n }\n .report-time[_ngcontent-%COMP%] {\n width: 100%;\n margin-left: 0;\n margin-top: 6px;\n }\n .report-details[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n .actions-row[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n .actions-row[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n width: 100%;\n }\n}\n@media (prefers-color-scheme: dark) {\n .stats-bar[_ngcontent-%COMP%], \n .report-card[_ngcontent-%COMP%] {\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);\n }\n .report-card.expanded[_ngcontent-%COMP%] {\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);\n }\n .report-details[_ngcontent-%COMP%] {\n background: var(--ion-color-step-100);\n }\n}'] }); 1162var ProblemReportsPage = _ProblemReportsPage; 1163(() => { 1164 (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ProblemReportsPage, [{ 1165 type: Component, 1166 args: [{ selector: "app-problem-reports", standalone: true, imports: [ 1167 CommonModule, 1168 FormsModule, 1169 IonicModule, 1170 TranslateModule, 1171 BreadcrumbNavigationComponent 1172 ], template: `<ion-content [fullscreen]="true"> 1173 <app-breadcrumb-navigation class="admin-navigation" [items]="breadcrumbItems"></app-breadcrumb-navigation> 1174 1175 <ion-refresher slot="fixed" (ionRefresh)="refresh($event)"> 1176 <ion-refresher-content></ion-refresher-content> 1177 </ion-refresher> 1178 1179 <div class="admin-content"> 1180 <!-- Stats Bar --> 1181 <div class="stats-bar"> 1182 <div class="stats-icon-wrapper"> 1183 <ion-icon name="alert-circle-outline"></ion-icon> 1184 </div> 1185 <div class="stats-info"> 1186 <span class="stats-label">{{ 'problemReport.admin.title' | translate }}</span> 1187 <span class="stats-value">{{ 'problemReport.admin.tracked' | translate:{ count: totalCount } }}</span> 1188 </div>
1189 <div class="admin-page-actions"> 1190 <ion-button fill="clear" (click)="toggleFilters()" [class.active]="showFilters" [attr.aria-label]="'problemReport.admin.toggleFilters' | translate"> 1191 <ion-icon slot="icon-only" name="filter-outline"></ion-icon> 1192 </ion-button> 1193 <ion-button fill="clear" (click)="refresh()" [attr.aria-label]="'problemReport.admin.refresh' | translate"> 1194 <ion-icon slot="icon-only" name="refresh-outline"></ion-icon> 1195 </ion-button> 1196 </div> 1197 </div> 1198 1199 <!-- Filters Panel --> 1200 @if (showFilters) { 1201 <div class="filter-toolbar"> 1202 <div class="filter-container"> 1203 <div class="filter-group"> 1204 <label>{{ 'problemReport.admin.filterStatus' | translate }}</label> 1205 <ion-select [(ngModel)]="filterStatus" interface="popover" class="filter-select"> 1206 <ion-select-option value="">{{ 'common.all' | translate }}</ion-select-option> 1207 @for (status of statuses; track status.value) { 1208 <ion-select-option [value]="status.value">{{ status.labelKey | translate }}</ion-select-option> 1209 } 1210 </ion-select> 1211 </div> 1212 1213 <div class="filter-group"> 1214 <label>{{ 'problemReport.admin.filterCategory' | translate }}</label> 1215 <ion-select [(ngModel)]="filterCategory" interface="popover" class="filter-select"> 1216 <ion-select-option value="">{{ 'common.all' | translate }}</ion-select-option> 1217 @for (cat of categories; track cat.value) { 1218 <ion-select-option [value]="cat.value">{{ cat.labelKey | translate }}</ion-select-option> 1219 } 1220 </ion-select> 1221 </div> 1222 1223 <div class="filter-group"> 1224 <label>{{ 'problemReport.admin.filterSeverity' | translate }}</label> 1225 <ion-select [(ngModel)]="filterSeverity" interface="popover" class="filter-select"> 1226 <ion-select-option value="">{{ 'common.all' | translate }}</ion-select-option> 1227 @for (sev of severities; track sev.value) { 1228 <ion-select-option [value]="sev.value">{{ sev.labelKey | translate }}</ion-select-option> 1229 } 1230 </ion-select> 1231 </div> 1232 1233 <div class="filter-group"> 1234 <label>{{ 'admin.users.campusFilter' | translate }}</label> 1235 <ion-select [(ngModel)]="selectedCampusId" interface="popover" class="filter-select"> 1236 <ion-select-option value="">{{ 'admin.users.allCampuses' | translate }}</ion-select-option> 1237 @for (campus of accessibleCampuses; track campus.id) { 1238 <ion-select-option [value]="campus.id">{{ campus.name }}</ion-select-option> 1239 } 1240 </ion-select> 1241 </div> 1242 1243 <div class="filter-actions"> 1244 <ion-button fill="outline" size="small" (click)="clearFilters()"> 1245 {{ 'common.clear' | translate }} 1246 </ion-button> 1247 <ion-button size="small" (click)="applyFilters()"> 1248 {{ 'common.apply' | translate }} 1249 </ion-button> 1250 </div> 1251 </div> 1252 </div> 1253 } 1254 1255 <!-- Error State --> 1256 @if (error) { 1257 <div class="error-container"> 1258 <div class="error-icon-wrapper"> 1259 <ion-icon name="alert-circle-outline"></ion-icon> 1260 </div> 1261 <h3>{{ 'problemReport.admin.connectionFailed' | translate }}</h3> 1262 <p>{{ error }}</p> 1263 <ion-button (click)="refresh()"> 1264 <ion-icon slot="start" name="refresh-outline"></ion-icon> 1265 {{ 'common.retry' | translate }} 1266 </ion-button> 1267 </div> 1268 } 1269 1270 <!-- Loading State --> 1271 @if (isLoading && !error) { 1272 <div class="loading-container"> 1273 <ion-spinner></ion-spinner> 1274 <p>Fetching reports...</p> 1275 </div> 1276 } 1277 1278 <!-- Empty State --> 1279 @if (!isLoading && !error && reports.length === 0) { 1280 <div class="empty-state"> 1281 <div class="empty-state-card"> 1282 <div class="empty-icon-wrapper"> 1283 <ion-icon name="alert-circle-outline"></ion-icon> 1284 </div> 1285 <h3>No Reports Found</h3> 1286 <p>All systems operational or no matching reports.</p> 1287 @if (hasActiveFilters()) { 1288 <ion-button (click)="clearFilters()"> 1289 <ion-icon slot="start" name="close-outline"></ion-icon> 1290 Clear Filters 1291 </ion-button> 1292 } 1293 </div> 1294 </div> 1295 } 1296 1297 <!-- Reports List --> 1298 @if (!isLoading && !error && reports.length > 0) { 1299 <ion-list class="report-list"> 1300 @for (report of reports; track report.id; let idx = $index) { 1301 <ion-card class="report-card" [class.expanded]="isExpanded(report.id!)" [class.severity-low]="report.severity === 'low'" [class.severity-medium]="report.severity === 'medium'" [class.severity-high]="report.severity === 'high'"> 1302 <!-- Report Header --> 1303 <ion-card-header (click)="toggleReport(report.id!)" class="report-header"> 1304 <div class="report-header-inner"> 1305 <!-- Status Icon --> 1306 <div class="report-icon-wrapper" [class]="getSeverityClass(report.severity)"> 1307 <ion-icon [name]="getCategoryIcon(report.category)"></ion-icon> 1308 </div> 1309 1310 <div class="report-header-content"> 1311 <!-- Status Row --> 1312 <div class="report-status-row"> 1313 <ion-badge [color]="getStatusColor(report.status)" class="status-badge"> 1314 {{ 'problemReport.status.' + report.status | translate }} 1315 </ion-badge> 1316 <ion-badge [color]="getSeverityColor(report.severity)" class="severity-badge"> 1317 {{ 'problemReport.severity.' + report.severity | translate }} 1318 </ion-badge>
1319 <span class="report-time">{{ formatDate(report.createdAt) }}</span> 1320 </div> 1321 1322 <!-- Title --> 1323 <h3 class="report-title">{{ report.title }}</h3> 1324 1325 <!-- Meta Info --> 1326 <div class="report-meta"> 1327 <span class="meta-item"> 1328 <ion-icon name="business-outline"></ion-icon> 1329 {{ report.campusName || ('common.unknown' | translate) }} 1330 </span> 1331 @if (report.buildingName) { 1332 <span class="meta-item"> 1333 <ion-icon name="home-outline"></ion-icon> 1334 {{ report.buildingName }} 1335 </span> 1336 } 1337 <span class="meta-item category-tag"> 1338 {{ 'problemReport.category.' + report.category | translate }} 1339 </span> 1340 </div> 1341 </div> 1342 1343 <!-- Expand Icon --> 1344 <ion-icon 1345 [name]="isExpanded(report.id!) ? 'chevron-up-outline' : 'chevron-down-outline'" 1346 class="expand-icon"> 1347 </ion-icon> 1348 </div> 1349 </ion-card-header> 1350 1351 <!-- Expanded Content --> 1352 @if (isExpanded(report.id!)) { 1353 <ion-card-content class="report-details"> 1354 <!-- Photo --> 1355 @if (report.photoUploadId) { 1356 <div class="detail-section photo-section"> 1357 <h4> 1358 <ion-icon name="image-outline"></ion-icon> 1359 Reported Image 1360 </h4> 1361 <img [src]="getPhotoUrl(report)" alt="Problem photo" class="report-photo" /> 1362 </div> 1363 } 1364 1365 <!-- Description --> 1366 @if (report.description) { 1367 <div class="detail-section description-section"> 1368 <h4> 1369 <ion-icon name="document-text-outline"></ion-icon> 1370 Description 1371 </h4> 1372 <p>{{ report.description }}</p> 1373 </div> 1374 } 1375 1376 <!-- Location Details --> 1377 <div class="detail-section location-details-section"> 1378 <h4> 1379 <ion-icon name="location-outline"></ion-icon> 1380 {{ 'problemReport.admin.location' | translate }} 1381 </h4> 1382 <div class="location-grid"> 1383 <div class="location-item"> 1384 <span class="location-label">{{ 'problemReport.admin.building' | translate }}</span> 1385 <span class="location-value">{{ report.buildingName || '-' }}</span> 1386 </div> 1387 <div class="location-item"> 1388 <span class="location-label">{{ 'problemReport.admin.floor' | translate }}</span> 1389 <span class="location-value">{{ formatFloor(report.floorName, report.floorLevel) }}</span> 1390 </div> 1391 @if (report.locationX != null && report.locationY != null) { 1392 <div class="location-item"> 1393 <span class="location-label">{{ 'problemReport.admin.indoorCoords' | translate }}</span> 1394 <span class="location-value monospace">{{ formatIndoorCoords(report.locationX, report.locationY) }}</span> 1395 </div> 1396 } 1397 @if (report.gpsLatitude != null && report.gpsLongitude != null) { 1398 <div class="location-item"> 1399 <span class="location-label">{{ 'problemReport.admin.gpsCoords' | translate }}</span> 1400 <span class="location-value monospace">{{ formatGpsCoords(report.gpsLatitude, report.gpsLongitude) }}</span> 1401 </div> 1402 } 1403 @if (report.locationDescription) { 1404 <div class="location-item full-width">
1405 <span class="location-label">{{ 'problemReport.admin.nearestPoint' | translate }}</span> 1406 <span class="location-value">{{ report.locationDescription }}</span> 1407 </div> 1408 } 1409 </div> 1410 </div> 1411 1412 <!-- Admin Notes --> 1413 @if (report.adminNotes) { 1414 <div class="detail-section admin-notes-section"> 1415 <h4> 1416 <ion-icon name="document-text-outline"></ion-icon> 1417 Admin Notes 1418 </h4> 1419 <p class="admin-notes">{{ report.adminNotes }}</p> 1420 </div> 1421 } 1422 1423 <!-- Actions --> 1424 <div class="actions-row"> 1425 <ion-button fill="outline" size="small" (click)="updateStatus(report)"> 1426 <ion-icon slot="start" name="sync-outline"></ion-icon> 1427 Change Status 1428 </ion-button> 1429 <ion-button fill="outline" size="small" color="danger" (click)="confirmDelete(report)"> 1430 <ion-icon slot="start" name="trash-outline"></ion-icon> 1431 Delete 1432 </ion-button> 1433 </div> 1434 </ion-card-content> 1435 } 1436 </ion-card> 1437 } 1438 </ion-list> 1439 1440 <!-- Load More --> 1441 @if (hasMore) { 1442 <div class="load-more"> 1443 <ion-button fill="outline" (click)="loadMore($event)" [disabled]="isLoadingMore"> 1444 @if (isLoadingMore) { 1445 <ion-spinner name="crescent"></ion-spinner> 1446 } @else { 1447 <ion-icon slot="start" name="chevron-down-outline"></ion-icon> 1448 Load More 1449 } 1450 </ion-button> 1451 </div> 1452 } 1453 } 1454 </div> 1455</ion-content> 1456`, styles: ['/* src/app/pages/admin/problem-reports/problem-reports.page.scss */\n.admin-navigation {\n position: sticky;\n top: 0;\n z-index: 20;\n display: block;\n}\n.admin-page-actions {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n margin-left: auto;\n flex-shrink: 0;\n}\n.admin-container {\n min-height: 100%;\n background: var(--ion-background-color);\n padding-top: constant(safe-area-inset-top);\n padding-top: env(safe-area-inset-top);\n padding-top: var(--safe-area-inset-top, 0px);\n}\n.admin-content {\n padding: 1rem;\n max-width: 900px;\n margin: 0 auto;\n}\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n padding: 2rem;\n}\n.loading-container ion-spinner {\n margin-bottom: 1rem;\n width: 48px;\n height: 48px;\n --color: var(--ion-color-primary);\n}\n.loading-container p {\n color: var(--ion-color-medium);\n font-size: 0.95rem;\n margin: 0;\n}\n.error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 3rem 2rem;\n text-align: center;\n}\n.error-container .error-icon-wrapper {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.15) 0%,\n rgba(239, 68, 68, 0.05) 100%);\n border-radius: 50%;\n margin-bottom: 1.5rem;\n}\n.error-container .error-icon-wrapper ion-icon {\n font-size: 40px;\n color: #ef4444;\n}\n.error-container h3 {\n font-size: 1.25rem;\n font-weight: 600;\n margin: 0 0 0.5rem;\n color: var(--ion-text-color);\n}\n.error-container p {\n color: var(--ion-color-medium);\n margin: 0 0 1.5rem;\n font-size: 0.95rem;\n}\n.error-container ion-button {\n --box-shadow: 0 4px 12px rgba(var(--ion-color-primary-rgb), 0.3);\n}\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: calc(100vh - 350px);\n padding: 2rem;\n}\n.empty-state-card {\n text-align: center;\n max-width: 400px;\n}\n.empty-state-card .empty-icon-wrapper {\n width: 100px;\n height: 100px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-medium-rgb), 0.1) 0%,\n rgba(var(--ion-color-medium-rgb), 0.05) 100%);\n border-radius: 24px;\n margin: 0 auto 1.5rem;\n}\n.empty-state-card .empty-icon-wrapper ion-icon {\n font-size: 48px;\n color: var(--ion-color-medium);\n opacity: 0.6;\n}\n.empty-state-card h3 {\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--ion-text-color);\n margin: 0 0 0.5rem;\n}\n.empty-state-card p {\n font-size: 1rem;\n color: var(--ion-color-medium);\n margin: 0 0 2rem;\n line-height: 1.5;\n}
1456\n.empty-state-card ion-button {\n --box-shadow: 0 4px 12px rgba(var(--ion-color-primary-rgb), 0.3);\n --padding-start: 20px;\n --padding-end: 24px;\n --padding-top: 12px;\n --padding-bottom: 12px;\n font-weight: 600;\n font-size: 1rem;\n}\n.empty-state-card ion-button:hover {\n transform: translateY(-2px);\n --box-shadow: 0 6px 20px rgba(var(--ion-color-primary-rgb), 0.4);\n}\n.nav-card {\n margin-bottom: 1rem;\n border-radius: 16px;\n overflow: hidden;\n box-shadow: 0 4px 16px var(--shadow-color-light);\n cursor: pointer;\n transition: all 0.3s ease;\n}\n.nav-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 24px var(--shadow-color-light);\n}\n.nav-card:hover .nav-icon-wrapper {\n transform: scale(1.05);\n}\n.nav-card ion-card-content {\n padding: 0;\n}\n.nav-card-inner {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1.25rem;\n}\n.nav-icon-wrapper {\n width: 56px;\n height: 56px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n var(--ion-color-primary),\n var(--ion-color-primary-shade));\n border-radius: 14px;\n flex-shrink: 0;\n transition: transform 0.3s ease;\n}\n.nav-icon-wrapper ion-icon {\n font-size: 28px;\n color: white;\n}\n.nav-card-text {\n flex: 1;\n}\n.nav-card-text h3 {\n margin: 0 0 4px;\n font-size: 1.1rem;\n font-weight: 600;\n color: var(--ion-text-color);\n}\n.nav-card-text p {\n margin: 0;\n font-size: 0.9rem;\n color: var(--ion-color-medium);\n line-height: 1.4;\n}\n.nav-arrow {\n color: var(--ion-color-medium);\n opacity: 0.5;\n font-size: 1.5rem;\n transition: transform 0.2s ease;\n}\n.nav-card:hover .nav-arrow {\n transform: translateX(4px);\n opacity: 0.8;\n}\n.section-card {\n margin-bottom: 1rem;\n border-radius: 16px;\n overflow: hidden;\n box-shadow: 0 4px 16px var(--shadow-color-light);\n}\n.section-card ion-card-header {\n padding: 1.25rem;\n background: var(--ion-item-background);\n}\n.section-card ion-card-content {\n padding: 1rem 1.25rem 1.25rem;\n}\n.section-header-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 1rem;\n flex-wrap: wrap;\n}\n.section-header-info {\n flex: 1;\n min-width: 200px;\n}\n.section-header-info ion-card-title {\n font-size: 1.25rem;\n font-weight: 700;\n margin-bottom: 0.25rem;\n}\n.section-header-info ion-card-subtitle {\n font-size: 0.9rem;\n color: var(--ion-color-medium);\n}\n.section-header-actions {\n display: flex;\n gap: 0.5rem;\n}\n.section-header-actions ion-button {\n --box-shadow: 0 2px 8px rgba(var(--ion-color-primary-rgb), 0.25);\n font-weight: 600;\n}\n.section-header-actions ion-button:hover {\n --box-shadow: 0 4px 12px rgba(var(--ion-color-primary-rgb), 0.35);\n}\n.info-notice {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n margin-bottom: 1rem;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-primary-rgb), 0.12) 0%,\n rgba(var(--ion-color-primary-rgb), 0.06) 100%);\n border-radius: 12px;\n border-left: 4px solid var(--ion-color-primary);\n}\n.info-notice ion-icon {\n flex-shrink: 0;\n font-size: 1.5rem;\n color: var(--ion-color-primary);\n}\n.info-notice span {\n font-size: 0.9rem;\n color: var(--ion-text-color);\n line-height: 1.4;\n}\n.custom-searchbar {\n --background: var(--ion-item-background);\n --box-shadow: 0 2px 12px var(--shadow-color-light);\n --border-radius: 12px;\n --placeholder-opacity: 0.6;\n margin-bottom: 1rem;\n padding: 0;\n}\n.custom-searchbar.searchbar-has-value {\n --clear-button-color: var(--ion-color-medium);\n}\n.list-section-header {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin: 1.5rem 0 1rem;\n}\n.list-section-header:first-child {\n margin-top: 0;\n}\n.list-section-header .section-icon {\n width: 28px;\n height: 28px;\n color: var(--ion-color-primary);\n}\n.list-section-header h3 {\n flex: 1;\n margin: 0;\n font-size: 1.1rem;\n font-weight: 600;\n color: var(--ion-text-color);\n}\n.list-section-header .count-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 32px;\n height: 28px;\n padding: 0 12px;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-primary-rgb), 0.15) 0%,\n rgba(var(--ion-color-primary-rgb), 0.08) 100%);\n color: var(--ion-color-primary);\n font-size: 0.85rem;\n font-weight: 600;\n border-radius: 14px;\n}\n.entity-list {\n background: transparent;\n margin-bottom: 1rem;\n padding: 0;\n}\n.entity-list ion-item {\n margin-bottom: 0.75rem;\n border-radius: 14px;\n overflow: hidden;\n box-shadow: 0 2px 12px var(--shadow-color-light);\n}\n.entity-item {\n --background: var(--ion-item-background);\n --padding-start: 1rem;\n --padding-end: 1rem;\n --inner-padding-end: 0;\n --min-height: 84px;\n --transition: all 0.2s ease;\n --border-color: transparent;\n position: relative;\n}\n.entity-item::part(native) {\n border-radius: 14px;\n}\n.entity-item:hover {\n --background: var(--ion-color-step-50);\n}\n.entity-item:hover .entity-icon-wrapper {\n transform: scale(1.05);\n}\n.entity-item:hover .entity-icon-wrapper ion-icon {\n transform: scale(1.1);\n}\n.entity-item ion-label {\n margin: 0.75rem 0;\n}\n.entity-item ion-label h2 {\n font-size: 1.05rem;\n font-weight: 600;\n color: var(--ion-text-color);\n margin-bottom: 0.25rem;\n}\n.entity-item ion-label p {\n font-size: 0.9rem;\n color: var(--ion-color-medium);\n margin: 0.2rem 0;\n line-height: 1.4;\n}\n.entity-icon-wrapper {\n --icon-color: var(--ion-color-primary);\n --icon-rgb: var(--ion-color-primary-rgb);\n width: 56px;\n height: 56px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--icon-rgb), 0.15) 0%,\n rgba(var(--icon-rgb), 0.06) 100%);\n border-radius: 14px;\n margin-right: 1rem;\n flex-shrink: 0;\n transition: all 0.3s ease;\n}\n.entity-icon-wrapper ion-icon {\n font-size: 1.75rem;\n color: var(--icon-color);\n transition: transform 0.3s ease;\n}\n.entity-icon-wrapper.role-superadmin {\n --icon-color: #6030ff;\n --icon-rgb:\n 96,\n 48,\n 255;\n}\n.entity-icon-wrapper.role-admin {\n --icon-color: #c5000f;\n --icon-rgb:\n 197,\n 0,\n 15;\n}\n.entity-icon-wrapper.role-moderator {\n --icon-color: #f59e0b;\n --icon-rgb:\n 245,\n 158,\n 11;\n}\n.entity-icon-wrapper.role-user {\n --icon-color: var(--ion-color-primary);\n --icon-rgb: var(--ion-color-primary-rgb);\n}\n.role-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n.role-badge.role-superadmin {\n background: rgba(96, 48, 255, 0.15);\n color: #6030ff;\n}\n.role-badge.role-admin {\n background: rgba(197, 0, 15, 0.15);\n color: #c5000f;\n}\n.role-badge.role-moderator {\n background: rgba(245, 158, 11, 0.15);\n color: #f59e0b;\n}\n.role-badge.role-user {\n background: rgba(var(--ion-color-primary-rgb), 0.15);\n color: var(--ion-color-primary);\n}\n.meta-info {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 0.5rem;\n font-size: 0.85rem;\n color: var(--ion-color-medium);\n}\n.meta-info ion-icon {\n font-size: 1rem;\n opacity: 0.7;\n}\n.action-buttons {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n.action-buttons ion-button {\n --padding-start: 10px;\n --padding-end: 10px;\n --padding-top: 10px;\n --padding-bottom: 10px;\n margin: 0;\n}\n.action-buttons ion-button ion-icon {\n font-size: 1.25rem;\n}\n.action-buttons ion-button:hover {\n --background-hover: var(--ion-color-light);\n}\n.action-buttons .desktop-actions {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n.action-buttons .mobile-menu-button {\n display: none;\n}\n.edit-form-card {\n border-radius: 16px;\n overflow: hidden;\n box-shadow: 0 4px 20px var(--shadow-color-light);\n}\n.edit-form-card ion-card-header {\n padding: 1.25rem;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-primary-rgb), 0.08) 0%,\n rgba(var(--ion-color-primary-rgb), 0.02) 100%);\n border-bottom: 1px solid var(--ion-border-color);\n}\n.edit-form-card ion-card-content {\n padding: 1.5rem;\n}\n.edit-form-card ion-item {\n --background: transparent;\n --border-color: var(--ion-border-color);\n margin-bottom: 1rem;\n}\n.edit-form-card ion-item:last-of-type {\n margin-bottom: 0;\n}\n.form-actions {\n display: flex;\n justify-content: flex-end;\n gap: 1rem;\n padding-top: 1.5rem;\n margin-top: 1.5rem;\n border-top: 1px solid var(--ion-border-color);\n}\n.form-actions ion-button {\n min-width: 120px;\n}\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateX(-12px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.entity-item {\n animation: slideIn 0.35s ease-out;\n animation-fill-mode: both;\n}
1456\n.entity-item:nth-child(1) {\n animation-delay: 0.04s;\n}\n.entity-item:nth-child(2) {\n animation-delay: 0.08s;\n}\n.entity-item:nth-child(3) {\n animation-delay: 0.12s;\n}\n.entity-item:nth-child(4) {\n animation-delay: 0.16s;\n}\n.entity-item:nth-child(5) {\n animation-delay: 0.2s;\n}\n.entity-item:nth-child(6) {\n animation-delay: 0.24s;\n}\n.entity-item:nth-child(7) {\n animation-delay: 0.28s;\n}\n.entity-item:nth-child(8) {\n animation-delay: 0.32s;\n}\n.entity-item:nth-child(9) {\n animation-delay: 0.36s;\n}\n.entity-item:nth-child(10) {\n animation-delay: 0.4s;\n}\n.entity-item:nth-child(11) {\n animation-delay: 0.44s;\n}\n.entity-item:nth-child(12) {\n animation-delay: 0.48s;\n}\n.entity-item:nth-child(13) {\n animation-delay: 0.52s;\n}\n.entity-item:nth-child(14) {\n animation-delay: 0.56s;\n}\n.entity-item:nth-child(15) {\n animation-delay: 0.6s;\n}\n.entity-item:nth-child(16) {\n animation-delay: 0.64s;\n}\n.entity-item:nth-child(17) {\n animation-delay: 0.68s;\n}\n.entity-item:nth-child(18) {\n animation-delay: 0.72s;\n}\n.entity-item:nth-child(19) {\n animation-delay: 0.76s;\n}\n.entity-item:nth-child(20) {\n animation-delay: 0.8s;\n}\n.nav-card,\n.section-card {\n animation: fadeIn 0.4s ease-out;\n}\n@media (max-width: 768px) {\n .admin-content {\n padding: 0.75rem;\n }\n .section-header-row {\n flex-direction: column;\n align-items: stretch;\n gap: 0.75rem;\n }\n .section-header-actions {\n justify-content: flex-end;\n }\n .entity-item {\n --min-height: 76px;\n --padding-start: 0.75rem;\n --padding-end: 0.75rem;\n }\n .entity-icon-wrapper {\n width: 46px;\n height: 46px;\n margin-right: 0.75rem;\n border-radius: 12px;\n }\n .entity-icon-wrapper ion-icon {\n font-size: 1.5rem;\n }\n .action-buttons {\n gap: 0;\n }\n .action-buttons .desktop-actions {\n display: none;\n }\n .action-buttons .mobile-menu-button {\n display: flex;\n }\n ion-label h2 {\n font-size: 1rem;\n }\n ion-label .meta-info {\n font-size: 0.8rem;\n gap: 4px;\n }\n ion-label .meta-info ion-icon {\n font-size: 0.9rem;\n }\n .nav-card-inner {\n padding: 1rem;\n }\n .nav-icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n }\n .nav-icon-wrapper ion-icon {\n font-size: 24px;\n }\n}\n@media (prefers-color-scheme: dark) {\n .nav-card,\n .section-card,\n .entity-list ion-item {\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);\n }\n .info-notice {\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-primary-rgb), 0.2) 0%,\n rgba(var(--ion-color-primary-rgb), 0.1) 100%);\n }\n}\n.filter-toolbar {\n background: var(--ion-item-background, var(--ion-background-color, #ffffff));\n padding: 0.75rem 1rem;\n border: 1px solid var(--ion-border-color, var(--ion-color-step-200, #e2e8f0));\n border-radius: 12px;\n margin-bottom: 1rem;\n}\n.filter-container {\n display: flex;\n gap: 0.75rem;\n padding: 0;\n flex-wrap: wrap;\n align-items: flex-end;\n}\n.filter-group {\n flex: 1;\n min-width: 140px;\n display: flex;\n flex-direction: column;\n gap: 0.35rem;\n}\n.filter-group label {\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--ion-color-medium);\n margin-left: 0.25rem;\n}\n.filter-select {\n --padding-start: 12px;\n font-size: 14px;\n background: var(--ion-background-color);\n border-radius: 10px;\n border: 1px solid var(--ion-border-color);\n}\n.filter-actions {\n display: flex;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.stats-bar {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem 1.25rem;\n background: var(--ion-item-background);\n border-radius: 14px;\n margin: 0 0 1rem;\n box-shadow: 0 2px 12px var(--shadow-color-light);\n}\n.stats-icon-wrapper {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.06));\n border-radius: 12px;\n}\n.stats-icon-wrapper ion-icon {\n font-size: 1.5rem;\n color: #ef4444;\n}\n.stats-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.stats-label {\n font-size: 0.8rem;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--ion-color-medium);\n}\n.stats-value {\n font-size: 0.95rem;\n color: var(--ion-text-color);\n}\n.report-list {\n background: transparent;\n padding: 0.5rem;\n}\n.report-card {\n margin: 0 0 0.75rem;\n border-radius: 14px;\n overflow: hidden;\n box-shadow: 0 2px 12px var(--shadow-color-light);\n transition: all 0.3s ease;\n animation: fadeSlideIn 0.35s ease-out;\n animation-fill-mode: both;\n}\n.report-card.severity-low {\n border-left: 4px solid #22c55e;\n}\n.report-card.severity-medium {\n border-left: 4px solid #f59e0b;\n}\n.report-card.severity-high {\n border-left: 4px solid #ef4444;\n}\n.report-card:hover {\n box-shadow: 0 4px 20px var(--shadow-color-light);\n}\n.report-card.expanded {\n box-shadow: 0 6px 24px var(--shadow-color-light);\n}
1456\n.report-card:nth-child(1) {\n animation-delay: 0.04s;\n}\n.report-card:nth-child(2) {\n animation-delay: 0.08s;\n}\n.report-card:nth-child(3) {\n animation-delay: 0.12s;\n}\n.report-card:nth-child(4) {\n animation-delay: 0.16s;\n}\n.report-card:nth-child(5) {\n animation-delay: 0.2s;\n}\n.report-card:nth-child(6) {\n animation-delay: 0.24s;\n}\n.report-card:nth-child(7) {\n animation-delay: 0.28s;\n}\n.report-card:nth-child(8) {\n animation-delay: 0.32s;\n}\n.report-card:nth-child(9) {\n animation-delay: 0.36s;\n}\n.report-card:nth-child(10) {\n animation-delay: 0.4s;\n}\n.report-card:nth-child(11) {\n animation-delay: 0.44s;\n}\n.report-card:nth-child(12) {\n animation-delay: 0.48s;\n}\n.report-card:nth-child(13) {\n animation-delay: 0.52s;\n}\n.report-card:nth-child(14) {\n animation-delay: 0.56s;\n}\n.report-card:nth-child(15) {\n animation-delay: 0.6s;\n}\n.report-card:nth-child(16) {\n animation-delay: 0.64s;\n}\n.report-card:nth-child(17) {\n animation-delay: 0.68s;\n}\n.report-card:nth-child(18) {\n animation-delay: 0.72s;\n}\n.report-card:nth-child(19) {\n animation-delay: 0.76s;\n}\n.report-card:nth-child(20) {\n animation-delay: 0.8s;\n}\n@keyframes fadeSlideIn {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.report-header {\n cursor: pointer;\n padding: 1rem 1.25rem;\n transition: background 0.2s ease;\n}\n.report-header:hover {\n background: var(--ion-color-step-50);\n}\n.report-header-inner {\n display: flex;\n align-items: flex-start;\n gap: 1rem;\n}\n.report-icon-wrapper {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n flex-shrink: 0;\n transition: transform 0.3s ease;\n}\n.report-icon-wrapper ion-icon {\n font-size: 1.5rem;\n transition: transform 0.3s ease;\n}\n.report-header:hover .report-icon-wrapper {\n transform: scale(1.05);\n}\n.report-header:hover .report-icon-wrapper ion-icon {\n transform: scale(1.1);\n}\n.report-icon-wrapper.severity-low {\n background:\n linear-gradient(\n 135deg,\n rgba(34, 197, 94, 0.15),\n rgba(34, 197, 94, 0.06));\n}\n.report-icon-wrapper.severity-low ion-icon {\n color: #22c55e;\n}\n.report-icon-wrapper.severity-medium {\n background:\n linear-gradient(\n 135deg,\n rgba(245, 158, 11, 0.15),\n rgba(245, 158, 11, 0.06));\n}\n.report-icon-wrapper.severity-medium ion-icon {\n color: #f59e0b;\n}\n.report-icon-wrapper.severity-high {\n background:\n linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.06));\n}\n.report-icon-wrapper.severity-high ion-icon {\n color: #ef4444;\n}\n.report-header-content {\n flex: 1;\n min-width: 0;\n}\n.report-status-row {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n margin-bottom: 8px;\n}\n.status-badge,\n.severity-badge {\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n padding: 4px 10px;\n}\n.report-time {\n font-size: 0.8rem;\n color: var(--ion-color-medium);\n margin-left: auto;\n}\n.report-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--ion-text-color);\n margin: 0 0 0.75rem;\n line-height: 1.4;\n}\n.report-meta {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n align-items: center;\n}\n.meta-item {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 0.8rem;\n color: var(--ion-color-medium);\n}\n.meta-item ion-icon {\n font-size: 1rem;\n opacity: 0.7;\n}\n.meta-item.category-tag {\n padding: 3px 8px;\n background: var(--ion-color-light);\n border-radius: 4px;\n font-weight: 600;\n font-size: 0.75rem;\n}\n.expand-icon {\n font-size: 1.25rem;\n color: var(--ion-color-medium);\n opacity: 0.6;\n transition: transform 0.2s ease;\n flex-shrink: 0;\n margin-top: 4px;\n}\n.report-card.expanded .expand-icon {\n transform: rotate(180deg);\n}\n.report-details {\n border-top: 1px solid var(--ion-border-color);\n padding: 1.25rem;\n background: var(--ion-color-step-50);\n animation: expandIn 0.3s ease-out;\n}\n@keyframes expandIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.detail-section {\n margin-bottom: 1.5rem;\n}\n.detail-section:last-of-type {\n margin-bottom: 0;\n}\n.detail-section h4 {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 0.8rem;\n font-weight: 600;\n color: var(--ion-color-medium);\n margin: 0 0 12px;\n text-transform: uppercase;\n}\n.detail-section h4 ion-icon {\n font-size: 1.1rem;\n opacity: 0.8;\n}\n.detail-section p {\n font-size: 0.95rem;\n line-height: 1.5;\n color: var(--ion-text-color);\n margin: 0;\n white-space: pre-wrap;\n}\n.photo-section .report-photo {\n width: 100%;\n max-height: 350px;\n object-fit: contain;\n border-radius: 12px;\n border: 1px solid var(--ion-border-color);\n box-shadow: 0 2px 12px var(--shadow-color-light);\n}
1456\n.location-details-section {\n padding: 1rem;\n background: var(--ion-color-light);\n border-radius: 10px;\n border: 1px solid var(--ion-border-color);\n}\n.location-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n}\n@media (max-width: 768px) {\n .location-grid {\n grid-template-columns: 1fr;\n }\n}\n.location-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.location-item.full-width {\n grid-column: 1/-1;\n}\n.location-label {\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--ion-color-medium);\n}\n.location-value {\n font-size: 0.95rem;\n color: var(--ion-text-color);\n}\n.location-value.monospace {\n font-family:\n "SF Mono",\n Monaco,\n "Inconsolata",\n monospace;\n font-size: 0.85rem;\n}\n.admin-notes-section .admin-notes {\n padding: 1rem;\n background: var(--ion-item-background);\n border-radius: 10px;\n border: 1px solid var(--ion-border-color);\n color: var(--ion-text-color);\n font-size: 0.95rem;\n line-height: 1.5;\n margin: 0;\n}\n.actions-row {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n padding-top: 1rem;\n margin-top: 1.5rem;\n border-top: 1px solid var(--ion-border-color);\n}\n.actions-row ion-button {\n --border-radius: 10px;\n font-weight: 500;\n}\n.load-more {\n display: flex;\n justify-content: center;\n padding: 1.5rem;\n}\n.load-more ion-button {\n --border-radius: 12px;\n font-weight: 500;\n}\n.loading-container,\n.error-container,\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n text-align: center;\n animation: fadeIn 0.4s ease-out;\n}\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.loading-container ion-spinner {\n color: var(--ion-color-primary);\n margin-bottom: 1rem;\n}\n.loading-container p {\n color: var(--ion-color-medium);\n}\n.error-container .error-icon-wrapper {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.05));\n border-radius: 50%;\n margin-bottom: 1.5rem;\n}\n.error-container .error-icon-wrapper ion-icon {\n font-size: 2.5rem;\n color: #ef4444;\n}\n.error-container h3 {\n font-size: 1.25rem;\n font-weight: 700;\n color: #ef4444;\n margin-bottom: 0.5rem;\n text-transform: uppercase;\n}\n.error-container p {\n color: var(--ion-color-medium);\n margin-bottom: 1.5rem;\n}\n.empty-state .empty-state-card {\n max-width: 400px;\n padding: 2rem;\n background: var(--ion-item-background);\n border-radius: 16px;\n border: 1px solid var(--ion-border-color);\n}\n.empty-state .empty-state-card .empty-icon-wrapper {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background:\n linear-gradient(\n 135deg,\n rgba(var(--ion-color-medium-rgb), 0.15),\n rgba(var(--ion-color-medium-rgb), 0.05));\n border-radius: 50%;\n margin: 0 auto 1.5rem;\n}\n.empty-state .empty-state-card .empty-icon-wrapper ion-icon {\n font-size: 2.5rem;\n color: var(--ion-color-medium);\n}\n.empty-state .empty-state-card h3 {\n font-size: 1.25rem;\n font-weight: 700;\n color: var(--ion-text-color);\n margin-bottom: 0.5rem;\n text-transform: uppercase;\n}\n.empty-state .empty-state-card p {\n color: var(--ion-color-medium);\n margin-bottom: 1.5rem;\n}\n@media (max-width: 768px) {\n .filter-container {\n flex-direction: column;\n align-items: stretch;\n }\n .filter-group {\n min-width: 100%;\n }\n .stats-bar {\n margin: 0 0 0.75rem;\n padding: 0.875rem 1rem;\n }\n .stats-bar .stats-icon-wrapper {\n width: 40px;\n height: 40px;\n }\n .stats-bar .stats-icon-wrapper ion-icon {\n font-size: 1.25rem;\n }\n .report-header {\n padding: 0.875rem 1rem;\n }\n .report-icon-wrapper {\n width: 42px;\n height: 42px;\n }\n .report-icon-wrapper ion-icon {\n font-size: 1.25rem;\n }\n .report-title {\n font-size: 0.95rem;\n }\n .report-time {\n width: 100%;\n margin-left: 0;\n margin-top: 6px;\n }\n .report-details {\n padding: 1rem;\n }\n .actions-row {\n flex-direction: column;\n }\n .actions-row ion-button {\n width: 100%;\n }\n}\n@media (prefers-color-scheme: dark) {\n .stats-bar,\n .report-card {\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);\n }\n .report-card.expanded {\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);\n }\n .report-details {\n background: var(--ion-color-step-100);\n }\n}\n'] }] 1457 }], () => [{ type: ApiService }, { type: ProblemReportStateService }, { type: ApiUrlService }, { type: AlertController }, { type: LoadingController }, { type: ToastController }, { type: TranslateService }, { type: UserCampusService }, { type: ActivatedRoute }], null); 1458})(); 1459(() => { 1460 (typeof ngDevMode === "undefined" || ngDevMode) && \u0275setClassDebugInfo(ProblemReportsPage, { className: "ProblemReportsPage", filePath: "src/app/pages/admin/problem-reports/problem-reports.page.ts", lineNumber: 69 }); 1461})(); 1462export { 1463 ProblemReportsPage 1464};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.