Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package-lock.json

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

51 changes: 51 additions & 0 deletions src/app/(user-access)/AuthLayout.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.authContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
width: 100%;
background-color: var(--white);
}

.authContent {
width: 100%;
max-width: 400px;
box-sizing: border-box;
display: flex;

justify-content: center;
background-color: var(--white);
border-radius: 8px;
padding: 20px;
}

.logoContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 16px 0;
}

.logo {
width: 100%;
height: auto;
}

.greeting {
margin-top: 16px;
font-size: 20px;
text-align: center;
}
@media screen and (min-width: 768px) {
.authContent {
max-width: 351px;
}
}

@media screen and (min-width: 1200px) {
.authContent {
max-width: 520px;
}
}
31 changes: 31 additions & 0 deletions src/app/(user-access)/AuthLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client';

import React from 'react';
import styles from './AuthLayout.module.css';
import Image from 'next/image';
import { useRouter } from 'next/navigation';

interface AuthLayoutProps {
children: React.ReactNode;
}

export default function AuthLayout({ children }: AuthLayoutProps) {
const router = useRouter();

return (
<div className={styles.authContainer}>
<div className={styles.logoContainer}>
<Image
src="/images/logo_main.svg"
alt="둜고"
width={100}
height={100}
className={styles.logo}
onClick={() => router.push('/')}
style={{ cursor: 'pointer' }}
/>
</div>
<div className={styles.authContent}>{children}</div>
</div>
);
}
25 changes: 5 additions & 20 deletions src/app/(user-access)/login/loginPage.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
gap: 18px;
width: 100%;
max-width: 400px;
margin: 0 auto;
}

.inputWrapper {
Expand All @@ -20,6 +19,7 @@
}

.input {
width: 100%;
padding: 8px;
border: 1px solid var(--gray-300);
border-radius: 8px;
Expand All @@ -39,28 +39,13 @@
margin-top: 10px;
}

.logoContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 16px 0;
margin-top: 209px;
}

.logo {
width: 50%;
height: auto;
.disabled {
background-color: var(--gray-400);
cursor: not-allowed;
opacity: 0.5;
}

.greeting {
margin-top: 16px;
font-size: 20px;
text-align: center;
}

.disabled {
background-color: var(--gray-400);
cursor: not-allowed;
opacity: 0.5;
}
146 changes: 68 additions & 78 deletions src/app/(user-access)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import useAuthStore from '@/store/authStore';
import Button from '@/components/Button';
import styles from './loginPage.module.css';
import axiosInstance from '@/lib/axiosInstance';
import Image from 'next/image';
import { ERROR_MESSAGES } from '@/constants/message';
import AuthLayout from '@/app/(user-access)/AuthLayout';

type LoginFormInputs = {
email: string;
Expand All @@ -21,6 +21,7 @@ type CustomUseFormReturn<TFieldValues extends FieldValues = FieldValues> =
isValid: boolean;
};
};

