@djangocfg/layouts 2.1.30 → 2.1.31

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/layouts",
3
- "version": "2.1.30",
3
+ "version": "2.1.31",
4
4
  "description": "Simple, straightforward layout components for Next.js - import and use with props",
5
5
  "keywords": [
6
6
  "layouts",
@@ -92,9 +92,9 @@
92
92
  "check": "tsc --noEmit"
93
93
  },
94
94
  "peerDependencies": {
95
- "@djangocfg/api": "^2.1.30",
96
- "@djangocfg/centrifugo": "^2.1.30",
97
- "@djangocfg/ui-nextjs": "^2.1.30",
95
+ "@djangocfg/api": "^2.1.31",
96
+ "@djangocfg/centrifugo": "^2.1.31",
97
+ "@djangocfg/ui-nextjs": "^2.1.31",
98
98
  "@hookform/resolvers": "^5.2.0",
99
99
  "consola": "^3.4.2",
100
100
  "lucide-react": "^0.545.0",
@@ -114,7 +114,7 @@
114
114
  "uuid": "^11.1.0"
115
115
  },
116
116
  "devDependencies": {
117
- "@djangocfg/typescript-config": "^2.1.30",
117
+ "@djangocfg/typescript-config": "^2.1.31",
118
118
  "@types/node": "^24.7.2",
119
119
  "@types/react": "^19.1.0",
120
120
  "@types/react-dom": "^19.1.0",
@@ -104,7 +104,10 @@ export const IdentifierForm: React.FC = () => {
104
104
  ? 'Enter your phone number to receive a verification code via SMS'
105
105
  : 'Enter your email address to receive a verification code';
106
106
  };
107
-
107
+
108
+ // Check if we have any links for terms/privacy - if not, we don't show the checkbox
109
+ const hasAnyLinks = Boolean(termsUrl || privacyUrl);
110
+
108
111
  return (
109
112
  <Card className="w-full max-w-md mx-auto shadow-lg border border-border bg-card/50 backdrop-blur-sm">
110
113
  <CardHeader className="text-center pb-6">
@@ -173,44 +176,46 @@ export const IdentifierForm: React.FC = () => {
173
176
  />
174
177
  </TabsContent>
175
178
 
176
- {/* Terms and Conditions */}
177
- <div className="flex items-start gap-3">
178
- <Checkbox
179
- id="terms"
180
- checked={acceptedTerms}
181
- onCheckedChange={setAcceptedTerms}
182
- disabled={isLoading}
183
- className="mt-1"
184
- />
185
- <div className="text-sm text-muted-foreground leading-5">
186
- <Label htmlFor="terms" className="cursor-pointer">
187
- I agree to the{' '}
188
- {termsUrl && (
189
- <>
179
+ {/* Terms and Conditions - only show if we have links */}
180
+ {hasAnyLinks && (
181
+ <div className="flex items-start gap-3">
182
+ <Checkbox
183
+ id="terms"
184
+ checked={acceptedTerms}
185
+ onCheckedChange={setAcceptedTerms}
186
+ disabled={isLoading}
187
+ className="mt-1"
188
+ />
189
+ <div className="text-sm text-muted-foreground leading-5">
190
+ <Label htmlFor="terms" className="cursor-pointer">
191
+ I agree to the{' '}
192
+ {termsUrl && (
193
+ <>
194
+ <a
195
+ href={termsUrl}
196
+ target="_blank"
197
+ rel="noopener noreferrer"
198
+ className="text-primary hover:underline font-medium"
199
+ >
200
+ Terms of Service
201
+ </a>
202
+ {privacyUrl && <>{' '}and{' '}</>}
203
+ </>
204
+ )}
205
+ {privacyUrl && (
190
206
  <a
191
- href={termsUrl}
207
+ href={privacyUrl}
192
208
  target="_blank"
193
209
  rel="noopener noreferrer"
194
210
  className="text-primary hover:underline font-medium"
195
211
  >
196
- Terms of Service
197
- </a>{' '}
198
- and{' '}
199
- </>
200
- )}
201
- {privacyUrl && (
202
- <a
203
- href={privacyUrl}
204
- target="_blank"
205
- rel="noopener noreferrer"
206
- className="text-primary hover:underline font-medium"
207
- >
208
- Privacy Policy
209
- </a>
210
- )}
211
- </Label>
212
+ Privacy Policy
213
+ </a>
214
+ )}
215
+ </Label>
216
+ </div>
212
217
  </div>
213
- </div>
218
+ )}
214
219
 
215
220
  {/* Error Message */}
216
221
  {error && (
@@ -223,7 +228,7 @@ export const IdentifierForm: React.FC = () => {
223
228
  <Button
224
229
  type="submit"
225
230
  className="w-full h-11 text-base font-medium"
226
- disabled={isLoading || !identifier || !acceptedTerms}
231
+ disabled={isLoading || !identifier || (hasAnyLinks && !acceptedTerms)}
227
232
  >
228
233
  {isLoading ? (
229
234
  <div className="flex items-center gap-2">
@@ -262,44 +267,46 @@ export const IdentifierForm: React.FC = () => {
262
267
  />
263
268
  </div>
264
269
 
265
- {/* Terms and Conditions */}
266
- <div className="flex items-start gap-3">
267
- <Checkbox
268
- id="terms-email"
269
- checked={acceptedTerms}
270
- onCheckedChange={setAcceptedTerms}
271
- disabled={isLoading}
272
- className="mt-1"
273
- />
274
- <div className="text-sm text-muted-foreground leading-5">
275
- <Label htmlFor="terms-email" className="cursor-pointer">
276
- I agree to the{' '}
277
- {termsUrl && (
278
- <>
270
+ {/* Terms and Conditions - only show if we have links */}
271
+ {hasAnyLinks && (
272
+ <div className="flex items-start gap-3">
273
+ <Checkbox
274
+ id="terms-email"
275
+ checked={acceptedTerms}
276
+ onCheckedChange={setAcceptedTerms}
277
+ disabled={isLoading}
278
+ className="mt-1"
279
+ />
280
+ <div className="text-sm text-muted-foreground leading-5">
281
+ <Label htmlFor="terms-email" className="cursor-pointer">
282
+ I agree to the{' '}
283
+ {termsUrl && (
284
+ <>
285
+ <a
286
+ href={termsUrl}
287
+ target="_blank"
288
+ rel="noopener noreferrer"
289
+ className="text-primary hover:underline font-medium"
290
+ >
291
+ Terms of Service
292
+ </a>
293
+ {privacyUrl && <>{' '}and{' '}</>}
294
+ </>
295
+ )}
296
+ {privacyUrl && (
279
297
  <a
280
- href={termsUrl}
298
+ href={privacyUrl}
281
299
  target="_blank"
282
300
  rel="noopener noreferrer"
283
301
  className="text-primary hover:underline font-medium"
284
302
  >
285
- Terms of Service
286
- </a>{' '}
287
- and{' '}
288
- </>
289
- )}
290
- {privacyUrl && (
291
- <a
292
- href={privacyUrl}
293
- target="_blank"
294
- rel="noopener noreferrer"
295
- className="text-primary hover:underline font-medium"
296
- >
297
- Privacy Policy
298
- </a>
299
- )}
300
- </Label>
303
+ Privacy Policy
304
+ </a>
305
+ )}
306
+ </Label>
307
+ </div>
301
308
  </div>
302
- </div>
309
+ )}
303
310
 
304
311
  {/* Error Message */}
305
312
  {error && (
@@ -312,7 +319,7 @@ export const IdentifierForm: React.FC = () => {
312
319
  <Button
313
320
  type="submit"
314
321
  className="w-full h-11 text-base font-medium"
315
- disabled={isLoading || !identifier || !acceptedTerms}
322
+ disabled={isLoading || !identifier || (hasAnyLinks && !acceptedTerms)}
316
323
  >
317
324
  {isLoading ? (
318
325
  <div className="flex items-center gap-2">
@@ -10,13 +10,12 @@ import {
10
10
  CardDescription,
11
11
  CardHeader,
12
12
  CardTitle,
13
- InputOTP,
14
- InputOTPGroup,
15
- InputOTPSlot,
13
+ OTPInput,
16
14
  } from '@djangocfg/ui-nextjs/components';
17
15
 
18
16
  import { useAuthContext } from './AuthContext';
19
17
  import { AuthHelp } from './AuthHelp';
18
+ import { config } from '../../utils';
20
19
 
21
20
  export const OTPForm: React.FC = () => {
22
21
  const {
@@ -72,41 +71,24 @@ export const OTPForm: React.FC = () => {
72
71
  Enter verification code
73
72
  </label>
74
73
  <div className="flex justify-center">
75
- <InputOTP
74
+ <OTPInput
75
+ length={6}
76
+ validationMode="numeric"
77
+ pasteBehavior="clean"
76
78
  value={otp}
77
79
  onChange={setOtp}
78
- maxLength={6}
79
80
  disabled={isLoading}
80
- containerClassName="gap-3"
81
- >
82
- <InputOTPGroup className="gap-2">
83
- <InputOTPSlot
84
- index={0}
85
- className="h-12 w-12 text-lg font-semibold border-2 border-border bg-background rounded-sm shadow-sm"
86
- />
87
- <InputOTPSlot
88
- index={1}
89
- className="h-12 w-12 text-lg font-semibold border-2 border-border bg-background rounded-sm shadow-sm"
90
- />
91
- <InputOTPSlot
92
- index={2}
93
- className="h-12 w-12 text-lg font-semibold border-2 border-border bg-background rounded-sm shadow-sm"
94
- />
95
- <InputOTPSlot
96
- index={3}
97
- className="h-12 w-12 text-lg font-semibold border-2 border-border bg-background rounded-sm shadow-sm"
98
- />
99
- <InputOTPSlot
100
- index={4}
101
- className="h-12 w-12 text-lg font-semibold border-2 border-border bg-background rounded-sm shadow-sm"
102
- />
103
- <InputOTPSlot
104
- index={5}
105
- className="h-12 w-12 text-lg font-semibold border-2 border-border bg-background rounded-sm shadow-sm"
106
- />
107
- </InputOTPGroup>
108
- </InputOTP>
81
+ autoFocus={true}
82
+ size="lg"
83
+ />
109
84
  </div>
85
+
86
+ {/* Development Mode Notice */}
87
+ {config.isDevelopment && (
88
+ <div className="text-xs text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-950/30 p-2 rounded-md border border-amber-200 dark:border-amber-800 text-center">
89
+ 🔧 Dev Mode: Any OTP code works
90
+ </div>
91
+ )}
110
92
  </div>
111
93
 
112
94
  <div className="space-y-4">
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Frontend configuration from environment variables
3
+ */
4
+ export const config = {
5
+ /**
6
+ * Development mode flag
7
+ * In development mode, any OTP code is accepted for authentication
8
+ */
9
+ isDevelopment: process.env.NODE_ENV === 'development',
10
+ } as const;
@@ -2,5 +2,6 @@
2
2
  * Utils - Utility functions and helpers
3
3
  */
4
4
 
5
+ export * from './config';
5
6
  export * from './logger';
6
7