@authdog/react-elements 0.0.35 → 0.0.37
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/.turbo/turbo-build.log +39 -39
- package/CHANGELOG.md +13 -0
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +85 -28
- package/package.json +3 -3
- package/src/components/core/user-dropdown.tsx +3 -3
- package/src/components/core/user-profile.tsx +76 -6
- package/src/stories/UserProfile.stories.tsx +42 -63
package/dist/styles.css
CHANGED
|
@@ -665,6 +665,9 @@ video {
|
|
|
665
665
|
.mt-1 {
|
|
666
666
|
margin-top: 0.25rem;
|
|
667
667
|
}
|
|
668
|
+
.mt-2 {
|
|
669
|
+
margin-top: 0.5rem;
|
|
670
|
+
}
|
|
668
671
|
.mt-auto {
|
|
669
672
|
margin-top: auto;
|
|
670
673
|
}
|
|
@@ -871,6 +874,9 @@ video {
|
|
|
871
874
|
.items-center {
|
|
872
875
|
align-items: center;
|
|
873
876
|
}
|
|
877
|
+
.justify-end {
|
|
878
|
+
justify-content: flex-end;
|
|
879
|
+
}
|
|
874
880
|
.justify-center {
|
|
875
881
|
justify-content: center;
|
|
876
882
|
}
|
|
@@ -998,9 +1004,9 @@ video {
|
|
|
998
1004
|
.border-none {
|
|
999
1005
|
border-style: none;
|
|
1000
1006
|
}
|
|
1001
|
-
.border-amber-
|
|
1007
|
+
.border-amber-300 {
|
|
1002
1008
|
--tw-border-opacity: 1;
|
|
1003
|
-
border-color: rgb(
|
|
1009
|
+
border-color: rgb(252 211 77 / var(--tw-border-opacity, 1));
|
|
1004
1010
|
}
|
|
1005
1011
|
.border-border {
|
|
1006
1012
|
border-color: hsl(var(--border));
|
|
@@ -1009,9 +1015,9 @@ video {
|
|
|
1009
1015
|
--tw-border-opacity: 1;
|
|
1010
1016
|
border-color: rgb(187 247 208 / var(--tw-border-opacity, 1));
|
|
1011
1017
|
}
|
|
1012
|
-
.border-green-
|
|
1018
|
+
.border-green-300 {
|
|
1013
1019
|
--tw-border-opacity: 1;
|
|
1014
|
-
border-color: rgb(
|
|
1020
|
+
border-color: rgb(134 239 172 / var(--tw-border-opacity, 1));
|
|
1015
1021
|
}
|
|
1016
1022
|
.border-input {
|
|
1017
1023
|
border-color: hsl(var(--input));
|
|
@@ -1019,9 +1025,9 @@ video {
|
|
|
1019
1025
|
.border-transparent {
|
|
1020
1026
|
border-color: transparent;
|
|
1021
1027
|
}
|
|
1022
|
-
.bg-amber-
|
|
1028
|
+
.bg-amber-100 {
|
|
1023
1029
|
--tw-bg-opacity: 1;
|
|
1024
|
-
background-color: rgb(
|
|
1030
|
+
background-color: rgb(254 243 199 / var(--tw-bg-opacity, 1));
|
|
1025
1031
|
}
|
|
1026
1032
|
.bg-background {
|
|
1027
1033
|
background-color: hsl(var(--background));
|
|
@@ -1062,10 +1068,6 @@ video {
|
|
|
1062
1068
|
--tw-bg-opacity: 1;
|
|
1063
1069
|
background-color: rgb(240 253 244 / var(--tw-bg-opacity, 1));
|
|
1064
1070
|
}
|
|
1065
|
-
.bg-green-600 {
|
|
1066
|
-
--tw-bg-opacity: 1;
|
|
1067
|
-
background-color: rgb(22 163 74 / var(--tw-bg-opacity, 1));
|
|
1068
|
-
}
|
|
1069
1071
|
.bg-muted {
|
|
1070
1072
|
background-color: hsl(var(--muted));
|
|
1071
1073
|
}
|
|
@@ -1117,10 +1119,17 @@ video {
|
|
|
1117
1119
|
.p-4 {
|
|
1118
1120
|
padding: 1rem;
|
|
1119
1121
|
}
|
|
1122
|
+
.p-6 {
|
|
1123
|
+
padding: 1.5rem;
|
|
1124
|
+
}
|
|
1120
1125
|
.px-2 {
|
|
1121
1126
|
padding-left: 0.5rem;
|
|
1122
1127
|
padding-right: 0.5rem;
|
|
1123
1128
|
}
|
|
1129
|
+
.px-2\.5 {
|
|
1130
|
+
padding-left: 0.625rem;
|
|
1131
|
+
padding-right: 0.625rem;
|
|
1132
|
+
}
|
|
1124
1133
|
.px-3 {
|
|
1125
1134
|
padding-left: 0.75rem;
|
|
1126
1135
|
padding-right: 0.75rem;
|
|
@@ -1231,6 +1240,10 @@ video {
|
|
|
1231
1240
|
.tracking-widest {
|
|
1232
1241
|
letter-spacing: 0.1em;
|
|
1233
1242
|
}
|
|
1243
|
+
.text-amber-800 {
|
|
1244
|
+
--tw-text-opacity: 1;
|
|
1245
|
+
color: rgb(146 64 14 / var(--tw-text-opacity, 1));
|
|
1246
|
+
}
|
|
1234
1247
|
.text-blue-600 {
|
|
1235
1248
|
--tw-text-opacity: 1;
|
|
1236
1249
|
color: rgb(37 99 235 / var(--tw-text-opacity, 1));
|
|
@@ -1271,6 +1284,10 @@ video {
|
|
|
1271
1284
|
--tw-text-opacity: 1;
|
|
1272
1285
|
color: rgb(21 128 61 / var(--tw-text-opacity, 1));
|
|
1273
1286
|
}
|
|
1287
|
+
.text-green-800 {
|
|
1288
|
+
--tw-text-opacity: 1;
|
|
1289
|
+
color: rgb(22 101 52 / var(--tw-text-opacity, 1));
|
|
1290
|
+
}
|
|
1274
1291
|
.text-green-900 {
|
|
1275
1292
|
--tw-text-opacity: 1;
|
|
1276
1293
|
color: rgb(20 83 45 / var(--tw-text-opacity, 1));
|
|
@@ -1338,6 +1355,11 @@ video {
|
|
|
1338
1355
|
.outline {
|
|
1339
1356
|
outline-style: solid;
|
|
1340
1357
|
}
|
|
1358
|
+
.ring-0 {
|
|
1359
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1360
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1361
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1362
|
+
}
|
|
1341
1363
|
.ring-offset-background {
|
|
1342
1364
|
--tw-ring-offset-color: hsl(var(--background));
|
|
1343
1365
|
}
|
|
@@ -1458,6 +1480,10 @@ video {
|
|
|
1458
1480
|
.hover\:bg-primary\/90:hover {
|
|
1459
1481
|
background-color: hsl(var(--primary) / 0.9);
|
|
1460
1482
|
}
|
|
1483
|
+
.hover\:bg-red-50:hover {
|
|
1484
|
+
--tw-bg-opacity: 1;
|
|
1485
|
+
background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1));
|
|
1486
|
+
}
|
|
1461
1487
|
.hover\:bg-secondary\/80:hover {
|
|
1462
1488
|
background-color: hsl(var(--secondary) / 0.8);
|
|
1463
1489
|
}
|
|
@@ -1471,6 +1497,10 @@ video {
|
|
|
1471
1497
|
.hover\:text-primary:hover {
|
|
1472
1498
|
color: hsl(var(--primary));
|
|
1473
1499
|
}
|
|
1500
|
+
.hover\:text-red-700:hover {
|
|
1501
|
+
--tw-text-opacity: 1;
|
|
1502
|
+
color: rgb(185 28 28 / var(--tw-text-opacity, 1));
|
|
1503
|
+
}
|
|
1474
1504
|
.hover\:underline:hover {
|
|
1475
1505
|
text-decoration-line: underline;
|
|
1476
1506
|
}
|
|
@@ -1480,6 +1510,10 @@ video {
|
|
|
1480
1510
|
.focus\:bg-accent:focus {
|
|
1481
1511
|
background-color: hsl(var(--accent));
|
|
1482
1512
|
}
|
|
1513
|
+
.focus\:bg-red-50:focus {
|
|
1514
|
+
--tw-bg-opacity: 1;
|
|
1515
|
+
background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1));
|
|
1516
|
+
}
|
|
1483
1517
|
.focus\:text-accent-foreground:focus {
|
|
1484
1518
|
color: hsl(var(--accent-foreground));
|
|
1485
1519
|
}
|
|
@@ -1487,10 +1521,6 @@ video {
|
|
|
1487
1521
|
--tw-text-opacity: 1;
|
|
1488
1522
|
color: rgb(185 28 28 / var(--tw-text-opacity, 1));
|
|
1489
1523
|
}
|
|
1490
|
-
.focus\:outline-none:focus {
|
|
1491
|
-
outline: 2px solid transparent;
|
|
1492
|
-
outline-offset: 2px;
|
|
1493
|
-
}
|
|
1494
1524
|
.focus\:ring-2:focus {
|
|
1495
1525
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1496
1526
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
@@ -1522,6 +1552,9 @@ video {
|
|
|
1522
1552
|
.focus-visible\:ring-destructive\/20:focus-visible {
|
|
1523
1553
|
--tw-ring-color: hsl(var(--destructive) / 0.2);
|
|
1524
1554
|
}
|
|
1555
|
+
.focus-visible\:ring-red-400\/40:focus-visible {
|
|
1556
|
+
--tw-ring-color: rgb(248 113 113 / 0.4);
|
|
1557
|
+
}
|
|
1525
1558
|
.focus-visible\:ring-ring:focus-visible {
|
|
1526
1559
|
--tw-ring-color: hsl(var(--ring));
|
|
1527
1560
|
}
|
|
@@ -1679,24 +1712,23 @@ video {
|
|
|
1679
1712
|
.group[data-disabled="true"] .group-data-\[disabled\=true\]\:opacity-50 {
|
|
1680
1713
|
opacity: 0.5;
|
|
1681
1714
|
}
|
|
1682
|
-
.dark\:border-amber-
|
|
1683
|
-
|
|
1684
|
-
border-color: rgb(217 119 6 / var(--tw-border-opacity, 1));
|
|
1715
|
+
.dark\:border-amber-400\/40:is(.dark *) {
|
|
1716
|
+
border-color: rgb(251 191 36 / 0.4);
|
|
1685
1717
|
}
|
|
1686
|
-
.dark\:border-green-
|
|
1687
|
-
|
|
1688
|
-
border-color: rgb(22 163 74 / var(--tw-border-opacity, 1));
|
|
1718
|
+
.dark\:border-green-400\/40:is(.dark *) {
|
|
1719
|
+
border-color: rgb(74 222 128 / 0.4);
|
|
1689
1720
|
}
|
|
1690
|
-
.dark\:
|
|
1691
|
-
|
|
1692
|
-
|
|
1721
|
+
.dark\:border-red-500\/30:is(.dark *) {
|
|
1722
|
+
border-color: rgb(239 68 68 / 0.3);
|
|
1723
|
+
}
|
|
1724
|
+
.dark\:bg-amber-500\/20:is(.dark *) {
|
|
1725
|
+
background-color: rgb(245 158 11 / 0.2);
|
|
1693
1726
|
}
|
|
1694
1727
|
.dark\:bg-destructive\/60:is(.dark *) {
|
|
1695
1728
|
background-color: hsl(var(--destructive) / 0.6);
|
|
1696
1729
|
}
|
|
1697
|
-
.dark\:bg-green-500:is(.dark *) {
|
|
1698
|
-
|
|
1699
|
-
background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
|
|
1730
|
+
.dark\:bg-green-500\/20:is(.dark *) {
|
|
1731
|
+
background-color: rgb(34 197 94 / 0.2);
|
|
1700
1732
|
}
|
|
1701
1733
|
.dark\:bg-input\/30:is(.dark *) {
|
|
1702
1734
|
background-color: hsl(var(--input) / 0.3);
|
|
@@ -1705,6 +1737,10 @@ video {
|
|
|
1705
1737
|
--tw-bg-opacity: 1;
|
|
1706
1738
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
|
1707
1739
|
}
|
|
1740
|
+
.dark\:text-amber-200:is(.dark *) {
|
|
1741
|
+
--tw-text-opacity: 1;
|
|
1742
|
+
color: rgb(253 230 138 / var(--tw-text-opacity, 1));
|
|
1743
|
+
}
|
|
1708
1744
|
.dark\:text-gray-100:is(.dark *) {
|
|
1709
1745
|
--tw-text-opacity: 1;
|
|
1710
1746
|
color: rgb(243 244 246 / var(--tw-text-opacity, 1));
|
|
@@ -1717,13 +1753,34 @@ video {
|
|
|
1717
1753
|
--tw-text-opacity: 1;
|
|
1718
1754
|
color: rgb(156 163 175 / var(--tw-text-opacity, 1));
|
|
1719
1755
|
}
|
|
1720
|
-
.dark\:text-
|
|
1756
|
+
.dark\:text-green-200:is(.dark *) {
|
|
1721
1757
|
--tw-text-opacity: 1;
|
|
1722
|
-
color: rgb(
|
|
1758
|
+
color: rgb(187 247 208 / var(--tw-text-opacity, 1));
|
|
1759
|
+
}
|
|
1760
|
+
.dark\:text-red-300:is(.dark *) {
|
|
1761
|
+
--tw-text-opacity: 1;
|
|
1762
|
+
color: rgb(252 165 165 / var(--tw-text-opacity, 1));
|
|
1763
|
+
}
|
|
1764
|
+
.dark\:hover\:bg-red-500\/20:hover:is(.dark *) {
|
|
1765
|
+
background-color: rgb(239 68 68 / 0.2);
|
|
1766
|
+
}
|
|
1767
|
+
.dark\:hover\:text-red-100:hover:is(.dark *) {
|
|
1768
|
+
--tw-text-opacity: 1;
|
|
1769
|
+
color: rgb(254 226 226 / var(--tw-text-opacity, 1));
|
|
1770
|
+
}
|
|
1771
|
+
.dark\:focus\:bg-red-500\/25:focus:is(.dark *) {
|
|
1772
|
+
background-color: rgb(239 68 68 / 0.25);
|
|
1773
|
+
}
|
|
1774
|
+
.dark\:focus\:text-red-100:focus:is(.dark *) {
|
|
1775
|
+
--tw-text-opacity: 1;
|
|
1776
|
+
color: rgb(254 226 226 / var(--tw-text-opacity, 1));
|
|
1723
1777
|
}
|
|
1724
1778
|
.dark\:focus-visible\:ring-destructive\/40:focus-visible:is(.dark *) {
|
|
1725
1779
|
--tw-ring-color: hsl(var(--destructive) / 0.4);
|
|
1726
1780
|
}
|
|
1781
|
+
.dark\:focus-visible\:ring-red-400\/40:focus-visible:is(.dark *) {
|
|
1782
|
+
--tw-ring-color: rgb(248 113 113 / 0.4);
|
|
1783
|
+
}
|
|
1727
1784
|
.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:focus[data-variant="destructive"]:is(.dark *) {
|
|
1728
1785
|
background-color: hsl(var(--destructive) / 0.2);
|
|
1729
1786
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@authdog/react-elements",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.37",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.mts",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"ts-loader": "^9.5.1",
|
|
26
26
|
"typescript": "^5.6.3",
|
|
27
27
|
"webpack": "^5.89.0",
|
|
28
|
-
"@authdog/
|
|
29
|
-
"@authdog/
|
|
28
|
+
"@authdog/eslint-config": "0.0.0",
|
|
29
|
+
"@authdog/typescript-config": "0.0.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@radix-ui/react-avatar": "^1.1.9",
|
|
@@ -58,7 +58,7 @@ export const UserDropdown = ({ trigger, user, className, onManageAccount, onSign
|
|
|
58
58
|
|
|
59
59
|
return (
|
|
60
60
|
<DropdownMenu>
|
|
61
|
-
<DropdownMenuTrigger
|
|
61
|
+
<DropdownMenuTrigger asChild>
|
|
62
62
|
{trigger}
|
|
63
63
|
</DropdownMenuTrigger>
|
|
64
64
|
<DropdownMenuContent align={align} side={side} sideOffset={sideOffset} className={cn("w-72 p-2 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md", className)}>
|
|
@@ -87,8 +87,8 @@ export const UserDropdown = ({ trigger, user, className, onManageAccount, onSign
|
|
|
87
87
|
)
|
|
88
88
|
})}
|
|
89
89
|
<DropdownMenuSeparator />
|
|
90
|
-
<DropdownMenuItem className="cursor-pointer text-red-600 focus:text-red-700
|
|
91
|
-
<LogOut className="mr-2 h-4 w-4" />
|
|
90
|
+
<DropdownMenuItem className="cursor-pointer py-2 rounded-md font-semibold text-red-600 dark:text-red-300 hover:bg-red-50 hover:text-red-700 focus:bg-red-50 focus:text-red-700 dark:hover:bg-red-500/20 dark:focus:bg-red-500/25 dark:hover:text-red-100 dark:focus:text-red-100 border border-transparent dark:border-red-500/30 ring-0 focus-visible:ring-2 focus-visible:ring-red-400/40 dark:focus-visible:ring-red-400/40" onClick={() => onSignout?.()}>
|
|
91
|
+
<LogOut className="mr-2 h-4 w-4 text-red-600 dark:text-red-300" />
|
|
92
92
|
<span>Sign out</span>
|
|
93
93
|
</DropdownMenuItem>
|
|
94
94
|
</DropdownMenuContent>
|
|
@@ -4,6 +4,16 @@ import { useEffect, useState } from "react"
|
|
|
4
4
|
import { Avatar, AvatarFallback, AvatarImage } from "../../components/ui/avatar"
|
|
5
5
|
import { Button } from "../../components/ui/button"
|
|
6
6
|
import { Badge } from "../../components/ui/badge"
|
|
7
|
+
import {
|
|
8
|
+
Card,
|
|
9
|
+
CardHeader,
|
|
10
|
+
CardTitle,
|
|
11
|
+
CardDescription,
|
|
12
|
+
CardContent,
|
|
13
|
+
CardFooter,
|
|
14
|
+
} from "../../components/ui/card"
|
|
15
|
+
import { Input } from "../../components/ui/input"
|
|
16
|
+
import { Label } from "../../components/ui/label"
|
|
7
17
|
import { User, Shield, SlidersHorizontal, LucideProps } from "lucide-react"
|
|
8
18
|
|
|
9
19
|
export interface UserProfileProps {
|
|
@@ -13,6 +23,7 @@ export interface UserProfileProps {
|
|
|
13
23
|
handleAuthenticated?: () => void;
|
|
14
24
|
onRequestEmailVerification?: (email: string) => Promise<{ success: boolean; message?: string } | void>;
|
|
15
25
|
onVerifyEmail?: (email: string, code: string) => Promise<{ success: boolean; message?: string } | void>;
|
|
26
|
+
onAddEmail?: (email: string) => Promise<{ success: boolean; message?: string } | void>;
|
|
16
27
|
}
|
|
17
28
|
|
|
18
29
|
export const UserProfile = ({
|
|
@@ -21,11 +32,14 @@ export const UserProfile = ({
|
|
|
21
32
|
handleAuthenticated,
|
|
22
33
|
onRequestEmailVerification,
|
|
23
34
|
onVerifyEmail,
|
|
35
|
+
onAddEmail,
|
|
24
36
|
}: UserProfileProps) => {
|
|
25
37
|
const [isMounted, setIsMounted] = useState(false)
|
|
26
38
|
const [activeTab, setActiveTab] = useState<"profile" | "security" | "preferences">("profile");
|
|
27
39
|
const [verifyingEmail, setVerifyingEmail] = useState<string | null>(null)
|
|
28
40
|
const [codeByEmail, setCodeByEmail] = useState<Record<string, string>>({})
|
|
41
|
+
const [addingEmail, setAddingEmail] = useState<boolean>(false)
|
|
42
|
+
const [newEmail, setNewEmail] = useState<string>("")
|
|
29
43
|
|
|
30
44
|
useEffect(() => {
|
|
31
45
|
setIsMounted(true);
|
|
@@ -161,11 +175,11 @@ export const UserProfile = ({
|
|
|
161
175
|
<span className="text-foreground">{email.value}</span>
|
|
162
176
|
<div className="mt-1">
|
|
163
177
|
{isVerified ? (
|
|
164
|
-
<Badge className="text-xs bg-green-
|
|
178
|
+
<Badge className="text-xs rounded-full px-2.5 py-0.5 bg-green-100 text-green-800 border border-green-300 dark:bg-green-500/20 dark:text-green-200 dark:border-green-400/40">
|
|
165
179
|
Verified
|
|
166
180
|
</Badge>
|
|
167
181
|
) : (
|
|
168
|
-
<Badge className="text-xs bg-amber-
|
|
182
|
+
<Badge className="text-xs rounded-full px-2.5 py-0.5 bg-amber-100 text-amber-800 border border-amber-300 dark:bg-amber-500/20 dark:text-amber-200 dark:border-amber-400/40">
|
|
169
183
|
Not verified
|
|
170
184
|
</Badge>
|
|
171
185
|
)}
|
|
@@ -225,10 +239,66 @@ export const UserProfile = ({
|
|
|
225
239
|
</div>
|
|
226
240
|
)
|
|
227
241
|
})}
|
|
228
|
-
|
|
229
|
-
{
|
|
230
|
-
|
|
231
|
-
|
|
242
|
+
<div className="mt-2">
|
|
243
|
+
{addingEmail ? (
|
|
244
|
+
<div className="max-w-md">
|
|
245
|
+
<Card>
|
|
246
|
+
<CardHeader>
|
|
247
|
+
<CardTitle>Add email address</CardTitle>
|
|
248
|
+
<CardDescription>
|
|
249
|
+
You'll need to verify this email address before it can be added to your account.
|
|
250
|
+
</CardDescription>
|
|
251
|
+
</CardHeader>
|
|
252
|
+
<CardContent>
|
|
253
|
+
<div className="space-y-2">
|
|
254
|
+
<Label htmlFor="new-email">Email address</Label>
|
|
255
|
+
<Input
|
|
256
|
+
id="new-email"
|
|
257
|
+
placeholder="Enter your email address"
|
|
258
|
+
value={newEmail}
|
|
259
|
+
onChange={(e) => setNewEmail(e.target.value)}
|
|
260
|
+
onKeyDown={async (e) => {
|
|
261
|
+
if (e.key === "Enter") {
|
|
262
|
+
const v = String(newEmail || "").trim().toLowerCase()
|
|
263
|
+
if (!v) return
|
|
264
|
+
if (onAddEmail) await onAddEmail(v)
|
|
265
|
+
setAddingEmail(false)
|
|
266
|
+
setNewEmail("")
|
|
267
|
+
}
|
|
268
|
+
}}
|
|
269
|
+
/>
|
|
270
|
+
</div>
|
|
271
|
+
</CardContent>
|
|
272
|
+
<CardFooter className="justify-end gap-2">
|
|
273
|
+
<Button
|
|
274
|
+
variant="ghost"
|
|
275
|
+
onClick={() => {
|
|
276
|
+
setAddingEmail(false)
|
|
277
|
+
setNewEmail("")
|
|
278
|
+
}}
|
|
279
|
+
>
|
|
280
|
+
Cancel
|
|
281
|
+
</Button>
|
|
282
|
+
<Button
|
|
283
|
+
onClick={async () => {
|
|
284
|
+
const v = String(newEmail || "").trim().toLowerCase()
|
|
285
|
+
if (!v) return
|
|
286
|
+
if (onAddEmail) await onAddEmail(v)
|
|
287
|
+
setAddingEmail(false)
|
|
288
|
+
setNewEmail("")
|
|
289
|
+
}}
|
|
290
|
+
>
|
|
291
|
+
Add
|
|
292
|
+
</Button>
|
|
293
|
+
</CardFooter>
|
|
294
|
+
</Card>
|
|
295
|
+
</div>
|
|
296
|
+
) : (
|
|
297
|
+
<Button variant="outline" size="sm" className="text-xs" onClick={() => setAddingEmail(true)}>
|
|
298
|
+
Add email
|
|
299
|
+
</Button>
|
|
300
|
+
)}
|
|
301
|
+
</div>
|
|
232
302
|
</div>
|
|
233
303
|
</div>
|
|
234
304
|
|
|
@@ -1,67 +1,46 @@
|
|
|
1
|
-
import type { Story } from
|
|
2
|
-
import { UserProfile
|
|
3
|
-
import "../global.css"
|
|
1
|
+
import type { StoryDefault, Story } from "@ladle/react"
|
|
2
|
+
import { UserProfile } from "../components/core/user-profile"
|
|
3
|
+
import "../global.css"
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
id: "123",
|
|
9
|
-
displayName: "Jaylon Dias",
|
|
10
|
-
emails: [{ value: "example@authdog.xyz" }],
|
|
11
|
-
photos: [{ value: "https://i.pravatar.cc/150?u=a042581f4e29026704d" }],
|
|
12
|
-
provider: "authdog",
|
|
13
|
-
}}
|
|
14
|
-
loading={false}
|
|
15
|
-
handleAuthenticated={() => {}}
|
|
16
|
-
emails={[{ address: "example@authdog.xyz", isPrimary: true }]}
|
|
17
|
-
/>
|
|
18
|
-
);
|
|
19
|
-
Default.storyName = 'Default User Profile';
|
|
5
|
+
export default {
|
|
6
|
+
title: "Core/UserProfile",
|
|
7
|
+
} satisfies StoryDefault
|
|
20
8
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}}
|
|
30
|
-
loading={false}
|
|
31
|
-
handleAuthenticated={() => {}}
|
|
32
|
-
emails={[{ address: "example@authdog.xyz", isPrimary: true }]}
|
|
33
|
-
/>
|
|
34
|
-
);
|
|
35
|
-
WithCustomUser.storyName = 'User Profile with Custom User';
|
|
9
|
+
const baseUser: any = {
|
|
10
|
+
id: "user_123",
|
|
11
|
+
displayName: "Jane Doe",
|
|
12
|
+
provider: "google-oauth20",
|
|
13
|
+
emails: [{ id: "e1", value: "jane.primary@example.com" }],
|
|
14
|
+
verifications: [],
|
|
15
|
+
photos: [],
|
|
16
|
+
}
|
|
36
17
|
|
|
37
|
-
export const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}}
|
|
46
|
-
loading={false}
|
|
47
|
-
handleAuthenticated={() => {}}
|
|
48
|
-
emails={[{ address: "example@authdog.xyz", isPrimary: true }, { address: "example@gmail.com", isPrimary: false }]}
|
|
49
|
-
/>
|
|
50
|
-
);
|
|
51
|
-
WithMultipleEmails.storyName = 'User Profile with Multiple Emails';
|
|
18
|
+
export const EmailNotVerified: Story = () => {
|
|
19
|
+
return (
|
|
20
|
+
<div className="p-6 bg-background text-foreground">
|
|
21
|
+
<UserProfile loading={false} user={{ ...baseUser }} />
|
|
22
|
+
</div>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
EmailNotVerified.storyName = "Email not verified"
|
|
52
26
|
|
|
53
|
-
export const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
27
|
+
export const EmailVerified: Story = () => {
|
|
28
|
+
const verifiedUser = {
|
|
29
|
+
...baseUser,
|
|
30
|
+
verifications: [
|
|
31
|
+
{
|
|
32
|
+
id: "v1",
|
|
33
|
+
email: "jane.primary@example.com",
|
|
34
|
+
verified: true,
|
|
35
|
+
createdAt: new Date().toISOString(),
|
|
36
|
+
updatedAt: new Date().toISOString(),
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
}
|
|
40
|
+
return (
|
|
41
|
+
<div className="p-6 bg-background text-foreground">
|
|
42
|
+
<UserProfile loading={false} user={verifiedUser} />
|
|
43
|
+
</div>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
EmailVerified.storyName = "Email verified"
|