export default function LoginPage() {
const {
register,
Expand All @@ -47,85 +48,74 @@ export default function LoginPage() {
};

return (
<form onSubmit={handleSubmit(onSubmit)} className={styles.form}>
<div className={styles.inputWrapper}>
<div className={styles.logoContainer}>
<Image
src="/images/logo_main.svg"
alt="둜고"
width={100}
height={100}
className={styles.logo}
onClick={() => router.push('/')}
style={{ cursor: 'pointer' }}
/>
<AuthLayout>
<form onSubmit={handleSubmit(onSubmit)} className={styles.form}>
<div className={styles.inputWrapper}>
<p className={styles.greeting}>μ˜€λŠ˜λ„ λ§Œλ‚˜μ„œ λ°˜κ°€μ›Œμš”!</p>
<label htmlFor="email" className={styles.label}>
이메일
</label>
<input
id="email"
type="email"
className={`${styles.input} ${errors.email ? styles.inputError : ''}`}
{...register('email', {
required: ERROR_MESSAGES.REQUIRED_EMAIL,
pattern: {
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: ERROR_MESSAGES.INVALID_EMAIL,
},
})}
/>
{errors.email && (
<span className={styles.errorMessage}>{errors.email.message}</span>
)}
</div>

<label htmlFor="email" className={styles.label}>
이메일
</label>
<input
id="email"
type="email"
className={`${styles.input} ${errors.email ? styles.inputError : ''}`}
{...register('email', {
required: ERROR_MESSAGES.REQUIRED_EMAIL,
pattern: {
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: ERROR_MESSAGES.INVALID_EMAIL,
},
})}
/>
{errors.email && (
<span className={styles.errorMessage}>{errors.email.message}</span>
)}
</div>

<div className={styles.inputWrapper}>
<label htmlFor="password" className={styles.label}>
λΉ„λ°€λ²ˆν˜Έ
</label>
<input
id="password"
type="password"
className={`${styles.input} ${errors.password ? styles.inputError : ''}`}
{...register('password', {
required: ERROR_MESSAGES.PASSWORD_REQUIRE,
minLength: {
value: 8,
message: ERROR_MESSAGES.PASSWORD_TOO_SHORT,
},
})}
/>
{errors.password && (
<p className={styles.errorMessage}>{errors.password.message}</p>
)}
</div>

<Button
type="submit"
disabled={!isValid}
className={!isValid ? styles.disabled : ''}
style={{ height: '40px' }}
>
둜그인
</Button>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<p>
νšŒμ›μ΄ μ•„λ‹ˆμ‹ κ°€μš”?{' '}
<span
style={{
color: 'var(--violet)',
textDecoration: 'underline',
cursor: 'pointer',
}}
onClick={() => router.push('/signup')}
>
νšŒμ›κ°€μž…ν•˜κΈ°
</span>{' '}
</p>
</div>
</form>
<div className={styles.inputWrapper}>
<label htmlFor="password" className={styles.label}>
λΉ„λ°€λ²ˆν˜Έ
</label>
<input
id="password"
type="password"
className={`${styles.input} ${errors.password ? styles.inputError : ''}`}
{...register('password', {
required: ERROR_MESSAGES.PASSWORD_REQUIRE,
minLength: {
value: 8,
message: ERROR_MESSAGES.PASSWORD_TOO_SHORT,
},
})}
/>
{errors.password && (
<p className={styles.errorMessage}>{errors.password.message}</p>
)}
</div>
<Button
type="submit"
disabled={!isValid}
className={!isValid ? styles.disabled : ''}
style={{ height: '40px' }}
>
둜그인
</Button>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<p>
νšŒμ›μ΄ μ•„λ‹ˆμ‹ κ°€μš”?{' '}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맨였λ₯Έμͺ½ λ„μ–΄μ“°κΈ°λŠ” μΌλΆ€λŸ¬ λ„£μœΌμ‹ κ±΄κ°€μš”?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

λ„€..곡백이 μž‡λŠ”κ²Œ 더 μ΄λ»λ³΄μ—¬μ„œ

Copy link
Collaborator

@devmanta devmanta Nov 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naseungyeop μ•„.. μ € 사이사이 간격을 μ΄λ ‡κ²Œ ν•˜μ…¨κ΅°μš”..!
λ‹€μŒλ²ˆμ— css둜 μ²˜λ¦¬ν•˜λŠ” λ°©ν–₯ κ³ λ €ν•΄μ£Όμ‹œλ©΄ μ’‹μ„κ²ƒκ°™λ„€μš”~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

λ„΅

<span
style={{
color: 'var(--violet)',
textDecoration: 'underline',
cursor: 'pointer',
}}
onClick={() => router.push('/signup')}
>
νšŒμ›κ°€μž…ν•˜κΈ°
</span>{' '}
</p>
</div>
</form>
</AuthLayout>
);
}