@visns-studio/visns-components 6.3.17 → 6.4.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.
|
@@ -22,10 +22,54 @@ import TwoFactorAuth from '../auth/TwoFactorAuth';
|
|
|
22
22
|
import ClientLogin from '../auth/ClientLogin';
|
|
23
23
|
import ClientOTPVerify from '../auth/ClientOTPVerify';
|
|
24
24
|
|
|
25
|
+
// Shown while the profile check is in flight. Rendering null there leaves a
|
|
26
|
+
// blank white page between the sign-in redirect and the first authenticated
|
|
27
|
+
// paint. Self-contained: SMIL animation, no stylesheet dependency, and the
|
|
28
|
+
// consuming app's design tokens with neutral fallbacks.
|
|
29
|
+
const AuthLoading = () => (
|
|
30
|
+
<div
|
|
31
|
+
role="status"
|
|
32
|
+
aria-label="Loading"
|
|
33
|
+
style={{
|
|
34
|
+
position: 'fixed',
|
|
35
|
+
inset: 0,
|
|
36
|
+
display: 'flex',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
justifyContent: 'center',
|
|
39
|
+
background: 'var(--bg-color, #f4f4f5)',
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
<svg width="42" height="42" viewBox="0 0 42 42" fill="none">
|
|
43
|
+
<circle
|
|
44
|
+
cx="21"
|
|
45
|
+
cy="21"
|
|
46
|
+
r="18"
|
|
47
|
+
stroke="var(--border-color, #dfe3eb)"
|
|
48
|
+
strokeWidth="4"
|
|
49
|
+
/>
|
|
50
|
+
<path
|
|
51
|
+
d="M39 21a18 18 0 0 0-18-18"
|
|
52
|
+
stroke="var(--primary-color, #52525b)"
|
|
53
|
+
strokeWidth="4"
|
|
54
|
+
strokeLinecap="round"
|
|
55
|
+
>
|
|
56
|
+
<animateTransform
|
|
57
|
+
attributeName="transform"
|
|
58
|
+
type="rotate"
|
|
59
|
+
from="0 21 21"
|
|
60
|
+
to="360 21 21"
|
|
61
|
+
dur="0.9s"
|
|
62
|
+
repeatCount="indefinite"
|
|
63
|
+
/>
|
|
64
|
+
</path>
|
|
65
|
+
</svg>
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
|
|
25
69
|
const ProtectedRoute = ({ user, loading, redirectPath = '/login' }) => {
|
|
26
70
|
const location = useLocation();
|
|
27
71
|
|
|
28
|
-
return loading ?
|
|
72
|
+
return loading ? <AuthLoading /> : !user || !user.id ? (
|
|
29
73
|
<Navigate
|
|
30
74
|
to={redirectPath}
|
|
31
75
|
replace
|
|
@@ -43,7 +87,7 @@ const ClientProtectedRoute = ({
|
|
|
43
87
|
}) => {
|
|
44
88
|
const location = useLocation();
|
|
45
89
|
|
|
46
|
-
return loading ?
|
|
90
|
+
return loading ? <AuthLoading /> : !clientUser || !clientUser.id ? (
|
|
47
91
|
<Navigate
|
|
48
92
|
to={redirectPath}
|
|
49
93
|
replace
|
|
@@ -971,10 +971,22 @@
|
|
|
971
971
|
|
|
972
972
|
.aside--cms {
|
|
973
973
|
width: 100%;
|
|
974
|
+
/* The content header is sticky at z-index 995, so the drawer sits
|
|
975
|
+
below it: start the drawer under the 50px header instead of
|
|
976
|
+
letting the header paint over the drawer's top row. This also
|
|
977
|
+
keeps the hamburger tappable while the drawer is open. */
|
|
978
|
+
top: 50px;
|
|
979
|
+
height: calc(100% - 50px);
|
|
974
980
|
transform: translateX(-2000px);
|
|
975
981
|
transition: all 0.55s cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
976
982
|
will-change: transform;
|
|
977
983
|
z-index: 600;
|
|
984
|
+
|
|
985
|
+
/* The header already anchors the screen; the drawer's own logo
|
|
986
|
+
plate would render as a second 50px brand row. */
|
|
987
|
+
.logo {
|
|
988
|
+
display: none;
|
|
989
|
+
}
|
|
978
990
|
}
|
|
979
991
|
|
|
980
992
|
.aside--cms--open {
|