Repository navigation
Expand file tree
/
Copy pathhelp.php
More file actions
2018 lines (1914 loc) · 133 KB
/
Copy pathhelp.php
File metadata and controls
2018 lines (1914 loc) · 133 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?php
/**
* NewUI v4.0 - Built-in Help System
*
* Searchable help topics organized by category.
* All content stored as PHP arrays — no database needed.
* Client-side search filtering with print support.
*/
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/inc/i18n.php';
require_once __DIR__ . '/inc/rbac.php';
// 2026-07-04 (GH #13) — pick the session profile matching the
// client's cookie (TCADMOBILE vs PHPSESSID). Without this, a
// browser holding a mobile cookie opens an empty desktop session
// here and bounces to login -> redirect loop.
require_once __DIR__ . '/inc/session-bootstrap.php';
sess_bootstrap_auto();
session_start();
if (empty($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
require_once __DIR__ . '/inc/force-pw-change.php';
force_pw_change_redirect();
$user = e($_SESSION['user']);
$level = current_role_name();
$theme = $_SESSION['day_night'] ?? 'Day';
$bs_theme = ($theme === 'Night') ? 'dark' : 'light';
$csrf = csrf_token();
$active_page = 'help';
// ── Help Content ────────────────────────────────────────────────
// Each category has an icon, a label, and an array of topics.
// Each topic has a slug (used for anchoring), a title, and HTML body.
$help_categories = [
'getting-started' => [
'icon' => 'bi-rocket-takeoff',
'label' => 'Getting Started',
'topics' => [
[
'slug' => 'logging-in',
'title' => 'Logging In',
'body' => '
<p>Open your web browser and navigate to the address your administrator provided (for example, <code>http://your-server/newui/</code>).</p>
<ol>
<li>Enter your <strong>Username</strong> and <strong>Password</strong>.</li>
<li>Choose your preferred theme — <strong>Day</strong> (light) or <strong>Night</strong> (dark).</li>
<li>Click <strong>Log In</strong>.</li>
</ol>
<p>If your administrator has enabled Two-Factor Authentication (2FA), you will see an additional screen asking for a 6-digit code from your authenticator app. Enter the code and it will auto-submit.</p>
<p>If your account is locked after too many failed attempts, a countdown timer will appear. Wait for the timer to expire, then try again.</p>
'
],
[
'slug' => 'dashboard-overview',
'title' => 'The Dashboard',
'body' => '
<p>After logging in you land on the <strong>Dashboard</strong>. This is your main workspace — a live overview of your dispatch operation.</p>
<p>The dashboard uses movable, resizable panels called <strong>widgets</strong>:</p>
<table class="table table-sm table-bordered">
<thead><tr><th>Widget</th><th>What It Shows</th></tr></thead>
<tbody>
<tr><td>Statistics</td><td>Quick counts: open incidents, unassigned calls, units on scene, available responders, and more.</td></tr>
<tr><td>Active Incidents</td><td>A table of every open incident. Click a row to see details.</td></tr>
<tr><td>Responders</td><td>All responder units with name, handle, type, status, and assignment count.</td></tr>
<tr><td>Facilities</td><td>Hospitals, shelters, stations with name, type, status, and hours.</td></tr>
<tr><td>Map</td><td>Live map with markers for incidents, units, and facilities.</td></tr>
<tr><td>Activity Log</td><td>Recent events: dispatches, status changes, notes.</td></tr>
<tr><td>Controls</td><td>Quick-action buttons for common tasks.</td></tr>
<tr><td>Communications</td><td>Buttons for Chat, SMS, Radio, Zello, and Alerts.</td></tr>
</tbody>
</table>
<h6>Moving and Resizing</h6>
<ul>
<li><strong>Move:</strong> Click and drag a widget's title bar.</li>
<li><strong>Resize:</strong> Drag the bottom-right corner of any widget.</li>
<li><strong>Toggle:</strong> Use the Widget Toggles bar to show or hide individual widgets.</li>
</ul>
<h6>Layout Tools</h6>
<ul>
<li><strong>Reset</strong> — Restore the default widget positions.</li>
<li><strong>Undo</strong> — Reverse the last layout change.</li>
<li><strong>Snapshots</strong> — Save named layouts (e.g., "Normal Ops" or "Major Event").</li>
</ul>
'
],
[
'slug' => 'navigation',
'title' => 'Navigating the Menu Bar',
'body' => '
<p>The navigation bar runs across the top of every page:</p>
<table class="table table-sm table-bordered">
<thead><tr><th>Button</th><th>Destination</th></tr></thead>
<tbody>
<tr><td>Situation</td><td>Main dashboard (home page).</td></tr>
<tr><td>Full Screen</td><td>Full-screen Situation View in a new tab (wall display).</td></tr>
<tr><td>New</td><td>New Incident form.</td></tr>
<tr><td>Units</td><td>All responder units and their status.</td></tr>
<tr><td>Fac's</td><td>Facilities (hospitals, shelters, stations).</td></tr>
<tr><td>Search</td><td>Incident search page.</td></tr>
<tr><td>Personnel</td><td>Dropdown: Roster, Teams, Scheduling, Vehicles, Equipment.</td></tr>
<tr><td>Reports</td><td>Reporting and statistics.</td></tr>
<tr><td>Config</td><td>Settings page (administrators only).</td></tr>
<tr><td>SOP</td><td>Standard Operating Procedures viewer.</td></tr>
<tr><td>Contacts</td><td>Constituents (external contacts).</td></tr>
<tr><td>Messages</td><td>Internal messaging system.</td></tr>
</tbody>
</table>
<p>On the right side: SSE connection indicator, 24-hour clock, message badge, audio mute, theme toggle, org switcher (if applicable), and your user menu.</p>
'
],
[
'slug' => 'theme-toggle',
'title' => 'Day / Night Theme',
'body' => '
<p>In the upper-right corner you will see two buttons with a sun and moon icon:</p>
<ul>
<li><i class="bi bi-sun-fill text-warning"></i> <strong>Day</strong> — Light backgrounds. Best for well-lit rooms.</li>
<li><i class="bi bi-moon-fill text-primary"></i> <strong>Night</strong> — Dark backgrounds. Easier on the eyes in low-light environments.</li>
</ul>
<p>Your theme choice is saved to your account and persists across sessions.</p>
'
],
],
],
'dispatch' => [
'icon' => 'bi-telephone-inbound',
'label' => 'Dispatch Operations',
'topics' => [
[
'slug' => 'new-incident',
'title' => 'Creating a New Incident',
'body' => '
<p>Click <strong>New</strong> in the navigation bar. The form has two columns:</p>
<ul>
<li><strong>Left:</strong> Form fields in 8 collapsible sections.</li>
<li><strong>Right:</strong> Map for location and responder assignment panel.</li>
</ul>
<h6>The 8 Sections</h6>
<ol>
<li><strong>Classification</strong> — Incident type, severity, scope, description, signal, major incident link.</li>
<li><strong>Location</strong> — Street address, city, state, zip, cross street, coordinates, destination.</li>
<li><strong>Contact</strong> — Caller name, phone, notes.</li>
<li><strong>Facilities</strong> — Receiving facility selection.</li>
<li><strong>Time & Status</strong> — Reported time, initial status.</li>
<li><strong>Call History</strong> — Search previous calls by phone or address.</li>
<li><strong>Patients</strong> — Add/remove patients with name, age, gender, chief complaint.</li>
<li><strong>Additional Details</strong> — Internal notes.</li>
</ol>
<p>When you select an incident type that has a <strong>response protocol</strong>, the protocol text appears above the map. Read it to the caller as appropriate.</p>
<p>Click <strong>Submit Incident</strong> (green button) or press <strong>Ctrl+Enter</strong> from any field.</p>
'
],
[
'slug' => 'assign-units',
'title' => 'Assigning Responder Units',
'body' => '
<p>Below the map on the New Incident form is the responder assignment panel.</p>
<ol>
<li>Use the <strong>search filter</strong> to find a unit by name or callsign.</li>
<li>Check the box next to each unit you want to dispatch.</li>
<li>When you submit the incident, all checked units are assigned automatically.</li>
</ol>
<p>You can also assign units from the <strong>Incident Detail</strong> page after the incident is created.</p>
'
],
[
'slug' => 'close-incident',
'title' => 'Closing an Incident',
'body' => '
<ol>
<li>Open the incident detail view (click the incident row on the dashboard).</li>
<li>Change the status to <strong>Closed</strong>.</li>
<li>Add any closing notes.</li>
<li>Click <strong>Save</strong>.</li>
</ol>
<p>To reopen a closed incident, change the status back to <strong>Open</strong> and save.</p>
'
],
[
'slug' => 'major-incidents',
'title' => 'Major Incidents',
'body' => '
<p>A major incident groups related calls under one umbrella. For example, a wildfire might generate separate calls for structure fires, evacuations, and medical emergencies.</p>
<ul>
<li><strong>Create</strong> a major incident from the incident detail view.</li>
<li><strong>Link</strong> existing incidents to it.</li>
<li><strong>Command structure</strong> fields record Gold, Silver, and Bronze command positions.</li>
<li><strong>Navigate</strong> between linked incidents from any call in the group.</li>
</ul>
'
],
[
'slug' => 'towing-roadside',
'title' => 'Towing and Roadside Dispatch',
'body' => '
<p>When a unit on scene needs a tow truck, a locksmith or another roadside company, use the <strong>Tow / Roadside</strong> button on the incident (or <strong>New</strong> on the <strong>Towing / Roadside</strong> card). It works on <em>every</em> incident type. If you do not see it, the feature is turned off or your role does not include it (ask an administrator; see <a href="documentation/?doc=VENDOR-DISPATCH-GUIDE" target="_blank" rel="noopener">the full guide</a>).</p>
<ol>
<li>Choose the <strong>service needed</strong> (Tow, Lockout, Jumpstart, Tire Change, or whatever your agency added).</li>
<li>The list shows who is <strong>NEXT UP</strong> in your rotation. Press <strong>Log call</strong> (or <strong>Call</strong>). The call is <strong>recorded first</strong>, then dialled if click-to-dial is on. If another dispatcher called the same company a moment earlier you are told who is next now, and nothing is recorded.</li>
<li>Under <strong>Calls awaiting an outcome</strong> press <strong>Accepted</strong> (enter the ETA), <strong>Declined</strong>, <strong>No answer</strong> or <strong>Unavailable</strong>.</li>
<li>Add the <strong>vehicle</strong> and <strong>plate</strong>. For a tow, pick a <strong>destination</strong>: the company's yard, a facility on file, or type an address. A typed address never blocks you.</li>
<li>Use <strong>Read to the driver</strong> to read out the pickup, vehicle, destination and reference (for example <code>26-0123-T1</code>); <strong>Copy</strong> puts it on the clipboard.</li>
</ol>
<h6>Calling out of order</h6>
<p>Pick a company that is not next and you are asked for a <strong>reason</strong> (earlier company did not answer, owner or driver requested it, closest truck, special equipment). That call is recorded as an override and does <strong>not</strong> use up that company's turn. Tick <strong>The driver or owner requested this company</strong> when that is the case. A company that is on no list can be typed in under <strong>Another company</strong>.</p>
<h6>Afterwards</h6>
<p><strong>Manage</strong> on the card row lets you mark <strong>On scene</strong>, <strong>Completed</strong>, <strong>Company withdrew</strong>, <strong>Gone on arrival</strong>, update the <strong>ETA</strong>, add a note, or <strong>Void</strong> an entry made by mistake (your own within 15 minutes; a supervisor any time). Every step is also written to the incident log.</p>
<p><strong>Administrators:</strong> Settings > Resources > <strong>Service Providers (Towing)</strong> holds the companies, the rotation lists, the service types, the history (with a CSV download) and the settings. The service types and the settings apply to every agency on the install, so only a Super Admin can change them.</p>
'
],
[
'slug' => 'incident-detail',
'title' => 'The Incident Detail View',
'body' => '
<p>Click any incident on the dashboard to open its detail view. This page shows:</p>
<ul>
<li><strong>Header</strong> — Incident number, type, severity (color-coded), status.</li>
<li><strong>Location</strong> — Address, city, state, and a map with the incident marker.</li>
<li><strong>Timeline</strong> — Chronological log of notes, status changes, and assignments.</li>
<li><strong>Assignments</strong> — Currently assigned responder units.</li>
<li><strong>Patients</strong> — Patient information (if any).</li>
</ul>
<h6>Action Buttons</h6>
<ul>
<li><strong>Add a note</strong> — Append text to the timeline.</li>
<li><strong>Change status</strong> — Update the incident status.</li>
<li><strong>Assign/remove units</strong> — Manage responders.</li>
<li><strong>Navigate</strong> — Open turn-by-turn directions externally.</li>
<li><strong>ICS-213 Export</strong> — Generate a Winlink-compatible XML form.</li>
</ul>
'
],
],
],
'maps' => [
'icon' => 'bi-map',
'label' => 'Maps',
'topics' => [
[
'slug' => 'map-controls',
'title' => 'Basic Map Controls',
'body' => '
<ul>
<li><strong>Pan:</strong> Click and drag to move the map.</li>
<li><strong>Zoom:</strong> Use the scroll wheel, or click the + and − buttons.</li>
<li><strong>Click a marker:</strong> See details about the incident, unit, or facility.</li>
</ul>
<p>Maps appear on the dashboard, new incident form, incident detail views, and the full-screen situation view.</p>
'
],
[
'slug' => 'address-search',
'title' => 'Address Search / Geocoding',
'body' => '
<h6>Forward Geocoding (address to map)</h6>
<ol>
<li>Type the street address in the Address field.</li>
<li>Click <strong>Lookup</strong> or Tab to it and press Enter.</li>
<li>The map zooms to the result and drops a marker. City, State, and Cross Street auto-fill.</li>
</ol>
<h6>Reverse Geocoding (map click to address)</h6>
<ol>
<li>Click anywhere on the map.</li>
<li>A marker appears and address fields fill in automatically.</li>
</ol>
<p><strong>Tip:</strong> The geocoder prioritizes addresses near your configured location. If results are wrong, try including the city and state in your search.</p>
'
],
[
'slug' => 'map-markups',
'title' => 'Map Markups (Drawing)',
'body' => '
<p>Markups let you draw shapes and annotations on the map for operational planning:</p>
<ul>
<li><strong>Polygons</strong> — Outline search zones, perimeters, staging areas.</li>
<li><strong>Circles</strong> — Mark radius zones (hazmat, evacuation rings).</li>
<li><strong>Lines</strong> — Draw routes, boundaries, or barriers.</li>
<li><strong>Rectangles</strong> — Mark rectangular areas.</li>
<li><strong>Markers</strong> — Place labeled points of interest.</li>
</ul>
<p>Each markup has a name, description, color, and category. Categories can be toggled on/off. Markups persist in the database and are visible to all users.</p>
'
],
[
'slug' => 'weather-overlay',
'title' => 'Weather Overlay',
'body' => '
<p>If your administrator has configured a weather API key, the dashboard map can display weather overlays for temperature, precipitation, cloud cover, and wind.</p>
<p>Weather tiles are cached to reduce load and update periodically.</p>
'
],
[
'slug' => 'situation-view',
'title' => 'Situation View (Full-Screen EOC Display)',
'body' => '
<p>The <strong>Full Screen</strong> link in the top nav opens the Situation
View — a wall-display map showing every active incident, unit, and
facility, with a live side panel. It is built to run unattended for hours.</p>
<h6>The view-lock (why the map stops re-centering)</h6>
<ul>
<li>The map auto-fits to show all active incidents, and re-fits only when
the set of incidents changes — never on an idle refresh.</li>
<li><strong>Any manual pan or zoom — including the on-screen +/−
buttons — locks the view.</strong> After that, automatic refreshes
stop moving the map, so you can watch one area without being snapped
back.</li>
<li>A <strong>★ (star)</strong> button appears top-right once the view
is locked. Click it to resume auto-fit and jump back to the incidents.</li>
<li>The +/− tightness buttons bias how tight the auto-fit is (fill the
screen vs. leave margin to watch approaching weather).</li>
</ul>
<h6>Click-to-zoom with restore</h6>
<p>Click any incident, unit, or facility row in the side panel to zoom to it.
Click the <strong>same</strong> row again to restore the exact view you had
before you zoomed in.</p>
<h6>Overlays and markups — one place to show or hide</h6>
<ul>
<li>Show or hide anything on this map with the <strong>layer control</strong>
(top-right): each map overlay category, <strong>Uncategorised
markups</strong> (markups drawn on this screen), weather, units and
facilities. What you turn off stays off when the screen reloads.</li>
<li>If you can manage the map, a drawing toolbar sits below the layer
control. Its last button (<i class="bi bi-pin-map"></i>) opens
<strong>Edit Markups</strong>, where you rename or delete a markup, or
hide it on <em>every</em> map for <em>every</em> user. It does not
show or hide anything just for you — that is the layer
control’s job.</li>
<li>A markup you draw here is uncategorised. Drawing one turns
<strong>Uncategorised markups</strong> on, so you can see it.</li>
</ul>
<h6>Radar — two layers</h6>
<p>The layer control (top-right) offers two radar layers:</p>
<ul>
<li><strong>Radar — US (NWS)</strong> — NOAA/NWS high-resolution
radar (1 km, ~2-minute updates). Stays sharp at any zoom. <em>US
coverage only.</em> Best for watching a cell approach a specific
site.</li>
<li><strong>Radar — Global</strong> — RainViewer worldwide
mosaic. Use it outside the US or for a country-wide glance. Looks coarse
when zoomed in (that is expected — switch to the NWS layer for a
sharp US close-up).</li>
</ul>
<p class="small text-body-secondary">Both radar layers, plus your chosen
weather/road/markup overlays and the selected side-panel tab, are remembered
per browser across reloads. Radar and weather require internet access to the
providers; an air-gapped display will not show them.</p>
'
],
[
'slug' => 'zone-coverage',
'title' => 'Zone Coverage — Who is where',
'body' => '
<p>The <strong>Zone Coverage</strong> board answers one question at a glance:
<em>how many units are in each zone right now?</em> It is built for events where
volunteers roam between areas — a festival, parade, or fair — so
anyone can decide whether to <strong>meet up</strong> with another unit or
<strong>spread out</strong> for better coverage.</p>
<h6>How it relates to Net Control</h6>
<p><strong>Net Control</strong> is the dispatcher's command board — a
dense grid where net control moves units between zones, runs PAR checks, and
logs everything to the ICS-214. <strong>Zone Coverage</strong> is the
volunteer's companion view: big, phone-friendly cards, visible to
<em>every</em> role (including Field Unit). Both read the same zones and the same
live unit positions — changing a unit's zone in one shows up in the
other within seconds.</p>
<h6>Reading the board</h6>
<ul>
<li>Each <strong>zone</strong> is a card with its colour, a big
<strong>unit count</strong>, and the units currently in it (callsign +
the lead's name).</li>
<li>A <strong>No zone reported yet</strong> bucket at the bottom lists units
that are assigned to the event but have not been placed in a zone, so
nobody is invisible.</li>
<li>The board <strong>updates in real time</strong> — a small
<em>live</em> indicator top-right shows the connection. It also re-polls
every 15 seconds as a safety net.</li>
</ul>
<h6>Reporting your own zone (one tap)</h6>
<p>If you are the person on a unit assigned to the event, an <strong>“I'm
in:”</strong> strip appears with a button for each zone. Tap one and your
unit moves there instantly — no radio call needed — and it shows up
for everyone on the board. It also writes an ICS-214 activity note
(<em>“Alpha → North Gate (self-reported)”</em>) so the
after-action log is complete. You can only ever move <strong>your own</strong>
unit this way; net control still moves any unit from the Net Control board.</p>
<h6>Choosing the event</h6>
<p>The board automatically shows the active event that has zones. If you run more
than one event with zones at once, an event picker appears top-right; your choice
is remembered on that device.</p>
<h6>Setting up zones</h6>
<p>Zones are defined on the <strong>Net Control</strong> board (draw them on the
map, or name them). Once zones exist and units are assigned to the event, Zone
Coverage fills in on its own. If the board says no zones are set up yet, that is
the place to start.</p>
<h6>Who can see and use it</h6>
<ul>
<li><strong>See the board</strong> — every role, including Field Unit
(permission <code>screen.zone_coverage</code>).</li>
<li><strong>Report own zone</strong> — Super Admin, Org Admin,
Dispatcher, Operator, and Field Unit (permission
<code>action.set_own_zone</code>); Read-Only can watch but not change.</li>
</ul>
'
],
[
'slug' => 'tile-providers',
'title' => 'Tile Providers — Map Basemap Reference',
'body' => '
<p>TicketsCAD ships with a registry of tile (basemap) providers. An admin
picks a provider in <strong>Settings » Tile Providers</strong>, and with
<strong>Default basemap for everyone</strong> decides whether every map starts on
it (choose “The provider configured above” for an install whose maps must
work without the internet; otherwise maps start on Street, or Dark in dark mode).
Individual dispatchers can still switch between providers from each map's
layer-control widget, or pick their own default in Display Preferences; a
dispatcher's own choice wins until they set it back to “Install
default”. This reference covers what every built-in option is, whether it
needs a key, and what attribution it requires.</p>
<h6>Tile Mode — who fetches the tiles</h6>
<p>Every map tile your browser requests tells the provider which patch of
ground is on screen. Over a shift that adds up to a running account of where
your incidents are. <strong>Tile Mode</strong> (Settings » Tile Providers)
controls who makes that request:</p>
<ul>
<li><strong>Proxy</strong> (the default) — <em>your server</em> fetches
the tiles and caches them. Dispatchers' browsers never contact the
provider, so the provider sees one server rather than every workstation.</li>
<li><strong>Direct</strong> — each dispatcher's browser fetches
tiles itself, exposing their IP address and browser to the provider.
Use this if your server has no outbound internet access but your
workstations do.</li>
</ul>
<p><strong>Proxy mode does not apply to every provider.</strong> Some
providers' terms do not permit a third party to cache and re-serve their
tiles, and TicketsCAD will not breach them on your behalf — those
providers always go direct. <em>OpenStreetMap, OSM Humanitarian, OpenTopoMap,
USGS and your own tile server can be proxied. CARTO, Esri, Mapbox, Google and
Bing cannot.</em> In practice that means the <strong>Satellite</strong>
basemap, and <strong>Dark</strong> and <strong>Light</strong> when a CARTO key is
set, still reach out from the browser even in proxy mode. The live per-provider verdict is shown in
Settings » Tile Providers.</p>
<p class="mb-1"><strong>Two things worth setting:</strong></p>
<ul>
<li><strong>Proxy User-Agent</strong> — OpenStreetMap blocks generic
identifiers. Leave it blank for an automatic value, or enter something
contactable such as <code>Metro ARES CAD ([email protected])</code>.</li>
<li><strong>Cache Size Limit</strong> and <strong>Keep Disk Free</strong>
— the cache evicts its least-recently-used tiles at the size
limit, and stops writing (but keeps serving maps) if free disk would
fall below the reserve. It cannot fill your disk.</li>
</ul>
<p>Address lookup (the <strong>Lookup</strong> buttons) is <em>not</em>
proxied — the typed address always goes from the browser to the public
geocoder. If that matters for your deployment, host geocoding internally.</p>
<h6>Free — no key required (recommended)</h6>
<table class="table table-sm table-bordered">
<thead><tr><th>Name</th><th>Coverage</th><th>Best for</th><th>Attribution</th></tr></thead>
<tbody>
<tr><td><strong>OpenStreetMap — Standard</strong></td>
<td>Worldwide</td>
<td>General-purpose street map. Best default.</td>
<td>© OpenStreetMap contributors</td></tr>
<tr><td><strong>OpenStreetMap — Humanitarian (HOT)</strong></td>
<td>Worldwide</td>
<td>Emergency-focused styling. Hospitals, schools, evacuation features highlighted. Great for dispatch.</td>
<td>© OpenStreetMap contributors, Humanitarian OSM Team</td></tr>
<tr><td><strong>USGS — Topographic</strong></td>
<td>United States only</td>
<td>Public-domain US topo map. Contour lines, hydrography, shaded relief.</td>
<td>US Geological Survey (public domain)</td></tr>
<tr><td><strong>USGS — Imagery</strong></td>
<td>United States only</td>
<td>US satellite imagery, no labels.</td>
<td>US Geological Survey</td></tr>
<tr><td><strong>USGS — Imagery + Topo</strong></td>
<td>United States only</td>
<td>Satellite imagery with topographic overlay.</td>
<td>US Geological Survey</td></tr>
<tr><td><strong>Esri — Street</strong></td>
<td>Worldwide</td>
<td>Esri-styled street map. Useful when matching agency's existing ArcGIS visuals.</td>
<td>Esri, HERE, Garmin, FAO, NOAA, USGS</td></tr>
<tr><td><strong>Esri — World Imagery</strong></td>
<td>Worldwide</td>
<td>High-resolution satellite imagery from Esri. Excellent zoom-in detail.</td>
<td>Esri, Maxar, Earthstar Geographics</td></tr>
<tr><td><strong>Esri — Topographic</strong></td>
<td>Worldwide</td>
<td>Esri-styled topo. Good worldwide alternative to USGS Topo.</td>
<td>Esri, USGS, NOAA</td></tr>
</tbody>
</table>
<p class="small text-body-secondary">
These are usable without any account or key. They will continue to
work over time as long as the tile servers themselves stay online.
Heavy production traffic should be considerate of the public
OSM/USGS infrastructure — the providers ask that you not hammer
them with sustained high-volume requests. For a 24/7 EOC display
with dozens of dispatchers, a CDN-backed paid plan (Mapbox,
MapTiler, Stadia, Azure Maps) is more appropriate.
</p>
<p><strong>The Dark and Light basemaps.</strong> Every map offers Dark and
Light, and Dark is where maps start in dark mode. They are drawn by CARTO, which
since September 2026 needs a free key for them (carto.com/basemaps/apikey —
no account). Enter it in Settings » Tile Providers » “CARTO key
for the Dark and Light maps”. Without a key, Dark and Light are drawn from
OpenStreetMap instead, recoloured, rather than showing CARTO’s “API
key required” tiles. When the provider configured in Tile Providers is a
CARTO one, its key is used for Dark and Light as well.</p>
<h6>Requires an API key</h6>
<table class="table table-sm table-bordered">
<thead><tr><th>Name</th><th>How to get a key</th><th>Free tier (approx.)</th></tr></thead>
<tbody>
<tr><td><strong>CartoDB — Positron</strong></td>
<td>carto.com/basemaps/apikey — free, takes a minute, no CARTO account required. CARTO added this requirement to raster basemaps in 2026; the same key also works for Dark Matter below.</td>
<td>5,000,000 requests/month (non-commercial); 1,000,000/month (commercial).</td></tr>
<tr><td><strong>CartoDB — Dark Matter</strong></td>
<td>carto.com/basemaps/apikey — same key as Positron above.</td>
<td>5,000,000 requests/month (non-commercial); 1,000,000/month (commercial).</td></tr>
<tr><td><strong>Mapbox</strong></td>
<td>account.mapbox.com — sign up for a free account, copy the default public token.</td>
<td>50,000 free map loads/month, then $0.60/1,000.</td></tr>
<tr><td><strong>Custom URL</strong> (Azure Maps, MapTiler, Stadia, Thunderforest, your own tileserver, etc.)</td>
<td>Sign up with the provider, get their tile URL template, paste it into the <strong>Custom URL</strong> field. Substitute the key in the template (e.g. <code>?key={key}</code> with the key value in <strong>API Key</strong>). Fill in <strong>Map credit</strong> with the credit the provider requires; tiles made from OpenStreetMap data need “© OpenStreetMap contributors”.</td>
<td>Varies by provider.</td></tr>
</tbody>
</table>
<h6>Azure Maps (Microsoft's Bing replacement)</h6>
<p>If you want Microsoft tiles, the path forward is Azure Maps:</p>
<ol>
<li>Sign up at <code>portal.azure.com</code>, create an Azure Maps account (free Azure subscription works).</li>
<li>Get a subscription key from the Authentication page of your Azure Maps account.</li>
<li>In TicketsCAD: Settings » Tile Providers, choose <strong>Custom URL</strong>, and paste:</li>
</ol>
<pre><code>https://atlas.microsoft.com/map/tile?subscription-key={key}&api-version=2024-04-01&tilesetId=microsoft.imagery&zoom={z}&x={x}&y={y}</code></pre>
<p>Put your subscription key in the <strong>API Key</strong> field. Other tilesets to try by swapping <code>microsoft.imagery</code>: <code>microsoft.base.road</code>, <code>microsoft.base.darkgrey</code>, <code>microsoft.weather.infrared.main</code>.</p>
<p>Azure Maps tile pricing is roughly $0.50 per 1,000 transactions on the Gen2 pay-as-you-go tier (tiles are <strong>not</strong> included in the 250k/month free transactions on Gen2). For a small fire department / ARES group typical usage runs under $1/month; for a busy 24/7 EOC, model the cost before committing.</p>
<h6>Backward compatibility — not recommended for new use</h6>
<table class="table table-sm table-bordered">
<thead><tr><th>Name</th><th>Status</th><th>Notes</th></tr></thead>
<tbody>
<tr><td><strong>Google Maps</strong> (Streets / Satellite / Hybrid)</td>
<td>Unofficial</td>
<td>Google does not publish a public tile URL or a free Maps Static / Tile API for this kind of consumption. The URLs in our dropdown hit Google's tile servers directly — they work today but are not licensed and can be blocked at any time. For supported Google tiles, use the Maps JavaScript API (different integration, not a drop-in tile URL).</td></tr>
<tr><td><strong>Bing Maps — Road / Aerial</strong></td>
<td><span class="badge bg-danger">Retired by Microsoft</span></td>
<td>Microsoft discontinued Bing Maps for Enterprise. Basic (free) accounts were shut down on <strong>June 30, 2025</strong>; existing paid Enterprise accounts run through <strong>June 30, 2028</strong> but renewal terms tighten after July 2026 and new accounts are no longer issued. The dropdown options are kept so existing configs don't break; new deployments should pick Azure Maps (see above) or one of the free no-key options.</td></tr>
</tbody>
</table>
<h6>Troubleshooting</h6>
<ul>
<li><strong>Tiles don't load:</strong> open browser DevTools » Network and look for the tile URL. If you see 401/403, the provider needs a key. If you see 404, the URL template is malformed. If you see CORS errors, the provider may not allow direct browser access — use the tile-proxy mode under Settings.</li>
<li><strong>USGS only shows blank tiles outside the US:</strong> USGS basemaps are US-only. Switch to OpenStreetMap or Esri for international coverage.</li>
<li><strong>Bing tiles stopped working:</strong> if your install was using Bing before mid-2025, the Basic account was shut down. Switch to any free option or migrate to Azure Maps.</li>
</ul>
'
],
[
'slug' => 'road-conditions',
'title' => 'Road Conditions',
'body' => '
<p>Road condition markers show hazards on the map: slippery roads, flooding, closures, construction, and debris.</p>
<ul>
<li>Manage conditions from the Controls widget on the dashboard (click <strong>Roads</strong>).</li>
<li>Conditions can auto-expire after a set time.</li>
<li>Visual markers appear directly on the map so dispatchers can warn responders.</li>
<li>Admins editing a road condition report in Settings can click <strong>Lookup</strong> next to the Address field to fill in Latitude/Longitude automatically instead of typing coordinates by hand. A report saved with no coordinates (0, 0) is still valid but will not appear on the map overlay — the form shows a warning when that is the case.</li>
</ul>
'
],
],
],
'communications' => [
'icon' => 'bi-chat-dots',
'label' => 'Communications',
'topics' => [
[
'slug' => 'chat',
'title' => 'Chat',
'body' => '
<p>TicketsCAD has a built-in chat system. Open it from the Communications widget on the dashboard.</p>
<h6>Channels</h6>
<ul>
<li><strong>General</strong> — Visible to everyone.</li>
<li><strong>Dispatch</strong> — Dispatch operators only.</li>
<li><strong>Admin</strong> — Administrators only.</li>
</ul>
<p>Select a channel, type your message, and press <strong>Enter</strong> or click <strong>Send</strong>.</p>
<h6>Signal Codes</h6>
<p>Click the <strong>Codes</strong> button to see predefined signal codes. Clicking a code sends it instantly.</p>
'
],
[
'slug' => 'audio-alerts',
'title' => 'Audio Alerts',
'body' => '
<p>TicketsCAD can play sounds when important events occur (new incidents, status changes, chat messages).</p>
<p>Click the <strong>speaker icon</strong> in the navigation bar to mute/unmute. Sound configuration is managed by your administrator in Config > App Preferences > Sound / Alerts.</p>
<p><strong>Note:</strong> Browsers require at least one click on the page before they allow audio playback.</p>
'
],
[
'slug' => 'has-broadcast',
'title' => 'HAS Broadcast',
'body' => '
<p>Dispatchers and administrators can send a <strong>HAS (Hearing All Stations) Broadcast</strong> — a message that goes to all connected users immediately.</p>
<p>Click the <i class="bi bi-megaphone-fill"></i> megaphone icon in the navigation bar. Enter your message and send. All logged-in users will see the broadcast.</p>
'
],
[
'slug' => 'other-integrations',
'title' => 'SMS, Radio & Meshtastic',
'body' => '
<p>Depending on your configuration, you may also have access to:</p>
<ul>
<li><strong>SMS messaging</strong> — Send text messages to responders or contacts.</li>
<li><strong>DMR radio messaging</strong> — Send text messages over digital radio.</li>
<li><strong>Meshtastic</strong> — Send messages over LoRa mesh networks.</li>
<li><strong>Zello push-to-talk</strong> — Voice and text messaging over Zello channels.</li>
<li><strong>Slack</strong> — Forward notifications to Slack channels.</li>
</ul>
<p>These are configured in Settings > Communications.</p>
'
],
[
'slug' => 'notification-rules',
'title' => 'Notification Rules (alerts by email, text and chat)',
'body' => '
<p>A <strong>notification rule</strong> tells people when something happens in the CAD: <em>when</em> a unit is dispatched (or a new incident is created, an incident is closed, a high-alert incident appears...), <em>send</em> this message by email, text, chat, push, or to a Slack/Telegram channel. Only a <strong>Super Admin</strong> can create or change rules, because they send mail and texts as the agency.</p>
<p>Open <strong>Settings > Communications & Integrations > Notification Rules</strong>.</p>
<h6>Making a rule</h6>
<ol>
<li>Choose <strong>New rule</strong>, or <strong>From template</strong> (Active911 StandardA or Cadpage, email supervisors on a high-alert incident, post every new incident to Slack).</li>
<li><strong>When</strong> — pick the event; optionally narrow it to one severity level or incident type.</li>
<li><strong>Who and where</strong> — pick the channel, then add people, email addresses, mobile numbers or an email list. A warning icon means that person has no address or number on file for the channel.</li>
<li><strong>Message</strong> — leave blank for the default, or write your own. Field buttons like <code>{street}</code> insert values; <code>{street|clean}</code> strips semicolons and line breaks for one-line formats.</li>
<li><strong>Review</strong> shows the message and every delivery it would make, and which it would skip, without sending anything.</li>
<li><strong>Send a test to me</strong>, then <strong>Save</strong>.</li>
</ol>
<h6>Good to know</h6>
<ul>
<li><strong>Only the first time for each incident</strong> pages once per call instead of once per unit dispatched.</li>
<li>Messages go into a queue and are sent by the scheduled job within a minute; a failed delivery is retried until it is too late to matter, then marked Expired. The <strong>Delivery log</strong> shows what happened to every message and why.</li>
<li>A high-alert incident always gets through, whatever a person\'s preferences or quiet hours say.</li>
<li>A security label on an incident can block or delay a rule\'s message, the same way it does for Message Routing.</li>
<li><strong>Send a test to the real recipients</strong> asks first — a pager or Active911 address pages real devices.</li>
</ul>
<p><strong>Not the same as:</strong> Message Routing (copies traffic between channels and radios) or Webhooks (sends events to other software).</p>
<p>See the <a href="documentation/?doc=NOTIFICATION-RULES" target="_blank">Notification Rules guide</a> for the Active911 recipes, the list of events and fields, and troubleshooting.</p>
'
],
[
'slug' => 'email-lists',
'title' => 'Email Distribution Lists',
'body' => '
<p>An <strong>email list</strong> is a named group of recipients that a <a href="documentation/?doc=NOTIFICATION-RULES" target="_blank">Notification Rule</a> can send to. Notification Rules are the only thing that reads a list, and the list is read each time the rule fires. Super Admin only: <strong>Settings > Communications & Integrations > Email Lists</strong>.</p>
<h6>Adding people</h6>
<p>Choose <strong>Manage</strong>, pick <strong>Member</strong>, <strong>Contact</strong>, <strong>Sub-list</strong> or <strong>Email address</strong>, then search and press <strong>Enter</strong>. A member or contact with no email address can still be added (the button says so) and is marked <em>No email address</em> with a link to fix the record.</p>
<h6>What the window tells you</h6>
<ul>
<li>The top line says how many unique addresses the list resolves to right now, and what needs attention.</li>
<li>Entries with a problem are listed first, each with a status: no email, deleted member, archived sub-list, a loop, skipped because of the member\'s status, or opted out of email.</li>
<li><strong>Preview recipients</strong> shows exactly who would receive a message, and who would not and why.</li>
</ul>
<h6>List options</h6>
<p>Choose which member statuses are left out (Suspended and Retired by default, when your install has them), and whether a member or contact with no email may be added at all.</p>
<p>More detail in the <a href="documentation/?doc=NEWUI-USER-GUIDE#managing-email-distribution-lists" target="_blank">user guide</a>.</p>
'
],
[
'slug' => 'comms-console',
'title' => 'Communications Console',
'body' => '
<p>The <strong>Console</strong> page (navbar > Console) shows every configured communications channel as a vertical <strong>channel strip</strong> — Zello channels, DMR talkgroups, Meshtastic, local chat, weather alerts, and more. Each strip has a status light (green connected / amber degraded / red down / grey unknown), the last caller and how long ago they were heard, and the controls that channel supports.</p>
<ul>
<li><strong>Voice channels</strong> (Zello, DMR) — a button opens the matching radio widget for listening and push-to-talk, plus a <strong>Sel</strong> button, <strong>Mon</strong>/<strong>Mute</strong> toggles, and a <strong>Volume</strong> slider.</li>
<li><strong>Text channels</strong> — a Messages drawer shows recent traffic and lets you send directly onto the channel, plus a <strong>Sel</strong> button.</li>
<li><strong>Feeds</strong> (weather alerts, event bus) — read-only activity drawers, plus a <strong>Sel</strong> button.</li>
</ul>
<p><strong>Select / Monitor / Mute / Volume:</strong> click <strong>Sel</strong> on a channel to mark it as the one you’re actively working — every other voice channel then drops to a quieter background level, exactly like a commercial dispatch console. Until you select anything, nothing is de-prioritized. On voice channels, <strong>Mon</strong> (default ON) controls whether an unselected channel still plays quietly in the background at all; <strong>Mute</strong> silences it outright; <strong>Volume</strong> is a per-channel ceiling. Text channels use Select/Mute for visual prominence (highlight + auto-open feed / suppress the new-message flash) instead of a literal volume — a missed message is never silenced by another channel being selected. Check the <strong>Sim</strong> box on a TX-capable strip to add it to the simulselect paging set, then hold the <strong>Simulselect PTT</strong> button (appears above the strip bank) to transmit on every selected channel at once.</p>
<p><strong>Views:</strong> administrators can author named <em>shared</em> layouts everyone sees, in the <strong>Console Designer</strong> (Design Views button) — pick which channels appear, their order, colors, labels, and controls. Published shared views appear as tabs for every dispatcher; the built-in <em>All Channels</em> tab always shows everything enabled. Your last-used tab is remembered per browser.</p>
<p><strong>Personal views:</strong> any dispatcher can build their own layout too — click <strong>My Views</strong> (shown instead of Design Views if you don’t hold the admin permission) to open the same designer scoped to your own views. Build from scratch or clone an existing shared/personal view. Mark a personal view <strong>Shared</strong> to let other operators clone it for themselves — it never becomes a tab on their console automatically.</p>
<p>Access requires the <code>screen.console</code> permission; transmitting requires <code>action.console_tx</code>; authoring <em>shared</em> views requires <code>console.design</code>. Your own personal views need no extra permission.</p>
<p>An <strong>AMATEUR</strong> badge on a channel strip means FCC station-ID rules apply — see the <a href="documentation/?doc=FCC-STATION-ID-COMPLIANCE" target="_blank">FCC station-ID compliance guide</a> for the radio widget’s countdown, Monitoring ID, and End conversation controls.</p>
'
],
[
'slug' => 'browser-phone',
'title' => 'Browser Phone',
'body' => '
<p>If your administrator has connected a phone system (an Asterisk PBX), you can place and answer calls from the browser with a headset — nothing to install. Click the <i class="bi bi-telephone"></i> <strong>phone</strong> button in the navigation bar. On the <strong>Console</strong> it opens the floating phone; on any other page it opens the <strong>Phone window</strong>, a small window that <em>keeps ringing while you work in other tabs</em>. Open it once at the start of a shift and leave it open. Your phone only receives calls while one of these is open — moving between ordinary pages does not keep it registered.</p>
<ul>
<li><strong>Answering:</strong> an incoming call shows the caller with <strong>Answer</strong> focused — press <kbd>Enter</kbd>. When the phone system tags the call, answering here <em>also</em> claims it in the ringing-call banner and opens the New Incident form in a new tab (and clicking <strong>Answer</strong> in the banner answers the audio in the phone) — one click either way.</li>
<li><strong>Dialing:</strong> type a number and press <kbd>Enter</kbd>, use the keypad, or the general-number button.</li>
<li><strong>The footer line</strong> tells you what is wrong in words: a blocked microphone, a page that is not secure (https), a certificate this browser has not yet trusted, a wrong password, a lost connection.</li>
<li><strong>Not bound?</strong> Open the Console and click <strong>Phone token</strong> in the workstation bar, and give the token to an administrator to bind to your extension.</li>
</ul>
<p>Callers are looked up (and added) in <strong>Contacts</strong> however their number is written, so a repeat caller finds their history. The incident page’s optional <strong>Relay test page</strong> button is a <em>simulated</em> test of the relay path, not AllStarLink — it is off unless an administrator enables it. See the <a href="documentation/?doc=PHONE-TELEPHONY-GUIDE" target="_blank">Browser Phone guide</a> for setup and what has and has not been verified.</p>
'
],
[
'slug' => 'digital-voice-bridges',
'title' => 'Digital Voice Bridges (P25 / DMR)',
'body' => '
<p>If your administrator has connected one, a <strong>digital voice bridge</strong> channel brings a P25, DMR or analog talkgroup onto the Console from a bridge program (for example DVMProject’s <code>dvmbridge</code>). It appears as an ordinary channel strip with one difference: <strong>it is listen-only</strong>.</p>
<ul>
<li>The strip says <strong>Listen-only · P25 · TG …</strong> and has <strong>no PTT button</strong>. Nothing you press can transmit on it.</li>
<li>Tick <strong>Listen</strong> on the strip to hear it. You do not need Console Transmit permission to listen, and your browser is not asked for the microphone unless you hold that permission.</li>
<li>The <strong>RX</strong> lamp lights while audio is arriving. The status light stays grey (<em>unknown</em>) unless the optional network link check is connected — a quiet channel is never shown as connected.</li>
<li>Its audio can be patched <em>out</em> to other channels; nothing can be patched <em>into</em> it.</li>
</ul>
<p><strong>Administrators:</strong> open <strong>Settings > Communications & Integrations > Digital Voice Bridges</strong> (permission <code>action.manage_voice_bridges</code>). A DVMProject channel needs a recorded acknowledgment of the DVMProject usage-policy statement first — DVMProject’s own guidelines say its software is not intended for public-safety or dispatch use, and the decision to use it is yours. The statement is shown on that page. TicketsCAD bundles no DVMProject software and no vocoder. This feature has been tested against simulators only, not a live DVMProject network. See the <a href="documentation/?doc=DIGITAL-VOICE-USRP" target="_blank">Digital Voice Bridges guide</a>.</p>
'
],
[
'slug' => 'weather-alerts',
'title' => 'Weather Alerts (NWS)',
'body' => '
<p>If your administrator has enabled it, TicketsCAD can surface <strong>National Weather Service</strong> watches and warnings for your area. When a matching alert is issued you will see a <i class="bi bi-cloud-lightning-rain-fill text-danger"></i> card in the notification tray (bell icon) with an audible chime, and a banner on the Situation view.</p>
<p>Weather alerts are <strong>off by default</strong> and configured per-install. Administrators set coverage areas (a state, forecast zones, or a point + radius) and routing rules (which severity of alert goes where) at <strong>Settings > Communications & Integrations > Weather Alerts</strong>. Later phases can route alerts to chat/SMS/email and read severe warnings out over DMR/Zello radio.</p>
<p>See the <a href="documentation/?doc=WEATHER-ALERTS-GUIDE" target="_blank">Weather Alerts administrator guide</a> for setup.</p>
'
],
[
'slug' => 'public-incident-board',
'title' => 'Public Incident Board',
'body' => '
<p>If your administrator has enabled it, TicketsCAD can publish a credential-free, read-only board of currently active incidents — for a public website or a lobby display. This is <strong>off by default</strong> and most agencies will never turn it on.</p>
<p><strong>Nothing new to configure per-incident.</strong> The board respects whatever Security Label is already applied to an incident — a call marked with a label that disallows broadcast simply never appears on the public board, the same way it is already kept off other broadcast-facing surfaces. Apply Security Labels the way you normally would for a sensitive call and this is handled automatically.</p>
<p>Administrators can also mark specific incident <em>types</em> (not individual incidents) as never publishing, or as showing only a generic label with no address — a one-time setup decision, not something chosen per call.</p>
<p>Address detail is capped by a board-wide precision setting (exact / street-only / city-only / hidden) configured at <strong>Settings > Communications & Integrations > Public Board</strong>. Not sure whether the board is currently enabled? Check <strong>Settings > System Health</strong>, which reports its status.</p>
<p>The board’s map shows OpenStreetMap unless an administrator enters a different public tile address on that same page (<strong>Map tiles for the public board</strong>). That address is shown to every visitor, so it must never contain an API key, token or password, and it should not be an internal server — visitors’ browsers fetch tiles from it directly. The main <strong>Tile Providers</strong> settings and TicketsCAD’s tile proxy are never used for the public board.</p>
<p>See <code>docs/PUBLIC-INCIDENT-BOARD.md</code> in the repository for the full setup and security details.</p>
'
],
],
],
'personnel' => [
'icon' => 'bi-person-badge',
'label' => 'Personnel',
'topics' => [
[
'slug' => 'roster',
'title' => 'The Roster',
'body' => '
<p>Click <strong>Personnel > Roster</strong> to manage all members. The page has a two-column layout:</p>
<ul>
<li><strong>Left:</strong> Searchable, filterable member list with count badge.</li>
<li><strong>Right:</strong> Detail panel for the selected member.</li>
</ul>
<h6>Searching and Filtering</h6>
<ul>
<li>Search by name, callsign, phone, or email.</li>
<li>Filter by status (Active/Inactive), team, or member type.</li>
</ul>
<h6>Adding a Member</h6>
<ol>
<li>Click <strong>New Member</strong>.</li>
<li>Fill in name, contact details, member type, status.</li>
<li>Click <strong>Save</strong>.</li>
</ol>
<h6>Assigning Teams</h6>
<p>Open a member's detail panel and expand the <strong>Team
Memberships</strong> card. It lists every team the member belongs to (a
member can belong to more than one). If your account can manage teams:</p>
<ul>
<li>Use the <strong>Add to Team</strong> control at the bottom of the
card to assign the member to another team, with a role (Member,
Leader, Deputy, Observer).</li>
<li>Click the <i class="bi bi-x-lg"></i> button on any row to remove
the member from that team.</li>
</ul>
<p class="small text-body-secondary">Team assignment lives entirely here
and on the <strong>Teams</strong> tab — both write to the same place,
so a change made on either page shows up on the other immediately. For
finer control (ICS position, assigned date, notes), use the
<strong>Teams</strong> tab.</p>
<h6>Removing Members</h6>
<p>Delete one member from the detail panel's <strong>Delete</strong>
button (soft delete — the member moves to the Wastebasket and can be
restored).</p>
<p>If your account holds the <strong>Bulk Delete Members</strong> permission,
a checkbox column appears at the right edge of the roster table with a
select-all box in the header:</p>
<ol>
<li>Tick the members to remove (or use the header box to select every
member currently shown).</li>
<li>In the bulk-actions bar, click <strong>Delete Selected</strong>.</li>
<li>Confirm in the dialog. Removed members go to the Wastebasket (soft
delete); up to 500 per request.</li>
</ol>
<p class="small text-body-secondary">The selection persists as you change the
search/filter, so a bulk delete can span members from more than one filter
view — use <strong>Clear</strong> to reset. The checkbox column only
appears for accounts with the Bulk Delete Members permission (Super Admin by
default; an admin can grant it to other roles under Config » Roles).</p>
'
],
[
'slug' => 'teams',
'title' => 'Teams',
'body' => '
<p>Click <strong>Personnel > Teams</strong>. Each team has a name, NIMS resource type, members, and description.</p>
<p>Use teams to organize members into functional groups (e.g., "Engine 1 Crew," "CERT Alpha," "Net Control").</p>
'
],
[
'slug' => 'certifications',
'title' => 'Certifications & Training',
'body' => '
<p>Each member can have certifications (EMT, HAZMAT, CPR, etc.) and training records (ICS-100, FEMA IS-700, etc.) attached to their profile.</p>
<ul>
<li>Certifications have issue and expiration dates for renewal tracking.</li>
<li>Types are configured by your administrator under Config > Personnel.</li>
</ul>
'
],
[
'slug' => 'scheduling',
'title' => 'Scheduling',
'body' => '
<p>Click <strong>Personnel > Scheduling</strong>. Two types of time management are supported:</p>
<h6>Shifts</h6>
<ul>
<li>View and manage recurring shift patterns.</li>
<li>See who is on duty at any given time.</li>
<li>Assign members to specific shifts.</li>
</ul>
<h6>Events</h6>
<ul>
<li>Create one-time or recurring events (training, meetings, community events).</li>
<li>Define time slots with specific roles needed.</li>
<li>Members can self-sign up for available slots.</li>
</ul>
'
],
[
'slug' => 'fcc-lookup',
'title' => 'FCC Callsign Lookup',
'body' => '
<p>When adding a member with an amateur radio or GMRS license:</p>
<ol>
<li>Enter the callsign in the lookup field.</li>
<li>Click <strong>Lookup</strong> to query the FCC database.</li>
<li>If found, click <strong>Apply to Form</strong> to auto-fill name and license details.</li>
</ol>
<p>Works for both amateur radio and GMRS callsigns.</p>
<p>The lookup source is set under <em>Settings → Lookup Services</em>. The default,
<strong>OpenCallbook</strong>, is a free public service that covers both the amateur
and GMRS databases. Other choices are a local offline copy of the FCC data, the
amateur-only callook.info, or a self-hosted FCC-ULS-API. You can also choose how much
detail an internet lookup service is told about who is querying (the User-Agent).</p>
'
],
],
],
'reports' => [
'icon' => 'bi-bar-chart-line',
'label' => 'Reports',
'topics' => [
[
'slug' => 'search-incidents',
'title' => 'Searching Past Incidents',
'body' => '
<p>Click <strong>Search</strong> in the navigation bar. Filter by:</p>
<ul>
<li>Text search (scope, description, address, caller info)</li>
<li>Incident type, status, severity</li>
<li>Date range</li>
</ul>
<p>Results appear in a sortable table. Click any row to view the incident.</p>
'
],
[
'slug' => 'generating-reports',
'title' => 'Generating Reports',
'body' => '
<p>Click <strong>Reports</strong> in the navigation bar. Available reports include:</p>
<ul>
<li><strong>Incident Summary</strong> — Counts by type, severity, or time period.</li>
<li><strong>Response Time Analysis</strong> — Dispatch-to-on-scene times.</li>
<li><strong>Unit Activity</strong> — Hours, incidents, mileage per unit.</li>
<li><strong>Daily/Weekly/Monthly Activity</strong> — Volume over time.</li>
</ul>
<p>All reports can be filtered by date range, type, unit, and other criteria.</p>
'
],
[
'slug' => 'ics-213-export',
'title' => 'ICS-213 Export',
'body' => '
<p>Export incident data as ICS-213 (General Message) forms compatible with Winlink:</p>
<ol>
<li>Open the Incident Detail view.</li>
<li>Click the <strong>ICS-213</strong> export button.</li>
<li>Download the generated XML file.</li>
<li>Import it into Winlink Express or Pat for radio transmission.</li>
</ol>
'
],
[
'slug' => 'ics-forms',
'title' => 'ICS Forms (FEMA)',
'body' => '
<p>The <strong>ICS Forms</strong> page (menu, or <code>/ics</code>) has every form in the FEMA NIMS ICS Forms Booklet, laid out as FEMA lays them out: the same blocks, block numbers, titles, order and columns, with FEMA’s instruction under each block and FEMA’s heading, signature lines and footer on the printout.</p>
<ul>
<li><strong>Find a form</strong> — type a number or word (“205”, “medical”) and press <kbd>Enter</kbd> to open the first match; <kbd>Esc</kbd> clears it.</li>
<li><strong>Link to Incident</strong> — fills in the incident name and number, the date and time prepared, the operational period start and form-specific details. Nothing you typed is overwritten.</li>
<li><strong>ICS 214</strong> works for one person or a whole unit: list the people with you in block 6. The pre-2010 ICS 214a is kept only for logs already saved.</li>
<li><strong>Signature lines</strong> print blank, to be signed by hand.</li>
<li>Forms saved before October 2026 open with their values in the corrected FEMA fields; fields FEMA does not have are marked <em>earlier version</em>. Nothing saved was lost.</li>
</ul>
<p>The full list and the notes for older forms are in the <a href="documentation/?doc=ICS-FORMS" target="_blank">ICS Forms guide</a>.</p>
'
],
[
'slug' => 'import-export',
'title' => 'Import & Export',
'body' => '
<p>The Import/Export page (Config > System > Import / Export) allows:</p>
<ul>
<li><strong>Exporting</strong> incidents, members, facilities to CSV or JSON.</li>
<li><strong>Importing</strong> data from CSV with column mapping and preview.</li>
<li><strong>Legacy migration</strong> from Tickets v3.x.</li>
</ul>
'
],
],
],
'configuration' => [
'icon' => 'bi-gear',
'label' => 'Configuration',
'topics' => [
[
'slug' => 'settings-overview',
'title' => 'Settings Overview',
'body' => '
<p>The Settings page (admin only) has a sidebar with 9 sections:</p>
<table class="table table-sm table-bordered">
<thead><tr><th>Section</th><th>Contains</th></tr></thead>
<tbody>
<tr><td>System</td><td>Health dashboard, Audit Log, Import/Export.</td></tr>
<tr><td>Installation</td><td>System Settings, API Keys, Lookup Services, Database Info, Backup.</td></tr>
<tr><td>App Preferences</td><td>Incident Types, Severity, Signals, Unit Statuses, Facility Types, Display, Sound, Numbering.</td></tr>
<tr><td>Users</td><td>Accounts, Roles, Login Settings, 2FA, Encryption.</td></tr>
<tr><td>Personnel</td><td>Organizations, Members, Teams, Certs, ICS Positions, Equipment, Vehicles, Training.</td></tr>
<tr><td>Communications</td><td>Notifications, Email, SMS, Slack, Radio, Zello, Meshtastic, Webhooks, Chat.</td></tr>
<tr><td>Locations</td><td>Facilities, Regions, Places, Road Conditions.</td></tr>
<tr><td>Maps</td><td>Map Defaults, Tile Providers.</td></tr>
<tr><td>Location Tracking</td><td>APRS, Meshtastic, OwnTracks, DMR, Zello providers, Geofencing.</td></tr>
</tbody>
</table>
'
],
[
'slug' => 'agency-logo',
'title' => 'Agency Logo & Branding',
'body' => '
<p>Show <strong>your agency’s own logo</strong> instead of the generic radio-tower icon, and as a letterhead on what you print. Nothing changes until a logo is uploaded.</p>
<p>Set it up at <strong>Settings → Application — Presentation → Agency Logo & Branding</strong>. The page needs the <em>Manage Agency Branding</em> permission (Super Admin), or <em>Manage Own Org’s Logo</em> (Org Admin, your own organization only).</p>
<ol>
<li>Choose a <strong>PNG or JPEG</strong> file (up to 2 MB) in the <strong>For light backgrounds</strong> slot and click <strong>Upload</strong>. SVG is not accepted — export your logo as a PNG.</li>
<li>Check the <strong>Live preview</strong>: the sign-in card (with a Day/Night toggle), the top bar and a printed page. Nothing is saved until you click Upload or Save.</li>
<li>Optional: add a second image <strong>For dark backgrounds</strong>. Without one, dark theme puts your logo on a white plate.</li>
<li>Optional: under <strong>Where it appears</strong>, turn individual places on or off and pick sizes, then click <strong>Save settings</strong>.</li>
</ol>
<table class="table table-sm table-bordered">
<thead><tr><th>Where</th><th>What shows</th></tr></thead>
<tbody>