1
1
'use client'
2
2
3
- import React from 'react'
3
+ import React , { useEffect } from 'react'
4
4
import { AnimatePresence } from 'framer-motion'
5
5
import dynamic from 'next/dynamic'
6
6
import { usePathname } from 'next/navigation'
7
7
8
- import { useIsLogged , useResolveAdminUrl } from '~/atoms'
8
+ import { useSignIn } from '@clerk/nextjs'
9
+
10
+ import { refreshToken , useIsLogged , useResolveAdminUrl } from '~/atoms'
11
+ import { UserArrowLeftIcon } from '~/components/icons/user-arrow-left'
9
12
import { MotionButtonBase } from '~/components/ui/button'
13
+ import { FloatPopover } from '~/components/ui/float-popover'
10
14
import { urlBuilder } from '~/lib/url-builder'
11
15
import { useAggregationSelector } from '~/providers/root/aggregation-data-provider'
12
16
13
- const UserAuthFromIcon = dynamic ( ( ) =>
14
- import ( './UserAuthFromIcon' ) . then ( ( mod ) => mod . UserAuthFromIcon ) ,
15
- )
17
+ import { HeaderActionButton } from './HeaderActionButton'
16
18
17
19
const SignedIn = dynamic ( ( ) =>
18
20
import ( '@clerk/nextjs' ) . then ( ( mod ) => mod . SignedIn ) ,
19
21
)
20
22
23
+ const UserAuthFromIcon = dynamic ( ( ) =>
24
+ import ( './UserAuthFromIcon' ) . then ( ( mod ) => mod . UserAuthFromIcon ) ,
25
+ )
26
+ const SignedOut = dynamic ( ( ) =>
27
+ import ( '@clerk/nextjs' ) . then ( ( mod ) => mod . SignedOut ) ,
28
+ )
21
29
const UserButton = dynamic ( ( ) =>
22
30
import ( '@clerk/nextjs' ) . then ( ( mod ) => mod . UserButton ) ,
23
31
)
32
+ const SignInButton = dynamic ( ( ) =>
33
+ import ( '@clerk/nextjs' ) . then ( ( mod ) => mod . SignInButton ) ,
34
+ )
24
35
25
36
const OwnerAvatar = ( ) => {
26
37
const ownerAvatar = useAggregationSelector ( ( s ) => s . user . avatar ) !
@@ -30,18 +41,26 @@ const OwnerAvatar = () => {
30
41
onClick = { ( ) => {
31
42
window . open ( resolveAdminUrl ( ) , '_blank' )
32
43
} }
33
- className = "pointer-events-auto flex h-10 w-10 items-center justify-center overflow-hidden rounded-full "
44
+ className = "pointer-events-auto relative flex h-10 w-10 items-center justify-center"
34
45
>
35
46
< span className = "sr-only" > Go to dashboard</ span >
36
- < img src = { ownerAvatar } alt = "site owner" />
47
+ < img className = "rounded-full" src = { ownerAvatar } alt = "site owner" />
48
+ < UserAuthFromIcon className = "absolute -bottom-1 -right-1" />
37
49
</ MotionButtonBase >
38
50
)
39
51
}
52
+
40
53
export function UserAuth ( ) {
41
54
const pathname = usePathname ( )
42
-
43
55
const isLogged = useIsLogged ( )
44
56
57
+ const { isLoaded } = useSignIn ( )
58
+
59
+ useEffect ( ( ) => {
60
+ // token 刷新,使用 mx token 替换
61
+ if ( isLoaded ) refreshToken ( )
62
+ } , [ isLoaded ] )
63
+
45
64
if ( isLogged ) {
46
65
return < OwnerAvatar />
47
66
}
@@ -63,6 +82,27 @@ export function UserAuth() {
63
82
</ div >
64
83
</ div >
65
84
</ SignedIn >
85
+
86
+ < SignedOut key = "sign-in" >
87
+ < FloatPopover
88
+ TriggerComponent = { TriggerComponent }
89
+ wrapperClassName = "h-full w-full flex items-center justify-center"
90
+ type = "tooltip"
91
+ >
92
+ 登录
93
+ </ FloatPopover >
94
+ </ SignedOut >
66
95
</ AnimatePresence >
67
96
)
68
97
}
98
+
99
+ const TriggerComponent = ( ) => {
100
+ const pathname = usePathname ( )
101
+ return (
102
+ < SignInButton mode = "modal" redirectUrl = { urlBuilder ( pathname ) . href } >
103
+ < HeaderActionButton aria-label = "Guest Login" >
104
+ < UserArrowLeftIcon className = "h-4 w-4" />
105
+ </ HeaderActionButton >
106
+ </ SignInButton >
107
+ )
108
+ }
0 commit comments