academe-kit 0.1.9 → 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.js CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
- var axios = require('axios');
6
5
 
7
6
  function _interopNamespaceDefault(e) {
8
7
  var n = Object.create(null);
@@ -2251,147 +2250,1020 @@ function isObject(input) {
2251
2250
  return typeof input === 'object' && input !== null;
2252
2251
  }
2253
2252
 
2254
- /**
2255
- * User Service - Fetches complete user data from MongoDB
2256
- * This service interacts with the new unified users collection
2257
- */
2258
- class UserService {
2259
- constructor(config) {
2260
- this.cachedUser = null;
2261
- this.cacheExpiry = 0;
2262
- this.getAccessToken = config.getAccessToken;
2263
- this.client = axios.create({
2264
- baseURL: config.apiBaseUrl,
2265
- headers: {
2266
- 'Content-Type': 'application/json'
2267
- }
2268
- });
2269
- // Add auth interceptor
2270
- this.client.interceptors.request.use((config) => {
2271
- const token = this.getAccessToken();
2272
- if (token) {
2273
- config.headers.Authorization = `Bearer ${token}`;
2274
- }
2275
- return config;
2276
- });
2277
- // Add response interceptor for error handling
2278
- this.client.interceptors.response.use((response) => response, (error) => {
2279
- if (error.response?.status === 401) {
2280
- // Clear cache on authentication error
2281
- this.clearCache();
2282
- }
2283
- return Promise.reject(error);
2284
- });
2253
+ const PATH_PARAM_RE = /\{[^{}]+\}/g;
2254
+ const supportsRequestInitExt = () => {
2255
+ return typeof process === "object" && Number.parseInt(process?.versions?.node?.substring(0, 2)) >= 18 && process.versions.undici;
2256
+ };
2257
+ function randomID() {
2258
+ return Math.random().toString(36).slice(2, 11);
2259
+ }
2260
+ function createClient(clientOptions) {
2261
+ let {
2262
+ baseUrl = "",
2263
+ Request: CustomRequest = globalThis.Request,
2264
+ fetch: baseFetch = globalThis.fetch,
2265
+ querySerializer: globalQuerySerializer,
2266
+ bodySerializer: globalBodySerializer,
2267
+ headers: baseHeaders,
2268
+ requestInitExt = void 0,
2269
+ ...baseOptions
2270
+ } = { ...clientOptions };
2271
+ requestInitExt = supportsRequestInitExt() ? requestInitExt : void 0;
2272
+ baseUrl = removeTrailingSlash(baseUrl);
2273
+ const globalMiddlewares = [];
2274
+ async function coreFetch(schemaPath, fetchOptions) {
2275
+ const {
2276
+ baseUrl: localBaseUrl,
2277
+ fetch = baseFetch,
2278
+ Request = CustomRequest,
2279
+ headers,
2280
+ params = {},
2281
+ parseAs = "json",
2282
+ querySerializer: requestQuerySerializer,
2283
+ bodySerializer = globalBodySerializer ?? defaultBodySerializer,
2284
+ body,
2285
+ middleware: requestMiddlewares = [],
2286
+ ...init
2287
+ } = fetchOptions || {};
2288
+ let finalBaseUrl = baseUrl;
2289
+ if (localBaseUrl) {
2290
+ finalBaseUrl = removeTrailingSlash(localBaseUrl) ?? baseUrl;
2285
2291
  }
2286
- /**
2287
- * Get current user data from MongoDB
2288
- * Includes caching to reduce API calls
2289
- */
2290
- async getCurrentUser(forceRefresh = false) {
2291
- try {
2292
- // Check cache
2293
- if (!forceRefresh && this.cachedUser && Date.now() < this.cacheExpiry) {
2294
- return this.cachedUser;
2292
+ let querySerializer = typeof globalQuerySerializer === "function" ? globalQuerySerializer : createQuerySerializer(globalQuerySerializer);
2293
+ if (requestQuerySerializer) {
2294
+ querySerializer = typeof requestQuerySerializer === "function" ? requestQuerySerializer : createQuerySerializer({
2295
+ ...typeof globalQuerySerializer === "object" ? globalQuerySerializer : {},
2296
+ ...requestQuerySerializer
2297
+ });
2298
+ }
2299
+ const serializedBody = body === void 0 ? void 0 : bodySerializer(
2300
+ body,
2301
+ // Note: we declare mergeHeaders() both here and below because it’s a bit of a chicken-or-egg situation:
2302
+ // bodySerializer() needs all headers so we aren’t dropping ones set by the user, however,
2303
+ // the result of this ALSO sets the lowest-priority content-type header. So we re-merge below,
2304
+ // setting the content-type at the very beginning to be overwritten.
2305
+ // Lastly, based on the way headers work, it’s not a simple “present-or-not” check becauase null intentionally un-sets headers.
2306
+ mergeHeaders(baseHeaders, headers, params.header)
2307
+ );
2308
+ const finalHeaders = mergeHeaders(
2309
+ // with no body, we should not to set Content-Type
2310
+ serializedBody === void 0 || // if serialized body is FormData; browser will correctly set Content-Type & boundary expression
2311
+ serializedBody instanceof FormData ? {} : {
2312
+ "Content-Type": "application/json"
2313
+ },
2314
+ baseHeaders,
2315
+ headers,
2316
+ params.header
2317
+ );
2318
+ const finalMiddlewares = [...globalMiddlewares, ...requestMiddlewares];
2319
+ const requestInit = {
2320
+ redirect: "follow",
2321
+ ...baseOptions,
2322
+ ...init,
2323
+ body: serializedBody,
2324
+ headers: finalHeaders
2325
+ };
2326
+ let id;
2327
+ let options;
2328
+ let request = new Request(
2329
+ createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer }),
2330
+ requestInit
2331
+ );
2332
+ let response;
2333
+ for (const key in init) {
2334
+ if (!(key in request)) {
2335
+ request[key] = init[key];
2336
+ }
2337
+ }
2338
+ if (finalMiddlewares.length) {
2339
+ id = randomID();
2340
+ options = Object.freeze({
2341
+ baseUrl: finalBaseUrl,
2342
+ fetch,
2343
+ parseAs,
2344
+ querySerializer,
2345
+ bodySerializer
2346
+ });
2347
+ for (const m of finalMiddlewares) {
2348
+ if (m && typeof m === "object" && typeof m.onRequest === "function") {
2349
+ const result = await m.onRequest({
2350
+ request,
2351
+ schemaPath,
2352
+ params,
2353
+ options,
2354
+ id
2355
+ });
2356
+ if (result) {
2357
+ if (result instanceof Request) {
2358
+ request = result;
2359
+ } else if (result instanceof Response) {
2360
+ response = result;
2361
+ break;
2362
+ } else {
2363
+ throw new Error("onRequest: must return new Request() or Response() when modifying the request");
2295
2364
  }
2296
- const response = await this.client.get('/api/users/me');
2297
- if (response.data) {
2298
- // Cache for 5 minutes
2299
- this.cachedUser = response.data;
2300
- this.cacheExpiry = Date.now() + (5 * 60 * 1000);
2301
- return response.data;
2365
+ }
2366
+ }
2367
+ }
2368
+ }
2369
+ if (!response) {
2370
+ try {
2371
+ response = await fetch(request, requestInitExt);
2372
+ } catch (error2) {
2373
+ let errorAfterMiddleware = error2;
2374
+ if (finalMiddlewares.length) {
2375
+ for (let i = finalMiddlewares.length - 1; i >= 0; i--) {
2376
+ const m = finalMiddlewares[i];
2377
+ if (m && typeof m === "object" && typeof m.onError === "function") {
2378
+ const result = await m.onError({
2379
+ request,
2380
+ error: errorAfterMiddleware,
2381
+ schemaPath,
2382
+ params,
2383
+ options,
2384
+ id
2385
+ });
2386
+ if (result) {
2387
+ if (result instanceof Response) {
2388
+ errorAfterMiddleware = void 0;
2389
+ response = result;
2390
+ break;
2391
+ }
2392
+ if (result instanceof Error) {
2393
+ errorAfterMiddleware = result;
2394
+ continue;
2395
+ }
2396
+ throw new Error("onError: must return new Response() or instance of Error");
2397
+ }
2302
2398
  }
2303
- return null;
2399
+ }
2304
2400
  }
2305
- catch (error) {
2306
- console.error('Error fetching current user:', error);
2307
- // If it's a 404, user doesn't exist in MongoDB yet
2308
- if (axios.isAxiosError(error) && error.response?.status === 404) {
2309
- // User will be auto-created on next API call
2310
- return null;
2401
+ if (errorAfterMiddleware) {
2402
+ throw errorAfterMiddleware;
2403
+ }
2404
+ }
2405
+ if (finalMiddlewares.length) {
2406
+ for (let i = finalMiddlewares.length - 1; i >= 0; i--) {
2407
+ const m = finalMiddlewares[i];
2408
+ if (m && typeof m === "object" && typeof m.onResponse === "function") {
2409
+ const result = await m.onResponse({
2410
+ request,
2411
+ response,
2412
+ schemaPath,
2413
+ params,
2414
+ options,
2415
+ id
2416
+ });
2417
+ if (result) {
2418
+ if (!(result instanceof Response)) {
2419
+ throw new Error("onResponse: must return new Response() when modifying the response");
2420
+ }
2421
+ response = result;
2311
2422
  }
2312
- throw error;
2423
+ }
2313
2424
  }
2425
+ }
2314
2426
  }
2315
- /**
2316
- * Update current user data
2317
- */
2318
- async updateCurrentUser(data) {
2319
- try {
2320
- // First get current user to get the ID
2321
- const currentUser = await this.getCurrentUser();
2322
- if (!currentUser) {
2323
- throw new Error('User not found');
2324
- }
2325
- const response = await this.client.put(`/api/users/${currentUser.id}`, data);
2326
- if (response.data) {
2327
- // Update cache
2328
- this.cachedUser = response.data;
2329
- this.cacheExpiry = Date.now() + (5 * 60 * 1000);
2330
- return response.data;
2331
- }
2332
- return null;
2427
+ if (response.status === 204 || request.method === "HEAD" || response.headers.get("Content-Length") === "0") {
2428
+ return response.ok ? { data: void 0, response } : { error: void 0, response };
2429
+ }
2430
+ if (response.ok) {
2431
+ if (parseAs === "stream") {
2432
+ return { data: response.body, response };
2433
+ }
2434
+ return { data: await response[parseAs](), response };
2435
+ }
2436
+ let error = await response.text();
2437
+ try {
2438
+ error = JSON.parse(error);
2439
+ } catch {
2440
+ }
2441
+ return { error, response };
2442
+ }
2443
+ return {
2444
+ request(method, url, init) {
2445
+ return coreFetch(url, { ...init, method: method.toUpperCase() });
2446
+ },
2447
+ /** Call a GET endpoint */
2448
+ GET(url, init) {
2449
+ return coreFetch(url, { ...init, method: "GET" });
2450
+ },
2451
+ /** Call a PUT endpoint */
2452
+ PUT(url, init) {
2453
+ return coreFetch(url, { ...init, method: "PUT" });
2454
+ },
2455
+ /** Call a POST endpoint */
2456
+ POST(url, init) {
2457
+ return coreFetch(url, { ...init, method: "POST" });
2458
+ },
2459
+ /** Call a DELETE endpoint */
2460
+ DELETE(url, init) {
2461
+ return coreFetch(url, { ...init, method: "DELETE" });
2462
+ },
2463
+ /** Call a OPTIONS endpoint */
2464
+ OPTIONS(url, init) {
2465
+ return coreFetch(url, { ...init, method: "OPTIONS" });
2466
+ },
2467
+ /** Call a HEAD endpoint */
2468
+ HEAD(url, init) {
2469
+ return coreFetch(url, { ...init, method: "HEAD" });
2470
+ },
2471
+ /** Call a PATCH endpoint */
2472
+ PATCH(url, init) {
2473
+ return coreFetch(url, { ...init, method: "PATCH" });
2474
+ },
2475
+ /** Call a TRACE endpoint */
2476
+ TRACE(url, init) {
2477
+ return coreFetch(url, { ...init, method: "TRACE" });
2478
+ },
2479
+ /** Register middleware */
2480
+ use(...middleware) {
2481
+ for (const m of middleware) {
2482
+ if (!m) {
2483
+ continue;
2333
2484
  }
2334
- catch (error) {
2335
- console.error('Error updating user:', error);
2336
- throw error;
2485
+ if (typeof m !== "object" || !("onRequest" in m || "onResponse" in m || "onError" in m)) {
2486
+ throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");
2337
2487
  }
2488
+ globalMiddlewares.push(m);
2489
+ }
2490
+ },
2491
+ /** Unregister middleware */
2492
+ eject(...middleware) {
2493
+ for (const m of middleware) {
2494
+ const i = globalMiddlewares.indexOf(m);
2495
+ if (i !== -1) {
2496
+ globalMiddlewares.splice(i, 1);
2497
+ }
2498
+ }
2338
2499
  }
2339
- /**
2340
- * Clear cached user data
2341
- */
2342
- clearCache() {
2343
- this.cachedUser = null;
2344
- this.cacheExpiry = 0;
2500
+ };
2501
+ }
2502
+ function serializePrimitiveParam(name, value, options) {
2503
+ if (value === void 0 || value === null) {
2504
+ return "";
2505
+ }
2506
+ if (typeof value === "object") {
2507
+ throw new Error(
2508
+ "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
2509
+ );
2510
+ }
2511
+ return `${name}=${options?.allowReserved === true ? value : encodeURIComponent(value)}`;
2512
+ }
2513
+ function serializeObjectParam(name, value, options) {
2514
+ if (!value || typeof value !== "object") {
2515
+ return "";
2516
+ }
2517
+ const values = [];
2518
+ const joiner = {
2519
+ simple: ",",
2520
+ label: ".",
2521
+ matrix: ";"
2522
+ }[options.style] || "&";
2523
+ if (options.style !== "deepObject" && options.explode === false) {
2524
+ for (const k in value) {
2525
+ values.push(k, options.allowReserved === true ? value[k] : encodeURIComponent(value[k]));
2345
2526
  }
2346
- /**
2347
- * Check if user has a specific role
2348
- */
2349
- hasRole(user, role) {
2350
- if (!user || !user.roles)
2351
- return false;
2352
- return user.roles.includes(role);
2527
+ const final2 = values.join(",");
2528
+ switch (options.style) {
2529
+ case "form": {
2530
+ return `${name}=${final2}`;
2531
+ }
2532
+ case "label": {
2533
+ return `.${final2}`;
2534
+ }
2535
+ case "matrix": {
2536
+ return `;${name}=${final2}`;
2537
+ }
2538
+ default: {
2539
+ return final2;
2540
+ }
2353
2541
  }
2354
- /**
2355
- * Check if user has access to a specific school
2356
- */
2357
- hasSchoolAccess(user, schoolId) {
2358
- if (!user)
2359
- return false;
2360
- // Admin has access to all schools
2361
- if (this.hasRole(user, 'admin_academe'))
2362
- return true;
2363
- // Check if user's school matches
2364
- return user.school_id === schoolId;
2542
+ }
2543
+ for (const k in value) {
2544
+ const finalName = options.style === "deepObject" ? `${name}[${k}]` : k;
2545
+ values.push(serializePrimitiveParam(finalName, value[k], options));
2546
+ }
2547
+ const final = values.join(joiner);
2548
+ return options.style === "label" || options.style === "matrix" ? `${joiner}${final}` : final;
2549
+ }
2550
+ function serializeArrayParam(name, value, options) {
2551
+ if (!Array.isArray(value)) {
2552
+ return "";
2553
+ }
2554
+ if (options.explode === false) {
2555
+ const joiner2 = { form: ",", spaceDelimited: "%20", pipeDelimited: "|" }[options.style] || ",";
2556
+ const final = (options.allowReserved === true ? value : value.map((v) => encodeURIComponent(v))).join(joiner2);
2557
+ switch (options.style) {
2558
+ case "simple": {
2559
+ return final;
2560
+ }
2561
+ case "label": {
2562
+ return `.${final}`;
2563
+ }
2564
+ case "matrix": {
2565
+ return `;${name}=${final}`;
2566
+ }
2567
+ // case "spaceDelimited":
2568
+ // case "pipeDelimited":
2569
+ default: {
2570
+ return `${name}=${final}`;
2571
+ }
2365
2572
  }
2366
- /**
2367
- * Check if user is a student (has student-specific data)
2368
- */
2369
- isStudent(user) {
2370
- if (!user)
2371
- return false;
2372
- return !!user.registration_number || this.hasRole(user, 'student');
2573
+ }
2574
+ const joiner = { simple: ",", label: ".", matrix: ";" }[options.style] || "&";
2575
+ const values = [];
2576
+ for (const v of value) {
2577
+ if (options.style === "simple" || options.style === "label") {
2578
+ values.push(options.allowReserved === true ? v : encodeURIComponent(v));
2579
+ } else {
2580
+ values.push(serializePrimitiveParam(name, v, options));
2373
2581
  }
2374
- /**
2375
- * Check if user has completed onboarding
2376
- */
2377
- hasCompletedOnboarding(user) {
2378
- if (!user)
2379
- return false;
2380
- return user.onboarding_completo;
2582
+ }
2583
+ return options.style === "label" || options.style === "matrix" ? `${joiner}${values.join(joiner)}` : values.join(joiner);
2584
+ }
2585
+ function createQuerySerializer(options) {
2586
+ return function querySerializer(queryParams) {
2587
+ const search = [];
2588
+ if (queryParams && typeof queryParams === "object") {
2589
+ for (const name in queryParams) {
2590
+ const value = queryParams[name];
2591
+ if (value === void 0 || value === null) {
2592
+ continue;
2593
+ }
2594
+ if (Array.isArray(value)) {
2595
+ if (value.length === 0) {
2596
+ continue;
2597
+ }
2598
+ search.push(
2599
+ serializeArrayParam(name, value, {
2600
+ style: "form",
2601
+ explode: true,
2602
+ ...options?.array,
2603
+ allowReserved: options?.allowReserved || false
2604
+ })
2605
+ );
2606
+ continue;
2607
+ }
2608
+ if (typeof value === "object") {
2609
+ search.push(
2610
+ serializeObjectParam(name, value, {
2611
+ style: "deepObject",
2612
+ explode: true,
2613
+ ...options?.object,
2614
+ allowReserved: options?.allowReserved || false
2615
+ })
2616
+ );
2617
+ continue;
2618
+ }
2619
+ search.push(serializePrimitiveParam(name, value, options));
2620
+ }
2381
2621
  }
2382
- /**
2383
- * Check if user has access enabled
2384
- */
2385
- hasAccessEnabled(user) {
2386
- if (!user)
2387
- return false;
2388
- return user.acesso_liberado && user.active;
2622
+ return search.join("&");
2623
+ };
2624
+ }
2625
+ function defaultPathSerializer(pathname, pathParams) {
2626
+ let nextURL = pathname;
2627
+ for (const match of pathname.match(PATH_PARAM_RE) ?? []) {
2628
+ let name = match.substring(1, match.length - 1);
2629
+ let explode = false;
2630
+ let style = "simple";
2631
+ if (name.endsWith("*")) {
2632
+ explode = true;
2633
+ name = name.substring(0, name.length - 1);
2389
2634
  }
2635
+ if (name.startsWith(".")) {
2636
+ style = "label";
2637
+ name = name.substring(1);
2638
+ } else if (name.startsWith(";")) {
2639
+ style = "matrix";
2640
+ name = name.substring(1);
2641
+ }
2642
+ if (!pathParams || pathParams[name] === void 0 || pathParams[name] === null) {
2643
+ continue;
2644
+ }
2645
+ const value = pathParams[name];
2646
+ if (Array.isArray(value)) {
2647
+ nextURL = nextURL.replace(match, serializeArrayParam(name, value, { style, explode }));
2648
+ continue;
2649
+ }
2650
+ if (typeof value === "object") {
2651
+ nextURL = nextURL.replace(match, serializeObjectParam(name, value, { style, explode }));
2652
+ continue;
2653
+ }
2654
+ if (style === "matrix") {
2655
+ nextURL = nextURL.replace(match, `;${serializePrimitiveParam(name, value)}`);
2656
+ continue;
2657
+ }
2658
+ nextURL = nextURL.replace(match, style === "label" ? `.${encodeURIComponent(value)}` : encodeURIComponent(value));
2659
+ }
2660
+ return nextURL;
2661
+ }
2662
+ function defaultBodySerializer(body, headers) {
2663
+ if (body instanceof FormData) {
2664
+ return body;
2665
+ }
2666
+ if (headers) {
2667
+ const contentType = headers.get instanceof Function ? headers.get("Content-Type") ?? headers.get("content-type") : headers["Content-Type"] ?? headers["content-type"];
2668
+ if (contentType === "application/x-www-form-urlencoded") {
2669
+ return new URLSearchParams(body).toString();
2670
+ }
2671
+ }
2672
+ return JSON.stringify(body);
2673
+ }
2674
+ function createFinalURL(pathname, options) {
2675
+ let finalURL = `${options.baseUrl}${pathname}`;
2676
+ if (options.params?.path) {
2677
+ finalURL = defaultPathSerializer(finalURL, options.params.path);
2678
+ }
2679
+ let search = options.querySerializer(options.params.query ?? {});
2680
+ if (search.startsWith("?")) {
2681
+ search = search.substring(1);
2682
+ }
2683
+ if (search) {
2684
+ finalURL += `?${search}`;
2685
+ }
2686
+ return finalURL;
2687
+ }
2688
+ function mergeHeaders(...allHeaders) {
2689
+ const finalHeaders = new Headers();
2690
+ for (const h of allHeaders) {
2691
+ if (!h || typeof h !== "object") {
2692
+ continue;
2693
+ }
2694
+ const iterator = h instanceof Headers ? h.entries() : Object.entries(h);
2695
+ for (const [k, v] of iterator) {
2696
+ if (v === null) {
2697
+ finalHeaders.delete(k);
2698
+ } else if (Array.isArray(v)) {
2699
+ for (const v2 of v) {
2700
+ finalHeaders.append(k, v2);
2701
+ }
2702
+ } else if (v !== void 0) {
2703
+ finalHeaders.set(k, v);
2704
+ }
2705
+ }
2706
+ }
2707
+ return finalHeaders;
2708
+ }
2709
+ function removeTrailingSlash(url) {
2710
+ if (url.endsWith("/")) {
2711
+ return url.substring(0, url.length - 1);
2712
+ }
2713
+ return url;
2714
+ }
2715
+
2716
+ function createUserService(apiClient) {
2717
+ return {
2718
+ /**
2719
+ * Get current authenticated user
2720
+ */
2721
+ getMe() {
2722
+ return apiClient.GET('/users/me');
2723
+ },
2724
+ /**
2725
+ * List all users with optional filters
2726
+ */
2727
+ getUsers(params) {
2728
+ return apiClient.GET('/users', {
2729
+ params: { query: params },
2730
+ });
2731
+ },
2732
+ /**
2733
+ * Get user by ID
2734
+ */
2735
+ getUserById(id) {
2736
+ return apiClient.GET('/users/{id}', {
2737
+ params: { path: { id } },
2738
+ });
2739
+ },
2740
+ /**
2741
+ * Create a new user
2742
+ */
2743
+ createUser(body) {
2744
+ return apiClient.POST('/users', {
2745
+ body,
2746
+ });
2747
+ },
2748
+ /**
2749
+ * Update user information
2750
+ */
2751
+ updateUser(id, body) {
2752
+ return apiClient.PATCH('/users/{id}', {
2753
+ params: { path: { id } },
2754
+ body,
2755
+ });
2756
+ },
2757
+ /**
2758
+ * Delete user
2759
+ */
2760
+ deleteUser(id) {
2761
+ return apiClient.DELETE('/users/{id}', {
2762
+ params: { path: { id } },
2763
+ });
2764
+ },
2765
+ /**
2766
+ * Get user's groups
2767
+ */
2768
+ getUserGroups(id) {
2769
+ return apiClient.GET('/users/{id}/groups', {
2770
+ params: { path: { id } },
2771
+ });
2772
+ },
2773
+ /**
2774
+ * Get user's certificates
2775
+ */
2776
+ getUserCertificates(id) {
2777
+ return apiClient.GET('/users/{id}/certificates', {
2778
+ params: { path: { id } },
2779
+ });
2780
+ },
2781
+ /**
2782
+ * Get user's institutions
2783
+ */
2784
+ getUserInstitutions(id) {
2785
+ return apiClient.GET('/users/{id}/institutions', {
2786
+ params: { path: { id } },
2787
+ });
2788
+ },
2789
+ /**
2790
+ * Sync user with Keycloak
2791
+ */
2792
+ syncUser(id) {
2793
+ return apiClient.POST('/users/{id}/sync', {
2794
+ params: { path: { id } },
2795
+ });
2796
+ },
2797
+ };
2798
+ }
2799
+
2800
+ function createInstitutionService(apiClient) {
2801
+ return {
2802
+ getAll() {
2803
+ return apiClient.GET('/institutions');
2804
+ },
2805
+ getById(id) {
2806
+ return apiClient.GET('/institutions/{id}', { params: { path: { id } } });
2807
+ },
2808
+ // Institution Groups
2809
+ getGroups(institutionId) {
2810
+ return apiClient.GET('/institutions/{institutionId}/groups', {
2811
+ params: { path: { institutionId } },
2812
+ });
2813
+ },
2814
+ addGroup(institutionId, data) {
2815
+ return apiClient.POST('/institutions/{institutionId}/groups', {
2816
+ params: { path: { institutionId } },
2817
+ body: data,
2818
+ });
2819
+ },
2820
+ removeGroup(institutionId, groupId) {
2821
+ return apiClient.DELETE('/institutions/{institutionId}/groups/{groupId}', {
2822
+ params: { path: { institutionId, groupId } },
2823
+ });
2824
+ },
2825
+ updateGroup(institutionId, groupId, data) {
2826
+ return apiClient.PATCH('/institutions/{institutionId}/groups/{groupId}', {
2827
+ params: { path: { institutionId, groupId } },
2828
+ body: data,
2829
+ });
2830
+ },
2831
+ // Institution Classrooms
2832
+ getClassrooms(institutionId, options) {
2833
+ return apiClient.GET('/institutions/{institutionId}/classrooms', {
2834
+ params: {
2835
+ path: { institutionId },
2836
+ query: options,
2837
+ },
2838
+ });
2839
+ },
2840
+ getClassroomById(institutionId, classroomId) {
2841
+ return apiClient.GET('/institutions/{institutionId}/classrooms/{classroomId}', {
2842
+ params: { path: { institutionId, classroomId } },
2843
+ });
2844
+ },
2845
+ addClassroom(institutionId, data) {
2846
+ return apiClient.POST('/institutions/{institutionId}/classrooms', {
2847
+ params: { path: { institutionId } },
2848
+ body: data,
2849
+ });
2850
+ },
2851
+ updateClassroom(institutionId, classroomId, data) {
2852
+ return apiClient.PATCH('/institutions/{institutionId}/classrooms/{classroomId}', {
2853
+ params: { path: { institutionId, classroomId } },
2854
+ body: data,
2855
+ });
2856
+ },
2857
+ removeClassroom(institutionId, classroomId) {
2858
+ return apiClient.DELETE('/institutions/{institutionId}/classrooms/{classroomId}', {
2859
+ params: { path: { institutionId, classroomId } },
2860
+ });
2861
+ },
2862
+ // Institution Registrations (Users in Institution)
2863
+ getRegistrations(institutionId) {
2864
+ return apiClient.GET('/institutions/{institutionId}/registrations', {
2865
+ params: { path: { institutionId } },
2866
+ });
2867
+ },
2868
+ getRegistrationById(institutionId, registrationId) {
2869
+ return apiClient.GET('/institutions/{institutionId}/registrations/{registrationId}', {
2870
+ params: { path: { institutionId, registrationId } },
2871
+ });
2872
+ },
2873
+ getRegistrationByUserId(institutionId, userId) {
2874
+ return apiClient.GET('/institutions/{institutionId}/registrations/user/{userId}', {
2875
+ params: { path: { institutionId, userId } },
2876
+ });
2877
+ },
2878
+ registerUser(institutionId, data) {
2879
+ return apiClient.POST('/institutions/{institutionId}/registrations', {
2880
+ params: { path: { institutionId } },
2881
+ body: data,
2882
+ });
2883
+ },
2884
+ updateRegistration(institutionId, registrationId, data) {
2885
+ return apiClient.PATCH('/institutions/{institutionId}/registrations/{registrationId}', {
2886
+ params: { path: { institutionId, registrationId } },
2887
+ body: data,
2888
+ });
2889
+ },
2890
+ assignUserToClassroom(institutionId, registrationId, data) {
2891
+ return apiClient.PATCH('/institutions/{institutionId}/registrations/{registrationId}/classroom', {
2892
+ params: { path: { institutionId, registrationId } },
2893
+ body: data,
2894
+ });
2895
+ },
2896
+ removeRegistration(institutionId, registrationId) {
2897
+ return apiClient.DELETE('/institutions/{institutionId}/registrations/{registrationId}', {
2898
+ params: { path: { institutionId, registrationId } },
2899
+ });
2900
+ },
2901
+ };
2902
+ }
2903
+
2904
+ function createReportService(apiClient) {
2905
+ return {
2906
+ /**
2907
+ * Get dashboard data (global)
2908
+ * Returns aggregated dashboard data for all institutions (requires admin permission)
2909
+ */
2910
+ getDashboard(params) {
2911
+ return apiClient.GET('/reports/dashboard', {
2912
+ params: { query: params },
2913
+ });
2914
+ },
2915
+ /**
2916
+ * Get dashboard data for specific institution
2917
+ * Returns aggregated dashboard data for a specific institution
2918
+ */
2919
+ getDashboardByInstitution(id) {
2920
+ return apiClient.GET('/reports/dashboard/{id}', {
2921
+ params: { path: { id } },
2922
+ });
2923
+ },
2924
+ /**
2925
+ * Get courses distribution by area (global)
2926
+ * Returns distribution of course completions by area/category
2927
+ */
2928
+ getCoursesByArea() {
2929
+ return apiClient.GET('/reports/courses-by-area');
2930
+ },
2931
+ /**
2932
+ * Get courses distribution by area for specific institution
2933
+ * Returns distribution of course completions by area/category for an institution
2934
+ */
2935
+ getCoursesByAreaByInstitution(id) {
2936
+ return apiClient.GET('/reports/courses-by-area/{id}', {
2937
+ params: { path: { id } },
2938
+ });
2939
+ },
2940
+ /**
2941
+ * Get adhesion rate (global)
2942
+ * Returns adhesion rate (unique students who accessed) per month for the last 6 months
2943
+ */
2944
+ getAdhesionRate() {
2945
+ return apiClient.GET('/reports/adhesion-rate');
2946
+ },
2947
+ /**
2948
+ * Get adhesion rate for specific institution
2949
+ * Returns adhesion rate for an institution for the last 6 months
2950
+ */
2951
+ getAdhesionRateByInstitution(id) {
2952
+ return apiClient.GET('/reports/adhesion-rate/{id}', {
2953
+ params: { path: { id } },
2954
+ });
2955
+ },
2956
+ /**
2957
+ * Get recent activities (global)
2958
+ * Returns recent student activities (certificates issued and courses started)
2959
+ */
2960
+ getRecentActivities(params) {
2961
+ return apiClient.GET('/reports/recent-activities', {
2962
+ params: { query: params },
2963
+ });
2964
+ },
2965
+ /**
2966
+ * Get recent activities for specific institution
2967
+ * Returns recent student activities for an institution
2968
+ */
2969
+ getRecentActivitiesByInstitution(id, params) {
2970
+ return apiClient.GET('/reports/recent-activities/{id}', {
2971
+ params: {
2972
+ path: { id },
2973
+ query: params,
2974
+ },
2975
+ });
2976
+ },
2977
+ /**
2978
+ * Get top students (global)
2979
+ * Returns top 10 students based on selected filter
2980
+ */
2981
+ getTopStudents(params) {
2982
+ return apiClient.GET('/reports/top-students', {
2983
+ params: { query: params },
2984
+ });
2985
+ },
2986
+ /**
2987
+ * Get top students for specific institution
2988
+ * Returns top 10 students for an institution based on selected filter
2989
+ */
2990
+ getTopStudentsByInstitution(id, params) {
2991
+ return apiClient.GET('/reports/top-students/{id}', {
2992
+ params: {
2993
+ path: { id },
2994
+ query: params,
2995
+ },
2996
+ });
2997
+ },
2998
+ };
2999
+ }
3000
+
3001
+ function createClassroomService(apiClient) {
3002
+ return {
3003
+ /**
3004
+ * List all classrooms
3005
+ */
3006
+ getAll() {
3007
+ return apiClient.GET('/classrooms');
3008
+ },
3009
+ /**
3010
+ * Get classroom by ID
3011
+ */
3012
+ getById(id) {
3013
+ return apiClient.GET('/classrooms/{id}', {
3014
+ params: { path: { id } },
3015
+ });
3016
+ },
3017
+ /**
3018
+ * Get classrooms by institution ID
3019
+ */
3020
+ getByInstitution(institutionId, params) {
3021
+ return apiClient.GET('/classrooms/institution/{id}', {
3022
+ params: {
3023
+ path: { id: institutionId },
3024
+ query: params,
3025
+ },
3026
+ });
3027
+ },
3028
+ /**
3029
+ * Create a new classroom
3030
+ */
3031
+ create(data) {
3032
+ return apiClient.POST('/classrooms', {
3033
+ body: data,
3034
+ });
3035
+ },
3036
+ /**
3037
+ * Update classroom
3038
+ */
3039
+ update(id, data) {
3040
+ return apiClient.PATCH('/classrooms/{id}', {
3041
+ params: { path: { id } },
3042
+ body: data,
3043
+ });
3044
+ },
3045
+ /**
3046
+ * Delete classroom
3047
+ */
3048
+ delete(id) {
3049
+ return apiClient.DELETE('/classrooms/{id}', {
3050
+ params: { path: { id } },
3051
+ });
3052
+ },
3053
+ };
3054
+ }
3055
+
3056
+ function createOrganizationService(apiClient) {
3057
+ return {
3058
+ /**
3059
+ * List all organizations with optional filters
3060
+ */
3061
+ getAll(params) {
3062
+ return apiClient.GET('/organizations', {
3063
+ params: { query: params },
3064
+ });
3065
+ },
3066
+ /**
3067
+ * Get organization by ID
3068
+ */
3069
+ getById(id) {
3070
+ return apiClient.GET('/organizations/{id}', {
3071
+ params: { path: { id } },
3072
+ });
3073
+ },
3074
+ /**
3075
+ * Create a new organization
3076
+ */
3077
+ create(body) {
3078
+ return apiClient.POST('/organizations', {
3079
+ body,
3080
+ });
3081
+ },
3082
+ /**
3083
+ * Update organization information
3084
+ */
3085
+ update(id, body) {
3086
+ return apiClient.PATCH('/organizations/{id}', {
3087
+ params: { path: { id } },
3088
+ body,
3089
+ });
3090
+ },
3091
+ /**
3092
+ * Delete organization
3093
+ * Note: Cannot delete organizations with children
3094
+ */
3095
+ delete(id) {
3096
+ return apiClient.DELETE('/organizations/{id}', {
3097
+ params: { path: { id } },
3098
+ });
3099
+ },
3100
+ };
2390
3101
  }
2391
- // Export singleton instance creator
2392
- const createUserService = (config) => {
2393
- return new UserService(config);
2394
- };
3102
+
3103
+ function createSerieService(apiClient) {
3104
+ return {
3105
+ /**
3106
+ * List all series
3107
+ */
3108
+ getAll() {
3109
+ return apiClient.GET('/series');
3110
+ },
3111
+ /**
3112
+ * Get serie by ID
3113
+ */
3114
+ getById(id) {
3115
+ return apiClient.GET('/series/{id}', {
3116
+ params: { path: { id } },
3117
+ });
3118
+ },
3119
+ /**
3120
+ * Create a new serie
3121
+ */
3122
+ create(data) {
3123
+ return apiClient.POST('/series', {
3124
+ body: data,
3125
+ });
3126
+ },
3127
+ /**
3128
+ * Update serie
3129
+ */
3130
+ update(id, data) {
3131
+ return apiClient.PATCH('/series/{id}', {
3132
+ params: { path: { id } },
3133
+ body: data,
3134
+ });
3135
+ },
3136
+ /**
3137
+ * Delete serie
3138
+ */
3139
+ delete(id) {
3140
+ return apiClient.DELETE('/series/{id}', {
3141
+ params: { path: { id } },
3142
+ });
3143
+ },
3144
+ };
3145
+ }
3146
+
3147
+ function createShiftService(apiClient) {
3148
+ return {
3149
+ /**
3150
+ * List all shifts
3151
+ */
3152
+ getAll() {
3153
+ return apiClient.GET('/shifts');
3154
+ },
3155
+ /**
3156
+ * Get shift by ID
3157
+ */
3158
+ getById(id) {
3159
+ return apiClient.GET('/shifts/{id}', {
3160
+ params: { path: { id } },
3161
+ });
3162
+ },
3163
+ /**
3164
+ * Create a new shift
3165
+ */
3166
+ create(data) {
3167
+ return apiClient.POST('/shifts', {
3168
+ body: data,
3169
+ });
3170
+ },
3171
+ /**
3172
+ * Update shift
3173
+ */
3174
+ update(id, data) {
3175
+ return apiClient.PATCH('/shifts/{id}', {
3176
+ params: { path: { id } },
3177
+ body: data,
3178
+ });
3179
+ },
3180
+ /**
3181
+ * Delete shift
3182
+ */
3183
+ delete(id) {
3184
+ return apiClient.DELETE('/shifts/{id}', {
3185
+ params: { path: { id } },
3186
+ });
3187
+ },
3188
+ };
3189
+ }
3190
+
3191
+ function createGuardianService(apiClient) {
3192
+ return {
3193
+ // List all guardians
3194
+ getAll() {
3195
+ return apiClient.GET('/guardians');
3196
+ },
3197
+ // Get guardian by ID
3198
+ getById(id) {
3199
+ return apiClient.GET('/guardians/{id}', {
3200
+ params: { path: { id } },
3201
+ });
3202
+ },
3203
+ // Create a new guardian
3204
+ create(data) {
3205
+ return apiClient.POST('/guardians', {
3206
+ body: data,
3207
+ });
3208
+ },
3209
+ // Update guardian
3210
+ update(id, data) {
3211
+ return apiClient.PATCH('/guardians/{id}', {
3212
+ params: { path: { id } },
3213
+ body: data,
3214
+ });
3215
+ },
3216
+ // Delete guardian
3217
+ delete(id) {
3218
+ return apiClient.DELETE('/guardians/{id}', {
3219
+ params: { path: { id } },
3220
+ });
3221
+ },
3222
+ // Get guardian's users (students)
3223
+ getUsers(id) {
3224
+ return apiClient.GET('/guardians/{id}/users', {
3225
+ params: { path: { id } },
3226
+ });
3227
+ },
3228
+ // Assign guardian to user
3229
+ assignToUser(data) {
3230
+ return apiClient.POST('/guardians/assign', {
3231
+ body: data,
3232
+ });
3233
+ },
3234
+ // Remove guardian from user
3235
+ removeFromUser(guardianId, userId) {
3236
+ return apiClient.DELETE('/guardians/{guardianId}/users/{userId}', {
3237
+ params: { path: { guardianId, userId } },
3238
+ });
3239
+ },
3240
+ };
3241
+ }
3242
+
3243
+ function createAcademeApiClient(baseUrl) {
3244
+ return createClient({ baseUrl });
3245
+ }
3246
+ function createAcademeServices(apiClient) {
3247
+ return {
3248
+ user: createUserService(apiClient),
3249
+ institution: createInstitutionService(apiClient),
3250
+ report: createReportService(apiClient),
3251
+ classroom: createClassroomService(apiClient),
3252
+ organization: createOrganizationService(apiClient),
3253
+ serie: createSerieService(apiClient),
3254
+ shift: createShiftService(apiClient),
3255
+ guardian: createGuardianService(apiClient),
3256
+ };
3257
+ }
3258
+
3259
+ exports.GLOBAL_ROLES = void 0;
3260
+ (function (GLOBAL_ROLES) {
3261
+ GLOBAL_ROLES["ADMIN_ACADEME"] = "admin_academe";
3262
+ GLOBAL_ROLES["SCHOOL_ADMIN"] = "school_admin";
3263
+ GLOBAL_ROLES["TEACHER"] = "teacher";
3264
+ GLOBAL_ROLES["STUDENT"] = "student";
3265
+ GLOBAL_ROLES["GUARDIAN"] = "guardian";
3266
+ })(exports.GLOBAL_ROLES || (exports.GLOBAL_ROLES = {}));
2395
3267
 
2396
3268
  const AcademeAuthProvider = ({ realm, hubUrl, children, clientId, keycloakUrl, apiBaseUrl, }) => {
2397
3269
  return (jsxRuntime.jsx(ReactKeycloakProvider, { authClient: new Keycloak({ clientId, realm, url: keycloakUrl }), children: jsxRuntime.jsx(SecurityProvider, { hubUrl: hubUrl, apiBaseUrl: apiBaseUrl, children: children }) }));
@@ -2406,30 +3278,53 @@ const SecurityContext = React.createContext({
2406
3278
  hasRealmRole: () => false,
2407
3279
  hasClientRole: () => false,
2408
3280
  isAuthenticated: () => false,
3281
+ apiClient: null,
3282
+ services: null,
2409
3283
  });
2410
- const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children, }) => {
3284
+ const SecurityProvider = ({ apiBaseUrl = "https://stg-api.academe.com.br", children, }) => {
2411
3285
  const [isInitialized, setIsInitialized] = React.useState(false);
2412
3286
  const [currentUser, setCurrentUser] = React.useState(null);
2413
3287
  const { initialized, keycloak } = useKeycloak();
2414
- const userService = createUserService({
2415
- apiBaseUrl,
2416
- getAccessToken: () => keycloak?.token || null,
2417
- });
3288
+ // Create API client with the provided baseUrl
3289
+ const apiClient = React.useMemo(() => {
3290
+ return createAcademeApiClient(apiBaseUrl);
3291
+ }, [apiBaseUrl]);
3292
+ const services = React.useMemo(() => {
3293
+ return createAcademeServices(apiClient);
3294
+ }, [apiClient]);
3295
+ React.useEffect(() => {
3296
+ if (keycloak?.token) {
3297
+ apiClient.use({
3298
+ onRequest({ request }) {
3299
+ request.headers.set("Authorization", `Bearer ${keycloak.token}`);
3300
+ return request;
3301
+ },
3302
+ });
3303
+ }
3304
+ }, [keycloak?.token, apiClient]);
2418
3305
  React.useEffect(() => {
2419
3306
  setIsInitialized(initialized);
2420
3307
  }, [initialized]);
2421
3308
  React.useEffect(() => {
2422
3309
  window.accessToken = keycloak.token;
2423
3310
  }, [keycloak.token]);
2424
- // Fetch user data from MongoDB when authenticated
3311
+ const getKeycloakUser = React.useCallback(() => {
3312
+ const idTokenParsed = keycloak?.idTokenParsed || {};
3313
+ return {
3314
+ email: idTokenParsed?.email || "",
3315
+ name: idTokenParsed?.given_name || "",
3316
+ lastName: idTokenParsed?.family_name || "",
3317
+ };
3318
+ }, [keycloak?.idTokenParsed]);
3319
+ // Fetch user data from API when authenticated
2425
3320
  React.useEffect(() => {
2426
3321
  const fetchUserData = async () => {
2427
3322
  if (initialized && keycloak?.authenticated && keycloak?.token) {
2428
3323
  try {
2429
- const mongoUser = await userService.getCurrentUser();
2430
- if (mongoUser) {
3324
+ const response = await services.user.getMe();
3325
+ if (response?.data?.data) {
2431
3326
  const academeUser = {
2432
- ...mongoUser,
3327
+ ...response.data.data,
2433
3328
  keycloakUser: getKeycloakUser(),
2434
3329
  };
2435
3330
  setCurrentUser(academeUser);
@@ -2440,28 +3335,24 @@ const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children,
2440
3335
  }
2441
3336
  }
2442
3337
  else if (!keycloak?.authenticated) {
2443
- // Clear user data when not authenticated
2444
3338
  setCurrentUser(null);
2445
- userService.clearCache();
2446
3339
  }
2447
3340
  };
2448
3341
  fetchUserData();
2449
- }, [initialized, keycloak?.authenticated, keycloak?.token]);
2450
- const getKeycloakUser = () => {
2451
- const idTokenParsed = keycloak?.idTokenParsed || {};
2452
- return {
2453
- email: idTokenParsed?.email || "",
2454
- name: idTokenParsed?.given_name || "",
2455
- lastName: idTokenParsed?.family_name || "",
2456
- };
2457
- };
3342
+ }, [
3343
+ initialized,
3344
+ keycloak?.authenticated,
3345
+ keycloak?.token,
3346
+ getKeycloakUser,
3347
+ services,
3348
+ ]);
2458
3349
  const refreshUserData = React.useCallback(async () => {
2459
3350
  if (keycloak?.authenticated) {
2460
3351
  try {
2461
- const mongoUser = await userService.getCurrentUser(true); // Force refresh
2462
- if (mongoUser) {
3352
+ const response = await services.user.getMe();
3353
+ if (response?.data?.data) {
2463
3354
  const academeUser = {
2464
- ...mongoUser,
3355
+ ...response.data.data,
2465
3356
  keycloakUser: getKeycloakUser(),
2466
3357
  };
2467
3358
  setCurrentUser(academeUser);
@@ -2471,9 +3362,8 @@ const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children,
2471
3362
  console.error("Error refreshing user data:", error);
2472
3363
  }
2473
3364
  }
2474
- }, [keycloak?.authenticated]);
3365
+ }, [keycloak?.authenticated, getKeycloakUser, services]);
2475
3366
  const signOut = () => {
2476
- userService.clearCache();
2477
3367
  setCurrentUser(null);
2478
3368
  keycloak?.logout();
2479
3369
  };
@@ -2481,12 +3371,13 @@ const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children,
2481
3371
  return (!!keycloak?.idTokenParsed?.email?.length && !!keycloak?.authenticated);
2482
3372
  };
2483
3373
  const hasSchool = (schoolId) => {
2484
- if (currentUser?.school_id) {
2485
- return (currentUser.school_id === schoolId ||
2486
- userService.hasRole(currentUser, "admin_academe"));
3374
+ if (keycloak?.hasRealmRole(exports.GLOBAL_ROLES.ADMIN_ACADEME)) {
3375
+ return true;
3376
+ }
3377
+ if (currentUser?.institutionRegistrations?.some((registration) => registration.institutionId === schoolId)) {
3378
+ return true;
2487
3379
  }
2488
- // Fallback to Keycloak data
2489
- return false; // No school_id in Keycloak data
3380
+ return false;
2490
3381
  };
2491
3382
  return (jsxRuntime.jsx(SecurityContext.Provider, { value: {
2492
3383
  isInitialized,
@@ -2498,6 +3389,8 @@ const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children,
2498
3389
  goToLogin: keycloak.login,
2499
3390
  hasRealmRole: keycloak?.hasRealmRole,
2500
3391
  hasClientRole: keycloak.hasResourceRole,
3392
+ apiClient,
3393
+ services,
2501
3394
  }, children: children }));
2502
3395
  };
2503
3396
  const useAcademeAuth = () => React.useContext(SecurityContext);
@@ -5654,19 +6547,42 @@ function styleInject(css, ref) {
5654
6547
  }
5655
6548
  }
5656
6549
 
5657
- 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}.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}";
6550
+ 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}";
5658
6551
  styleInject(css_248z$1,{"insertAt":"top"});
5659
6552
 
5660
- 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}.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}";
6553
+ 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}";
5661
6554
  styleInject(css_248z,{"insertAt":"top"});
5662
6555
 
6556
+ exports.BACKOFFICE_ROLES = void 0;
6557
+ (function (BACKOFFICE_ROLES) {
6558
+ })(exports.BACKOFFICE_ROLES || (exports.BACKOFFICE_ROLES = {}));
6559
+
6560
+ exports.DASHBOARD_ROLES = void 0;
6561
+ (function (DASHBOARD_ROLES) {
6562
+ })(exports.DASHBOARD_ROLES || (exports.DASHBOARD_ROLES = {}));
6563
+
6564
+ var index = /*#__PURE__*/Object.freeze({
6565
+ __proto__: null
6566
+ });
6567
+
6568
+ /**
6569
+ * This file was auto-generated by openapi-typescript.
6570
+ * Do not make direct changes to the file.
6571
+ */
6572
+
6573
+ var academeApi = /*#__PURE__*/Object.freeze({
6574
+ __proto__: null
6575
+ });
6576
+
5663
6577
  exports.AcademeAuthProvider = AcademeAuthProvider;
5664
6578
  exports.Button = Button;
5665
6579
  exports.ProtectedApp = ProtectedApp;
5666
6580
  exports.ProtectedComponent = ProtectedComponent;
5667
6581
  exports.ProtectedRouter = ProtectedRouter;
5668
6582
  exports.Spinner = Spinner;
6583
+ exports.apiTypes = academeApi;
5669
6584
  exports.cn = cn;
5670
- exports.createUserService = createUserService;
6585
+ exports.createAcademeApiClient = createAcademeApiClient;
6586
+ exports.types = index;
5671
6587
  exports.useAcademeAuth = useAcademeAuth;
5672
6588
  //# sourceMappingURL=index.js.map