academe-kit 0.9.8 → 0.9.9

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.
@@ -16,6 +16,7 @@ export { useProtectedAppColors } from "./components/ProtectedApp";
16
16
  export type { AcademeKeycloakContextProps, SecurityProviderProps, KeycloakUser, SecurityContextType, AcademeUser, } from "./context/SecurityProvider/types";
17
17
  export { createAcademeApiClient } from "./services";
18
18
  export type { AcademeApiClient, AcademeServices } from "./services";
19
+ export type { ChallengeUserQuizAttempt, ChallengeUserQuizAttemptsResponse, } from "./services/ChallengeService";
19
20
  export { cn } from "./lib/utils";
20
21
  import "./index.css";
21
22
  import "./styles/globals.css";
@@ -28,6 +28,35 @@ export interface UpdateEvaluationCriterionBody {
28
28
  description?: string;
29
29
  index?: number;
30
30
  }
31
+ export interface ChallengeUserQuizAttempt {
32
+ challengeStepId: string;
33
+ challengeStepName: string;
34
+ challengeStepIndex: number;
35
+ courseModuleId: string;
36
+ courseModuleTitle: string;
37
+ quizId: string;
38
+ quizTitle: string;
39
+ attempt: {
40
+ id: string;
41
+ score: number;
42
+ passed: boolean;
43
+ startedAt: string;
44
+ completedAt: string | null;
45
+ } | null;
46
+ certificate: {
47
+ id: string;
48
+ certificateNumber: string;
49
+ url: string | null;
50
+ } | null;
51
+ }
52
+ export interface ChallengeUserQuizAttemptsResponse {
53
+ data?: {
54
+ status?: string;
55
+ data?: ChallengeUserQuizAttempt[];
56
+ };
57
+ error?: unknown;
58
+ response: Response;
59
+ }
31
60
  export declare function createChallengeService(apiClient: AcademeApiClient): {
32
61
  /**
33
62
  * List challenges with filters and pagination
@@ -339,6 +368,12 @@ export declare function createChallengeService(apiClient: AcademeApiClient): {
339
368
  title?: string;
340
369
  };
341
370
  }, `${string}/${string}`>>;
371
+ /**
372
+ * Get a user's quiz attempts for the quizzes attached to this challenge's
373
+ * course modules (one entry per step with course_module.quiz_id).
374
+ * Defaults to the authenticated user when userId is omitted.
375
+ */
376
+ getUserQuizAttempts(challengeId: string, userId?: string): Promise<ChallengeUserQuizAttemptsResponse>;
342
377
  /**
343
378
  * Add a step to the challenge
344
379
  */
@@ -570,6 +570,62 @@ export declare function createReportService(apiClient: AcademeApiClient): {
570
570
  query: GetTopStudentsParams;
571
571
  };
572
572
  }, `${string}/${string}`>>;
573
+ /**
574
+ * Get encourage dashboard for an institution
575
+ * Retorna o payload agregado da tela /new-dashboard:
576
+ * overview, KPIs, licenças (alunos), jornada (cursos), submissões,
577
+ * desempenho por turma, top alunos e top professores.
578
+ *
579
+ * @param id UUID da instituição.
580
+ */
581
+ getEncourageDashboardByInstitution(id: string): Promise<import("openapi-fetch").FetchResponse<{
582
+ parameters: {
583
+ query?: never;
584
+ header?: never;
585
+ path: {
586
+ id: string;
587
+ };
588
+ cookie?: never;
589
+ };
590
+ requestBody?: never;
591
+ responses: {
592
+ 200: {
593
+ headers: {
594
+ [name: string]: unknown;
595
+ };
596
+ content: {
597
+ "application/json": {
598
+ status?: string;
599
+ data?: import("../types/academe-api").components["schemas"]["EncourageDashboardResponse"];
600
+ };
601
+ };
602
+ };
603
+ 400: {
604
+ headers: {
605
+ [name: string]: unknown;
606
+ };
607
+ content?: never;
608
+ };
609
+ 401: {
610
+ headers: {
611
+ [name: string]: unknown;
612
+ };
613
+ content?: never;
614
+ };
615
+ 500: {
616
+ headers: {
617
+ [name: string]: unknown;
618
+ };
619
+ content?: never;
620
+ };
621
+ };
622
+ }, {
623
+ params: {
624
+ path: {
625
+ id: string;
626
+ };
627
+ };
628
+ }, `${string}/${string}`>>;
573
629
  };
