Skip to content

Commit

Permalink
Merge pull request #135 from boostcampwm-2024/Feature/#130_로그인_회원가입_U_구현
Browse files Browse the repository at this point in the history
Feature/#130 로그인 회원가입 ui 구현
  • Loading branch information
github-actions[bot] authored Nov 18, 2024
2 parents b2680bb + 564924f commit 07c63f7
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 8 deletions.
3 changes: 3 additions & 0 deletions client/src/assets/icons/lock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions client/src/assets/icons/mail.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions client/src/assets/icons/user.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion client/src/components/button/textButton.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const textButtonContainer = ({ variant }: { variant: "primary" | "seconda
const textButton = cva({
base: {
borderRadius: "md",
width: "150px",
width: "50%",
height: "40px",
cursor: "pointer",
},
Expand Down
36 changes: 36 additions & 0 deletions client/src/components/inputField/InputField.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { css } from "@styled-system/css";

export const formGroup = css({
position: "relative",
});

export const inputContainer = css({
position: "relative",
borderRadius: "md",
padding: "1",
background: "white/30",
});

export const inputBox = css({
width: "100%",
padding: "2",
paddingLeft: "4",
paddingRight: "12",
color: "gray.700",
"&:focus": {
outline: "none",
},
"&:placeholder": {
color: "gray.500",
},
});

export const iconBox = css({
position: "absolute",
top: "50%",
right: "4",
transform: "translateY(-50%)",
width: "6",
height: "6",
color: "white",
});
27 changes: 27 additions & 0 deletions client/src/components/inputField/InputField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { formGroup, iconBox, inputBox, inputContainer } from "./InputField.style";

interface InputFieldProps {
type?: string;
name: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
placeholder?: string;
Icon?: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
}

export const InputField = ({ type, name, value, onChange, placeholder, Icon }: InputFieldProps) => (
<div className={formGroup}>
<div className={inputContainer}>
<input
type={type}
name={name}
value={value}
onChange={onChange}
className={inputBox}
placeholder={placeholder}
required
/>
</div>
{Icon && <Icon className={iconBox} />}
</div>
);
10 changes: 7 additions & 3 deletions client/src/components/modal/modal.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export const overlayBox = css({
inset: 0,
width: "100%",
height: "100%",
background: "gray.500/30",
backdropFilter: "blur(5px)",
background: "gray.500/10",
backdropFilter: "blur(3px)",
});

export const modalContainer = cx(
Expand All @@ -29,14 +29,18 @@ export const modalContainer = cx(
position: "absolute",
transform: "translate(-50%, -50%)",
flexDirection: "column",
justifyContent: "space-between",
width: "400px",
height: "200px",
minHeight: "200px",
padding: "md",
background: "white/20",
boxShadow: "md",
blur: "1px",
}),
);
export const modalContent = css({
display: "flex",
flexGrow: 1,
justifyContent: "center",
alignItems: "center",
width: "100%",
Expand Down
1 change: 1 addition & 0 deletions client/src/components/sidebar/MenuButton.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const menuItemWrapper = css({
width: "300px",
padding: "md",
boxShadow: "sm",
cursor: "pointer",
});

export const imageBox = css({
Expand Down
15 changes: 11 additions & 4 deletions client/src/components/sidebar/MenuButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { useModal } from "@components/modal/useModal";
import { AuthModal } from "@src/features/auth/AuthModal";
import { menuItemWrapper, imageBox, textBox } from "./MenuButton.style";

export const MenuButton = () => {
const { isOpen, openModal, closeModal } = useModal();

return (
<div className={menuItemWrapper}>
<div className={imageBox}></div>
<p className={textBox}>Noctturn</p>
</div>
<>
<button className={menuItemWrapper} onClick={openModal}>
<div className={imageBox}></div>
<p className={textBox}>Noctturn</p>
</button>
<AuthModal isOpen={isOpen} onClose={closeModal} />
</>
);
};
46 changes: 46 additions & 0 deletions client/src/features/auth/AuthModal.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { css, cva } from "@styled-system/css";

export const container = cva({
base: {
display: "flex",
gap: "lg",
flexDirection: "column",
justifyContent: "space-between",
width: "100%",
},
variants: {
mode: {
login: {
height: "300px",
},
register: {
height: "360px",
},
},
},
defaultVariants: {
mode: "login",
},
});

export const title = css({
textStyle: "display-medium32",
color: "white",
textAlign: "center",
textShadow: "0 2px 4px rgba(0,0,0,0.1)",
});

export const toggleButton = css({
marginBottom: "md",
color: "white",
cursor: "pointer",
"&:hover": {
textDecoration: "underline",
},
});

export const formContainer = css({
display: "flex",
gap: "md",
flexDirection: "column",
});
91 changes: 91 additions & 0 deletions client/src/features/auth/AuthModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useState } from "react";
import Lock from "@assets/icons/lock.svg?react";
import Mail from "@assets/icons/mail.svg?react";
import User from "@assets/icons/user.svg?react";
import { Modal } from "@components/modal/modal";
import { InputField } from "@src/components/inputField/InputField";
import { container, formContainer, title, toggleButton } from "./AuthModal.style";

interface AuthModalProps {
isOpen: boolean;
onClose: () => void;
}

export const AuthModal = ({ isOpen, onClose }: AuthModalProps) => {
const [mode, setMode] = useState<"login" | "register">("login");
const [formData, setFormData] = useState({
name: "",
email: "",
password: "",
});

const toggleMode = () => {
setMode(mode === "login" ? "register" : "login");
setFormData({ email: "", password: "", name: "" });
};

const closeModal = () => {
setMode("login");
setFormData({ email: "", password: "", name: "" });
onClose();
};

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
};

const handleSubmitButtonClick = () => {
// TODO API 연결
closeModal();
};

return (
<Modal
isOpen={isOpen}
primaryButtonLabel={mode === "login" ? "로그인" : "회원가입"}
primaryButtonOnClick={handleSubmitButtonClick}
secondaryButtonLabel="취소"
secondaryButtonOnClick={closeModal}
>
<div className={container({ mode })}>
<h1 className={title}>{mode === "login" ? "Login" : "Sign Up"}</h1>
<div className={formContainer}>
{mode === "register" && (
<InputField
type="text"
name="name"
value={formData.name}
onChange={handleInputChange}
placeholder="이름"
Icon={User}
/>
)}
<InputField
type="email"
name="email"
value={formData.email}
onChange={handleInputChange}
placeholder="이메일"
Icon={Mail}
/>
<InputField
type="password"
name="password"
value={formData.password}
onChange={handleInputChange}
placeholder="비밀번호"
Icon={Lock}
/>
</div>

<button onClick={toggleMode} className={toggleButton}>
{mode === "login"
? "계정이 없으신가요? 회원가입하기"
: "이미 계정이 있으신가요? 로그인하기"}
</button>
</div>
</Modal>
);
};
12 changes: 12 additions & 0 deletions client/src/styles/typography.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,16 @@ export const textStyles = defineTextStyles({
textTransform: "None",
},
},

"display-medium32": {
value: {
fontFamily: "Inter",
fontWeight: "700",
fontSize: "32px",
lineHeight: "40px",
letterSpacing: "-0.2px",
textDecoration: "None",
textTransform: "None",
},
},
});

0 comments on commit 07c63f7

Please sign in to comment.