academe-kit 0.2.9 → 0.3.1
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/README.md +474 -6
- package/package.json +13 -5
package/README.md
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Academe Kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Official React SDK for the Academe ecosystem. Provides authentication, protected routes, API services, and UI components for building educational management applications.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/academe-kit)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Features](#features)
|
|
11
|
+
- [Installation](#installation)
|
|
12
|
+
- [Quick Start](#quick-start)
|
|
13
|
+
- [Authentication](#authentication)
|
|
14
|
+
- [AcademeAuthProvider](#academeauthprovider)
|
|
15
|
+
- [useAcademeAuth Hook](#useacademeauth-hook)
|
|
16
|
+
- [Protected Components](#protected-components)
|
|
17
|
+
- [ProtectedApp](#protectedapp)
|
|
18
|
+
- [ProtectedComponent](#protectedcomponent)
|
|
19
|
+
- [ProtectedRouter](#protectedrouter)
|
|
20
|
+
- [API Services](#api-services)
|
|
21
|
+
- [UserService](#userservice)
|
|
22
|
+
- [InstitutionService](#institutionservice)
|
|
23
|
+
- [ClassroomService](#classroomservice)
|
|
24
|
+
- [ShiftService](#shiftservice)
|
|
25
|
+
- [SerieService](#serieservice)
|
|
26
|
+
- [OrganizationService](#organizationservice)
|
|
27
|
+
- [ReportService](#reportservice)
|
|
28
|
+
- [GuardianService](#guardianservice)
|
|
29
|
+
- [Roles](#roles)
|
|
30
|
+
- [UI Components](#ui-components)
|
|
31
|
+
- [Types](#types)
|
|
32
|
+
- [Development](#development)
|
|
33
|
+
- [License](#license)
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **Authentication**: Keycloak-based authentication with automatic token management
|
|
38
|
+
- **Protected Routes**: Role-based access control for routes and components
|
|
39
|
+
- **API Client**: Type-safe API client with OpenAPI-generated types
|
|
40
|
+
- **Services**: Pre-built services for Users, Institutions, Classrooms, and more
|
|
41
|
+
- **UI Components**: Reusable React components styled with Tailwind CSS
|
|
42
|
+
- **TypeScript**: Full TypeScript support with comprehensive type definitions
|
|
4
43
|
|
|
5
44
|
## Installation
|
|
6
45
|
|
|
@@ -8,29 +47,458 @@ A React component library built with Tailwind CSS and Storybook.
|
|
|
8
47
|
npm install academe-kit
|
|
9
48
|
```
|
|
10
49
|
|
|
11
|
-
|
|
50
|
+
**Peer Dependencies:**
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install react react-dom
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Quick Start
|
|
12
57
|
|
|
13
58
|
```tsx
|
|
14
|
-
import {
|
|
59
|
+
import { AcademeAuthProvider, ProtectedApp, useAcademeAuth } from 'academe-kit';
|
|
60
|
+
import 'academe-kit/dist/index.css';
|
|
15
61
|
|
|
16
62
|
function App() {
|
|
17
|
-
return
|
|
63
|
+
return (
|
|
64
|
+
<AcademeAuthProvider
|
|
65
|
+
realm="your-realm"
|
|
66
|
+
hubUrl="https://hub.academe.com.br"
|
|
67
|
+
clientId="your-client-id"
|
|
68
|
+
keycloakUrl="https://auth.academe.com.br"
|
|
69
|
+
apiBaseUrl="https://api.academe.com.br"
|
|
70
|
+
>
|
|
71
|
+
<ProtectedApp>
|
|
72
|
+
<MainApp />
|
|
73
|
+
</ProtectedApp>
|
|
74
|
+
</AcademeAuthProvider>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function MainApp() {
|
|
79
|
+
const { user, services } = useAcademeAuth();
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<div>
|
|
83
|
+
<h1>Welcome, {user?.name}</h1>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Authentication
|
|
90
|
+
|
|
91
|
+
### AcademeAuthProvider
|
|
92
|
+
|
|
93
|
+
The main provider that wraps your application and handles authentication with Keycloak.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { AcademeAuthProvider } from 'academe-kit';
|
|
97
|
+
|
|
98
|
+
<AcademeAuthProvider
|
|
99
|
+
realm="your-realm" // Keycloak realm name
|
|
100
|
+
hubUrl="https://hub.url" // Academe Hub URL
|
|
101
|
+
clientId="your-client-id" // Keycloak client ID
|
|
102
|
+
keycloakUrl="https://kc.url" // Keycloak server URL
|
|
103
|
+
apiBaseUrl="https://api.url" // Optional: API base URL (default: https://stg-api.academe.com.br)
|
|
104
|
+
>
|
|
105
|
+
{children}
|
|
106
|
+
</AcademeAuthProvider>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### useAcademeAuth Hook
|
|
110
|
+
|
|
111
|
+
Access authentication state and methods from any component within the provider.
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import { useAcademeAuth } from 'academe-kit';
|
|
115
|
+
|
|
116
|
+
function MyComponent() {
|
|
117
|
+
const {
|
|
118
|
+
// State
|
|
119
|
+
isInitialized, // boolean - Provider initialization status
|
|
120
|
+
user, // AcademeUser | null - Current user data
|
|
121
|
+
apiClient, // AcademeApiClient | null - Type-safe API client
|
|
122
|
+
services, // AcademeServices | null - All available services
|
|
123
|
+
|
|
124
|
+
// Methods
|
|
125
|
+
isAuthenticated, // () => boolean - Check authentication status
|
|
126
|
+
signOut, // () => void - Sign out and clear session
|
|
127
|
+
goToLogin, // (options?) => void - Redirect to login
|
|
128
|
+
refreshUserData, // () => Promise<void> - Refresh user data from API
|
|
129
|
+
|
|
130
|
+
// Role checks
|
|
131
|
+
hasRealmRole, // (role: string) => boolean
|
|
132
|
+
hasClientRole, // (role: string, resource?: string) => boolean
|
|
133
|
+
hasSchool, // (schoolId: string) => boolean
|
|
134
|
+
} = useAcademeAuth();
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<div>
|
|
138
|
+
{isAuthenticated() ? (
|
|
139
|
+
<p>Logged in as {user?.name}</p>
|
|
140
|
+
) : (
|
|
141
|
+
<button onClick={() => goToLogin()}>Login</button>
|
|
142
|
+
)}
|
|
143
|
+
</div>
|
|
144
|
+
);
|
|
18
145
|
}
|
|
19
146
|
```
|
|
20
147
|
|
|
148
|
+
#### User Object
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
interface AcademeUser {
|
|
152
|
+
id: string;
|
|
153
|
+
name: string;
|
|
154
|
+
email: string;
|
|
155
|
+
document?: string;
|
|
156
|
+
institutionRegistrations?: InstitutionRegistration[];
|
|
157
|
+
keycloakUser?: {
|
|
158
|
+
name: string;
|
|
159
|
+
lastName: string;
|
|
160
|
+
email: string;
|
|
161
|
+
};
|
|
162
|
+
// ... other fields from API
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Protected Components
|
|
167
|
+
|
|
168
|
+
### ProtectedApp
|
|
169
|
+
|
|
170
|
+
Wraps your entire application to ensure authentication before rendering. Shows a loading spinner during initialization and redirects unauthenticated users to login.
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
import { ProtectedApp } from 'academe-kit';
|
|
174
|
+
|
|
175
|
+
<ProtectedApp
|
|
176
|
+
requiredRealmRoles={['school_admin']} // Optional: Required realm roles
|
|
177
|
+
requiredClientRoles={['manage-users']} // Optional: Required client roles
|
|
178
|
+
>
|
|
179
|
+
<YourApp />
|
|
180
|
+
</ProtectedApp>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### ProtectedComponent
|
|
184
|
+
|
|
185
|
+
Conditionally renders children based on user roles. Returns empty fragment if user lacks required permissions.
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
import { ProtectedComponent } from 'academe-kit';
|
|
189
|
+
|
|
190
|
+
function Dashboard() {
|
|
191
|
+
return (
|
|
192
|
+
<div>
|
|
193
|
+
<h1>Dashboard</h1>
|
|
194
|
+
|
|
195
|
+
{/* Only visible to admins */}
|
|
196
|
+
<ProtectedComponent requiredRealmRoles={['admin_academe']}>
|
|
197
|
+
<AdminPanel />
|
|
198
|
+
</ProtectedComponent>
|
|
199
|
+
|
|
200
|
+
{/* Only visible to users with specific client role */}
|
|
201
|
+
<ProtectedComponent requiredClientRoles={['manage-reports']}>
|
|
202
|
+
<ReportsSection />
|
|
203
|
+
</ProtectedComponent>
|
|
204
|
+
</div>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### ProtectedRouter
|
|
210
|
+
|
|
211
|
+
Route-level protection that shows an unauthorized message instead of hiding content.
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
import { ProtectedRouter } from 'academe-kit';
|
|
215
|
+
|
|
216
|
+
function AdminPage() {
|
|
217
|
+
return (
|
|
218
|
+
<ProtectedRouter
|
|
219
|
+
requiredClientRoles={['admin-access']}
|
|
220
|
+
unauthorizedMessage="You don't have permission to access this page."
|
|
221
|
+
>
|
|
222
|
+
<AdminDashboard />
|
|
223
|
+
</ProtectedRouter>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## API Services
|
|
229
|
+
|
|
230
|
+
All services are available through the `useAcademeAuth` hook via `services` object.
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
const { services } = useAcademeAuth();
|
|
234
|
+
|
|
235
|
+
// Use any service
|
|
236
|
+
const users = await services.user.getUsers();
|
|
237
|
+
const institutions = await services.institution.getAll();
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### UserService
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
services.user.getMe() // Get current user
|
|
244
|
+
services.user.getUsers(params?) // List users with filters
|
|
245
|
+
services.user.getUserById(id) // Get user by ID
|
|
246
|
+
services.user.createUser(body) // Create new user
|
|
247
|
+
services.user.updateUser(id, body) // Update user
|
|
248
|
+
services.user.deleteUser(id) // Delete user
|
|
249
|
+
services.user.getUserGroups(id) // Get user's groups
|
|
250
|
+
services.user.getUserCertificates(id) // Get user's certificates
|
|
251
|
+
services.user.getUserInstitutions(id) // Get user's institutions
|
|
252
|
+
services.user.syncUser(id) // Sync with Keycloak
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### InstitutionService
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
services.institution.getAll() // List all institutions
|
|
259
|
+
services.institution.getById(id) // Get institution by ID
|
|
260
|
+
|
|
261
|
+
// Groups
|
|
262
|
+
services.institution.getGroups(institutionId)
|
|
263
|
+
services.institution.addGroup(institutionId, data)
|
|
264
|
+
services.institution.updateGroup(institutionId, groupId, data)
|
|
265
|
+
services.institution.removeGroup(institutionId, groupId)
|
|
266
|
+
|
|
267
|
+
// Classrooms
|
|
268
|
+
services.institution.getClassrooms(institutionId, options?)
|
|
269
|
+
services.institution.getClassroomById(institutionId, classroomId)
|
|
270
|
+
services.institution.addClassroom(institutionId, data)
|
|
271
|
+
services.institution.updateClassroom(institutionId, classroomId, data)
|
|
272
|
+
services.institution.removeClassroom(institutionId, classroomId)
|
|
273
|
+
|
|
274
|
+
// Users & Registrations
|
|
275
|
+
services.institution.getUsers(institutionId, options?)
|
|
276
|
+
services.institution.getRegistrations(institutionId)
|
|
277
|
+
services.institution.getRegistrationById(institutionId, registrationId)
|
|
278
|
+
services.institution.getRegistrationByUserId(institutionId, userId)
|
|
279
|
+
services.institution.registerUser(institutionId, data)
|
|
280
|
+
services.institution.updateRegistration(institutionId, registrationId, data)
|
|
281
|
+
services.institution.assignUserToClassroom(institutionId, registrationId, data)
|
|
282
|
+
services.institution.removeRegistration(institutionId, registrationId)
|
|
283
|
+
services.institution.getGroupUsers(institutionId)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### ClassroomService
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
services.classroom.getAll() // List all classrooms
|
|
290
|
+
services.classroom.getById(id) // Get classroom by ID
|
|
291
|
+
services.classroom.getByInstitution(institutionId, params?)
|
|
292
|
+
services.classroom.create(data) // Create classroom
|
|
293
|
+
services.classroom.update(id, data) // Update classroom
|
|
294
|
+
services.classroom.delete(id) // Delete classroom
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### ShiftService
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
services.shift.getAll() // List all shifts
|
|
301
|
+
services.shift.getById(id) // Get shift by ID
|
|
302
|
+
services.shift.create(data) // Create shift
|
|
303
|
+
services.shift.update(id, data) // Update shift
|
|
304
|
+
services.shift.delete(id) // Delete shift
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### SerieService
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
services.serie.getAll() // List all series
|
|
311
|
+
services.serie.getById(id) // Get serie by ID
|
|
312
|
+
services.serie.create(data) // Create serie
|
|
313
|
+
services.serie.update(id, data) // Update serie
|
|
314
|
+
services.serie.delete(id) // Delete serie
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### OrganizationService
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
services.organization.getAll(params?) // List with filters (name, type, isActive, etc.)
|
|
321
|
+
services.organization.getById(id) // Get organization by ID
|
|
322
|
+
services.organization.create(body) // Create organization
|
|
323
|
+
services.organization.update(id, body) // Update organization
|
|
324
|
+
services.organization.delete(id) // Delete organization
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### ReportService
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
// Dashboard
|
|
331
|
+
services.report.getDashboard(params?)
|
|
332
|
+
services.report.getDashboardByInstitution(id)
|
|
333
|
+
|
|
334
|
+
// Courses by Area
|
|
335
|
+
services.report.getCoursesByArea()
|
|
336
|
+
services.report.getCoursesByAreaByInstitution(id)
|
|
337
|
+
|
|
338
|
+
// Adhesion Rate
|
|
339
|
+
services.report.getAdhesionRate()
|
|
340
|
+
services.report.getAdhesionRateByInstitution(id)
|
|
341
|
+
|
|
342
|
+
// Recent Activities
|
|
343
|
+
services.report.getRecentActivities(params?) // period: '7days' | '30days' | 'all'
|
|
344
|
+
services.report.getRecentActivitiesByInstitution(id, params?)
|
|
345
|
+
|
|
346
|
+
// Top Students
|
|
347
|
+
services.report.getTopStudents(params) // filterType: 'nota' | 'engajamento' | 'conclusao'
|
|
348
|
+
services.report.getTopStudentsByInstitution(id, params)
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### GuardianService
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
services.guardian.getAll() // List all guardians
|
|
355
|
+
services.guardian.getById(id) // Get guardian by ID
|
|
356
|
+
services.guardian.create(data) // Create guardian
|
|
357
|
+
services.guardian.update(id, data) // Update guardian
|
|
358
|
+
services.guardian.delete(id) // Delete guardian
|
|
359
|
+
services.guardian.getUsers(id) // Get guardian's students
|
|
360
|
+
services.guardian.assignToUser(data) // Assign guardian to user
|
|
361
|
+
services.guardian.removeFromUser(guardianId, userId)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Roles
|
|
365
|
+
|
|
366
|
+
Pre-defined role constants for consistent role checking.
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
import { GLOBAL_ROLES, DASHBOARD_ROLES, BACKOFFICE_ROLES } from 'academe-kit';
|
|
370
|
+
|
|
371
|
+
// Available global roles
|
|
372
|
+
GLOBAL_ROLES.ADMIN_ACADEME // 'admin_academe'
|
|
373
|
+
GLOBAL_ROLES.SCHOOL_ADMIN // 'school_admin'
|
|
374
|
+
GLOBAL_ROLES.TEACHER // 'teacher'
|
|
375
|
+
GLOBAL_ROLES.STUDENT // 'student'
|
|
376
|
+
GLOBAL_ROLES.GUARDIAN // 'guardian'
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Usage with protected components:
|
|
380
|
+
|
|
381
|
+
```tsx
|
|
382
|
+
import { ProtectedComponent, GLOBAL_ROLES } from 'academe-kit';
|
|
383
|
+
|
|
384
|
+
<ProtectedComponent requiredRealmRoles={[GLOBAL_ROLES.ADMIN_ACADEME]}>
|
|
385
|
+
<AdminContent />
|
|
386
|
+
</ProtectedComponent>
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## UI Components
|
|
390
|
+
|
|
391
|
+
### Button
|
|
392
|
+
|
|
393
|
+
```tsx
|
|
394
|
+
import { Button } from 'academe-kit';
|
|
395
|
+
|
|
396
|
+
<Button variant="primary" size="md" onClick={handleClick}>
|
|
397
|
+
Click me
|
|
398
|
+
</Button>
|
|
399
|
+
|
|
400
|
+
// Variants: 'primary' | 'secondary' | 'outline'
|
|
401
|
+
// Sizes: 'sm' | 'md' | 'lg'
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Spinner
|
|
405
|
+
|
|
406
|
+
```tsx
|
|
407
|
+
import { Spinner } from 'academe-kit';
|
|
408
|
+
|
|
409
|
+
<Spinner />
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Utility: cn
|
|
413
|
+
|
|
414
|
+
Class name utility combining `clsx` and `tailwind-merge`:
|
|
415
|
+
|
|
416
|
+
```tsx
|
|
417
|
+
import { cn } from 'academe-kit';
|
|
418
|
+
|
|
419
|
+
<div className={cn('base-class', isActive && 'active-class', className)} />
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## Types
|
|
423
|
+
|
|
424
|
+
All types are exported for TypeScript support:
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
import type {
|
|
428
|
+
// Auth types
|
|
429
|
+
AcademeUser,
|
|
430
|
+
SecurityContextType,
|
|
431
|
+
KeycloakUser,
|
|
432
|
+
SecurityProviderProps,
|
|
433
|
+
AcademeKeycloakContextProps,
|
|
434
|
+
|
|
435
|
+
// Component props
|
|
436
|
+
ButtonProps,
|
|
437
|
+
|
|
438
|
+
// API types
|
|
439
|
+
types, // Entity types (User, Institution, Classroom, etc.)
|
|
440
|
+
apiTypes, // Full OpenAPI-generated types
|
|
441
|
+
} from 'academe-kit';
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Entity Types
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
import { types } from 'academe-kit';
|
|
448
|
+
|
|
449
|
+
type User = types.User;
|
|
450
|
+
type Institution = types.Institution;
|
|
451
|
+
type Classroom = types.Classroom;
|
|
452
|
+
type Organization = types.Organization;
|
|
453
|
+
type Serie = types.Serie;
|
|
454
|
+
type Shift = types.Shift;
|
|
455
|
+
```
|
|
456
|
+
|
|
21
457
|
## Development
|
|
22
458
|
|
|
23
459
|
```bash
|
|
24
460
|
# Install dependencies
|
|
25
461
|
npm install
|
|
26
462
|
|
|
27
|
-
# Run Storybook
|
|
463
|
+
# Run Storybook for component development
|
|
28
464
|
npm run dev
|
|
29
465
|
|
|
30
466
|
# Build the library
|
|
31
467
|
npm run build
|
|
468
|
+
|
|
469
|
+
# Build with watch mode
|
|
470
|
+
npm run build:watch
|
|
471
|
+
|
|
472
|
+
# Build Storybook static site
|
|
473
|
+
npm run build-storybook
|
|
474
|
+
|
|
475
|
+
# Generate API types from OpenAPI spec (requires API running locally)
|
|
476
|
+
npm run generate:api-types
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Project Structure
|
|
480
|
+
|
|
481
|
+
```
|
|
482
|
+
src/
|
|
483
|
+
├── components/ # UI components
|
|
484
|
+
│ ├── Button/
|
|
485
|
+
│ ├── ProtectedApp/
|
|
486
|
+
│ ├── ProtectedComponent/
|
|
487
|
+
│ ├── ProtectedRouter/
|
|
488
|
+
│ └── ui/
|
|
489
|
+
├── context/ # React context providers
|
|
490
|
+
│ └── SecurityProvider/
|
|
491
|
+
├── services/ # API services
|
|
492
|
+
├── roles/ # Role definitions
|
|
493
|
+
├── types/ # TypeScript types
|
|
494
|
+
├── lib/ # Utilities
|
|
495
|
+
└── index.ts # Main entry point
|
|
32
496
|
```
|
|
33
497
|
|
|
34
498
|
## License
|
|
35
499
|
|
|
36
500
|
MIT
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
504
|
+
Made with care by [Academe](https://academe.com.br)
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "academe-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Official React SDK for Academe ecosystem - Authentication, protected routes, API services, and UI components for educational management applications",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.esm.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
@@ -28,10 +28,18 @@
|
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
30
|
"react",
|
|
31
|
-
"
|
|
31
|
+
"academe",
|
|
32
|
+
"authentication",
|
|
33
|
+
"keycloak",
|
|
34
|
+
"education",
|
|
35
|
+
"sdk",
|
|
36
|
+
"protected-routes",
|
|
37
|
+
"rbac",
|
|
38
|
+
"role-based-access-control",
|
|
32
39
|
"tailwind",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
40
|
+
"components",
|
|
41
|
+
"api-client",
|
|
42
|
+
"typescript"
|
|
35
43
|
],
|
|
36
44
|
"author": "tecnologia@academe.com.br",
|
|
37
45
|
"license": "MIT",
|