@optifye/dashboard-core 3.0.1 → 4.0.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/README.md CHANGED
@@ -196,6 +196,53 @@ This CSS file includes:
196
196
 
197
197
  **Note:** You do NOT need to separately import `react-day-picker/dist/style.css` as these styles are already included in the package's global CSS.
198
198
 
199
+ ## Authentication Components
200
+
201
+ The package now includes built-in authentication components for a complete Supabase OTP-based authentication flow. See [AUTH_COMPONENTS_GUIDE.md](./AUTH_COMPONENTS_GUIDE.md) for detailed usage.
202
+
203
+ ### Quick Start
204
+
205
+ 1. **Copy the Optifye logo** from `node_modules/@optifye/dashboard-core/src/assets/optifye-logo.png` to your `public` folder.
206
+
207
+ 2. **Create login page**:
208
+ ```tsx
209
+ import { LoginPage } from '@optifye/dashboard-core';
210
+
211
+ export default function Login() {
212
+ return <LoginPage logoSrc="/optifye-logo.png" />;
213
+ }
214
+ ```
215
+
216
+ 3. **Create auth callback page**:
217
+ ```tsx
218
+ import { AuthCallback } from '@optifye/dashboard-core';
219
+
220
+ export default function AuthCallbackPage() {
221
+ return <AuthCallback />;
222
+ }
223
+ ```
224
+
225
+ ### Available Auth Components
226
+
227
+ - **LoginPage**: Full-featured login page with email OTP authentication
228
+ - **AuthCallback**: Handles Supabase authentication callbacks
229
+ - **DebugAuth**: Debug page for troubleshooting Supabase configuration
230
+ - **withAuth**: HOC for protecting routes (already documented)
231
+
232
+ ### Rate Limiting
233
+
234
+ The package includes built-in rate limiting utilities:
235
+
236
+ ```tsx
237
+ import { checkRateLimit } from '@optifye/dashboard-core';
238
+
239
+ // In your API route
240
+ const { allowed, retryAfter } = checkRateLimit(email, {
241
+ windowMs: 60000, // 1 minute
242
+ maxRequests: 3 // 3 attempts
243
+ });
244
+ ```
245
+
199
246
  ## Mobile Responsiveness
200
247
 
201
248
  All dashboard components are designed to be fully responsive and mobile-friendly:
@@ -736,4 +783,8 @@ The package repository field has been properly formatted for npm publishing stan
736
783
 
737
784
  ## License
738
785
 
