Loading…
{{ pendingCount }} pending registration{{ pendingCount > 1 ? 's' : '' }} awaiting approval
Review →
📢 Announcements
No announcements.
Total Events
{{ events.length }}
Active Now
{{ activeEvents.length }}
My Hours
{{ totalHours }}
Events Attended
{{ uniqueEventsCount }}
0?'pending-users':'users')">
Members ({{ pendingCount }} pending)
{{ users.length }}
Active Events
No active events right now.
{{ ev.name }}
{{ ev.currently_present }} checked in
Upcoming
{{ ev.name }}
{{ ev.event_type_name }}
Upcoming
No events.
No check-ins found.
📅 {{ group.event_name }} — {{ group.date }}
| Member | Role | Checked In | Checked Out | Duration | |
|---|---|---|---|---|---|
{{ initials(ci.user_name) }} {{ ci.user_name }} |
{{ ci.user_roles||'—' }} | {{ fmtDatetime(ci.checked_in_at) }} | {{ ci.checked_out_at?fmtDatetime(ci.checked_out_at):'—' }} | {{ duration(ci.checked_in_at,ci.checked_out_at) }} |
|
| Member | Roles | Event | Checked In | Checked Out | Duration | |
|---|---|---|---|---|---|---|
{{ initials(ci.user_name) }} {{ ci.user_name }} |
{{ ci.user_roles||'—' }} | {{ ci.event_name||eventNameById(ci.event_id) }} | {{ fmtDatetime(ci.checked_in_at) }} | {{ ci.checked_out_at?fmtDatetime(ci.checked_out_at):'—' }} | {{ duration(ci.checked_in_at,ci.checked_out_at) }} |
|
Select an event above to view its report.
{{ eventReport.parentName || eventReport.event.name }}
Multi-Day Event Summary
Sessions
{{ eventReport.children.length }}
Total Attendees
{{ Object.keys(eventReport.memberTotals).length }}
Total Hours
{{ minsToHours(eventReport.grandTotalMins) }}
| Member | Sessions | Total Hours |
|---|---|---|
| {{ name }} | {{ mt.sessions }} | {{ minsToHours(mt.minutes) }} |
Date
{{ fmtDate(eventReport.children[eventReport.activeChildIdx].event.event_date)||'—' }}
Attendees
{{ eventReport.children[eventReport.activeChildIdx].attendees.length }}
Total Hours
{{ minsToHours(eventReport.children[eventReport.activeChildIdx].total_minutes) }}
| Member | Role | Check In | Check Out | Hours |
|---|---|---|---|---|
| {{ a.name }} | {{ a.roles||'—' }} | {{ fmtDatetime(a.first_in) }} | Still present{{ fmtDatetime(a.last_out) }} | {{ minsToHours(a.total_minutes) }} (running) |
Date
{{ fmtDate(eventReport.event.event_date) }}
Attendees
{{ eventReport.attendees.length }}
Total Hours
{{ minsToHours(eventReport.total_minutes) }}
Still Present
{{ eventReport.attendees.filter(a=>a.still_present>0).length }}
| Member | Roles | Check In | Check Out | Hours |
|---|---|---|---|---|
| {{ a.name }} | {{ a.roles||'—' }} | {{ fmtDatetime(a.first_in) }} | Still present{{ fmtDatetime(a.last_out) }} | {{ minsToHours(a.total_minutes) }} (running) |
1
Import Events
Paste or upload a CSV. Columns:
Name, Date (YYYY-MM-DD), Start Time (HH:MM), End Time (HH:MM), Location, Event Type{{ eventImportParsed.length }} events ready
| Name | Date | Time | Location | Type |
|---|---|---|---|---|
| {{ e.name }} | {{ fmtDate(e.event_date) }} | {{ e.start_time }}–{{ e.end_time }} | {{ e.location||'—' }} | {{ e.event_type||'—' }} |
Results: {{ eventImportResults.filter(r=>r.status==='imported').length }} imported, {{ eventImportResults.filter(r=>r.status==='skipped').length }} skipped, {{ eventImportResults.filter(r=>r.status==='error').length }} errors
{{ r.status==='imported'?'✓':r.status==='skipped'?'—':'✗' }}
{{ r.name }} {{ fmtDate(r.event_date) }}
ID: {{ r.id }}
{{ r.error }}
2
Import Check-ins
Columns:
Member Email (or First Last), Role, Check-in Time (YYYY-MM-DD HH:MM), Check-out Time{{ checkinImportParsed.length }} check-ins ready
| Event | Member | Role | Check-in | Check-out |
|---|---|---|---|---|
| {{ c.event_name }} | {{ c.member }} | {{ c.role||'—' }} | {{ c.checked_in_at }} | {{ c.checked_out_at||'—' }} |
Results: {{ checkinImportResults.filter(r=>r.status==='imported').length }} imported, {{ checkinImportResults.filter(r=>r.status==='error').length }} errors
{{ r.status==='imported'?'✓':'✗' }}
{{ r.member }} @ {{ r.event_name }}
{{ r.error }}
{{ approvedUsers.length }} member{{ approvedUsers.length===1?'':'s' }}
No members match.
No pending members.
No credentials assigned yet.
Forms module coming soon.
Documents module coming soon.
No events available.
{{ ev.name }}
{{ ev.description }}
{{ ev.currently_present }} attending
No attendance history yet.
Events attended
{{ uniqueEventsCount }}
Hours logged
{{ totalHours }}
Active now
{{ myOpenCheckins.length }}
{{ collapsedHistory[group.label] ? '▶' : '▼' }}
{{ group.label }}
{{ group.checkins.length }} session{{ group.checkins.length===1?'':'s' }}
{{ fmtDate(group.latestDate) }}
{{ ci.parent_event_name ? ci.event_name : ci.event_name }}
{{ fmtDatetime(ci.checked_in_at) }}
· Out {{ fmtDatetime(ci.checked_out_at) }} · {{ duration(ci.checked_in_at,ci.checked_out_at) }}
Active
{{ collapsedHistory['__time_entries__'] ? '▶' : '▼' }}
Manual Time Entries
{{ myTimeEntries.length }}
{{ te.description }}
{{ fmtDate(te.entry_date) }} · {{ te.start_time }}–{{ te.end_time }} · {{ minsToHours(te.minutes) }}
{{ collapsedHistory['__credentials__'] ? '▶' : '▼' }}
Credentials
{{ myCredentials.length }}
{{ cr.name }}
Issued: {{ fmtDate(cr.issued_date) }}
· Expires: {{ fmtDate(cr.expiry_date) }}
· {{ cr.hours_worth }}h training
hours excluded
{{ cr.notes }}
No data yet.
| Member | Role | Events | Total Hours |
|---|---|---|---|
| {{ r.name }} | {{ r.role||'—' }} | {{ r.event_count || '—' }} | {{ minsToHours(r.total_minutes) }} |
| {{ reportHoursRoleMember ? reportHoursRoleDrilldown[0].name : 'All members' }} {{ reportHoursRoleYear === 'all' ? 'All time' : reportHoursRoleYear }} | {{ minsToHours(reportHoursRoleDrilldown.reduce((s,r)=>s+r.total_minutes,0)) }} | ||
No data yet.
Select a member to view their attendance history.
Events attended
{{ memberHistoryEventsCount }}
Hours
{{ minsToHours(memberHistoryFilteredMins) }}
Credentials
{{ memberHistoryCredentials.length }}
{{ collapsedMemberHistory['__credentials__'] ? '▶' : '▼' }}
Credentials
{{ memberHistoryCredentials.length }}
{{ cr.name }}
Issued: {{ fmtDate(cr.issued_date) }}
· Expires: {{ fmtDate(cr.expiry_date) }}
· {{ cr.hours_worth }}h training
hours excluded
{{ cr.notes }}
{{ yrGroup.year }}
{{ minsToHours(Math.round(yrGroup.checkins.filter(c=>c.checked_out_at).reduce((s,c)=>s+Math.round((new Date(c.checked_out_at)-new Date(c.checked_in_at))/60000),0))) }}
{{ collapsedMemberHistory[yrGroup.year+':'+group.label] ? '▶' : '▼' }}
{{ group.label }}
{{ group.checkins.length }}
{{ fmtDate(group.latestDate) }}
{{ ci.event_name }}
{{ fmtDatetime(ci.checked_in_at) }}
· Out {{ fmtDatetime(ci.checked_out_at) }} · {{ duration(ci.checked_in_at,ci.checked_out_at) }}
Active
{{ ci.user_roles }}
{{ collapsedMemberHistory[group.label] ? '▶' : '▼' }}
{{ group.label }}
{{ group.checkins.length }} session{{ group.checkins.length===1?'':'s' }}
{{ fmtDate(group.latestDate) }}
{{ ci.event_name }}
{{ fmtDatetime(ci.checked_in_at) }}
· Out {{ fmtDatetime(ci.checked_out_at) }} · {{ duration(ci.checked_in_at,ci.checked_out_at) }}
Active
{{ ci.user_roles }}
{{ collapsedMemberHistory['__time_entries__'] ? '▶' : '▼' }}
Manual Time Entries
{{ memberHistoryTimeEntries.length }}
{{ te.description }}
{{ fmtDate(te.entry_date) }} · {{ te.start_time }}–{{ te.end_time }} · {{ minsToHours(te.minutes) }}
No attendance records for this member.
No members or credentials found.
| Member | {{ cr.name }} |
|---|---|
| {{ m.member_name }} | ✓ — |
Define the types of equipment that can be issued to members.
No equipment items defined yet.
All equipment currently issued to members.
No equipment issued yet.
{{ timeEntries.length }} entr{{ timeEntries.length===1?'y':'ies' }}
No manual time entries yet.
| Member | Description | Date | Start | End | Duration | Added by | |
|---|---|---|---|---|---|---|---|
| {{ te.member_name }} | {{ te.description }} | {{ fmtDate(te.entry_date) }} | {{ te.start_time }} | {{ te.end_time }} | {{ minsToHours(te.minutes) }} | {{ te.created_by_name }} |
|
No manual time entries yet.
| Member | Entries | Total Hours |
|---|---|---|
| {{ r.name }} | {{ r.entry_count }} | {{ minsToHours(r.total_minutes) }} |
{{ initials(auth.name) }}
{{ auth.name }}
{{ auth.email }}
Account
Contact & Details
Radio
{{ profileForm.gmrs_callsign||'—' }}
{{ profileForm.ham_callsign||'—' }}
{{ profileForm.tactical_callsign||'—' }}
Call signs are managed by Command Staff. Contact an admin to update.