thecore-auth 0.0.214 → 0.0.215

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 CHANGED
@@ -1,195 +1,1385 @@
1
- # THECORE-AUTH Documentation
1
+ # thecore-auth Documentation (English)
2
2
 
3
- ## Overview
3
+ > 🇮🇹 [Documentazione in Italiano](https://github.com/SantiGalvan/thecore-auth/blob/main/DOCUMENTATION_IT.md) | 🇪🇸 [Documentación en Español](https://github.com/SantiGalvan/thecore-auth/blob/main/DOCUMENTATION_ES.md)
4
4
 
5
- THECORE-AUTH is an authentication package for React applications. This documentation explains its configuration, usage, and available customization options.
5
+ > Version: 0.0.214 | License: MIT | Author: Santiago Galvan
6
6
 
7
- ## Configuration (`config.json`)
8
- After installation, create a `config.json` file inside the `public/` folder. This file contains the necessary configuration variables.
7
+ ---
8
+
9
+ ## What is thecore-auth?
10
+
11
+ **thecore-auth** is a React library that provides a complete authentication system based on **JWT (JSON Web Tokens)**, integrated with **React Router** and built for the **thecore** architecture pattern.
12
+
13
+ It ships ready-to-use:
14
+ - JWT login / logout with automatic token refresh
15
+ - Context providers for auth, loading, alerts, modals, forms, and routing
16
+ - A set of UI components (login form, modal, inputs, loaders, alerts)
17
+ - Utility hooks for device detection, form management, calendar, IndexedDB, and more
18
+ - Re-exports of the most common React Router APIs so you only import from one place
19
+
20
+ ---
21
+
22
+ ## Installation
23
+
24
+ ### 1. Create a new React project with Vite
25
+
26
+ ```bash
27
+ npm create vite@latest my-app -- --template react
28
+ cd my-app
29
+ npm install
30
+ ```
31
+
32
+ ### 2. Install thecore-auth
33
+
34
+ ```bash
35
+ npm install thecore-auth
36
+ ```
37
+
38
+ ### 3. Import the CSS
39
+
40
+ In your main CSS file (e.g. `src/index.css`) add:
41
+
42
+ ```css
43
+ @import url('../node_modules/thecore-auth/dist/thecore-auth.css');
44
+ ```
45
+
46
+ Or in `src/main.jsx`:
47
+
48
+ ```jsx
49
+ import 'thecore-auth/dist/thecore-auth.css';
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Required Configuration
55
+
56
+ Create a file `public/config.json` in your project. This file is loaded at runtime and drives the entire auth system:
9
57
 
10
- ### Example:
11
58
  ```json
12
59
  {
13
- "baseUri": "",
14
- "authenticatedEndpoint": "",
15
- "usersEndpoint": "",
16
- "heartbeatEndpoint": "",
17
- "firstPrivatePath": "/dashboard/",
60
+ "baseUri": "https://api.myapp.com",
61
+ "authenticatedEndpoint": "/auth/login",
62
+ "usersEndpoint": "/auth/me",
63
+ "heartbeatEndpoint": "/auth/refresh",
64
+ "firstPrivatePath": "/dashboard",
18
65
  "firstPrivateTitle": "Dashboard",
19
- "configRoutes": [
20
- {"path": "", "title": "", "element": ""}
21
- ],
22
- "infiniteSession": 60000,
23
- "alertTimeout": 5000,
24
- "axiosTimeout": 3000,
66
+ "defaultTitle": "My App",
67
+ "infiniteSession": false,
68
+ "timeDeducted": 60000,
69
+ "alertTimeout": 4000,
25
70
  "axiosErrors": {
26
- "unauthorized": "Accesso negato",
27
- "notFound": "Risorsa non trovata",
28
- "defaultMessage": "Errore sconosciuto"
71
+ "unauthorized": "Session expired. Please log in again.",
72
+ "notFound": "Resource not found.",
73
+ "defaultMessage": "An unexpected error occurred."
29
74
  },
30
75
  "clearLoginFormOnError": true,
31
76
  "autoLogin": false,
32
- "backendToken": "token-machine-to-machine",
33
- "isDebug": true
77
+ "backendToken": "",
78
+ "isDebug": false,
79
+ "tokenLog": false,
80
+ "isDevelopment": false,
81
+ "hasSessionKey": false,
82
+ "appKey": "myapp",
83
+ "showHeaderButton": false,
84
+ "useCustomLoginTimeout": false,
85
+ "customLoginTimeout": 10000,
86
+ "stopLoaderOnFinish": true,
87
+ "timerInfiniteSession": "",
88
+ "customDeviceType": "",
89
+ "sileoToastEnabled": false,
90
+ "sileoToastConfig": {
91
+ "position": "bottom-center",
92
+ "options": {
93
+ "fill": "#000000",
94
+ "duration": 2000,
95
+ "styles": {
96
+ "title": "text-white font-semibold",
97
+ "description": "text-white/75",
98
+ "badge": "bg-white/20"
99
+ }
100
+ }
101
+ },
102
+ "pwa": {
103
+ "enabled": false,
104
+ "promptOnLoad": false,
105
+ "customPrompt": false
106
+ },
107
+ "routes": [
108
+ { "path": "/dashboard", "title": "Dashboard" },
109
+ { "path": "/profile", "title": "Profile" }
110
+ ],
111
+ "configRoutes": []
34
112
  }
35
113
  ```
36
114
 
37
- #### Details of each key:
115
+ | Key | Type | Description |
116
+ |-----|------|-------------|
117
+ | `baseUri` | `string` | Base URL of the backend API |
118
+ | `authenticatedEndpoint` | `string` | Login endpoint path |
119
+ | `usersEndpoint` | `string` | Endpoint to fetch the authenticated user |
120
+ | `heartbeatEndpoint` | `string` | Endpoint to refresh the JWT token |
121
+ | `firstPrivatePath` | `string` | Redirect path after successful login |
122
+ | `firstPrivateTitle` | `string` | Title of the first private page |
123
+ | `infiniteSession` | `boolean` | If `true`, session never expires |
124
+ | `timeDeducted` | `number` | Milliseconds to subtract from token expiry for early refresh |
125
+ | `alertTimeout` | `number` | Duration (ms) to show alert notifications |
126
+ | `axiosErrors` | `object` | Custom error messages for 401, 404, and generic errors |
127
+ | `clearLoginFormOnError` | `boolean` | Clear login form fields when an error occurs |
128
+ | `autoLogin` | `boolean` | Enable machine-to-machine auto-login |
129
+ | `backendToken` | `string` | Token used for auto-login |
130
+ | `isDebug` | `boolean` | Enable debug logging to console |
131
+ | `sileoToastEnabled` | `boolean` | Enable Sileo mobile toast notifications |
132
+ | `sileoToastConfig` | `object` | Sileo toast options: `position`, `options.fill`, `options.duration`, `options.styles` |
133
+ | `hasSessionKey` | `boolean` | Generate a unique session key per browser tab |
134
+ | `appKey` | `string` | App prefix for the session key |
135
+ | `isDevelopment` | `boolean` | Development mode flag |
136
+ | `defaultTitle` | `string` | Default browser tab title |
137
+ | `routes` | `array` | Array of `{ path, title }` for automatic page title updates |
138
+ | `configRoutes` | `array` | Additional custom routes injected by the package |
139
+ | `tokenLog` | `boolean` | Log JWT token details to the console (debug) |
140
+ | `showHeaderButton` | `boolean` | Show a logout button in the default header |
141
+ | `useCustomLoginTimeout` | `boolean` | Enable a custom timeout for the login request |
142
+ | `customLoginTimeout` | `number` | Timeout (ms) for the login request when `useCustomLoginTimeout` is `true` |
143
+ | `stopLoaderOnFinish` | `boolean` | Stop the global loader when SmartLogin finishes its intro animation |
144
+ | `timerInfiniteSession` | `string` | Cron-like string for infinite-session heartbeat scheduling |
145
+ | `customDeviceType` | `string` | Override the detected device type (`'mobile'`, `'tablet'`, `'desktop'`) |
146
+ | `pwa` | `object` | PWA install prompt config: `enabled`, `promptOnLoad`, `customPrompt` |
147
+
148
+ ---
38
149
 
39
- - `baseUri`: The base URI of the back-end, used to compose the API URLs. This is the fixed part of the server's URL.
40
- - `authenticatedEndpoint`: The endpoint for user login and authentication. This URL is used to send the authentication request.
41
- - `usersEndpoint`: The endpoint to retrieve user information, such as the user list or details of the authenticated user.
42
- - `heartbeatEndpoint`: The endpoint for renewing the authentication token (heartbeat). This URL is used to keep the session active, preventing the token from expiring.
43
- - `firstPrivatePath`: The path to the first private route that the user sees after logging in. For example, it might be a page like the dashboard.
44
- - `firstPrivateTitle`: The title to display for the first private page, useful for defining the page name in the layout.
45
- - `configRoutes`: A list of new customizable routes to add to the application. Each route contains a `path` (URL), a `title` (title to display on the page), and an `element` (the element defining the route content, such as a React component).
46
- - `infiniteSession`: The number of milliseconds to subtract from the authentication token's expiration time to determine when the session should be considered expired and therefore renewed.
47
- - `alertTimeout`: The time, in milliseconds, for how long an alert (e.g., an on-screen notification) should remain visible.
48
- - `axiosTimeout`: The maximum duration (in milliseconds) that an Axios request can take before it times out.
49
- - `axiosErrors`: An object containing custom messages to display for specific Axios errors:
50
- - `unauthorized`: The message displayed when error code 401 (access denied) is returned from the request.
51
- - `notFound`: The message displayed when error code 404 (resource not found) is returned from the request.
52
- - `defaultMessage`: A generic message displayed for unspecified errors.
53
- - `clearLoginFormOnError`: A flag that indicates whether the login form data should be cleared in case of an error.
54
- - `autoLogin`: A flag that enables or disables auto-login. When set to true, the app will automatically log in with predefined credentials.
55
- - `backendToken`: The token for auto-login, used for automatic login in "machine-to-machine" mode or without user interaction.
56
- - `isDebug`: A flag that, when set to true, enables the display of debug logs (console.log) to assist with application debugging.
150
+ ## Quick Start Complete Setup
57
151
 
58
- Additional variables can be included and retrieved using the `useConfig` hook:
152
+ ### `src/main.jsx`
59
153
 
60
154
  ```jsx
61
- const { numOfRecords } = useConfig();
155
+ import { StrictMode } from 'react';
156
+ import { createRoot } from 'react-dom/client';
157
+ import { BrowserRouter } from 'thecore-auth';
158
+ import App from './App.jsx';
159
+ import 'thecore-auth/dist/thecore-auth.css';
160
+ import './index.css';
161
+
162
+ createRoot(document.getElementById('root')).render(
163
+ <StrictMode>
164
+ <BrowserRouter>
165
+ <App />
166
+ </BrowserRouter>
167
+ </StrictMode>
168
+ );
62
169
  ```
63
170
 
64
- ## Providers
171
+ ### `src/App.jsx`
65
172
 
66
- THECORE-AUTH offers various context providers to integrate into your application. They can be included individually or using the `ProvidersContainer`, which exclusively includes `LoadingProvider`, `ConfigProvider`, and `AlertProvider`. This helps keep the `main.jsx` file cleaner without manually declaring these providers.
173
+ ```jsx
174
+ import {
175
+ PackageRoutes,
176
+ ConfigProvider,
177
+ AuthProvider,
178
+ LoadingProvider,
179
+ AlertProvider,
180
+ LoginFormProvider,
181
+ ModalProvider,
182
+ RouteProvider
183
+ } from 'thecore-auth';
67
184
 
68
- ### Example: Individual Providers
185
+ // Your private pages
186
+ import Dashboard from './pages/Dashboard';
69
187
 
70
- ```jsx
71
- createRoot(document.getElementById('root')).render(
72
- <StrictMode>
73
- <BrowserRouter>
188
+ // Define your private routes
189
+ const privateRoutes = [
190
+ { path: '/dashboard', element: <Dashboard /> }
191
+ ];
192
+
193
+ export default function App() {
194
+ return (
195
+ <ConfigProvider>
74
196
  <LoadingProvider>
75
- <ConfigProvider>
76
- <AlertProvider>
77
- <AuthProvider>
78
- <LoginFormProvider>
79
- <App />
80
- </LoginFormProvider>
81
- </AuthProvider>
82
- </AlertProvider>
83
- </ConfigProvider>
197
+ <AlertProvider>
198
+ <AuthProvider>
199
+ <LoginFormProvider>
200
+ <ModalProvider>
201
+ <RouteProvider privateRoutes={privateRoutes} publicRoutes={[]}>
202
+ <PackageRoutes
203
+ firstPrivateElement={<Dashboard />}
204
+ />
205
+ </RouteProvider>
206
+ </ModalProvider>
207
+ </LoginFormProvider>
208
+ </AuthProvider>
209
+ </AlertProvider>
84
210
  </LoadingProvider>
85
- </BrowserRouter>
86
- </StrictMode>,
87
- )
211
+ </ConfigProvider>
212
+ );
213
+ }
88
214
  ```
89
215
 
90
- ### Example: ProvidersContainer
216
+ ---
217
+
218
+ ## Context Providers & Hooks
219
+
220
+ ### ConfigProvider / useConfig
221
+
222
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/contexts/ConfigProvider.md)
223
+
224
+ Loads and exposes the runtime `config.json` configuration. Also provides IndexedDB utilities and the current date helper.
91
225
 
