Loading...
{{ adminStats.total||0 }}
Total
{{ adminStats.pending||0 }}
Pending
{{ adminStats.approved||0 }}
Approved
{{ adminStats.totalKids||0 }}
Total Kids
RM {{ adminStats.revenue||0 }}
Revenue
Workshop Date & Time
{{ dayOfWeek(viewingApp.workshop_date) }}, {{ viewingApp.workshop_date || 'N/A' }} · {{ viewingApp.workshop_time || '' }}
Status
{{ viewingApp.status }}Parent / Guardian Information
Participants ({{ viewingApp.num_participants }})
{{ p.name }}
Age: {{ p.age }} · Gender: {{ p.gender }}
Payment Details
Registration Fee
RM {{ parseFloat(Number(viewingApp.total_fee) + Number(viewingApp.voucher_discount || 0)) }}
Voucher Discount
− RM {{ parseFloat(viewingApp.voucher_discount) }} ({{ viewingApp.voucher_code }})
{{ viewingApp.voucher_discount > 0 ? 'Amount Due' : 'Registration Fee' }}
AI Detected Amount
{{ viewingApp.extracted_amount || '-' }}
Payment Evidence
View PDF Receipt
{{ viewingApp.payment_slip_path }}· {{ viewingApp.payment_slip_size }}
{{ viewingApp.payment_slip_size }}
No evidence uploaded
How Did They Hear About Us
Submitted At
{{ viewingApp.created_at }}
Last Updated
{{ viewingApp.updated_at }}
Admin Notes
Parent / Guardian *
Emergency Contact *
Participants ({{ newReg.participants.length }})
Auto: RM {{ newRegAutoFee }}
{{ addRegError }}
{{ filteredParticipants.length }}
Total
{{ filteredParticipants.filter(p=>Number(p.checked_in)).length }}
Checked In
{{ filteredParticipants.filter(p=>p.interview_story).length }}
Interviewed
{{ filteredParticipants.filter(p=>p.cartoon_image_path||p.creation_image_path).length }}
Wallpapers
{{ filteredParticipants.filter(p=>Number(p.is_active)===0).length }}
Deactivated
| # | Participant | Workshop Date | Guardian | Check-in | Active | Actions |
|---|---|---|---|---|---|---|
| {{ p.id }} |
{{ (p.name||'?')[0] }}
{{ p.name }}
{{ p.age }} yrs · {{ p.gender||'—' }}
{{ p.app_status }}
|
{{ dayOfWeek(p.workshop_date) }} {{ p.workshop_date }} N/A |
{{ p.guardian_name }}
{{ p.guardian_mobile }}
|
|||
| No participants found | ||||||
| ID | Day | Date | Time | Max Seats | Active | Actions |
|---|---|---|---|---|---|---|
| {{ d.id }} | {{ dayOfWeek(d.workshop_date) || '—' }} |
📅 {{ dayOfWeek(newDate.workshop_date) }}
English
Chinese
Malay
Tamil
English
Chinese
Malay
Tamil
Create discount voucher codes for registrants. Set discount (RM) per participant count. Enter 0 = no discount for that tier. Max Uses = 0 means unlimited.
| Code | Discount → Final Price | Description | Uses | Status | |
|---|---|---|---|---|---|
| {{ v.code }} |
{{ t }}p:
RM{{ getBasePrice(t) }}
→ RM{{ getDiscountedPrice(t, v['discount_'+t]) }}
(−RM{{ Number(v['discount_'+t]).toFixed(0) }})
—
|
{{ v.description || '—' }} | {{ v.used_count }}/{{ v.max_uses==0?'∞':v.max_uses }} |
|
|
| No voucher codes yet | |||||
| Participants | Registration Fee | Voucher Discount | Fee After Discount |
|---|---|---|---|
| {{ t }} {{ t > 1 ? 'participants' : 'participant' }} | RM {{ getBasePrice(t) }} | {{ Number(v['discount_'+t]) > 0 ? '− RM ' + Number(v['discount_'+t]).toFixed(0) : '—' }} | RM {{ Number(v['discount_'+t]) > 0 ? getDiscountedPrice(t, v['discount_'+t]) : getBasePrice(t) }} |
Control how strict the face scan must be before granting station access. A stricter setting requires a closer match but reduces false identifications.
| # | Step Name | Time Limit (min) |
|---|---|---|
| {{ i + 1 }} | {{ STEP_LABELS[s.step_key] || s.step_key }} |
| # | TIME | ELAPSED | STATION | TASK | ACTION | PTS | |
|---|---|---|---|---|---|---|---|
| {{ li+1 }} | {{ formatLogTime(log.created_at) }} | {{ logElapsed(activityLogModal.participant?.checked_in_at, log.created_at) }} | S{{ log.station }} | {{ log.task_label }} | {{ log.event_type==='delete' ? 'DELETED' : log.event_type==='modify' ? 'MODIFIED' : log.task_key?.includes('_start') ? 'ARRIVED' : 'COMPLETED' }} | {{ log.event_type==='delete' && log.points > 0 ? '-'+log.points : log.points > 0 ? '+'+log.points : '' }} |