academe-kit 0.1.8 → 0.2.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.
package/dist/index.esm.js CHANGED
@@ -1,7 +1,6 @@
1
- import { jsx, Fragment } from 'react/jsx-runtime';
1
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { createContext, useContext, useState, useEffect, useCallback, forwardRef, createElement } from 'react';
4
- import axios from 'axios';
3
+ import React__default, { createContext, useContext, useState, useMemo, useEffect, useCallback, forwardRef, createElement } from 'react';
5
4
 
6
5
  function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
7
6
 
@@ -2231,147 +2230,1020 @@ function isObject(input) {
2231
2230
  return typeof input === 'object' && input !== null;
2232
2231
  }
2233
2232
 
2234
- /**
2235
- * User Service - Fetches complete user data from MongoDB
2236
- * This service interacts with the new unified users collection
2237
- */
2238
- class UserService {
2239
- constructor(config) {
2240
- this.cachedUser = null;
2241
- this.cacheExpiry = 0;
2242
- this.getAccessToken = config.getAccessToken;
2243
- this.client = axios.create({
2244
- baseURL: config.apiBaseUrl,
2245
- headers: {
2246
- 'Content-Type': 'application/json'
2247
- }
2248
- });
2249
- // Add auth interceptor
2250
- this.client.interceptors.request.use((config) => {
2251
- const token = this.getAccessToken();
2252
- if (token) {
2253
- config.headers.Authorization = `Bearer ${token}`;
2254
- }
2255
- return config;
2256
- });
2257
- // Add response interceptor for error handling
2258
- this.client.interceptors.response.use((response) => response, (error) => {
2259
- if (error.response?.status === 401) {
2260
- // Clear cache on authentication error
2261
- this.clearCache();
2262
- }
2263
- return Promise.reject(error);
2264
- });
2233
+ const PATH_PARAM_RE = /\{[^{}]+\}/g;
2234
+ const supportsRequestInitExt = () => {
2235
+ return typeof process === "object" && Number.parseInt(process?.versions?.node?.substring(0, 2)) >= 18 && process.versions.undici;
2236
+ };
2237
+ function randomID() {
2238
+ return Math.random().toString(36).slice(2, 11);
2239
+ }
2240
+ function createClient(clientOptions) {
2241
+ let {
2242
+ baseUrl = "",
2243
+ Request: CustomRequest = globalThis.Request,
2244
+ fetch: baseFetch = globalThis.fetch,
2245
+ querySerializer: globalQuerySerializer,
2246
+ bodySerializer: globalBodySerializer,
2247
+ headers: baseHeaders,
2248
+ requestInitExt = void 0,
2249
+ ...baseOptions
2250
+ } = { ...clientOptions };
2251
+ requestInitExt = supportsRequestInitExt() ? requestInitExt : void 0;
2252
+ baseUrl = removeTrailingSlash(baseUrl);
2253
+ const globalMiddlewares = [];
2254
+ async function coreFetch(schemaPath, fetchOptions) {
2255
+ const {
2256
+ baseUrl: localBaseUrl,
2257
+ fetch = baseFetch,
2258
+ Request = CustomRequest,
2259
+ headers,
2260
+ params = {},
2261
+ parseAs = "json",
2262
+ querySerializer: requestQuerySerializer,
2263
+ bodySerializer = globalBodySerializer ?? defaultBodySerializer,
2264
+ body,
2265
+ middleware: requestMiddlewares = [],
2266
+ ...init
2267
+ } = fetchOptions || {};
2268
+ let finalBaseUrl = baseUrl;
2269
+ if (localBaseUrl) {
2270
+ finalBaseUrl = removeTrailingSlash(localBaseUrl) ?? baseUrl;
2265
2271
  }
2266
- /**
2267
- * Get current user data from MongoDB
2268
- * Includes caching to reduce API calls
2269
- */
2270
- async getCurrentUser(forceRefresh = false) {
2271
- try {
2272
- // Check cache
2273
- if (!forceRefresh && this.cachedUser && Date.now() < this.cacheExpiry) {
2274
- return this.cachedUser;
2272
+ let querySerializer = typeof globalQuerySerializer === "function" ? globalQuerySerializer : createQuerySerializer(globalQuerySerializer);
2273
+ if (requestQuerySerializer) {
2274
+ querySerializer = typeof requestQuerySerializer === "function" ? requestQuerySerializer : createQuerySerializer({
2275
+ ...typeof globalQuerySerializer === "object" ? globalQuerySerializer : {},
2276
+ ...requestQuerySerializer
2277
+ });
2278
+ }
2279
+ const serializedBody = body === void 0 ? void 0 : bodySerializer(
2280
+ body,
2281
+ // Note: we declare mergeHeaders() both here and below because it’s a bit of a chicken-or-egg situation:
2282
+ // bodySerializer() needs all headers so we aren’t dropping ones set by the user, however,
2283
+ // the result of this ALSO sets the lowest-priority content-type header. So we re-merge below,
2284
+ // setting the content-type at the very beginning to be overwritten.
2285
+ // Lastly, based on the way headers work, it’s not a simple “present-or-not” check becauase null intentionally un-sets headers.
2286
+ mergeHeaders(baseHeaders, headers, params.header)
2287
+ );
2288
+ const finalHeaders = mergeHeaders(
2289
+ // with no body, we should not to set Content-Type
2290
+ serializedBody === void 0 || // if serialized body is FormData; browser will correctly set Content-Type & boundary expression
2291
+ serializedBody instanceof FormData ? {} : {
2292
+ "Content-Type": "application/json"
2293
+ },
2294
+ baseHeaders,
2295
+ headers,
2296
+ params.header
2297
+ );
2298
+ const finalMiddlewares = [...globalMiddlewares, ...requestMiddlewares];
2299
+ const requestInit = {
2300
+ redirect: "follow",
2301
+ ...baseOptions,
2302
+ ...init,
2303
+ body: serializedBody,
2304
+ headers: finalHeaders
2305
+ };
2306
+ let id;
2307
+ let options;
2308
+ let request = new Request(
2309
+ createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer }),
2310
+ requestInit
2311
+ );
2312
+ let response;
2313
+ for (const key in init) {
2314
+ if (!(key in request)) {
2315
+ request[key] = init[key];
2316
+ }
2317
+ }
2318
+ if (finalMiddlewares.length) {
2319
+ id = randomID();
2320
+ options = Object.freeze({
2321
+ baseUrl: finalBaseUrl,
2322
+ fetch,
2323
+ parseAs,
2324
+ querySerializer,
2325
+ bodySerializer
2326
+ });
2327
+ for (const m of finalMiddlewares) {
2328
+ if (m && typeof m === "object" && typeof m.onRequest === "function") {
2329
+ const result = await m.onRequest({
2330
+ request,
2331
+ schemaPath,
2332
+ params,
2333
+ options,
2334
+ id
2335
+ });
2336
+ if (result) {
2337
+ if (result instanceof Request) {
2338
+ request = result;
2339
+ } else if (result instanceof Response) {
2340
+ response = result;
2341
+ break;
2342
+ } else {
2343
+ throw new Error("onRequest: must return new Request() or Response() when modifying the request");
2275
2344
  }
2276
- const response = await this.client.get('/api/users/me');
2277
- if (response.data) {
2278
- // Cache for 5 minutes
2279
- this.cachedUser = response.data;
2280
- this.cacheExpiry = Date.now() + (5 * 60 * 1000);
2281
- return response.data;
2345
+ }
2346
+ }
2347
+ }
2348
+ }
2349
+ if (!response) {
2350
+ try {
2351
+ response = await fetch(request, requestInitExt);
2352
+ } catch (error2) {
2353
+ let errorAfterMiddleware = error2;
2354
+ if (finalMiddlewares.length) {
2355
+ for (let i = finalMiddlewares.length - 1; i >= 0; i--) {
2356
+ const m = finalMiddlewares[i];
2357
+ if (m && typeof m === "object" && typeof m.onError === "function") {
2358
+ const result = await m.onError({
2359
+ request,
2360
+ error: errorAfterMiddleware,
2361
+ schemaPath,
2362
+ params,
2363
+ options,
2364
+ id
2365
+ });
2366
+ if (result) {
2367
+ if (result instanceof Response) {
2368
+ errorAfterMiddleware = void 0;
2369
+ response = result;
2370
+ break;
2371
+ }
2372
+ if (result instanceof Error) {
2373
+ errorAfterMiddleware = result;
2374
+ continue;
2375
+ }
2376
+ throw new Error("onError: must return new Response() or instance of Error");
2377
+ }
2282
2378
  }
2283
- return null;
2379
+ }
2284
2380
  }
2285
- catch (error) {
2286
- console.error('Error fetching current user:', error);
2287
- // If it's a 404, user doesn't exist in MongoDB yet
2288
- if (axios.isAxiosError(error) && error.response?.status === 404) {
2289
- // User will be auto-created on next API call
2290
- return null;
2381
+ if (errorAfterMiddleware) {
2382
+ throw errorAfterMiddleware;
2383
+ }
2384
+ }
2385
+ if (finalMiddlewares.length) {
2386
+ for (let i = finalMiddlewares.length - 1; i >= 0; i--) {
2387
+ const m = finalMiddlewares[i];
2388
+ if (m && typeof m === "object" && typeof m.onResponse === "function") {
2389
+ const result = await m.onResponse({
2390
+ request,
2391
+ response,
2392
+ schemaPath,
2393
+ params,
2394
+ options,
2395
+ id
2396
+ });
2397
+ if (result) {
2398
+ if (!(result instanceof Response)) {
2399
+ throw new Error("onResponse: must return new Response() when modifying the response");
2400
+ }
2401
+ response = result;
2291
2402
  }
2292
- throw error;
2403
+ }
2293
2404
  }
2405
+ }
2294
2406
  }
2295
- /**
2296
- * Update current user data
2297
- */
2298
- async updateCurrentUser(data) {
2299
- try {
2300
- // First get current user to get the ID
2301
- const currentUser = await this.getCurrentUser();
2302
- if (!currentUser) {
2303
- throw new Error('User not found');
2304
- }
2305
- const response = await this.client.put(`/api/users/${currentUser.id}`, data);
2306
- if (response.data) {
2307
- // Update cache
2308
- this.cachedUser = response.data;
2309
- this.cacheExpiry = Date.now() + (5 * 60 * 1000);
2310
- return response.data;
2311
- }
2312
- return null;
2407
+ if (response.status === 204 || request.method === "HEAD" || response.headers.get("Content-Length") === "0") {
2408
+ return response.ok ? { data: void 0, response } : { error: void 0, response };
2409
+ }
2410
+ if (response.ok) {
2411
+ if (parseAs === "stream") {
2412
+ return { data: response.body, response };
2413
+ }
2414
+ return { data: await response[parseAs](), response };
2415
+ }
2416
+ let error = await response.text();
2417
+ try {
2418
+ error = JSON.parse(error);
2419
+ } catch {
2420
+ }
2421
+ return { error, response };
2422
+ }
2423
+ return {
2424
+ request(method, url, init) {
2425
+ return coreFetch(url, { ...init, method: method.toUpperCase() });
2426
+ },
2427
+ /** Call a GET endpoint */
2428
+ GET(url, init) {
2429
+ return coreFetch(url, { ...init, method: "GET" });
2430
+ },
2431
+ /** Call a PUT endpoint */
2432
+ PUT(url, init) {
2433
+ return coreFetch(url, { ...init, method: "PUT" });
2434
+ },
2435
+ /** Call a POST endpoint */
2436
+ POST(url, init) {
2437
+ return coreFetch(url, { ...init, method: "POST" });
2438
+ },
2439
+ /** Call a DELETE endpoint */
2440
+ DELETE(url, init) {
2441
+ return coreFetch(url, { ...init, method: "DELETE" });
2442
+ },
2443
+ /** Call a OPTIONS endpoint */
2444
+ OPTIONS(url, init) {
2445
+ return coreFetch(url, { ...init, method: "OPTIONS" });
2446
+ },
2447
+ /** Call a HEAD endpoint */
2448
+ HEAD(url, init) {
2449
+ return coreFetch(url, { ...init, method: "HEAD" });
2450
+ },
2451
+ /** Call a PATCH endpoint */
2452
+ PATCH(url, init) {
2453
+ return coreFetch(url, { ...init, method: "PATCH" });
2454
+ },
2455
+ /** Call a TRACE endpoint */
2456
+ TRACE(url, init) {
2457
+ return coreFetch(url, { ...init, method: "TRACE" });
2458
+ },
2459
+ /** Register middleware */
2460
+ use(...middleware) {
2461
+ for (const m of middleware) {
2462
+ if (!m) {
2463
+ continue;
2313
2464
  }
2314
- catch (error) {
2315
- console.error('Error updating user:', error);
2316
- throw error;
2465
+ if (typeof m !== "object" || !("onRequest" in m || "onResponse" in m || "onError" in m)) {
2466
+ throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");
2317
2467
  }
2468
+ globalMiddlewares.push(m);
2469
+ }
2470
+ },
2471
+ /** Unregister middleware */
2472
+ eject(...middleware) {
2473
+ for (const m of middleware) {
2474
+ const i = globalMiddlewares.indexOf(m);
2475
+ if (i !== -1) {
2476
+ globalMiddlewares.splice(i, 1);
2477
+ }
2478
+ }
2318
2479
  }
2319
- /**
2320
- * Clear cached user data
2321
- */
2322
- clearCache() {
2323
- this.cachedUser = null;
2324
- this.cacheExpiry = 0;
2480
+ };
2481
+ }
2482
+ function serializePrimitiveParam(name, value, options) {
2483
+ if (value === void 0 || value === null) {
2484
+ return "";
2485
+ }
2486
+ if (typeof value === "object") {
2487
+ throw new Error(
2488
+ "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
2489
+ );
2490
+ }
2491
+ return `${name}=${options?.allowReserved === true ? value : encodeURIComponent(value)}`;
2492
+ }
2493
+ function serializeObjectParam(name, value, options) {
2494
+ if (!value || typeof value !== "object") {
2495
+ return "";
2496
+ }
2497
+ const values = [];
2498
+ const joiner = {
2499
+ simple: ",",
2500
+ label: ".",
2501
+ matrix: ";"
2502
+ }[options.style] || "&";
2503
+ if (options.style !== "deepObject" && options.explode === false) {
2504
+ for (const k in value) {
2505
+ values.push(k, options.allowReserved === true ? value[k] : encodeURIComponent(value[k]));
2325
2506
  }
2326
- /**
2327
- * Check if user has a specific role
2328
- */
2329
- hasRole(user, role) {
2330
- if (!user || !user.roles)
2331
- return false;
2332
- return user.roles.includes(role);
2507
+ const final2 = values.join(",");
2508
+ switch (options.style) {
2509
+ case "form": {
2510
+ return `${name}=${final2}`;
2511
+ }
2512
+ case "label": {
2513
+ return `.${final2}`;
2514
+ }
2515
+ case "matrix": {
2516
+ return `;${name}=${final2}`;
2517
+ }
2518
+ default: {
2519
+ return final2;
2520
+ }
2333
2521
  }
2334
- /**
2335
- * Check if user has access to a specific school
2336
- */
2337
- hasSchoolAccess(user, schoolId) {
2338
- if (!user)
2339
- return false;
2340
- // Admin has access to all schools
2341
- if (this.hasRole(user, 'admin_academe'))
2342
- return true;
2343
- // Check if user's school matches
2344
- return user.school_id === schoolId;
2522
+ }
2523
+ for (const k in value) {
2524
+ const finalName = options.style === "deepObject" ? `${name}[${k}]` : k;
2525
+ values.push(serializePrimitiveParam(finalName, value[k], options));
2526
+ }
2527
+ const final = values.join(joiner);
2528
+ return options.style === "label" || options.style === "matrix" ? `${joiner}${final}` : final;
2529
+ }
2530
+ function serializeArrayParam(name, value, options) {
2531
+ if (!Array.isArray(value)) {
2532
+ return "";
2533
+ }
2534
+ if (options.explode === false) {
2535
+ const joiner2 = { form: ",", spaceDelimited: "%20", pipeDelimited: "|" }[options.style] || ",";
2536
+ const final = (options.allowReserved === true ? value : value.map((v) => encodeURIComponent(v))).join(joiner2);
2537
+ switch (options.style) {
2538
+ case "simple": {
2539
+ return final;
2540
+ }
2541
+ case "label": {
2542
+ return `.${final}`;
2543
+ }
2544
+ case "matrix": {
2545
+ return `;${name}=${final}`;
2546
+ }
2547
+ // case "spaceDelimited":
2548
+ // case "pipeDelimited":
2549
+ default: {
2550
+ return `${name}=${final}`;
2551
+ }
2345
2552
  }
2346
- /**
2347
- * Check if user is a student (has student-specific data)
2348
- */
2349
- isStudent(user) {
2350
- if (!user)
2351
- return false;
2352
- return !!user.registration_number || this.hasRole(user, 'student');
2553
+ }
2554
+ const joiner = { simple: ",", label: ".", matrix: ";" }[options.style] || "&";
2555
+ const values = [];
2556
+ for (const v of value) {
2557
+ if (options.style === "simple" || options.style === "label") {
2558
+ values.push(options.allowReserved === true ? v : encodeURIComponent(v));
2559
+ } else {
2560
+ values.push(serializePrimitiveParam(name, v, options));
2353
2561
  }
2354
- /**
2355
- * Check if user has completed onboarding
2356
- */
2357
- hasCompletedOnboarding(user) {
2358
- if (!user)
2359
- return false;
2360
- return user.onboarding_completo;
2562
+ }
2563
+ return options.style === "label" || options.style === "matrix" ? `${joiner}${values.join(joiner)}` : values.join(joiner);
2564
+ }
2565
+ function createQuerySerializer(options) {
2566
+ return function querySerializer(queryParams) {
2567
+ const search = [];
2568
+ if (queryParams && typeof queryParams === "object") {
2569
+ for (const name in queryParams) {
2570
+ const value = queryParams[name];
2571
+ if (value === void 0 || value === null) {
2572
+ continue;
2573
+ }
2574
+ if (Array.isArray(value)) {
2575
+ if (value.length === 0) {
2576
+ continue;
2577
+ }
2578
+ search.push(
2579
+ serializeArrayParam(name, value, {
2580
+ style: "form",
2581
+ explode: true,
2582
+ ...options?.array,
2583
+ allowReserved: options?.allowReserved || false
2584
+ })
2585
+ );
2586
+ continue;
2587
+ }
2588
+ if (typeof value === "object") {
2589
+ search.push(
2590
+ serializeObjectParam(name, value, {
2591
+ style: "deepObject",
2592
+ explode: true,
2593
+ ...options?.object,
2594
+ allowReserved: options?.allowReserved || false
2595
+ })
2596
+ );
2597
+ continue;
2598
+ }
2599
+ search.push(serializePrimitiveParam(name, value, options));
2600
+ }
2361
2601
  }
2362
- /**
2363
- * Check if user has access enabled
2364
- */
2365
- hasAccessEnabled(user) {
2366
- if (!user)
2367
- return false;
2368
- return user.acesso_liberado && user.active;
2602
+ return search.join("&");
2603
+ };
2604
+ }
2605
+ function defaultPathSerializer(pathname, pathParams) {
2606
+ let nextURL = pathname;
2607
+ for (const match of pathname.match(PATH_PARAM_RE) ?? []) {
2608
+ let name = match.substring(1, match.length - 1);
2609
+ let explode = false;
2610
+ let style = "simple";
2611
+ if (name.endsWith("*")) {
2612
+ explode = true;
2613
+ name = name.substring(0, name.length - 1);
2614
+ }
2615
+ if (name.startsWith(".")) {
2616
+ style = "label";
2617
+ name = name.substring(1);
2618
+ } else if (name.startsWith(";")) {
2619
+ style = "matrix";
2620
+ name = name.substring(1);
2621
+ }
2622
+ if (!pathParams || pathParams[name] === void 0 || pathParams[name] === null) {
2623
+ continue;
2369
2624
  }
2625
+ const value = pathParams[name];
2626
+ if (Array.isArray(value)) {
2627
+ nextURL = nextURL.replace(match, serializeArrayParam(name, value, { style, explode }));
2628
+ continue;
2629
+ }
2630
+ if (typeof value === "object") {
2631
+ nextURL = nextURL.replace(match, serializeObjectParam(name, value, { style, explode }));
2632
+ continue;
2633
+ }
2634
+ if (style === "matrix") {
2635
+ nextURL = nextURL.replace(match, `;${serializePrimitiveParam(name, value)}`);
2636
+ continue;
2637
+ }
2638
+ nextURL = nextURL.replace(match, style === "label" ? `.${encodeURIComponent(value)}` : encodeURIComponent(value));
2639
+ }
2640
+ return nextURL;
2641
+ }
2642
+ function defaultBodySerializer(body, headers) {
2643
+ if (body instanceof FormData) {
2644
+ return body;
2645
+ }
2646
+ if (headers) {
2647
+ const contentType = headers.get instanceof Function ? headers.get("Content-Type") ?? headers.get("content-type") : headers["Content-Type"] ?? headers["content-type"];
2648
+ if (contentType === "application/x-www-form-urlencoded") {
2649
+ return new URLSearchParams(body).toString();
2650
+ }
2651
+ }
2652
+ return JSON.stringify(body);
2653
+ }
2654
+ function createFinalURL(pathname, options) {
2655
+ let finalURL = `${options.baseUrl}${pathname}`;
2656
+ if (options.params?.path) {
2657
+ finalURL = defaultPathSerializer(finalURL, options.params.path);
2658
+ }
2659
+ let search = options.querySerializer(options.params.query ?? {});
2660
+ if (search.startsWith("?")) {
2661
+ search = search.substring(1);
2662
+ }
2663
+ if (search) {
2664
+ finalURL += `?${search}`;
2665
+ }
2666
+ return finalURL;
2667
+ }
2668
+ function mergeHeaders(...allHeaders) {
2669
+ const finalHeaders = new Headers();
2670
+ for (const h of allHeaders) {
2671
+ if (!h || typeof h !== "object") {
2672
+ continue;
2673
+ }
2674
+ const iterator = h instanceof Headers ? h.entries() : Object.entries(h);
2675
+ for (const [k, v] of iterator) {
2676
+ if (v === null) {
2677
+ finalHeaders.delete(k);
2678
+ } else if (Array.isArray(v)) {
2679
+ for (const v2 of v) {
2680
+ finalHeaders.append(k, v2);
2681
+ }
2682
+ } else if (v !== void 0) {
2683
+ finalHeaders.set(k, v);
2684
+ }
2685
+ }
2686
+ }
2687
+ return finalHeaders;
2688
+ }
2689
+ function removeTrailingSlash(url) {
2690
+ if (url.endsWith("/")) {
2691
+ return url.substring(0, url.length - 1);
2692
+ }
2693
+ return url;
2694
+ }
2695
+
2696
+ function createUserService(apiClient) {
2697
+ return {
2698
+ /**
2699
+ * Get current authenticated user
2700
+ */
2701
+ getMe() {
2702
+ return apiClient.GET('/users/me');
2703
+ },
2704
+ /**
2705
+ * List all users with optional filters
2706
+ */
2707
+ getUsers(params) {
2708
+ return apiClient.GET('/users', {
2709
+ params: { query: params },
2710
+ });
2711
+ },
2712
+ /**
2713
+ * Get user by ID
2714
+ */
2715
+ getUserById(id) {
2716
+ return apiClient.GET('/users/{id}', {
2717
+ params: { path: { id } },
2718
+ });
2719
+ },
2720
+ /**
2721
+ * Create a new user
2722
+ */
2723
+ createUser(body) {
2724
+ return apiClient.POST('/users', {
2725
+ body,
2726
+ });
2727
+ },
2728
+ /**
2729
+ * Update user information
2730
+ */
2731
+ updateUser(id, body) {
2732
+ return apiClient.PATCH('/users/{id}', {
2733
+ params: { path: { id } },
2734
+ body,
2735
+ });
2736
+ },
2737
+ /**
2738
+ * Delete user
2739
+ */
2740
+ deleteUser(id) {
2741
+ return apiClient.DELETE('/users/{id}', {
2742
+ params: { path: { id } },
2743
+ });
2744
+ },
2745
+ /**
2746
+ * Get user's groups
2747
+ */
2748
+ getUserGroups(id) {
2749
+ return apiClient.GET('/users/{id}/groups', {
2750
+ params: { path: { id } },
2751
+ });
2752
+ },
2753
+ /**
2754
+ * Get user's certificates
2755
+ */
2756
+ getUserCertificates(id) {
2757
+ return apiClient.GET('/users/{id}/certificates', {
2758
+ params: { path: { id } },
2759
+ });
2760
+ },
2761
+ /**
2762
+ * Get user's institutions
2763
+ */
2764
+ getUserInstitutions(id) {
2765
+ return apiClient.GET('/users/{id}/institutions', {
2766
+ params: { path: { id } },
2767
+ });
2768
+ },
2769
+ /**
2770
+ * Sync user with Keycloak
2771
+ */
2772
+ syncUser(id) {
2773
+ return apiClient.POST('/users/{id}/sync', {
2774
+ params: { path: { id } },
2775
+ });
2776
+ },
2777
+ };
2370
2778
  }
2371
- // Export singleton instance creator
2372
- const createUserService = (config) => {
2373
- return new UserService(config);
2374
- };
2779
+
2780
+ function createInstitutionService(apiClient) {
2781
+ return {
2782
+ getAll() {
2783
+ return apiClient.GET('/institutions');
2784
+ },
2785
+ getById(id) {
2786
+ return apiClient.GET('/institutions/{id}', { params: { path: { id } } });
2787
+ },
2788
+ // Institution Groups
2789
+ getGroups(institutionId) {
2790
+ return apiClient.GET('/institutions/{institutionId}/groups', {
2791
+ params: { path: { institutionId } },
2792
+ });
2793
+ },
2794
+ addGroup(institutionId, data) {
2795
+ return apiClient.POST('/institutions/{institutionId}/groups', {
2796
+ params: { path: { institutionId } },
2797
+ body: data,
2798
+ });
2799
+ },
2800
+ removeGroup(institutionId, groupId) {
2801
+ return apiClient.DELETE('/institutions/{institutionId}/groups/{groupId}', {
2802
+ params: { path: { institutionId, groupId } },
2803
+ });
2804
+ },
2805
+ updateGroup(institutionId, groupId, data) {
2806
+ return apiClient.PATCH('/institutions/{institutionId}/groups/{groupId}', {
2807
+ params: { path: { institutionId, groupId } },
2808
+ body: data,
2809
+ });
2810
+ },
2811
+ // Institution Classrooms
2812
+ getClassrooms(institutionId, options) {
2813
+ return apiClient.GET('/institutions/{institutionId}/classrooms', {
2814
+ params: {
2815
+ path: { institutionId },
2816
+ query: options,
2817
+ },
2818
+ });
2819
+ },
2820
+ getClassroomById(institutionId, classroomId) {
2821
+ return apiClient.GET('/institutions/{institutionId}/classrooms/{classroomId}', {
2822
+ params: { path: { institutionId, classroomId } },
2823
+ });
2824
+ },
2825
+ addClassroom(institutionId, data) {
2826
+ return apiClient.POST('/institutions/{institutionId}/classrooms', {
2827
+ params: { path: { institutionId } },
2828
+ body: data,
2829
+ });
2830
+ },
2831
+ updateClassroom(institutionId, classroomId, data) {
2832
+ return apiClient.PATCH('/institutions/{institutionId}/classrooms/{classroomId}', {
2833
+ params: { path: { institutionId, classroomId } },
2834
+ body: data,
2835
+ });
2836
+ },
2837
+ removeClassroom(institutionId, classroomId) {
2838
+ return apiClient.DELETE('/institutions/{institutionId}/classrooms/{classroomId}', {
2839
+ params: { path: { institutionId, classroomId } },
2840
+ });
2841
+ },
2842
+ // Institution Registrations (Users in Institution)
2843
+ getRegistrations(institutionId) {
2844
+ return apiClient.GET('/institutions/{institutionId}/registrations', {
2845
+ params: { path: { institutionId } },
2846
+ });
2847
+ },
2848
+ getRegistrationById(institutionId, registrationId) {
2849
+ return apiClient.GET('/institutions/{institutionId}/registrations/{registrationId}', {
2850
+ params: { path: { institutionId, registrationId } },
2851
+ });
2852
+ },
2853
+ getRegistrationByUserId(institutionId, userId) {
2854
+ return apiClient.GET('/institutions/{institutionId}/registrations/user/{userId}', {
2855
+ params: { path: { institutionId, userId } },
2856
+ });
2857
+ },
2858
+ registerUser(institutionId, data) {
2859
+ return apiClient.POST('/institutions/{institutionId}/registrations', {
2860
+ params: { path: { institutionId } },
2861
+ body: data,
2862
+ });
2863
+ },
2864
+ updateRegistration(institutionId, registrationId, data) {
2865
+ return apiClient.PATCH('/institutions/{institutionId}/registrations/{registrationId}', {
2866
+ params: { path: { institutionId, registrationId } },
2867
+ body: data,
2868
+ });
2869
+ },
2870
+ assignUserToClassroom(institutionId, registrationId, data) {
2871
+ return apiClient.PATCH('/institutions/{institutionId}/registrations/{registrationId}/classroom', {
2872
+ params: { path: { institutionId, registrationId } },
2873
+ body: data,
2874
+ });
2875
+ },
2876
+ removeRegistration(institutionId, registrationId) {
2877
+ return apiClient.DELETE('/institutions/{institutionId}/registrations/{registrationId}', {
2878
+ params: { path: { institutionId, registrationId } },
2879
+ });
2880
+ },
2881
+ };
2882
+ }
2883
+
2884
+ function createReportService(apiClient) {
2885
+ return {
2886
+ /**
2887
+ * Get dashboard data (global)
2888
+ * Returns aggregated dashboard data for all institutions (requires admin permission)
2889
+ */
2890
+ getDashboard(params) {
2891
+ return apiClient.GET('/reports/dashboard', {
2892
+ params: { query: params },
2893
+ });
2894
+ },
2895
+ /**
2896
+ * Get dashboard data for specific institution
2897
+ * Returns aggregated dashboard data for a specific institution
2898
+ */
2899
+ getDashboardByInstitution(id) {
2900
+ return apiClient.GET('/reports/dashboard/{id}', {
2901
+ params: { path: { id } },
2902
+ });
2903
+ },
2904
+ /**
2905
+ * Get courses distribution by area (global)
2906
+ * Returns distribution of course completions by area/category
2907
+ */
2908
+ getCoursesByArea() {
2909
+ return apiClient.GET('/reports/courses-by-area');
2910
+ },
2911
+ /**
2912
+ * Get courses distribution by area for specific institution
2913
+ * Returns distribution of course completions by area/category for an institution
2914
+ */
2915
+ getCoursesByAreaByInstitution(id) {
2916
+ return apiClient.GET('/reports/courses-by-area/{id}', {
2917
+ params: { path: { id } },
2918
+ });
2919
+ },
2920
+ /**
2921
+ * Get adhesion rate (global)
2922
+ * Returns adhesion rate (unique students who accessed) per month for the last 6 months
2923
+ */
2924
+ getAdhesionRate() {
2925
+ return apiClient.GET('/reports/adhesion-rate');
2926
+ },
2927
+ /**
2928
+ * Get adhesion rate for specific institution
2929
+ * Returns adhesion rate for an institution for the last 6 months
2930
+ */
2931
+ getAdhesionRateByInstitution(id) {
2932
+ return apiClient.GET('/reports/adhesion-rate/{id}', {
2933
+ params: { path: { id } },
2934
+ });
2935
+ },
2936
+ /**
2937
+ * Get recent activities (global)
2938
+ * Returns recent student activities (certificates issued and courses started)
2939
+ */
2940
+ getRecentActivities(params) {
2941
+ return apiClient.GET('/reports/recent-activities', {
2942
+ params: { query: params },
2943
+ });
2944
+ },
2945
+ /**
2946
+ * Get recent activities for specific institution
2947
+ * Returns recent student activities for an institution
2948
+ */
2949
+ getRecentActivitiesByInstitution(id, params) {
2950
+ return apiClient.GET('/reports/recent-activities/{id}', {
2951
+ params: {
2952
+ path: { id },
2953
+ query: params,
2954
+ },
2955
+ });
2956
+ },
2957
+ /**
2958
+ * Get top students (global)
2959
+ * Returns top 10 students based on selected filter
2960
+ */
2961
+ getTopStudents(params) {
2962
+ return apiClient.GET('/reports/top-students', {
2963
+ params: { query: params },
2964
+ });
2965
+ },
2966
+ /**
2967
+ * Get top students for specific institution
2968
+ * Returns top 10 students for an institution based on selected filter
2969
+ */
2970
+ getTopStudentsByInstitution(id, params) {
2971
+ return apiClient.GET('/reports/top-students/{id}', {
2972
+ params: {
2973
+ path: { id },
2974
+ query: params,
2975
+ },
2976
+ });
2977
+ },
2978
+ };
2979
+ }
2980
+
2981
+ function createClassroomService(apiClient) {
2982
+ return {
2983
+ /**
2984
+ * List all classrooms
2985
+ */
2986
+ getAll() {
2987
+ return apiClient.GET('/classrooms');
2988
+ },
2989
+ /**
2990
+ * Get classroom by ID
2991
+ */
2992
+ getById(id) {
2993
+ return apiClient.GET('/classrooms/{id}', {
2994
+ params: { path: { id } },
2995
+ });
2996
+ },
2997
+ /**
2998
+ * Get classrooms by institution ID
2999
+ */
3000
+ getByInstitution(institutionId, params) {
3001
+ return apiClient.GET('/classrooms/institution/{id}', {
3002
+ params: {
3003
+ path: { id: institutionId },
3004
+ query: params,
3005
+ },
3006
+ });
3007
+ },
3008
+ /**
3009
+ * Create a new classroom
3010
+ */
3011
+ create(data) {
3012
+ return apiClient.POST('/classrooms', {
3013
+ body: data,
3014
+ });
3015
+ },
3016
+ /**
3017
+ * Update classroom
3018
+ */
3019
+ update(id, data) {
3020
+ return apiClient.PATCH('/classrooms/{id}', {
3021
+ params: { path: { id } },
3022
+ body: data,
3023
+ });
3024
+ },
3025
+ /**
3026
+ * Delete classroom
3027
+ */
3028
+ delete(id) {
3029
+ return apiClient.DELETE('/classrooms/{id}', {
3030
+ params: { path: { id } },
3031
+ });
3032
+ },
3033
+ };
3034
+ }
3035
+
3036
+ function createOrganizationService(apiClient) {
3037
+ return {
3038
+ /**
3039
+ * List all organizations with optional filters
3040
+ */
3041
+ getAll(params) {
3042
+ return apiClient.GET('/organizations', {
3043
+ params: { query: params },
3044
+ });
3045
+ },
3046
+ /**
3047
+ * Get organization by ID
3048
+ */
3049
+ getById(id) {
3050
+ return apiClient.GET('/organizations/{id}', {
3051
+ params: { path: { id } },
3052
+ });
3053
+ },
3054
+ /**
3055
+ * Create a new organization
3056
+ */
3057
+ create(body) {
3058
+ return apiClient.POST('/organizations', {
3059
+ body,
3060
+ });
3061
+ },
3062
+ /**
3063
+ * Update organization information
3064
+ */
3065
+ update(id, body) {
3066
+ return apiClient.PATCH('/organizations/{id}', {
3067
+ params: { path: { id } },
3068
+ body,
3069
+ });
3070
+ },
3071
+ /**
3072
+ * Delete organization
3073
+ * Note: Cannot delete organizations with children
3074
+ */
3075
+ delete(id) {
3076
+ return apiClient.DELETE('/organizations/{id}', {
3077
+ params: { path: { id } },
3078
+ });
3079
+ },
3080
+ };
3081
+ }
3082
+
3083
+ function createSerieService(apiClient) {
3084
+ return {
3085
+ /**
3086
+ * List all series
3087
+ */
3088
+ getAll() {
3089
+ return apiClient.GET('/series');
3090
+ },
3091
+ /**
3092
+ * Get serie by ID
3093
+ */
3094
+ getById(id) {
3095
+ return apiClient.GET('/series/{id}', {
3096
+ params: { path: { id } },
3097
+ });
3098
+ },
3099
+ /**
3100
+ * Create a new serie
3101
+ */
3102
+ create(data) {
3103
+ return apiClient.POST('/series', {
3104
+ body: data,
3105
+ });
3106
+ },
3107
+ /**
3108
+ * Update serie
3109
+ */
3110
+ update(id, data) {
3111
+ return apiClient.PATCH('/series/{id}', {
3112
+ params: { path: { id } },
3113
+ body: data,
3114
+ });
3115
+ },
3116
+ /**
3117
+ * Delete serie
3118
+ */
3119
+ delete(id) {
3120
+ return apiClient.DELETE('/series/{id}', {
3121
+ params: { path: { id } },
3122
+ });
3123
+ },
3124
+ };
3125
+ }
3126
+
3127
+ function createShiftService(apiClient) {
3128
+ return {
3129
+ /**
3130
+ * List all shifts
3131
+ */
3132
+ getAll() {
3133
+ return apiClient.GET('/shifts');
3134
+ },
3135
+ /**
3136
+ * Get shift by ID
3137
+ */
3138
+ getById(id) {
3139
+ return apiClient.GET('/shifts/{id}', {
3140
+ params: { path: { id } },
3141
+ });
3142
+ },
3143
+ /**
3144
+ * Create a new shift
3145
+ */
3146
+ create(data) {
3147
+ return apiClient.POST('/shifts', {
3148
+ body: data,
3149
+ });
3150
+ },
3151
+ /**
3152
+ * Update shift
3153
+ */
3154
+ update(id, data) {
3155
+ return apiClient.PATCH('/shifts/{id}', {
3156
+ params: { path: { id } },
3157
+ body: data,
3158
+ });
3159
+ },
3160
+ /**
3161
+ * Delete shift
3162
+ */
3163
+ delete(id) {
3164
+ return apiClient.DELETE('/shifts/{id}', {
3165
+ params: { path: { id } },
3166
+ });
3167
+ },
3168
+ };
3169
+ }
3170
+
3171
+ function createGuardianService(apiClient) {
3172
+ return {
3173
+ // List all guardians
3174
+ getAll() {
3175
+ return apiClient.GET('/guardians');
3176
+ },
3177
+ // Get guardian by ID
3178
+ getById(id) {
3179
+ return apiClient.GET('/guardians/{id}', {
3180
+ params: { path: { id } },
3181
+ });
3182
+ },
3183
+ // Create a new guardian
3184
+ create(data) {
3185
+ return apiClient.POST('/guardians', {
3186
+ body: data,
3187
+ });
3188
+ },
3189
+ // Update guardian
3190
+ update(id, data) {
3191
+ return apiClient.PATCH('/guardians/{id}', {
3192
+ params: { path: { id } },
3193
+ body: data,
3194
+ });
3195
+ },
3196
+ // Delete guardian
3197
+ delete(id) {
3198
+ return apiClient.DELETE('/guardians/{id}', {
3199
+ params: { path: { id } },
3200
+ });
3201
+ },
3202
+ // Get guardian's users (students)
3203
+ getUsers(id) {
3204
+ return apiClient.GET('/guardians/{id}/users', {
3205
+ params: { path: { id } },
3206
+ });
3207
+ },
3208
+ // Assign guardian to user
3209
+ assignToUser(data) {
3210
+ return apiClient.POST('/guardians/assign', {
3211
+ body: data,
3212
+ });
3213
+ },
3214
+ // Remove guardian from user
3215
+ removeFromUser(guardianId, userId) {
3216
+ return apiClient.DELETE('/guardians/{guardianId}/users/{userId}', {
3217
+ params: { path: { guardianId, userId } },
3218
+ });
3219
+ },
3220
+ };
3221
+ }
3222
+
3223
+ function createAcademeApiClient(baseUrl) {
3224
+ return createClient({ baseUrl });
3225
+ }
3226
+ function createAcademeServices(apiClient) {
3227
+ return {
3228
+ user: createUserService(apiClient),
3229
+ institution: createInstitutionService(apiClient),
3230
+ report: createReportService(apiClient),
3231
+ classroom: createClassroomService(apiClient),
3232
+ organization: createOrganizationService(apiClient),
3233
+ serie: createSerieService(apiClient),
3234
+ shift: createShiftService(apiClient),
3235
+ guardian: createGuardianService(apiClient),
3236
+ };
3237
+ }
3238
+
3239
+ var GLOBAL_ROLES;
3240
+ (function (GLOBAL_ROLES) {
3241
+ GLOBAL_ROLES["ADMIN_ACADEME"] = "admin_academe";
3242
+ GLOBAL_ROLES["SCHOOL_ADMIN"] = "school_admin";
3243
+ GLOBAL_ROLES["TEACHER"] = "teacher";
3244
+ GLOBAL_ROLES["STUDENT"] = "student";
3245
+ GLOBAL_ROLES["GUARDIAN"] = "guardian";
3246
+ })(GLOBAL_ROLES || (GLOBAL_ROLES = {}));
2375
3247
 
2376
3248
  const AcademeAuthProvider = ({ realm, hubUrl, children, clientId, keycloakUrl, apiBaseUrl, }) => {
2377
3249
  return (jsx(ReactKeycloakProvider, { authClient: new Keycloak({ clientId, realm, url: keycloakUrl }), children: jsx(SecurityProvider, { hubUrl: hubUrl, apiBaseUrl: apiBaseUrl, children: children }) }));
@@ -2386,30 +3258,53 @@ const SecurityContext = createContext({
2386
3258
  hasRealmRole: () => false,
2387
3259
  hasClientRole: () => false,
2388
3260
  isAuthenticated: () => false,
3261
+ apiClient: null,
3262
+ services: null,
2389
3263
  });
2390
- const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children, }) => {
3264
+ const SecurityProvider = ({ apiBaseUrl = "https://stg-api.academe.com.br", children, }) => {
2391
3265
  const [isInitialized, setIsInitialized] = useState(false);
2392
3266
  const [currentUser, setCurrentUser] = useState(null);
2393
3267
  const { initialized, keycloak } = useKeycloak();
2394
- const userService = createUserService({
2395
- apiBaseUrl,
2396
- getAccessToken: () => keycloak?.token || null,
2397
- });
3268
+ // Create API client with the provided baseUrl
3269
+ const apiClient = useMemo(() => {
3270
+ return createAcademeApiClient(apiBaseUrl);
3271
+ }, [apiBaseUrl]);
3272
+ const services = useMemo(() => {
3273
+ return createAcademeServices(apiClient);
3274
+ }, [apiClient]);
3275
+ useEffect(() => {
3276
+ if (keycloak?.token) {
3277
+ apiClient.use({
3278
+ onRequest({ request }) {
3279
+ request.headers.set("Authorization", `Bearer ${keycloak.token}`);
3280
+ return request;
3281
+ },
3282
+ });
3283
+ }
3284
+ }, [keycloak?.token, apiClient]);
2398
3285
  useEffect(() => {
2399
3286
  setIsInitialized(initialized);
2400
3287
  }, [initialized]);
2401
3288
  useEffect(() => {
2402
3289
  window.accessToken = keycloak.token;
2403
3290
  }, [keycloak.token]);
2404
- // Fetch user data from MongoDB when authenticated
3291
+ const getKeycloakUser = useCallback(() => {
3292
+ const idTokenParsed = keycloak?.idTokenParsed || {};
3293
+ return {
3294
+ email: idTokenParsed?.email || "",
3295
+ name: idTokenParsed?.given_name || "",
3296
+ lastName: idTokenParsed?.family_name || "",
3297
+ };
3298
+ }, [keycloak?.idTokenParsed]);
3299
+ // Fetch user data from API when authenticated
2405
3300
  useEffect(() => {
2406
3301
  const fetchUserData = async () => {
2407
3302
  if (initialized && keycloak?.authenticated && keycloak?.token) {
2408
3303
  try {
2409
- const mongoUser = await userService.getCurrentUser();
2410
- if (mongoUser) {
3304
+ const response = await services.user.getMe();
3305
+ if (response?.data?.data) {
2411
3306
  const academeUser = {
2412
- ...mongoUser,
3307
+ ...response.data.data,
2413
3308
  keycloakUser: getKeycloakUser(),
2414
3309
  };
2415
3310
  setCurrentUser(academeUser);
@@ -2420,28 +3315,24 @@ const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children,
2420
3315
  }
2421
3316
  }
2422
3317
  else if (!keycloak?.authenticated) {
2423
- // Clear user data when not authenticated
2424
3318
  setCurrentUser(null);
2425
- userService.clearCache();
2426
3319
  }
2427
3320
  };
2428
3321
  fetchUserData();
2429
- }, [initialized, keycloak?.authenticated, keycloak?.token]);
2430
- const getKeycloakUser = () => {
2431
- const idTokenParsed = keycloak?.idTokenParsed || {};
2432
- return {
2433
- email: idTokenParsed?.email || "",
2434
- name: idTokenParsed?.given_name || "",
2435
- lastName: idTokenParsed?.family_name || "",
2436
- };
2437
- };
3322
+ }, [
3323
+ initialized,
3324
+ keycloak?.authenticated,
3325
+ keycloak?.token,
3326
+ getKeycloakUser,
3327
+ services,
3328
+ ]);
2438
3329
  const refreshUserData = useCallback(async () => {
2439
3330
  if (keycloak?.authenticated) {
2440
3331
  try {
2441
- const mongoUser = await userService.getCurrentUser(true); // Force refresh
2442
- if (mongoUser) {
3332
+ const response = await services.user.getMe();
3333
+ if (response?.data?.data) {
2443
3334
  const academeUser = {
2444
- ...mongoUser,
3335
+ ...response.data.data,
2445
3336
  keycloakUser: getKeycloakUser(),
2446
3337
  };
2447
3338
  setCurrentUser(academeUser);
@@ -2451,9 +3342,8 @@ const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children,
2451
3342
  console.error("Error refreshing user data:", error);
2452
3343
  }
2453
3344
  }
2454
- }, [keycloak?.authenticated]);
3345
+ }, [keycloak?.authenticated, getKeycloakUser, services]);
2455
3346
  const signOut = () => {
2456
- userService.clearCache();
2457
3347
  setCurrentUser(null);
2458
3348
  keycloak?.logout();
2459
3349
  };
@@ -2461,12 +3351,13 @@ const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children,
2461
3351
  return (!!keycloak?.idTokenParsed?.email?.length && !!keycloak?.authenticated);
2462
3352
  };
2463
3353
  const hasSchool = (schoolId) => {
2464
- if (currentUser?.school_id) {
2465
- return (currentUser.school_id === schoolId ||
2466
- userService.hasRole(currentUser, "admin_academe"));
3354
+ if (keycloak?.hasRealmRole(GLOBAL_ROLES.ADMIN_ACADEME)) {
3355
+ return true;
3356
+ }
3357
+ if (currentUser?.institutionRegistrations?.some((registration) => registration.institutionId === schoolId)) {
3358
+ return true;
2467
3359
  }
2468
- // Fallback to Keycloak data
2469
- return false; // No school_id in Keycloak data
3360
+ return false;
2470
3361
  };
2471
3362
  return (jsx(SecurityContext.Provider, { value: {
2472
3363
  isInitialized,
@@ -2478,6 +3369,8 @@ const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children,
2478
3369
  goToLogin: keycloak.login,
2479
3370
  hasRealmRole: keycloak?.hasRealmRole,
2480
3371
  hasClientRole: keycloak.hasResourceRole,
3372
+ apiClient,
3373
+ services,
2481
3374
  }, children: children }));
2482
3375
  };
2483
3376
  const useAcademeAuth = () => useContext(SecurityContext);
@@ -5565,8 +6458,8 @@ function Spinner({ className, ...props }) {
5565
6458
  return (jsx(LoaderCircle, { role: "status", "aria-label": "Loading", className: cn("size-10 animate-spin text-violet-500", className), ...props }));
5566
6459
  }
5567
6460
 
5568
- const ProtectedApp = ({ children, requiredClientRoles, }) => {
5569
- const { isInitialized, goToLogin, hasClientRole, isAuthenticated } = useAcademeAuth();
6461
+ const ProtectedApp = ({ children, requiredClientRoles, requiredRealmRoles, }) => {
6462
+ const { isInitialized, goToLogin, hasClientRole, hasRealmRole, isAuthenticated, } = useAcademeAuth();
5570
6463
  if (!isInitialized) {
5571
6464
  return (jsx("div", { className: "flex w-screen h-screen items-center justify-center", children: jsx(Spinner, { className: "size-10 text-violet-500" }) }));
5572
6465
  }
@@ -5578,6 +6471,10 @@ const ProtectedApp = ({ children, requiredClientRoles, }) => {
5578
6471
  !requiredClientRoles?.some((role) => hasClientRole(role))) {
5579
6472
  return jsx(Fragment, {});
5580
6473
  }
6474
+ if (requiredRealmRoles &&
6475
+ !requiredRealmRoles?.some((role) => hasRealmRole(role))) {
6476
+ return (jsxs("div", { className: "flex w-screen h-screen items-center justify-center", children: [jsx("h1", { className: "text-2xl font-bold", children: "Voc\u00EA n\u00E3o tem permiss\u00E3o para acessar esta p\u00E1gina" }), jsx("span", { children: "Se voc\u00EA acredita que isso \u00E9 um erro, entre em contato com o suporte." })] }));
6477
+ }
5581
6478
  return children;
5582
6479
  };
5583
6480
 
@@ -5630,11 +6527,32 @@ function styleInject(css, ref) {
5630
6527
  }
5631
6528
  }
5632
6529
 
5633
- var css_248z$1 = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--primary:222.2 47.4% 11.2%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:222.2 84% 4.9%;--radius:0.5rem}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.flex{display:flex}.size-10{height:2.5rem;width:2.5rem}.h-screen{height:100vh}.w-screen{width:100vw}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.items-center{align-items:center}.justify-center{justify-content:center}.rounded-lg{border-radius:var(--radius)}.border-2{border-width:2px}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-violet-500{--tw-text-opacity:1;color:rgb(139 92 246/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.outline{outline-style:solid}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.hover\\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\\:ring-gray-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(107 114 128/var(--tw-ring-opacity,1))}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px}";
6530
+ var css_248z$1 = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--primary:222.2 47.4% 11.2%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:222.2 84% 4.9%;--radius:0.5rem}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.flex{display:flex}.size-10{height:2.5rem;width:2.5rem}.h-screen{height:100vh}.w-screen{width:100vw}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.items-center{align-items:center}.justify-center{justify-content:center}.rounded-lg{border-radius:var(--radius)}.border-2{border-width:2px}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-violet-500{--tw-text-opacity:1;color:rgb(139 92 246/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.hover\\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\\:ring-gray-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(107 114 128/var(--tw-ring-opacity,1))}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px}";
5634
6531
  styleInject(css_248z$1,{"insertAt":"top"});
5635
6532
 
5636
- var css_248z = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}.flex{display:flex}.size-10{height:2.5rem;width:2.5rem}.h-screen{height:100vh}.w-screen{width:100vw}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.items-center{align-items:center}.justify-center{justify-content:center}.rounded-lg{border-radius:var(--radius)}.border-2{border-width:2px}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-violet-500{--tw-text-opacity:1;color:rgb(139 92 246/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.outline{outline-style:solid}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.hover\\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\\:ring-gray-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(107 114 128/var(--tw-ring-opacity,1))}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px}";
6533
+ var css_248z = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}.flex{display:flex}.size-10{height:2.5rem;width:2.5rem}.h-screen{height:100vh}.w-screen{width:100vw}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.items-center{align-items:center}.justify-center{justify-content:center}.rounded-lg{border-radius:var(--radius)}.border-2{border-width:2px}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-violet-500{--tw-text-opacity:1;color:rgb(139 92 246/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.hover\\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\\:ring-gray-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(107 114 128/var(--tw-ring-opacity,1))}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px}";
5637
6534
  styleInject(css_248z,{"insertAt":"top"});
5638
6535
 
5639
- export { AcademeAuthProvider, Button, ProtectedApp, ProtectedComponent, ProtectedRouter, Spinner, cn, createUserService, useAcademeAuth };
6536
+ var BACKOFFICE_ROLES;
6537
+ (function (BACKOFFICE_ROLES) {
6538
+ })(BACKOFFICE_ROLES || (BACKOFFICE_ROLES = {}));
6539
+
6540
+ var DASHBOARD_ROLES;
6541
+ (function (DASHBOARD_ROLES) {
6542
+ })(DASHBOARD_ROLES || (DASHBOARD_ROLES = {}));
6543
+
6544
+ var index = /*#__PURE__*/Object.freeze({
6545
+ __proto__: null
6546
+ });
6547
+
6548
+ /**
6549
+ * This file was auto-generated by openapi-typescript.
6550
+ * Do not make direct changes to the file.
6551
+ */
6552
+
6553
+ var academeApi = /*#__PURE__*/Object.freeze({
6554
+ __proto__: null
6555
+ });
6556
+
6557
+ export { AcademeAuthProvider, BACKOFFICE_ROLES, Button, DASHBOARD_ROLES, GLOBAL_ROLES, ProtectedApp, ProtectedComponent, ProtectedRouter, Spinner, academeApi as apiTypes, cn, createAcademeApiClient, index as types, useAcademeAuth };
5640
6558
  //# sourceMappingURL=index.esm.js.map