92
226
  ```jsx
93
- createRoot(document.getElementById('root')).render(
94
- <StrictMode>
95
- <BrowserRouter>
96
- <ProvidersContainer>
97
- <AuthProvider>
98
- <LoginFormProvider>
99
- <App />
100
- </LoginFormProvider>
101
- </AuthProvider>
102
- </ProvidersContainer>
103
- </BrowserRouter>
104
- </StrictMode>,
105
- )
227
+ import { useConfig } from 'thecore-auth';
228
+
229
+ function MyComponent() {
230
+ const { config, version, setCurrentDate, getDataIndexedDB } = useConfig();
231
+
232
+ return <p>API base: {config.baseUri}</p>;
233
+ }
234
+ ```
235
+
236
+ **Returned values:**
237
+
238
+ | Name | Type | Description |
239
+ |------|------|-------------|
240
+ | `config` | `object` | All values from `config.json` |
241
+ | `version` | `string` | Package version |
242
+ | `setCurrentDate()` | `function` | Returns current date as `dd/mm/yyyy hh:mm:ss` |
243
+ | `openIndexedDB(db, store)` | `function` | Open an IndexedDB connection |
244
+ | `getDataIndexedDB(db, store, key)` | `function` | Read a value from IndexedDB |
245
+ | `setDataIndexedDB(db, store, data)` | `function` | Write a value to IndexedDB |
246
+ | `generateUniqueId(db, store)` | `function` | Generate a unique numeric ID |
247
+ | `setDataWithAutoId(db, store, data)` | `function` | Save data with an auto-generated ID |
248
+ | `activity` | `object` | User activity info (visibility, focus) |
249
+ | `sessionKey` | `string \| undefined` | Unique session key (if `hasSessionKey: true`) |
250
+
251
+ ---
252
+
253
+ ### AuthProvider / useAuth
254
+
255
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/contexts/AuthProvider.md)
256
+
257
+ Manages JWT authentication state, token refresh, and login/logout.
258
+
259
+ ```jsx
260
+ import { useAuth } from 'thecore-auth';
261
+
262
+ function Header() {
263
+ const { isAuthenticated, logout } = useAuth();
264
+
265
+ return isAuthenticated
266
+ ? <button onClick={logout}>Logout</button>
267
+ : <p>Not logged in</p>;
268
+ }
269
+ ```
270
+
271
+ **Returned values:**
272
+
273
+ | Name | Type | Description |
274
+ |------|------|-------------|
275
+ | `isAuthenticated` | `boolean \| null` | Auth state (`null` = loading) |
276
+ | `login(e?, formData)` | `function` | Submit login credentials |
277
+ | `logout()` | `function` | Clear session and redirect to login |
278
+ | `createAxiosInstances(...)` | `function` | Create axios instance with Bearer token |
279
+ | `fetchHeartbeat()` | `function` | Manually refresh the JWT token |
280
+ | `getTokenExpiry(token?)` | `function` | Get remaining ms before token expires |
281
+ | `checkTokenValidity(token)` | `function` | Returns `true` if token is still valid |
282
+ | `timeoutToken` | `number` | Ms until next token refresh |
283
+ | `sessionTimeout` | `number` | Ms until session expires |
284
+
285
+ ---
286
+
287
+ ### LoadingProvider / useLoading
288
+
289
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/contexts/LoadingProvider.md)
290
+
291
+ Global loading spinner visible over the entire application.
292
+
293
+ ```jsx
294
+ import { useLoading } from 'thecore-auth';
295
+
296
+ function SaveButton() {
297
+ const { setIsLoading } = useLoading();
298
+
299
+ const handleSave = async () => {
300
+ setIsLoading(true);
301
+ await saveData();
302
+ setIsLoading(false);
303
+ };
304
+
305
+ return <button onClick={handleSave}>Save</button>;
306
+ }
307
+ ```
308
+
309
+ **Returned values:**
310
+
311
+ | Name | Type | Description |
312
+ |------|------|-------------|
313
+ | `isLoading` | `boolean` | Current loading state |
314
+ | `setIsLoading(bool)` | `function` | Show or hide the spinner |
315
+ | `showLoadingFor(ms?, props?)` | `function` | Show spinner for a fixed duration |
316
+ | `loadingProps` | `object` | Props passed to `Loading` component |
317
+
318
+ ---
319
+
320
+ ### AlertProvider / useAlert
321
+
322
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/contexts/AlertProvider.md)
323
+
324
+ Displays in-app notifications of type `danger`, `info`, `success`, or `warning`.
325
+
326
+ ```jsx
327
+ import { useAlert } from 'thecore-auth';
328
+
329
+ function SubmitForm() {
330
+ const { activeAlert } = useAlert();
331
+
332
+ const handleSubmit = async () => {
333
+ try {
334
+ await submitData();
335
+ activeAlert('success', 'Data saved successfully!');
336
+ } catch {
337
+ activeAlert('danger', 'Something went wrong.');
338
+ }
339
+ };
340
+
341
+ return <button onClick={handleSubmit}>Submit</button>;
342
+ }
106
343
  ```
