Skip to content

Commit

Permalink
feat: login page
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Jun 19, 2023
1 parent 9ad87c3 commit 02c5e9e
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 11 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@tanstack/react-query-devtools": "4.29.14",
"@tanstack/react-query-persist-client": "4.29.14",
"@uidotdev/usehooks": "2.0.1",
"@vercel/analytics": "1.0.1",
"axios": "1.4.0",
"clsx": "1.2.1",
"daisyui": "3.1.1",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions src/app/@login/page.tsx

This file was deleted.

2 changes: 2 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '../styles/index.css'

import { dehydrate } from '@tanstack/react-query'
import { Analytics } from '@vercel/analytics/react'
import { ToastContainer } from 'react-toastify'

import { ClerkProvider } from '@clerk/nextjs'
Expand Down Expand Up @@ -95,6 +96,7 @@ export default async function RootLayout(props: Props) {
<ToastContainer />
</body>
</html>
<Analytics />
</ClerkProvider>
)
}
52 changes: 52 additions & 0 deletions src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use client'

import { useState } from 'react'
import { useRouter } from 'next/navigation'

import { login } from '~/atoms/owner'
import { MotionButtonBase } from '~/components/ui/button'
import { Routes } from '~/lib/route-builder'

export default () => {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const router = useRouter()

const handleLogin = (e: any) => {
e.preventDefault()
login(username, password).then(() => {
router.push(Routes.Home)
})
}
return (
<div className="flex min-h-[calc(100vh-7rem)] center">
<form className="flex flex-col space-y-5" onSubmit={handleLogin}>
<input
autoFocus
value={username}
onChange={(e) => setUsername(e.target.value)}
type="text"
placeholder="Username"
className="input w-full max-w-xs"
/>
<input
value={password}
onChange={(e) => setPassword(e.target.value)}
type="password"
placeholder="Password"
className="input w-full max-w-xs"
/>

<div className="flex center">
<MotionButtonBase
disabled={!username || !password}
className="btn-primary btn text-white"
onClick={handleLogin}
>
Login
</MotionButtonBase>
</div>
</form>
</div>
)
}
27 changes: 24 additions & 3 deletions src/atoms/owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,43 @@ const ownerAtom = atom((get) => {
})
const tokenAtom = atom(null as string | null)

export const login = async () => {
export const login = async (username?: string, password?: string) => {
if (username && password) {
const user = await apiClient.user.login(username, password).catch((err) => {
console.error(err)
toast('再试试哦', 'error')
return null
})
if (user) {
const token = user.token
setToken(token)
jotaiStore.set(tokenAtom, token)

toast(`欢迎回来,${jotaiStore.get(ownerAtom)?.name}`, 'success')
}

return Promise.resolve()
}

const token = getToken()
if (!token) {
return
}
const outdateToast = () => toast('登录身份过期了,再登录一下吧!', 'warning')
const validated = await apiClient.user
.checkTokenValid(token)
.then((res) => !!res.ok)

.catch(() => {
removeToken()
toast('登录身份过期了,再登录一下吧!', 'warning')
outdateToast()
return false
})

if (!validated) return
if (!validated) {
outdateToast()
return
}

apiClient.user.proxy.login.put<{ token: string }>().then((res) => {
jotaiStore.set(tokenAtom, res.token)
Expand Down
19 changes: 17 additions & 2 deletions src/components/layout/header/internal/AnimatedLogo.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
'use client'

import { AnimatePresence, motion } from 'framer-motion'
import { useRouter } from 'next/navigation'

import { useViewport } from '~/atoms'
import { useSingleAndDoubleClick } from '~/hooks/common/use-single-double-click'
import { Routes } from '~/lib/route-builder'

import { useHeaderMetaShouldShow } from './hooks'
import { Logo } from './Logo'

const TapableLogo = () => {
const router = useRouter()
const fn = useSingleAndDoubleClick(
() => {
router.push(Routes.Home)
},
() => {
router.push(Routes.Login)
},
)
return <Logo onClick={fn} className="cursor-pointer" />
}
export const AnimatedLogo = () => {
const shouldShowMeta = useHeaderMetaShouldShow()

const isDesktop = useViewport(($) => $.lg && $.w !== 0)

if (isDesktop) return <Logo />
if (isDesktop) return <TapableLogo />

return (
<AnimatePresence>
Expand All @@ -23,7 +38,7 @@ export const AnimatedLogo = () => {
exit={{ opacity: 0 }}
className="scale-75"
>
<Logo />
<TapableLogo />
</motion.div>
)}
</AnimatePresence>
Expand Down
9 changes: 7 additions & 2 deletions src/components/layout/header/internal/Logo.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
export const Logo = () => {
import type { SVGProps } from 'react'

import { clsxm } from '~/utils/helper'

export const Logo = (props: SVGProps<SVGSVGElement>) => {
return (
<svg
className="inline-block h-[4.5rem] p-3"
viewBox="0 0 220 220"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
{...props}
className={clsxm('inline-block h-[4.5rem] p-3', props.className)}
>
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
<g id="forest-black" transform="translate(25.000000, 25.000000)">
Expand Down
2 changes: 1 addition & 1 deletion src/lib/route-builder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export enum Routes {
Home = '/home',
Home = '/',
Posts = '/posts',
Post = '/posts/',
Notes = '/notes',
Expand Down
3 changes: 3 additions & 0 deletions src/styles/toastify.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
right: 12px;
width: 300px;
}
.Toastify__toast-icon {
display: none;
}
.Toastify__toast-container {
width: 100%;
}
Expand Down

0 comments on commit 02c5e9e

Please sign in to comment.