flowlink-auth 2.7.9 → 2.8.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/dist/SignUp.js +275 -261
- package/package.json +1 -1
- package/src/SignUp.jsx +342 -335
- package/dist/AuthClient.js +0 -2822
- package/dist/Protected.js +0 -2628
- package/dist/index.css +0 -694
package/src/SignUp.jsx
CHANGED
|
@@ -258,11 +258,12 @@
|
|
|
258
258
|
// const errorBox = { marginTop: 10, color: '#ffb4b4', fontSize: 13 }
|
|
259
259
|
// const successBox = { marginTop: 10, color: '#bef264', fontSize: 13 }
|
|
260
260
|
|
|
261
|
+
// src/signup.jsx
|
|
261
262
|
// src/signup.jsx
|
|
262
263
|
'use client'
|
|
263
264
|
import React, { useState, useRef, useEffect } from 'react'
|
|
264
265
|
import Link from 'next/link'
|
|
265
|
-
import { useAuth } from './provider.js' // keep if your
|
|
266
|
+
import { useAuth } from './provider.js' // keep if your SDK provides this; safe to remove if not used
|
|
266
267
|
|
|
267
268
|
export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
268
269
|
const {
|
|
@@ -282,41 +283,49 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
282
283
|
const [loading, setLoading] = useState(false)
|
|
283
284
|
const [loadingOauth, setLoadingOauth] = useState({ google: false, github: false })
|
|
284
285
|
const redirectTimer = useRef(null)
|
|
286
|
+
|
|
287
|
+
// Local toast system (black background)
|
|
285
288
|
const toastId = useRef(0)
|
|
286
|
-
const [toasts, setToasts] = useState([])
|
|
289
|
+
const [toasts, setToasts] = useState([])
|
|
287
290
|
|
|
288
291
|
useEffect(() => {
|
|
292
|
+
// Soft-disable pinch-zoom on mobile while this component is mounted.
|
|
293
|
+
// This inserts a viewport meta tag and removes it on unmount.
|
|
294
|
+
const meta = document.createElement('meta')
|
|
295
|
+
meta.name = 'viewport'
|
|
296
|
+
meta.content = 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'
|
|
297
|
+
document.head.appendChild(meta)
|
|
298
|
+
|
|
289
299
|
return () => {
|
|
300
|
+
// cleanup timer & meta tag
|
|
290
301
|
if (redirectTimer.current) clearTimeout(redirectTimer.current)
|
|
291
|
-
|
|
292
|
-
|
|
302
|
+
const existing = document.querySelector('meta[name="viewport"]')
|
|
303
|
+
if (existing && existing.content === meta.content) {
|
|
304
|
+
document.head.removeChild(existing)
|
|
305
|
+
}
|
|
306
|
+
// clear any toast timers if present (we store timers on the toast objects)
|
|
307
|
+
toasts.forEach(t => {
|
|
308
|
+
if (t._timer) clearTimeout(t._timer)
|
|
309
|
+
})
|
|
293
310
|
}
|
|
294
311
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
295
312
|
}, [])
|
|
296
313
|
|
|
297
|
-
//
|
|
314
|
+
// Toast helpers
|
|
298
315
|
function showToast(type, message, ms = 5000) {
|
|
299
316
|
const id = ++toastId.current
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
// add toast
|
|
303
|
-
setToasts(prev => {
|
|
304
|
-
const next = [t, ...prev].slice(0, 6)
|
|
305
|
-
return next
|
|
306
|
-
})
|
|
307
|
-
// schedule removal
|
|
317
|
+
const t = { id, type, message, _timer: null }
|
|
318
|
+
setToasts(prev => [t, ...prev].slice(0, 6))
|
|
308
319
|
const timer = setTimeout(() => {
|
|
309
320
|
setToasts(prev => prev.filter(x => x.id !== id))
|
|
310
321
|
}, ms)
|
|
311
|
-
// store timer so cleanup can clear it
|
|
312
322
|
t._timer = timer
|
|
313
323
|
}
|
|
314
324
|
|
|
315
|
-
// remove toast immediately
|
|
316
325
|
function removeToast(id) {
|
|
317
326
|
setToasts(prev => {
|
|
318
327
|
prev.forEach(t => {
|
|
319
|
-
if (t.id === id) clearTimeout(t._timer)
|
|
328
|
+
if (t.id === id && t._timer) clearTimeout(t._timer)
|
|
320
329
|
})
|
|
321
330
|
return prev.filter(x => x.id !== id)
|
|
322
331
|
})
|
|
@@ -330,6 +339,7 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
330
339
|
return null
|
|
331
340
|
}
|
|
332
341
|
|
|
342
|
+
// Prevent double submit
|
|
333
343
|
async function submit(e) {
|
|
334
344
|
e.preventDefault()
|
|
335
345
|
if (loading) return
|
|
@@ -366,8 +376,8 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
366
376
|
})
|
|
367
377
|
|
|
368
378
|
const data = await res.json().catch(async () => {
|
|
369
|
-
const
|
|
370
|
-
return { _raw:
|
|
379
|
+
const txt = await res.text().catch(() => '')
|
|
380
|
+
return { _raw: txt }
|
|
371
381
|
})
|
|
372
382
|
|
|
373
383
|
if (!res.ok) {
|
|
@@ -379,7 +389,7 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
379
389
|
if (typeof fetchMe === 'function') await fetchMe()
|
|
380
390
|
|
|
381
391
|
showToast('success', 'Account created. Redirecting…')
|
|
382
|
-
|
|
392
|
+
|
|
383
393
|
if (redirect) {
|
|
384
394
|
redirectTimer.current = setTimeout(() => {
|
|
385
395
|
if (typeof redirectTo === 'function') redirectTo(redirect)
|
|
@@ -387,9 +397,9 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
387
397
|
}, 450)
|
|
388
398
|
}
|
|
389
399
|
} catch (err) {
|
|
390
|
-
// present server errors as toast (black background)
|
|
391
400
|
const text = err?.message ?? 'Network error'
|
|
392
401
|
showToast('error', text)
|
|
402
|
+
// keep console error for integrators
|
|
393
403
|
console.error('Signup error:', err)
|
|
394
404
|
} finally {
|
|
395
405
|
setLoading(false)
|
|
@@ -410,9 +420,7 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
410
420
|
const sdkBase = baseUrl || (typeof window !== 'undefined' ? window.location.origin.replace(/\/+$/, '') : '')
|
|
411
421
|
const startUrl = `${sdkBase}/sdk/auth/start?rid=${rid}&source=${encodeURIComponent(provider)}&callbackUrl=${callbackUrl}`
|
|
412
422
|
|
|
413
|
-
if (!publishableKey)
|
|
414
|
-
throw new Error('Missing publishable key (client side).')
|
|
415
|
-
}
|
|
423
|
+
if (!publishableKey) throw new Error('Missing publishable key (client side).')
|
|
416
424
|
|
|
417
425
|
const res = await fetch(startUrl, {
|
|
418
426
|
method: 'GET',
|
|
@@ -423,7 +431,7 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
423
431
|
if (!res.ok) throw new Error(data?.error || `OAuth start failed (${res.status})`)
|
|
424
432
|
if (!data?.oauthUrl) throw new Error('SDK start did not return oauthUrl')
|
|
425
433
|
|
|
426
|
-
//
|
|
434
|
+
// Navigate to provider (this will unload the page)
|
|
427
435
|
if (typeof window !== 'undefined') window.location.href = data.oauthUrl
|
|
428
436
|
} catch (err) {
|
|
429
437
|
showToast('error', err?.message || 'OAuth start failed')
|
|
@@ -443,54 +451,51 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
443
451
|
}
|
|
444
452
|
|
|
445
453
|
return (
|
|
446
|
-
<div style={overlay}>
|
|
447
|
-
{/* toast container (
|
|
448
|
-
<div style={toastContainer}>
|
|
454
|
+
<div style={styles.overlay}>
|
|
455
|
+
{/* custom toast container (black background) */}
|
|
456
|
+
<div style={styles.toastContainer} aria-live="polite" aria-atomic="true">
|
|
449
457
|
{toasts.map(t => (
|
|
450
458
|
<div
|
|
451
459
|
key={t.id}
|
|
452
460
|
role="status"
|
|
453
|
-
aria-live="polite"
|
|
454
461
|
style={{
|
|
455
|
-
...toastBase,
|
|
456
|
-
...(t.type === 'error' ? toastError : t.type === 'success' ? toastSuccess : toastInfo)
|
|
462
|
+
...styles.toastBase,
|
|
463
|
+
...(t.type === 'error' ? styles.toastError : t.type === 'success' ? styles.toastSuccess : styles.toastInfo)
|
|
457
464
|
}}
|
|
458
465
|
onMouseEnter={() => {
|
|
459
|
-
|
|
460
|
-
clearTimeout(t._timer)
|
|
466
|
+
if (t._timer) clearTimeout(t._timer)
|
|
461
467
|
}}
|
|
462
468
|
onMouseLeave={() => {
|
|
463
|
-
// restart dismiss
|
|
469
|
+
// restart auto-dismiss shorter when mouse leaves
|
|
464
470
|
const timer = setTimeout(() => removeToast(t.id), 3000)
|
|
465
|
-
// patch timer into state (imperative but fine for local toast)
|
|
466
471
|
setToasts(prev => prev.map(x => x.id === t.id ? { ...x, _timer: timer } : x))
|
|
467
472
|
}}
|
|
468
473
|
>
|
|
469
474
|
<div style={{ flex: 1 }}>{t.message}</div>
|
|
470
|
-
<button aria-label="Dismiss" onClick={() => removeToast(t.id)} style={toastCloseBtn}>✕</button>
|
|
475
|
+
<button aria-label="Dismiss" onClick={() => removeToast(t.id)} style={styles.toastCloseBtn}>✕</button>
|
|
471
476
|
</div>
|
|
472
477
|
))}
|
|
473
478
|
</div>
|
|
474
479
|
|
|
475
|
-
<div style={modal}>
|
|
476
|
-
<div style={modalInner}>
|
|
477
|
-
<header style={header}>
|
|
478
|
-
<div style={brandRow}>
|
|
479
|
-
<div style={logo}>
|
|
480
|
-
<div style={logoCircle}
|
|
480
|
+
<div style={styles.modal} role="dialog" aria-modal="true" aria-labelledby="signup-title">
|
|
481
|
+
<div style={styles.modalInner}>
|
|
482
|
+
<header style={styles.header}>
|
|
483
|
+
<div style={styles.brandRow}>
|
|
484
|
+
<div style={styles.logo} aria-hidden>
|
|
485
|
+
<div style={styles.logoCircle} />
|
|
481
486
|
</div>
|
|
482
487
|
<div>
|
|
483
|
-
<h1 style={title}>Sign up to {agency?.name || 'App'}</h1>
|
|
484
|
-
<div style={subtitle}>Welcome
|
|
488
|
+
<h1 id="signup-title" style={styles.title}>Sign up to {agency?.name || 'App'}</h1>
|
|
489
|
+
<div style={styles.subtitle}>Welcome — create your account.</div>
|
|
485
490
|
</div>
|
|
486
491
|
</div>
|
|
487
492
|
</header>
|
|
488
493
|
|
|
489
|
-
<section style={oauthSection}>
|
|
494
|
+
<section style={styles.oauthSection}>
|
|
490
495
|
<button
|
|
491
496
|
onClick={handleGoogle}
|
|
492
497
|
type="button"
|
|
493
|
-
style={{ ...oauthButton, ...oauthGoogle }}
|
|
498
|
+
style={{ ...styles.oauthButton, ...styles.oauthGoogle }}
|
|
494
499
|
disabled={loading || loadingOauth.google}
|
|
495
500
|
aria-disabled={loading || loadingOauth.google}
|
|
496
501
|
>
|
|
@@ -506,7 +511,7 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
506
511
|
<button
|
|
507
512
|
onClick={handleGithub}
|
|
508
513
|
type="button"
|
|
509
|
-
style={{ ...oauthButton, ...oauthGithub }}
|
|
514
|
+
style={{ ...styles.oauthButton, ...styles.oauthGithub }}
|
|
510
515
|
disabled={loading || loadingOauth.github}
|
|
511
516
|
aria-disabled={loading || loadingOauth.github}
|
|
512
517
|
>
|
|
@@ -517,28 +522,28 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
517
522
|
</button>
|
|
518
523
|
</section>
|
|
519
524
|
|
|
520
|
-
<div style={dividerRow}>
|
|
521
|
-
<div style={line} />
|
|
522
|
-
<div style={orText}>or</div>
|
|
523
|
-
<div style={line} />
|
|
525
|
+
<div style={styles.dividerRow}>
|
|
526
|
+
<div style={styles.line} />
|
|
527
|
+
<div style={styles.orText}>or</div>
|
|
528
|
+
<div style={styles.line} />
|
|
524
529
|
</div>
|
|
525
530
|
|
|
526
|
-
<form onSubmit={submit} style={form}>
|
|
527
|
-
<label style={label} htmlFor="name">
|
|
528
|
-
<span style={labelText}>Name</span>
|
|
531
|
+
<form onSubmit={submit} style={styles.form}>
|
|
532
|
+
<label style={styles.label} htmlFor="name">
|
|
533
|
+
<span style={styles.labelText}>Name</span>
|
|
529
534
|
<input
|
|
530
535
|
id="name"
|
|
531
536
|
type="text"
|
|
532
537
|
value={name}
|
|
533
538
|
onChange={e => setName(e.target.value)}
|
|
534
539
|
placeholder="Your name"
|
|
535
|
-
style={input}
|
|
540
|
+
style={styles.input}
|
|
536
541
|
autoComplete="name"
|
|
537
542
|
/>
|
|
538
543
|
</label>
|
|
539
544
|
|
|
540
|
-
<label style={label} htmlFor="email">
|
|
541
|
-
<span style={labelText}>Email address</span>
|
|
545
|
+
<label style={styles.label} htmlFor="email">
|
|
546
|
+
<span style={styles.labelText}>Email address</span>
|
|
542
547
|
<input
|
|
543
548
|
id="email"
|
|
544
549
|
type="email"
|
|
@@ -546,13 +551,13 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
546
551
|
onChange={e => setEmail(e.target.value)}
|
|
547
552
|
required
|
|
548
553
|
placeholder="you@example.com"
|
|
549
|
-
style={input}
|
|
554
|
+
style={styles.input}
|
|
550
555
|
autoComplete="email"
|
|
551
556
|
/>
|
|
552
557
|
</label>
|
|
553
558
|
|
|
554
|
-
<label style={label} htmlFor="password">
|
|
555
|
-
<span style={labelText}>Password</span>
|
|
559
|
+
<label style={styles.label} htmlFor="password">
|
|
560
|
+
<span style={styles.labelText}>Password</span>
|
|
556
561
|
<input
|
|
557
562
|
id="password"
|
|
558
563
|
type="password"
|
|
@@ -560,14 +565,14 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
560
565
|
onChange={e => setPassword(e.target.value)}
|
|
561
566
|
required
|
|
562
567
|
placeholder="••••••••"
|
|
563
|
-
style={input}
|
|
568
|
+
style={styles.input}
|
|
564
569
|
autoComplete="new-password"
|
|
565
570
|
/>
|
|
566
571
|
</label>
|
|
567
572
|
|
|
568
573
|
<button
|
|
569
574
|
type="submit"
|
|
570
|
-
style={submitButton}
|
|
575
|
+
style={styles.submitButton}
|
|
571
576
|
disabled={loading}
|
|
572
577
|
aria-disabled={loading}
|
|
573
578
|
>
|
|
@@ -576,14 +581,14 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
576
581
|
</form>
|
|
577
582
|
</div>
|
|
578
583
|
|
|
579
|
-
<div style={modalFooter}>
|
|
580
|
-
<div style={belowRow}>
|
|
581
|
-
<span style={muted}>Already have an account? </span>
|
|
582
|
-
<Link href="/sign-in" style={link}>Sign in</Link>
|
|
584
|
+
<div style={styles.modalFooter}>
|
|
585
|
+
<div style={styles.belowRow}>
|
|
586
|
+
<span style={styles.muted}>Already have an account? </span>
|
|
587
|
+
<Link href="/sign-in" style={styles.link}>Sign in</Link>
|
|
583
588
|
</div>
|
|
584
|
-
<div style={dividerThin} />
|
|
585
|
-
<div style={secured}>
|
|
586
|
-
<div style={securedText}>Secured by auth</div>
|
|
589
|
+
<div style={styles.dividerThin} />
|
|
590
|
+
<div style={styles.secured}>
|
|
591
|
+
<div style={styles.securedText}>Secured by auth</div>
|
|
587
592
|
</div>
|
|
588
593
|
</div>
|
|
589
594
|
</div>
|
|
@@ -591,271 +596,273 @@ export default function SignUp({ agency = { name: 'MyApp', logo: '' } }) {
|
|
|
591
596
|
)
|
|
592
597
|
}
|
|
593
598
|
|
|
594
|
-
/*
|
|
595
|
-
const
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
599
|
+
/* Styles (JS objects) - reduced width and zoom-resilient layout; neutral palette */
|
|
600
|
+
const styles = {
|
|
601
|
+
overlay: {
|
|
602
|
+
position: 'fixed',
|
|
603
|
+
inset: 0,
|
|
604
|
+
display: 'block', // use block + scrolling container for zoom resilience
|
|
605
|
+
padding: 20,
|
|
606
|
+
background: 'linear-gradient(180deg, rgba(2,6,23,0.22), rgba(2,6,23,0.32))',
|
|
607
|
+
backdropFilter: 'blur(6px)',
|
|
608
|
+
overflowY: 'auto', // allow page scroll when zoomed
|
|
609
|
+
WebkitOverflowScrolling: 'touch',
|
|
610
|
+
minHeight: '100vh',
|
|
611
|
+
zIndex: 9999
|
|
612
|
+
},
|
|
613
|
+
|
|
614
|
+
// modal: reduced width (not too wide), centered with margin auto, allows internal scroll
|
|
615
|
+
modal: {
|
|
616
|
+
width: '100%',
|
|
617
|
+
maxWidth: 460, // reduced width per request
|
|
618
|
+
margin: '40px auto', // vertical margin so modal isn't glued to top when zoomed
|
|
619
|
+
borderRadius: 14,
|
|
620
|
+
background: 'linear-gradient(180deg, rgba(15,19,24,0.85), rgba(10,12,16,0.85))', // translucent neutral
|
|
621
|
+
border: '1px solid rgba(99,102,106,0.12)', // visible neutral border
|
|
622
|
+
boxShadow: '0 18px 48px rgba(2,6,23,0.55), inset 0 1px 0 rgba(255,255,255,0.02)',
|
|
623
|
+
overflow: 'hidden',
|
|
624
|
+
display: 'flex',
|
|
625
|
+
flexDirection: 'column',
|
|
626
|
+
maxHeight: 'calc(100vh - 80px)', // keep inside viewport
|
|
627
|
+
},
|
|
628
|
+
|
|
629
|
+
modalInner: {
|
|
630
|
+
padding: 18,
|
|
631
|
+
display: 'flex',
|
|
632
|
+
flexDirection: 'column',
|
|
633
|
+
gap: 12,
|
|
634
|
+
overflowY: 'auto'
|
|
635
|
+
},
|
|
636
|
+
|
|
637
|
+
header: {
|
|
638
|
+
paddingBottom: 6,
|
|
639
|
+
borderBottom: '1px solid rgba(148,163,184,0.04)'
|
|
640
|
+
},
|
|
641
|
+
|
|
642
|
+
brandRow: {
|
|
643
|
+
display: 'flex',
|
|
644
|
+
alignItems: 'center',
|
|
645
|
+
gap: 12
|
|
646
|
+
},
|
|
647
|
+
|
|
648
|
+
logo: {
|
|
649
|
+
width: 44,
|
|
650
|
+
height: 44,
|
|
651
|
+
display: 'flex',
|
|
652
|
+
alignItems: 'center',
|
|
653
|
+
justifyContent: 'center'
|
|
654
|
+
},
|
|
655
|
+
|
|
656
|
+
logoCircle: {
|
|
657
|
+
width: 36,
|
|
658
|
+
height: 36,
|
|
659
|
+
borderRadius: 999,
|
|
660
|
+
background: 'linear-gradient(135deg,#2f3438,#11151a)',
|
|
661
|
+
boxShadow: '0 4px 12px rgba(2,6,23,0.6)'
|
|
662
|
+
},
|
|
663
|
+
|
|
664
|
+
title: {
|
|
665
|
+
margin: 0,
|
|
666
|
+
fontSize: 18,
|
|
667
|
+
fontWeight: 600,
|
|
668
|
+
color: '#e6e6e6'
|
|
669
|
+
},
|
|
670
|
+
|
|
671
|
+
subtitle: {
|
|
672
|
+
fontSize: 13,
|
|
673
|
+
color: 'rgba(230,230,230,0.72)',
|
|
674
|
+
marginTop: 4
|
|
675
|
+
},
|
|
676
|
+
|
|
677
|
+
oauthSection: {
|
|
678
|
+
marginTop: 8,
|
|
679
|
+
display: 'flex',
|
|
680
|
+
gap: 8
|
|
681
|
+
},
|
|
682
|
+
|
|
683
|
+
oauthButton: {
|
|
684
|
+
flex: 1,
|
|
685
|
+
display: 'inline-flex',
|
|
686
|
+
alignItems: 'center',
|
|
687
|
+
justifyContent: 'center',
|
|
688
|
+
padding: '10px 12px',
|
|
689
|
+
borderRadius: 10,
|
|
690
|
+
border: '1px solid rgba(148,163,184,0.08)',
|
|
691
|
+
fontSize: 14,
|
|
692
|
+
cursor: 'pointer',
|
|
693
|
+
userSelect: 'none',
|
|
694
|
+
gap: 8,
|
|
695
|
+
minHeight: 40,
|
|
696
|
+
background: 'transparent',
|
|
697
|
+
color: '#fff'
|
|
698
|
+
},
|
|
699
|
+
|
|
700
|
+
oauthGoogle: {
|
|
701
|
+
background: 'linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.01))'
|
|
702
|
+
},
|
|
703
|
+
|
|
704
|
+
oauthGithub: {
|
|
705
|
+
background: 'linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.00))'
|
|
706
|
+
},
|
|
707
|
+
|
|
708
|
+
dividerRow: {
|
|
709
|
+
display: 'flex',
|
|
710
|
+
alignItems: 'center',
|
|
711
|
+
gap: 10,
|
|
712
|
+
marginTop: 12
|
|
713
|
+
},
|
|
714
|
+
|
|
715
|
+
line: {
|
|
716
|
+
flex: 1,
|
|
717
|
+
height: 1,
|
|
718
|
+
background: 'rgba(148,163,184,0.06)'
|
|
719
|
+
},
|
|
720
|
+
|
|
721
|
+
orText: {
|
|
722
|
+
fontSize: 13,
|
|
723
|
+
color: 'rgba(230,230,230,0.65)',
|
|
724
|
+
padding: '0 8px'
|
|
725
|
+
},
|
|
726
|
+
|
|
727
|
+
form: {
|
|
728
|
+
display: 'flex',
|
|
729
|
+
flexDirection: 'column',
|
|
730
|
+
gap: 10,
|
|
731
|
+
marginTop: 6
|
|
732
|
+
},
|
|
733
|
+
|
|
734
|
+
label: {
|
|
735
|
+
display: 'flex',
|
|
736
|
+
flexDirection: 'column',
|
|
737
|
+
gap: 6
|
|
738
|
+
},
|
|
739
|
+
|
|
740
|
+
labelText: {
|
|
741
|
+
fontSize: 13,
|
|
742
|
+
color: 'rgba(230,230,230,0.68)'
|
|
743
|
+
},
|
|
744
|
+
|
|
745
|
+
input: {
|
|
746
|
+
width: '100%',
|
|
747
|
+
padding: '10px 12px',
|
|
748
|
+
borderRadius: 10,
|
|
749
|
+
background: 'rgba(255,255,255,0.02)',
|
|
750
|
+
color: '#e6e6e6',
|
|
751
|
+
border: '1px solid rgba(148,163,184,0.10)',
|
|
752
|
+
fontSize: 14,
|
|
753
|
+
outline: 'none',
|
|
754
|
+
boxSizing: 'border-box',
|
|
755
|
+
transition: 'box-shadow 120ms, border-color 120ms'
|
|
756
|
+
},
|
|
757
|
+
|
|
758
|
+
submitButton: {
|
|
759
|
+
marginTop: 6,
|
|
760
|
+
width: '100%',
|
|
761
|
+
padding: '10px 12px',
|
|
762
|
+
borderRadius: 10,
|
|
763
|
+
background: 'linear-gradient(180deg,#475569,#94a3b8)',
|
|
764
|
+
border: 'none',
|
|
765
|
+
color: '#fff',
|
|
766
|
+
fontWeight: 600,
|
|
767
|
+
cursor: 'pointer',
|
|
768
|
+
fontSize: 15,
|
|
769
|
+
display: 'inline-flex',
|
|
770
|
+
alignItems: 'center',
|
|
771
|
+
justifyContent: 'center',
|
|
772
|
+
minHeight: 44
|
|
773
|
+
},
|
|
774
|
+
|
|
775
|
+
modalFooter: {
|
|
776
|
+
padding: '12px 18px 18px 18px',
|
|
777
|
+
borderTop: '1px solid rgba(148,163,184,0.03)',
|
|
778
|
+
display: 'flex',
|
|
779
|
+
flexDirection: 'column',
|
|
780
|
+
gap: 8
|
|
781
|
+
},
|
|
782
|
+
|
|
783
|
+
belowRow: {
|
|
784
|
+
textAlign: 'center',
|
|
785
|
+
display: 'flex',
|
|
786
|
+
justifyContent: 'center',
|
|
787
|
+
gap: 8,
|
|
788
|
+
alignItems: 'center'
|
|
789
|
+
},
|
|
790
|
+
|
|
791
|
+
muted: {
|
|
792
|
+
color: 'rgba(230,230,230,0.66)',
|
|
793
|
+
fontSize: 13
|
|
794
|
+
},
|
|
795
|
+
|
|
796
|
+
link: {
|
|
797
|
+
color: '#9fb0d9',
|
|
798
|
+
textDecoration: 'none',
|
|
799
|
+
fontWeight: 600
|
|
800
|
+
},
|
|
801
|
+
|
|
802
|
+
dividerThin: {
|
|
803
|
+
height: 1,
|
|
804
|
+
background: 'rgba(148,163,184,0.04)',
|
|
805
|
+
marginTop: 6,
|
|
806
|
+
marginBottom: 6
|
|
807
|
+
},
|
|
808
|
+
|
|
809
|
+
secured: {
|
|
810
|
+
textAlign: 'center'
|
|
811
|
+
},
|
|
812
|
+
|
|
813
|
+
securedText: {
|
|
814
|
+
color: 'rgba(230,230,230,0.9)',
|
|
815
|
+
fontSize: 13,
|
|
816
|
+
fontWeight: 600
|
|
817
|
+
},
|
|
818
|
+
|
|
819
|
+
/* Toasts: black background */
|
|
820
|
+
toastContainer: {
|
|
821
|
+
position: 'fixed',
|
|
822
|
+
top: 18,
|
|
823
|
+
right: 18,
|
|
824
|
+
width: 360,
|
|
825
|
+
maxWidth: 'calc(100% - 36px)',
|
|
826
|
+
display: 'flex',
|
|
827
|
+
flexDirection: 'column',
|
|
828
|
+
gap: 10,
|
|
829
|
+
zIndex: 60000
|
|
830
|
+
},
|
|
831
|
+
|
|
832
|
+
toastBase: {
|
|
833
|
+
display: 'flex',
|
|
834
|
+
gap: 10,
|
|
835
|
+
alignItems: 'center',
|
|
836
|
+
padding: '10px 12px',
|
|
837
|
+
borderRadius: 10,
|
|
838
|
+
boxShadow: '0 8px 20px rgba(2,6,23,0.6)',
|
|
839
|
+
color: '#fff',
|
|
840
|
+
fontSize: 13,
|
|
841
|
+
minWidth: 120
|
|
842
|
+
},
|
|
843
|
+
|
|
844
|
+
toastError: {
|
|
845
|
+
background: '#000000',
|
|
846
|
+
border: '1px solid rgba(255,255,255,0.06)'
|
|
847
|
+
},
|
|
848
|
+
|
|
849
|
+
toastSuccess: {
|
|
850
|
+
background: '#000000',
|
|
851
|
+
border: '1px solid rgba(255,255,255,0.06)'
|
|
852
|
+
},
|
|
853
|
+
|
|
854
|
+
toastInfo: {
|
|
855
|
+
background: '#000000',
|
|
856
|
+
border: '1px solid rgba(255,255,255,0.06)'
|
|
857
|
+
},
|
|
858
|
+
|
|
859
|
+
toastCloseBtn: {
|
|
860
|
+
marginLeft: 8,
|
|
861
|
+
background: 'transparent',
|
|
862
|
+
border: 'none',
|
|
863
|
+
color: 'rgba(255,255,255,0.7)',
|
|
864
|
+
cursor: 'pointer',
|
|
865
|
+
fontSize: 14,
|
|
866
|
+
lineHeight: 1
|
|
867
|
+
}
|
|
861
868
|
}
|