107
344
 
108
- ## Modals and Modal Management
345
+ **Returned values:**
109
346
 
110
- `THECORE-AUTH` uses a centralized modal system to manage dialog windows, forms, and multi-step flows in a simple and dynamic way. The modal management is fully controlled via Context, allowing modals to be opened from anywhere in the application with customizable content and behavior.
347
+ | Name | Type | Description |
348
+ |------|------|-------------|
349
+ | `showAlert` | `boolean` | Whether the alert is visible |
350
+ | `typeAlert` | `string` | Alert type (`danger`, `info`, `success`, `warning`) |
351
+ | `messageAlert` | `string` | Alert message text |
352
+ | `activeAlert(type, message)` | `function` | Show an alert |
353
+ | `closeAlert()` | `function` | Dismiss the current alert |
111
354
 
112
- For more details on usage, customization, and advanced use cases of the modal system, please refer to the [dedicated modal documentation](./documentation/Modal%20documentation.md).
355
+ ---
113
356
 
114
- ## Routing
357
+ ### ModalProvider / useModal
115
358
 
116
- ### `RouteProvider`
359
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/contexts/ModalProvider.md)
117
360
 
118
- Used to manage public and private routes. Routes are passed as an array.
361
+ Centralized modal system supporting `submit`, `delete`, and `custom` modal types.
119
362
 
120
363
  ```jsx
364
+ import { useModal } from 'thecore-auth';
365
+
366
+ function UserList() {
367
+ const { openModal, closeModal } = useModal();
368
+
369
+ const handleDelete = (user) => {
370
+ openModal({
371
+ type: 'delete',
372
+ title: 'Delete user',
373
+ item: user,
374
+ onConfirm: async () => {
375
+ await deleteUser(user.id);
376
+ closeModal();
377
+ }
378
+ });
379
+ };
380
+
381
+ return <button onClick={() => handleDelete(user)}>Delete</button>;
382
+ }
383
+ ```
384
+
385
+ **`openModal` options:**
386
+
387
+ | Property | Type | Description |
388
+ |----------|------|-------------|
389
+ | `type` | `'submit' \| 'delete' \| 'custom'` | Modal behavior type |
390
+ | `title` | `string` | Modal header title |
391
+ | `component` | `ReactNode` | Content to render inside the modal |
392
+ | `modalData` | `object` | Initial form data |
393
+ | `onConfirm` | `function` | Confirm callback |
394
+ | `onCancel` | `function` | Cancel callback |
395
+ | `formId` | `string` | ID of the form inside the modal |
396
+ | `item` | `any` | Entity the modal is acting upon |
397
+ | `style` | `object` | Custom styles |
398
+
399
+ ---
400
+
401
+ ### LoginFormProvider / useLoginForm
402
+
403
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/contexts/LoginFormProvider.md)
404
+
405
+ Manages the login form state and customization options.
406
+
407
+ ```jsx
408
+ import { LoginFormProvider } from 'thecore-auth';
409
+
410
+ <LoginFormProvider
411
+ title="Sign In"
412
+ label="Email address"
413
+ buttonText="Log in"
414
+ LogoImg={MyLogo}
415
+ >
416
+ {/* children */}
417
+ </LoginFormProvider>
418
+ ```
419
+
420
+ **Provider props:**
421
+
422
+ | Prop | Type | Default | Description |
423
+ |------|------|---------|-------------|
424
+ | `title` | `string` | `'Accedi'` | Form card title |
425
+ | `label` | `string` | `'Email'` | Email field label |
426
+ | `type` | `string` | `'email'` | Email field input type |
427
+ | `placeholder` | `string` | — | Email field placeholder |
428
+ | `buttonText` | `string` | `'Accedi'` | Submit button text |
429
+ | `LogoImg` | `ReactNode` | — | Logo component |
430
+ | `styleCardForm` | `object` | — | Card container styles |
431
+ | `styleLogo` | `object` | — | Logo styles |
432
+ | `overrideStyle` | `object` | — | CSS override object |
433
+ | `customVersion` | `string` | — | Custom version string |
434
+
435
+ ---
436
+
437
+ ### RouteProvider / useRoutesInjection
438
+
439
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/contexts/RouteProvider.md)
440
+
441
+ Registers public and private routes to be rendered by `PackageRoutes`.
442
+
443
+ ```jsx
444
+ import { RouteProvider } from 'thecore-auth';
445
+
121
446
  const privateRoutes = [
122
- { path: 'test/:id', element: <TestPage /> }
447
+ { path: '/profile', element: <ProfilePage /> },
448
+ { path: '/settings', element: <SettingsPage /> }
123
449
  ];
450
+
124
451
  const publicRoutes = [
125
- { path: 'publictest', element: <TestPublicPage /> }
452
+ { path: '/about', element: <AboutPage /> }
126
453
  ];
127
454
 
128
455
  <RouteProvider privateRoutes={privateRoutes} publicRoutes={publicRoutes}>
129
- <PackageRoutes />
456
+ <PackageRoutes firstPrivateElement={<Dashboard />} />
130
457
  </RouteProvider>
131
458
  ```
