Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
74.12% covered (warning)
74.12%
63 / 85
54.55% covered (warning)
54.55%
6 / 11
CRAP
n/a
0 / 0
format_percentage
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
format_score
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
status_label
60.87% covered (warning)
60.87%
14 / 23
0.00% covered (danger)
0.00%
0 / 1
1.06
status_badge_classes
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
1.00
level_chip_style
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
gender_label
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
yes_no_label
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
day_of_week_label
50.00% covered (danger)
50.00%
5 / 10
0.00% covered (danger)
0.00%
0 / 1
1.12
session_status_options
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
attendance_record_options
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
nav_item_classes
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3if (! function_exists('format_percentage')) {
4    function format_percentage(?float $value, int $decimals = 0): string
5    {
6        $value ??= 0.0;
7
8        return number_format($value, $decimals) . '%';
9    }
10}
11
12if (! function_exists('format_score')) {
13    function format_score(null|float|int|string $value, int $decimals = 2): string
14    {
15        if ($value === null || $value === '') {
16            return '-';
17        }
18
19        return number_format((float) $value, $decimals);
20    }
21}
22
23if (! function_exists('status_label')) {
24    function status_label(?string $status): string
25    {
26        $status = strtoupper((string) $status);
27
28        return match ($status) {
29            'ALMOST_READY', 'ALMOST READY' => 'Almost Ready',
30            'ALMOST' => 'Almost',
31            'ATTENDANCE' => 'Attendance',
32            'ATTENDANCE_ALERT' => 'Attendance Alert',
33            'ABSENT_EXCUSED' => 'Absent motivat',
34            'ABSENT UNEXCUSED', 'ABSENT_UNEXCUSED' => 'Absent nemotivat',
35            'PRESENT' => 'Prezent',
36            'RECOVERY' => 'Recuperare',
37            'INACTIVE' => 'Inactiv',
38            'OVERDUE' => 'Overdue',
39            'PROMOTION_READY' => 'Promotion Ready',
40            'EVALUATION_OVERDUE' => 'Evaluation Overdue',
41            'UNREAD' => 'Unread',
42            'READ' => 'Read',
43            'COMPLETED' => 'Completed',
44            'CANCELLED' => 'Cancelled',
45            'SCHEDULED' => 'Scheduled',
46            'READY' => 'Ready',
47            'HOLD' => 'Hold',
48            default => ucwords(strtolower(str_replace('_', ' ', $status))),
49        };
50    }
51}
52
53if (! function_exists('status_badge_classes')) {
54    function status_badge_classes(?string $status): string
55    {
56        $status = strtoupper((string) $status);
57
58        return match ($status) {
59            'READY', 'PROMOTION_READY' => 'bg-emerald-50 text-emerald-700 ring-emerald-600/20',
60            'ALMOST_READY', 'ALMOST READY', 'ALMOST', 'SCHEDULED', 'ABSENT_EXCUSED' => 'bg-amber-50 text-amber-700 ring-amber-600/20',
61            'HOLD', 'ATTENDANCE', 'ATTENDANCE_ALERT', 'ABSENT_UNEXCUSED', 'ABSENT UNEXCUSED' => 'bg-rose-50 text-rose-700 ring-rose-600/20',
62            'PRESENT', 'COMPLETED' => 'bg-emerald-50 text-emerald-700 ring-emerald-600/20',
63            'RECOVERY', 'ACTIVE', 'UNREAD' => 'bg-sky-50 text-sky-700 ring-sky-600/20',
64            'OVERDUE', 'EVALUATION_OVERDUE', 'PAUSE', 'READ' => 'bg-slate-100 text-slate-700 ring-slate-500/20',
65            'INACTIVE', 'LEFT', 'CANCELLED' => 'bg-zinc-100 text-zinc-700 ring-zinc-500/20',
66            default => 'bg-slate-100 text-slate-700 ring-slate-500/20',
67        };
68    }
69}
70
71if (! function_exists('level_chip_style')) {
72    function level_chip_style(?string $hexColor): string
73    {
74        $hexColor = $hexColor ?: '#94a3b8';
75
76        if (strlen($hexColor) === 7) {
77            return "border-color: {$hexColor}; color: {$hexColor}; background-color: {$hexColor}14;";
78        }
79
80        return '';
81    }
82}
83
84if (! function_exists('gender_label')) {
85    function gender_label(?string $gender): string
86    {
87        return match ((string) $gender) {
88            'male' => 'Baiat',
89            'female' => 'Fata',
90            default => '-',
91        };
92    }
93}
94
95if (! function_exists('yes_no_label')) {
96    function yes_no_label(bool|int|string|null $value): string
97    {
98        return (int) $value === 1 ? 'Da' : 'Nu';
99    }
100}
101
102if (! function_exists('day_of_week_label')) {
103    function day_of_week_label(int|string|null $day): string
104    {
105        return match ((int) $day) {
106            1 => 'Luni',
107            2 => 'Marti',
108            3 => 'Miercuri',
109            4 => 'Joi',
110            5 => 'Vineri',
111            6 => 'Sambata',
112            7 => 'Duminica',
113            default => '-',
114        };
115    }
116}
117
118if (! function_exists('session_status_options')) {
119    function session_status_options(): array
120    {
121        return [
122            'scheduled' => 'Scheduled',
123            'completed' => 'Completed',
124            'cancelled' => 'Cancelled',
125            'recovery' => 'Recovery',
126        ];
127    }
128}
129
130if (! function_exists('attendance_record_options')) {
131    function attendance_record_options(): array
132    {
133        return [
134            'present' => 'Prezent',
135            'absent_excused' => 'Absent motivat',
136            'absent_unexcused' => 'Absent nemotivat',
137            'recovery' => 'Recuperare',
138        ];
139    }
140}
141
142if (! function_exists('nav_item_classes')) {
143    function nav_item_classes(bool $active): string
144    {
145        return $active
146            ? 'bg-indigo-600 text-white shadow-soft'
147            : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900';
148    }
149}