Skip to content

Commit

Permalink
Merge pull request #218 from boostcampwm2023/feature/signup-animation
Browse files Browse the repository at this point in the history
feat: 회원가입 화면 애니메이션 구현
  • Loading branch information
surinkwon authored Mar 11, 2024
2 parents 6fdf027 + 11f630c commit 6a4649f
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 93 deletions.
29 changes: 20 additions & 9 deletions frontend/src/components/account/NicknameInput.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import { ChangeEvent, useState } from "react";
import { SIGNUP_STEP } from "../../constants/account";
import NextStepButton from "./NextStepButton";
import { SIGNUP_STEP } from "../../constants/account";

interface NicknameInputProps {
currentStepNumber: number;
setCurrentStep: React.Dispatch<
React.SetStateAction<{ NUMBER: number; NAME: string }>
>;
nicknameRef: React.MutableRefObject<string>;
}

const NicknameInput = ({ setCurrentStep, nicknameRef }: NicknameInputProps) => {
const NicknameInput = ({
currentStepNumber,
setCurrentStep,
nicknameRef,
}: NicknameInputProps) => {
const [inputValue, setInputValue] = useState<string>("");
const [validated] = useState<boolean | null>(null);

const handleNextButtonClick = () => {
setCurrentStep(SIGNUP_STEP.STEP2);
const jobElement = document.getElementById("job");
jobElement?.scrollIntoView({ behavior: "smooth", block: "nearest" });
};

const handleInputChange = ({ target }: ChangeEvent<HTMLInputElement>) => {
Expand All @@ -25,7 +28,13 @@ const NicknameInput = ({ setCurrentStep, nicknameRef }: NicknameInputProps) => {
};

return (
<div id="nickname" className="h-[100%] flex items-center">
<div
className={`flex h-[100%] ${
currentStepNumber === SIGNUP_STEP.STEP1.NUMBER
? "items-center"
: "items-end"
}`}
>
<div className="w-[80%]">
<label
className="text-3xl font-semibold text-dark-gray"
Expand All @@ -34,7 +43,7 @@ const NicknameInput = ({ setCurrentStep, nicknameRef }: NicknameInputProps) => {
LESSER에서 사용할 제 이름은
</label>
<br />
<div className="flex">
<div id="nickname-input-box" className="flex">
<div className="inline">
<input
type="text"
Expand All @@ -57,9 +66,11 @@ const NicknameInput = ({ setCurrentStep, nicknameRef }: NicknameInputProps) => {
<span className="text-3xl font-semibold text-dark-gray">입니다</span>
</div>
</div>
<NextStepButton onNextButtonClick={handleNextButtonClick}>
Next
</NextStepButton>
{currentStepNumber === SIGNUP_STEP.STEP1.NUMBER && (
<NextStepButton onNextButtonClick={handleNextButtonClick}>
Next
</NextStepButton>
)}
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,45 +1,62 @@
import { useEffect } from "react";
import useDropdown from "../../hooks/common/dropdown/useDropdown";
import { JOB_INPUT_INFO, SIGNUP_STEP } from "../../constants/account";
import NextStepButton from "./NextStepButton";
import { JOB_INPUT_INFO, SIGNUP_STEP } from "../../constants/account";

interface JobInputProps {
setCurrentStep: React.Dispatch<React.SetStateAction<{ NUMBER: number; NAME: string }>>;
jobRef: React.MutableRefObject<string | null>;
currentStepNumber: number;
setCurrentStep: React.Dispatch<
React.SetStateAction<{ NUMBER: number; NAME: string }>
>;
positionRef: React.MutableRefObject<string | null>;
}

const JobInput = ({ setCurrentStep, jobRef }: JobInputProps) => {
const PositionInput = ({
currentStepNumber,
setCurrentStep,
positionRef,
}: JobInputProps) => {
const { Dropdown, selectedOption } = useDropdown({
placeholder: JOB_INPUT_INFO.PLACEHOLDER,
options: JOB_INPUT_INFO.OPTIONS,
});

const handleNextButtonClick = () => {
setCurrentStep(SIGNUP_STEP.STEP3);
const techElement = document.getElementById("tech");
techElement?.scrollIntoView({ behavior: "smooth", block: "nearest" });
};

useEffect(() => {
jobRef.current = selectedOption;
positionRef.current = selectedOption;
}, [selectedOption]);

return (
<div id="job" className="h-[100%] flex items-center">
<div className="w-[80%] flex gap-4 items-center">
<span className="text-3xl font-semibold text-dark-gray">저의 주요 직무는</span>
<div
className={`flex h-[90%] ${
currentStepNumber !== SIGNUP_STEP.STEP3.NUMBER
? "items-center"
: "items-end"
}`}
>
<div id="position-input-box" className="w-[80%] flex gap-4 items-center">
<span className="text-3xl font-semibold text-dark-gray">
저의 주요 직무는
</span>
<Dropdown
buttonClassName={`w-[14.25rem] h-[3.25rem] rounded-xl bg-middle-green text-white text-m shadow-box ${
buttonClassName={`w-[14.25rem] min-h-[3.25rem] rounded-xl bg-middle-green text-white text-m shadow-box ${
selectedOption && "font-bold"
}`}
containerClassName="w-[14.25rem] h-[18.5rem] overflow-y-auto shadow-box"
itemClassName="text-2xl text-text-gray py-3 px-9 hover:bg-middle-green hover:text-white hover:font-bold"
/>
<span className="text-3xl font-semibold text-dark-gray">입니다</span>
</div>
<NextStepButton onNextButtonClick={handleNextButtonClick}>Next</NextStepButton>
{currentStepNumber !== SIGNUP_STEP.STEP3.NUMBER && (
<NextStepButton onNextButtonClick={handleNextButtonClick}>
Next
</NextStepButton>
)}
</div>
);
};

export default JobInput;
export default PositionInput;
85 changes: 85 additions & 0 deletions frontend/src/components/account/SignupMainSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { useEffect, useRef } from "react";
import NicknameInput from "./NicknameInput";
import PositionInput from "./PositionInput";
import TechStackInput from "./TechStackInput";
import { SIGNUP_STEP } from "../../constants/account";

interface SignupMainSectionProps {
currentStepNumber: number;
setCurrentStep: React.Dispatch<
React.SetStateAction<{ NUMBER: number; NAME: string }>
>;
}

const SignupMainSection = ({
currentStepNumber,
setCurrentStep,
}: SignupMainSectionProps) => {
const nicknameRef = useRef<string>("");
const positionRef = useRef<string | null>(null);
const techRef = useRef<string[]>([]);

const handlePrevStepAreaClick = () => {
setCurrentStep((prevStep) => {
if (prevStep.NUMBER === SIGNUP_STEP.STEP3.NUMBER) {
return SIGNUP_STEP.STEP2;
}

if (prevStep.NUMBER === SIGNUP_STEP.STEP2.NUMBER) {
return SIGNUP_STEP.STEP1;
}

return prevStep;
});
};

const handleSignupButtonClick = () => {};

useEffect(() => {
const nicknameInput = document.getElementById("nickname");
const nicknameInputElement = document.getElementById("nickname-input-box");
const techStackInput = document.getElementById("tech");

switch (currentStepNumber) {
case SIGNUP_STEP.STEP1.NUMBER:
nicknameInput?.scrollIntoView({ behavior: "smooth", block: "center" });
break;

case SIGNUP_STEP.STEP2.NUMBER:
nicknameInputElement?.scrollIntoView({
behavior: "smooth",
block: "start",
});
break;

case SIGNUP_STEP.STEP3.NUMBER:
techStackInput?.scrollIntoView({ behavior: "smooth", block: "center" });
break;
}
}, [currentStepNumber]);

return (
<main className="relative ml-10 pl-7 w-[100%] h-[40.5rem]">
<div
className={`absolute top-0 bg-gradient-to-b from-white to-90% min-w-[90%] min-h-[9.25rem] z-10 ${
currentStepNumber > 1 && "hover:cursor-pointer"
}`}
onClick={handlePrevStepAreaClick}
></div>
<section className="h-[100%] overflow-y-hidden">
<NicknameInput
{...{ currentStepNumber, setCurrentStep, nicknameRef }}
/>
<PositionInput
{...{ currentStepNumber, setCurrentStep, positionRef }}
/>
<TechStackInput
{...{ setCurrentStep, techRef }}
onSignupButtonClick={handleSignupButtonClick}
/>
</section>
</main>
);
};

export default SignupMainSection;
27 changes: 21 additions & 6 deletions frontend/src/components/account/TechStackInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ import NextStepButton from "./NextStepButton";
import CategoryButton from "../common/CategoryButton";

interface TechStackInputProps {
setCurrentStep: React.Dispatch<
React.SetStateAction<{ NUMBER: number; NAME: string }>
>;
techRef: React.MutableRefObject<string[]>;
onSignupButtonClick: () => void;
}

const TechStackInput = ({ techRef, onSignupButtonClick }: TechStackInputProps) => {
const TechStackInput = ({
techRef,
onSignupButtonClick,
}: TechStackInputProps) => {
const { open, close } = useModal();
const [techStackList, setTechStackList] = useState<string[]>([]);

Expand All @@ -23,25 +29,34 @@ const TechStackInput = ({ techRef, onSignupButtonClick }: TechStackInputProps) =
};

return (
<div id="tech" className="h-[100%] flex items-center">
<div id="tech" className="h-[90%] flex items-center">
<div className="w-[80%]">
<p className="mb-3 text-3xl font-semibold text-dark-gray">저의 주요 기술 스택은</p>
<p className="mb-3 text-3xl font-semibold text-dark-gray">
저의 주요 기술 스택은
</p>
<div className="flex flex-wrap gap-3 mb-3">
{techStackList.map((techStack) => (
<CategoryButton category={techStack} onCloseButtonClick={handleCloseButtonClick} />
<CategoryButton
category={techStack}
onCloseButtonClick={handleCloseButtonClick}
/>
))}
</div>
<button
className="w-[11.25rem] h-[3.25rem] bg-middle-green rounded-xl text-m text-white mb-3 flex items-center shadow-box pl-3 pr-9"
type="button"
onClick={() => open(<TechStackModal {...{ techRef, close, setTechStackList }} />)}
onClick={() =>
open(<TechStackModal {...{ techRef, close, setTechStackList }} />)
}
>
<img src={plus} alt="plus" />
추가하기
</button>
<p className="text-3xl font-semibold text-dark-gray">입니다</p>
</div>
<NextStepButton onNextButtonClick={onSignupButtonClick}>가입하기</NextStepButton>
<NextStepButton onNextButtonClick={onSignupButtonClick}>
가입하기
</NextStepButton>
</div>
);
};
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/common/CategoryButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const CategoryButton = ({
category,
onCloseButtonClick,
}: CategoryButtonProps) => (
<div className="w-[12.25rem] h-[3.25rem] bg-light-green rounded-xl text-white text-2xl font-bold flex items-center py-2 pl-9 pr-3">
<div className="min-w-[12.25rem] min-h-[3.25rem] bg-light-green rounded-xl text-white text-2xl font-bold flex items-center py-2 pl-9 pr-3 shadow-box">
{category}
<button
type="button"
Expand Down
15 changes: 14 additions & 1 deletion frontend/src/hooks/common/dropdown/useDropdown.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ describe("dropdown hook test", () => {
options,
});

return <Dropdown />;
return (
<div>
<p>외부</p>
<Dropdown />;
</div>
);
};

it("드롭다운 클릭 시 잘 펼쳐지는가", () => {
Expand All @@ -42,4 +47,12 @@ describe("dropdown hook test", () => {
expect(screen.getByText(placeholder).textContent).toBe(placeholder);
expect(screen.queryByText(options[0])).toBeNull();
});

it("외부 클릭 시 드롭다운이 닫히는가", () => {
render(<TestComponent />);
fireEvent.click(screen.getByText(placeholder));
fireEvent.click(screen.getByText("외부"));

expect(screen.queryByText(options[0])).toBeNull();
});
});
Loading

0 comments on commit 6a4649f

Please sign in to comment.