File tree 10 files changed +114
-11
lines changed
10 files changed +114
-11
lines changed Original file line number Diff line number Diff line change 53
53
"@tanstack/react-query-devtools" : " 4.29.14" ,
54
54
"@tanstack/react-query-persist-client" : " 4.29.14" ,
55
55
"@uidotdev/usehooks" : " 2.0.1" ,
56
+ "@vercel/analytics" : " 1.0.1" ,
56
57
"axios" : " 1.4.0" ,
57
58
"clsx" : " 1.2.1" ,
58
59
"daisyui" : " 3.1.1" ,
Load Diff This file was deleted.
Original file line number Diff line number Diff line change 1
1
import '../styles/index.css'
2
2
3
3
import { dehydrate } from '@tanstack/react-query'
4
+ import { Analytics } from '@vercel/analytics/react'
4
5
import { ToastContainer } from 'react-toastify'
5
6
6
7
import { ClerkProvider } from '@clerk/nextjs'
@@ -95,6 +96,7 @@ export default async function RootLayout(props: Props) {
95
96
< ToastContainer />
96
97
</ body >
97
98
</ html >
99
+ < Analytics />
98
100
</ ClerkProvider >
99
101
)
100
102
}
Original file line number Diff line number Diff line change
1
+ 'use client'
2
+
3
+ import { useState } from 'react'
4
+ import { useRouter } from 'next/navigation'
5
+
6
+ import { login } from '~/atoms/owner'
7
+ import { MotionButtonBase } from '~/components/ui/button'
8
+ import { Routes } from '~/lib/route-builder'
9
+
10
+ export default ( ) => {
11
+ const [ username , setUsername ] = useState ( '' )
12
+ const [ password , setPassword ] = useState ( '' )
13
+ const router = useRouter ( )
14
+
15
+ const handleLogin = ( e : any ) => {
16
+ e . preventDefault ( )
17
+ login ( username , password ) . then ( ( ) => {
18
+ router . push ( Routes . Home )
19
+ } )
20
+ }
21
+ return (
22
+ < div className = "flex min-h-[calc(100vh-7rem)] center" >
23
+ < form className = "flex flex-col space-y-5" onSubmit = { handleLogin } >
24
+ < input
25
+ autoFocus
26
+ value = { username }
27
+ onChange = { ( e ) => setUsername ( e . target . value ) }
28
+ type = "text"
29
+ placeholder = "Username"
30
+ className = "input w-full max-w-xs"
31
+ />
32
+ < input
33
+ value = { password }
34
+ onChange = { ( e ) => setPassword ( e . target . value ) }
35
+ type = "password"
36
+ placeholder = "Password"
37
+ className = "input w-full max-w-xs"
38
+ />
39
+
40
+ < div className = "flex center" >
41
+ < MotionButtonBase
42
+ disabled = { ! username || ! password }
43
+ className = "btn-primary btn text-white"
44
+ onClick = { handleLogin }
45
+ >
46
+ Login
47
+ </ MotionButtonBase >
48
+ </ div >
49
+ </ form >
50
+ </ div >
51
+ )
52
+ }
Original file line number Diff line number Diff line change @@ -11,22 +11,43 @@ const ownerAtom = atom((get) => {
11
11
} )
12
12
const tokenAtom = atom ( null as string | null )
13
13
14
- export const login = async ( ) => {
14
+ export const login = async ( username ?: string , password ?: string ) => {
15
+ if ( username && password ) {
16
+ const user = await apiClient . user . login ( username , password ) . catch ( ( err ) => {
17
+ console . error ( err )
18
+ toast ( '再试试哦' , 'error' )
19
+ return null
20
+ } )
21
+ if ( user ) {
22
+ const token = user . token
23
+ setToken ( token )
24
+ jotaiStore . set ( tokenAtom , token )
25
+
26
+ toast ( `欢迎回来,${ jotaiStore . get ( ownerAtom ) ?. name } ` , 'success' )
27
+ }
28
+
29
+ return Promise . resolve ( )
30
+ }
31
+
15
32
const token = getToken ( )
16
33
if ( ! token ) {
17
34
return
18
35
}
36
+ const outdateToast = ( ) => toast ( '登录身份过期了,再登录一下吧!' , 'warning' )
19
37
const validated = await apiClient . user
20
38
. checkTokenValid ( token )
21
39
. then ( ( res ) => ! ! res . ok )
22
40
23
41
. catch ( ( ) => {
24
42
removeToken ( )
25
- toast ( '登录身份过期了,再登录一下吧!' , 'warning' )
43
+ outdateToast ( )
26
44
return false
27
45
} )
28
46
29
- if ( ! validated ) return
47
+ if ( ! validated ) {
48
+ outdateToast ( )
49
+ return
50
+ }
30
51
31
52
apiClient . user . proxy . login . put < { token : string } > ( ) . then ( ( res ) => {
32
53
jotaiStore . set ( tokenAtom , res . token )
Original file line number Diff line number Diff line change 1
1
'use client'
2
2
3
3
import { AnimatePresence , motion } from 'framer-motion'
4
+ import { useRouter } from 'next/navigation'
4
5
5
6
import { useViewport } from '~/atoms'
7
+ import { useSingleAndDoubleClick } from '~/hooks/common/use-single-double-click'
8
+ import { Routes } from '~/lib/route-builder'
6
9
7
10
import { useHeaderMetaShouldShow } from './hooks'
8
11
import { Logo } from './Logo'
9
12
13
+ const TapableLogo = ( ) => {
14
+ const router = useRouter ( )
15
+ const fn = useSingleAndDoubleClick (
16
+ ( ) => {
17
+ router . push ( Routes . Home )
18
+ } ,
19
+ ( ) => {
20
+ router . push ( Routes . Login )
21
+ } ,
22
+ )
23
+ return < Logo onClick = { fn } className = "cursor-pointer" />
24
+ }
10
25
export const AnimatedLogo = ( ) => {
11
26
const shouldShowMeta = useHeaderMetaShouldShow ( )
12
27
13
28
const isDesktop = useViewport ( ( $ ) => $ . lg && $ . w !== 0 )
14
29
15
- if ( isDesktop ) return < Logo />
30
+ if ( isDesktop ) return < TapableLogo />
16
31
17
32
return (
18
33
< AnimatePresence >
@@ -23,7 +38,7 @@ export const AnimatedLogo = () => {
23
38
exit = { { opacity : 0 } }
24
39
className = "scale-75"
25
40
>
26
- < Logo />
41
+ < TapableLogo />
27
42
</ motion . div >
28
43
) }
29
44
</ AnimatePresence >
Original file line number Diff line number Diff line change 1
- export const Logo = ( ) => {
1
+ import type { SVGProps } from 'react'
2
+
3
+ import { clsxm } from '~/utils/helper'
4
+
5
+ export const Logo = ( props : SVGProps < SVGSVGElement > ) => {
2
6
return (
3
7
< svg
4
- className = "inline-block h-[4.5rem] p-3"
5
8
viewBox = "0 0 220 220"
6
9
version = "1.1"
7
10
xmlns = "http://www.w3.org/2000/svg"
11
+ { ...props }
12
+ className = { clsxm ( 'inline-block h-[4.5rem] p-3' , props . className ) }
8
13
>
9
14
< g stroke = "none" strokeWidth = "1" fill = "none" fillRule = "evenodd" >
10
15
< g id = "forest-black" transform = "translate(25.000000, 25.000000)" >
Original file line number Diff line number Diff line change 1
1
export enum Routes {
2
- Home = '/home ' ,
2
+ Home = '/' ,
3
3
Posts = '/posts' ,
4
4
Post = '/posts/' ,
5
5
Notes = '/notes' ,
Original file line number Diff line number Diff line change 6
6
right : 12px ;
7
7
width : 300px ;
8
8
}
9
+ .Toastify__toast-icon {
10
+ display : none;
11
+ }
9
12
.Toastify__toast-container {
10
13
width : 100% ;
11
14
}
You can’t perform that action at this time.
0 commit comments