analytica-frontend-lib 1.0.82 → 1.0.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Accordation/index.js +2 -2
- package/dist/Accordation/index.js.map +1 -1
- package/dist/Accordation/index.mjs +2 -2
- package/dist/Accordation/index.mjs.map +1 -1
- package/dist/AlertDialog/index.js +1 -1
- package/dist/AlertDialog/index.js.map +1 -1
- package/dist/AlertDialog/index.mjs +1 -1
- package/dist/AlertDialog/index.mjs.map +1 -1
- package/dist/Card/index.js +2 -2
- package/dist/Card/index.js.map +1 -1
- package/dist/Card/index.mjs +2 -2
- package/dist/Card/index.mjs.map +1 -1
- package/dist/Modal/index.js +1 -1
- package/dist/Modal/index.js.map +1 -1
- package/dist/Modal/index.mjs +1 -1
- package/dist/Modal/index.mjs.map +1 -1
- package/dist/Quiz/index.d.mts +52 -0
- package/dist/Quiz/index.d.ts +52 -0
- package/dist/Quiz/index.js +4185 -0
- package/dist/Quiz/index.js.map +1 -0
- package/dist/Quiz/index.mjs +4191 -0
- package/dist/Quiz/index.mjs.map +1 -0
- package/dist/Quiz/useQuizStore/index.d.mts +140 -0
- package/dist/Quiz/useQuizStore/index.d.ts +140 -0
- package/dist/Quiz/useQuizStore/index.js +395 -0
- package/dist/Quiz/useQuizStore/index.js.map +1 -0
- package/dist/Quiz/useQuizStore/index.mjs +367 -0
- package/dist/Quiz/useQuizStore/index.mjs.map +1 -0
- package/dist/index.css +59 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1008 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1003 -4
- package/dist/index.mjs.map +1 -1
- package/dist/simulated-result-QN5HCUY5.png +0 -0
- package/dist/styles.css +59 -0
- package/dist/styles.css.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,4191 @@
|
|
|
1
|
+
// src/components/Quiz/Quiz.tsx
|
|
2
|
+
import {
|
|
3
|
+
CaretLeft,
|
|
4
|
+
CaretRight as CaretRight2,
|
|
5
|
+
Clock as Clock2,
|
|
6
|
+
SquaresFour,
|
|
7
|
+
BookOpen,
|
|
8
|
+
Book
|
|
9
|
+
} from "phosphor-react";
|
|
10
|
+
|
|
11
|
+
// src/components/Badge/Badge.tsx
|
|
12
|
+
import { Bell } from "phosphor-react";
|
|
13
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
+
var VARIANT_ACTION_CLASSES = {
|
|
15
|
+
solid: {
|
|
16
|
+
error: "bg-error-background text-error-700 focus-visible:outline-none",
|
|
17
|
+
warning: "bg-warning text-warning-800 focus-visible:outline-none",
|
|
18
|
+
success: "bg-success text-success-800 focus-visible:outline-none",
|
|
19
|
+
info: "bg-info text-info-800 focus-visible:outline-none",
|
|
20
|
+
muted: "bg-background-muted text-background-800 focus-visible:outline-none"
|
|
21
|
+
},
|
|
22
|
+
outlined: {
|
|
23
|
+
error: "bg-error text-error-700 border border-error-300 focus-visible:outline-none",
|
|
24
|
+
warning: "bg-warning text-warning-800 border border-warning-300 focus-visible:outline-none",
|
|
25
|
+
success: "bg-success text-success-800 border border-success-300 focus-visible:outline-none",
|
|
26
|
+
info: "bg-info text-info-800 border border-info-300 focus-visible:outline-none",
|
|
27
|
+
muted: "bg-background-muted text-background-800 border border-border-300 focus-visible:outline-none"
|
|
28
|
+
},
|
|
29
|
+
exams: {
|
|
30
|
+
exam1: "bg-exam-1 text-info-700 focus-visible:outline-none",
|
|
31
|
+
exam2: "bg-exam-2 text-typography-1 focus-visible:outline-none",
|
|
32
|
+
exam3: "bg-exam-3 text-typography-2 focus-visible:outline-none",
|
|
33
|
+
exam4: "bg-exam-4 text-success-700 focus-visible:outline-none"
|
|
34
|
+
},
|
|
35
|
+
examsOutlined: {
|
|
36
|
+
exam1: "bg-exam-1 text-info-700 border border-info-700 focus-visible:outline-none",
|
|
37
|
+
exam2: "bg-exam-2 text-typography-1 border border-typography-1 focus-visible:outline-none",
|
|
38
|
+
exam3: "bg-exam-3 text-typography-2 border border-typography-2 focus-visible:outline-none",
|
|
39
|
+
exam4: "bg-exam-4 text-success-700 border border-success-700 focus-visible:outline-none"
|
|
40
|
+
},
|
|
41
|
+
resultStatus: {
|
|
42
|
+
negative: "bg-error text-error-800 focus-visible:outline-none",
|
|
43
|
+
positive: "bg-success text-success-800 focus-visible:outline-none"
|
|
44
|
+
},
|
|
45
|
+
notification: "text-primary"
|
|
46
|
+
};
|
|
47
|
+
var SIZE_CLASSES = {
|
|
48
|
+
small: "text-2xs px-2 py-1",
|
|
49
|
+
medium: "text-xs px-2 py-1",
|
|
50
|
+
large: "text-sm px-2 py-1"
|
|
51
|
+
};
|
|
52
|
+
var SIZE_CLASSES_ICON = {
|
|
53
|
+
small: "size-3",
|
|
54
|
+
medium: "size-3.5",
|
|
55
|
+
large: "size-4"
|
|
56
|
+
};
|
|
57
|
+
var Badge = ({
|
|
58
|
+
children,
|
|
59
|
+
iconLeft,
|
|
60
|
+
iconRight,
|
|
61
|
+
size = "medium",
|
|
62
|
+
variant = "solid",
|
|
63
|
+
action = "error",
|
|
64
|
+
className = "",
|
|
65
|
+
notificationActive = false,
|
|
66
|
+
...props
|
|
67
|
+
}) => {
|
|
68
|
+
const sizeClasses = SIZE_CLASSES[size];
|
|
69
|
+
const sizeClassesIcon = SIZE_CLASSES_ICON[size];
|
|
70
|
+
const variantActionMap = VARIANT_ACTION_CLASSES[variant] || {};
|
|
71
|
+
const variantClasses = typeof variantActionMap === "string" ? variantActionMap : variantActionMap[action] ?? variantActionMap.muted ?? "";
|
|
72
|
+
const baseClasses = "inline-flex items-center justify-center rounded-xs font-normal gap-1 relative";
|
|
73
|
+
const baseClassesIcon = "flex items-center";
|
|
74
|
+
if (variant === "notification") {
|
|
75
|
+
return /* @__PURE__ */ jsxs(
|
|
76
|
+
"div",
|
|
77
|
+
{
|
|
78
|
+
className: `${baseClasses} ${variantClasses} ${sizeClasses} ${className}`,
|
|
79
|
+
...props,
|
|
80
|
+
children: [
|
|
81
|
+
/* @__PURE__ */ jsx(Bell, { size: 24, className: "text-current", "aria-hidden": "true" }),
|
|
82
|
+
notificationActive && /* @__PURE__ */ jsx(
|
|
83
|
+
"span",
|
|
84
|
+
{
|
|
85
|
+
"data-testid": "notification-dot",
|
|
86
|
+
className: "absolute top-[5px] right-[10px] block h-2 w-2 rounded-full bg-indicator-error ring-2 ring-white"
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return /* @__PURE__ */ jsxs(
|
|
94
|
+
"div",
|
|
95
|
+
{
|
|
96
|
+
className: `${baseClasses} ${variantClasses} ${sizeClasses} ${className}`,
|
|
97
|
+
...props,
|
|
98
|
+
children: [
|
|
99
|
+
iconLeft && /* @__PURE__ */ jsx("span", { className: `${baseClassesIcon} ${sizeClassesIcon}`, children: iconLeft }),
|
|
100
|
+
children,
|
|
101
|
+
iconRight && /* @__PURE__ */ jsx("span", { className: `${baseClassesIcon} ${sizeClassesIcon}`, children: iconRight })
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
var Badge_default = Badge;
|
|
107
|
+
|
|
108
|
+
// src/components/Alternative/Alternative.tsx
|
|
109
|
+
import { CheckCircle, XCircle } from "phosphor-react";
|
|
110
|
+
|
|
111
|
+
// src/components/Radio/Radio.tsx
|
|
112
|
+
import {
|
|
113
|
+
forwardRef,
|
|
114
|
+
useState,
|
|
115
|
+
useId,
|
|
116
|
+
useEffect,
|
|
117
|
+
useRef,
|
|
118
|
+
Children,
|
|
119
|
+
cloneElement,
|
|
120
|
+
isValidElement
|
|
121
|
+
} from "react";
|
|
122
|
+
import { create, useStore } from "zustand";
|
|
123
|
+
|
|
124
|
+
// src/components/Text/Text.tsx
|
|
125
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
126
|
+
var Text = ({
|
|
127
|
+
children,
|
|
128
|
+
size = "md",
|
|
129
|
+
weight = "normal",
|
|
130
|
+
color = "text-text-950",
|
|
131
|
+
as,
|
|
132
|
+
className = "",
|
|
133
|
+
...props
|
|
134
|
+
}) => {
|
|
135
|
+
let sizeClasses = "";
|
|
136
|
+
let weightClasses = "";
|
|
137
|
+
const sizeClassMap = {
|
|
138
|
+
"2xs": "text-2xs",
|
|
139
|
+
xs: "text-xs",
|
|
140
|
+
sm: "text-sm",
|
|
141
|
+
md: "text-md",
|
|
142
|
+
lg: "text-lg",
|
|
143
|
+
xl: "text-xl",
|
|
144
|
+
"2xl": "text-2xl",
|
|
145
|
+
"3xl": "text-3xl",
|
|
146
|
+
"4xl": "text-4xl",
|
|
147
|
+
"5xl": "text-5xl",
|
|
148
|
+
"6xl": "text-6xl"
|
|
149
|
+
};
|
|
150
|
+
sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;
|
|
151
|
+
const weightClassMap = {
|
|
152
|
+
hairline: "font-hairline",
|
|
153
|
+
light: "font-light",
|
|
154
|
+
normal: "font-normal",
|
|
155
|
+
medium: "font-medium",
|
|
156
|
+
semibold: "font-semibold",
|
|
157
|
+
bold: "font-bold",
|
|
158
|
+
extrabold: "font-extrabold",
|
|
159
|
+
black: "font-black"
|
|
160
|
+
};
|
|
161
|
+
weightClasses = weightClassMap[weight] ?? weightClassMap.normal;
|
|
162
|
+
const baseClasses = "font-primary";
|
|
163
|
+
const Component = as ?? "p";
|
|
164
|
+
return /* @__PURE__ */ jsx2(
|
|
165
|
+
Component,
|
|
166
|
+
{
|
|
167
|
+
className: `${baseClasses} ${sizeClasses} ${weightClasses} ${color} ${className}`,
|
|
168
|
+
...props,
|
|
169
|
+
children
|
|
170
|
+
}
|
|
171
|
+
);
|
|
172
|
+
};
|
|
173
|
+
var Text_default = Text;
|
|
174
|
+
|
|
175
|
+
// src/components/Radio/Radio.tsx
|
|
176
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
177
|
+
var SIZE_CLASSES2 = {
|
|
178
|
+
small: {
|
|
179
|
+
radio: "w-5 h-5",
|
|
180
|
+
textSize: "sm",
|
|
181
|
+
spacing: "gap-1.5",
|
|
182
|
+
borderWidth: "border-2",
|
|
183
|
+
dotSize: "w-2.5 h-2.5",
|
|
184
|
+
labelHeight: "h-5"
|
|
185
|
+
},
|
|
186
|
+
medium: {
|
|
187
|
+
radio: "w-6 h-6",
|
|
188
|
+
textSize: "md",
|
|
189
|
+
spacing: "gap-2",
|
|
190
|
+
borderWidth: "border-2",
|
|
191
|
+
dotSize: "w-3 h-3",
|
|
192
|
+
labelHeight: "h-6"
|
|
193
|
+
},
|
|
194
|
+
large: {
|
|
195
|
+
radio: "w-7 h-7",
|
|
196
|
+
textSize: "lg",
|
|
197
|
+
spacing: "gap-2",
|
|
198
|
+
borderWidth: "border-2",
|
|
199
|
+
dotSize: "w-3.5 h-3.5",
|
|
200
|
+
labelHeight: "h-7"
|
|
201
|
+
},
|
|
202
|
+
extraLarge: {
|
|
203
|
+
radio: "w-8 h-8",
|
|
204
|
+
textSize: "xl",
|
|
205
|
+
spacing: "gap-3",
|
|
206
|
+
borderWidth: "border-2",
|
|
207
|
+
dotSize: "w-4 h-4",
|
|
208
|
+
labelHeight: "h-8"
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
var BASE_RADIO_CLASSES = "rounded-full border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none";
|
|
212
|
+
var STATE_CLASSES = {
|
|
213
|
+
default: {
|
|
214
|
+
unchecked: "border-border-400 bg-background hover:border-border-500",
|
|
215
|
+
checked: "border-primary-950 bg-background hover:border-primary-800"
|
|
216
|
+
},
|
|
217
|
+
hovered: {
|
|
218
|
+
unchecked: "border-border-500 bg-background",
|
|
219
|
+
checked: "border-info-700 bg-background"
|
|
220
|
+
},
|
|
221
|
+
focused: {
|
|
222
|
+
unchecked: "border-border-400 bg-background",
|
|
223
|
+
checked: "border-primary-950 bg-background"
|
|
224
|
+
},
|
|
225
|
+
invalid: {
|
|
226
|
+
unchecked: "border-border-400 bg-background",
|
|
227
|
+
checked: "border-primary-950 bg-background"
|
|
228
|
+
},
|
|
229
|
+
disabled: {
|
|
230
|
+
unchecked: "border-border-400 bg-background cursor-not-allowed",
|
|
231
|
+
checked: "border-primary-950 bg-background cursor-not-allowed"
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
var DOT_CLASSES = {
|
|
235
|
+
default: "bg-primary-950",
|
|
236
|
+
hovered: "bg-info-700",
|
|
237
|
+
focused: "bg-primary-950",
|
|
238
|
+
invalid: "bg-primary-950",
|
|
239
|
+
disabled: "bg-primary-950"
|
|
240
|
+
};
|
|
241
|
+
var Radio = forwardRef(
|
|
242
|
+
({
|
|
243
|
+
label,
|
|
244
|
+
size = "medium",
|
|
245
|
+
state = "default",
|
|
246
|
+
errorMessage,
|
|
247
|
+
helperText,
|
|
248
|
+
className = "",
|
|
249
|
+
labelClassName = "",
|
|
250
|
+
checked: checkedProp,
|
|
251
|
+
defaultChecked = false,
|
|
252
|
+
disabled,
|
|
253
|
+
id,
|
|
254
|
+
name,
|
|
255
|
+
value,
|
|
256
|
+
onChange,
|
|
257
|
+
...props
|
|
258
|
+
}, ref) => {
|
|
259
|
+
const generatedId = useId();
|
|
260
|
+
const inputId = id ?? `radio-${generatedId}`;
|
|
261
|
+
const inputRef = useRef(null);
|
|
262
|
+
const [internalChecked, setInternalChecked] = useState(defaultChecked);
|
|
263
|
+
const isControlled = checkedProp !== void 0;
|
|
264
|
+
const checked = isControlled ? checkedProp : internalChecked;
|
|
265
|
+
const handleChange = (event) => {
|
|
266
|
+
const newChecked = event.target.checked;
|
|
267
|
+
if (!isControlled) {
|
|
268
|
+
setInternalChecked(newChecked);
|
|
269
|
+
}
|
|
270
|
+
if (event.target) {
|
|
271
|
+
event.target.blur();
|
|
272
|
+
}
|
|
273
|
+
onChange?.(event);
|
|
274
|
+
};
|
|
275
|
+
const currentState = disabled ? "disabled" : state;
|
|
276
|
+
const sizeClasses = SIZE_CLASSES2[size];
|
|
277
|
+
const actualRadioSize = sizeClasses.radio;
|
|
278
|
+
const actualDotSize = sizeClasses.dotSize;
|
|
279
|
+
const radioVariant = checked ? "checked" : "unchecked";
|
|
280
|
+
const stylingClasses = STATE_CLASSES[currentState][radioVariant];
|
|
281
|
+
const getBorderWidth = () => {
|
|
282
|
+
if (currentState === "focused") {
|
|
283
|
+
return "border-2";
|
|
284
|
+
}
|
|
285
|
+
return sizeClasses.borderWidth;
|
|
286
|
+
};
|
|
287
|
+
const borderWidthClass = getBorderWidth();
|
|
288
|
+
const radioClasses = `${BASE_RADIO_CLASSES} ${actualRadioSize} ${borderWidthClass} ${stylingClasses} ${className}`;
|
|
289
|
+
const dotClasses = `${actualDotSize} rounded-full ${DOT_CLASSES[currentState]} transition-all duration-200`;
|
|
290
|
+
const isWrapperNeeded = currentState === "focused" || currentState === "invalid";
|
|
291
|
+
const wrapperBorderColor = currentState === "focused" ? "border-indicator-info" : "border-indicator-error";
|
|
292
|
+
const getTextColor = () => {
|
|
293
|
+
if (currentState === "disabled") {
|
|
294
|
+
return checked ? "text-text-900" : "text-text-600";
|
|
295
|
+
}
|
|
296
|
+
if (currentState === "focused") {
|
|
297
|
+
return "text-text-900";
|
|
298
|
+
}
|
|
299
|
+
return checked ? "text-text-900" : "text-text-600";
|
|
300
|
+
};
|
|
301
|
+
const getCursorClass = () => {
|
|
302
|
+
return currentState === "disabled" ? "cursor-not-allowed" : "cursor-pointer";
|
|
303
|
+
};
|
|
304
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col", children: [
|
|
305
|
+
/* @__PURE__ */ jsxs2(
|
|
306
|
+
"div",
|
|
307
|
+
{
|
|
308
|
+
className: `flex flex-row items-center ${isWrapperNeeded ? `p-1 border-2 ${wrapperBorderColor} rounded-lg gap-1.5` : sizeClasses.spacing} ${disabled ? "opacity-40" : ""}`,
|
|
309
|
+
children: [
|
|
310
|
+
/* @__PURE__ */ jsx3(
|
|
311
|
+
"input",
|
|
312
|
+
{
|
|
313
|
+
ref: (node) => {
|
|
314
|
+
inputRef.current = node;
|
|
315
|
+
if (typeof ref === "function") ref(node);
|
|
316
|
+
else if (ref) ref.current = node;
|
|
317
|
+
},
|
|
318
|
+
type: "radio",
|
|
319
|
+
id: inputId,
|
|
320
|
+
checked,
|
|
321
|
+
disabled,
|
|
322
|
+
name,
|
|
323
|
+
value,
|
|
324
|
+
onChange: handleChange,
|
|
325
|
+
className: "sr-only",
|
|
326
|
+
style: {
|
|
327
|
+
position: "absolute",
|
|
328
|
+
left: "-9999px",
|
|
329
|
+
visibility: "hidden"
|
|
330
|
+
},
|
|
331
|
+
...props
|
|
332
|
+
}
|
|
333
|
+
),
|
|
334
|
+
/* @__PURE__ */ jsx3(
|
|
335
|
+
"button",
|
|
336
|
+
{
|
|
337
|
+
type: "button",
|
|
338
|
+
className: radioClasses,
|
|
339
|
+
disabled,
|
|
340
|
+
"aria-pressed": checked,
|
|
341
|
+
onClick: (e) => {
|
|
342
|
+
e.preventDefault();
|
|
343
|
+
if (!disabled) {
|
|
344
|
+
if (inputRef.current) {
|
|
345
|
+
inputRef.current.click();
|
|
346
|
+
inputRef.current.blur();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
onKeyDown: (e) => {
|
|
351
|
+
if ((e.key === "Enter" || e.key === " ") && !disabled) {
|
|
352
|
+
e.preventDefault();
|
|
353
|
+
if (inputRef.current) {
|
|
354
|
+
inputRef.current.click();
|
|
355
|
+
inputRef.current.blur();
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
children: checked && /* @__PURE__ */ jsx3("div", { className: dotClasses })
|
|
360
|
+
}
|
|
361
|
+
),
|
|
362
|
+
label && /* @__PURE__ */ jsx3(
|
|
363
|
+
"div",
|
|
364
|
+
{
|
|
365
|
+
className: `flex flex-row items-center ${sizeClasses.labelHeight} flex-1 min-w-0`,
|
|
366
|
+
children: /* @__PURE__ */ jsx3(
|
|
367
|
+
Text_default,
|
|
368
|
+
{
|
|
369
|
+
as: "label",
|
|
370
|
+
htmlFor: inputId,
|
|
371
|
+
size: sizeClasses.textSize,
|
|
372
|
+
weight: "normal",
|
|
373
|
+
className: `${getCursorClass()} select-none leading-normal flex items-center font-roboto truncate ${labelClassName}`,
|
|
374
|
+
color: getTextColor(),
|
|
375
|
+
children: label
|
|
376
|
+
}
|
|
377
|
+
)
|
|
378
|
+
}
|
|
379
|
+
)
|
|
380
|
+
]
|
|
381
|
+
}
|
|
382
|
+
),
|
|
383
|
+
errorMessage && /* @__PURE__ */ jsx3(
|
|
384
|
+
Text_default,
|
|
385
|
+
{
|
|
386
|
+
size: "sm",
|
|
387
|
+
weight: "normal",
|
|
388
|
+
className: "mt-1.5 truncate",
|
|
389
|
+
color: "text-error-600",
|
|
390
|
+
children: errorMessage
|
|
391
|
+
}
|
|
392
|
+
),
|
|
393
|
+
helperText && !errorMessage && /* @__PURE__ */ jsx3(
|
|
394
|
+
Text_default,
|
|
395
|
+
{
|
|
396
|
+
size: "sm",
|
|
397
|
+
weight: "normal",
|
|
398
|
+
className: "mt-1.5 truncate",
|
|
399
|
+
color: "text-text-500",
|
|
400
|
+
children: helperText
|
|
401
|
+
}
|
|
402
|
+
)
|
|
403
|
+
] });
|
|
404
|
+
}
|
|
405
|
+
);
|
|
406
|
+
Radio.displayName = "Radio";
|
|
407
|
+
var createRadioGroupStore = (name, defaultValue, disabled, onValueChange) => create((set, get) => ({
|
|
408
|
+
value: defaultValue,
|
|
409
|
+
setValue: (value) => {
|
|
410
|
+
if (!get().disabled) {
|
|
411
|
+
set({ value });
|
|
412
|
+
get().onValueChange?.(value);
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
onValueChange,
|
|
416
|
+
disabled,
|
|
417
|
+
name
|
|
418
|
+
}));
|
|
419
|
+
var useRadioGroupStore = (externalStore) => {
|
|
420
|
+
if (!externalStore) {
|
|
421
|
+
throw new Error("RadioGroupItem must be used within a RadioGroup");
|
|
422
|
+
}
|
|
423
|
+
return externalStore;
|
|
424
|
+
};
|
|
425
|
+
var injectStore = (children, store) => Children.map(children, (child) => {
|
|
426
|
+
if (!isValidElement(child)) return child;
|
|
427
|
+
const typedChild = child;
|
|
428
|
+
const shouldInject = typedChild.type === RadioGroupItem;
|
|
429
|
+
return cloneElement(typedChild, {
|
|
430
|
+
...shouldInject ? { store } : {},
|
|
431
|
+
...typedChild.props.children ? { children: injectStore(typedChild.props.children, store) } : {}
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
var RadioGroup = forwardRef(
|
|
435
|
+
({
|
|
436
|
+
value: propValue,
|
|
437
|
+
defaultValue = "",
|
|
438
|
+
onValueChange,
|
|
439
|
+
name: propName,
|
|
440
|
+
disabled = false,
|
|
441
|
+
className = "",
|
|
442
|
+
children,
|
|
443
|
+
...props
|
|
444
|
+
}, ref) => {
|
|
445
|
+
const generatedId = useId();
|
|
446
|
+
const name = propName || `radio-group-${generatedId}`;
|
|
447
|
+
const storeRef = useRef(null);
|
|
448
|
+
storeRef.current ??= createRadioGroupStore(
|
|
449
|
+
name,
|
|
450
|
+
defaultValue,
|
|
451
|
+
disabled,
|
|
452
|
+
onValueChange
|
|
453
|
+
);
|
|
454
|
+
const store = storeRef.current;
|
|
455
|
+
const { setValue } = useStore(store, (s) => s);
|
|
456
|
+
useEffect(() => {
|
|
457
|
+
const currentValue = store.getState().value;
|
|
458
|
+
if (currentValue && onValueChange) {
|
|
459
|
+
onValueChange(currentValue);
|
|
460
|
+
}
|
|
461
|
+
}, []);
|
|
462
|
+
useEffect(() => {
|
|
463
|
+
if (propValue !== void 0) {
|
|
464
|
+
setValue(propValue);
|
|
465
|
+
}
|
|
466
|
+
}, [propValue, setValue]);
|
|
467
|
+
useEffect(() => {
|
|
468
|
+
store.setState({ disabled });
|
|
469
|
+
}, [disabled, store]);
|
|
470
|
+
return /* @__PURE__ */ jsx3(
|
|
471
|
+
"div",
|
|
472
|
+
{
|
|
473
|
+
ref,
|
|
474
|
+
className,
|
|
475
|
+
role: "radiogroup",
|
|
476
|
+
"aria-label": name,
|
|
477
|
+
...props,
|
|
478
|
+
children: injectStore(children, store)
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
);
|
|
483
|
+
RadioGroup.displayName = "RadioGroup";
|
|
484
|
+
var RadioGroupItem = forwardRef(
|
|
485
|
+
({
|
|
486
|
+
value,
|
|
487
|
+
store: externalStore,
|
|
488
|
+
disabled: itemDisabled,
|
|
489
|
+
size = "medium",
|
|
490
|
+
state = "default",
|
|
491
|
+
className = "",
|
|
492
|
+
id,
|
|
493
|
+
...props
|
|
494
|
+
}, ref) => {
|
|
495
|
+
const store = useRadioGroupStore(externalStore);
|
|
496
|
+
const {
|
|
497
|
+
value: groupValue,
|
|
498
|
+
setValue,
|
|
499
|
+
disabled: groupDisabled,
|
|
500
|
+
name
|
|
501
|
+
} = useStore(store);
|
|
502
|
+
const generatedId = useId();
|
|
503
|
+
const inputId = id ?? `radio-item-${generatedId}`;
|
|
504
|
+
const isChecked = groupValue === value;
|
|
505
|
+
const isDisabled = groupDisabled || itemDisabled;
|
|
506
|
+
const currentState = isDisabled ? "disabled" : state;
|
|
507
|
+
return /* @__PURE__ */ jsx3(
|
|
508
|
+
Radio,
|
|
509
|
+
{
|
|
510
|
+
ref,
|
|
511
|
+
id: inputId,
|
|
512
|
+
name,
|
|
513
|
+
value,
|
|
514
|
+
checked: isChecked,
|
|
515
|
+
disabled: isDisabled,
|
|
516
|
+
size,
|
|
517
|
+
state: currentState,
|
|
518
|
+
className,
|
|
519
|
+
onChange: (e) => {
|
|
520
|
+
if (e.target.checked && !isDisabled) {
|
|
521
|
+
setValue(value);
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
...props
|
|
525
|
+
}
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
);
|
|
529
|
+
RadioGroupItem.displayName = "RadioGroupItem";
|
|
530
|
+
|
|
531
|
+
// src/components/Alternative/Alternative.tsx
|
|
532
|
+
import { forwardRef as forwardRef2, useId as useId2, useState as useState2 } from "react";
|
|
533
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
534
|
+
var AlternativesList = ({
|
|
535
|
+
alternatives,
|
|
536
|
+
name,
|
|
537
|
+
defaultValue,
|
|
538
|
+
value,
|
|
539
|
+
onValueChange,
|
|
540
|
+
disabled = false,
|
|
541
|
+
layout = "default",
|
|
542
|
+
className = "",
|
|
543
|
+
mode = "interactive",
|
|
544
|
+
selectedValue
|
|
545
|
+
}) => {
|
|
546
|
+
const uniqueId = useId2();
|
|
547
|
+
const groupName = name || `alternatives-${uniqueId}`;
|
|
548
|
+
const [actualValue, setActualValue] = useState2(value);
|
|
549
|
+
const isReadonly = mode === "readonly";
|
|
550
|
+
const getStatusStyles = (status, isReadonly2) => {
|
|
551
|
+
const hoverClass = isReadonly2 ? "" : "hover:bg-background-50";
|
|
552
|
+
switch (status) {
|
|
553
|
+
case "correct":
|
|
554
|
+
return "bg-success-background border-success-300";
|
|
555
|
+
case "incorrect":
|
|
556
|
+
return "bg-error-background border-error-300";
|
|
557
|
+
default:
|
|
558
|
+
return `bg-background border-border-100 ${hoverClass}`;
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
const getStatusBadge = (status) => {
|
|
562
|
+
switch (status) {
|
|
563
|
+
case "correct":
|
|
564
|
+
return /* @__PURE__ */ jsx4(Badge_default, { variant: "solid", action: "success", iconLeft: /* @__PURE__ */ jsx4(CheckCircle, {}), children: "Resposta correta" });
|
|
565
|
+
case "incorrect":
|
|
566
|
+
return /* @__PURE__ */ jsx4(Badge_default, { variant: "solid", action: "error", iconLeft: /* @__PURE__ */ jsx4(XCircle, {}), children: "Resposta incorreta" });
|
|
567
|
+
default:
|
|
568
|
+
return null;
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
const getLayoutClasses = () => {
|
|
572
|
+
switch (layout) {
|
|
573
|
+
case "compact":
|
|
574
|
+
return "gap-2";
|
|
575
|
+
case "detailed":
|
|
576
|
+
return "gap-4";
|
|
577
|
+
default:
|
|
578
|
+
return "gap-3.5";
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
const renderReadonlyAlternative = (alternative) => {
|
|
582
|
+
const alternativeId = alternative.value;
|
|
583
|
+
const isUserSelected = selectedValue === alternative.value;
|
|
584
|
+
const isCorrectAnswer = alternative.status === "correct";
|
|
585
|
+
let displayStatus = void 0;
|
|
586
|
+
if (isUserSelected && !isCorrectAnswer) {
|
|
587
|
+
displayStatus = "incorrect";
|
|
588
|
+
} else if (isCorrectAnswer) {
|
|
589
|
+
displayStatus = "correct";
|
|
590
|
+
}
|
|
591
|
+
const statusStyles = getStatusStyles(displayStatus, true);
|
|
592
|
+
const statusBadge = getStatusBadge(displayStatus);
|
|
593
|
+
const renderRadio = () => {
|
|
594
|
+
const radioClasses = `w-6 h-6 rounded-full border-2 cursor-default transition-all duration-200 flex items-center justify-center ${isUserSelected ? "border-primary-950 bg-background" : "border-border-400 bg-background"}`;
|
|
595
|
+
const dotClasses = "w-3 h-3 rounded-full bg-primary-950 transition-all duration-200";
|
|
596
|
+
return /* @__PURE__ */ jsx4("div", { className: radioClasses, children: isUserSelected && /* @__PURE__ */ jsx4("div", { className: dotClasses }) });
|
|
597
|
+
};
|
|
598
|
+
if (layout === "detailed") {
|
|
599
|
+
return /* @__PURE__ */ jsx4(
|
|
600
|
+
"div",
|
|
601
|
+
{
|
|
602
|
+
className: `border-2 rounded-lg p-4 w-full ${statusStyles} ${alternative.disabled ? "opacity-50" : ""}`,
|
|
603
|
+
children: /* @__PURE__ */ jsxs3("div", { className: "flex items-start justify-between gap-3", children: [
|
|
604
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-start gap-3 flex-1", children: [
|
|
605
|
+
/* @__PURE__ */ jsx4("div", { className: "mt-1", children: renderRadio() }),
|
|
606
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex-1", children: [
|
|
607
|
+
/* @__PURE__ */ jsx4(
|
|
608
|
+
"p",
|
|
609
|
+
{
|
|
610
|
+
className: `block font-medium ${selectedValue === alternative.value || statusBadge ? "text-text-950" : "text-text-600"}`,
|
|
611
|
+
children: alternative.label
|
|
612
|
+
}
|
|
613
|
+
),
|
|
614
|
+
alternative.description && /* @__PURE__ */ jsx4("p", { className: "text-sm text-text-600 mt-1", children: alternative.description })
|
|
615
|
+
] })
|
|
616
|
+
] }),
|
|
617
|
+
statusBadge && /* @__PURE__ */ jsx4("div", { className: "flex-shrink-0", children: statusBadge })
|
|
618
|
+
] })
|
|
619
|
+
},
|
|
620
|
+
alternativeId
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
return /* @__PURE__ */ jsxs3(
|
|
624
|
+
"div",
|
|
625
|
+
{
|
|
626
|
+
className: `flex flex-row justify-between items-start gap-2 p-2 rounded-lg w-full ${statusStyles} ${alternative.disabled ? "opacity-50" : ""}`,
|
|
627
|
+
children: [
|
|
628
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 flex-1", children: [
|
|
629
|
+
renderRadio(),
|
|
630
|
+
/* @__PURE__ */ jsx4(
|
|
631
|
+
"span",
|
|
632
|
+
{
|
|
633
|
+
className: `flex-1 ${selectedValue === alternative.value || statusBadge ? "text-text-950" : "text-text-600"}`,
|
|
634
|
+
children: alternative.label
|
|
635
|
+
}
|
|
636
|
+
)
|
|
637
|
+
] }),
|
|
638
|
+
statusBadge && /* @__PURE__ */ jsx4("div", { className: "flex-shrink-0", children: statusBadge })
|
|
639
|
+
]
|
|
640
|
+
},
|
|
641
|
+
alternativeId
|
|
642
|
+
);
|
|
643
|
+
};
|
|
644
|
+
if (isReadonly) {
|
|
645
|
+
return /* @__PURE__ */ jsx4(
|
|
646
|
+
"div",
|
|
647
|
+
{
|
|
648
|
+
className: `flex flex-col ${getLayoutClasses()} w-full ${className}`,
|
|
649
|
+
children: alternatives.map(
|
|
650
|
+
(alternative) => renderReadonlyAlternative(alternative)
|
|
651
|
+
)
|
|
652
|
+
}
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
return /* @__PURE__ */ jsx4(
|
|
656
|
+
RadioGroup,
|
|
657
|
+
{
|
|
658
|
+
name: groupName,
|
|
659
|
+
defaultValue,
|
|
660
|
+
value,
|
|
661
|
+
onValueChange: (value2) => {
|
|
662
|
+
setActualValue(value2);
|
|
663
|
+
onValueChange?.(value2);
|
|
664
|
+
},
|
|
665
|
+
disabled,
|
|
666
|
+
className: `flex flex-col ${getLayoutClasses()} ${className}`,
|
|
667
|
+
children: alternatives.map((alternative, index) => {
|
|
668
|
+
const alternativeId = alternative.value || `alt-${index}`;
|
|
669
|
+
const statusStyles = getStatusStyles(alternative.status, false);
|
|
670
|
+
const statusBadge = getStatusBadge(alternative.status);
|
|
671
|
+
if (layout === "detailed") {
|
|
672
|
+
return /* @__PURE__ */ jsx4(
|
|
673
|
+
"div",
|
|
674
|
+
{
|
|
675
|
+
className: `border-2 rounded-lg p-4 transition-all ${statusStyles} ${alternative.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}`,
|
|
676
|
+
children: /* @__PURE__ */ jsxs3("div", { className: "flex items-start justify-between gap-3", children: [
|
|
677
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-start gap-3 flex-1", children: [
|
|
678
|
+
/* @__PURE__ */ jsx4(
|
|
679
|
+
RadioGroupItem,
|
|
680
|
+
{
|
|
681
|
+
value: alternative.value,
|
|
682
|
+
id: alternativeId,
|
|
683
|
+
disabled: alternative.disabled,
|
|
684
|
+
className: "mt-1"
|
|
685
|
+
}
|
|
686
|
+
),
|
|
687
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex-1", children: [
|
|
688
|
+
/* @__PURE__ */ jsx4(
|
|
689
|
+
"label",
|
|
690
|
+
{
|
|
691
|
+
htmlFor: alternativeId,
|
|
692
|
+
className: `block font-medium
|
|
693
|
+
${actualValue === alternative.value ? "text-text-950" : "text-text-600"}
|
|
694
|
+
${alternative.disabled ? "cursor-not-allowed" : "cursor-pointer"}`,
|
|
695
|
+
children: alternative.label
|
|
696
|
+
}
|
|
697
|
+
),
|
|
698
|
+
alternative.description && /* @__PURE__ */ jsx4("p", { className: "text-sm text-text-600 mt-1", children: alternative.description })
|
|
699
|
+
] })
|
|
700
|
+
] }),
|
|
701
|
+
statusBadge && /* @__PURE__ */ jsx4("div", { className: "flex-shrink-0", children: statusBadge })
|
|
702
|
+
] })
|
|
703
|
+
},
|
|
704
|
+
alternativeId
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
return /* @__PURE__ */ jsxs3(
|
|
708
|
+
"div",
|
|
709
|
+
{
|
|
710
|
+
className: `flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all ${statusStyles} ${alternative.disabled ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
711
|
+
children: [
|
|
712
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 flex-1", children: [
|
|
713
|
+
/* @__PURE__ */ jsx4(
|
|
714
|
+
RadioGroupItem,
|
|
715
|
+
{
|
|
716
|
+
value: alternative.value,
|
|
717
|
+
id: alternativeId,
|
|
718
|
+
disabled: alternative.disabled
|
|
719
|
+
}
|
|
720
|
+
),
|
|
721
|
+
/* @__PURE__ */ jsx4(
|
|
722
|
+
"label",
|
|
723
|
+
{
|
|
724
|
+
htmlFor: alternativeId,
|
|
725
|
+
className: `flex-1
|
|
726
|
+
${actualValue === alternative.value ? "text-text-950" : "text-text-600"}
|
|
727
|
+
${alternative.disabled ? "cursor-not-allowed" : "cursor-pointer"}`,
|
|
728
|
+
children: alternative.label
|
|
729
|
+
}
|
|
730
|
+
)
|
|
731
|
+
] }),
|
|
732
|
+
statusBadge && /* @__PURE__ */ jsx4("div", { className: "flex-shrink-0", children: statusBadge })
|
|
733
|
+
]
|
|
734
|
+
},
|
|
735
|
+
alternativeId
|
|
736
|
+
);
|
|
737
|
+
})
|
|
738
|
+
}
|
|
739
|
+
);
|
|
740
|
+
};
|
|
741
|
+
var HeaderAlternative = forwardRef2(
|
|
742
|
+
({ className, title, subTitle, content, ...props }, ref) => {
|
|
743
|
+
return /* @__PURE__ */ jsxs3(
|
|
744
|
+
"div",
|
|
745
|
+
{
|
|
746
|
+
ref,
|
|
747
|
+
className: `bg-background p-4 flex flex-col gap-4 rounded-xl ${className}`,
|
|
748
|
+
...props,
|
|
749
|
+
children: [
|
|
750
|
+
/* @__PURE__ */ jsxs3("span", { className: "flex flex-col", children: [
|
|
751
|
+
/* @__PURE__ */ jsx4("p", { className: "text-text-950 font-bold text-lg", children: title }),
|
|
752
|
+
/* @__PURE__ */ jsx4("p", { className: "text-text-700 text-sm ", children: subTitle })
|
|
753
|
+
] }),
|
|
754
|
+
/* @__PURE__ */ jsx4("p", { className: "text-text-950 text-md", children: content })
|
|
755
|
+
]
|
|
756
|
+
}
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
);
|
|
760
|
+
|
|
761
|
+
// src/components/Button/Button.tsx
|
|
762
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
763
|
+
var VARIANT_ACTION_CLASSES2 = {
|
|
764
|
+
solid: {
|
|
765
|
+
primary: "bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
766
|
+
positive: "bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
767
|
+
negative: "bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed"
|
|
768
|
+
},
|
|
769
|
+
outline: {
|
|
770
|
+
primary: "bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
771
|
+
positive: "bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
772
|
+
negative: "bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed"
|
|
773
|
+
},
|
|
774
|
+
link: {
|
|
775
|
+
primary: "bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
776
|
+
positive: "bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
777
|
+
negative: "bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed"
|
|
778
|
+
}
|
|
779
|
+
};
|
|
780
|
+
var SIZE_CLASSES3 = {
|
|
781
|
+
"extra-small": "text-xs px-3.5 py-2",
|
|
782
|
+
small: "text-sm px-4 py-2.5",
|
|
783
|
+
medium: "text-md px-5 py-2.5",
|
|
784
|
+
large: "text-lg px-6 py-3",
|
|
785
|
+
"extra-large": "text-lg px-7 py-3.5"
|
|
786
|
+
};
|
|
787
|
+
var Button = ({
|
|
788
|
+
children,
|
|
789
|
+
iconLeft,
|
|
790
|
+
iconRight,
|
|
791
|
+
size = "medium",
|
|
792
|
+
variant = "solid",
|
|
793
|
+
action = "primary",
|
|
794
|
+
className = "",
|
|
795
|
+
disabled,
|
|
796
|
+
type = "button",
|
|
797
|
+
...props
|
|
798
|
+
}) => {
|
|
799
|
+
const sizeClasses = SIZE_CLASSES3[size];
|
|
800
|
+
const variantClasses = VARIANT_ACTION_CLASSES2[variant][action];
|
|
801
|
+
const baseClasses = "inline-flex items-center justify-center rounded-full cursor-pointer font-medium";
|
|
802
|
+
return /* @__PURE__ */ jsxs4(
|
|
803
|
+
"button",
|
|
804
|
+
{
|
|
805
|
+
className: `${baseClasses} ${variantClasses} ${sizeClasses} ${className}`,
|
|
806
|
+
disabled,
|
|
807
|
+
type,
|
|
808
|
+
...props,
|
|
809
|
+
children: [
|
|
810
|
+
iconLeft && /* @__PURE__ */ jsx5("span", { className: "mr-2 flex items-center", children: iconLeft }),
|
|
811
|
+
children,
|
|
812
|
+
iconRight && /* @__PURE__ */ jsx5("span", { className: "ml-2 flex items-center", children: iconRight })
|
|
813
|
+
]
|
|
814
|
+
}
|
|
815
|
+
);
|
|
816
|
+
};
|
|
817
|
+
var Button_default = Button;
|
|
818
|
+
|
|
819
|
+
// src/components/IconButton/IconButton.tsx
|
|
820
|
+
import { forwardRef as forwardRef3 } from "react";
|
|
821
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
822
|
+
var IconButton = forwardRef3(
|
|
823
|
+
({ icon, size = "md", active = false, className = "", disabled, ...props }, ref) => {
|
|
824
|
+
const baseClasses = [
|
|
825
|
+
"inline-flex",
|
|
826
|
+
"items-center",
|
|
827
|
+
"justify-center",
|
|
828
|
+
"rounded-lg",
|
|
829
|
+
"font-medium",
|
|
830
|
+
"bg-transparent",
|
|
831
|
+
"text-text-950",
|
|
832
|
+
"cursor-pointer",
|
|
833
|
+
"hover:bg-primary-600",
|
|
834
|
+
"hover:text-text",
|
|
835
|
+
"focus-visible:outline-none",
|
|
836
|
+
"focus-visible:ring-2",
|
|
837
|
+
"focus-visible:ring-offset-0",
|
|
838
|
+
"focus-visible:ring-indicator-info",
|
|
839
|
+
"disabled:opacity-50",
|
|
840
|
+
"disabled:cursor-not-allowed",
|
|
841
|
+
"disabled:pointer-events-none"
|
|
842
|
+
];
|
|
843
|
+
const sizeClasses = {
|
|
844
|
+
sm: ["w-6", "h-6", "text-sm"],
|
|
845
|
+
md: ["w-10", "h-10", "text-base"]
|
|
846
|
+
};
|
|
847
|
+
const activeClasses = active ? ["!bg-primary-50", "!text-primary-950", "hover:!bg-primary-100"] : [];
|
|
848
|
+
const allClasses = [
|
|
849
|
+
...baseClasses,
|
|
850
|
+
...sizeClasses[size],
|
|
851
|
+
...activeClasses
|
|
852
|
+
].join(" ");
|
|
853
|
+
const ariaLabel = props["aria-label"] ?? "Bot\xE3o de a\xE7\xE3o";
|
|
854
|
+
return /* @__PURE__ */ jsx6(
|
|
855
|
+
"button",
|
|
856
|
+
{
|
|
857
|
+
ref,
|
|
858
|
+
type: "button",
|
|
859
|
+
className: `${allClasses} ${className}`,
|
|
860
|
+
disabled,
|
|
861
|
+
"aria-pressed": active,
|
|
862
|
+
"aria-label": ariaLabel,
|
|
863
|
+
...props,
|
|
864
|
+
children: /* @__PURE__ */ jsx6("span", { className: "flex items-center justify-center", children: icon })
|
|
865
|
+
}
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
);
|
|
869
|
+
IconButton.displayName = "IconButton";
|
|
870
|
+
var IconButton_default = IconButton;
|
|
871
|
+
|
|
872
|
+
// src/components/Quiz/Quiz.tsx
|
|
873
|
+
import { forwardRef as forwardRef7, useState as useState4 } from "react";
|
|
874
|
+
|
|
875
|
+
// src/components/Quiz/useQuizStore.ts
|
|
876
|
+
import { create as create2 } from "zustand";
|
|
877
|
+
import { devtools } from "zustand/middleware";
|
|
878
|
+
var useQuizStore = create2()(
|
|
879
|
+
devtools(
|
|
880
|
+
(set, get) => {
|
|
881
|
+
let timerInterval = null;
|
|
882
|
+
const startTimer = () => {
|
|
883
|
+
if (get().isFinished) {
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
if (timerInterval) {
|
|
887
|
+
clearInterval(timerInterval);
|
|
888
|
+
}
|
|
889
|
+
timerInterval = setInterval(() => {
|
|
890
|
+
const { timeElapsed } = get();
|
|
891
|
+
set({ timeElapsed: timeElapsed + 1 });
|
|
892
|
+
}, 1e3);
|
|
893
|
+
};
|
|
894
|
+
const stopTimer = () => {
|
|
895
|
+
if (timerInterval) {
|
|
896
|
+
clearInterval(timerInterval);
|
|
897
|
+
timerInterval = null;
|
|
898
|
+
}
|
|
899
|
+
};
|
|
900
|
+
return {
|
|
901
|
+
// Initial State
|
|
902
|
+
currentQuestionIndex: 0,
|
|
903
|
+
selectedAnswers: {},
|
|
904
|
+
userAnswers: [],
|
|
905
|
+
timeElapsed: 0,
|
|
906
|
+
isStarted: false,
|
|
907
|
+
isFinished: false,
|
|
908
|
+
userId: "",
|
|
909
|
+
// Setters
|
|
910
|
+
setBySimulated: (simulado) => set({ bySimulated: simulado }),
|
|
911
|
+
setByActivity: (atividade) => set({ byActivity: atividade }),
|
|
912
|
+
setByQuestionary: (aula) => set({ byQuestionary: aula }),
|
|
913
|
+
setUserId: (userId) => set({ userId }),
|
|
914
|
+
getUserId: () => get().userId,
|
|
915
|
+
// Navigation
|
|
916
|
+
goToNextQuestion: () => {
|
|
917
|
+
const { currentQuestionIndex, getTotalQuestions } = get();
|
|
918
|
+
const totalQuestions = getTotalQuestions();
|
|
919
|
+
if (currentQuestionIndex < totalQuestions - 1) {
|
|
920
|
+
set({ currentQuestionIndex: currentQuestionIndex + 1 });
|
|
921
|
+
}
|
|
922
|
+
},
|
|
923
|
+
goToPreviousQuestion: () => {
|
|
924
|
+
const { currentQuestionIndex } = get();
|
|
925
|
+
if (currentQuestionIndex > 0) {
|
|
926
|
+
set({ currentQuestionIndex: currentQuestionIndex - 1 });
|
|
927
|
+
}
|
|
928
|
+
},
|
|
929
|
+
goToQuestion: (index) => {
|
|
930
|
+
const { getTotalQuestions } = get();
|
|
931
|
+
const totalQuestions = getTotalQuestions();
|
|
932
|
+
if (index >= 0 && index < totalQuestions) {
|
|
933
|
+
set({ currentQuestionIndex: index });
|
|
934
|
+
}
|
|
935
|
+
},
|
|
936
|
+
getActiveQuiz: () => {
|
|
937
|
+
const { bySimulated, byActivity, byQuestionary } = get();
|
|
938
|
+
if (bySimulated)
|
|
939
|
+
return { quiz: bySimulated, type: "bySimulated" };
|
|
940
|
+
if (byActivity)
|
|
941
|
+
return { quiz: byActivity, type: "byActivity" };
|
|
942
|
+
if (byQuestionary)
|
|
943
|
+
return { quiz: byQuestionary, type: "byQuestionary" };
|
|
944
|
+
return null;
|
|
945
|
+
},
|
|
946
|
+
selectAnswer: (questionId, answerId) => {
|
|
947
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
948
|
+
const activeQuiz = getActiveQuiz();
|
|
949
|
+
if (!activeQuiz) return;
|
|
950
|
+
const updatedQuestions = activeQuiz.quiz.questions.map(
|
|
951
|
+
(question) => question.id === questionId ? { ...question, answerKey: answerId } : question
|
|
952
|
+
);
|
|
953
|
+
const updatedQuiz = {
|
|
954
|
+
...activeQuiz.quiz,
|
|
955
|
+
questions: updatedQuestions
|
|
956
|
+
};
|
|
957
|
+
const activityId = activeQuiz.quiz.id;
|
|
958
|
+
const userId = get().getUserId();
|
|
959
|
+
if (!userId) {
|
|
960
|
+
console.warn("selectAnswer called before userId is set");
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
const existingAnswerIndex = userAnswers.findIndex(
|
|
964
|
+
(answer) => answer.questionId === questionId
|
|
965
|
+
);
|
|
966
|
+
const newUserAnswer = {
|
|
967
|
+
questionId,
|
|
968
|
+
activityId,
|
|
969
|
+
userId,
|
|
970
|
+
answer: answerId,
|
|
971
|
+
optionId: answerId
|
|
972
|
+
};
|
|
973
|
+
let updatedUserAnswers;
|
|
974
|
+
if (existingAnswerIndex !== -1) {
|
|
975
|
+
updatedUserAnswers = [...userAnswers];
|
|
976
|
+
updatedUserAnswers[existingAnswerIndex] = newUserAnswer;
|
|
977
|
+
} else {
|
|
978
|
+
updatedUserAnswers = [...userAnswers, newUserAnswer];
|
|
979
|
+
}
|
|
980
|
+
set({
|
|
981
|
+
[activeQuiz.type]: updatedQuiz,
|
|
982
|
+
userAnswers: updatedUserAnswers
|
|
983
|
+
});
|
|
984
|
+
},
|
|
985
|
+
skipQuestion: () => {
|
|
986
|
+
const { getCurrentQuestion, userAnswers, getActiveQuiz } = get();
|
|
987
|
+
const currentQuestion = getCurrentQuestion();
|
|
988
|
+
const activeQuiz = getActiveQuiz();
|
|
989
|
+
if (!activeQuiz) return;
|
|
990
|
+
if (currentQuestion) {
|
|
991
|
+
const activityId = activeQuiz.quiz.id;
|
|
992
|
+
const userId = get().getUserId();
|
|
993
|
+
const existingAnswerIndex = userAnswers.findIndex(
|
|
994
|
+
(answer) => answer.questionId === currentQuestion.id
|
|
995
|
+
);
|
|
996
|
+
const newUserAnswer = {
|
|
997
|
+
questionId: currentQuestion.id,
|
|
998
|
+
activityId,
|
|
999
|
+
userId,
|
|
1000
|
+
answer: null,
|
|
1001
|
+
optionId: null
|
|
1002
|
+
};
|
|
1003
|
+
let updatedUserAnswers;
|
|
1004
|
+
if (existingAnswerIndex !== -1) {
|
|
1005
|
+
updatedUserAnswers = [...userAnswers];
|
|
1006
|
+
updatedUserAnswers[existingAnswerIndex] = newUserAnswer;
|
|
1007
|
+
} else {
|
|
1008
|
+
updatedUserAnswers = [...userAnswers, newUserAnswer];
|
|
1009
|
+
}
|
|
1010
|
+
set({
|
|
1011
|
+
userAnswers: updatedUserAnswers
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
1015
|
+
addUserAnswer: (questionId, answerId) => {
|
|
1016
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
1017
|
+
const activeQuiz = getActiveQuiz();
|
|
1018
|
+
if (!activeQuiz) return;
|
|
1019
|
+
const activityId = activeQuiz.quiz.id;
|
|
1020
|
+
const userId = get().getUserId();
|
|
1021
|
+
const existingAnswerIndex = userAnswers.findIndex(
|
|
1022
|
+
(answer) => answer.questionId === questionId
|
|
1023
|
+
);
|
|
1024
|
+
const newUserAnswer = {
|
|
1025
|
+
questionId,
|
|
1026
|
+
activityId,
|
|
1027
|
+
userId,
|
|
1028
|
+
answer: answerId || null,
|
|
1029
|
+
optionId: answerId || null
|
|
1030
|
+
};
|
|
1031
|
+
if (existingAnswerIndex !== -1) {
|
|
1032
|
+
const updatedUserAnswers = [...userAnswers];
|
|
1033
|
+
updatedUserAnswers[existingAnswerIndex] = newUserAnswer;
|
|
1034
|
+
set({ userAnswers: updatedUserAnswers });
|
|
1035
|
+
} else {
|
|
1036
|
+
set({ userAnswers: [...userAnswers, newUserAnswer] });
|
|
1037
|
+
}
|
|
1038
|
+
},
|
|
1039
|
+
startQuiz: () => {
|
|
1040
|
+
set({ isStarted: true, timeElapsed: 0 });
|
|
1041
|
+
startTimer();
|
|
1042
|
+
},
|
|
1043
|
+
finishQuiz: () => {
|
|
1044
|
+
set({ isFinished: true });
|
|
1045
|
+
stopTimer();
|
|
1046
|
+
},
|
|
1047
|
+
resetQuiz: () => {
|
|
1048
|
+
stopTimer();
|
|
1049
|
+
set({
|
|
1050
|
+
currentQuestionIndex: 0,
|
|
1051
|
+
selectedAnswers: {},
|
|
1052
|
+
userAnswers: [],
|
|
1053
|
+
timeElapsed: 0,
|
|
1054
|
+
isStarted: false,
|
|
1055
|
+
isFinished: false,
|
|
1056
|
+
userId: ""
|
|
1057
|
+
});
|
|
1058
|
+
},
|
|
1059
|
+
// Timer
|
|
1060
|
+
updateTime: (time) => set({ timeElapsed: time }),
|
|
1061
|
+
startTimer,
|
|
1062
|
+
stopTimer,
|
|
1063
|
+
// Getters
|
|
1064
|
+
getCurrentQuestion: () => {
|
|
1065
|
+
const { currentQuestionIndex, getActiveQuiz } = get();
|
|
1066
|
+
const activeQuiz = getActiveQuiz();
|
|
1067
|
+
if (!activeQuiz) {
|
|
1068
|
+
return null;
|
|
1069
|
+
}
|
|
1070
|
+
return activeQuiz.quiz.questions[currentQuestionIndex];
|
|
1071
|
+
},
|
|
1072
|
+
getTotalQuestions: () => {
|
|
1073
|
+
const { getActiveQuiz } = get();
|
|
1074
|
+
const activeQuiz = getActiveQuiz();
|
|
1075
|
+
return activeQuiz?.quiz?.questions?.length || 0;
|
|
1076
|
+
},
|
|
1077
|
+
getAnsweredQuestions: () => {
|
|
1078
|
+
const { userAnswers } = get();
|
|
1079
|
+
return userAnswers.filter((answer) => answer.answer !== null).length;
|
|
1080
|
+
},
|
|
1081
|
+
getUnansweredQuestions: () => {
|
|
1082
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
1083
|
+
const activeQuiz = getActiveQuiz();
|
|
1084
|
+
if (!activeQuiz) return [];
|
|
1085
|
+
const unansweredQuestions = [];
|
|
1086
|
+
activeQuiz.quiz.questions.forEach((question, index) => {
|
|
1087
|
+
const userAnswer = userAnswers.find(
|
|
1088
|
+
(answer) => answer.questionId === question.id
|
|
1089
|
+
);
|
|
1090
|
+
const isAnswered = userAnswer && userAnswer.answer !== null;
|
|
1091
|
+
const isSkipped = userAnswer && userAnswer.answer === null;
|
|
1092
|
+
if (!isAnswered && !isSkipped) {
|
|
1093
|
+
unansweredQuestions.push(index + 1);
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
return unansweredQuestions;
|
|
1097
|
+
},
|
|
1098
|
+
getSkippedQuestions: () => {
|
|
1099
|
+
const { userAnswers } = get();
|
|
1100
|
+
return userAnswers.filter((answer) => answer.answer === null).length;
|
|
1101
|
+
},
|
|
1102
|
+
getProgress: () => {
|
|
1103
|
+
const { getTotalQuestions, getAnsweredQuestions } = get();
|
|
1104
|
+
const total = getTotalQuestions();
|
|
1105
|
+
const answered = getAnsweredQuestions();
|
|
1106
|
+
return total > 0 ? answered / total * 100 : 0;
|
|
1107
|
+
},
|
|
1108
|
+
isQuestionAnswered: (questionId) => {
|
|
1109
|
+
const { userAnswers } = get();
|
|
1110
|
+
const userAnswer = userAnswers.find(
|
|
1111
|
+
(answer) => answer.questionId === questionId
|
|
1112
|
+
);
|
|
1113
|
+
return userAnswer ? userAnswer.answer !== null : false;
|
|
1114
|
+
},
|
|
1115
|
+
isQuestionSkipped: (questionId) => {
|
|
1116
|
+
const { userAnswers } = get();
|
|
1117
|
+
const userAnswer = userAnswers.find(
|
|
1118
|
+
(answer) => answer.questionId === questionId
|
|
1119
|
+
);
|
|
1120
|
+
return userAnswer ? userAnswer.answer === null : false;
|
|
1121
|
+
},
|
|
1122
|
+
getCurrentAnswer: () => {
|
|
1123
|
+
const { getCurrentQuestion, userAnswers } = get();
|
|
1124
|
+
const currentQuestion = getCurrentQuestion();
|
|
1125
|
+
if (!currentQuestion) return void 0;
|
|
1126
|
+
const userAnswer = userAnswers.find(
|
|
1127
|
+
(answer) => answer.questionId === currentQuestion.id
|
|
1128
|
+
);
|
|
1129
|
+
return userAnswer?.answer;
|
|
1130
|
+
},
|
|
1131
|
+
getQuizTitle: () => {
|
|
1132
|
+
const { getActiveQuiz } = get();
|
|
1133
|
+
const activeQuiz = getActiveQuiz();
|
|
1134
|
+
return activeQuiz?.quiz?.title || "Quiz";
|
|
1135
|
+
},
|
|
1136
|
+
formatTime: (seconds) => {
|
|
1137
|
+
const minutes = Math.floor(seconds / 60);
|
|
1138
|
+
const remainingSeconds = seconds % 60;
|
|
1139
|
+
return `${minutes.toString().padStart(2, "0")}:${remainingSeconds.toString().padStart(2, "0")}`;
|
|
1140
|
+
},
|
|
1141
|
+
getUserAnswers: () => {
|
|
1142
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
1143
|
+
const activeQuiz = getActiveQuiz();
|
|
1144
|
+
if (!activeQuiz) return [];
|
|
1145
|
+
return activeQuiz.quiz.questions.map((question) => {
|
|
1146
|
+
const userAnswer = userAnswers.find(
|
|
1147
|
+
(answer) => answer.questionId === question.id
|
|
1148
|
+
);
|
|
1149
|
+
return {
|
|
1150
|
+
...question,
|
|
1151
|
+
isSkipped: userAnswer ? userAnswer.answer === null : false
|
|
1152
|
+
};
|
|
1153
|
+
});
|
|
1154
|
+
},
|
|
1155
|
+
getUnansweredQuestionsFromUserAnswers: () => {
|
|
1156
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
1157
|
+
const activeQuiz = getActiveQuiz();
|
|
1158
|
+
if (!activeQuiz) return [];
|
|
1159
|
+
const unansweredQuestions = [];
|
|
1160
|
+
activeQuiz.quiz.questions.forEach((question, index) => {
|
|
1161
|
+
const userAnswer = userAnswers.find(
|
|
1162
|
+
(answer) => answer.questionId === question.id
|
|
1163
|
+
);
|
|
1164
|
+
const hasAnswer = userAnswer && userAnswer.answer !== null;
|
|
1165
|
+
const isSkipped = userAnswer && userAnswer.answer === null;
|
|
1166
|
+
if (!hasAnswer || isSkipped) {
|
|
1167
|
+
unansweredQuestions.push(index + 1);
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
return unansweredQuestions;
|
|
1171
|
+
},
|
|
1172
|
+
getQuestionsGroupedBySubject: () => {
|
|
1173
|
+
const { getActiveQuiz } = get();
|
|
1174
|
+
const activeQuiz = getActiveQuiz();
|
|
1175
|
+
if (!activeQuiz) return {};
|
|
1176
|
+
const groupedQuestions = {};
|
|
1177
|
+
activeQuiz.quiz.questions.forEach((question) => {
|
|
1178
|
+
const subjectId = question.knowledgeMatrix?.[0]?.subjectId || "Sem mat\xE9ria";
|
|
1179
|
+
if (!groupedQuestions[subjectId]) {
|
|
1180
|
+
groupedQuestions[subjectId] = [];
|
|
1181
|
+
}
|
|
1182
|
+
groupedQuestions[subjectId].push(question);
|
|
1183
|
+
});
|
|
1184
|
+
return groupedQuestions;
|
|
1185
|
+
},
|
|
1186
|
+
// New methods for userAnswers
|
|
1187
|
+
getUserAnswerByQuestionId: (questionId) => {
|
|
1188
|
+
const { userAnswers } = get();
|
|
1189
|
+
return userAnswers.find((answer) => answer.questionId === questionId) || null;
|
|
1190
|
+
},
|
|
1191
|
+
isQuestionAnsweredByUserAnswers: (questionId) => {
|
|
1192
|
+
const { userAnswers } = get();
|
|
1193
|
+
const answer = userAnswers.find(
|
|
1194
|
+
(answer2) => answer2.questionId === questionId
|
|
1195
|
+
);
|
|
1196
|
+
return answer ? answer.answer !== null : false;
|
|
1197
|
+
},
|
|
1198
|
+
getQuestionStatusFromUserAnswers: (questionId) => {
|
|
1199
|
+
const { userAnswers } = get();
|
|
1200
|
+
const answer = userAnswers.find(
|
|
1201
|
+
(answer2) => answer2.questionId === questionId
|
|
1202
|
+
);
|
|
1203
|
+
if (!answer) return "unanswered";
|
|
1204
|
+
if (answer.answer === null) return "skipped";
|
|
1205
|
+
return "answered";
|
|
1206
|
+
},
|
|
1207
|
+
getUserAnswersForActivity: () => {
|
|
1208
|
+
const { userAnswers } = get();
|
|
1209
|
+
return userAnswers;
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
},
|
|
1213
|
+
{
|
|
1214
|
+
name: "quiz-store"
|
|
1215
|
+
}
|
|
1216
|
+
)
|
|
1217
|
+
);
|
|
1218
|
+
|
|
1219
|
+
// src/components/AlertDialog/AlertDialog.tsx
|
|
1220
|
+
import {
|
|
1221
|
+
forwardRef as forwardRef4,
|
|
1222
|
+
useEffect as useEffect2
|
|
1223
|
+
} from "react";
|
|
1224
|
+
import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1225
|
+
var SIZE_CLASSES4 = {
|
|
1226
|
+
"extra-small": "w-screen max-w-[324px]",
|
|
1227
|
+
small: "w-screen max-w-[378px]",
|
|
1228
|
+
medium: "w-screen max-w-[459px]",
|
|
1229
|
+
large: "w-screen max-w-[578px]",
|
|
1230
|
+
"extra-large": "w-screen max-w-[912px]"
|
|
1231
|
+
};
|
|
1232
|
+
var AlertDialog = forwardRef4(
|
|
1233
|
+
({
|
|
1234
|
+
description,
|
|
1235
|
+
cancelButtonLabel = "Cancelar",
|
|
1236
|
+
submitButtonLabel = "Deletar",
|
|
1237
|
+
title,
|
|
1238
|
+
isOpen,
|
|
1239
|
+
closeOnBackdropClick = true,
|
|
1240
|
+
closeOnEscape = true,
|
|
1241
|
+
className = "",
|
|
1242
|
+
onSubmit,
|
|
1243
|
+
onChangeOpen,
|
|
1244
|
+
submitValue,
|
|
1245
|
+
onCancel,
|
|
1246
|
+
cancelValue,
|
|
1247
|
+
size = "medium",
|
|
1248
|
+
...props
|
|
1249
|
+
}, ref) => {
|
|
1250
|
+
useEffect2(() => {
|
|
1251
|
+
if (!isOpen || !closeOnEscape) return;
|
|
1252
|
+
const handleEscape = (event) => {
|
|
1253
|
+
if (event.key === "Escape") {
|
|
1254
|
+
onChangeOpen(false);
|
|
1255
|
+
}
|
|
1256
|
+
};
|
|
1257
|
+
document.addEventListener("keydown", handleEscape);
|
|
1258
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
1259
|
+
}, [isOpen, closeOnEscape]);
|
|
1260
|
+
useEffect2(() => {
|
|
1261
|
+
if (isOpen) {
|
|
1262
|
+
document.body.style.overflow = "hidden";
|
|
1263
|
+
} else {
|
|
1264
|
+
document.body.style.overflow = "unset";
|
|
1265
|
+
}
|
|
1266
|
+
return () => {
|
|
1267
|
+
document.body.style.overflow = "unset";
|
|
1268
|
+
};
|
|
1269
|
+
}, [isOpen]);
|
|
1270
|
+
const handleBackdropClick = (event) => {
|
|
1271
|
+
if (event.target === event.currentTarget && closeOnBackdropClick) {
|
|
1272
|
+
onChangeOpen(false);
|
|
1273
|
+
}
|
|
1274
|
+
};
|
|
1275
|
+
const handleBackdropKeyDown = (event) => {
|
|
1276
|
+
if (event.key === "Escape" && closeOnEscape) {
|
|
1277
|
+
onChangeOpen(false);
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
const handleSubmit = () => {
|
|
1281
|
+
onChangeOpen(false);
|
|
1282
|
+
onSubmit?.(submitValue);
|
|
1283
|
+
};
|
|
1284
|
+
const handleCancel = () => {
|
|
1285
|
+
onChangeOpen(false);
|
|
1286
|
+
onCancel?.(cancelValue);
|
|
1287
|
+
};
|
|
1288
|
+
const sizeClasses = SIZE_CLASSES4[size];
|
|
1289
|
+
return /* @__PURE__ */ jsx7(Fragment, { children: isOpen && /* @__PURE__ */ jsx7(
|
|
1290
|
+
"div",
|
|
1291
|
+
{
|
|
1292
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm",
|
|
1293
|
+
onClick: handleBackdropClick,
|
|
1294
|
+
onKeyDown: handleBackdropKeyDown,
|
|
1295
|
+
"data-testid": "alert-dialog-overlay",
|
|
1296
|
+
children: /* @__PURE__ */ jsxs5(
|
|
1297
|
+
"div",
|
|
1298
|
+
{
|
|
1299
|
+
ref,
|
|
1300
|
+
className: `bg-background border border-border-100 rounded-lg shadow-lg p-6 m-3 ${sizeClasses} ${className}`,
|
|
1301
|
+
...props,
|
|
1302
|
+
children: [
|
|
1303
|
+
/* @__PURE__ */ jsx7(
|
|
1304
|
+
"h2",
|
|
1305
|
+
{
|
|
1306
|
+
id: "alert-dialog-title",
|
|
1307
|
+
className: "pb-3 text-xl font-semibold text-text-950",
|
|
1308
|
+
children: title
|
|
1309
|
+
}
|
|
1310
|
+
),
|
|
1311
|
+
/* @__PURE__ */ jsx7(
|
|
1312
|
+
"p",
|
|
1313
|
+
{
|
|
1314
|
+
id: "alert-dialog-description",
|
|
1315
|
+
className: "text-text-700 text-sm",
|
|
1316
|
+
children: description
|
|
1317
|
+
}
|
|
1318
|
+
),
|
|
1319
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-row items-center justify-end pt-4 gap-3", children: [
|
|
1320
|
+
/* @__PURE__ */ jsx7(Button_default, { variant: "outline", size: "small", onClick: handleCancel, children: cancelButtonLabel }),
|
|
1321
|
+
/* @__PURE__ */ jsx7(
|
|
1322
|
+
Button_default,
|
|
1323
|
+
{
|
|
1324
|
+
variant: "solid",
|
|
1325
|
+
size: "small",
|
|
1326
|
+
action: "negative",
|
|
1327
|
+
onClick: handleSubmit,
|
|
1328
|
+
children: submitButtonLabel
|
|
1329
|
+
}
|
|
1330
|
+
)
|
|
1331
|
+
] })
|
|
1332
|
+
]
|
|
1333
|
+
}
|
|
1334
|
+
)
|
|
1335
|
+
}
|
|
1336
|
+
) });
|
|
1337
|
+
}
|
|
1338
|
+
);
|
|
1339
|
+
AlertDialog.displayName = "AlertDialog";
|
|
1340
|
+
|
|
1341
|
+
// src/components/Modal/Modal.tsx
|
|
1342
|
+
import { useEffect as useEffect3 } from "react";
|
|
1343
|
+
import { X } from "phosphor-react";
|
|
1344
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1345
|
+
var SIZE_CLASSES5 = {
|
|
1346
|
+
xs: "max-w-[360px]",
|
|
1347
|
+
sm: "max-w-[420px]",
|
|
1348
|
+
md: "max-w-[510px]",
|
|
1349
|
+
lg: "max-w-[640px]",
|
|
1350
|
+
xl: "max-w-[970px]"
|
|
1351
|
+
};
|
|
1352
|
+
var Modal = ({
|
|
1353
|
+
isOpen,
|
|
1354
|
+
onClose,
|
|
1355
|
+
title,
|
|
1356
|
+
children,
|
|
1357
|
+
size = "md",
|
|
1358
|
+
className = "",
|
|
1359
|
+
closeOnBackdropClick = true,
|
|
1360
|
+
closeOnEscape = true,
|
|
1361
|
+
footer,
|
|
1362
|
+
hideCloseButton = false
|
|
1363
|
+
}) => {
|
|
1364
|
+
useEffect3(() => {
|
|
1365
|
+
if (!isOpen || !closeOnEscape) return;
|
|
1366
|
+
const handleEscape = (event) => {
|
|
1367
|
+
if (event.key === "Escape") {
|
|
1368
|
+
onClose();
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
document.addEventListener("keydown", handleEscape);
|
|
1372
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
1373
|
+
}, [isOpen, closeOnEscape, onClose]);
|
|
1374
|
+
useEffect3(() => {
|
|
1375
|
+
const originalOverflow = document.body.style.overflow;
|
|
1376
|
+
if (isOpen) {
|
|
1377
|
+
document.body.style.overflow = "hidden";
|
|
1378
|
+
} else {
|
|
1379
|
+
document.body.style.overflow = originalOverflow;
|
|
1380
|
+
}
|
|
1381
|
+
return () => {
|
|
1382
|
+
document.body.style.overflow = originalOverflow;
|
|
1383
|
+
};
|
|
1384
|
+
}, [isOpen]);
|
|
1385
|
+
const handleBackdropClick = (event) => {
|
|
1386
|
+
if (closeOnBackdropClick && event.target === event.currentTarget) {
|
|
1387
|
+
onClose();
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
const handleBackdropKeyDown = (event) => {
|
|
1391
|
+
if (closeOnBackdropClick && (event.key === "Enter" || event.key === " ")) {
|
|
1392
|
+
onClose();
|
|
1393
|
+
}
|
|
1394
|
+
};
|
|
1395
|
+
if (!isOpen) return null;
|
|
1396
|
+
const sizeClasses = SIZE_CLASSES5[size];
|
|
1397
|
+
const baseClasses = "bg-secondary-50 rounded-3xl shadow-hard-shadow-2 border border-border-100 w-full mx-4";
|
|
1398
|
+
const dialogResetClasses = "p-0 m-0 border-none outline-none max-h-none static";
|
|
1399
|
+
const modalClasses = `${baseClasses} ${sizeClasses} ${dialogResetClasses} ${className}`;
|
|
1400
|
+
return /* @__PURE__ */ jsx8(
|
|
1401
|
+
"div",
|
|
1402
|
+
{
|
|
1403
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs",
|
|
1404
|
+
onClick: handleBackdropClick,
|
|
1405
|
+
onKeyDown: handleBackdropKeyDown,
|
|
1406
|
+
role: "button",
|
|
1407
|
+
tabIndex: closeOnBackdropClick ? 0 : -1,
|
|
1408
|
+
"aria-label": "Fechar modal clicando no fundo",
|
|
1409
|
+
children: /* @__PURE__ */ jsxs6("dialog", { className: modalClasses, "aria-labelledby": "modal-title", open: true, children: [
|
|
1410
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between px-6 py-6", children: [
|
|
1411
|
+
/* @__PURE__ */ jsx8("h2", { id: "modal-title", className: "text-lg font-semibold text-text-950", children: title }),
|
|
1412
|
+
!hideCloseButton && /* @__PURE__ */ jsx8(
|
|
1413
|
+
"button",
|
|
1414
|
+
{
|
|
1415
|
+
onClick: onClose,
|
|
1416
|
+
className: "p-1 text-text-500 hover:text-text-700 hover:bg-background-50 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-indicator-info focus:ring-offset-2",
|
|
1417
|
+
"aria-label": "Fechar modal",
|
|
1418
|
+
children: /* @__PURE__ */ jsx8(X, { size: 18 })
|
|
1419
|
+
}
|
|
1420
|
+
)
|
|
1421
|
+
] }),
|
|
1422
|
+
/* @__PURE__ */ jsx8("div", { className: "px-6 pb-6", children: /* @__PURE__ */ jsx8("div", { className: "text-text-500 font-normal text-sm leading-6", children }) }),
|
|
1423
|
+
footer && /* @__PURE__ */ jsx8("div", { className: "flex justify-end gap-3 px-6 pb-6", children: footer })
|
|
1424
|
+
] })
|
|
1425
|
+
}
|
|
1426
|
+
);
|
|
1427
|
+
};
|
|
1428
|
+
var Modal_default = Modal;
|
|
1429
|
+
|
|
1430
|
+
// src/assets/img/simulated-result.png
|
|
1431
|
+
var simulated_result_default = "../simulated-result-QN5HCUY5.png";
|
|
1432
|
+
|
|
1433
|
+
// src/components/Select/Select.tsx
|
|
1434
|
+
import { create as create3, useStore as useStore2 } from "zustand";
|
|
1435
|
+
import {
|
|
1436
|
+
useEffect as useEffect4,
|
|
1437
|
+
useRef as useRef2,
|
|
1438
|
+
forwardRef as forwardRef5,
|
|
1439
|
+
isValidElement as isValidElement2,
|
|
1440
|
+
Children as Children2,
|
|
1441
|
+
cloneElement as cloneElement2,
|
|
1442
|
+
useId as useId3
|
|
1443
|
+
} from "react";
|
|
1444
|
+
import { CaretDown, Check, WarningCircle } from "phosphor-react";
|
|
1445
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1446
|
+
var VARIANT_CLASSES = {
|
|
1447
|
+
outlined: "border rounded-lg focus:border-primary-950",
|
|
1448
|
+
underlined: "border-b focus:border-primary-950",
|
|
1449
|
+
rounded: "border rounded-full focus:border-primary-950"
|
|
1450
|
+
};
|
|
1451
|
+
var SIZE_CLASSES6 = {
|
|
1452
|
+
small: "text-sm",
|
|
1453
|
+
medium: "text-md",
|
|
1454
|
+
large: "text-lg",
|
|
1455
|
+
"extra-large": "text-lg"
|
|
1456
|
+
};
|
|
1457
|
+
var HEIGHT_CLASSES = {
|
|
1458
|
+
small: "h-8",
|
|
1459
|
+
medium: "h-9",
|
|
1460
|
+
large: "h-10",
|
|
1461
|
+
"extra-large": "h-12"
|
|
1462
|
+
};
|
|
1463
|
+
var PADDING_CLASSES = {
|
|
1464
|
+
small: "px-2 py-1",
|
|
1465
|
+
medium: "px-3 py-2",
|
|
1466
|
+
large: "px-4 py-3",
|
|
1467
|
+
"extra-large": "px-5 py-4"
|
|
1468
|
+
};
|
|
1469
|
+
var SIDE_CLASSES = {
|
|
1470
|
+
top: "bottom-full -translate-y-1",
|
|
1471
|
+
right: "top-full translate-y-1",
|
|
1472
|
+
bottom: "top-full translate-y-1",
|
|
1473
|
+
left: "top-full translate-y-1"
|
|
1474
|
+
};
|
|
1475
|
+
var ALIGN_CLASSES = {
|
|
1476
|
+
start: "left-0",
|
|
1477
|
+
center: "left-1/2 -translate-x-1/2",
|
|
1478
|
+
end: "right-0"
|
|
1479
|
+
};
|
|
1480
|
+
function createSelectStore(onValueChange) {
|
|
1481
|
+
return create3((set) => ({
|
|
1482
|
+
open: false,
|
|
1483
|
+
setOpen: (open) => set({ open }),
|
|
1484
|
+
value: "",
|
|
1485
|
+
setValue: (value) => set({ value }),
|
|
1486
|
+
selectedLabel: "",
|
|
1487
|
+
setSelectedLabel: (label) => set({ selectedLabel: label }),
|
|
1488
|
+
onValueChange
|
|
1489
|
+
}));
|
|
1490
|
+
}
|
|
1491
|
+
var useSelectStore = (externalStore) => {
|
|
1492
|
+
if (!externalStore) {
|
|
1493
|
+
throw new Error(
|
|
1494
|
+
"Component must be used within a Select (store is missing)"
|
|
1495
|
+
);
|
|
1496
|
+
}
|
|
1497
|
+
return externalStore;
|
|
1498
|
+
};
|
|
1499
|
+
function getLabelAsNode(children) {
|
|
1500
|
+
if (typeof children === "string" || typeof children === "number") {
|
|
1501
|
+
return children;
|
|
1502
|
+
}
|
|
1503
|
+
const flattened = Children2.toArray(children);
|
|
1504
|
+
if (flattened.length === 1) return flattened[0];
|
|
1505
|
+
return /* @__PURE__ */ jsx9(Fragment2, { children: flattened });
|
|
1506
|
+
}
|
|
1507
|
+
var injectStore2 = (children, store, size, selectId) => {
|
|
1508
|
+
return Children2.map(children, (child) => {
|
|
1509
|
+
if (isValidElement2(child)) {
|
|
1510
|
+
const typedChild = child;
|
|
1511
|
+
const newProps = {
|
|
1512
|
+
store
|
|
1513
|
+
};
|
|
1514
|
+
if (typedChild.type === SelectTrigger) {
|
|
1515
|
+
newProps.size = size;
|
|
1516
|
+
newProps.selectId = selectId;
|
|
1517
|
+
}
|
|
1518
|
+
if (typedChild.props.children) {
|
|
1519
|
+
newProps.children = injectStore2(
|
|
1520
|
+
typedChild.props.children,
|
|
1521
|
+
store,
|
|
1522
|
+
size,
|
|
1523
|
+
selectId
|
|
1524
|
+
);
|
|
1525
|
+
}
|
|
1526
|
+
return cloneElement2(typedChild, newProps);
|
|
1527
|
+
}
|
|
1528
|
+
return child;
|
|
1529
|
+
});
|
|
1530
|
+
};
|
|
1531
|
+
var Select = ({
|
|
1532
|
+
children,
|
|
1533
|
+
defaultValue = "",
|
|
1534
|
+
value: propValue,
|
|
1535
|
+
onValueChange,
|
|
1536
|
+
size = "small",
|
|
1537
|
+
label,
|
|
1538
|
+
helperText,
|
|
1539
|
+
errorMessage,
|
|
1540
|
+
id
|
|
1541
|
+
}) => {
|
|
1542
|
+
const storeRef = useRef2(null);
|
|
1543
|
+
storeRef.current ??= createSelectStore(onValueChange);
|
|
1544
|
+
const store = storeRef.current;
|
|
1545
|
+
const selectRef = useRef2(null);
|
|
1546
|
+
const { open, setOpen, setValue, selectedLabel } = useStore2(store, (s) => s);
|
|
1547
|
+
const generatedId = useId3();
|
|
1548
|
+
const selectId = id ?? `select-${generatedId}`;
|
|
1549
|
+
const findLabelForValue = (children2, targetValue) => {
|
|
1550
|
+
let found = null;
|
|
1551
|
+
const search = (nodes) => {
|
|
1552
|
+
Children2.forEach(nodes, (child) => {
|
|
1553
|
+
if (!isValidElement2(child)) return;
|
|
1554
|
+
const typedChild = child;
|
|
1555
|
+
if (typedChild.type === SelectItem && typedChild.props.value === targetValue) {
|
|
1556
|
+
if (typeof typedChild.props.children === "string")
|
|
1557
|
+
found = typedChild.props.children;
|
|
1558
|
+
}
|
|
1559
|
+
if (typedChild.props.children && !found)
|
|
1560
|
+
search(typedChild.props.children);
|
|
1561
|
+
});
|
|
1562
|
+
};
|
|
1563
|
+
search(children2);
|
|
1564
|
+
return found;
|
|
1565
|
+
};
|
|
1566
|
+
useEffect4(() => {
|
|
1567
|
+
if (!selectedLabel && defaultValue) {
|
|
1568
|
+
const label2 = findLabelForValue(children, defaultValue);
|
|
1569
|
+
if (label2) store.setState({ selectedLabel: label2 });
|
|
1570
|
+
}
|
|
1571
|
+
}, [children, defaultValue, selectedLabel]);
|
|
1572
|
+
useEffect4(() => {
|
|
1573
|
+
const handleClickOutside = (event) => {
|
|
1574
|
+
if (selectRef.current && !selectRef.current.contains(event.target)) {
|
|
1575
|
+
setOpen(false);
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
const handleArrowKeys = (event) => {
|
|
1579
|
+
const selectContent = selectRef.current?.querySelector('[role="menu"]');
|
|
1580
|
+
if (selectContent) {
|
|
1581
|
+
event.preventDefault();
|
|
1582
|
+
const items = Array.from(
|
|
1583
|
+
selectContent.querySelectorAll(
|
|
1584
|
+
'[role="menuitem"]:not([aria-disabled="true"])'
|
|
1585
|
+
)
|
|
1586
|
+
).filter((el) => el instanceof HTMLElement);
|
|
1587
|
+
const focused = document.activeElement;
|
|
1588
|
+
const currentIndex = items.findIndex((item) => item === focused);
|
|
1589
|
+
let nextIndex = 0;
|
|
1590
|
+
if (event.key === "ArrowDown") {
|
|
1591
|
+
nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;
|
|
1592
|
+
} else {
|
|
1593
|
+
nextIndex = currentIndex === -1 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;
|
|
1594
|
+
}
|
|
1595
|
+
items[nextIndex]?.focus();
|
|
1596
|
+
}
|
|
1597
|
+
};
|
|
1598
|
+
if (open) {
|
|
1599
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1600
|
+
document.addEventListener("keydown", handleArrowKeys);
|
|
1601
|
+
}
|
|
1602
|
+
return () => {
|
|
1603
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1604
|
+
document.removeEventListener("keydown", handleArrowKeys);
|
|
1605
|
+
};
|
|
1606
|
+
}, [open]);
|
|
1607
|
+
useEffect4(() => {
|
|
1608
|
+
if (propValue) {
|
|
1609
|
+
setValue(propValue);
|
|
1610
|
+
const label2 = findLabelForValue(children, propValue);
|
|
1611
|
+
if (label2) store.setState({ selectedLabel: label2 });
|
|
1612
|
+
}
|
|
1613
|
+
}, [propValue]);
|
|
1614
|
+
const sizeClasses = SIZE_CLASSES6[size];
|
|
1615
|
+
return /* @__PURE__ */ jsxs7("div", { className: "w-full", children: [
|
|
1616
|
+
label && /* @__PURE__ */ jsx9(
|
|
1617
|
+
"label",
|
|
1618
|
+
{
|
|
1619
|
+
htmlFor: selectId,
|
|
1620
|
+
className: `block font-bold text-text-900 mb-1.5 ${sizeClasses}`,
|
|
1621
|
+
children: label
|
|
1622
|
+
}
|
|
1623
|
+
),
|
|
1624
|
+
/* @__PURE__ */ jsx9("div", { className: `relative ${sizeClasses}`, ref: selectRef, children: injectStore2(children, store, size, selectId) }),
|
|
1625
|
+
/* @__PURE__ */ jsxs7("div", { className: "mt-1.5 gap-1.5", children: [
|
|
1626
|
+
helperText && /* @__PURE__ */ jsx9("p", { className: "text-sm text-text-500", children: helperText }),
|
|
1627
|
+
errorMessage && /* @__PURE__ */ jsxs7("p", { className: "flex gap-1 items-center text-sm text-indicator-error", children: [
|
|
1628
|
+
/* @__PURE__ */ jsx9(WarningCircle, { size: 16 }),
|
|
1629
|
+
" ",
|
|
1630
|
+
errorMessage
|
|
1631
|
+
] })
|
|
1632
|
+
] })
|
|
1633
|
+
] });
|
|
1634
|
+
};
|
|
1635
|
+
var SelectValue = ({
|
|
1636
|
+
placeholder,
|
|
1637
|
+
store: externalStore
|
|
1638
|
+
}) => {
|
|
1639
|
+
const store = useSelectStore(externalStore);
|
|
1640
|
+
const selectedLabel = useStore2(store, (s) => s.selectedLabel);
|
|
1641
|
+
const value = useStore2(store, (s) => s.value);
|
|
1642
|
+
return /* @__PURE__ */ jsx9("span", { className: "text-inherit", children: selectedLabel || placeholder || value });
|
|
1643
|
+
};
|
|
1644
|
+
var SelectTrigger = forwardRef5(
|
|
1645
|
+
({
|
|
1646
|
+
className,
|
|
1647
|
+
invalid = false,
|
|
1648
|
+
variant = "outlined",
|
|
1649
|
+
store: externalStore,
|
|
1650
|
+
disabled,
|
|
1651
|
+
size = "medium",
|
|
1652
|
+
selectId,
|
|
1653
|
+
...props
|
|
1654
|
+
}, ref) => {
|
|
1655
|
+
const store = useSelectStore(externalStore);
|
|
1656
|
+
const open = useStore2(store, (s) => s.open);
|
|
1657
|
+
const toggleOpen = () => store.setState({ open: !open });
|
|
1658
|
+
const variantClasses = VARIANT_CLASSES[variant];
|
|
1659
|
+
const heightClasses = HEIGHT_CLASSES[size];
|
|
1660
|
+
const paddingClasses = PADDING_CLASSES[size];
|
|
1661
|
+
return /* @__PURE__ */ jsxs7(
|
|
1662
|
+
"button",
|
|
1663
|
+
{
|
|
1664
|
+
ref,
|
|
1665
|
+
id: selectId,
|
|
1666
|
+
className: `
|
|
1667
|
+
flex min-w-[220px] w-full items-center justify-between border-border-300
|
|
1668
|
+
${heightClasses} ${paddingClasses}
|
|
1669
|
+
${invalid && `${variant == "underlined" ? "border-b-2" : "border-2"} border-indicator-error text-text-600`}
|
|
1670
|
+
${disabled ? "cursor-not-allowed text-text-400 pointer-events-none opacity-50" : "cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground"}
|
|
1671
|
+
${!invalid && !disabled ? "text-text-700" : ""}
|
|
1672
|
+
${variantClasses}
|
|
1673
|
+
${className}
|
|
1674
|
+
`,
|
|
1675
|
+
onClick: toggleOpen,
|
|
1676
|
+
"aria-expanded": open,
|
|
1677
|
+
"aria-haspopup": "listbox",
|
|
1678
|
+
"aria-controls": open ? "select-content" : void 0,
|
|
1679
|
+
...props,
|
|
1680
|
+
children: [
|
|
1681
|
+
props.children,
|
|
1682
|
+
/* @__PURE__ */ jsx9(
|
|
1683
|
+
CaretDown,
|
|
1684
|
+
{
|
|
1685
|
+
className: `h-[1em] w-[1em] opacity-50 transition-transform ${open ? "rotate-180" : ""}`
|
|
1686
|
+
}
|
|
1687
|
+
)
|
|
1688
|
+
]
|
|
1689
|
+
}
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
);
|
|
1693
|
+
SelectTrigger.displayName = "SelectTrigger";
|
|
1694
|
+
var SelectContent = forwardRef5(
|
|
1695
|
+
({
|
|
1696
|
+
children,
|
|
1697
|
+
className,
|
|
1698
|
+
align = "start",
|
|
1699
|
+
side = "bottom",
|
|
1700
|
+
store: externalStore,
|
|
1701
|
+
...props
|
|
1702
|
+
}, ref) => {
|
|
1703
|
+
const store = useSelectStore(externalStore);
|
|
1704
|
+
const open = useStore2(store, (s) => s.open);
|
|
1705
|
+
if (!open) return null;
|
|
1706
|
+
const getPositionClasses = () => `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;
|
|
1707
|
+
return /* @__PURE__ */ jsx9(
|
|
1708
|
+
"div",
|
|
1709
|
+
{
|
|
1710
|
+
role: "menu",
|
|
1711
|
+
ref,
|
|
1712
|
+
className: `bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md border-border-100 ${getPositionClasses()} ${className}`,
|
|
1713
|
+
...props,
|
|
1714
|
+
children
|
|
1715
|
+
}
|
|
1716
|
+
);
|
|
1717
|
+
}
|
|
1718
|
+
);
|
|
1719
|
+
SelectContent.displayName = "SelectContent";
|
|
1720
|
+
var SelectItem = forwardRef5(
|
|
1721
|
+
({
|
|
1722
|
+
className,
|
|
1723
|
+
children,
|
|
1724
|
+
value,
|
|
1725
|
+
disabled = false,
|
|
1726
|
+
store: externalStore,
|
|
1727
|
+
...props
|
|
1728
|
+
}, ref) => {
|
|
1729
|
+
const store = useSelectStore(externalStore);
|
|
1730
|
+
const {
|
|
1731
|
+
value: selectedValue,
|
|
1732
|
+
setValue,
|
|
1733
|
+
setOpen,
|
|
1734
|
+
setSelectedLabel,
|
|
1735
|
+
onValueChange
|
|
1736
|
+
} = useStore2(store, (s) => s);
|
|
1737
|
+
const handleClick = (e) => {
|
|
1738
|
+
const labelNode = getLabelAsNode(children);
|
|
1739
|
+
if (!disabled) {
|
|
1740
|
+
setValue(value);
|
|
1741
|
+
setSelectedLabel(labelNode);
|
|
1742
|
+
setOpen(false);
|
|
1743
|
+
onValueChange?.(value);
|
|
1744
|
+
}
|
|
1745
|
+
props.onClick?.(e);
|
|
1746
|
+
};
|
|
1747
|
+
return /* @__PURE__ */ jsxs7(
|
|
1748
|
+
"div",
|
|
1749
|
+
{
|
|
1750
|
+
role: "menuitem",
|
|
1751
|
+
"aria-disabled": disabled,
|
|
1752
|
+
ref,
|
|
1753
|
+
className: `
|
|
1754
|
+
focus-visible:bg-background-50
|
|
1755
|
+
relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0
|
|
1756
|
+
${className}
|
|
1757
|
+
${disabled ? "cursor-not-allowed text-text-400 pointer-events-none opacity-50" : "cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground"}
|
|
1758
|
+
${selectedValue === value && "bg-background-50"}
|
|
1759
|
+
`,
|
|
1760
|
+
onClick: handleClick,
|
|
1761
|
+
onKeyDown: (e) => {
|
|
1762
|
+
if (e.key === "Enter" || e.key === " ") handleClick(e);
|
|
1763
|
+
},
|
|
1764
|
+
tabIndex: disabled ? -1 : 0,
|
|
1765
|
+
...props,
|
|
1766
|
+
children: [
|
|
1767
|
+
/* @__PURE__ */ jsx9("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: selectedValue === value && /* @__PURE__ */ jsx9(Check, { className: "" }) }),
|
|
1768
|
+
children
|
|
1769
|
+
]
|
|
1770
|
+
}
|
|
1771
|
+
);
|
|
1772
|
+
}
|
|
1773
|
+
);
|
|
1774
|
+
SelectItem.displayName = "SelectItem";
|
|
1775
|
+
var Select_default = Select;
|
|
1776
|
+
|
|
1777
|
+
// src/components/Card/Card.tsx
|
|
1778
|
+
import {
|
|
1779
|
+
forwardRef as forwardRef6,
|
|
1780
|
+
Fragment as Fragment4,
|
|
1781
|
+
useState as useState3,
|
|
1782
|
+
useRef as useRef3
|
|
1783
|
+
} from "react";
|
|
1784
|
+
|
|
1785
|
+
// src/components/ProgressBar/ProgressBar.tsx
|
|
1786
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1787
|
+
var SIZE_CLASSES7 = {
|
|
1788
|
+
small: {
|
|
1789
|
+
container: "h-1",
|
|
1790
|
+
// 4px height (h-1 = 4px in Tailwind)
|
|
1791
|
+
bar: "h-1",
|
|
1792
|
+
// 4px height for the fill bar
|
|
1793
|
+
spacing: "gap-2",
|
|
1794
|
+
// 8px gap between label and progress bar
|
|
1795
|
+
layout: "flex-col",
|
|
1796
|
+
// vertical layout for small
|
|
1797
|
+
borderRadius: "rounded-full"
|
|
1798
|
+
// 9999px border radius
|
|
1799
|
+
},
|
|
1800
|
+
medium: {
|
|
1801
|
+
container: "h-2",
|
|
1802
|
+
// 8px height (h-2 = 8px in Tailwind)
|
|
1803
|
+
bar: "h-2",
|
|
1804
|
+
// 8px height for the fill bar
|
|
1805
|
+
spacing: "gap-2",
|
|
1806
|
+
// 8px gap between progress bar and label
|
|
1807
|
+
layout: "flex-row items-center",
|
|
1808
|
+
// horizontal layout for medium
|
|
1809
|
+
borderRadius: "rounded-lg"
|
|
1810
|
+
// 8px border radius
|
|
1811
|
+
}
|
|
1812
|
+
};
|
|
1813
|
+
var VARIANT_CLASSES2 = {
|
|
1814
|
+
blue: {
|
|
1815
|
+
background: "bg-background-300",
|
|
1816
|
+
// Background track color (#D5D4D4)
|
|
1817
|
+
fill: "bg-primary-700"
|
|
1818
|
+
// Blue for activity progress (#2271C4)
|
|
1819
|
+
},
|
|
1820
|
+
green: {
|
|
1821
|
+
background: "bg-background-300",
|
|
1822
|
+
// Background track color (#D5D4D4)
|
|
1823
|
+
fill: "bg-success-200"
|
|
1824
|
+
// Green for performance (#84D3A2)
|
|
1825
|
+
}
|
|
1826
|
+
};
|
|
1827
|
+
var calculateProgressValues = (value, max) => {
|
|
1828
|
+
const safeValue = isNaN(value) ? 0 : value;
|
|
1829
|
+
const clampedValue = Math.max(0, Math.min(safeValue, max));
|
|
1830
|
+
const percentage = max === 0 ? 0 : clampedValue / max * 100;
|
|
1831
|
+
return { clampedValue, percentage };
|
|
1832
|
+
};
|
|
1833
|
+
var shouldShowHeader = (label, showPercentage, showHitCount) => {
|
|
1834
|
+
return !!(label || showPercentage || showHitCount);
|
|
1835
|
+
};
|
|
1836
|
+
var getDisplayPriority = (showHitCount, showPercentage, label, clampedValue, max, percentage) => {
|
|
1837
|
+
if (showHitCount) {
|
|
1838
|
+
return {
|
|
1839
|
+
type: "hitCount",
|
|
1840
|
+
content: `${Math.round(clampedValue)} de ${max}`,
|
|
1841
|
+
hasMetrics: true
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
if (showPercentage) {
|
|
1845
|
+
return {
|
|
1846
|
+
type: "percentage",
|
|
1847
|
+
content: `${Math.round(percentage)}%`,
|
|
1848
|
+
hasMetrics: true
|
|
1849
|
+
};
|
|
1850
|
+
}
|
|
1851
|
+
return {
|
|
1852
|
+
type: "label",
|
|
1853
|
+
content: label,
|
|
1854
|
+
hasMetrics: false
|
|
1855
|
+
};
|
|
1856
|
+
};
|
|
1857
|
+
var getCompactLayoutConfig = ({
|
|
1858
|
+
showPercentage,
|
|
1859
|
+
showHitCount,
|
|
1860
|
+
percentage,
|
|
1861
|
+
clampedValue,
|
|
1862
|
+
max,
|
|
1863
|
+
label,
|
|
1864
|
+
percentageClassName,
|
|
1865
|
+
labelClassName
|
|
1866
|
+
}) => {
|
|
1867
|
+
const displayPriority = getDisplayPriority(
|
|
1868
|
+
showHitCount,
|
|
1869
|
+
showPercentage,
|
|
1870
|
+
label,
|
|
1871
|
+
clampedValue,
|
|
1872
|
+
max,
|
|
1873
|
+
percentage
|
|
1874
|
+
);
|
|
1875
|
+
return {
|
|
1876
|
+
color: displayPriority.hasMetrics ? "text-primary-600" : "text-primary-700",
|
|
1877
|
+
className: displayPriority.hasMetrics ? percentageClassName : labelClassName,
|
|
1878
|
+
content: displayPriority.content
|
|
1879
|
+
};
|
|
1880
|
+
};
|
|
1881
|
+
var getDefaultLayoutDisplayConfig = (size, label, showPercentage) => ({
|
|
1882
|
+
showHeader: size === "small" && !!(label || showPercentage),
|
|
1883
|
+
showPercentage: size === "medium" && showPercentage,
|
|
1884
|
+
showLabel: size === "medium" && !!label && !showPercentage
|
|
1885
|
+
// Only show label when percentage is not shown
|
|
1886
|
+
});
|
|
1887
|
+
var renderStackedHitCountDisplay = (showHitCount, showPercentage, clampedValue, max, percentage, percentageClassName) => {
|
|
1888
|
+
if (!showHitCount && !showPercentage) return null;
|
|
1889
|
+
const displayPriority = getDisplayPriority(
|
|
1890
|
+
showHitCount,
|
|
1891
|
+
showPercentage,
|
|
1892
|
+
null,
|
|
1893
|
+
// label is not relevant for stacked layout metrics display
|
|
1894
|
+
clampedValue,
|
|
1895
|
+
max,
|
|
1896
|
+
percentage
|
|
1897
|
+
);
|
|
1898
|
+
return /* @__PURE__ */ jsx10(
|
|
1899
|
+
"div",
|
|
1900
|
+
{
|
|
1901
|
+
className: `text-xs font-medium leading-[14px] text-right ${percentageClassName}`,
|
|
1902
|
+
children: displayPriority.type === "hitCount" ? /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
1903
|
+
/* @__PURE__ */ jsx10("span", { className: "text-success-200", children: Math.round(clampedValue) }),
|
|
1904
|
+
/* @__PURE__ */ jsxs8("span", { className: "text-text-600", children: [
|
|
1905
|
+
" de ",
|
|
1906
|
+
max
|
|
1907
|
+
] })
|
|
1908
|
+
] }) : /* @__PURE__ */ jsxs8(Text_default, { size: "xs", weight: "medium", className: "text-success-200", children: [
|
|
1909
|
+
Math.round(percentage),
|
|
1910
|
+
"%"
|
|
1911
|
+
] })
|
|
1912
|
+
}
|
|
1913
|
+
);
|
|
1914
|
+
};
|
|
1915
|
+
var ProgressBarBase = ({
|
|
1916
|
+
clampedValue,
|
|
1917
|
+
max,
|
|
1918
|
+
percentage,
|
|
1919
|
+
label,
|
|
1920
|
+
variantClasses,
|
|
1921
|
+
containerClassName,
|
|
1922
|
+
fillClassName
|
|
1923
|
+
}) => /* @__PURE__ */ jsxs8(
|
|
1924
|
+
"div",
|
|
1925
|
+
{
|
|
1926
|
+
className: `${containerClassName} ${variantClasses.background} overflow-hidden relative`,
|
|
1927
|
+
children: [
|
|
1928
|
+
/* @__PURE__ */ jsx10(
|
|
1929
|
+
"progress",
|
|
1930
|
+
{
|
|
1931
|
+
value: clampedValue,
|
|
1932
|
+
max,
|
|
1933
|
+
"aria-label": typeof label === "string" ? `${label}: ${Math.round(percentage)}% complete` : `Progress: ${Math.round(percentage)}% of ${max}`,
|
|
1934
|
+
className: "absolute inset-0 w-full h-full opacity-0"
|
|
1935
|
+
}
|
|
1936
|
+
),
|
|
1937
|
+
/* @__PURE__ */ jsx10(
|
|
1938
|
+
"div",
|
|
1939
|
+
{
|
|
1940
|
+
className: `${fillClassName} ${variantClasses.fill} transition-all duration-300 ease-out`,
|
|
1941
|
+
style: { width: `${percentage}%` }
|
|
1942
|
+
}
|
|
1943
|
+
)
|
|
1944
|
+
]
|
|
1945
|
+
}
|
|
1946
|
+
);
|
|
1947
|
+
var StackedLayout = ({
|
|
1948
|
+
className,
|
|
1949
|
+
label,
|
|
1950
|
+
showPercentage,
|
|
1951
|
+
showHitCount,
|
|
1952
|
+
labelClassName,
|
|
1953
|
+
percentageClassName,
|
|
1954
|
+
clampedValue,
|
|
1955
|
+
max,
|
|
1956
|
+
percentage,
|
|
1957
|
+
variantClasses,
|
|
1958
|
+
dimensions
|
|
1959
|
+
}) => /* @__PURE__ */ jsxs8(
|
|
1960
|
+
"div",
|
|
1961
|
+
{
|
|
1962
|
+
className: `flex flex-col items-start gap-2 ${dimensions.width} ${dimensions.height} ${className}`,
|
|
1963
|
+
children: [
|
|
1964
|
+
shouldShowHeader(label, showPercentage, showHitCount) && /* @__PURE__ */ jsxs8("div", { className: "flex flex-row justify-between items-center w-full h-[19px]", children: [
|
|
1965
|
+
label && /* @__PURE__ */ jsx10(
|
|
1966
|
+
Text_default,
|
|
1967
|
+
{
|
|
1968
|
+
as: "div",
|
|
1969
|
+
size: "md",
|
|
1970
|
+
weight: "medium",
|
|
1971
|
+
className: `text-text-600 leading-[19px] ${labelClassName}`,
|
|
1972
|
+
children: label
|
|
1973
|
+
}
|
|
1974
|
+
),
|
|
1975
|
+
renderStackedHitCountDisplay(
|
|
1976
|
+
showHitCount,
|
|
1977
|
+
showPercentage,
|
|
1978
|
+
clampedValue,
|
|
1979
|
+
max,
|
|
1980
|
+
percentage,
|
|
1981
|
+
percentageClassName
|
|
1982
|
+
)
|
|
1983
|
+
] }),
|
|
1984
|
+
/* @__PURE__ */ jsx10(
|
|
1985
|
+
ProgressBarBase,
|
|
1986
|
+
{
|
|
1987
|
+
clampedValue,
|
|
1988
|
+
max,
|
|
1989
|
+
percentage,
|
|
1990
|
+
label,
|
|
1991
|
+
variantClasses,
|
|
1992
|
+
containerClassName: "w-full h-2 rounded-lg",
|
|
1993
|
+
fillClassName: "h-2 rounded-lg shadow-hard-shadow-3"
|
|
1994
|
+
}
|
|
1995
|
+
)
|
|
1996
|
+
]
|
|
1997
|
+
}
|
|
1998
|
+
);
|
|
1999
|
+
var CompactLayout = ({
|
|
2000
|
+
className,
|
|
2001
|
+
label,
|
|
2002
|
+
showPercentage,
|
|
2003
|
+
showHitCount,
|
|
2004
|
+
labelClassName,
|
|
2005
|
+
percentageClassName,
|
|
2006
|
+
clampedValue,
|
|
2007
|
+
max,
|
|
2008
|
+
percentage,
|
|
2009
|
+
variantClasses,
|
|
2010
|
+
dimensions
|
|
2011
|
+
}) => {
|
|
2012
|
+
const {
|
|
2013
|
+
color,
|
|
2014
|
+
className: compactClassName,
|
|
2015
|
+
content
|
|
2016
|
+
} = getCompactLayoutConfig({
|
|
2017
|
+
showPercentage,
|
|
2018
|
+
showHitCount,
|
|
2019
|
+
percentage,
|
|
2020
|
+
clampedValue,
|
|
2021
|
+
max,
|
|
2022
|
+
label,
|
|
2023
|
+
percentageClassName,
|
|
2024
|
+
labelClassName
|
|
2025
|
+
});
|
|
2026
|
+
return /* @__PURE__ */ jsxs8(
|
|
2027
|
+
"div",
|
|
2028
|
+
{
|
|
2029
|
+
className: `flex flex-col items-start gap-1 ${dimensions.width} ${dimensions.height} ${className}`,
|
|
2030
|
+
children: [
|
|
2031
|
+
shouldShowHeader(label, showPercentage, showHitCount) && /* @__PURE__ */ jsx10(
|
|
2032
|
+
Text_default,
|
|
2033
|
+
{
|
|
2034
|
+
as: "div",
|
|
2035
|
+
size: "sm",
|
|
2036
|
+
weight: "medium",
|
|
2037
|
+
color,
|
|
2038
|
+
className: `leading-4 w-full ${compactClassName}`,
|
|
2039
|
+
children: content
|
|
2040
|
+
}
|
|
2041
|
+
),
|
|
2042
|
+
/* @__PURE__ */ jsx10(
|
|
2043
|
+
ProgressBarBase,
|
|
2044
|
+
{
|
|
2045
|
+
clampedValue,
|
|
2046
|
+
max,
|
|
2047
|
+
percentage,
|
|
2048
|
+
label,
|
|
2049
|
+
variantClasses,
|
|
2050
|
+
containerClassName: "w-full h-1 rounded-full",
|
|
2051
|
+
fillClassName: "h-1 rounded-full"
|
|
2052
|
+
}
|
|
2053
|
+
)
|
|
2054
|
+
]
|
|
2055
|
+
}
|
|
2056
|
+
);
|
|
2057
|
+
};
|
|
2058
|
+
var DefaultLayout = ({
|
|
2059
|
+
className,
|
|
2060
|
+
size,
|
|
2061
|
+
sizeClasses,
|
|
2062
|
+
variantClasses,
|
|
2063
|
+
label,
|
|
2064
|
+
showPercentage,
|
|
2065
|
+
labelClassName,
|
|
2066
|
+
percentageClassName,
|
|
2067
|
+
clampedValue,
|
|
2068
|
+
max,
|
|
2069
|
+
percentage
|
|
2070
|
+
}) => {
|
|
2071
|
+
const gapClass = size === "medium" ? "gap-2" : sizeClasses.spacing;
|
|
2072
|
+
const progressBarClass = size === "medium" ? "flex-grow" : "w-full";
|
|
2073
|
+
const displayConfig = getDefaultLayoutDisplayConfig(
|
|
2074
|
+
size,
|
|
2075
|
+
label,
|
|
2076
|
+
showPercentage
|
|
2077
|
+
);
|
|
2078
|
+
return /* @__PURE__ */ jsxs8("div", { className: `flex ${sizeClasses.layout} ${gapClass} ${className}`, children: [
|
|
2079
|
+
displayConfig.showHeader && /* @__PURE__ */ jsxs8("div", { className: "flex flex-row items-center justify-between w-full", children: [
|
|
2080
|
+
label && /* @__PURE__ */ jsx10(
|
|
2081
|
+
Text_default,
|
|
2082
|
+
{
|
|
2083
|
+
as: "div",
|
|
2084
|
+
size: "xs",
|
|
2085
|
+
weight: "medium",
|
|
2086
|
+
className: `text-text-950 leading-none tracking-normal text-center ${labelClassName}`,
|
|
2087
|
+
children: label
|
|
2088
|
+
}
|
|
2089
|
+
),
|
|
2090
|
+
showPercentage && /* @__PURE__ */ jsxs8(
|
|
2091
|
+
Text_default,
|
|
2092
|
+
{
|
|
2093
|
+
size: "xs",
|
|
2094
|
+
weight: "medium",
|
|
2095
|
+
className: `text-text-950 leading-none tracking-normal text-center ${percentageClassName}`,
|
|
2096
|
+
children: [
|
|
2097
|
+
Math.round(percentage),
|
|
2098
|
+
"%"
|
|
2099
|
+
]
|
|
2100
|
+
}
|
|
2101
|
+
)
|
|
2102
|
+
] }),
|
|
2103
|
+
/* @__PURE__ */ jsx10(
|
|
2104
|
+
ProgressBarBase,
|
|
2105
|
+
{
|
|
2106
|
+
clampedValue,
|
|
2107
|
+
max,
|
|
2108
|
+
percentage,
|
|
2109
|
+
label,
|
|
2110
|
+
variantClasses,
|
|
2111
|
+
containerClassName: `${progressBarClass} ${sizeClasses.container} ${sizeClasses.borderRadius}`,
|
|
2112
|
+
fillClassName: `${sizeClasses.bar} ${sizeClasses.borderRadius} shadow-hard-shadow-3`
|
|
2113
|
+
}
|
|
2114
|
+
),
|
|
2115
|
+
displayConfig.showPercentage && /* @__PURE__ */ jsxs8(
|
|
2116
|
+
Text_default,
|
|
2117
|
+
{
|
|
2118
|
+
size: "xs",
|
|
2119
|
+
weight: "medium",
|
|
2120
|
+
className: `text-text-950 leading-none tracking-normal text-center flex-none ${percentageClassName}`,
|
|
2121
|
+
children: [
|
|
2122
|
+
Math.round(percentage),
|
|
2123
|
+
"%"
|
|
2124
|
+
]
|
|
2125
|
+
}
|
|
2126
|
+
),
|
|
2127
|
+
displayConfig.showLabel && /* @__PURE__ */ jsx10(
|
|
2128
|
+
Text_default,
|
|
2129
|
+
{
|
|
2130
|
+
as: "div",
|
|
2131
|
+
size: "xs",
|
|
2132
|
+
weight: "medium",
|
|
2133
|
+
className: `text-text-950 leading-none tracking-normal text-center flex-none ${labelClassName}`,
|
|
2134
|
+
children: label
|
|
2135
|
+
}
|
|
2136
|
+
)
|
|
2137
|
+
] });
|
|
2138
|
+
};
|
|
2139
|
+
var ProgressBar = ({
|
|
2140
|
+
value,
|
|
2141
|
+
max = 100,
|
|
2142
|
+
size = "medium",
|
|
2143
|
+
variant = "blue",
|
|
2144
|
+
layout = "default",
|
|
2145
|
+
label,
|
|
2146
|
+
showPercentage = false,
|
|
2147
|
+
showHitCount = false,
|
|
2148
|
+
className = "",
|
|
2149
|
+
labelClassName = "",
|
|
2150
|
+
percentageClassName = "",
|
|
2151
|
+
stackedWidth,
|
|
2152
|
+
stackedHeight,
|
|
2153
|
+
compactWidth,
|
|
2154
|
+
compactHeight
|
|
2155
|
+
}) => {
|
|
2156
|
+
const { clampedValue, percentage } = calculateProgressValues(value, max);
|
|
2157
|
+
const sizeClasses = SIZE_CLASSES7[size];
|
|
2158
|
+
const variantClasses = VARIANT_CLASSES2[variant];
|
|
2159
|
+
if (layout === "stacked") {
|
|
2160
|
+
return /* @__PURE__ */ jsx10(
|
|
2161
|
+
StackedLayout,
|
|
2162
|
+
{
|
|
2163
|
+
className,
|
|
2164
|
+
label,
|
|
2165
|
+
showPercentage,
|
|
2166
|
+
showHitCount,
|
|
2167
|
+
labelClassName,
|
|
2168
|
+
percentageClassName,
|
|
2169
|
+
clampedValue,
|
|
2170
|
+
max,
|
|
2171
|
+
percentage,
|
|
2172
|
+
variantClasses,
|
|
2173
|
+
dimensions: {
|
|
2174
|
+
width: stackedWidth ?? "w-[380px]",
|
|
2175
|
+
height: stackedHeight ?? "h-[35px]"
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
);
|
|
2179
|
+
}
|
|
2180
|
+
if (layout === "compact") {
|
|
2181
|
+
return /* @__PURE__ */ jsx10(
|
|
2182
|
+
CompactLayout,
|
|
2183
|
+
{
|
|
2184
|
+
className,
|
|
2185
|
+
label,
|
|
2186
|
+
showPercentage,
|
|
2187
|
+
showHitCount,
|
|
2188
|
+
labelClassName,
|
|
2189
|
+
percentageClassName,
|
|
2190
|
+
clampedValue,
|
|
2191
|
+
max,
|
|
2192
|
+
percentage,
|
|
2193
|
+
variantClasses,
|
|
2194
|
+
dimensions: {
|
|
2195
|
+
width: compactWidth ?? "w-[131px]",
|
|
2196
|
+
height: compactHeight ?? "h-[24px]"
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
);
|
|
2200
|
+
}
|
|
2201
|
+
return /* @__PURE__ */ jsx10(
|
|
2202
|
+
DefaultLayout,
|
|
2203
|
+
{
|
|
2204
|
+
className,
|
|
2205
|
+
size,
|
|
2206
|
+
sizeClasses,
|
|
2207
|
+
variantClasses,
|
|
2208
|
+
label,
|
|
2209
|
+
showPercentage,
|
|
2210
|
+
labelClassName,
|
|
2211
|
+
percentageClassName,
|
|
2212
|
+
clampedValue,
|
|
2213
|
+
max,
|
|
2214
|
+
percentage
|
|
2215
|
+
}
|
|
2216
|
+
);
|
|
2217
|
+
};
|
|
2218
|
+
var ProgressBar_default = ProgressBar;
|
|
2219
|
+
|
|
2220
|
+
// src/components/Card/Card.tsx
|
|
2221
|
+
import {
|
|
2222
|
+
CaretRight,
|
|
2223
|
+
ChatCircleText,
|
|
2224
|
+
CheckCircle as CheckCircle2,
|
|
2225
|
+
Clock,
|
|
2226
|
+
DotsThreeVertical,
|
|
2227
|
+
Play,
|
|
2228
|
+
SpeakerHigh,
|
|
2229
|
+
SpeakerLow,
|
|
2230
|
+
SpeakerSimpleX,
|
|
2231
|
+
XCircle as XCircle2
|
|
2232
|
+
} from "phosphor-react";
|
|
2233
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2234
|
+
var CARD_BASE_CLASSES = {
|
|
2235
|
+
default: "w-full bg-background border border-border-50 rounded-xl",
|
|
2236
|
+
compact: "w-full bg-background border border-border-50 rounded-lg",
|
|
2237
|
+
minimal: "w-full bg-background border border-border-100 rounded-md"
|
|
2238
|
+
};
|
|
2239
|
+
var CARD_PADDING_CLASSES = {
|
|
2240
|
+
none: "",
|
|
2241
|
+
small: "p-2",
|
|
2242
|
+
medium: "p-4",
|
|
2243
|
+
large: "p-6"
|
|
2244
|
+
};
|
|
2245
|
+
var CARD_MIN_HEIGHT_CLASSES = {
|
|
2246
|
+
none: "",
|
|
2247
|
+
small: "min-h-16",
|
|
2248
|
+
medium: "min-h-20",
|
|
2249
|
+
large: "min-h-24"
|
|
2250
|
+
};
|
|
2251
|
+
var CARD_LAYOUT_CLASSES = {
|
|
2252
|
+
horizontal: "flex flex-row",
|
|
2253
|
+
vertical: "flex flex-col"
|
|
2254
|
+
};
|
|
2255
|
+
var CARD_CURSOR_CLASSES = {
|
|
2256
|
+
default: "",
|
|
2257
|
+
pointer: "cursor-pointer"
|
|
2258
|
+
};
|
|
2259
|
+
var CardBase = forwardRef6(
|
|
2260
|
+
({
|
|
2261
|
+
children,
|
|
2262
|
+
variant = "default",
|
|
2263
|
+
layout = "horizontal",
|
|
2264
|
+
padding = "medium",
|
|
2265
|
+
minHeight = "medium",
|
|
2266
|
+
cursor = "default",
|
|
2267
|
+
className = "",
|
|
2268
|
+
...props
|
|
2269
|
+
}, ref) => {
|
|
2270
|
+
const baseClasses = CARD_BASE_CLASSES[variant];
|
|
2271
|
+
const paddingClasses = CARD_PADDING_CLASSES[padding];
|
|
2272
|
+
const minHeightClasses = CARD_MIN_HEIGHT_CLASSES[minHeight];
|
|
2273
|
+
const layoutClasses = CARD_LAYOUT_CLASSES[layout];
|
|
2274
|
+
const cursorClasses = CARD_CURSOR_CLASSES[cursor];
|
|
2275
|
+
const combinedClasses = [
|
|
2276
|
+
baseClasses,
|
|
2277
|
+
paddingClasses,
|
|
2278
|
+
minHeightClasses,
|
|
2279
|
+
layoutClasses,
|
|
2280
|
+
cursorClasses,
|
|
2281
|
+
className
|
|
2282
|
+
].filter(Boolean).join(" ");
|
|
2283
|
+
return /* @__PURE__ */ jsx11("div", { ref, className: combinedClasses, ...props, children });
|
|
2284
|
+
}
|
|
2285
|
+
);
|
|
2286
|
+
var ACTION_CARD_CLASSES = {
|
|
2287
|
+
warning: "bg-warning-background",
|
|
2288
|
+
success: "bg-success-300",
|
|
2289
|
+
error: "bg-error-100",
|
|
2290
|
+
info: "bg-info-background"
|
|
2291
|
+
};
|
|
2292
|
+
var ACTION_ICON_CLASSES = {
|
|
2293
|
+
warning: "bg-warning-300 text-text",
|
|
2294
|
+
success: "bg-yellow-300 text-text-950",
|
|
2295
|
+
error: "bg-error-500 text-text",
|
|
2296
|
+
info: "bg-info-500 text-text"
|
|
2297
|
+
};
|
|
2298
|
+
var ACTION_SUBTITLE_CLASSES = {
|
|
2299
|
+
warning: "text-warning-600",
|
|
2300
|
+
success: "text-success-700",
|
|
2301
|
+
error: "text-error-700",
|
|
2302
|
+
info: "text-info-700"
|
|
2303
|
+
};
|
|
2304
|
+
var ACTION_HEADER_CLASSES = {
|
|
2305
|
+
warning: "text-warning-300",
|
|
2306
|
+
success: "text-success-300",
|
|
2307
|
+
error: "text-error-300",
|
|
2308
|
+
info: "text-info-300"
|
|
2309
|
+
};
|
|
2310
|
+
var CardActivitiesResults = forwardRef6(
|
|
2311
|
+
({
|
|
2312
|
+
icon,
|
|
2313
|
+
title,
|
|
2314
|
+
subTitle,
|
|
2315
|
+
header,
|
|
2316
|
+
extended = false,
|
|
2317
|
+
action = "success",
|
|
2318
|
+
description,
|
|
2319
|
+
className,
|
|
2320
|
+
...props
|
|
2321
|
+
}, ref) => {
|
|
2322
|
+
const actionCardClasses = ACTION_CARD_CLASSES[action];
|
|
2323
|
+
const actionIconClasses = ACTION_ICON_CLASSES[action];
|
|
2324
|
+
const actionSubTitleClasses = ACTION_SUBTITLE_CLASSES[action];
|
|
2325
|
+
const actionHeaderClasses = ACTION_HEADER_CLASSES[action];
|
|
2326
|
+
return /* @__PURE__ */ jsxs9(
|
|
2327
|
+
"div",
|
|
2328
|
+
{
|
|
2329
|
+
ref,
|
|
2330
|
+
className: `w-full flex flex-col border border-border-50 bg-background rounded-xl ${className}`,
|
|
2331
|
+
...props,
|
|
2332
|
+
children: [
|
|
2333
|
+
/* @__PURE__ */ jsxs9(
|
|
2334
|
+
"div",
|
|
2335
|
+
{
|
|
2336
|
+
className: `
|
|
2337
|
+
flex flex-col gap-1 items-center justify-center p-4
|
|
2338
|
+
${actionCardClasses}
|
|
2339
|
+
${extended ? "rounded-t-xl" : "rounded-xl"}`,
|
|
2340
|
+
children: [
|
|
2341
|
+
/* @__PURE__ */ jsx11(
|
|
2342
|
+
"span",
|
|
2343
|
+
{
|
|
2344
|
+
className: `size-7.5 rounded-full flex items-center justify-center ${actionIconClasses}`,
|
|
2345
|
+
children: icon
|
|
2346
|
+
}
|
|
2347
|
+
),
|
|
2348
|
+
/* @__PURE__ */ jsx11(
|
|
2349
|
+
Text_default,
|
|
2350
|
+
{
|
|
2351
|
+
size: "2xs",
|
|
2352
|
+
weight: "medium",
|
|
2353
|
+
className: "text-text-800 uppercase truncate",
|
|
2354
|
+
children: title
|
|
2355
|
+
}
|
|
2356
|
+
),
|
|
2357
|
+
/* @__PURE__ */ jsx11("p", { className: `text-lg font-bold truncate ${actionSubTitleClasses}`, children: subTitle })
|
|
2358
|
+
]
|
|
2359
|
+
}
|
|
2360
|
+
),
|
|
2361
|
+
extended && /* @__PURE__ */ jsxs9("div", { className: "flex flex-col items-center gap-2.5 pb-9.5 pt-2.5", children: [
|
|
2362
|
+
/* @__PURE__ */ jsx11(
|
|
2363
|
+
"p",
|
|
2364
|
+
{
|
|
2365
|
+
className: `text-2xs font-medium uppercase truncate ${actionHeaderClasses}`,
|
|
2366
|
+
children: header
|
|
2367
|
+
}
|
|
2368
|
+
),
|
|
2369
|
+
/* @__PURE__ */ jsx11(Badge_default, { size: "large", action: "info", children: description })
|
|
2370
|
+
] })
|
|
2371
|
+
]
|
|
2372
|
+
}
|
|
2373
|
+
);
|
|
2374
|
+
}
|
|
2375
|
+
);
|
|
2376
|
+
var CardQuestions = forwardRef6(
|
|
2377
|
+
({
|
|
2378
|
+
header,
|
|
2379
|
+
state = "undone",
|
|
2380
|
+
className,
|
|
2381
|
+
onClickButton,
|
|
2382
|
+
valueButton,
|
|
2383
|
+
...props
|
|
2384
|
+
}, ref) => {
|
|
2385
|
+
const isDone = state === "done";
|
|
2386
|
+
const stateLabel = isDone ? "Realizado" : "N\xE3o Realizado";
|
|
2387
|
+
const buttonLabel = isDone ? "Ver Quest\xE3o" : "Responder";
|
|
2388
|
+
return /* @__PURE__ */ jsxs9(
|
|
2389
|
+
CardBase,
|
|
2390
|
+
{
|
|
2391
|
+
ref,
|
|
2392
|
+
layout: "horizontal",
|
|
2393
|
+
padding: "medium",
|
|
2394
|
+
minHeight: "medium",
|
|
2395
|
+
className: `justify-between gap-4 ${className}`,
|
|
2396
|
+
...props,
|
|
2397
|
+
children: [
|
|
2398
|
+
/* @__PURE__ */ jsxs9("section", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [
|
|
2399
|
+
/* @__PURE__ */ jsx11("p", { className: "font-bold text-xs text-text-950 truncate", children: header }),
|
|
2400
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-row gap-6 items-center", children: [
|
|
2401
|
+
/* @__PURE__ */ jsx11(
|
|
2402
|
+
Badge_default,
|
|
2403
|
+
{
|
|
2404
|
+
size: "medium",
|
|
2405
|
+
variant: "solid",
|
|
2406
|
+
action: isDone ? "success" : "error",
|
|
2407
|
+
children: stateLabel
|
|
2408
|
+
}
|
|
2409
|
+
),
|
|
2410
|
+
/* @__PURE__ */ jsxs9("span", { className: "flex flex-row items-center gap-1 text-text-700 text-xs", children: [
|
|
2411
|
+
isDone ? "Nota" : "Sem nota",
|
|
2412
|
+
isDone && /* @__PURE__ */ jsx11(Badge_default, { size: "medium", action: "success", children: "00" })
|
|
2413
|
+
] })
|
|
2414
|
+
] })
|
|
2415
|
+
] }),
|
|
2416
|
+
/* @__PURE__ */ jsx11("span", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx11(
|
|
2417
|
+
Button_default,
|
|
2418
|
+
{
|
|
2419
|
+
size: "extra-small",
|
|
2420
|
+
onClick: () => onClickButton?.(valueButton),
|
|
2421
|
+
className: "min-w-fit",
|
|
2422
|
+
children: buttonLabel
|
|
2423
|
+
}
|
|
2424
|
+
) })
|
|
2425
|
+
]
|
|
2426
|
+
}
|
|
2427
|
+
);
|
|
2428
|
+
}
|
|
2429
|
+
);
|
|
2430
|
+
var CardProgress = forwardRef6(
|
|
2431
|
+
({
|
|
2432
|
+
header,
|
|
2433
|
+
subhead,
|
|
2434
|
+
initialDate,
|
|
2435
|
+
endDate,
|
|
2436
|
+
progress = 0,
|
|
2437
|
+
direction = "horizontal",
|
|
2438
|
+
icon,
|
|
2439
|
+
color = "#B7DFFF",
|
|
2440
|
+
progressVariant = "blue",
|
|
2441
|
+
showDates = true,
|
|
2442
|
+
className,
|
|
2443
|
+
...props
|
|
2444
|
+
}, ref) => {
|
|
2445
|
+
const isHorizontal = direction === "horizontal";
|
|
2446
|
+
const contentComponent = {
|
|
2447
|
+
horizontal: /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
2448
|
+
showDates && /* @__PURE__ */ jsxs9("div", { className: "flex flex-row gap-6 items-center", children: [
|
|
2449
|
+
initialDate && /* @__PURE__ */ jsxs9("span", { className: "flex flex-row gap-1 items-center text-2xs", children: [
|
|
2450
|
+
/* @__PURE__ */ jsx11("p", { className: "text-text-800 font-semibold", children: "In\xEDcio" }),
|
|
2451
|
+
/* @__PURE__ */ jsx11("p", { className: "text-text-600", children: initialDate })
|
|
2452
|
+
] }),
|
|
2453
|
+
endDate && /* @__PURE__ */ jsxs9("span", { className: "flex flex-row gap-1 items-center text-2xs", children: [
|
|
2454
|
+
/* @__PURE__ */ jsx11("p", { className: "text-text-800 font-semibold", children: "Fim" }),
|
|
2455
|
+
/* @__PURE__ */ jsx11("p", { className: "text-text-600", children: endDate })
|
|
2456
|
+
] })
|
|
2457
|
+
] }),
|
|
2458
|
+
/* @__PURE__ */ jsxs9("span", { className: "grid grid-cols-[1fr_auto] items-center gap-2", children: [
|
|
2459
|
+
/* @__PURE__ */ jsx11(
|
|
2460
|
+
ProgressBar_default,
|
|
2461
|
+
{
|
|
2462
|
+
size: "small",
|
|
2463
|
+
value: progress,
|
|
2464
|
+
variant: progressVariant,
|
|
2465
|
+
"data-testid": "progress-bar"
|
|
2466
|
+
}
|
|
2467
|
+
),
|
|
2468
|
+
/* @__PURE__ */ jsxs9(
|
|
2469
|
+
Text_default,
|
|
2470
|
+
{
|
|
2471
|
+
size: "xs",
|
|
2472
|
+
weight: "medium",
|
|
2473
|
+
className: `text-text-950 leading-none tracking-normal text-center flex-none`,
|
|
2474
|
+
children: [
|
|
2475
|
+
Math.round(progress),
|
|
2476
|
+
"%"
|
|
2477
|
+
]
|
|
2478
|
+
}
|
|
2479
|
+
)
|
|
2480
|
+
] })
|
|
2481
|
+
] }),
|
|
2482
|
+
vertical: /* @__PURE__ */ jsx11("p", { className: "text-sm text-text-800", children: subhead })
|
|
2483
|
+
};
|
|
2484
|
+
return /* @__PURE__ */ jsxs9(
|
|
2485
|
+
CardBase,
|
|
2486
|
+
{
|
|
2487
|
+
ref,
|
|
2488
|
+
layout: isHorizontal ? "horizontal" : "vertical",
|
|
2489
|
+
padding: "none",
|
|
2490
|
+
minHeight: "medium",
|
|
2491
|
+
cursor: "pointer",
|
|
2492
|
+
className: `${isHorizontal ? "h-20" : ""} ${className}`,
|
|
2493
|
+
...props,
|
|
2494
|
+
children: [
|
|
2495
|
+
/* @__PURE__ */ jsx11(
|
|
2496
|
+
"div",
|
|
2497
|
+
{
|
|
2498
|
+
className: `
|
|
2499
|
+
flex justify-center items-center [&>svg]:size-6 text-text-950
|
|
2500
|
+
${isHorizontal ? "min-w-[80px] min-h-[80px] rounded-l-xl" : "min-h-[50px] w-full rounded-t-xl"}
|
|
2501
|
+
${!color.startsWith("#") ? `bg-${color}` : ""}
|
|
2502
|
+
`,
|
|
2503
|
+
style: color.startsWith("#") ? { backgroundColor: color } : void 0,
|
|
2504
|
+
"data-testid": "icon-container",
|
|
2505
|
+
children: icon
|
|
2506
|
+
}
|
|
2507
|
+
),
|
|
2508
|
+
/* @__PURE__ */ jsxs9(
|
|
2509
|
+
"div",
|
|
2510
|
+
{
|
|
2511
|
+
className: `
|
|
2512
|
+
p-4 flex flex-col justify-between w-full h-full
|
|
2513
|
+
${!isHorizontal && "gap-4"}
|
|
2514
|
+
`,
|
|
2515
|
+
children: [
|
|
2516
|
+
/* @__PURE__ */ jsx11(Text_default, { size: "sm", weight: "bold", className: "text-text-950 truncate", children: header }),
|
|
2517
|
+
contentComponent[direction]
|
|
2518
|
+
]
|
|
2519
|
+
}
|
|
2520
|
+
)
|
|
2521
|
+
]
|
|
2522
|
+
}
|
|
2523
|
+
);
|
|
2524
|
+
}
|
|
2525
|
+
);
|
|
2526
|
+
var CardTopic = forwardRef6(
|
|
2527
|
+
({
|
|
2528
|
+
header,
|
|
2529
|
+
subHead,
|
|
2530
|
+
progress,
|
|
2531
|
+
showPercentage = false,
|
|
2532
|
+
progressVariant = "blue",
|
|
2533
|
+
className = "",
|
|
2534
|
+
...props
|
|
2535
|
+
}, ref) => {
|
|
2536
|
+
return /* @__PURE__ */ jsxs9(
|
|
2537
|
+
CardBase,
|
|
2538
|
+
{
|
|
2539
|
+
ref,
|
|
2540
|
+
layout: "vertical",
|
|
2541
|
+
padding: "small",
|
|
2542
|
+
minHeight: "medium",
|
|
2543
|
+
cursor: "pointer",
|
|
2544
|
+
className: `justify-center gap-2 py-2 px-4 ${className}`,
|
|
2545
|
+
...props,
|
|
2546
|
+
children: [
|
|
2547
|
+
subHead && /* @__PURE__ */ jsx11("span", { className: "text-text-600 text-2xs flex flex-row gap-1", children: subHead.map((text, index) => /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
2548
|
+
/* @__PURE__ */ jsx11("p", { children: text }),
|
|
2549
|
+
index < subHead.length - 1 && /* @__PURE__ */ jsx11("p", { children: "\u2022" })
|
|
2550
|
+
] }, `${text} - ${index}`)) }),
|
|
2551
|
+
/* @__PURE__ */ jsx11("p", { className: "text-sm text-text-950 font-bold truncate", children: header }),
|
|
2552
|
+
/* @__PURE__ */ jsxs9("span", { className: "grid grid-cols-[1fr_auto] items-center gap-2", children: [
|
|
2553
|
+
/* @__PURE__ */ jsx11(
|
|
2554
|
+
ProgressBar_default,
|
|
2555
|
+
{
|
|
2556
|
+
size: "small",
|
|
2557
|
+
value: progress,
|
|
2558
|
+
variant: progressVariant,
|
|
2559
|
+
"data-testid": "progress-bar"
|
|
2560
|
+
}
|
|
2561
|
+
),
|
|
2562
|
+
showPercentage && /* @__PURE__ */ jsxs9(
|
|
2563
|
+
Text_default,
|
|
2564
|
+
{
|
|
2565
|
+
size: "xs",
|
|
2566
|
+
weight: "medium",
|
|
2567
|
+
className: `text-text-950 leading-none tracking-normal text-center flex-none`,
|
|
2568
|
+
children: [
|
|
2569
|
+
Math.round(progress),
|
|
2570
|
+
"%"
|
|
2571
|
+
]
|
|
2572
|
+
}
|
|
2573
|
+
)
|
|
2574
|
+
] })
|
|
2575
|
+
]
|
|
2576
|
+
}
|
|
2577
|
+
);
|
|
2578
|
+
}
|
|
2579
|
+
);
|
|
2580
|
+
var CardPerformance = forwardRef6(
|
|
2581
|
+
({
|
|
2582
|
+
header,
|
|
2583
|
+
progress,
|
|
2584
|
+
description = "Sem dados ainda! Voc\xEA ainda n\xE3o fez um question\xE1rio neste assunto.",
|
|
2585
|
+
actionVariant = "button",
|
|
2586
|
+
progressVariant = "blue",
|
|
2587
|
+
labelProgress = "",
|
|
2588
|
+
className = "",
|
|
2589
|
+
onClickButton,
|
|
2590
|
+
valueButton,
|
|
2591
|
+
...props
|
|
2592
|
+
}, ref) => {
|
|
2593
|
+
const hasProgress = progress !== void 0;
|
|
2594
|
+
return /* @__PURE__ */ jsxs9(
|
|
2595
|
+
CardBase,
|
|
2596
|
+
{
|
|
2597
|
+
ref,
|
|
2598
|
+
layout: "horizontal",
|
|
2599
|
+
padding: "medium",
|
|
2600
|
+
minHeight: "none",
|
|
2601
|
+
className: `justify-between gap-2 ${actionVariant == "caret" ? "cursor-pointer" : ""} ${className}`,
|
|
2602
|
+
onClick: () => actionVariant == "caret" && onClickButton?.(valueButton),
|
|
2603
|
+
...props,
|
|
2604
|
+
children: [
|
|
2605
|
+
/* @__PURE__ */ jsxs9("div", { className: "w-full flex flex-col justify-between gap-2", children: [
|
|
2606
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-row justify-between items-center gap-2", children: [
|
|
2607
|
+
/* @__PURE__ */ jsx11("p", { className: "text-lg font-bold text-text-950 truncate flex-1 min-w-0", children: header }),
|
|
2608
|
+
actionVariant === "button" && /* @__PURE__ */ jsx11(
|
|
2609
|
+
Button_default,
|
|
2610
|
+
{
|
|
2611
|
+
variant: "outline",
|
|
2612
|
+
size: "extra-small",
|
|
2613
|
+
onClick: () => onClickButton?.(valueButton),
|
|
2614
|
+
className: "min-w-fit flex-shrink-0",
|
|
2615
|
+
children: "Ver Aula"
|
|
2616
|
+
}
|
|
2617
|
+
)
|
|
2618
|
+
] }),
|
|
2619
|
+
/* @__PURE__ */ jsx11("div", { className: "w-full", children: hasProgress ? /* @__PURE__ */ jsx11(
|
|
2620
|
+
ProgressBar_default,
|
|
2621
|
+
{
|
|
2622
|
+
value: progress,
|
|
2623
|
+
label: `${progress}% ${labelProgress}`,
|
|
2624
|
+
variant: progressVariant
|
|
2625
|
+
}
|
|
2626
|
+
) : /* @__PURE__ */ jsx11("p", { className: "text-xs text-text-600 truncate", children: description }) })
|
|
2627
|
+
] }),
|
|
2628
|
+
actionVariant == "caret" && /* @__PURE__ */ jsx11(
|
|
2629
|
+
CaretRight,
|
|
2630
|
+
{
|
|
2631
|
+
className: "size-4.5 text-text-800 cursor-pointer",
|
|
2632
|
+
"data-testid": "caret-icon"
|
|
2633
|
+
}
|
|
2634
|
+
)
|
|
2635
|
+
]
|
|
2636
|
+
}
|
|
2637
|
+
);
|
|
2638
|
+
}
|
|
2639
|
+
);
|
|
2640
|
+
var CardResults = forwardRef6(
|
|
2641
|
+
({
|
|
2642
|
+
header,
|
|
2643
|
+
correct_answers,
|
|
2644
|
+
incorrect_answers,
|
|
2645
|
+
icon,
|
|
2646
|
+
direction = "col",
|
|
2647
|
+
color = "#B7DFFF",
|
|
2648
|
+
className,
|
|
2649
|
+
...props
|
|
2650
|
+
}, ref) => {
|
|
2651
|
+
const isRow = direction == "row";
|
|
2652
|
+
return /* @__PURE__ */ jsxs9(
|
|
2653
|
+
CardBase,
|
|
2654
|
+
{
|
|
2655
|
+
ref,
|
|
2656
|
+
layout: "horizontal",
|
|
2657
|
+
padding: "none",
|
|
2658
|
+
minHeight: "medium",
|
|
2659
|
+
className: `items-center cursor-pointer pr-4 ${className}`,
|
|
2660
|
+
...props,
|
|
2661
|
+
children: [
|
|
2662
|
+
/* @__PURE__ */ jsx11(
|
|
2663
|
+
"div",
|
|
2664
|
+
{
|
|
2665
|
+
className: `
|
|
2666
|
+
flex justify-center items-center [&>svg]:size-8 text-text-950 min-w-20 max-w-20 min-h-20 h-full rounded-l-xl
|
|
2667
|
+
`,
|
|
2668
|
+
style: {
|
|
2669
|
+
backgroundColor: color
|
|
2670
|
+
},
|
|
2671
|
+
children: icon
|
|
2672
|
+
}
|
|
2673
|
+
),
|
|
2674
|
+
/* @__PURE__ */ jsxs9(
|
|
2675
|
+
"div",
|
|
2676
|
+
{
|
|
2677
|
+
className: `
|
|
2678
|
+
p-4 flex justify-between w-full h-full
|
|
2679
|
+
${isRow ? "flex-row items-center gap-2" : "flex-col"}
|
|
2680
|
+
`,
|
|
2681
|
+
children: [
|
|
2682
|
+
/* @__PURE__ */ jsx11("p", { className: "text-sm font-bold text-text-950 truncate flex-1 min-w-0", children: header }),
|
|
2683
|
+
/* @__PURE__ */ jsxs9("span", { className: "flex flex-row gap-1 items-center", children: [
|
|
2684
|
+
/* @__PURE__ */ jsxs9(
|
|
2685
|
+
Badge_default,
|
|
2686
|
+
{
|
|
2687
|
+
action: "success",
|
|
2688
|
+
variant: "solid",
|
|
2689
|
+
size: "large",
|
|
2690
|
+
iconLeft: /* @__PURE__ */ jsx11(CheckCircle2, {}),
|
|
2691
|
+
children: [
|
|
2692
|
+
correct_answers,
|
|
2693
|
+
" Corretas"
|
|
2694
|
+
]
|
|
2695
|
+
}
|
|
2696
|
+
),
|
|
2697
|
+
/* @__PURE__ */ jsxs9(
|
|
2698
|
+
Badge_default,
|
|
2699
|
+
{
|
|
2700
|
+
action: "error",
|
|
2701
|
+
variant: "solid",
|
|
2702
|
+
size: "large",
|
|
2703
|
+
iconLeft: /* @__PURE__ */ jsx11(XCircle2, {}),
|
|
2704
|
+
children: [
|
|
2705
|
+
incorrect_answers,
|
|
2706
|
+
" Incorretas"
|
|
2707
|
+
]
|
|
2708
|
+
}
|
|
2709
|
+
)
|
|
2710
|
+
] })
|
|
2711
|
+
]
|
|
2712
|
+
}
|
|
2713
|
+
),
|
|
2714
|
+
/* @__PURE__ */ jsx11(CaretRight, { className: "min-w-6 min-h-6 text-text-800" })
|
|
2715
|
+
]
|
|
2716
|
+
}
|
|
2717
|
+
);
|
|
2718
|
+
}
|
|
2719
|
+
);
|
|
2720
|
+
var CardStatus = forwardRef6(
|
|
2721
|
+
({ header, className, status, label, ...props }, ref) => {
|
|
2722
|
+
return /* @__PURE__ */ jsx11(
|
|
2723
|
+
CardBase,
|
|
2724
|
+
{
|
|
2725
|
+
ref,
|
|
2726
|
+
layout: "horizontal",
|
|
2727
|
+
padding: "medium",
|
|
2728
|
+
minHeight: "medium",
|
|
2729
|
+
className: `items-center cursor-pointer ${className}`,
|
|
2730
|
+
...props,
|
|
2731
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex justify-between w-full h-full flex-row items-center gap-2", children: [
|
|
2732
|
+
/* @__PURE__ */ jsx11("p", { className: "text-sm font-bold text-text-950 truncate flex-1 min-w-0", children: header }),
|
|
2733
|
+
/* @__PURE__ */ jsxs9("span", { className: "flex flex-row gap-1 items-center flex-shrink-0", children: [
|
|
2734
|
+
status && /* @__PURE__ */ jsx11(
|
|
2735
|
+
Badge_default,
|
|
2736
|
+
{
|
|
2737
|
+
action: status == "correct" ? "success" : "error",
|
|
2738
|
+
variant: "solid",
|
|
2739
|
+
size: "medium",
|
|
2740
|
+
iconLeft: /* @__PURE__ */ jsx11(CheckCircle2, {}),
|
|
2741
|
+
children: status == "correct" ? "Correta" : "Incorreta"
|
|
2742
|
+
}
|
|
2743
|
+
),
|
|
2744
|
+
label && /* @__PURE__ */ jsx11("p", { className: "text-sm text-text-800", children: label })
|
|
2745
|
+
] }),
|
|
2746
|
+
/* @__PURE__ */ jsx11(CaretRight, { className: "min-w-6 min-h-6 text-text-800 cursor-pointer flex-shrink-0 ml-2" })
|
|
2747
|
+
] })
|
|
2748
|
+
}
|
|
2749
|
+
);
|
|
2750
|
+
}
|
|
2751
|
+
);
|
|
2752
|
+
var CardSettings = forwardRef6(
|
|
2753
|
+
({ header, className, icon, ...props }, ref) => {
|
|
2754
|
+
return /* @__PURE__ */ jsxs9(
|
|
2755
|
+
CardBase,
|
|
2756
|
+
{
|
|
2757
|
+
ref,
|
|
2758
|
+
layout: "horizontal",
|
|
2759
|
+
padding: "small",
|
|
2760
|
+
minHeight: "none",
|
|
2761
|
+
className: `border-none items-center gap-2 text-text-700 ${className}`,
|
|
2762
|
+
...props,
|
|
2763
|
+
children: [
|
|
2764
|
+
/* @__PURE__ */ jsx11("span", { className: "[&>svg]:size-6", children: icon }),
|
|
2765
|
+
/* @__PURE__ */ jsx11("p", { className: "w-full text-sm truncate", children: header }),
|
|
2766
|
+
/* @__PURE__ */ jsx11(CaretRight, { size: 24, className: "cursor-pointer" })
|
|
2767
|
+
]
|
|
2768
|
+
}
|
|
2769
|
+
);
|
|
2770
|
+
}
|
|
2771
|
+
);
|
|
2772
|
+
var CardSupport = forwardRef6(
|
|
2773
|
+
({ header, className, direction = "col", children, ...props }, ref) => {
|
|
2774
|
+
return /* @__PURE__ */ jsxs9(
|
|
2775
|
+
CardBase,
|
|
2776
|
+
{
|
|
2777
|
+
ref,
|
|
2778
|
+
layout: "horizontal",
|
|
2779
|
+
padding: "medium",
|
|
2780
|
+
minHeight: "none",
|
|
2781
|
+
className: `border-none items-center gap-2 text-text-700 ${className}`,
|
|
2782
|
+
...props,
|
|
2783
|
+
children: [
|
|
2784
|
+
/* @__PURE__ */ jsxs9(
|
|
2785
|
+
"div",
|
|
2786
|
+
{
|
|
2787
|
+
className: `
|
|
2788
|
+
w-full flex ${direction == "col" ? "flex-col" : "flex-row items-center"} gap-2
|
|
2789
|
+
`,
|
|
2790
|
+
children: [
|
|
2791
|
+
/* @__PURE__ */ jsx11("span", { className: "w-full min-w-0", children: /* @__PURE__ */ jsx11("p", { className: "text-sm text-text-950 font-bold truncate", children: header }) }),
|
|
2792
|
+
/* @__PURE__ */ jsx11("span", { className: "flex flex-row gap-1", children })
|
|
2793
|
+
]
|
|
2794
|
+
}
|
|
2795
|
+
),
|
|
2796
|
+
/* @__PURE__ */ jsx11(CaretRight, { className: "text-text-800 cursor-pointer", size: 24 })
|
|
2797
|
+
]
|
|
2798
|
+
}
|
|
2799
|
+
);
|
|
2800
|
+
}
|
|
2801
|
+
);
|
|
2802
|
+
var CardForum = forwardRef6(
|
|
2803
|
+
({
|
|
2804
|
+
title,
|
|
2805
|
+
content,
|
|
2806
|
+
comments,
|
|
2807
|
+
onClickComments,
|
|
2808
|
+
valueComments,
|
|
2809
|
+
onClickProfile,
|
|
2810
|
+
valueProfile,
|
|
2811
|
+
className = "",
|
|
2812
|
+
date,
|
|
2813
|
+
hour,
|
|
2814
|
+
...props
|
|
2815
|
+
}, ref) => {
|
|
2816
|
+
return /* @__PURE__ */ jsxs9(
|
|
2817
|
+
CardBase,
|
|
2818
|
+
{
|
|
2819
|
+
ref,
|
|
2820
|
+
layout: "horizontal",
|
|
2821
|
+
padding: "medium",
|
|
2822
|
+
minHeight: "none",
|
|
2823
|
+
variant: "minimal",
|
|
2824
|
+
className: `w-auto h-auto gap-3 ${className}`,
|
|
2825
|
+
...props,
|
|
2826
|
+
children: [
|
|
2827
|
+
/* @__PURE__ */ jsx11(
|
|
2828
|
+
"button",
|
|
2829
|
+
{
|
|
2830
|
+
type: "button",
|
|
2831
|
+
"aria-label": "Ver perfil",
|
|
2832
|
+
onClick: () => onClickProfile?.(valueProfile),
|
|
2833
|
+
className: "min-w-8 h-8 rounded-full bg-background-950"
|
|
2834
|
+
}
|
|
2835
|
+
),
|
|
2836
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [
|
|
2837
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-row gap-1 items-center flex-wrap", children: [
|
|
2838
|
+
/* @__PURE__ */ jsx11("p", { className: "text-xs font-semibold text-primary-700 truncate", children: title }),
|
|
2839
|
+
/* @__PURE__ */ jsxs9("p", { className: "text-xs text-text-600", children: [
|
|
2840
|
+
"\u2022 ",
|
|
2841
|
+
date,
|
|
2842
|
+
" \u2022 ",
|
|
2843
|
+
hour
|
|
2844
|
+
] })
|
|
2845
|
+
] }),
|
|
2846
|
+
/* @__PURE__ */ jsx11("p", { className: "text-text-950 text-sm line-clamp-2 truncate", children: content }),
|
|
2847
|
+
/* @__PURE__ */ jsxs9(
|
|
2848
|
+
"button",
|
|
2849
|
+
{
|
|
2850
|
+
type: "button",
|
|
2851
|
+
"aria-label": "Ver coment\xE1rios",
|
|
2852
|
+
onClick: () => onClickComments?.(valueComments),
|
|
2853
|
+
className: "text-text-600 flex flex-row gap-2 items-center",
|
|
2854
|
+
children: [
|
|
2855
|
+
/* @__PURE__ */ jsx11(ChatCircleText, { "aria-hidden": "true", size: 16 }),
|
|
2856
|
+
/* @__PURE__ */ jsxs9("p", { className: "text-xs", children: [
|
|
2857
|
+
comments,
|
|
2858
|
+
" respostas"
|
|
2859
|
+
] })
|
|
2860
|
+
]
|
|
2861
|
+
}
|
|
2862
|
+
)
|
|
2863
|
+
] })
|
|
2864
|
+
]
|
|
2865
|
+
}
|
|
2866
|
+
);
|
|
2867
|
+
}
|
|
2868
|
+
);
|
|
2869
|
+
var CardAudio = forwardRef6(
|
|
2870
|
+
({
|
|
2871
|
+
src,
|
|
2872
|
+
title,
|
|
2873
|
+
onPlay,
|
|
2874
|
+
onPause,
|
|
2875
|
+
onEnded,
|
|
2876
|
+
onAudioTimeUpdate,
|
|
2877
|
+
loop = false,
|
|
2878
|
+
preload = "metadata",
|
|
2879
|
+
tracks,
|
|
2880
|
+
className,
|
|
2881
|
+
...props
|
|
2882
|
+
}, ref) => {
|
|
2883
|
+
const [isPlaying, setIsPlaying] = useState3(false);
|
|
2884
|
+
const [currentTime, setCurrentTime] = useState3(0);
|
|
2885
|
+
const [duration, setDuration] = useState3(0);
|
|
2886
|
+
const [volume, setVolume] = useState3(1);
|
|
2887
|
+
const [showVolumeControl, setShowVolumeControl] = useState3(false);
|
|
2888
|
+
const audioRef = useRef3(null);
|
|
2889
|
+
const formatTime = (time) => {
|
|
2890
|
+
const minutes = Math.floor(time / 60);
|
|
2891
|
+
const seconds = Math.floor(time % 60);
|
|
2892
|
+
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
|
2893
|
+
};
|
|
2894
|
+
const handlePlayPause = () => {
|
|
2895
|
+
if (isPlaying) {
|
|
2896
|
+
audioRef.current?.pause();
|
|
2897
|
+
setIsPlaying(false);
|
|
2898
|
+
onPause?.();
|
|
2899
|
+
} else {
|
|
2900
|
+
audioRef.current?.play();
|
|
2901
|
+
setIsPlaying(true);
|
|
2902
|
+
onPlay?.();
|
|
2903
|
+
}
|
|
2904
|
+
};
|
|
2905
|
+
const handleTimeUpdate = () => {
|
|
2906
|
+
const current = audioRef.current?.currentTime ?? 0;
|
|
2907
|
+
const total = audioRef.current?.duration ?? 0;
|
|
2908
|
+
setCurrentTime(current);
|
|
2909
|
+
setDuration(total);
|
|
2910
|
+
onAudioTimeUpdate?.(current, total);
|
|
2911
|
+
};
|
|
2912
|
+
const handleLoadedMetadata = () => {
|
|
2913
|
+
setDuration(audioRef.current?.duration ?? 0);
|
|
2914
|
+
};
|
|
2915
|
+
const handleEnded = () => {
|
|
2916
|
+
setIsPlaying(false);
|
|
2917
|
+
setCurrentTime(0);
|
|
2918
|
+
onEnded?.();
|
|
2919
|
+
};
|
|
2920
|
+
const handleProgressClick = (e) => {
|
|
2921
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
2922
|
+
const clickX = e.clientX - rect.left;
|
|
2923
|
+
const width = rect.width;
|
|
2924
|
+
const percentage = clickX / width;
|
|
2925
|
+
const newTime = percentage * duration;
|
|
2926
|
+
if (audioRef.current) {
|
|
2927
|
+
audioRef.current.currentTime = newTime;
|
|
2928
|
+
}
|
|
2929
|
+
setCurrentTime(newTime);
|
|
2930
|
+
};
|
|
2931
|
+
const handleVolumeChange = (e) => {
|
|
2932
|
+
const newVolume = parseFloat(e.target.value);
|
|
2933
|
+
setVolume(newVolume);
|
|
2934
|
+
if (audioRef.current) {
|
|
2935
|
+
audioRef.current.volume = newVolume;
|
|
2936
|
+
}
|
|
2937
|
+
};
|
|
2938
|
+
const toggleVolumeControl = () => {
|
|
2939
|
+
setShowVolumeControl(!showVolumeControl);
|
|
2940
|
+
};
|
|
2941
|
+
const getVolumeIcon = () => {
|
|
2942
|
+
if (volume === 0) {
|
|
2943
|
+
return /* @__PURE__ */ jsx11(SpeakerSimpleX, {});
|
|
2944
|
+
}
|
|
2945
|
+
if (volume < 0.5) {
|
|
2946
|
+
return /* @__PURE__ */ jsx11(SpeakerLow, {});
|
|
2947
|
+
}
|
|
2948
|
+
return /* @__PURE__ */ jsx11(SpeakerHigh, {});
|
|
2949
|
+
};
|
|
2950
|
+
return /* @__PURE__ */ jsxs9(
|
|
2951
|
+
CardBase,
|
|
2952
|
+
{
|
|
2953
|
+
ref,
|
|
2954
|
+
layout: "horizontal",
|
|
2955
|
+
padding: "medium",
|
|
2956
|
+
minHeight: "none",
|
|
2957
|
+
className: `w-auto h-14 items-center gap-2 ${className}`,
|
|
2958
|
+
...props,
|
|
2959
|
+
children: [
|
|
2960
|
+
/* @__PURE__ */ jsx11(
|
|
2961
|
+
"audio",
|
|
2962
|
+
{
|
|
2963
|
+
ref: audioRef,
|
|
2964
|
+
src,
|
|
2965
|
+
loop,
|
|
2966
|
+
preload,
|
|
2967
|
+
onTimeUpdate: handleTimeUpdate,
|
|
2968
|
+
onLoadedMetadata: handleLoadedMetadata,
|
|
2969
|
+
onEnded: handleEnded,
|
|
2970
|
+
"data-testid": "audio-element",
|
|
2971
|
+
"aria-label": title,
|
|
2972
|
+
children: tracks ? tracks.map((track) => /* @__PURE__ */ jsx11(
|
|
2973
|
+
"track",
|
|
2974
|
+
{
|
|
2975
|
+
kind: track.kind,
|
|
2976
|
+
src: track.src,
|
|
2977
|
+
srcLang: track.srcLang,
|
|
2978
|
+
label: track.label,
|
|
2979
|
+
default: track.default
|
|
2980
|
+
},
|
|
2981
|
+
track.src
|
|
2982
|
+
)) : /* @__PURE__ */ jsx11(
|
|
2983
|
+
"track",
|
|
2984
|
+
{
|
|
2985
|
+
kind: "captions",
|
|
2986
|
+
src: "data:text/vtt;base64,",
|
|
2987
|
+
srcLang: "pt",
|
|
2988
|
+
label: "Sem legendas dispon\xEDveis"
|
|
2989
|
+
}
|
|
2990
|
+
)
|
|
2991
|
+
}
|
|
2992
|
+
),
|
|
2993
|
+
/* @__PURE__ */ jsx11(
|
|
2994
|
+
"button",
|
|
2995
|
+
{
|
|
2996
|
+
type: "button",
|
|
2997
|
+
onClick: handlePlayPause,
|
|
2998
|
+
disabled: !src,
|
|
2999
|
+
className: "cursor-pointer text-text-950 hover:text-primary-600 disabled:text-text-400 disabled:cursor-not-allowed",
|
|
3000
|
+
"aria-label": isPlaying ? "Pausar" : "Reproduzir",
|
|
3001
|
+
children: isPlaying ? /* @__PURE__ */ jsx11("div", { className: "w-6 h-6 flex items-center justify-center", children: /* @__PURE__ */ jsxs9("div", { className: "flex gap-0.5", children: [
|
|
3002
|
+
/* @__PURE__ */ jsx11("div", { className: "w-1 h-4 bg-current rounded-sm" }),
|
|
3003
|
+
/* @__PURE__ */ jsx11("div", { className: "w-1 h-4 bg-current rounded-sm" })
|
|
3004
|
+
] }) }) : /* @__PURE__ */ jsx11(Play, { size: 24 })
|
|
3005
|
+
}
|
|
3006
|
+
),
|
|
3007
|
+
/* @__PURE__ */ jsx11("p", { className: "text-text-800 text-sm font-medium min-w-[2.5rem]", children: formatTime(currentTime) }),
|
|
3008
|
+
/* @__PURE__ */ jsx11("div", { className: "flex-1 relative", "data-testid": "progress-bar", children: /* @__PURE__ */ jsx11(
|
|
3009
|
+
"button",
|
|
3010
|
+
{
|
|
3011
|
+
type: "button",
|
|
3012
|
+
className: "w-full h-2 bg-border-100 rounded-full cursor-pointer",
|
|
3013
|
+
onClick: handleProgressClick,
|
|
3014
|
+
onKeyDown: (e) => {
|
|
3015
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3016
|
+
e.preventDefault();
|
|
3017
|
+
handleProgressClick(
|
|
3018
|
+
e
|
|
3019
|
+
);
|
|
3020
|
+
}
|
|
3021
|
+
},
|
|
3022
|
+
"aria-label": "Barra de progresso do \xE1udio",
|
|
3023
|
+
children: /* @__PURE__ */ jsx11(
|
|
3024
|
+
"div",
|
|
3025
|
+
{
|
|
3026
|
+
className: "h-full bg-primary-600 rounded-full transition-all duration-100",
|
|
3027
|
+
style: {
|
|
3028
|
+
width: duration > 0 ? `${currentTime / duration * 100}%` : "0%"
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
3031
|
+
)
|
|
3032
|
+
}
|
|
3033
|
+
) }),
|
|
3034
|
+
/* @__PURE__ */ jsx11("p", { className: "text-text-800 text-sm font-medium min-w-[2.5rem]", children: formatTime(duration) }),
|
|
3035
|
+
/* @__PURE__ */ jsxs9("div", { className: "relative", children: [
|
|
3036
|
+
/* @__PURE__ */ jsx11(
|
|
3037
|
+
"button",
|
|
3038
|
+
{
|
|
3039
|
+
type: "button",
|
|
3040
|
+
onClick: toggleVolumeControl,
|
|
3041
|
+
className: "cursor-pointer text-text-950 hover:text-primary-600",
|
|
3042
|
+
"aria-label": "Controle de volume",
|
|
3043
|
+
children: /* @__PURE__ */ jsx11("div", { className: "w-6 h-6 flex items-center justify-center", children: getVolumeIcon() })
|
|
3044
|
+
}
|
|
3045
|
+
),
|
|
3046
|
+
showVolumeControl && /* @__PURE__ */ jsx11(
|
|
3047
|
+
"button",
|
|
3048
|
+
{
|
|
3049
|
+
type: "button",
|
|
3050
|
+
className: "absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg focus:outline-none focus:ring-2 focus:ring-primary-500",
|
|
3051
|
+
onKeyDown: (e) => {
|
|
3052
|
+
if (e.key === "Escape") {
|
|
3053
|
+
setShowVolumeControl(false);
|
|
3054
|
+
}
|
|
3055
|
+
},
|
|
3056
|
+
children: /* @__PURE__ */ jsx11(
|
|
3057
|
+
"input",
|
|
3058
|
+
{
|
|
3059
|
+
type: "range",
|
|
3060
|
+
min: "0",
|
|
3061
|
+
max: "1",
|
|
3062
|
+
step: "0.1",
|
|
3063
|
+
value: volume,
|
|
3064
|
+
onChange: handleVolumeChange,
|
|
3065
|
+
onKeyDown: (e) => {
|
|
3066
|
+
if (e.key === "ArrowUp" || e.key === "ArrowRight") {
|
|
3067
|
+
e.preventDefault();
|
|
3068
|
+
const newVolume = Math.min(
|
|
3069
|
+
1,
|
|
3070
|
+
Math.round((volume + 0.1) * 10) / 10
|
|
3071
|
+
);
|
|
3072
|
+
setVolume(newVolume);
|
|
3073
|
+
if (audioRef.current) audioRef.current.volume = newVolume;
|
|
3074
|
+
} else if (e.key === "ArrowDown" || e.key === "ArrowLeft") {
|
|
3075
|
+
e.preventDefault();
|
|
3076
|
+
const newVolume = Math.max(
|
|
3077
|
+
0,
|
|
3078
|
+
Math.round((volume - 0.1) * 10) / 10
|
|
3079
|
+
);
|
|
3080
|
+
setVolume(newVolume);
|
|
3081
|
+
if (audioRef.current) audioRef.current.volume = newVolume;
|
|
3082
|
+
}
|
|
3083
|
+
},
|
|
3084
|
+
className: "w-20 h-2 bg-border-100 rounded-lg appearance-none cursor-pointer",
|
|
3085
|
+
style: {
|
|
3086
|
+
background: `linear-gradient(to right, #3b82f6 0%, #3b82f6 ${volume * 100}%, #e5e7eb ${volume * 100}%, #e5e7eb 100%)`
|
|
3087
|
+
},
|
|
3088
|
+
"aria-label": "Volume",
|
|
3089
|
+
"aria-valuenow": Math.round(volume * 100),
|
|
3090
|
+
"aria-valuemin": 0,
|
|
3091
|
+
"aria-valuemax": 100
|
|
3092
|
+
}
|
|
3093
|
+
)
|
|
3094
|
+
}
|
|
3095
|
+
)
|
|
3096
|
+
] }),
|
|
3097
|
+
/* @__PURE__ */ jsx11(
|
|
3098
|
+
DotsThreeVertical,
|
|
3099
|
+
{
|
|
3100
|
+
size: 24,
|
|
3101
|
+
className: "text-text-950 cursor-pointer hover:text-primary-600"
|
|
3102
|
+
}
|
|
3103
|
+
)
|
|
3104
|
+
]
|
|
3105
|
+
}
|
|
3106
|
+
);
|
|
3107
|
+
}
|
|
3108
|
+
);
|
|
3109
|
+
var SIMULADO_BACKGROUND_CLASSES = {
|
|
3110
|
+
enem: "bg-exam-1",
|
|
3111
|
+
prova: "bg-exam-2",
|
|
3112
|
+
simuladao: "bg-exam-3",
|
|
3113
|
+
vestibular: "bg-exam-4"
|
|
3114
|
+
};
|
|
3115
|
+
var CardSimulado = forwardRef6(
|
|
3116
|
+
({ title, duration, info, backgroundColor, className, ...props }, ref) => {
|
|
3117
|
+
const backgroundClass = SIMULADO_BACKGROUND_CLASSES[backgroundColor];
|
|
3118
|
+
return /* @__PURE__ */ jsx11(
|
|
3119
|
+
CardBase,
|
|
3120
|
+
{
|
|
3121
|
+
ref,
|
|
3122
|
+
layout: "horizontal",
|
|
3123
|
+
padding: "medium",
|
|
3124
|
+
minHeight: "none",
|
|
3125
|
+
cursor: "pointer",
|
|
3126
|
+
className: `${backgroundClass} hover:shadow-soft-shadow-2 transition-shadow duration-200 ${className}`,
|
|
3127
|
+
...props,
|
|
3128
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex justify-between items-center w-full gap-4", children: [
|
|
3129
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [
|
|
3130
|
+
/* @__PURE__ */ jsx11(Text_default, { size: "lg", weight: "bold", className: "text-text-950 truncate", children: title }),
|
|
3131
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-4 text-text-700", children: [
|
|
3132
|
+
duration && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1", children: [
|
|
3133
|
+
/* @__PURE__ */ jsx11(Clock, { size: 16, className: "flex-shrink-0" }),
|
|
3134
|
+
/* @__PURE__ */ jsx11(Text_default, { size: "sm", children: duration })
|
|
3135
|
+
] }),
|
|
3136
|
+
/* @__PURE__ */ jsx11(Text_default, { size: "sm", className: "truncate", children: info })
|
|
3137
|
+
] })
|
|
3138
|
+
] }),
|
|
3139
|
+
/* @__PURE__ */ jsx11(
|
|
3140
|
+
CaretRight,
|
|
3141
|
+
{
|
|
3142
|
+
size: 24,
|
|
3143
|
+
className: "text-text-800 flex-shrink-0",
|
|
3144
|
+
"data-testid": "caret-icon"
|
|
3145
|
+
}
|
|
3146
|
+
)
|
|
3147
|
+
] })
|
|
3148
|
+
}
|
|
3149
|
+
);
|
|
3150
|
+
}
|
|
3151
|
+
);
|
|
3152
|
+
var CardTest = forwardRef6(
|
|
3153
|
+
({
|
|
3154
|
+
title,
|
|
3155
|
+
duration,
|
|
3156
|
+
questionsCount,
|
|
3157
|
+
additionalInfo,
|
|
3158
|
+
selected = false,
|
|
3159
|
+
onSelect,
|
|
3160
|
+
className = "",
|
|
3161
|
+
...props
|
|
3162
|
+
}, ref) => {
|
|
3163
|
+
const handleClick = () => {
|
|
3164
|
+
if (onSelect) {
|
|
3165
|
+
onSelect(!selected);
|
|
3166
|
+
}
|
|
3167
|
+
};
|
|
3168
|
+
const handleKeyDown = (event) => {
|
|
3169
|
+
if ((event.key === "Enter" || event.key === " ") && onSelect) {
|
|
3170
|
+
event.preventDefault();
|
|
3171
|
+
onSelect(!selected);
|
|
3172
|
+
}
|
|
3173
|
+
};
|
|
3174
|
+
const isSelectable = !!onSelect;
|
|
3175
|
+
const getQuestionsText = (count) => {
|
|
3176
|
+
const singular = count === 1 ? "quest\xE3o" : "quest\xF5es";
|
|
3177
|
+
return `${count} ${singular}`;
|
|
3178
|
+
};
|
|
3179
|
+
const displayInfo = questionsCount ? getQuestionsText(questionsCount) : additionalInfo || "";
|
|
3180
|
+
const baseClasses = "flex flex-row items-center p-4 gap-2 w-full max-w-full bg-background shadow-soft-shadow-1 rounded-xl isolate border-0 text-left";
|
|
3181
|
+
const interactiveClasses = isSelectable ? "cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-950 focus:ring-offset-2" : "";
|
|
3182
|
+
const selectedClasses = selected ? "ring-2 ring-primary-950 ring-offset-2" : "";
|
|
3183
|
+
if (isSelectable) {
|
|
3184
|
+
return /* @__PURE__ */ jsx11(
|
|
3185
|
+
"button",
|
|
3186
|
+
{
|
|
3187
|
+
ref,
|
|
3188
|
+
type: "button",
|
|
3189
|
+
className: `${baseClasses} ${interactiveClasses} ${selectedClasses} ${className}`.trim(),
|
|
3190
|
+
onClick: handleClick,
|
|
3191
|
+
onKeyDown: handleKeyDown,
|
|
3192
|
+
"aria-pressed": selected,
|
|
3193
|
+
...props,
|
|
3194
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0", children: [
|
|
3195
|
+
/* @__PURE__ */ jsx11(
|
|
3196
|
+
Text_default,
|
|
3197
|
+
{
|
|
3198
|
+
size: "md",
|
|
3199
|
+
weight: "bold",
|
|
3200
|
+
className: "text-text-950 tracking-[0.2px] leading-[19px] truncate",
|
|
3201
|
+
children: title
|
|
3202
|
+
}
|
|
3203
|
+
),
|
|
3204
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-row justify-start items-end gap-4 w-full", children: [
|
|
3205
|
+
duration && /* @__PURE__ */ jsxs9("div", { className: "flex flex-row items-center gap-1 flex-shrink-0", children: [
|
|
3206
|
+
/* @__PURE__ */ jsx11(Clock, { size: 16, className: "text-text-700" }),
|
|
3207
|
+
/* @__PURE__ */ jsx11(
|
|
3208
|
+
Text_default,
|
|
3209
|
+
{
|
|
3210
|
+
size: "sm",
|
|
3211
|
+
className: "text-text-700 leading-[21px] whitespace-nowrap",
|
|
3212
|
+
children: duration
|
|
3213
|
+
}
|
|
3214
|
+
)
|
|
3215
|
+
] }),
|
|
3216
|
+
/* @__PURE__ */ jsx11(
|
|
3217
|
+
Text_default,
|
|
3218
|
+
{
|
|
3219
|
+
size: "sm",
|
|
3220
|
+
className: "text-text-700 leading-[21px] flex-grow truncate",
|
|
3221
|
+
children: displayInfo
|
|
3222
|
+
}
|
|
3223
|
+
)
|
|
3224
|
+
] })
|
|
3225
|
+
] })
|
|
3226
|
+
}
|
|
3227
|
+
);
|
|
3228
|
+
}
|
|
3229
|
+
return /* @__PURE__ */ jsx11(
|
|
3230
|
+
"div",
|
|
3231
|
+
{
|
|
3232
|
+
ref,
|
|
3233
|
+
className: `${baseClasses} ${className}`.trim(),
|
|
3234
|
+
...props,
|
|
3235
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0", children: [
|
|
3236
|
+
/* @__PURE__ */ jsx11(
|
|
3237
|
+
Text_default,
|
|
3238
|
+
{
|
|
3239
|
+
size: "md",
|
|
3240
|
+
weight: "bold",
|
|
3241
|
+
className: "text-text-950 tracking-[0.2px] leading-[19px] truncate",
|
|
3242
|
+
children: title
|
|
3243
|
+
}
|
|
3244
|
+
),
|
|
3245
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-row justify-start items-end gap-4 w-full", children: [
|
|
3246
|
+
duration && /* @__PURE__ */ jsxs9("div", { className: "flex flex-row items-center gap-1 flex-shrink-0", children: [
|
|
3247
|
+
/* @__PURE__ */ jsx11(Clock, { size: 16, className: "text-text-700" }),
|
|
3248
|
+
/* @__PURE__ */ jsx11(
|
|
3249
|
+
Text_default,
|
|
3250
|
+
{
|
|
3251
|
+
size: "sm",
|
|
3252
|
+
className: "text-text-700 leading-[21px] whitespace-nowrap",
|
|
3253
|
+
children: duration
|
|
3254
|
+
}
|
|
3255
|
+
)
|
|
3256
|
+
] }),
|
|
3257
|
+
/* @__PURE__ */ jsx11(
|
|
3258
|
+
Text_default,
|
|
3259
|
+
{
|
|
3260
|
+
size: "sm",
|
|
3261
|
+
className: "text-text-700 leading-[21px] flex-grow truncate min-w-0",
|
|
3262
|
+
children: displayInfo
|
|
3263
|
+
}
|
|
3264
|
+
)
|
|
3265
|
+
] })
|
|
3266
|
+
] })
|
|
3267
|
+
}
|
|
3268
|
+
);
|
|
3269
|
+
}
|
|
3270
|
+
);
|
|
3271
|
+
var SIMULATION_TYPE_STYLES = {
|
|
3272
|
+
enem: {
|
|
3273
|
+
background: "bg-exam-1",
|
|
3274
|
+
badge: "exam1",
|
|
3275
|
+
text: "Enem"
|
|
3276
|
+
},
|
|
3277
|
+
prova: {
|
|
3278
|
+
background: "bg-exam-2",
|
|
3279
|
+
badge: "exam2",
|
|
3280
|
+
text: "Prova"
|
|
3281
|
+
},
|
|
3282
|
+
simulado: {
|
|
3283
|
+
background: "bg-exam-3",
|
|
3284
|
+
badge: "exam3",
|
|
3285
|
+
text: "Simulado"
|
|
3286
|
+
},
|
|
3287
|
+
vestibular: {
|
|
3288
|
+
background: "bg-exam-4",
|
|
3289
|
+
badge: "exam4",
|
|
3290
|
+
text: "Vestibular"
|
|
3291
|
+
}
|
|
3292
|
+
};
|
|
3293
|
+
var CardSimulationHistory = forwardRef6(({ data, onSimulationClick, className, ...props }, ref) => {
|
|
3294
|
+
return /* @__PURE__ */ jsx11(
|
|
3295
|
+
"div",
|
|
3296
|
+
{
|
|
3297
|
+
ref,
|
|
3298
|
+
className: `w-full max-w-[992px] h-auto ${className}`,
|
|
3299
|
+
...props,
|
|
3300
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-0", children: [
|
|
3301
|
+
data.map((section, sectionIndex) => /* @__PURE__ */ jsx11("div", { className: "flex flex-col", children: /* @__PURE__ */ jsxs9(
|
|
3302
|
+
"div",
|
|
3303
|
+
{
|
|
3304
|
+
className: `
|
|
3305
|
+
flex flex-row justify-center items-start px-4 py-6 gap-2 w-full bg-white
|
|
3306
|
+
${sectionIndex === 0 ? "rounded-t-3xl" : ""}
|
|
3307
|
+
`,
|
|
3308
|
+
children: [
|
|
3309
|
+
/* @__PURE__ */ jsx11(
|
|
3310
|
+
Text_default,
|
|
3311
|
+
{
|
|
3312
|
+
size: "xs",
|
|
3313
|
+
weight: "bold",
|
|
3314
|
+
className: "text-text-800 w-11 flex-shrink-0",
|
|
3315
|
+
children: section.date
|
|
3316
|
+
}
|
|
3317
|
+
),
|
|
3318
|
+
/* @__PURE__ */ jsx11("div", { className: "flex flex-col gap-2 flex-1", children: section.simulations.map((simulation) => {
|
|
3319
|
+
const typeStyles = SIMULATION_TYPE_STYLES[simulation.type];
|
|
3320
|
+
return /* @__PURE__ */ jsx11(
|
|
3321
|
+
CardBase,
|
|
3322
|
+
{
|
|
3323
|
+
layout: "horizontal",
|
|
3324
|
+
padding: "medium",
|
|
3325
|
+
minHeight: "none",
|
|
3326
|
+
cursor: "pointer",
|
|
3327
|
+
className: `
|
|
3328
|
+
${typeStyles.background} rounded-xl hover:shadow-soft-shadow-2
|
|
3329
|
+
transition-shadow duration-200 h-auto min-h-[61px]
|
|
3330
|
+
`,
|
|
3331
|
+
onClick: () => onSimulationClick?.(simulation),
|
|
3332
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex justify-between items-center w-full gap-2", children: [
|
|
3333
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [
|
|
3334
|
+
/* @__PURE__ */ jsx11(
|
|
3335
|
+
Text_default,
|
|
3336
|
+
{
|
|
3337
|
+
size: "lg",
|
|
3338
|
+
weight: "bold",
|
|
3339
|
+
className: "text-text-950 truncate",
|
|
3340
|
+
children: simulation.title
|
|
3341
|
+
}
|
|
3342
|
+
),
|
|
3343
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
3344
|
+
/* @__PURE__ */ jsx11(
|
|
3345
|
+
Badge_default,
|
|
3346
|
+
{
|
|
3347
|
+
variant: "examsOutlined",
|
|
3348
|
+
action: typeStyles.badge,
|
|
3349
|
+
size: "medium",
|
|
3350
|
+
children: typeStyles.text
|
|
3351
|
+
}
|
|
3352
|
+
),
|
|
3353
|
+
/* @__PURE__ */ jsx11(Text_default, { size: "sm", className: "text-text-800 truncate", children: simulation.info })
|
|
3354
|
+
] })
|
|
3355
|
+
] }),
|
|
3356
|
+
/* @__PURE__ */ jsx11(
|
|
3357
|
+
CaretRight,
|
|
3358
|
+
{
|
|
3359
|
+
size: 24,
|
|
3360
|
+
className: "text-text-800 flex-shrink-0",
|
|
3361
|
+
"data-testid": "caret-icon"
|
|
3362
|
+
}
|
|
3363
|
+
)
|
|
3364
|
+
] })
|
|
3365
|
+
},
|
|
3366
|
+
simulation.id
|
|
3367
|
+
);
|
|
3368
|
+
}) })
|
|
3369
|
+
]
|
|
3370
|
+
}
|
|
3371
|
+
) }, section.date)),
|
|
3372
|
+
data.length > 0 && /* @__PURE__ */ jsx11("div", { className: "w-full h-6 bg-white rounded-b-3xl" })
|
|
3373
|
+
] })
|
|
3374
|
+
}
|
|
3375
|
+
);
|
|
3376
|
+
});
|
|
3377
|
+
|
|
3378
|
+
// src/components/ProgressCircle/ProgressCircle.tsx
|
|
3379
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3380
|
+
var SIZE_CLASSES8 = {
|
|
3381
|
+
small: {
|
|
3382
|
+
container: "w-[90px] h-[90px]",
|
|
3383
|
+
// 90px circle from design specs
|
|
3384
|
+
strokeWidth: 4,
|
|
3385
|
+
// 4px stroke width - matches ProgressBar small (h-1)
|
|
3386
|
+
textSize: "2xl",
|
|
3387
|
+
// 24px for percentage (font-size: 24px)
|
|
3388
|
+
textWeight: "medium",
|
|
3389
|
+
// font-weight: 500
|
|
3390
|
+
labelSize: "2xs",
|
|
3391
|
+
// Will be overridden with custom 8px in className
|
|
3392
|
+
labelWeight: "bold",
|
|
3393
|
+
// font-weight: 700
|
|
3394
|
+
spacing: "gap-0",
|
|
3395
|
+
// Reduced gap between percentage and label for better spacing
|
|
3396
|
+
contentWidth: "max-w-[50px]"
|
|
3397
|
+
// Reduced width to fit text inside circle
|
|
3398
|
+
},
|
|
3399
|
+
medium: {
|
|
3400
|
+
container: "w-[152px] h-[152px]",
|
|
3401
|
+
// 151.67px ≈ 152px circle from design specs
|
|
3402
|
+
strokeWidth: 8,
|
|
3403
|
+
// 8px stroke width - matches ProgressBar medium (h-2)
|
|
3404
|
+
textSize: "2xl",
|
|
3405
|
+
// 24px for percentage (font-size: 24px)
|
|
3406
|
+
textWeight: "medium",
|
|
3407
|
+
// font-weight: 500
|
|
3408
|
+
labelSize: "xs",
|
|
3409
|
+
// 12px for status label (font-size: 12px)
|
|
3410
|
+
labelWeight: "medium",
|
|
3411
|
+
// font-weight: 500 (changed from bold)
|
|
3412
|
+
spacing: "gap-1",
|
|
3413
|
+
// 4px gap between percentage and label
|
|
3414
|
+
contentWidth: "max-w-[90px]"
|
|
3415
|
+
// Reduced width to fit text inside circle
|
|
3416
|
+
}
|
|
3417
|
+
};
|
|
3418
|
+
var VARIANT_CLASSES3 = {
|
|
3419
|
+
blue: {
|
|
3420
|
+
background: "stroke-primary-100",
|
|
3421
|
+
// Light blue background (#BBDCF7)
|
|
3422
|
+
fill: "stroke-primary-700",
|
|
3423
|
+
// Blue for activity progress (#2271C4)
|
|
3424
|
+
textColor: "text-primary-700",
|
|
3425
|
+
// Blue text color (#2271C4)
|
|
3426
|
+
labelColor: "text-text-700"
|
|
3427
|
+
// Gray text for label (#525252)
|
|
3428
|
+
},
|
|
3429
|
+
green: {
|
|
3430
|
+
background: "stroke-background-300",
|
|
3431
|
+
// Gray background (#D5D4D4 - matches design)
|
|
3432
|
+
fill: "stroke-success-200",
|
|
3433
|
+
// Green for performance (#84D3A2 - matches design)
|
|
3434
|
+
textColor: "text-text-800",
|
|
3435
|
+
// Dark gray text (#404040 - matches design)
|
|
3436
|
+
labelColor: "text-text-600"
|
|
3437
|
+
// Medium gray text for label (#737373 - matches design)
|
|
3438
|
+
}
|
|
3439
|
+
};
|
|
3440
|
+
var ProgressCircle = ({
|
|
3441
|
+
value,
|
|
3442
|
+
max = 100,
|
|
3443
|
+
size = "small",
|
|
3444
|
+
variant = "blue",
|
|
3445
|
+
label,
|
|
3446
|
+
showPercentage = true,
|
|
3447
|
+
className = "",
|
|
3448
|
+
labelClassName = "",
|
|
3449
|
+
percentageClassName = ""
|
|
3450
|
+
}) => {
|
|
3451
|
+
const safeValue = isNaN(value) ? 0 : value;
|
|
3452
|
+
const clampedValue = Math.max(0, Math.min(safeValue, max));
|
|
3453
|
+
const percentage = max === 0 ? 0 : clampedValue / max * 100;
|
|
3454
|
+
const sizeClasses = SIZE_CLASSES8[size];
|
|
3455
|
+
const variantClasses = VARIANT_CLASSES3[variant];
|
|
3456
|
+
const radius = size === "small" ? 37 : 64;
|
|
3457
|
+
const circumference = 2 * Math.PI * radius;
|
|
3458
|
+
const strokeDashoffset = circumference - percentage / 100 * circumference;
|
|
3459
|
+
const center = size === "small" ? 45 : 76;
|
|
3460
|
+
const svgSize = size === "small" ? 90 : 152;
|
|
3461
|
+
return /* @__PURE__ */ jsxs10(
|
|
3462
|
+
"div",
|
|
3463
|
+
{
|
|
3464
|
+
className: `relative flex flex-col items-center justify-center ${sizeClasses.container} rounded-lg ${className}`,
|
|
3465
|
+
children: [
|
|
3466
|
+
/* @__PURE__ */ jsxs10(
|
|
3467
|
+
"svg",
|
|
3468
|
+
{
|
|
3469
|
+
className: "absolute inset-0 transform -rotate-90",
|
|
3470
|
+
width: svgSize,
|
|
3471
|
+
height: svgSize,
|
|
3472
|
+
viewBox: `0 0 ${svgSize} ${svgSize}`,
|
|
3473
|
+
"aria-hidden": "true",
|
|
3474
|
+
children: [
|
|
3475
|
+
/* @__PURE__ */ jsx12(
|
|
3476
|
+
"circle",
|
|
3477
|
+
{
|
|
3478
|
+
cx: center,
|
|
3479
|
+
cy: center,
|
|
3480
|
+
r: radius,
|
|
3481
|
+
fill: "none",
|
|
3482
|
+
strokeWidth: sizeClasses.strokeWidth,
|
|
3483
|
+
className: `${variantClasses.background} rounded-lg`
|
|
3484
|
+
}
|
|
3485
|
+
),
|
|
3486
|
+
/* @__PURE__ */ jsx12(
|
|
3487
|
+
"circle",
|
|
3488
|
+
{
|
|
3489
|
+
cx: center,
|
|
3490
|
+
cy: center,
|
|
3491
|
+
r: radius,
|
|
3492
|
+
fill: "none",
|
|
3493
|
+
strokeWidth: sizeClasses.strokeWidth,
|
|
3494
|
+
strokeLinecap: "round",
|
|
3495
|
+
strokeDasharray: circumference,
|
|
3496
|
+
strokeDashoffset,
|
|
3497
|
+
className: `${variantClasses.fill} transition-all duration-500 ease-out shadow-soft-shadow-3 rounded-lg`
|
|
3498
|
+
}
|
|
3499
|
+
)
|
|
3500
|
+
]
|
|
3501
|
+
}
|
|
3502
|
+
),
|
|
3503
|
+
/* @__PURE__ */ jsx12(
|
|
3504
|
+
"progress",
|
|
3505
|
+
{
|
|
3506
|
+
value: clampedValue,
|
|
3507
|
+
max,
|
|
3508
|
+
"aria-label": typeof label === "string" ? label : "Progress",
|
|
3509
|
+
className: "absolute opacity-0 w-0 h-0"
|
|
3510
|
+
}
|
|
3511
|
+
),
|
|
3512
|
+
/* @__PURE__ */ jsxs10(
|
|
3513
|
+
"div",
|
|
3514
|
+
{
|
|
3515
|
+
className: `relative z-10 flex flex-col items-center justify-center ${sizeClasses.spacing} ${sizeClasses.contentWidth}`,
|
|
3516
|
+
children: [
|
|
3517
|
+
showPercentage && /* @__PURE__ */ jsxs10(
|
|
3518
|
+
Text_default,
|
|
3519
|
+
{
|
|
3520
|
+
size: sizeClasses.textSize,
|
|
3521
|
+
weight: sizeClasses.textWeight,
|
|
3522
|
+
className: `text-center w-full ${variantClasses.textColor} ${percentageClassName}`,
|
|
3523
|
+
children: [
|
|
3524
|
+
Math.round(percentage),
|
|
3525
|
+
"%"
|
|
3526
|
+
]
|
|
3527
|
+
}
|
|
3528
|
+
),
|
|
3529
|
+
label && /* @__PURE__ */ jsx12(
|
|
3530
|
+
Text_default,
|
|
3531
|
+
{
|
|
3532
|
+
as: "span",
|
|
3533
|
+
size: sizeClasses.labelSize,
|
|
3534
|
+
weight: sizeClasses.labelWeight,
|
|
3535
|
+
className: `${variantClasses.labelColor} text-center uppercase tracking-wide truncate w-full ${size === "small" ? "text-[8px] leading-[9px]" : ""} ${labelClassName}`,
|
|
3536
|
+
children: label
|
|
3537
|
+
}
|
|
3538
|
+
)
|
|
3539
|
+
]
|
|
3540
|
+
}
|
|
3541
|
+
)
|
|
3542
|
+
]
|
|
3543
|
+
}
|
|
3544
|
+
);
|
|
3545
|
+
};
|
|
3546
|
+
var ProgressCircle_default = ProgressCircle;
|
|
3547
|
+
|
|
3548
|
+
// src/components/Quiz/Quiz.tsx
|
|
3549
|
+
import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3550
|
+
var Quiz = forwardRef7(({ children, className, ...props }, ref) => {
|
|
3551
|
+
return /* @__PURE__ */ jsx13(
|
|
3552
|
+
"div",
|
|
3553
|
+
{
|
|
3554
|
+
ref,
|
|
3555
|
+
className: `w-full max-w-[1000px] flex flex-col mx-auto h-full relative not-lg:px-6 ${className}`,
|
|
3556
|
+
...props,
|
|
3557
|
+
children
|
|
3558
|
+
}
|
|
3559
|
+
);
|
|
3560
|
+
});
|
|
3561
|
+
var QuizHeaderResult = forwardRef7(
|
|
3562
|
+
({ className, ...props }, ref) => {
|
|
3563
|
+
const { getCurrentQuestion, getCurrentAnswer } = useQuizStore();
|
|
3564
|
+
const currentQuestion = getCurrentQuestion();
|
|
3565
|
+
const userAnswer = getCurrentAnswer();
|
|
3566
|
+
const isCorrect = userAnswer === currentQuestion?.correctOptionId;
|
|
3567
|
+
return /* @__PURE__ */ jsxs11(
|
|
3568
|
+
"div",
|
|
3569
|
+
{
|
|
3570
|
+
ref,
|
|
3571
|
+
className: `flex flex-row items-center gap-10 p-3.5 rounded-xl ${isCorrect ? "bg-success-background" : "bg-error-background"} ${className}`,
|
|
3572
|
+
...props,
|
|
3573
|
+
children: [
|
|
3574
|
+
/* @__PURE__ */ jsx13("p", { className: "text-text-950 font-bold text-lg", children: "Resultado" }),
|
|
3575
|
+
/* @__PURE__ */ jsx13("p", { className: "text-text-700 text-md", children: isCorrect ? "\u{1F389} Parab\xE9ns!!" : "N\xE3o foi dessa vez..." })
|
|
3576
|
+
]
|
|
3577
|
+
}
|
|
3578
|
+
);
|
|
3579
|
+
}
|
|
3580
|
+
);
|
|
3581
|
+
var QuizTitle = forwardRef7(
|
|
3582
|
+
({ className, ...props }, ref) => {
|
|
3583
|
+
const {
|
|
3584
|
+
currentQuestionIndex,
|
|
3585
|
+
getTotalQuestions,
|
|
3586
|
+
getQuizTitle,
|
|
3587
|
+
timeElapsed,
|
|
3588
|
+
formatTime,
|
|
3589
|
+
isStarted
|
|
3590
|
+
} = useQuizStore();
|
|
3591
|
+
const totalQuestions = getTotalQuestions();
|
|
3592
|
+
const quizTitle = getQuizTitle();
|
|
3593
|
+
return /* @__PURE__ */ jsxs11(
|
|
3594
|
+
"div",
|
|
3595
|
+
{
|
|
3596
|
+
ref,
|
|
3597
|
+
className: `flex flex-row justify-center items-center relative p-2 ${className}`,
|
|
3598
|
+
...props,
|
|
3599
|
+
children: [
|
|
3600
|
+
/* @__PURE__ */ jsxs11("span", { className: "flex flex-col gap-2 text-center", children: [
|
|
3601
|
+
/* @__PURE__ */ jsx13("p", { className: "text-text-950 font-bold text-md", children: quizTitle }),
|
|
3602
|
+
/* @__PURE__ */ jsx13("p", { className: "text-text-600 text-xs", children: totalQuestions > 0 ? `${currentQuestionIndex + 1} de ${totalQuestions}` : "0 de 0" })
|
|
3603
|
+
] }),
|
|
3604
|
+
/* @__PURE__ */ jsx13("span", { className: "absolute right-2", children: /* @__PURE__ */ jsx13(Badge_default, { variant: "outlined", action: "info", iconLeft: /* @__PURE__ */ jsx13(Clock2, {}), children: isStarted ? formatTime(timeElapsed) : "00:00" }) })
|
|
3605
|
+
]
|
|
3606
|
+
}
|
|
3607
|
+
);
|
|
3608
|
+
}
|
|
3609
|
+
);
|
|
3610
|
+
var QuizHeader = () => {
|
|
3611
|
+
const { getCurrentQuestion } = useQuizStore();
|
|
3612
|
+
const currentQuestion = getCurrentQuestion();
|
|
3613
|
+
return /* @__PURE__ */ jsx13(
|
|
3614
|
+
HeaderAlternative,
|
|
3615
|
+
{
|
|
3616
|
+
title: currentQuestion ? `Quest\xE3o ${currentQuestion.id}` : "Quest\xE3o",
|
|
3617
|
+
subTitle: currentQuestion?.knowledgeMatrix?.[0]?.topicId ?? "",
|
|
3618
|
+
content: currentQuestion?.questionText ?? ""
|
|
3619
|
+
}
|
|
3620
|
+
);
|
|
3621
|
+
};
|
|
3622
|
+
var QuizContent = forwardRef7(({ type = "Alternativas", children, className, ...props }, ref) => {
|
|
3623
|
+
return /* @__PURE__ */ jsxs11(Fragment6, { children: [
|
|
3624
|
+
/* @__PURE__ */ jsx13("div", { className: "px-4 pb-2 pt-6", children: /* @__PURE__ */ jsx13("p", { className: "font-bold text-lg text-text-950", children: type }) }),
|
|
3625
|
+
/* @__PURE__ */ jsx13(
|
|
3626
|
+
"div",
|
|
3627
|
+
{
|
|
3628
|
+
ref,
|
|
3629
|
+
className: `rounded-t-xl px-4 pt-4 pb-[80px] h-full flex flex-col gap-4 mb-auto ${className}`,
|
|
3630
|
+
...props,
|
|
3631
|
+
children
|
|
3632
|
+
}
|
|
3633
|
+
)
|
|
3634
|
+
] });
|
|
3635
|
+
});
|
|
3636
|
+
var QuizAlternative = ({ variant = "default" }) => {
|
|
3637
|
+
const { getCurrentQuestion, selectAnswer, getCurrentAnswer } = useQuizStore();
|
|
3638
|
+
const currentQuestion = getCurrentQuestion();
|
|
3639
|
+
const currentAnswer = getCurrentAnswer();
|
|
3640
|
+
const alternatives = currentQuestion?.options?.map((option) => {
|
|
3641
|
+
let status = "neutral" /* NEUTRAL */;
|
|
3642
|
+
if (variant === "result") {
|
|
3643
|
+
if (option.id === currentQuestion.correctOptionId) {
|
|
3644
|
+
status = "correct" /* CORRECT */;
|
|
3645
|
+
} else if (currentAnswer === option.id && option.id !== currentQuestion.correctOptionId) {
|
|
3646
|
+
status = "incorrect" /* INCORRECT */;
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
return {
|
|
3650
|
+
label: option.option,
|
|
3651
|
+
value: option.id,
|
|
3652
|
+
status
|
|
3653
|
+
};
|
|
3654
|
+
});
|
|
3655
|
+
if (!alternatives)
|
|
3656
|
+
return /* @__PURE__ */ jsx13("div", { children: /* @__PURE__ */ jsx13("p", { children: "N\xE3o h\xE1 Alternativas" }) });
|
|
3657
|
+
return /* @__PURE__ */ jsx13("div", { className: "space-y-4", children: /* @__PURE__ */ jsx13(
|
|
3658
|
+
AlternativesList,
|
|
3659
|
+
{
|
|
3660
|
+
mode: variant === "default" ? "interactive" : "readonly",
|
|
3661
|
+
name: `question-${currentQuestion?.id || "1"}`,
|
|
3662
|
+
layout: "compact",
|
|
3663
|
+
alternatives,
|
|
3664
|
+
value: currentAnswer,
|
|
3665
|
+
selectedValue: currentAnswer,
|
|
3666
|
+
onValueChange: (value) => {
|
|
3667
|
+
if (currentQuestion) {
|
|
3668
|
+
selectAnswer(currentQuestion.id, value);
|
|
3669
|
+
}
|
|
3670
|
+
}
|
|
3671
|
+
},
|
|
3672
|
+
`question-${currentQuestion?.id || "1"}`
|
|
3673
|
+
) });
|
|
3674
|
+
};
|
|
3675
|
+
var QuizQuestionList = ({
|
|
3676
|
+
filterType = "all",
|
|
3677
|
+
onQuestionClick
|
|
3678
|
+
} = {}) => {
|
|
3679
|
+
const {
|
|
3680
|
+
getQuestionsGroupedBySubject,
|
|
3681
|
+
goToQuestion,
|
|
3682
|
+
getQuestionStatusFromUserAnswers
|
|
3683
|
+
} = useQuizStore();
|
|
3684
|
+
const groupedQuestions = getQuestionsGroupedBySubject();
|
|
3685
|
+
const getQuestionStatus = (questionId) => {
|
|
3686
|
+
return getQuestionStatusFromUserAnswers(questionId);
|
|
3687
|
+
};
|
|
3688
|
+
const filteredGroupedQuestions = Object.entries(groupedQuestions).reduce(
|
|
3689
|
+
(acc, [subjectId, questions]) => {
|
|
3690
|
+
const filteredQuestions = questions.filter((question) => {
|
|
3691
|
+
const status = getQuestionStatus(question.id);
|
|
3692
|
+
switch (filterType) {
|
|
3693
|
+
case "answered":
|
|
3694
|
+
return status === "answered";
|
|
3695
|
+
case "unanswered":
|
|
3696
|
+
return status === "unanswered";
|
|
3697
|
+
default:
|
|
3698
|
+
return true;
|
|
3699
|
+
}
|
|
3700
|
+
});
|
|
3701
|
+
if (filteredQuestions.length > 0) {
|
|
3702
|
+
acc[subjectId] = filteredQuestions;
|
|
3703
|
+
}
|
|
3704
|
+
return acc;
|
|
3705
|
+
},
|
|
3706
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3707
|
+
{}
|
|
3708
|
+
);
|
|
3709
|
+
const getQuestionIndex = (questionId) => {
|
|
3710
|
+
const { bySimulated, byActivity, byQuestionary } = useQuizStore.getState();
|
|
3711
|
+
const quiz = bySimulated ?? byActivity ?? byQuestionary;
|
|
3712
|
+
if (!quiz) return 0;
|
|
3713
|
+
const index = quiz.questions.findIndex((q) => q.id === questionId);
|
|
3714
|
+
return index + 1;
|
|
3715
|
+
};
|
|
3716
|
+
const getStatusLabel = (status) => {
|
|
3717
|
+
switch (status) {
|
|
3718
|
+
case "answered":
|
|
3719
|
+
return "Respondida";
|
|
3720
|
+
case "skipped":
|
|
3721
|
+
return "N\xE3o respondida";
|
|
3722
|
+
default:
|
|
3723
|
+
return "Em branco";
|
|
3724
|
+
}
|
|
3725
|
+
};
|
|
3726
|
+
return /* @__PURE__ */ jsx13("div", { className: "space-y-6 px-4", children: Object.entries(filteredGroupedQuestions).map(
|
|
3727
|
+
([subjectId, questions]) => /* @__PURE__ */ jsxs11("section", { className: "flex flex-col gap-2", children: [
|
|
3728
|
+
/* @__PURE__ */ jsxs11("span", { className: "pt-6 pb-4 flex flex-row gap-2", children: [
|
|
3729
|
+
/* @__PURE__ */ jsx13("div", { className: "bg-primary-500 p-1 rounded-sm flex items-center justify-center", children: /* @__PURE__ */ jsx13(BookOpen, { size: 17, className: "text-white" }) }),
|
|
3730
|
+
/* @__PURE__ */ jsx13("p", { className: "text-text-800 font-bold text-lg", children: subjectId })
|
|
3731
|
+
] }),
|
|
3732
|
+
/* @__PURE__ */ jsx13("ul", { className: "flex flex-col gap-2", children: questions.map((question) => {
|
|
3733
|
+
const status = getQuestionStatus(question.id);
|
|
3734
|
+
const questionNumber = getQuestionIndex(question.id);
|
|
3735
|
+
return /* @__PURE__ */ jsx13(
|
|
3736
|
+
CardStatus,
|
|
3737
|
+
{
|
|
3738
|
+
header: `Quest\xE3o ${questionNumber.toString().padStart(2, "0")}`,
|
|
3739
|
+
label: getStatusLabel(status),
|
|
3740
|
+
onClick: () => {
|
|
3741
|
+
goToQuestion(questionNumber - 1);
|
|
3742
|
+
onQuestionClick?.();
|
|
3743
|
+
}
|
|
3744
|
+
},
|
|
3745
|
+
question.id
|
|
3746
|
+
);
|
|
3747
|
+
}) })
|
|
3748
|
+
] }, subjectId)
|
|
3749
|
+
) });
|
|
3750
|
+
};
|
|
3751
|
+
var QuizFooter = forwardRef7(({ className, onGoToSimulated, onDetailResult, ...props }, ref) => {
|
|
3752
|
+
const {
|
|
3753
|
+
currentQuestionIndex,
|
|
3754
|
+
getUserAnswers,
|
|
3755
|
+
getTotalQuestions,
|
|
3756
|
+
goToNextQuestion,
|
|
3757
|
+
goToPreviousQuestion,
|
|
3758
|
+
getUnansweredQuestionsFromUserAnswers,
|
|
3759
|
+
getCurrentAnswer,
|
|
3760
|
+
skipQuestion,
|
|
3761
|
+
getCurrentQuestion,
|
|
3762
|
+
getQuestionStatusFromUserAnswers
|
|
3763
|
+
} = useQuizStore();
|
|
3764
|
+
const totalQuestions = getTotalQuestions();
|
|
3765
|
+
const isFirstQuestion = currentQuestionIndex === 0;
|
|
3766
|
+
const isLastQuestion = currentQuestionIndex === totalQuestions - 1;
|
|
3767
|
+
const currentAnswer = getCurrentAnswer();
|
|
3768
|
+
const currentQuestion = getCurrentQuestion();
|
|
3769
|
+
const isCurrentQuestionSkipped = currentQuestion ? getQuestionStatusFromUserAnswers(currentQuestion.id) === "skipped" : false;
|
|
3770
|
+
const [alertDialogOpen, setAlertDialogOpen] = useState4(false);
|
|
3771
|
+
const [modalResultOpen, setModalResultOpen] = useState4(false);
|
|
3772
|
+
const [modalNavigateOpen, setModalNavigateOpen] = useState4(false);
|
|
3773
|
+
const [filterType, setFilterType] = useState4("all");
|
|
3774
|
+
const unansweredQuestions = getUnansweredQuestionsFromUserAnswers();
|
|
3775
|
+
const userAnswers = getUserAnswers();
|
|
3776
|
+
const allQuestions = getTotalQuestions();
|
|
3777
|
+
return /* @__PURE__ */ jsxs11(Fragment6, { children: [
|
|
3778
|
+
/* @__PURE__ */ jsxs11(
|
|
3779
|
+
"footer",
|
|
3780
|
+
{
|
|
3781
|
+
ref,
|
|
3782
|
+
className: `w-full px-2 bg-background lg:max-w-[1000px] not-lg:max-w-[calc(100vw-32px)] border-t border-border-50 fixed bottom-0 min-h-[80px] flex flex-row justify-between items-center ${className}`,
|
|
3783
|
+
...props,
|
|
3784
|
+
children: [
|
|
3785
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-row items-center gap-1", children: [
|
|
3786
|
+
/* @__PURE__ */ jsx13(
|
|
3787
|
+
IconButton_default,
|
|
3788
|
+
{
|
|
3789
|
+
icon: /* @__PURE__ */ jsx13(SquaresFour, { size: 24, className: "text-text-950" }),
|
|
3790
|
+
size: "md",
|
|
3791
|
+
onClick: () => setModalNavigateOpen(true)
|
|
3792
|
+
}
|
|
3793
|
+
),
|
|
3794
|
+
isFirstQuestion ? /* @__PURE__ */ jsx13(
|
|
3795
|
+
Button_default,
|
|
3796
|
+
{
|
|
3797
|
+
variant: "outline",
|
|
3798
|
+
size: "small",
|
|
3799
|
+
onClick: () => {
|
|
3800
|
+
skipQuestion();
|
|
3801
|
+
goToNextQuestion();
|
|
3802
|
+
},
|
|
3803
|
+
children: "Pular"
|
|
3804
|
+
}
|
|
3805
|
+
) : /* @__PURE__ */ jsx13(
|
|
3806
|
+
Button_default,
|
|
3807
|
+
{
|
|
3808
|
+
size: "medium",
|
|
3809
|
+
variant: "link",
|
|
3810
|
+
action: "primary",
|
|
3811
|
+
iconLeft: /* @__PURE__ */ jsx13(CaretLeft, { size: 18 }),
|
|
3812
|
+
onClick: () => {
|
|
3813
|
+
goToPreviousQuestion();
|
|
3814
|
+
},
|
|
3815
|
+
children: "Voltar"
|
|
3816
|
+
}
|
|
3817
|
+
)
|
|
3818
|
+
] }),
|
|
3819
|
+
!isFirstQuestion && /* @__PURE__ */ jsx13(
|
|
3820
|
+
Button_default,
|
|
3821
|
+
{
|
|
3822
|
+
size: "small",
|
|
3823
|
+
variant: "outline",
|
|
3824
|
+
action: "primary",
|
|
3825
|
+
onClick: () => {
|
|
3826
|
+
skipQuestion();
|
|
3827
|
+
goToNextQuestion();
|
|
3828
|
+
},
|
|
3829
|
+
children: "Pular"
|
|
3830
|
+
}
|
|
3831
|
+
),
|
|
3832
|
+
isLastQuestion ? /* @__PURE__ */ jsx13(
|
|
3833
|
+
Button_default,
|
|
3834
|
+
{
|
|
3835
|
+
size: "medium",
|
|
3836
|
+
variant: "solid",
|
|
3837
|
+
action: "primary",
|
|
3838
|
+
disabled: !currentAnswer && !isCurrentQuestionSkipped,
|
|
3839
|
+
onClick: () => {
|
|
3840
|
+
if (unansweredQuestions.length > 0) {
|
|
3841
|
+
setAlertDialogOpen(true);
|
|
3842
|
+
} else {
|
|
3843
|
+
setModalResultOpen(true);
|
|
3844
|
+
}
|
|
3845
|
+
},
|
|
3846
|
+
children: "Finalizar"
|
|
3847
|
+
}
|
|
3848
|
+
) : /* @__PURE__ */ jsx13(
|
|
3849
|
+
Button_default,
|
|
3850
|
+
{
|
|
3851
|
+
size: "medium",
|
|
3852
|
+
variant: "link",
|
|
3853
|
+
action: "primary",
|
|
3854
|
+
iconRight: /* @__PURE__ */ jsx13(CaretRight2, { size: 18 }),
|
|
3855
|
+
disabled: !currentAnswer && !isCurrentQuestionSkipped,
|
|
3856
|
+
onClick: () => {
|
|
3857
|
+
goToNextQuestion();
|
|
3858
|
+
},
|
|
3859
|
+
children: "Avan\xE7ar"
|
|
3860
|
+
}
|
|
3861
|
+
)
|
|
3862
|
+
]
|
|
3863
|
+
}
|
|
3864
|
+
),
|
|
3865
|
+
/* @__PURE__ */ jsx13(
|
|
3866
|
+
AlertDialog,
|
|
3867
|
+
{
|
|
3868
|
+
isOpen: alertDialogOpen,
|
|
3869
|
+
onChangeOpen: setAlertDialogOpen,
|
|
3870
|
+
title: "Finalizar simulado?",
|
|
3871
|
+
description: unansweredQuestions.length > 0 ? `Voc\xEA deixou as quest\xF5es ${unansweredQuestions.join(", ")} sem resposta. Finalizar agora pode impactar seu desempenho.` : "Tem certeza que deseja finalizar o simulado?",
|
|
3872
|
+
cancelButtonLabel: "Voltar e revisar",
|
|
3873
|
+
submitButtonLabel: "Finalizar Mesmo Assim",
|
|
3874
|
+
onSubmit: () => {
|
|
3875
|
+
setModalResultOpen(true);
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
),
|
|
3879
|
+
/* @__PURE__ */ jsx13(
|
|
3880
|
+
Modal_default,
|
|
3881
|
+
{
|
|
3882
|
+
isOpen: modalResultOpen,
|
|
3883
|
+
onClose: () => setModalResultOpen(false),
|
|
3884
|
+
title: "",
|
|
3885
|
+
closeOnBackdropClick: false,
|
|
3886
|
+
closeOnEscape: false,
|
|
3887
|
+
hideCloseButton: true,
|
|
3888
|
+
size: "md",
|
|
3889
|
+
children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col w-full h-full items-center justify-center gap-4", children: [
|
|
3890
|
+
/* @__PURE__ */ jsx13(
|
|
3891
|
+
"img",
|
|
3892
|
+
{
|
|
3893
|
+
src: simulated_result_default,
|
|
3894
|
+
alt: "Simulated Result",
|
|
3895
|
+
className: "w-[282px] h-auto object-cover"
|
|
3896
|
+
}
|
|
3897
|
+
),
|
|
3898
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-2 text-center", children: [
|
|
3899
|
+
/* @__PURE__ */ jsx13("h2", { className: "text-text-950 font-bold text-lg", children: "Voc\xEA concluiu o simulado!" }),
|
|
3900
|
+
/* @__PURE__ */ jsxs11("p", { className: "text-text-500 font-sm", children: [
|
|
3901
|
+
"Voc\xEA acertou",
|
|
3902
|
+
" ",
|
|
3903
|
+
userAnswers.filter(
|
|
3904
|
+
(answer) => answer.answerKey === answer.correctOptionId
|
|
3905
|
+
).length,
|
|
3906
|
+
" ",
|
|
3907
|
+
"de ",
|
|
3908
|
+
allQuestions,
|
|
3909
|
+
" quest\xF5es."
|
|
3910
|
+
] })
|
|
3911
|
+
] }),
|
|
3912
|
+
/* @__PURE__ */ jsxs11("div", { className: "px-6 flex flex-row items-center gap-2 w-full", children: [
|
|
3913
|
+
/* @__PURE__ */ jsx13(
|
|
3914
|
+
Button_default,
|
|
3915
|
+
{
|
|
3916
|
+
variant: "outline",
|
|
3917
|
+
className: "w-full",
|
|
3918
|
+
size: "small",
|
|
3919
|
+
onClick: onGoToSimulated,
|
|
3920
|
+
children: "Ir para simulados"
|
|
3921
|
+
}
|
|
3922
|
+
),
|
|
3923
|
+
/* @__PURE__ */ jsx13(Button_default, { className: "w-full", onClick: onDetailResult, children: "Detalhar resultado" })
|
|
3924
|
+
] })
|
|
3925
|
+
] })
|
|
3926
|
+
}
|
|
3927
|
+
),
|
|
3928
|
+
/* @__PURE__ */ jsx13(
|
|
3929
|
+
Modal_default,
|
|
3930
|
+
{
|
|
3931
|
+
isOpen: modalNavigateOpen,
|
|
3932
|
+
onClose: () => setModalNavigateOpen(false),
|
|
3933
|
+
title: "Quest\xF5es",
|
|
3934
|
+
size: "lg",
|
|
3935
|
+
children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col w-full h-full", children: [
|
|
3936
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-row justify-between items-center py-6 pt-6 pb-4 border-b border-border-200", children: [
|
|
3937
|
+
/* @__PURE__ */ jsx13("p", { className: "text-text-950 font-bold text-lg", children: "Filtrar por" }),
|
|
3938
|
+
/* @__PURE__ */ jsx13("span", { className: "max-w-[266px]", children: /* @__PURE__ */ jsxs11(Select_default, { value: filterType, onValueChange: setFilterType, children: [
|
|
3939
|
+
/* @__PURE__ */ jsx13(SelectTrigger, { variant: "rounded", className: "max-w-[266px]", children: /* @__PURE__ */ jsx13(SelectValue, { placeholder: "Selecione uma op\xE7\xE3o" }) }),
|
|
3940
|
+
/* @__PURE__ */ jsxs11(SelectContent, { children: [
|
|
3941
|
+
/* @__PURE__ */ jsx13(SelectItem, { value: "all", children: "Todas" }),
|
|
3942
|
+
/* @__PURE__ */ jsx13(SelectItem, { value: "unanswered", children: "Em branco" }),
|
|
3943
|
+
/* @__PURE__ */ jsx13(SelectItem, { value: "answered", children: "Respondidas" })
|
|
3944
|
+
] })
|
|
3945
|
+
] }) })
|
|
3946
|
+
] }),
|
|
3947
|
+
/* @__PURE__ */ jsx13("div", { className: "flex flex-col gap-2 not-lg:h-[calc(100vh-200px)] lg:max-h-[687px] overflow-y-auto", children: /* @__PURE__ */ jsx13(
|
|
3948
|
+
QuizQuestionList,
|
|
3949
|
+
{
|
|
3950
|
+
filterType,
|
|
3951
|
+
onQuestionClick: () => setModalNavigateOpen(false)
|
|
3952
|
+
}
|
|
3953
|
+
) })
|
|
3954
|
+
] })
|
|
3955
|
+
}
|
|
3956
|
+
)
|
|
3957
|
+
] });
|
|
3958
|
+
});
|
|
3959
|
+
var QuizResultHeaderTitle = forwardRef7(({ className, ...props }, ref) => {
|
|
3960
|
+
const { bySimulated } = useQuizStore();
|
|
3961
|
+
return /* @__PURE__ */ jsxs11(
|
|
3962
|
+
"div",
|
|
3963
|
+
{
|
|
3964
|
+
ref,
|
|
3965
|
+
className: `flex flex-row pt-4 justify-between ${className}`,
|
|
3966
|
+
...props,
|
|
3967
|
+
children: [
|
|
3968
|
+
/* @__PURE__ */ jsx13("p", { className: "text-text-950 font-bold text-2xl", children: "Resultado" }),
|
|
3969
|
+
bySimulated && /* @__PURE__ */ jsx13(Badge_default, { variant: "solid", action: "info", children: bySimulated.category })
|
|
3970
|
+
]
|
|
3971
|
+
}
|
|
3972
|
+
);
|
|
3973
|
+
});
|
|
3974
|
+
var QuizResultTitle = forwardRef7(({ className, ...props }, ref) => {
|
|
3975
|
+
const { getQuizTitle } = useQuizStore();
|
|
3976
|
+
const quizTitle = getQuizTitle();
|
|
3977
|
+
return /* @__PURE__ */ jsx13(
|
|
3978
|
+
"p",
|
|
3979
|
+
{
|
|
3980
|
+
className: `pt-6 pb-4 text-text-950 font-bold text-lg ${className}`,
|
|
3981
|
+
ref,
|
|
3982
|
+
...props,
|
|
3983
|
+
children: quizTitle
|
|
3984
|
+
}
|
|
3985
|
+
);
|
|
3986
|
+
});
|
|
3987
|
+
var QuizResultPerformance = forwardRef7(
|
|
3988
|
+
({ ...props }, ref) => {
|
|
3989
|
+
const {
|
|
3990
|
+
getTotalQuestions,
|
|
3991
|
+
timeElapsed,
|
|
3992
|
+
formatTime,
|
|
3993
|
+
bySimulated,
|
|
3994
|
+
byActivity,
|
|
3995
|
+
byQuestionary
|
|
3996
|
+
} = useQuizStore();
|
|
3997
|
+
const totalQuestions = getTotalQuestions();
|
|
3998
|
+
const quiz = bySimulated || byActivity || byQuestionary;
|
|
3999
|
+
let correctAnswers = 0;
|
|
4000
|
+
let correctEasyAnswers = 0;
|
|
4001
|
+
let correctMediumAnswers = 0;
|
|
4002
|
+
let correctDifficultAnswers = 0;
|
|
4003
|
+
let totalEasyQuestions = 0;
|
|
4004
|
+
let totalMediumQuestions = 0;
|
|
4005
|
+
let totalDifficultQuestions = 0;
|
|
4006
|
+
if (quiz) {
|
|
4007
|
+
quiz.questions.forEach((question) => {
|
|
4008
|
+
const userAnswer = question.answerKey;
|
|
4009
|
+
const isCorrect = userAnswer && userAnswer === question.correctOptionId;
|
|
4010
|
+
if (isCorrect) {
|
|
4011
|
+
correctAnswers++;
|
|
4012
|
+
}
|
|
4013
|
+
if (question.difficulty === "FACIL" /* FACIL */) {
|
|
4014
|
+
totalEasyQuestions++;
|
|
4015
|
+
if (isCorrect) {
|
|
4016
|
+
correctEasyAnswers++;
|
|
4017
|
+
}
|
|
4018
|
+
} else if (question.difficulty === "MEDIO" /* MEDIO */) {
|
|
4019
|
+
totalMediumQuestions++;
|
|
4020
|
+
if (isCorrect) {
|
|
4021
|
+
correctMediumAnswers++;
|
|
4022
|
+
}
|
|
4023
|
+
} else if (question.difficulty === "DIFICIL" /* DIFICIL */) {
|
|
4024
|
+
totalDifficultQuestions++;
|
|
4025
|
+
if (isCorrect) {
|
|
4026
|
+
correctDifficultAnswers++;
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
});
|
|
4030
|
+
}
|
|
4031
|
+
const percentage = totalQuestions > 0 ? Math.round(correctAnswers / totalQuestions * 100) : 0;
|
|
4032
|
+
return /* @__PURE__ */ jsxs11(
|
|
4033
|
+
"div",
|
|
4034
|
+
{
|
|
4035
|
+
className: "flex flex-row gap-6 p-6 rounded-xl bg-background justify-between",
|
|
4036
|
+
ref,
|
|
4037
|
+
...props,
|
|
4038
|
+
children: [
|
|
4039
|
+
/* @__PURE__ */ jsxs11("div", { className: "relative", children: [
|
|
4040
|
+
/* @__PURE__ */ jsx13(
|
|
4041
|
+
ProgressCircle_default,
|
|
4042
|
+
{
|
|
4043
|
+
size: "medium",
|
|
4044
|
+
variant: "green",
|
|
4045
|
+
value: percentage,
|
|
4046
|
+
showPercentage: false,
|
|
4047
|
+
label: ""
|
|
4048
|
+
}
|
|
4049
|
+
),
|
|
4050
|
+
/* @__PURE__ */ jsxs11("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: [
|
|
4051
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 mb-1", children: [
|
|
4052
|
+
/* @__PURE__ */ jsx13(Clock2, { size: 12, weight: "regular", className: "text-text-800" }),
|
|
4053
|
+
/* @__PURE__ */ jsx13("span", { className: "text-2xs font-medium text-text-800", children: formatTime(timeElapsed) })
|
|
4054
|
+
] }),
|
|
4055
|
+
/* @__PURE__ */ jsxs11("div", { className: "text-2xl font-medium text-text-800 leading-7", children: [
|
|
4056
|
+
correctAnswers,
|
|
4057
|
+
" de ",
|
|
4058
|
+
totalQuestions
|
|
4059
|
+
] }),
|
|
4060
|
+
/* @__PURE__ */ jsx13("div", { className: "text-2xs font-medium text-text-600 mt-1", children: "Corretas" })
|
|
4061
|
+
] })
|
|
4062
|
+
] }),
|
|
4063
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-4 w-full", children: [
|
|
4064
|
+
/* @__PURE__ */ jsx13(
|
|
4065
|
+
ProgressBar_default,
|
|
4066
|
+
{
|
|
4067
|
+
className: "w-full",
|
|
4068
|
+
layout: "stacked",
|
|
4069
|
+
variant: "green",
|
|
4070
|
+
value: correctEasyAnswers,
|
|
4071
|
+
max: totalEasyQuestions,
|
|
4072
|
+
label: "F\xE1ceis",
|
|
4073
|
+
showHitCount: true,
|
|
4074
|
+
labelClassName: "text-base font-medium text-text-800 leading-none",
|
|
4075
|
+
percentageClassName: "text-xs font-medium leading-[14px] text-right"
|
|
4076
|
+
}
|
|
4077
|
+
),
|
|
4078
|
+
/* @__PURE__ */ jsx13(
|
|
4079
|
+
ProgressBar_default,
|
|
4080
|
+
{
|
|
4081
|
+
className: "w-full",
|
|
4082
|
+
layout: "stacked",
|
|
4083
|
+
variant: "green",
|
|
4084
|
+
value: correctMediumAnswers,
|
|
4085
|
+
max: totalMediumQuestions,
|
|
4086
|
+
label: "M\xE9dias",
|
|
4087
|
+
showHitCount: true,
|
|
4088
|
+
labelClassName: "text-base font-medium text-text-800 leading-none",
|
|
4089
|
+
percentageClassName: "text-xs font-medium leading-[14px] text-right"
|
|
4090
|
+
}
|
|
4091
|
+
),
|
|
4092
|
+
/* @__PURE__ */ jsx13(
|
|
4093
|
+
ProgressBar_default,
|
|
4094
|
+
{
|
|
4095
|
+
className: "w-full",
|
|
4096
|
+
layout: "stacked",
|
|
4097
|
+
variant: "green",
|
|
4098
|
+
value: correctDifficultAnswers,
|
|
4099
|
+
max: totalDifficultQuestions,
|
|
4100
|
+
label: "Dif\xEDceis",
|
|
4101
|
+
showHitCount: true,
|
|
4102
|
+
labelClassName: "text-base font-medium text-text-800 leading-none",
|
|
4103
|
+
percentageClassName: "text-xs font-medium leading-[14px] text-right"
|
|
4104
|
+
}
|
|
4105
|
+
)
|
|
4106
|
+
] })
|
|
4107
|
+
]
|
|
4108
|
+
}
|
|
4109
|
+
);
|
|
4110
|
+
}
|
|
4111
|
+
);
|
|
4112
|
+
var QuizListResult = forwardRef7(({ className, onSubjectClick, ...props }, ref) => {
|
|
4113
|
+
const { getQuestionsGroupedBySubject, isQuestionAnswered } = useQuizStore();
|
|
4114
|
+
const groupedQuestions = getQuestionsGroupedBySubject();
|
|
4115
|
+
const subjectsStats = Object.entries(groupedQuestions).map(
|
|
4116
|
+
([subjectId, questions]) => {
|
|
4117
|
+
let correct = 0;
|
|
4118
|
+
let incorrect = 0;
|
|
4119
|
+
questions.forEach((question) => {
|
|
4120
|
+
if (isQuestionAnswered(question.id)) {
|
|
4121
|
+
const userAnswer = question.answerKey;
|
|
4122
|
+
if (userAnswer === question.correctOptionId) {
|
|
4123
|
+
correct++;
|
|
4124
|
+
} else {
|
|
4125
|
+
incorrect++;
|
|
4126
|
+
}
|
|
4127
|
+
}
|
|
4128
|
+
});
|
|
4129
|
+
return {
|
|
4130
|
+
subject: subjectId,
|
|
4131
|
+
correct,
|
|
4132
|
+
incorrect,
|
|
4133
|
+
total: questions.length
|
|
4134
|
+
};
|
|
4135
|
+
}
|
|
4136
|
+
);
|
|
4137
|
+
return /* @__PURE__ */ jsxs11("section", { ref, className, ...props, children: [
|
|
4138
|
+
/* @__PURE__ */ jsx13("p", { className: "pt-6 pb-4 text-text-950 font-bold text-lg", children: "Mat\xE9rias" }),
|
|
4139
|
+
/* @__PURE__ */ jsx13("ul", { className: "flex flex-col gap-2", children: subjectsStats.map((subject) => /* @__PURE__ */ jsx13("li", { children: /* @__PURE__ */ jsx13(
|
|
4140
|
+
CardResults,
|
|
4141
|
+
{
|
|
4142
|
+
onClick: () => onSubjectClick?.(subject.subject),
|
|
4143
|
+
className: "max-w-full",
|
|
4144
|
+
header: subject.subject,
|
|
4145
|
+
correct_answers: subject.correct,
|
|
4146
|
+
incorrect_answers: subject.incorrect,
|
|
4147
|
+
icon: /* @__PURE__ */ jsx13(Book, { size: 20 }),
|
|
4148
|
+
direction: "row"
|
|
4149
|
+
}
|
|
4150
|
+
) }, subject.subject)) })
|
|
4151
|
+
] });
|
|
4152
|
+
});
|
|
4153
|
+
var QuizListResultByMateria = ({
|
|
4154
|
+
subject,
|
|
4155
|
+
onQuestionClick
|
|
4156
|
+
}) => {
|
|
4157
|
+
const { getQuestionsGroupedBySubject } = useQuizStore();
|
|
4158
|
+
const groupedQuestions = getQuestionsGroupedBySubject();
|
|
4159
|
+
const answeredQuestions = groupedQuestions[subject] || [];
|
|
4160
|
+
return /* @__PURE__ */ jsxs11("div", { className: "w-full max-w-[1000px] flex flex-col mx-auto h-full relative not-lg:px-6", children: [
|
|
4161
|
+
/* @__PURE__ */ jsx13("div", { className: "flex flex-row pt-4 justify-between", children: /* @__PURE__ */ jsx13("p", { className: "text-text-950 font-bold text-2xl", children: subject }) }),
|
|
4162
|
+
/* @__PURE__ */ jsxs11("section", { className: "flex flex-col ", children: [
|
|
4163
|
+
/* @__PURE__ */ jsx13("p", { className: "pt-6 pb-4 text-text-950 font-bold text-lg", children: "Resultado das quest\xF5es" }),
|
|
4164
|
+
/* @__PURE__ */ jsx13("ul", { className: "flex flex-col gap-2 pt-4", children: answeredQuestions.map((question) => /* @__PURE__ */ jsx13("li", { children: /* @__PURE__ */ jsx13(
|
|
4165
|
+
CardStatus,
|
|
4166
|
+
{
|
|
4167
|
+
className: "max-w-full",
|
|
4168
|
+
header: `Quest\xE3o ${question.id}`,
|
|
4169
|
+
status: question.answerKey === question.correctOptionId ? "correct" : "incorrect",
|
|
4170
|
+
onClick: () => onQuestionClick?.(question)
|
|
4171
|
+
}
|
|
4172
|
+
) }, question.id)) })
|
|
4173
|
+
] })
|
|
4174
|
+
] });
|
|
4175
|
+
};
|
|
4176
|
+
export {
|
|
4177
|
+
Quiz,
|
|
4178
|
+
QuizAlternative,
|
|
4179
|
+
QuizContent,
|
|
4180
|
+
QuizFooter,
|
|
4181
|
+
QuizHeader,
|
|
4182
|
+
QuizHeaderResult,
|
|
4183
|
+
QuizListResult,
|
|
4184
|
+
QuizListResultByMateria,
|
|
4185
|
+
QuizQuestionList,
|
|
4186
|
+
QuizResultHeaderTitle,
|
|
4187
|
+
QuizResultPerformance,
|
|
4188
|
+
QuizResultTitle,
|
|
4189
|
+
QuizTitle
|
|
4190
|
+
};
|
|
4191
|
+
//# sourceMappingURL=index.mjs.map
|