New 페이지에서 일기를 작성할 수 있는 기능을 구현했다.
날짜 선택, 감정 선택, 일기 내용 입력이 가능하며, 날짜 포맷팅 유틸리티를 통해 일관된 날짜 형식을 유지한다.
날짜 포맷팅 유틸리티
formatWithZero 함수
날짜를 두 자릿수로 일관되게 표시하기 위한 함수다.
const formatWithZero = (number: number) =>
number < 10 ? `0${number}` : number;
숫자가 10보다 작을 경우 앞에 0을 붙여 반환한다.
getStringDate 함수
날짜 데이터를 원하는 문자열 형식으로 변환하는 함수다.
export const getStringDate = (
targetDate: Date | string | number,
format: string = "yyyy-mm-dd"
) => {
const dateObj =
targetDate instanceof Date ? targetDate : new Date(targetDate);
const year = dateObj.getFullYear();
const month = formatWithZero(dateObj.getMonth() + 1);
const date = formatWithZero(dateObj.getDate());
switch (format) {
case "yyyy.mm.dd":
return `${year}.${month}.${date}`;
case "yyyy-mm-dd":
default:
return `${year}-${month}-${date}`;
}
};
날짜 데이터는 Date, string, number 형태로 입력 가능하며, yyyy-mm-dd 또는 yyyy.mm.dd 형태의 문자열로 변환된다.
사용 예시
기본 포맷 (yyyy-mm-dd)

<h4>오늘의 날짜</h4>
<input
// ...
value={getStringDate(input.createdDate)}
/>
포맷 지정 (yyyy-mm-dd)

<div>
{getStringDate(createdDate, "yyyy.mm.dd")}
</div>
일기 작성 기능
상태 관리
일기 작성에 필요한 날짜, 감정, 내용을 input상태로 관리한다.
const [input, setInput] = useState<DiaryType | CreateDiaryType>({
createdDate: new Date().getTime(),
emotion: Emotion.NORMAL,
content: "",
});
날짜 및 내용 입력
onChangeInput함수로 날짜와 일기 내용 입력을 처리한다.
const onChangeInput = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
const {
target: { name, value },
} = e;
setInput((prev) => ({
...prev,
[name]: name === "createdDate" ? new Date(value).getTime() : value,
}));
};
날짜는 Date객체를 통해 밀리초로 변환 후 저장하고, 일기 내용은 입력된 값을 직접 저장한다.
날짜 입력
<h4>오늘의 날짜</h4>
<input
type="date"
name="createdDate"
onChange={onChangeInput}
value={getStringDate(input.createdDate)}
/>
일기 내용 입력
<h4 className="font-bold text-xl my-7">오늘의 일기</h4>
<textarea
placeholder="오늘은 어땠나요?"
name="content"
value={input.content}
onChange={onChangeInput}
/>
감정 선택
onChangeEmotion함수로 선택된 감정을 상태에 반영한다.
const onChangeEmotion = (newEmotion: Emotion) => {
setInput((prev) => ({
...prev,
emotion: newEmotion,
}));
};
const emotionList = [
{ emotion: Emotion.HAPPY, emotionName: "행복" },
{ emotion: Emotion.GOOD, emotionName: "좋음" },
{ emotion: Emotion.NORMAL, emotionName: "보통" },
{ emotion: Emotion.BAD, emotionName: "나쁨" },
{ emotion: Emotion.TERRIBLE, emotionName: "끔찍" },
];
<h4>오늘의 감정</h4>
<div>
{emotionList.map((item) => (
<EmotionItem
key={item.emotion}
{...item}
isSelected={item.emotion === input.emotion}
onClick={onChangeEmotion}
/>
))}
</div>
사용자가 EmotionItem을 클릭하면 onChangeEmotion 함수가 호출되어 선택된 감정이 input 상태에 반영된다.
클릭된 감정과 현재 상태가 일치하면 isSelected가 true가 되어 시각적으로 강조된다.
'Dev Log' 카테고리의 다른 글
| [AI 감성 일기장] Tailwind CSS와 Context API를 활용한 다크모드 구현 (0) | 2025.11.07 |
|---|---|
| [AI 감성 일기장] Diary 페이지 일기 상세보기 기능 구현 (0) | 2025.11.07 |
| [AI 감성 일기장] Home 페이지 날짜 관리 및 정렬 기능 구현 (0) | 2025.11.07 |
| [AI 감성 일기장] TypeScript에서 toSorted 메서드 인식 오류 해결 (0) | 2025.11.07 |
| [AI 감성 일기장] TypeScript로 재사용 가능한 공용 컴포넌트 구현 (0) | 2025.11.06 |