132
459
 
133
- ### `PackageRoutes` Props
460
+ ---
461
+
462
+ ## Components
463
+
464
+ ### PackageRoutes
465
+
466
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/routing/PackageRoutes.md)
467
+
468
+ The main routing component. Renders public routes, the login page, and wraps private routes with authentication guards.
469
+
470
+ ```jsx
471
+ <PackageRoutes
472
+ firstPrivateElement={<Dashboard />}
473
+ globalLayout={MyLayout}
474
+ headerComponent={MyHeader}
475
+ footerComponent={MyFooter}
476
+ showHeaderOnLogin={false}
477
+ showFooterOnLogin={false}
478
+ headerExcludedRoutes={['/settings']}
479
+ footerExcludedRoutes={[]}
480
+ />
481
+ ```
482
+
483
+ | Prop | Type | Description |
484
+ |------|------|-------------|
485
+ | `firstPrivateElement` | `ReactNode` | Component for the first private route |
486
+ | `globalLayout` | `ReactNode` | Custom layout wrapper component |
487
+ | `headerComponent` | `ReactNode` | Header component |
488
+ | `footerComponent` | `ReactNode` | Footer component |
489
+ | `showHeaderOnLogin` | `boolean` | Show header on the login page |
490
+ | `showFooterOnLogin` | `boolean` | Show footer on the login page |
491
+ | `headerExcludedRoutes` | `string[]` | Paths where the header is hidden |
492
+ | `footerExcludedRoutes` | `string[]` | Paths where the footer is hidden |
493
+ | `privateProvider` | `ReactNode` | Extra provider wrapping private routes |
494
+ | `customProvider` | `ReactNode` | Extra provider wrapping all routes |
495
+ | `promptComponent` | `ReactNode` | Navigation prompt component |
496
+
497
+ ---
498
+
499
+ ### Login
500
+
501
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/pages/Login.md)
502
+
503
+ Pre-built login page. Automatically used by `PackageRoutes` at the `/` path.
504
+
505
+ ---
506
+
507
+ ### SmartLogin
508
+
509
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/pages/SmartLogin.md)
510
+
511
+ PWA-ready login page with advanced features. Drop-in replacement for `Login` with full
512
+ customization, accessibility improvements, and better mobile support.
513
+
514
+ ```jsx
515
+ import { SmartLogin } from 'thecore-auth';
516
+
517
+ <SmartLogin
518
+ Logo={MyLogo}
519
+ backgroundSrc="/images/bg.jpg"
520
+ overlayOpacity={0.5}
521
+ overlayColor="#f1f1f1"
522
+ cardVariant="glass"
523
+ cardPosition="center"
524
+ logoPosition="left"
525
+ showPasswordToggle={true}
526
+ animateEntrance={true}
527
+ />
528
+ ```
529
+
530
+ | Prop | Type | Default | Description |
531
+ |------|------|---------|-------------|
532
+ | `Logo` | `ComponentType` | — | SVG logo component |
533
+ | `backgroundSrc` | `string` | `undefined` | Custom background image URL |
534
+ | `overlayOpacity` | `number` | `0.5` | Background overlay opacity (0.0–1.0) |
535
+ | `overlayColor` | `string` | `'#f1f1f1'` | Background overlay base color |
536
+ | `cardVariant` | `'solid' \| 'glass' \| 'minimal'` | `'solid'` | Card style variant |
537
+ | `cardPosition` | `'center' \| 'left' \| 'right'` | `'center'` | Horizontal card position |
538
+ | `logoPosition` | `'left' \| 'top'` | `'left'` | Logo position on desktop |
539
+ | `showPasswordToggle` | `boolean` | `true` | Show password visibility toggle |
540
+ | `animateEntrance` | `boolean` | `true` | Animate card on mount |
541
+
542
+ All `overrideStyle` values from `LoginFormProvider` continue to work with `SmartLogin`.
543
+
544
+ ---
545
+
546
+ ### LoginForm
547
+
548
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/LoginForm.md)
549
+
550
+ Login form UI built on top of `LoginFormProvider`. Can be used standalone inside a custom layout.
551
+
552
+ ```jsx
553
+ import { LoginForm } from 'thecore-auth';
554
+
555
+ <LoginForm />
556
+ ```
557
+
558
+ ---
559
+
560
+ ### DefaultLayout
561
+
562
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/layouts/DefaultLayout.md)
563
+
564
+ Layout wrapper that renders `Loading`, `Alert`, `Modal`, and an optional toast layer alongside the page content.
565
+
566
+ ```jsx
567
+ import { DefaultLayout } from 'thecore-auth';
568
+
569
+ <DefaultLayout
570
+ headerComponent={<MyHeader />}
571
+ footerComponent={<MyFooter />}
572
+ isMain={true}
573
+ />
574
+ ```
575
+
576
+ ---
577
+
578
+ ### Input / InputLabel
579
+
580
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/Input.md) | [InputLabel](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/InputLabel.md)
581
+
582
+ Basic form input and label components.
583
+
584
+ ```jsx
585
+ import { Input, InputLabel } from 'thecore-auth';
586
+
587
+ <InputLabel label="Name" labelId="name" />
588
+ <Input
589
+ inputId="name"
590
+ inputType="text"
591
+ inputValue={name}
592
+ inputChange={(e) => setName(e.target.value)}
593
+ inputPlaceholder="Enter your name"
594
+ />
595
+ ```
596
+
597
+ ---
598
+
599
+ ### InputDate / InputStartEndDate
600
+
601
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/InputDate.md) | [InputStartEndDate](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/InputStartEndDate.md)
602
+
603
+ Date picker and date range picker components.
604
+
605
+ ```jsx
606
+ import { InputDate, InputStartEndDate } from 'thecore-auth';
607
+
608
+ // Single date
609
+ <InputDate
610
+ id="date"
611
+ name="date"
612
+ value={date}
613
+ onChange={(e) => setDate(e.target.value)}
614
+ title="Select date"
615
+ />
616
+
617
+ // Date range
618
+ <InputStartEndDate
619
+ startId="start"
620
+ endId="end"
621
+ startValue={startDate}
622
+ endValue={endDate}
623
+ onChange={handleChange}
624
+ startTitle="From"
625
+ endTitle="To"
626
+ />
627
+ ```
628
+
629
+ ---
630
+
631
+ ### FileDropzone
632
+
633
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/FileDropzone.md)
634
+
635
+ Drag-and-drop file upload area.
636
+
637
+ ```jsx
638
+ import { FileDropzone } from 'thecore-auth';
639
+
640
+ <FileDropzone
641
+ id="upload"
642
+ onFilesSelect={(files) => console.log(files)}
643
+ />
644
+ ```
645
+
646
+ ---
647
+
648
+ ### SwitchRadio
649
+
650
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/SwitchRadio.md)
651
+
652
+ A toggle switch (controlled or uncontrolled).
653
+
654
+ ```jsx
655
+ import { SwitchRadio } from 'thecore-auth';
656
+
657
+ <SwitchRadio value={active} onChange={(val) => setActive(val)} />
658
+ ```
659
+
660
+ ---
661
+
662
+ ### SingleSelect / MultiSelect
663
+
664
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/SingleSelect.md) | [MultiSelect](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/MultiSelect.md)
665
+
666
+ Dropdown select components.
667
+
668
+ ```jsx
669
+ import { SingleSelect, MultiSelect } from 'thecore-auth';
670
+
671
+ // Single
672
+ <SingleSelect
673
+ options={[{ label: 'Italy', value: 'IT' }, { label: 'France', value: 'FR' }]}
674
+ value={selected}
675
+ onChange={setSelected}
676
+ />
677
+
678
+ // Multi
679
+ <MultiSelect
680
+ label="Countries"
681
+ items={countries}
682
+ value={selectedCountries}
683
+ displayKey="label"
684
+ valueKey="value"
685
+ idKey="id"
686
+ updateFilter={setSelectedCountries}
687
+ />
688
+ ```
689
+
690
+ ---
691
+
692
+ ### Loading / LoadingComponent / Loader / LogoLoader
693
+
694
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/Loading.md) | [LoadingComponent](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/LoadingComponent.md) | [Loader](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/Loader.md) | [LogoLoader](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/LogoLoader.md)
695
+
696
+ Loading state components.
697
+
698
+ ```jsx
699
+ import { Loader } from 'thecore-auth';
700
+
701
+ <Loader
702
+ Logo={MyLogo}
703
+ spinnerColor="#3b82f6"
704
+ containerSize="100vh"
705
+ />
706
+ ```
707
+
708
+ ---
709
+
710
+ ### Alert
711
+
712
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/components/Alert.md)
713
+
714
+ Notification banner controlled by `AlertProvider`. Renders automatically when `activeAlert` is called.
715
+
716
+ ---
717
+
718
+ ### AuthPage / AuthAdmin
719
+
720
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/middlewares/AuthPage.md) | [AuthAdmin](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/middlewares/AuthAdmin.md)
721
+
722
+ Route guards for authentication and admin roles.
723
+
724
+ ```jsx
725
+ import { AuthPage, AuthAdmin } from 'thecore-auth';
726
+
727
+ // In your routes:
728
+ { path: '/dashboard', element: <AuthPage><Dashboard /></AuthPage> }
729
+ { path: '/admin', element: <AuthAdmin><AdminPanel /></AuthAdmin> }
730
+ ```
731
+
732
+ ---
733
+
734
+ ## Hooks
735
+
736
+ ### useStorage
737
+
738
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useStorage.md)
739
+
740
+ State synchronized with `localStorage`.
741
+
742
+ ```jsx
743
+ import { useStorage } from 'thecore-auth';
744
+
745
+ const [theme, setTheme, removeTheme] = useStorage('light', 'app-theme');
746
+ ```
747
+
748
+ | Parameter | Type | Description |
749
+ |-----------|------|-------------|
750
+ | `initialValue` | `any` | Default value if key is not in storage |
751
+ | `itemKey` | `string` | localStorage key |
752
+
753
+ Returns `[state, setState, remove]`.
754
+
755
+ ---
756
+
757
+ ### useAuthStorage
758
+
759
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useAuthStorage.md)
760
+
761
+ Manages `accessToken` and `user` in localStorage.
762
+
763
+ ```jsx
764
+ import { useAuthStorage } from 'thecore-auth';
765
+
766
+ const { token, user, setToken, setUser, storageLogout } = useAuthStorage();
767
+ ```
768
+
769
+ ---
770
+
771
+ ### useIndexedDB
772
+
773
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useIndexedDB.md)
774
+
775
+ Full CRUD operations on an IndexedDB object store.
776
+
777
+ ```jsx
778
+ import { useIndexedDB } from 'thecore-auth';
779
+
780
+ const db = useIndexedDB('myDatabase', 'myStore');
781
+
782
+ await db.set({ id: 1, name: 'Item' });
783
+ const item = await db.get(1);
784
+ await db.remove(1);
785
+ ```
786
+
787
+ | Method | Description |
788
+ |--------|-------------|
789
+ | `get(key)` | Read a record by key |
790
+ | `getAll()` | Read all records |
791
+ | `set(data)` | Write a record |
792
+ | `setWithAutoId(data)` | Write with auto-generated ID |
793
+ | `remove(id)` | Delete a record by ID |
794
+ | `clear()` | Delete all records |
795
+ | `isReady` | `boolean` — DB is ready to use |
796
+
797
+ ---
798
+
799
+ ### useForm
800
+
801
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useForm.md)
802
+
803
+ Form state management with file upload support.
804
+
805
+ ```jsx
806
+ import { useForm } from 'thecore-auth';
807
+
808
+ const { values, handleChange, files, addFiles, resetForm } = useForm({
809
+ name: '',
810
+ email: ''
811
+ });
812
+
813
+ <input
814
+ value={values.name}
815
+ onChange={(e) => handleChange('name', e.target.value)}
816
+ />
817
+ ```
818
+
819
+ | Returned value | Type | Description |
820
+ |----------------|------|-------------|
821
+ | `values` | `object` | Current form values |
822
+ | `handleChange(field, value)` | `function` | Update a field value |
823
+ | `files` | `object` | File inputs by field name |
824
+ | `previews` | `object` | Preview URLs for image files |
825
+ | `addFiles(field, fileList)` | `function` | Append files to a field |
826
+ | `replaceFiles(field, fileList)` | `function` | Replace files in a field |
827
+ | `removeFile(field, index)` | `function` | Remove a file by index |
828
+ | `setValues` | `function` | Override the entire form state |
829
+ | `resetForm()` | `function` | Reset to initial values |
830
+
831
+ ---
832
+
833
+ ### useDevice
834
+
835
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useDevice.md)
836
+
837
+ Detect the user's device type, OS, and browser.
838
+
839
+ ```jsx
840
+ import { useDevice } from 'thecore-auth';
841
+
842
+ const { isMobile, isDesktop, os, browser } = useDevice();
843
+ ```
844
+
845
+ | Returned value | Type | Description |
846
+ |----------------|------|-------------|
847
+ | `type` | `string` | `'mobile'`, `'tablet'`, or `'desktop'` |
848
+ | `os` | `string` | Operating system name |
849
+ | `browser` | `string` | Browser name |
850
+ | `vendor` | `string` | Device manufacturer |
851
+ | `model` | `string` | Device model |
852
+ | `isMobile` | `boolean` | — |
853
+ | `isTablet` | `boolean` | — |
854
+ | `isDesktop` | `boolean` | — |
855
+ | `isIPhone` | `boolean` | — |
856
+ | `isIPad` | `boolean` | — |
857
+ | `isAndroid` | `boolean` | — |
858
+
859
+ ---
860
+
861
+ ### useOrientation
862
+
863
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useOrientation.md)
864
+
865
+ Detect portrait or landscape orientation.
866
+
867
+ ```jsx
868
+ import { useOrientation } from 'thecore-auth';
869
+
870
+ const orientation = useOrientation(); // 'portrait' | 'landscape'
871
+ ```
872
+
873
+ ---
874
+
875
+ ### useViewportHeight
876
+
877
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useViewportHeight.md)
878
+
879
+ Reads the actual viewport height and exposes it as a CSS variable `--vh`.
880
+
881
+ ```jsx
882
+ import { useViewportHeight } from 'thecore-auth';
883
+
884
+ const { height, vh } = useViewportHeight({ getValues: true });
885
+ ```
886
+
887
+ ---
888
+
889
+ ### useSafeArea
890
+
891
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useSafeArea.md)
892
+
893
+ Adds the `with-safe-area` class to `<body>` when on devices with a notch or safe area insets (iPhone X+, etc.).
894
+
895
+ ```jsx
896
+ import { useSafeArea } from 'thecore-auth';
897
+
898
+ useSafeArea(['/login']); // exclude these paths
899
+ ```
900
+
901
+ ---
134
902
 