739
- (License information, e.g., MIT, would go here.)
786
+ (License information, e.g., MIT, would go here.)
787
+
788
+ ---
789
+
790
+ *Last updated for v4.0.0 - Published to npm*
package/dist/index.css ADDED
@@ -0,0 +1,389 @@
1
+ /* src/global.css */
2
+ *,
3
+ ::before,
4
+ ::after {
5
+ --tw-border-spacing-x: 0;
6
+ --tw-border-spacing-y: 0;
7
+ --tw-translate-x: 0;
8
+ --tw-translate-y: 0;
9
+ --tw-rotate: 0;
10
+ --tw-skew-x: 0;
11
+ --tw-skew-y: 0;
12
+ --tw-scale-x: 1;
13
+ --tw-scale-y: 1;
14
+ --tw-pan-x: ;
15
+ --tw-pan-y: ;
16
+ --tw-pinch-zoom: ;
17
+ --tw-scroll-snap-strictness: proximity;
18
+ --tw-gradient-from-position: ;
19
+ --tw-gradient-via-position: ;
20
+ --tw-gradient-to-position: ;
21
+ --tw-ordinal: ;
22
+ --tw-slashed-zero: ;
23
+ --tw-numeric-figure: ;
24
+ --tw-numeric-spacing: ;
25
+ --tw-numeric-fraction: ;
26
+ --tw-ring-inset: ;
27
+ --tw-ring-offset-width: 0px;
28
+ --tw-ring-offset-color: #fff;
29
+ --tw-ring-color: rgb(59 130 246 / 0.5);
30
+ --tw-ring-offset-shadow: 0 0 #0000;
31
+ --tw-ring-shadow: 0 0 #0000;
32
+ --tw-shadow: 0 0 #0000;
33
+ --tw-shadow-colored: 0 0 #0000;
34
+ --tw-blur: ;
35
+ --tw-brightness: ;
36
+ --tw-contrast: ;
37
+ --tw-grayscale: ;
38
+ --tw-hue-rotate: ;
39
+ --tw-invert: ;
40
+ --tw-saturate: ;
41
+ --tw-sepia: ;
42
+ --tw-drop-shadow: ;
43
+ --tw-backdrop-blur: ;
44
+ --tw-backdrop-brightness: ;
45
+ --tw-backdrop-contrast: ;
46
+ --tw-backdrop-grayscale: ;
47
+ --tw-backdrop-hue-rotate: ;
48
+ --tw-backdrop-invert: ;
49
+ --tw-backdrop-opacity: ;
50
+ --tw-backdrop-saturate: ;
51
+ --tw-backdrop-sepia: ;
52
+ --tw-contain-size: ;
53
+ --tw-contain-layout: ;
54
+ --tw-contain-paint: ;
55
+ --tw-contain-style: ;
56
+ }
57
+ ::backdrop {
58
+ --tw-border-spacing-x: 0;
59
+ --tw-border-spacing-y: 0;
60
+ --tw-translate-x: 0;
61
+ --tw-translate-y: 0;
62
+ --tw-rotate: 0;
63
+ --tw-skew-x: 0;
64
+ --tw-skew-y: 0;
65
+ --tw-scale-x: 1;
66
+ --tw-scale-y: 1;
67
+ --tw-pan-x: ;
68
+ --tw-pan-y: ;
69
+ --tw-pinch-zoom: ;
70
+ --tw-scroll-snap-strictness: proximity;
71
+ --tw-gradient-from-position: ;
72
+ --tw-gradient-via-position: ;
73
+ --tw-gradient-to-position: ;
74
+ --tw-ordinal: ;
75
+ --tw-slashed-zero: ;
76
+ --tw-numeric-figure: ;
77
+ --tw-numeric-spacing: ;
78
+ --tw-numeric-fraction: ;
79
+ --tw-ring-inset: ;
80
+ --tw-ring-offset-width: 0px;
81
+ --tw-ring-offset-color: #fff;
82
+ --tw-ring-color: rgb(59 130 246 / 0.5);
83
+ --tw-ring-offset-shadow: 0 0 #0000;
84
+ --tw-ring-shadow: 0 0 #0000;
85
+ --tw-shadow: 0 0 #0000;
86
+ --tw-shadow-colored: 0 0 #0000;
87
+ --tw-blur: ;
88
+ --tw-brightness: ;
89
+ --tw-contrast: ;
90
+ --tw-grayscale: ;
91
+ --tw-hue-rotate: ;
92
+ --tw-invert: ;
93
+ --tw-saturate: ;
94
+ --tw-sepia: ;
95
+ --tw-drop-shadow: ;
96
+ --tw-backdrop-blur: ;
97
+ --tw-backdrop-brightness: ;
98
+ --tw-backdrop-contrast: ;
99
+ --tw-backdrop-grayscale: ;
100
+ --tw-backdrop-hue-rotate: ;
101
+ --tw-backdrop-invert: ;
102
+ --tw-backdrop-opacity: ;
103
+ --tw-backdrop-saturate: ;
104
+ --tw-backdrop-sepia: ;
105
+ --tw-contain-size: ;
106
+ --tw-contain-layout: ;
107
+ --tw-contain-paint: ;
108
+ --tw-contain-style: ;
109
+ }
110
+ *,
111
+ ::before,
112
+ ::after {
113
+ box-sizing: border-box;
114
+ border-width: 0;
115
+ border-style: solid;
116
+ border-color: #e5e7eb;
117
+ }
118
+ ::before,
119
+ ::after {
120
+ --tw-content: "";
121
+ }
122
+ html,
123
+ :host {
124
+ line-height: 1.5;
125
+ -webkit-text-size-adjust: 100%;
126
+ -moz-tab-size: 4;
127
+ -o-tab-size: 4;
128
+ tab-size: 4;
129
+ font-family:
130
+ ui-sans-serif,
131
+ system-ui,
132
+ sans-serif,
133
+ "Apple Color Emoji",
134
+ "Segoe UI Emoji",
135
+ "Segoe UI Symbol",
136
+ "Noto Color Emoji";
137
+ font-feature-settings: normal;
138
+ font-variation-settings: normal;
139
+ -webkit-tap-highlight-color: transparent;
140
+ }
141
+ body {
142
+ margin: 0;
143
+ line-height: inherit;
144
+ }
145
+ hr {
146
+ height: 0;
147
+ color: inherit;
148
+ border-top-width: 1px;
149
+ }
150
+ abbr:where([title]) {
151
+ -webkit-text-decoration: underline dotted;
152
+ text-decoration: underline dotted;
153
+ }
154
+ h1,
155
+ h2,
156
+ h3,
157
+ h4,
158
+ h5,
159
+ h6 {
160
+ font-size: inherit;
161
+ font-weight: inherit;
162
+ }
163
+ a {
164
+ color: inherit;
165
+ text-decoration: inherit;
166
+ }
167
+ b,
168
+ strong {
169
+ font-weight: bolder;
170
+ }
171
+ code,
172
+ kbd,
173
+ samp,
174
+ pre {
175
+ font-family:
176
+ ui-monospace,
177
+ SFMono-Regular,
178
+ Menlo,
179
+ Monaco,
180
+ Consolas,
181
+ "Liberation Mono",
182
+ "Courier New",
183
+ monospace;
184
+ font-feature-settings: normal;
185
+ font-variation-settings: normal;
186
+ font-size: 1em;
187
+ }
188
+ small {
189
+ font-size: 80%;
190
+ }
191
+ sub,
192
+ sup {
193
+ font-size: 75%;
194
+ line-height: 0;
195
+ position: relative;
196
+ vertical-align: baseline;
197
+ }
198
+ sub {
199
+ bottom: -0.25em;
200
+ }
201
+ sup {
202
+ top: -0.5em;
203
+ }
204
+ table {
205
+ text-indent: 0;
206
+ border-color: inherit;
207
+ border-collapse: collapse;
208
+ }
209
+ button,
210
+ input,
211
+ optgroup,
212
+ select,
213
+ textarea {
214
+ font-family: inherit;
215
+ font-feature-settings: inherit;
216
+ font-variation-settings: inherit;
217
+ font-size: 100%;
218
+ font-weight: inherit;
219
+ line-height: inherit;
220
+ letter-spacing: inherit;
221
+ color: inherit;
222
+ margin: 0;
223
+ padding: 0;
224
+ }
225
+ button,
226
+ select {
227
+ text-transform: none;
228
+ }
229
+ button,
230
+ input:where([type=button]),
231
+ input:where([type=reset]),
232
+ input:where([type=submit]) {
233
+ -webkit-appearance: button;
234
+ background-color: transparent;
235
+ background-image: none;
236
+ }
237
+ :-moz-focusring {
238
+ outline: auto;
239
+ }
240
+ :-moz-ui-invalid {
241
+ box-shadow: none;
242
+ }
243
+ progress {
244
+ vertical-align: baseline;
245
+ }
246
+ ::-webkit-inner-spin-button,
247
+ ::-webkit-outer-spin-button {
248
+ height: auto;
249
+ }
250
+ [type=search] {
251
+ -webkit-appearance: textfield;
252
+ outline-offset: -2px;
253
+ }
254
+ ::-webkit-search-decoration {
255
+ -webkit-appearance: none;
256
+ }
257
+ ::-webkit-file-upload-button {
258
+ -webkit-appearance: button;
259
+ font: inherit;
260
+ }
261
+ summary {
262
+ display: list-item;
263
+ }
264
+ blockquote,
265
+ dl,
266
+ dd,
267
+ h1,
268
+ h2,
269
+ h3,
270
+ h4,
271
+ h5,
272
+ h6,
273
+ hr,
274
+ figure,
275
+ p,
276
+ pre {
277
+ margin: 0;
278
+ }
279
+ fieldset {
280
+ margin: 0;
281
+ padding: 0;
282
+ }
283
+ legend {
284
+ padding: 0;
285
+ }
286
+ ol,
287
+ ul,
288
+ menu {
289
+ list-style: none;
290
+ margin: 0;
291
+ padding: 0;
292
+ }
293
+ dialog {
294
+ padding: 0;
295
+ }
296
+ textarea {
297
+ resize: vertical;
298
+ }
299
+ input::-moz-placeholder,
300
+ textarea::-moz-placeholder {
301
+ opacity: 1;
302
+ color: #9ca3af;
303
+ }
304
+ input::placeholder,
305
+ textarea::placeholder {
306
+ opacity: 1;
307
+ color: #9ca3af;
308
+ }
309
+ button,
310
+ [role=button] {
311
+ cursor: pointer;
312
+ }
313
+ :disabled {
314
+ cursor: default;
315
+ }
316
+ img,
317
+ svg,
318
+ video,
319
+ canvas,
320
+ audio,
321
+ iframe,
322
+ embed,
323
+ object {
324
+ display: block;
325
+ vertical-align: middle;
326
+ }
327
+ img,
328
+ video {
329
+ max-width: 100%;
330
+ height: auto;
331
+ }
332
+ [hidden]:where(:not([hidden=until-found])) {
333
+ display: none;
334
+ }
335
+ :root {
336
+ --radius: 0.5rem;
337
+ }
338
+ body {
339
+ --tw-bg-opacity: 1;
340
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
341
+ --tw-text-opacity: 1;
342
+ color: rgb(17 24 39 / var(--tw-text-opacity, 1));
343
+ }
344
+ input[type=range] {
345
+ -webkit-appearance: none;
346
+ -moz-appearance: none;
347
+ appearance: none;
348
+ width: 100%;
349
+ cursor: pointer;
350
+ touch-action: manipulation;
351
+ }
352
+ input[type=range]::-webkit-slider-runnable-track {
353
+ height: 6px;
354
+ background-color: rgba(255, 255, 255, 0.3);
355
+ border-radius: 9999px;
356
+ }
357
+ input[type=range]::-webkit-slider-thumb {
358
+ -webkit-appearance: none;
359
+ appearance: none;
360
+ width: 18px;
361
+ height: 18px;
362
+ background: white;
363
+ border-radius: 50%;
364
+ margin-top: -6px;
365
+ box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
366
+ -webkit-transition: transform 0.1s ease;
367
+ transition: transform 0.1s ease;
368
+ }
369
+ input[type=range]::-moz-range-track {
370
+ height: 6px;
371
+ background-color: rgba(255, 255, 255, 0.3);
372
+ border-radius: 9999px;
373
+ }
374
+ input[type=range]::-moz-range-thumb {
375
+ width: 18px;
376
+ height: 18px;
377
+ background: white;
378
+ border-radius: 50%;
379
+ border: none;
380
+ box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
381
+ -moz-transition: transform 0.1s ease;
382
+ transition: transform 0.1s ease;
383
+ }
384
+ input[type=range]:active::-webkit-slider-thumb {
385
+ transform: scale(1.2);
386
+ }
387
+ input[type=range]:active::-moz-range-thumb {
388
+ transform: scale(1.2);
389
+ }