- 로그인 화면, 회원가입 화면, 비밀번호 초기화 화면 모바일 ui 대비 작업
This commit is contained in:
@@ -1 +1 @@
|
||||
VITE_API_URL=http://localhost:8080
|
||||
VITE_API_URL=http://localhost:8088
|
||||
|
||||
@@ -17,11 +17,13 @@ import { toast } from 'sonner';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { useIsMobile } from '@/hooks/use-mobile';
|
||||
|
||||
export default function LoginPage() {
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [autoLogin, setAutoLogin] = useState<boolean>(false);
|
||||
const { login } = useAuthStore();
|
||||
const isMobile = useIsMobile();
|
||||
const navigate = useNavigate();
|
||||
const accountNetwork = new AccountNetwork();
|
||||
const loginForm = useForm<z.infer<typeof LoginSchema>>({
|
||||
@@ -73,7 +75,7 @@ export default function LoginPage() {
|
||||
};
|
||||
login({...data});
|
||||
moveToHomePage();
|
||||
return "";
|
||||
return "로그인 성공";
|
||||
} else {
|
||||
throw new Error(res.data.message);
|
||||
}
|
||||
@@ -102,7 +104,7 @@ export default function LoginPage() {
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex flex-col justify-center items-center">
|
||||
<Card className="w-md pl-2 pr-2">
|
||||
<Card className={isMobile ? "w-full pl-2 pr-2" : "w-md pl-2 pr-2"}>
|
||||
<CardHeader>
|
||||
로그인
|
||||
</CardHeader>
|
||||
|
||||
@@ -18,6 +18,8 @@ import { AccountNetwork } from '@/network/AccountNetwork';
|
||||
import { toast } from 'sonner';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { PageRouting } from '@/const/PageRouting';
|
||||
import { useIsMobile } from '@/hooks/use-mobile';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
|
||||
export default function SignUpPage() {
|
||||
const [emailVerificationModalOpen, setEmailVerificationModalOpen] = useState<boolean>(false);
|
||||
@@ -28,6 +30,7 @@ export default function SignUpPage() {
|
||||
|
||||
const accountNetwork = new AccountNetwork();
|
||||
const navigate = useNavigate();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const signUpForm = useForm<z.infer<typeof SignUpSchema>>({
|
||||
resolver: zodResolver(SignUpSchema),
|
||||
@@ -119,145 +122,150 @@ export default function SignUpPage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex flex-col justify-center items-center">
|
||||
<Card className="w-md pl-2 pr-2">
|
||||
<CardHeader>회원가입</CardHeader>
|
||||
<CardContent>
|
||||
<form id="form-signup">
|
||||
<FieldGroup>
|
||||
<Controller
|
||||
name="accountId"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-account-id">아이디</FieldLabel>
|
||||
<div id="accountId-group" className="w-full flex flex-row justify-between gap-2.5">
|
||||
<div className={"w-full h-full flex flex-col justify-center items-center"}>
|
||||
|
||||
<Card className={isMobile ? "w-full pl-2 pr-2" : "w-md pl-2 pr-2"}>
|
||||
<CardHeader>회원가입</CardHeader>
|
||||
<ScrollArea className="h-72 [&>div>div:last-child]:hidden">
|
||||
<CardContent>
|
||||
<form id="form-signup">
|
||||
<FieldGroup>
|
||||
<Controller
|
||||
name="accountId"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-account-id">아이디</FieldLabel>
|
||||
<div id="accountId-group" className="w-full flex flex-row justify-between gap-2.5">
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-account-id"
|
||||
aria-invalid={fieldState.invalid}
|
||||
onInput={handleOnChangeAccountId}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => handleDuplicationCheckButtonClick('accountId')}
|
||||
className="bg-indigo-500 hover:bg-indigo-400"
|
||||
>
|
||||
중복 확인
|
||||
</Button>
|
||||
</div>
|
||||
{ isCheckedAccountIdDuplication && <p className="text-green-500 text-sm font-normal">사용할 수 있는 아이디입니다</p> }
|
||||
<FieldError errors={[fieldState.error]}/>
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="name"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-name">이름</FieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-account-id"
|
||||
id="form-signup-name"
|
||||
aria-invalid={fieldState.invalid}
|
||||
onInput={handleOnChangeAccountId}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => handleDuplicationCheckButtonClick('accountId')}
|
||||
className="bg-indigo-500 hover:bg-indigo-400"
|
||||
>
|
||||
중복 확인
|
||||
</Button>
|
||||
</div>
|
||||
{ isCheckedAccountIdDuplication && <p className="text-green-500 text-sm font-normal">사용할 수 있는 아이디입니다</p> }
|
||||
<FieldError errors={[fieldState.error]}/>
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="name"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-name">이름</FieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-name"
|
||||
aria-invalid={fieldState.invalid}
|
||||
/>
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="nickname"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-nickname">닉네임</FieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-nickname"
|
||||
aria-invalid={fieldState.invalid}
|
||||
/>
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="email"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-email">이메일</FieldLabel>
|
||||
<div id="email-group" className="w-full flex flex-row justify-between gap-2.5">
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="nickname"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-nickname">닉네임</FieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-email"
|
||||
id="form-signup-nickname"
|
||||
aria-invalid={fieldState.invalid}
|
||||
placeholder="example@domain.com"
|
||||
type="email"
|
||||
onInput={handleOnChangeEmail}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => handleDuplicationCheckButtonClick('email')}
|
||||
className="bg-indigo-500 hover:bg-indigo-400"
|
||||
>
|
||||
중복 확인
|
||||
</Button>
|
||||
</div>
|
||||
{ isCheckedEmailDuplication && <p className="text-green-500 text-sm font-normal">사용할 수 있는 이메일입니다</p> }
|
||||
<FieldError errors={[fieldState.error]}/>
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="password"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-password">비밀번호</FieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-password"
|
||||
aria-invalid={fieldState.invalid}
|
||||
type="password"
|
||||
/>
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="passwordConfirm"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-password-confirm">비밀번호 확인</FieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-password-confirm"
|
||||
aria-invalid={fieldState.invalid}
|
||||
type="password"
|
||||
/>
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
</FieldGroup>
|
||||
</form>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<EmailVerificationModal
|
||||
trigger={
|
||||
<Button type="button" onClick={handleOnSignUpButtonClick} className="0">
|
||||
회원가입
|
||||
</Button>
|
||||
}
|
||||
email={duplicationCheckedEmail}
|
||||
open={emailVerificationModalOpen} // ✅ 부모 상태 연결
|
||||
setOpen={setEmailVerificationModalOpen} // ✅ 부모 상태 변경 함수 전달
|
||||
onVerifySuccess={signup} // ✅ 인증 성공 시 signup 호출
|
||||
/>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="email"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-email">이메일</FieldLabel>
|
||||
<div id="email-group" className="w-full flex flex-row justify-between gap-2.5">
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-email"
|
||||
aria-invalid={fieldState.invalid}
|
||||
placeholder="example@domain.com"
|
||||
type="email"
|
||||
onInput={handleOnChangeEmail}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => handleDuplicationCheckButtonClick('email')}
|
||||
className="bg-indigo-500 hover:bg-indigo-400"
|
||||
>
|
||||
중복 확인
|
||||
</Button>
|
||||
</div>
|
||||
{ isCheckedEmailDuplication && <p className="text-green-500 text-sm font-normal">사용할 수 있는 이메일입니다</p> }
|
||||
<FieldError errors={[fieldState.error]}/>
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="password"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-password">비밀번호</FieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-password"
|
||||
aria-invalid={fieldState.invalid}
|
||||
type="password"
|
||||
/>
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="passwordConfirm"
|
||||
control={signUpForm.control}
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor="form-signup-password-confirm">비밀번호 확인</FieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
id="form-signup-password-confirm"
|
||||
aria-invalid={fieldState.invalid}
|
||||
type="password"
|
||||
/>
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
</FieldGroup>
|
||||
</form>
|
||||
</CardContent>
|
||||
</ScrollArea>
|
||||
<CardFooter>
|
||||
<EmailVerificationModal
|
||||
trigger={
|
||||
<Button type="button" onClick={handleOnSignUpButtonClick} className="0">
|
||||
회원가입
|
||||
</Button>
|
||||
}
|
||||
email={duplicationCheckedEmail}
|
||||
open={emailVerificationModalOpen} // ✅ 부모 상태 연결
|
||||
setOpen={setEmailVerificationModalOpen} // ✅ 부모 상태 변경 함수 전달
|
||||
onVerifySuccess={signup} // ✅ 인증 성공 시 signup 호출
|
||||
/>
|
||||
</CardFooter>
|
||||
|
||||
</Card>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
26
src/ui/page/schedule/ScheduleMainPage.tsx
Normal file
26
src/ui/page/schedule/ScheduleMainPage.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Calendar } from "@/components/ui/calendar";
|
||||
import { DayButton } from "react-day-picker";
|
||||
|
||||
export function ScheduleMainPage() {
|
||||
return (
|
||||
<div className="w-full h-full flex flex-col justify-start items-center">
|
||||
<Calendar
|
||||
mode="single"
|
||||
className="rounded-lg w-full h-full max-h-10/12 border"
|
||||
components={{
|
||||
Weeks: (props) => (
|
||||
<tbody {...props} className={props.className}></tbody>
|
||||
),
|
||||
Week: (props) => (
|
||||
<tr {...props} className={props.className + " h-1/10"}></tr>
|
||||
),
|
||||
Day: (props) => (
|
||||
<td {...props} className={props.className + " h-1"}></td>
|
||||
)
|
||||
}}
|
||||
>
|
||||
|
||||
</Calendar>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user