135
- | Prop | Type | Default | Description |
136
- | ---------------------- | --------- | --------------- | ----------------------------------------------------------- |
137
- | `firstPrivateElement` | Component | `<Dashboard />` | First component of the private route |
138
- | `firstPrivatePath` | String | `/dashboard/` | Path of the first private route (configurable in `config.json`) |
139
- | `logoImg` | Component | `MyWharehouse` | SVG component for the login logo |
140
- | `globalLayout` | Component | `null` | Custom global layout |
141
- | `isMain` | Boolean | `false` | Keeps the `main` tag in `DefaultLayout` |
142
- | `headerComponent` | Component | `null` | Header component |
143
- | `showHeaderOnLogin` | Boolean | `false` | Displays the header on the login page |
144
- | `headerExcludedRoutes` | Array | `[]` | Routes where the header should not be displayed |
145
- | `footerComponent` | Component | `null` | Footer component |
146
- | `showFooterOnLogin` | Boolean | `false` | Displays the footer on the login page |
147
- | `footerExcludedRoutes` | Array | `[]` | Routes where the footer should not be displayed |
903
+ ### useClickOutside
148
904
 
149
- ## Layout Management
905
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useClickOutside.md)
150
906
 
151
- `DefaultLayout` has been updated to support new props related to the header and footer.
907
+ Fire a callback when the user clicks outside a referenced element.
152
908
 