574
630
  export type ReportService = ReturnType<typeof createReportService>;
575
631
  export {};
@@ -37,7 +37,14 @@ export declare function createSubmissionService(apiClient: AcademeApiClient): {
37
37
  "application/json": {
38
38
  status?: string;
39
39
  data?: import("../types/academe-api").components["schemas"]["Submission"][];
40
- meta?: import("../types/academe-api").components["schemas"]["PaginationMeta"];
40
+ meta?: import("../types/academe-api").components["schemas"]["PaginationMeta"] & {
41
+ statusCounts?: {
42
+ submitted?: number;
43
+ ai_evaluated?: number;
44
+ approved?: number;
45
+ rejected?: number;
46
+ };
47
+ };
41
48
  };
42
49
  };
43
50
  };
@@ -2790,6 +2790,91 @@ export interface paths {
2790
2790
  };
2791
2791
  trace?: never;
2792
2792
  };
2793
+ "/challenges/{id}/quiz-attempts": {
2794
+ parameters: {
2795
+ query?: never;
2796
+ header?: never;
2797
+ path?: never;
2798
+ cookie?: never;
2799
+ };
2800
+ /**
2801
+ * Get a user's quiz attempts for this challenge's course modules
2802
+ * @description Returns the quiz attempts of `userId` on every quiz attached to a course
2803
+ * module that is referenced by one of this challenge's steps. Optionally
2804
+ * includes the issued certificate per attempt.
2805
+ *
2806
+ * Each entry corresponds to a `challenges_steps` row that has a non-null
2807
+ * `course_module_id` whose `course_module.quiz_id` is also non-null.
2808
+ * `attempt` is `null` when the user has not yet attempted that quiz.
2809
+ */
2810
+ get: {
2811
+ parameters: {
2812
+ query?: {
2813
+ /** @description Defaults to the authenticated user when omitted. */
2814
+ userId?: string;
2815
+ };
2816
+ header?: never;
2817
+ path: {
2818
+ /** @description Resource ID */
2819
+ id: components["parameters"]["id"];
2820
+ };
2821
+ cookie?: never;
2822
+ };
2823
+ requestBody?: never;
2824
+ responses: {
2825
+ /** @description List of quiz attempts (one per quiz-bearing challenge step) */
2826
+ 200: {
2827
+ headers: {
2828
+ [name: string]: unknown;
2829
+ };
2830
+ content: {
2831
+ "application/json": {
2832
+ /** @example success */
2833
+ status?: string;
2834
+ data?: {
2835
+ /** Format: uuid */
2836
+ challengeStepId?: string;
2837
+ challengeStepName?: string;
2838
+ challengeStepIndex?: number;
2839
+ /** Format: uuid */
2840
+ courseModuleId?: string;
2841
+ courseModuleTitle?: string;
2842
+ /** Format: uuid */
2843
+ quizId?: string;
2844
+ quizTitle?: string;
2845
+ attempt?: {
2846
+ /** Format: uuid */
2847
+ id?: string;
2848
+ score?: number;
2849
+ passed?: boolean;
2850
+ /** Format: date-time */
2851
+ startedAt?: string;
2852
+ /** Format: date-time */
2853
+ completedAt?: string | null;
2854
+ } | null;
2855
+ certificate?: {
2856
+ /** Format: uuid */
2857
+ id?: string;
2858
+ certificateNumber?: string;
2859
+ url?: string | null;
2860
+ } | null;
2861
+ }[];
2862
+ };
2863
+ };
2864
+ };
2865
+ 400: components["responses"]["BadRequest"];
2866
+ 401: components["responses"]["Unauthorized"];
2867
+ 404: components["responses"]["NotFound"];
2868
+ };
2869
+ };
2870
+ put?: never;
2871
+ post?: never;
2872
+ delete?: never;
2873
+ options?: never;
2874
+ head?: never;
2875
+ patch?: never;
2876
+ trace?: never;
2877
+ };
2793
2878
  "/classrooms": {
2794
2879
  parameters: {
2795
2880
  query?: never;
@@ -11619,7 +11704,22 @@ export interface paths {
11619
11704
  /** @example success */
11620
11705
  status?: string;
11621
11706
  data?: components["schemas"]["Submission"][];
11622
- meta?: components["schemas"]["PaginationMeta"];
11707
+ meta?: components["schemas"]["PaginationMeta"] & {
11708
+ /**
11709
+ * @description Contagem por status, ignorando o filtro `status`. Útil para
11710
+ * alimentar abas/pills sem requisições adicionais.
11711
+ */
11712
+ statusCounts?: {
11713
+ /** @example 12 */
11714
+ submitted?: number;
11715
+ /** @example 4 */
11716
+ ai_evaluated?: number;
11717
+ /** @example 30 */
11718
+ approved?: number;
11719
+ /** @example 2 */
11720
+ rejected?: number;
11721
+ };
11722
+ };
11623
11723
  };
11624
11724
  };
11625
11725
  };
