academe-kit 0.3.0 → 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.
Files changed (2) hide show
  1. package/README.md +474 -6
  2. package/package.json +13 -5
package/README.md CHANGED
@@ -1,6 +1,45 @@
1
- # academe-kit
1
+ # Academe Kit
2
2
 
3
- A React component library built with Tailwind CSS and Storybook.
3
+ Official React SDK for the Academe ecosystem. Provides authentication, protected routes, API services, and UI components for building educational management applications.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/academe-kit.svg)](https://www.npmjs.com/package/academe-kit)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
- ## Usage
50
+ **Peer Dependencies:**
51
+
52
+ ```bash
53
+ npm install react react-dom
54
+ ```
55
+
56
+ ## Quick Start
12
57
 
13
58
  ```tsx
14
- import { Button } from 'academe-kit';
59
+ import { AcademeAuthProvider, ProtectedApp, useAcademeAuth } from 'academe-kit';
60
+ import 'academe-kit/dist/index.css';
15
61
 
16
62
  function App() {
17
- return <Button>Click me</Button>;
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.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
- "description": "A React component library with Tailwind CSS and Storybook",
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
- "components",
31
+ "academe",
32
+ "authentication",
33
+ "keycloak",
34
+ "education",
35
+ "sdk",
36
+ "protected-routes",
37
+ "rbac",
38
+ "role-based-access-control",
32
39
  "tailwind",
33
- "ui",
34
- "academe"
40
+ "components",
41
+ "api-client",
42
+ "typescript"
35
43
  ],
36
44
  "author": "tecnologia@academe.com.br",
37
45
  "license": "MIT",