153
- ### Header Props
909
+ ```jsx
910
+ import { useClickOutside } from 'thecore-auth';
911
+ import { useRef } from 'react';
154
912
 
155
- - `headerComponent`: Component to be used as a header
156
- - `showHeaderOnLogin`: Boolean flag to show the header on the login page
157
- - `headerExcludedRoutes`: Array of routes where the header should not appear
913
+ const ref = useRef();
914
+ useClickOutside(ref, () => setOpen(false));
158
915
 
159
- ### Footer Props
916
+ <div ref={ref}>...</div>
917
+ ```
160
918
 
161
- - `footerComponent`: Component to be used as a footer
162
- - `showFooterOnLogin`: Boolean flag to show the footer on the login page
163
- - `footerExcludedRoutes`: Array of routes where the footer should not appear
919
+ ---
164
920
 
165
- ## Customizing Login
921
+ ### UsePageTitle
166
922
 
167
- To customize the Login, use the states provided by `LoginFormContext`. Some values can be directly modified, while others must be adjusted via CSS variables.
923
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/UsePageTitle.md)
168
924
 
169
- Example usage:
170
- ```javascript
171
- const { setButtonText, setOverrideStyle } = useLoginForm();
925
+ Update `document.title` automatically based on the current route.
172
926
 
173
- useLayoutEffect(() => {
174
- setButtonText('LOGIN');
175
- setOverrideStyle({
176
- container: 'container mx-auto flex items-center justify-center h-screen',
177
- cardForm: 'bg-[#A0D8F1] flex p-24 rounded-full h-[900px] w-[900px]',
178
- form: 'flex items-center justify-center flex-col basis-1/2'
179
- });
180
- }, []);
927
+ ```jsx
928
+ import { UsePageTitle } from 'thecore-auth';
929
+
930
+ // Inside your layout component:
931
+ UsePageTitle(routes, 'My App');
181
932
  ```
182
933
 
183
- ## Styling
184
- To apply package styles, import the CSS into your main styles file:
934
+ ---
935
+
936
+ ### useToast
937
+
938
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useToast.md)
939
+
940
+ Mobile-optimized toast notifications via the Sileo library.
941
+
942
+ ```jsx
943
+ import { useToast } from 'thecore-auth';
944
+
945
+ const toast = useToast();
946
+
947
+ toast.success('Saved!', 'Your changes have been saved.');
948
+ toast.error('Error', 'Something went wrong.');
949
+ toast.info('Notice', 'Please review the form.');
950
+ toast.warning('Warning', 'This action cannot be undone.');
951
+
952
+ // Promise toast
953
+ toast.promise(fetchData(), {
954
+ loading: 'Loading...',
955
+ success: 'Done!',
956
+ error: 'Failed'
957
+ });
958
+ ```
959
+
960
+ ---
961
+
962
+ ### useCalendar
963
+
964
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/hooks/useCalendar.md)
965
+
966
+ Calendar utilities with public holiday detection.
967
+
968
+ ```jsx
969
+ import { useCalendar } from 'thecore-auth';
970
+
971
+ const { isTodayHoliday, isHoliday, getDaysInMonth } = useCalendar(2025, 'IT');
972
+
973
+ const isHol = isTodayHoliday();
974
+ const days = getDaysInMonth(0, 2025); // January 2025
975
+ ```
976
+
977
+ | Returned value | Description |
978
+ |----------------|-------------|
979
+ | `holidays` | Array of holiday objects |
980
+ | `holidayMap` | Map for O(1) holiday lookup |
981
+ | `isTodayHoliday()` | `true` if today is a holiday |
982
+ | `isHoliday(date)` | `true` if the given date is a holiday |
983
+ | `getWeekDays(date)` | 7-day week starting from Monday |
984
+ | `getWeeksInMonth(month, year)` | Weeks in the given month |
985
+ | `getDaysInMonth(month, year)` | All days in the given month |
986
+ | `getDaysInMonths(start, year, n)` | Days across `n` months from `start` |
987
+ | `getDaysInYear(year)` | All days in the given year |
988
+
989
+ ---
990
+
991
+ ## Utility Functions
992
+
993
+ ### Date Utilities
994
+
995
+ [→ Full reference](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/utils/dateUtils.md) | [fetchAxiosConfig](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/utils/fetchAxiosConfig.md)
996
+
997
+ ```jsx
998
+ import {
999
+ toDatetimeLocalValue,
1000
+ setTime,
1001
+ subtractDays,
1002
+ parseUtcToLocal,
1003
+ toDateValue
1004
+ } from 'thecore-auth';
1005
+
1006
+ toDatetimeLocalValue(new Date()); // "2025-01-15T14:30"
1007
+ toDateValue(new Date()); // "2025-01-15"
1008
+ setTime(new Date(), 9, 0, 0); // Date at 09:00:00
1009
+ subtractDays(new Date(), 7); // 7 days ago
1010
+ parseUtcToLocal('2025-01-15T12:00:00Z'); // Local Date object
1011
+ ```
1012
+
1013
+ ---
1014
+
1015
+ ## React Router Re-exports
1016
+
1017
+ You do not need to install `react-router-dom` separately. Import everything from `thecore-auth`:
1018
+
1019
+ ```jsx
1020
+ import {
1021
+ BrowserRouter,
1022
+ Routes,
1023
+ Route,
1024
+ Outlet,
1025
+ Link,
1026
+ NavLink,
1027
+ useLocation,
1028
+ useNavigate,
1029
+ useParams,
1030
+ useMatch
1031
+ } from 'thecore-auth';
1032
+ ```
1033
+
1034
+ ---
1035
+
1036
+ ## CSS Customization
1037
+
1038
+ Override the package's design tokens in your own CSS file:
1039
+
1040
+ ```css
1041
+ :root {
1042
+ /* Brand colors */
1043
+ --color-primary: #3b82f6;
1044
+ --color-primary-hover: #2563eb;
1045
+ --color-primary-text: #ffffff;
1046
+
1047
+ /* Alert colors */
1048
+ --color-danger: #ef4444;
1049
+ --color-success: #22c55e;
1050
+ --color-warning: #f59e0b;
1051
+ --color-info: #3b82f6;
1052
+
1053
+ /* Login form sizing */
1054
+ --height-card-form: auto;
1055
+ --width-card-form: 400px;
1056
+ --max-width-card-form: 90vw;
1057
+ --padding-input: 0.75rem 1rem;
1058
+ --input-radius: 0.5rem;
1059
+
1060
+ /* Buttons */
1061
+ --padding-primary-button: 0.75rem 1.5rem;
1062
+ --radius-primary-button: 0.5rem;
1063
+ }
1064
+ ```
1065
+
1066
+ ---
1067
+
1068
+ ## Complete React App Example
1069
+
1070
+ Below is a minimal but complete example of a React application using `thecore-auth`.
1071
+
1072
+ ### File structure
1073
+
1074
+ ```
1075
+ my-app/
1076
+ ├── public/
1077
+ │ └── config.json
1078
+ ├── src/
1079
+ │ ├── pages/
1080
+ │ │ ├── Dashboard.jsx
1081
+ │ │ └── Profile.jsx
1082
+ │ ├── components/
1083
+ │ │ └── Header.jsx
1084
+ │ ├── App.jsx
1085
+ │ ├── main.jsx
1086
+ │ └── index.css
1087
+ └── package.json
1088
+ ```
1089
+
1090
+ ### `public/config.json`
1091
+
1092
+ ```json
1093
+ {
1094
+ "baseUri": "https://api.example.com",
1095
+ "authenticatedEndpoint": "/auth/login",
1096
+ "usersEndpoint": "/auth/me",
1097
+ "heartbeatEndpoint": "/auth/refresh",
1098
+ "firstPrivatePath": "/dashboard",
1099
+ "firstPrivateTitle": "Dashboard",
1100
+ "defaultTitle": "My App",
1101
+ "infiniteSession": false,
1102
+ "timeDeducted": 60000,
1103
+ "alertTimeout": 4000,
1104
+ "axiosErrors": {
1105
+ "unauthorized": "Your session has expired.",
1106
+ "notFound": "Page not found.",
1107
+ "defaultMessage": "An error occurred."
1108
+ },
1109
+ "clearLoginFormOnError": true,
1110
+ "autoLogin": false,
1111
+ "backendToken": "",
1112
+ "isDebug": false,
1113
+ "tokenLog": false,
1114
+ "isDevelopment": false,
1115
+ "hasSessionKey": false,
1116
+ "appKey": "myapp",
1117
+ "showHeaderButton": false,
1118
+ "useCustomLoginTimeout": false,
1119
+ "customLoginTimeout": 10000,
1120
+ "stopLoaderOnFinish": true,
1121
+ "timerInfiniteSession": "",
1122
+ "customDeviceType": "",
1123
+ "sileoToastEnabled": false,
1124
+ "sileoToastConfig": {
1125
+ "position": "bottom-center",
1126
+ "options": {
1127
+ "fill": "#000000",
1128
+ "duration": 2000,
1129
+ "styles": {
1130
+ "title": "text-white font-semibold",
1131
+ "description": "text-white/75",
1132
+ "badge": "bg-white/20"
1133
+ }
1134
+ }
1135
+ },
1136
+ "pwa": {
1137
+ "enabled": false,
1138
+ "promptOnLoad": false,
1139
+ "customPrompt": false
1140
+ },
1141
+ "routes": [
1142
+ { "path": "/dashboard", "title": "Dashboard" },
1143
+ { "path": "/profile", "title": "Profile" }
1144
+ ],
1145
+ "configRoutes": []
1146
+ }
1147
+ ```
1148
+
1149
+ ### `src/index.css`
185
1150
 
186
1151
  ```css
