analytica-frontend-lib 1.0.98 → 1.1.0

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.
@@ -69,6 +69,6 @@ declare const CheckBox: react.ForwardRefExoticComponent<{
69
69
  className?: string;
70
70
  /** Label CSS classes */
71
71
  labelClassName?: string;
72
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
72
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & react.RefAttributes<HTMLInputElement>>;
73
73
 
74
74
  export { type CheckBoxProps, CheckBox as default };
@@ -69,6 +69,6 @@ declare const CheckBox: react.ForwardRefExoticComponent<{
69
69
  className?: string;
70
70
  /** Label CSS classes */
71
71
  labelClassName?: string;
72
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
72
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & react.RefAttributes<HTMLInputElement>>;
73
73
 
74
74
  export { type CheckBoxProps, CheckBox as default };
@@ -30,6 +30,7 @@ declare const QuizDissertative: ({ variant, paddingBottom, }: QuizVariantInterfa
30
30
  declare const QuizTrueOrFalse: ({ variant, paddingBottom, }: QuizVariantInterface) => react_jsx_runtime.JSX.Element;
31
31
  declare const QuizConnectDots: ({ variant, paddingBottom, }: QuizVariantInterface) => react_jsx_runtime.JSX.Element;
32
32
  declare const QuizFill: ({ variant, paddingBottom, }: QuizVariantInterface) => react_jsx_runtime.JSX.Element;
33
+ declare const QuizImageQuestion: ({ variant, paddingBottom, }: QuizVariantInterface) => react_jsx_runtime.JSX.Element;
33
34
  declare const QuizQuestionList: ({ filterType, onQuestionClick, }?: {
34
35
  filterType?: string;
35
36
  onQuestionClick?: () => void;
@@ -39,6 +40,7 @@ declare const QuizFooter: react.ForwardRefExoticComponent<{
39
40
  variant?: "result" | "default";
40
41
  onGoToSimulated?: () => void;
41
42
  onDetailResult?: () => void;
43
+ handleFinishSimulated?: () => void;
42
44
  } & react.RefAttributes<HTMLDivElement>>;
43
45
  declare const QuizResultHeaderTitle: react.ForwardRefExoticComponent<{
44
46
  className?: string;
@@ -56,4 +58,4 @@ declare const QuizListResultByMateria: ({ subject, onQuestionClick, }: {
56
58
  onQuestionClick: (question: Question) => void;
57
59
  }) => react_jsx_runtime.JSX.Element;
58
60
 
59
- export { Quiz, QuizAlternative, QuizConnectDots, QuizContent, QuizDissertative, QuizFill, QuizFooter, QuizHeader, QuizHeaderResult, QuizListResult, QuizListResultByMateria, QuizMultipleChoice, QuizQuestionList, QuizResultHeaderTitle, QuizResultPerformance, QuizResultTitle, QuizTitle, QuizTrueOrFalse, getStatusBadge };
61
+ export { Quiz, QuizAlternative, QuizConnectDots, QuizContent, QuizDissertative, QuizFill, QuizFooter, QuizHeader, QuizHeaderResult, QuizImageQuestion, QuizListResult, QuizListResultByMateria, QuizMultipleChoice, QuizQuestionList, QuizResultHeaderTitle, QuizResultPerformance, QuizResultTitle, QuizTitle, QuizTrueOrFalse, getStatusBadge };
@@ -30,6 +30,7 @@ declare const QuizDissertative: ({ variant, paddingBottom, }: QuizVariantInterfa
30
30
  declare const QuizTrueOrFalse: ({ variant, paddingBottom, }: QuizVariantInterface) => react_jsx_runtime.JSX.Element;
31
31
  declare const QuizConnectDots: ({ variant, paddingBottom, }: QuizVariantInterface) => react_jsx_runtime.JSX.Element;
32
32
  declare const QuizFill: ({ variant, paddingBottom, }: QuizVariantInterface) => react_jsx_runtime.JSX.Element;
33
+ declare const QuizImageQuestion: ({ variant, paddingBottom, }: QuizVariantInterface) => react_jsx_runtime.JSX.Element;
33
34
  declare const QuizQuestionList: ({ filterType, onQuestionClick, }?: {
34
35
  filterType?: string;
35
36
  onQuestionClick?: () => void;
@@ -39,6 +40,7 @@ declare const QuizFooter: react.ForwardRefExoticComponent<{
39
40
  variant?: "result" | "default";
40
41
  onGoToSimulated?: () => void;
41
42
  onDetailResult?: () => void;
43
+ handleFinishSimulated?: () => void;
42
44
  } & react.RefAttributes<HTMLDivElement>>;
43
45
  declare const QuizResultHeaderTitle: react.ForwardRefExoticComponent<{
44
46
  className?: string;
@@ -56,4 +58,4 @@ declare const QuizListResultByMateria: ({ subject, onQuestionClick, }: {
56
58
  onQuestionClick: (question: Question) => void;
57
59
  }) => react_jsx_runtime.JSX.Element;
58
60
 
59
- export { Quiz, QuizAlternative, QuizConnectDots, QuizContent, QuizDissertative, QuizFill, QuizFooter, QuizHeader, QuizHeaderResult, QuizListResult, QuizListResultByMateria, QuizMultipleChoice, QuizQuestionList, QuizResultHeaderTitle, QuizResultPerformance, QuizResultTitle, QuizTitle, QuizTrueOrFalse, getStatusBadge };
61
+ export { Quiz, QuizAlternative, QuizConnectDots, QuizContent, QuizDissertative, QuizFill, QuizFooter, QuizHeader, QuizHeaderResult, QuizImageQuestion, QuizListResult, QuizListResultByMateria, QuizMultipleChoice, QuizQuestionList, QuizResultHeaderTitle, QuizResultPerformance, QuizResultTitle, QuizTitle, QuizTrueOrFalse, getStatusBadge };
@@ -29,6 +29,7 @@ __export(Quiz_exports, {
29
29
  QuizFooter: () => QuizFooter,
30
30
  QuizHeader: () => QuizHeader,
31
31
  QuizHeaderResult: () => QuizHeaderResult,
32
+ QuizImageQuestion: () => QuizImageQuestion,
32
33
  QuizListResult: () => QuizListResult,
33
34
  QuizListResultByMateria: () => QuizListResultByMateria,
34
35
  QuizMultipleChoice: () => QuizMultipleChoice,
@@ -4467,6 +4468,9 @@ var TextArea = (0, import_react11.forwardRef)(
4467
4468
  TextArea.displayName = "TextArea";
4468
4469
  var TextArea_default = TextArea;
4469
4470
 
4471
+ // src/assets/img/mock-image-question.png
4472
+ var mock_image_question_default = "../mock-image-question-HEZCLFDL.png";
4473
+
4470
4474
  // src/components/Quiz/Quiz.tsx
4471
4475
  var import_jsx_runtime17 = require("react/jsx-runtime");
4472
4476
  var getStatusBadge = (status) => {
@@ -4605,7 +4609,8 @@ var QuizContent = (0, import_react12.forwardRef)(({ variant, paddingBottom }) =>
4605
4609
  ["DISSERTATIVA" /* DISSERTATIVA */]: QuizDissertative,
4606
4610
  ["VERDADEIRO_FALSO" /* VERDADEIRO_FALSO */]: QuizTrueOrFalse,
4607
4611
  ["LIGAR_PONTOS" /* LIGAR_PONTOS */]: QuizConnectDots,
4608
- ["PREENCHER" /* PREENCHER */]: QuizFill
4612
+ ["PREENCHER" /* PREENCHER */]: QuizFill,
4613
+ ["IMAGEM" /* IMAGEM */]: QuizImageQuestion
4609
4614
  };
4610
4615
  const QuestionComponent = currentQuestion ? questionComponents[currentQuestion.type] : null;
4611
4616
  return QuestionComponent ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(QuestionComponent, { variant, paddingBottom }) : null;
@@ -5145,6 +5150,147 @@ var QuizFill = ({
5145
5150
  ] })
5146
5151
  ] });
5147
5152
  };
5153
+ var QuizImageQuestion = ({
5154
+ variant = "default",
5155
+ paddingBottom
5156
+ }) => {
5157
+ const correctPositionRelative = { x: 0.48, y: 0.45 };
5158
+ const calculateCorrectRadiusRelative = () => {
5159
+ const circleWidthRelative = 0.15;
5160
+ const circleHeightRelative = 0.3;
5161
+ const averageRadius = (circleWidthRelative + circleHeightRelative) / 4;
5162
+ const tolerance = 0.02;
5163
+ return averageRadius + tolerance;
5164
+ };
5165
+ const correctRadiusRelative = calculateCorrectRadiusRelative();
5166
+ const mockUserAnswerRelative = { x: 0.72, y: 0.348 };
5167
+ const [clickPositionRelative, setClickPositionRelative] = (0, import_react12.useState)(variant == "result" ? mockUserAnswerRelative : null);
5168
+ const convertToRelativeCoordinates = (x, y, rect) => {
5169
+ const safeWidth = Math.max(rect.width, 1e-3);
5170
+ const safeHeight = Math.max(rect.height, 1e-3);
5171
+ const xRelative = Math.max(0, Math.min(1, x / safeWidth));
5172
+ const yRelative = Math.max(0, Math.min(1, y / safeHeight));
5173
+ return { x: xRelative, y: yRelative };
5174
+ };
5175
+ const handleImageClick = (event) => {
5176
+ if (variant === "result") return;
5177
+ const rect = event.currentTarget.getBoundingClientRect();
5178
+ const x = event.clientX - rect.left;
5179
+ const y = event.clientY - rect.top;
5180
+ const positionRelative = convertToRelativeCoordinates(x, y, rect);
5181
+ setClickPositionRelative(positionRelative);
5182
+ };
5183
+ const handleKeyboardActivate = () => {
5184
+ if (variant === "result") return;
5185
+ setClickPositionRelative({ x: 0.5, y: 0.5 });
5186
+ };
5187
+ const isCorrect = () => {
5188
+ if (!clickPositionRelative) return false;
5189
+ const distance = Math.sqrt(
5190
+ Math.pow(clickPositionRelative.x - correctPositionRelative.x, 2) + Math.pow(clickPositionRelative.y - correctPositionRelative.y, 2)
5191
+ );
5192
+ return distance <= correctRadiusRelative;
5193
+ };
5194
+ const getUserCircleColorClasses = () => {
5195
+ if (variant === "default") {
5196
+ return "bg-indicator-primary/70 border-[#F8CC2E]";
5197
+ }
5198
+ if (variant === "result") {
5199
+ return isCorrect() ? "bg-success-600/70 border-white" : "bg-indicator-error/70 border-white";
5200
+ }
5201
+ return "bg-success-600/70 border-white";
5202
+ };
5203
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
5204
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(QuizSubTitle, { subTitle: "Clique na \xE1rea correta" }),
5205
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(QuizContainer, { className: cn("", paddingBottom), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5206
+ "div",
5207
+ {
5208
+ "data-testid": "quiz-image-container",
5209
+ className: "space-y-6 p-3 relative inline-block",
5210
+ children: [
5211
+ variant == "result" && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5212
+ "div",
5213
+ {
5214
+ "data-testid": "quiz-legend",
5215
+ className: "flex items-center gap-4 text-xs",
5216
+ children: [
5217
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2", children: [
5218
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "w-3 h-3 rounded-full bg-indicator-primary/70 border border-[#F8CC2E]" }),
5219
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-text-600 font-medium text-sm", children: "\xC1rea correta" })
5220
+ ] }),
5221
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2", children: [
5222
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "w-3 h-3 rounded-full bg-success-600/70 border border-white" }),
5223
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-text-600 font-medium text-sm", children: "Resposta correta" })
5224
+ ] }),
5225
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2", children: [
5226
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "w-3 h-3 rounded-full bg-indicator-error/70 border border-white" }),
5227
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-text-600 font-medium text-sm", children: "Resposta incorreta" })
5228
+ ] })
5229
+ ]
5230
+ }
5231
+ ),
5232
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5233
+ "button",
5234
+ {
5235
+ "data-testid": "quiz-image-button",
5236
+ type: "button",
5237
+ className: "relative cursor-pointer w-full h-full border-0 bg-transparent p-0",
5238
+ onClick: handleImageClick,
5239
+ onKeyDown: (e) => {
5240
+ if (e.key === "Enter" || e.key === " ") {
5241
+ e.preventDefault();
5242
+ handleKeyboardActivate();
5243
+ }
5244
+ },
5245
+ "aria-label": "\xC1rea da imagem interativa",
5246
+ children: [
5247
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5248
+ "img",
5249
+ {
5250
+ "data-testid": "quiz-image",
5251
+ src: mock_image_question_default,
5252
+ alt: "Question",
5253
+ className: "w-full h-auto rounded-md"
5254
+ }
5255
+ ),
5256
+ variant === "result" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5257
+ "div",
5258
+ {
5259
+ "data-testid": "quiz-correct-circle",
5260
+ className: "absolute rounded-full bg-indicator-primary/70 border-4 border-[#F8CC2E] pointer-events-none",
5261
+ style: {
5262
+ minWidth: "50px",
5263
+ maxWidth: "160px",
5264
+ width: "15%",
5265
+ aspectRatio: "1 / 1",
5266
+ left: `calc(${correctPositionRelative.x * 100}% - 7.5%)`,
5267
+ top: `calc(${correctPositionRelative.y * 100}% - 15%)`
5268
+ }
5269
+ }
5270
+ ),
5271
+ clickPositionRelative && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5272
+ "div",
5273
+ {
5274
+ "data-testid": "quiz-user-circle",
5275
+ className: `absolute rounded-full border-4 pointer-events-none ${getUserCircleColorClasses()}`,
5276
+ style: {
5277
+ minWidth: "30px",
5278
+ maxWidth: "52px",
5279
+ width: "5%",
5280
+ aspectRatio: "1 / 1",
5281
+ left: `calc(${clickPositionRelative.x * 100}% - 2.5%)`,
5282
+ top: `calc(${clickPositionRelative.y * 100}% - 2.5%)`
5283
+ }
5284
+ }
5285
+ )
5286
+ ]
5287
+ }
5288
+ )
5289
+ ]
5290
+ }
5291
+ ) })
5292
+ ] });
5293
+ };
5148
5294
  var QuizQuestionList = ({
5149
5295
  filterType = "all",
5150
5296
  onQuestionClick
@@ -5226,6 +5372,7 @@ var QuizFooter = (0, import_react12.forwardRef)(
5226
5372
  className,
5227
5373
  onGoToSimulated,
5228
5374
  onDetailResult,
5375
+ handleFinishSimulated,
5229
5376
  variant = "default",
5230
5377
  ...props
5231
5378
  }, ref) => {
@@ -5255,6 +5402,34 @@ var QuizFooter = (0, import_react12.forwardRef)(
5255
5402
  const unansweredQuestions = getUnansweredQuestionsFromUserAnswers();
5256
5403
  const userAnswers = getUserAnswers();
5257
5404
  const allQuestions = getTotalQuestions();
5405
+ const handleFinishQuiz = async () => {
5406
+ if (unansweredQuestions.length > 0) {
5407
+ setAlertDialogOpen(true);
5408
+ return;
5409
+ }
5410
+ try {
5411
+ if (handleFinishSimulated) {
5412
+ await Promise.resolve(handleFinishSimulated());
5413
+ }
5414
+ setModalResultOpen(true);
5415
+ } catch (err) {
5416
+ console.error("handleFinishSimulated failed:", err);
5417
+ setModalResultOpen(true);
5418
+ }
5419
+ };
5420
+ const handleAlertSubmit = async () => {
5421
+ try {
5422
+ if (handleFinishSimulated) {
5423
+ await Promise.resolve(handleFinishSimulated());
5424
+ }
5425
+ setModalResultOpen(true);
5426
+ setAlertDialogOpen(false);
5427
+ } catch (err) {
5428
+ console.error("handleFinishSimulated failed:", err);
5429
+ setModalResultOpen(true);
5430
+ setAlertDialogOpen(false);
5431
+ }
5432
+ };
5258
5433
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
5259
5434
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5260
5435
  "footer",
@@ -5320,13 +5495,7 @@ var QuizFooter = (0, import_react12.forwardRef)(
5320
5495
  variant: "solid",
5321
5496
  action: "primary",
5322
5497
  disabled: !currentAnswer && !isCurrentQuestionSkipped,
5323
- onClick: () => {
5324
- if (unansweredQuestions.length > 0) {
5325
- setAlertDialogOpen(true);
5326
- } else {
5327
- setModalResultOpen(true);
5328
- }
5329
- },
5498
+ onClick: handleFinishQuiz,
5330
5499
  children: "Finalizar"
5331
5500
  }
5332
5501
  ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
@@ -5355,9 +5524,7 @@ var QuizFooter = (0, import_react12.forwardRef)(
5355
5524
  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?",
5356
5525
  cancelButtonLabel: "Voltar e revisar",
5357
5526
  submitButtonLabel: "Finalizar Mesmo Assim",
5358
- onSubmit: () => {
5359
- setModalResultOpen(true);
5360
- }
5527
+ onSubmit: handleAlertSubmit
5361
5528
  }
5362
5529
  ),
5363
5530
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
@@ -5694,6 +5861,7 @@ var QuizListResultByMateria = ({
5694
5861
  QuizFooter,
5695
5862
  QuizHeader,
5696
5863
  QuizHeaderResult,
5864
+ QuizImageQuestion,
5697
5865
  QuizListResult,
5698
5866
  QuizListResultByMateria,
5699
5867
  QuizMultipleChoice,