This repository has been archived by the owner on Dec 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
681dc6f
commit f5ad470
Showing
10 changed files
with
382 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 124 additions & 0 deletions
124
frontend/src/app/(public)/signup/_components/SignUpForm.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
'use client' | ||
|
||
import { Button } from '@/components/ui/button' | ||
import { | ||
Form, | ||
FormControl, | ||
FormField, | ||
FormItem, | ||
FormLabel, | ||
FormMessage | ||
} from '@/components/ui/form' | ||
import { Input } from '@/components/ui/input' | ||
import fetcher from '@/lib/fetcher' | ||
import { SignUpFormSchema } from '@/lib/forms' | ||
import { zodResolver } from '@hookform/resolvers/zod' | ||
import { useRouter } from 'next/navigation' | ||
import { useState } from 'react' | ||
import { useForm } from 'react-hook-form' | ||
import { toast } from 'sonner' | ||
import type { z } from 'zod' | ||
|
||
export default function SignUpForm() { | ||
const [isFetching, setIsFetching] = useState(false) | ||
const router = useRouter() | ||
|
||
const form = useForm<z.infer<typeof SignUpFormSchema>>({ | ||
resolver: zodResolver(SignUpFormSchema), | ||
defaultValues: { | ||
username: '', | ||
password: '', | ||
email: '', | ||
nickname: '' | ||
} | ||
}) | ||
|
||
const onSubmit = async (data: z.infer<typeof SignUpFormSchema>) => { | ||
try { | ||
setIsFetching(true) | ||
|
||
await fetcher.post(`/user`, data, false) | ||
router.push(`/signup/verify-email?email=${data.email}`) | ||
} catch (error) { | ||
toast.error('회원가입 실패') | ||
} finally { | ||
setIsFetching(false) | ||
} | ||
} | ||
|
||
return ( | ||
<Form {...form}> | ||
<form onSubmit={form.handleSubmit(onSubmit)} className="w-full space-y-3"> | ||
<FormField | ||
control={form.control} | ||
name="username" | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormLabel>아이디</FormLabel> | ||
<FormControl> | ||
<Input {...field} /> | ||
</FormControl> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
<FormField | ||
control={form.control} | ||
name="password" | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormLabel>비밀번호</FormLabel> | ||
<FormControl> | ||
<Input type="password" {...field} /> | ||
</FormControl> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
<FormField | ||
control={form.control} | ||
name="email" | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormLabel>이메일</FormLabel> | ||
<FormControl> | ||
<Input type="email" {...field} /> | ||
</FormControl> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
<FormField | ||
control={form.control} | ||
name="nickname" | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormLabel>별명</FormLabel> | ||
<FormControl> | ||
<Input {...field} /> | ||
</FormControl> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
<div className="flex flex-col space-y-2 pt-5"> | ||
<Button | ||
variant="accent" | ||
type="submit" | ||
className="w-full" | ||
disabled={isFetching} | ||
> | ||
회원가입 | ||
</Button> | ||
<Button | ||
type="button" | ||
className="w-full" | ||
onClick={() => router.push('/')} | ||
> | ||
메인으로 | ||
</Button> | ||
</div> | ||
</form> | ||
</Form> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import Image from 'next/image' | ||
import SignUpForm from './_components/SignUpForm' | ||
|
||
export default function SignUpPage() { | ||
return ( | ||
<main className="mx-auto flex w-full max-w-7xl flex-grow flex-col items-center justify-center p-6 lg:px-8"> | ||
<div className="flex w-full max-w-[320px] flex-col items-center gap-y-10"> | ||
<Image | ||
src="/text-logo.png" | ||
alt="ROYALS" | ||
width={1158} | ||
height={277} | ||
className="hidden h-auto w-full max-w-[320px] dark:inline-block" | ||
priority={true} | ||
/> | ||
<Image | ||
src="/text-logo-light.png" | ||
alt="ROYALS" | ||
width={1158} | ||
height={277} | ||
className="inline-block h-auto w-full max-w-[320px] dark:hidden" | ||
priority={true} | ||
/> | ||
<SignUpForm /> | ||
</div> | ||
</main> | ||
) | ||
} |
80 changes: 80 additions & 0 deletions
80
frontend/src/app/(public)/signup/verify-email/_components/VerifyEmailForm.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
'use client' | ||
|
||
import { Button } from '@/components/ui/button' | ||
import { | ||
Form, | ||
FormControl, | ||
FormField, | ||
FormItem, | ||
FormLabel, | ||
FormMessage | ||
} from '@/components/ui/form' | ||
import { Input } from '@/components/ui/input' | ||
import fetcher from '@/lib/fetcher' | ||
import { VerifyEmailFormSchema } from '@/lib/forms' | ||
import { zodResolver } from '@hookform/resolvers/zod' | ||
import { useRouter } from 'next/navigation' | ||
import { useState } from 'react' | ||
import { useForm } from 'react-hook-form' | ||
import { toast } from 'sonner' | ||
import type { z } from 'zod' | ||
|
||
export default function VerifyEmailForm({ email }: { email: string }) { | ||
const [isFetching, setIsFetching] = useState(false) | ||
const router = useRouter() | ||
|
||
const form = useForm<z.infer<typeof VerifyEmailFormSchema>>({ | ||
resolver: zodResolver(VerifyEmailFormSchema), | ||
defaultValues: { | ||
pin: '' | ||
} | ||
}) | ||
|
||
const onSubmit = async (data: z.infer<typeof VerifyEmailFormSchema>) => { | ||
try { | ||
setIsFetching(true) | ||
const result = await fetcher.post<{ valid: boolean }>( | ||
`/user/verify-email?email=${email}&pin=${data.pin}`, | ||
{}, | ||
false | ||
) | ||
|
||
if (!result.valid) throw new Error() | ||
|
||
router.push('/login') | ||
toast.success('회원가입이 완료되었습니다') | ||
} catch (error) { | ||
toast.error('인증코드가 일치하지 않습니다') | ||
} finally { | ||
setIsFetching(false) | ||
} | ||
} | ||
|
||
return ( | ||
<Form {...form}> | ||
<form onSubmit={form.handleSubmit(onSubmit)} className="w-full space-y-3"> | ||
<FormField | ||
control={form.control} | ||
name="pin" | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormLabel className="sr-only">pin</FormLabel> | ||
<FormControl> | ||
<Input placeholder="인증코드" {...field} /> | ||
</FormControl> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
<Button | ||
variant="accent" | ||
type="submit" | ||
className="w-full" | ||
disabled={isFetching} | ||
> | ||
이메일 주소 인증 | ||
</Button> | ||
</form> | ||
</Form> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { Button } from '@/components/ui/button' | ||
import Image from 'next/image' | ||
import Link from 'next/link' | ||
import VerifyEmailForm from './_components/VerifyEmailForm' | ||
|
||
export default function VerifyEmailAddressPage({ | ||
searchParams | ||
}: { | ||
searchParams?: { | ||
email?: string | ||
} | ||
}) { | ||
return ( | ||
<main className="mx-auto flex w-full max-w-7xl flex-grow flex-col items-center justify-center p-6 lg:px-8"> | ||
<div className="flex w-full max-w-[320px] flex-col items-center gap-y-10"> | ||
{searchParams?.email ? ( | ||
<> | ||
<Image | ||
src="/text-logo.png" | ||
alt="ROYALS" | ||
width={1158} | ||
height={277} | ||
className="hidden h-auto w-full max-w-[320px] dark:inline-block" | ||
priority={true} | ||
/> | ||
<Image | ||
src="/text-logo-light.png" | ||
alt="ROYALS" | ||
width={1158} | ||
height={277} | ||
className="inline-block h-auto w-full max-w-[320px] dark:hidden" | ||
priority={true} | ||
/> | ||
<p className="text-md fond-bold text-center"> | ||
<span className="text-amber-400">{searchParams.email}</span>으(로) | ||
전송된 | ||
<br /> | ||
인증코드 6자리를 입력해주세요 | ||
</p> | ||
<VerifyEmailForm email={searchParams.email} /> | ||
</> | ||
) : ( | ||
<> | ||
<h1 className="text-xl font-bold">[ERROR] 잘못된 접근입니다</h1> | ||
<Link href="/"> | ||
<Button size="sm">메인으로</Button> | ||
</Link> | ||
</> | ||
)} | ||
</div> | ||
</main> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { Button } from '@/components/ui/button' | ||
import { AccountStatus } from '@/lib/enums' | ||
import { | ||
CheckCircleIcon, | ||
ExclamationTriangleIcon | ||
} from '@heroicons/react/24/outline' | ||
import Link from 'next/link' | ||
|
||
export default function UnverifiedPage({ | ||
searchParams | ||
}: { | ||
searchParams?: { | ||
status?: AccountStatus | ||
} | ||
}) { | ||
const status = searchParams?.status ?? AccountStatus.Disable | ||
|
||
const renderStatus = (status: AccountStatus) => { | ||
switch (status) { | ||
case AccountStatus.Verifying: | ||
return ( | ||
<div className="flex flex-col space-y-1.5"> | ||
<div className="flex flex-row items-center"> | ||
<CheckCircleIcon className="mr-1.5 mt-1 h-6 w-6 text-green-500" /> | ||
<p>이메일 인증이 완료되었습니다</p> | ||
</div> | ||
<div className="flex flex-row items-center"> | ||
<ExclamationTriangleIcon className="mr-1.5 mt-1 h-6 w-6 text-red-500" /> | ||
<p>관리자가 아직 회원가입을 승인하지 않았습니다</p> | ||
</div> | ||
</div> | ||
) | ||
default: | ||
return ( | ||
<div className="flex flex-col space-y-1.5"> | ||
<div className="flex flex-row items-center"> | ||
<ExclamationTriangleIcon className="mr-1.5 mt-1 h-6 w-6 text-red-500" /> | ||
<p>이메일 인증이 완료되지 않았습니다</p> | ||
</div> | ||
<div className="flex flex-row items-center"> | ||
<ExclamationTriangleIcon className="mr-1.5 mt-1 h-6 w-6 text-red-500" /> | ||
<p>관리자가 아직 회원가입을 승인하지 않았습니다</p> | ||
</div> | ||
</div> | ||
) | ||
} | ||
} | ||
|
||
return ( | ||
<main className="mx-auto flex w-full max-w-7xl flex-grow flex-col items-center justify-center p-6 lg:px-8"> | ||
<div className="flex w-full flex-col items-center justify-center space-y-5"> | ||
<h1 className="text-xl font-bold"> | ||
계정 인증절차가 완료되지 않았습니다 | ||
</h1> | ||
{renderStatus(status)} | ||
<Link href="/"> | ||
<Button variant={'outline'}>메인으로</Button> | ||
</Link> | ||
</div> | ||
</main> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.