187
- @import url(../node_modules/@dev/thecore-auth/dist/thecore-auth.css);
1152
+ @import url('../node_modules/thecore-auth/dist/thecore-auth.css');
1153
+
1154
+ :root {
1155
+ --color-primary: #6366f1;
1156
+ --color-primary-hover: #4f46e5;
1157
+ --color-primary-text: #ffffff;
1158
+ }
188
1159
  ```
189
1160
 
190
- For modifying the app’s appearance, we have implemented CSS variables that allow customization without creating new classes. For more details, see the [CSS Variables Documentation](./documentation/CSS%20variables%20documentation.md)
1161
+ ### `src/main.jsx`
1162
+
1163
+ ```jsx
1164
+ import { StrictMode } from 'react';
1165
+ import { createRoot } from 'react-dom/client';
1166
+ import { BrowserRouter } from 'thecore-auth';
1167
+ import App from './App.jsx';
1168
+ import './index.css';
1169
+
1170
+ createRoot(document.getElementById('root')).render(
1171
+ <StrictMode>
1172
+ <BrowserRouter>
1173
+ <App />
1174
+ </BrowserRouter>
1175
+ </StrictMode>
1176
+ );
1177
+ ```
1178
+
1179
+ ### `src/App.jsx`
1180
+
1181
+ ```jsx
1182
+ import {
1183
+ PackageRoutes,
1184
+ ConfigProvider,
1185
+ AuthProvider,
1186
+ LoadingProvider,
1187
+ AlertProvider,
1188
+ LoginFormProvider,
1189
+ ModalProvider,
1190
+ RouteProvider
1191
+ } from 'thecore-auth';
1192
+
1193
+ import Dashboard from './pages/Dashboard';
1194
+ import Profile from './pages/Profile';
1195
+ import Header from './components/Header';
1196
+
1197
+ const privateRoutes = [
1198
+ { path: '/profile', element: <Profile /> }
1199
+ ];
1200
+
1201
+ export default function App() {
1202
+ return (
1203
+ <ConfigProvider>
1204
+ <LoadingProvider>
1205
+ <AlertProvider>
1206
+ <AuthProvider>
1207
+ <LoginFormProvider
1208
+ title="Welcome back"
1209
+ label="Email address"
1210
+ buttonText="Sign in"
1211
+ >
1212
+ <ModalProvider>
1213
+ <RouteProvider privateRoutes={privateRoutes} publicRoutes={[]}>
1214
+ <PackageRoutes
1215
+ firstPrivateElement={<Dashboard />}
1216
+ headerComponent={<Header />}
1217
+ showHeaderOnLogin={false}
1218
+ />
1219
+ </RouteProvider>
1220
+ </ModalProvider>
1221
+ </LoginFormProvider>
1222
+ </AuthProvider>
1223
+ </AlertProvider>
1224
+ </LoadingProvider>
1225
+ </ConfigProvider>
1226
+ );
1227
+ }
1228
+ ```
1229
+
1230
+ ### `src/components/Header.jsx`
1231
+
1232
+ ```jsx
1233
+ import { useAuth, useNavigate, Link } from 'thecore-auth';
1234
+
1235
+ export default function Header() {
1236
+ const { isAuthenticated, logout } = useAuth();
1237
+ const navigate = useNavigate();
1238
+
1239
+ const handleLogout = () => {
1240
+ logout();
1241
+ navigate('/');
1242
+ };
1243
+
1244
+ return (
1245
+ <header style={{ padding: '1rem', display: 'flex', justifyContent: 'space-between' }}>
1246
+ <Link to="/dashboard">My App</Link>
1247
+ {isAuthenticated && (
1248
+ <nav style={{ display: 'flex', gap: '1rem' }}>
1249
+ <Link to="/profile">Profile</Link>
1250
+ <button onClick={handleLogout}>Logout</button>
1251
+ </nav>
1252
+ )}
1253
+ </header>
1254
+ );
1255
+ }
1256
+ ```
1257
+
1258
+ ### `src/pages/Dashboard.jsx`
1259
+
1260
+ ```jsx
1261
+ import { useAuth, useAlert, useLoading, useConfig } from 'thecore-auth';
1262
+
1263
+ export default function Dashboard() {
1264
+ const { isAuthenticated } = useAuth();
1265
+ const { activeAlert } = useAlert();
1266
+ const { setIsLoading } = useLoading();
1267
+ const { config } = useConfig();
1268
+
1269
+ const handleAction = async () => {
1270
+ setIsLoading(true);
1271
+ try {
1272
+ // simulate API call
1273
+ await new Promise((resolve) => setTimeout(resolve, 1500));
1274
+ activeAlert('success', 'Action completed successfully!');
1275
+ } catch {
1276
+ activeAlert('danger', 'Something went wrong.');
1277
+ } finally {
1278
+ setIsLoading(false);
1279
+ }
1280
+ };
1281
+
1282
+ if (!isAuthenticated) return null;
1283
+
1284
+ return (
1285
+ <main style={{ padding: '2rem' }}>
1286
+ <h1>Dashboard</h1>
1287
+ <p>API: {config.baseUri}</p>
1288
+ <button onClick={handleAction}>Run action</button>
1289
+ </main>
1290
+ );
1291
+ }
1292
+ ```
1293
+
1294
+ ### `src/pages/Profile.jsx`
1295
+
1296
+ ```jsx
1297
+ import { useForm, useAlert, useAuth } from 'thecore-auth';
1298
+
1299
+ export default function Profile() {
1300
+ const { values, handleChange, resetForm } = useForm({ name: '', bio: '' });
1301
+ const { activeAlert } = useAlert();
1302
+ const { createAxiosInstances } = useAuth();
1303
+
1304
+ const handleSubmit = async (e) => {
1305
+ e.preventDefault();
1306
+ const axios = createAxiosInstances();
1307
+ try {
1308
+ await axios.put('/profile', values);
1309
+ activeAlert('success', 'Profile updated!');
1310
+ } catch {
1311
+ activeAlert('danger', 'Failed to update profile.');
1312
+ }
1313
+ };
1314
+
1315
+ return (
1316
+ <main style={{ padding: '2rem' }}>
1317
+ <h1>Profile</h1>
1318
+ <form onSubmit={handleSubmit}>
1319
+ <div>
1320
+ <label>Name</label>
1321
+ <input
1322
+ value={values.name}
1323
+ onChange={(e) => handleChange('name', e.target.value)}
1324
+ />
1325
+ </div>
1326
+ <div>
1327
+ <label>Bio</label>
1328
+ <textarea
1329
+ value={values.bio}
1330
+ onChange={(e) => handleChange('bio', e.target.value)}
1331
+ />
1332
+ </div>
1333
+ <button type="submit">Save</button>
1334
+ <button type="button" onClick={resetForm}>Reset</button>
1335
+ </form>
1336
+ </main>
1337
+ );
1338
+ }
1339
+ ```
1340
+
1341
+ ---
1342
+
1343
+ ## CSS Variables
1344
+
1345
+ All visual aspects of the package are controlled through CSS custom properties.
1346
+ Override them in your own `:root {}` block after importing the package CSS.
1347
+
1348
+ | Language | Link |
1349
+ |----------|------|
1350
+ | 🇬🇧 English | [docs/en/css/css-variables.md](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/css/css-variables.md) |
1351
+ | 🇮🇹 Italiano | [docs/it/css-variables.md](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/it/css-variables.md) |
1352
+ | 🇪🇸 Español | [docs/es/css-variables.md](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/es/css-variables.md) |
1353
+
1354
+ Quick reference — most commonly overridden:
1355
+
1356
+ ```css
1357
+ :root {
1358
+ --color-primary: #6366f1; /* brand color */
1359
+ --color-primary-hover: #4f46e5; /* brand color on hover */
1360
+ --color-primary-text: #ffffff; /* text on brand-colored elements */
1361
+ --height-card-form: 65vh; /* login card height */
1362
+ --form-radius: 1.5rem; /* login card border radius */
1363
+ --input-radius: 0.5rem; /* input border radius */
1364
+ --color-spinner: #6366f1; /* loading spinner color */
1365
+ }
1366
+ ```
191
1367
 
192
1368
  ---
193
1369
 
194
- ## Conclusion
195
- This documentation covers the basic configuration and usage of THECORE-AUTH. For further customization, make sure to correctly use the context providers and configuration options.
1370
+ ## Modal System
1371
+
1372
+ Full API reference, style override guide, and usage examples for the centralized modal system (`useModal`, `openModal`, `closeModal`).
1373
+
1374
+ | Language | Link |
1375
+ |----------|------|
1376
+ | 🇬🇧 English | [docs/en/modal.md](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/en/modal.md) |
1377
+ | 🇮🇹 Italiano | [docs/it/modal.md](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/it/modal.md) |
1378
+ | 🇪🇸 Español | [docs/es/modal.md](https://github.com/SantiGalvan/thecore-auth/blob/main/docs/es/modal.md) |
1379
+
1380
+ ---
1381
+
1382
+ ## Repository
1383
+
1384
+ - GitHub: [https://github.com/SantiGalvan/thecore-auth](https://github.com/SantiGalvan/thecore-auth)
1385
+ - npm: `npm install thecore-auth`