@@ -12281,6 +12381,128 @@ export interface paths {
12281
12381
  patch?: never;
12282
12382
  trace?: never;
12283
12383
  };
12384
+ "/user-challenge-progress/journey": {
12385
+ parameters: {
12386
+ query?: never;
12387
+ header?: never;
12388
+ path?: never;
12389
+ cookie?: never;
12390
+ };
12391
+ /**
12392
+ * Jornada completa pré-computada do aluno autenticado
12393
+ * @description Retorna todos os desafios da série com suas etapas e o status de progresso do aluno
12394
+ * já computados pelo backend. Substitui as ~25 chamadas HTTP paralelas que o frontend
12395
+ * fazia anteriormente para montar a tela de jornada.
12396
+ *
12397
+ * **Regra de prioridade:** para cada `index` de desafio dentro da série, o backend
12398
+ * prefere o challenge específico da instituição do aluno sobre o template global
12399
+ * (`institution_id IS NULL`). Isso permite que escolas customizem desafios pontuais
12400
+ * sem recriar toda a jornada.
12401
+ *
12402
+ * **Resolução da série:** se `serieId` não for informado, o backend resolve
12403
+ * automaticamente a partir da turma (`institutionClassroom`) do aluno. Se o aluno
12404
+ * não estiver em nenhuma turma e `serieId` também não for passado, retorna
12405
+ * `challenges: []` com `serieId: null`.
12406
+ *
12407
+ * **Status por etapa:** `done` = completedAt preenchido; `current` = primeira etapa
12408
+ * não concluída (apenas uma por vez); `locked` = todas as demais.
12409
+ *
12410
+ * **Progresso:** para etapas `type=course` no status `current`, o campo `progress`
12411
+ * reflete o percentual de lições concluídas no módulo. Para `done` é sempre 100,
12412
+ * para `locked` é sempre 0.
12413
+ */
12414
+ get: {
12415
+ parameters: {
12416
+ query?: {
12417
+ /**
12418
+ * @description ID da série a filtrar. Opcional — se omitido, o backend resolve pela turma do aluno.
12419
+ * Útil para pré-visualização administrativa ou quando o aluno pertence a múltiplas séries.
12420
+ */
12421
+ serieId?: string;
12422
+ };
12423
+ header?: never;
12424
+ path?: never;
12425
+ cookie?: never;
12426
+ };
12427
+ requestBody?: never;
12428
+ responses: {
12429
+ /** @description Jornada pré-computada com desafios e etapas */
12430
+ 200: {
12431
+ headers: {
12432
+ [name: string]: unknown;
12433
+ };
12434
+ content: {
12435
+ /**
12436
+ * @example {
12437
+ * "status": "success",
12438
+ * "data": {
12439
+ * "serieId": "a1b2c3d4-0000-0000-0000-000000000001",
12440
+ * "serieLabel": "6º ANO",
12441
+ * "challenges": [
12442
+ * {
12443
+ * "id": "a1b2c3d4-0000-0000-0000-000000000002",
12444
+ * "title": "Desafio 1 — Energia Limpa",
12445
+ * "index": 0,
12446
+ * "courseId": "a1b2c3d4-0000-0000-0000-000000000003",
12447
+ * "isUpcoming": false,
12448
+ * "steps": [
12449
+ * {
12450
+ * "id": "a1b2c3d4-0000-0000-0000-000000000010",
12451
+ * "name": "Inicie o desafio",
12452
+ * "index": 0,
12453
+ * "type": "challenge",
12454
+ * "color": "#1AC84A",
12455
+ * "icon": "LuStar",
12456
+ * "status": "done",
12457
+ * "progress": 100,
12458
+ * "courseModuleId": null,
12459
+ * "courseModuleName": null
12460
+ * },
12461
+ * {
12462
+ * "id": "a1b2c3d4-0000-0000-0000-000000000011",
12463
+ * "name": "Módulo de IA",
12464
+ * "index": 1,
12465
+ * "type": "course",
12466
+ * "color": "#8030D8",
12467
+ * "icon": "LuCirclePlay",
12468
+ * "status": "current",
12469
+ * "progress": 67,
12470
+ * "courseModuleId": "a1b2c3d4-0000-0000-0000-000000000020",
12471
+ * "courseModuleName": "Introdução a IA"
12472
+ * }
12473
+ * ]
12474
+ * }
12475
+ * ]
12476
+ * }
12477
+ * }
12478
+ */
12479
+ "application/json": {
12480
+ /** @example success */
12481
+ status?: string;
12482
+ data?: components["schemas"]["JourneyView"];
12483
+ };
12484
+ };
12485
+ };
12486
+ /** @description serieId inválido (não é um UUID) */
12487
+ 400: {
12488
+ headers: {
12489
+ [name: string]: unknown;
12490
+ };
12491
+ content: {
12492
+ "application/json": components["schemas"]["Error"];
12493
+ };
12494
+ };
12495
+ 401: components["responses"]["Unauthorized"];
12496
+ };
12497
+ };
12498
+ put?: never;
12499
+ post?: never;
12500
+ delete?: never;
12501
+ options?: never;
12502
+ head?: never;
12503
+ patch?: never;
12504
+ trace?: never;
12505
+ };
12284
12506
  "/user-challenge-progress/challenges/{id}/advance": {
12285
12507
  parameters: {
12286
12508
  query?: never;
@@ -14445,6 +14667,9 @@ export interface components {
14445
14667
  createdAt: string;
14446
14668
  /** Format: date-time */
14447
14669
  updatedAt: string;
14670
+ organization?: components["schemas"]["Organization"] | null;
14671
+ address?: components["schemas"]["Address"] | null;
14672
+ institutionReward?: Record<string, never> | null;
14448
14673
  };
14449
14674
  Organization: {
14450
14675
  /** Format: uuid */
@@ -15145,6 +15370,99 @@ export interface components {
15145
15370
  /** Format: date-time */
15146
15371
  updatedAt?: string;
15147
15372
  };
15373
+ /** @description Etapa de um desafio com status computado pelo backend */
15374
+ JourneyStepView: {
15375
+ /**
15376
+ * Format: uuid
15377
+ * @description ID do challenge_step
15378
+ */
15379
+ id: string;
15380
+ /** @example Módulo de IA */
15381
+ name: string;
15382
+ /**
15383
+ * @description Ordem da etapa dentro do desafio
15384
+ * @example 1
15385
+ */
15386
+ index: number;
15387
+ /**
15388
+ * @description Tipo da etapa (do catálogo de steps)
15389
+ * @example course
15390
+ * @enum {string}
15391
+ */
15392
+ type: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate";
15393
+ /**
15394
+ * @description Cor hex do step catalog
15395
+ * @example #8030D8
15396
+ */
15397
+ color: string;
15398
+ /**
15399
+ * @description Nome do ícone Lucide do step catalog
15400
+ * @example LuCirclePlay
15401
+ */
15402
+ icon: string;
15403
+ /**
15404
+ * @description Status computado pelo backend: done=concluído, current=etapa ativa, locked=ainda bloqueado
15405
+ * @example current
15406
+ * @enum {string}
15407
+ */
15408
+ status: "done" | "current" | "locked";
15409
+ /**
15410
+ * @description Percentual de progresso (0-100). Para done=100, para locked=0, para current=% do curso ou 0
15411
+ * @example 67
15412
+ */
15413
+ progress: number;
15414
+ /**
15415
+ * Format: uuid
15416
+ * @description ID do módulo do curso referenciado por esta etapa (apenas quando type=course)
15417
+ */
15418
+ courseModuleId?: string | null;
15419
+ /**
15420
+ * @description Título do módulo do curso (apenas quando courseModuleId não é null)
15421
+ * @example Introdução a IA
15422
+ */
15423
+ courseModuleName?: string | null;
15424
+ };
15425
+ /** @description Desafio da jornada com suas etapas e status computados */
15426
+ JourneyChallengeView: {
15427
+ /**
15428
+ * Format: uuid
15429
+ * @description ID do challenge
15430
+ */
15431
+ id: string;
15432
+ /** @example Desafio 1 — Energia Limpa */
15433
+ title: string;
15434
+ /**
15435
+ * @description Ordem do desafio na série
15436
+ * @example 0
15437
+ */
15438
+ index: number;
15439
+ /**
15440
+ * Format: uuid
15441
+ * @description Curso ao qual o desafio está associado
15442
+ */
15443
+ courseId: string;
15444
+ /**
15445
+ * @description True quando o desafio ainda não está disponível para o aluno (challenge seguinte ao ativo com steps pendentes)
15446
+ * @example false
15447
+ */
15448
+ isUpcoming: boolean;
15449
+ steps: components["schemas"]["JourneyStepView"][];
15450
+ };
15451
+ /** @description Resposta completa do endpoint GET /user-challenge-progress/journey — dados pré-computados para renderização direta da tela de jornada */
15452
+ JourneyView: {
15453
+ /** @description Desafios da jornada ordenados por index, com prioridade escola > template aplicada */
15454
+ challenges: components["schemas"]["JourneyChallengeView"][];
15455
+ /**
15456
+ * Format: uuid
15457
+ * @description ID da série resolvida (da turma do aluno, ou do query param serieId)
15458
+ */
15459
+ serieId: string | null;
15460
+ /**
15461
+ * @description Rótulo legível da série para exibição na UI
15462
+ * @example 6º ANO
15463
+ */
15464
+ serieLabel: string | null;
15465
+ };
15148
15466
  /** @description Aggregated progress of a user on a course or module, derived from users_course_log completion events */
15149
15467
  UsersCourseLogProgress: {
15150
15468
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "academe-kit",
3
- "version": "0.9.8",
3
+ "version": "0.9.9",
4
4
  "type": "module",
5
5
  "description": "Official React SDK for Academe ecosystem - Authentication, protected routes, API services, and UI components for educational management applications",
6
6
  "main": "dist/index.cjs",
@@ -99,4 +99,4 @@
99
99
  "tailwind-merge": "^3.3.1",
100
100
  "tailwindcss-animate": "^1.0.7"
101
101
  }
102
- }
102
+ }