Skip to content

Conversation

@SanginJeong
Copy link
Collaborator

요구사항

기본

  • ‘로고’ 버튼을 클릭하면 ‘/’ 페이지로 이동합니다. (새로고침)
  • 진행 중인 할 일과 완료된 할 일을 나누어 볼 수 있습니다.
  • 상단 입력창에 할 일 텍스트를 입력하고 추가하기 버튼을 클릭하거나 엔터를 치면 할 일을 새로 생성합니다.
  • 진행 중 할 일 항목의 왼쪽 버튼을 클릭하면 체크 표시가 되면서 완료 상태가 됩니다.
  • 완료된 할 일 항목의 왼쪽 버튼을 다시 클릭하면 체크 표시가 사라지면서 진행 중 상태가 됩니다.

스크린샷

localhost_3000_ (24) localhost_3000_ (26) localhost_3000_ (28)

멘토에게

  • 앞으로 App router를 사용할 일이 많을 것 같아서 복습 겸 page router를 사용했습니다.
  • 심화 프로젝트 시작 전에 감을 유지하기 위해서 요구사항만 정말 가볍게 만들었습니다. 순한 맛으로 부탁드려요 ㅠㅠ ^^;

@SanginJeong SanginJeong requested a review from kiJu2 October 31, 2025 05:12
@SanginJeong SanginJeong added the 순한맛🐑 마음이 많이 여립니다.. label Oct 31, 2025
@SanginJeong SanginJeong self-assigned this Oct 31, 2025
@kiJu2
Copy link
Collaborator

kiJu2 commented Nov 3, 2025

스프리트 미션 하시느라 수고 많으셨어요.
학습에 도움 되실 수 있게 꼼꼼히 리뷰 하도록 해보겠습니다. 😊

@kiJu2
Copy link
Collaborator

kiJu2 commented Nov 3, 2025

앞으로 App router를 사용할 일이 많을 것 같아서 복습 겸 page router를 사용했습니다.

크으 ~ 좋습니다 !

심화 프로젝트 시작 전에 감을 유지하기 위해서 요구사항만 정말 가볍게 만들었습니다. 순한 맛으로 부탁드려요 ㅠㅠ ^^;

넵넵 ~! ㅎㅎㅎ 참고해서 리뷰하도록 하겠습니다 !

Copy link
Collaborator

Choose a reason for hiding this comment

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

크으 ~ Axios 세팅이 깔끔하고 좋네요 👍

Comment on lines +4 to +18
interface PostTodoRequest {
name: string;
}

export interface PostTodoResponse extends TodoItem {
tenantId: string;
memo: string;
imageUrl: string;
}

export const postTodo = async ({
name,
}: PostTodoRequest): Promise<PostTodoResponse> => {
return instance.post("/items", { name });
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

굿굿 ! 응답과 요청 타입을 정의하셨군요 !

이제 타입스크립트에 완전 적응하신게 느껴집니다 👍👍👍👍

return (
<span
className={`${styles.badge} ${styles[variants]} ${className ?? ""}`}
aria-label={variantsToLabel[variants]}
Copy link
Collaborator

Choose a reason for hiding this comment

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

오호 aria-label도 신경쓰셨군요 ? 👐

Comment on lines +3 to +13
const variantsToLabel = {
todo: "TO DO",
done: "DONE",
};

interface BadgeProps {
variants: keyof typeof variantsToLabel;
className?: string;
}

const Badge = ({ variants, className }: BadgeProps) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

(의견/선택) Badge는 흔히 사용되는 유저 인터페이스예요 !

근데 지금 정의하신걸 보니까 해당 뱃지는 공통으로 사용되는 흔한 뱃지가 아니라 상태에 대한 뱃지를 표현하고 있는 것으로 보이는군요?
StatusBadge와 같이 네이밍을 해도 괜찮을 것 같습니다 !

Comment on lines +19 to +30
export const getServerSideProps = async () => {
try {
const response = await getTodos();
return {
props: {
todos: response,
},
};
} catch (error) {
console.error(error);
}
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

크으 ~ 적절한 SSR 활용이네요 👍

이렇게 되면 페이지를 그려주는 속도가 훨씬 빠르겠어요 👍

Comment on lines +14 to +25
<search>
<form className={styles.form} onSubmit={onSubmit}>
<input
className={`${styles.input} font-regular-16`}
value={value}
onChange={onChange}
type="text"
placeholder="할 일을 입력해주세요"
/>
<Button variants="append" type="submit" disabled={isDisabled} />
</form>
</search>
Copy link
Collaborator

Choose a reason for hiding this comment

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

크으 ~ HTML에 대해서 꼼꼼히 공부하신게 느껴집니다.

와우 search 태그를 쓰시는 수강생님은 처음 봤어요 👍👍👍
영역에 대한 의미가 확실하네요 훌륭합니다

Comment on lines +35 to +58
const [isDisabled, setIsDisabled] = useState(false);

const completedTodos: TodoItem[] = [];
const pendingTodos: TodoItem[] = [];

todos.forEach((todo) => {
if (todo.isCompleted) completedTodos.push(todo);
else pendingTodos.push(todo);
});

const handleSearchTermSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setIsDisabled(true);
try {
await postTodo({ name: searchTerm });
const updatedTodos = await getTodos();
setTodos(updatedTodos);
setSearchTerm("");
} catch (error) {
console.error(error);
} finally {
setIsDisabled(false);
}
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

만약 중복 요청을 방지하는 거라면 disabled 상태를 제거하고 useTransition을 사용해볼 수 있습니다 !

다음과 같이 사용해볼 수 있어요 !

const [isPending, startTransition] = useTransition();

const handleSearchTermSubmit = (e: FormEvent<HTMLFormElement>) => {
  e.preventDefault();
  startTransition(async () => {
    try {
      await postTodo({ name: searchTerm });
      const updatedTodos = await getTodos();
      setTodos(updatedTodos);
      setSearchTerm("");
    } catch (error) {
      console.error(error);
    }
  });
};

@kiJu2
Copy link
Collaborator

kiJu2 commented Nov 3, 2025

크으 ~ 수고하셨습니다 상인님 !
팀 프로젝트가 끝나면 헤이해질 수 있는데 꾸준히 학습하시는 모습이 정말 보기 좋습니다 😉👍
HTML의 기본과 리액트, 타입스크립트, SSR을 제대로 이해하고 적용하시는 것 같군요 ! 👍👍

@kiJu2 kiJu2 merged commit 92940f3 into codeit-bootcamp-frontend:Next-정상인 Nov 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

순한맛🐑 마음이 많이 여립니다..

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants