Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/#67] 펫 이름 뷰 구현 #68

Merged
merged 5 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all 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 src/page/onboarding/index/Onboarding.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

const Onboarding = () => {
return (
<>
Expand Down
31 changes: 31 additions & 0 deletions src/page/onboarding/index/component/petName/PetName.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { style } from "@vanilla-extract/css";

export const layout = style({
display: "flex",
flexDirection: "column",
padding: "8rem 2rem",
gap: "9rem",
});

export const imgStyle = style({
width: "16.5rem",
height: "9.3rem",
marginBottom: "1.6rem",
});

export const btnWrapper = style({
maxWidth: "76.8rem",
width: "100%",
Copy link
Collaborator

Choose a reason for hiding this comment

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

p5) 미리 미리 고려해서 구현해두는 예림 누나 굿 ~

position: "fixed",
bottom: 0,

display: "grid",
gridTemplateColumns: "9.6rem calc(100% - 9.6rem)",
Copy link
Collaborator

Choose a reason for hiding this comment

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

p5) 이런 계산 식이라니.. 멋있다

gap: "1.2rem",
whiteSpace: "nowrap",
padding: "1.2rem 2rem 3.2rem 2rem",
});

export const errorLayout = style({
marginTop: "0.8rem",
});
71 changes: 71 additions & 0 deletions src/page/onboarding/index/component/petName/PetName.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useState, ChangeEvent } from "react";
import { useNavigate } from "react-router-dom";
import * as styles from "./PetName.css";
import onboardingImg from "@asset/image/image 1730.png";
import { ONBOARDING_GUIDE } from "@page/onboarding/index/constant/onboardingGuide";
import Title from "@page/onboarding/index/common/title/Title";
import Docs from "@page/onboarding/index/common/docs/Docs";
import { TextField } from "@common/component/TextField";
import { Button } from "@common/component/Button";
import { validatePetName } from "../../util/validatePetName";

const PetName = () => {
// 상태 하나로 관리
const [petName, setPetName] = useState("");

// 펫이름 입력 처리
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setPetName(e.target.value);
};

// 유효성 검사 결과
const validationMessages = petName ? validatePetName(petName) : [];
const isValid = petName && validationMessages.length === 0;
Comment on lines +21 to +23
Copy link
Collaborator

Choose a reason for hiding this comment

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

p5) 유효성 검사 좋아요 🫠❤️


// 뒤로 가기
const navigate = useNavigate();
const handleGoBack = () => {
navigate(-1);
};
Comment on lines +27 to +29
Copy link
Collaborator

Choose a reason for hiding this comment

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

p3) 전에 논의 많이 하기로는 -1 은 지양하기로 했던 거 같은데, 이걸 사용해야만 이유가 있었을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

아! 해당 pr은 논의 이전에 올린 pr입니다..!
논의 이후에도 온보딩 플로우 기디논의가 있어서 플로우 확정이 나면 변경하려고 모든 컴포넌트에서 이동 버튼 구현 안해두었습니다!
현재는 기디 논의가 확정 난 상황이고, 조립시 한 번에 구현 하려고 합니다!! 앞으로의 pr에서 해당 내용 작성해 두겠습니다!


// 다음 버튼
const handleNext = () => {
console.log("다음 pr에서 구현할래욥.");
};

return (
<>
{/* 상단 영역 */}
<div className={styles.layout}>
<div>
<img src={onboardingImg} alt="onboarding-character" className={styles.imgStyle} />
<Title text={ONBOARDING_GUIDE.petName.title} />
<Docs text={ONBOARDING_GUIDE.petName.docs} />
</div>

{/* 펫이름 입력 영역 */}
<div>
<TextField
state={petName === "" ? "default" : isValid ? "default" : "error"}
value={petName}
onChange={handleChange}
placeholder="닉네임을 입력해주세요."
/>
<div className={styles.errorLayout}>
{validationMessages.map((message) => (
<Docs key={`error-${message}`} state="lError" text={message} />
))}
</div>
</div>
</div>

{/* 하단 버튼 */}
<div className={styles.btnWrapper}>
<Button label="돌아가기" size="large" variant="solidNeutral" disabled={false} onClick={handleGoBack} />
<Button label="다음" size="large" variant="solidPrimary" disabled={!isValid} onClick={handleNext} />
</div>
</>
);
};

export default PetName;
7 changes: 6 additions & 1 deletion src/page/onboarding/index/constant/errorMsg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ export const ERROR_MSG = {
spaceSymbol: "공백이나 특수문자는 사용할 수 없어요.",
ko: "완성된 한글을 입력해 주세요.", // 해당 메시지 확정 아님
},

// 여기 메시지는 다 확정 아님
petName: {
ko: "한글만 입력할 수 있어요.",
enNum: "숫자나 영어는 사용할 수 없어요.",
length: "2자 이상 8자 이하로 입력해주세요.",
spaceSymbol: "공백이나 특수문자는 사용할 수 없어요.",
ko: "완성된 한글을 입력해 주세요.",
},

petAge: {
length: "100살 미만까지 가능해요",
},
Expand Down
2 changes: 1 addition & 1 deletion src/page/onboarding/index/util/validateNickname.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ export function validateNickname(nickname: string): string[] {
errors.push(ERROR_MSG.nickname.ko);
}

return errors; // 에러 메시지 배열 반환
return errors;
}
27 changes: 27 additions & 0 deletions src/page/onboarding/index/util/validatePetName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ERROR_MSG } from "../constant/errorMsg";

export function validatePetName(petName: string): string[] {
const errors: string[] = [];

// 영어 또는 숫자 하나라도 포함되면 오류
const alphanumericPattern = /[a-zA-Z0-9]/;
if (alphanumericPattern.test(petName)) {
errors.push(ERROR_MSG.petName.enNum); // 영어 또는 숫자가 포함된 경우
}
Comment on lines +4 to +10
Copy link
Collaborator

Choose a reason for hiding this comment

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

p4) error 라는 state 를 두고 setState 로 이전 상태 값에 에러를 추가하는 방법으로 세팅하는 방법이 있는데, 해당 방법으로 구현한 이유가 있을까용??

Copy link
Collaborator Author

@yarimu yarimu Jan 17, 2025

Choose a reason for hiding this comment

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

가장 큰 이유는 개인적인 취향이긴 한데, 상태 안두고 유틸 함수 작성하는 것을 좋아해서 입니도..호홍
그리고 해당 함수로 다른 컴포넌트에서 상태 비교를 통해 에러 메시지 렌더링도 해야하고, 버튼 활성화 유무도 결정해야해서 상태보다 함수로 들고다니는게 간편할 거라 생각했어요!

Copy link
Collaborator

Choose a reason for hiding this comment

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

p5) 아주 좋은 생각! 상태 많이 둬봤자 신경쓸 것만 많아져요~ 유틸함수 지향 잘 배웠네요! 좋습니다


// 펫이름 길이
if (petName.length < 2 || petName.length > 8) {
errors.push(ERROR_MSG.petName.length);
}

// 공백 특수문자
if (/[^a-zA-Z0-9가-힣ㄱ-ㅎㅏ-ㅣ]/.test(petName)) {
errors.push(ERROR_MSG.petName.spaceSymbol);
}
// 완성된 한글
if (/[ㄱ-ㅎㅏ-ㅣ]/.test(petName)) {
errors.push(ERROR_MSG.petName.ko);
}

return errors;
}
Loading