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

[2주차] 김철흥 미션 제출합니다. #3

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
54e725f
ReactTS To Do List Project Setup
DefineXX Mar 18, 2025
1e51731
docs: PR 템플릿 추가
DefineXX Mar 18, 2025
61e3d03
chore: 경로 별칭 설정
DefineXX Mar 18, 2025
3c36fdc
chore: favicon 변경
DefineXX Mar 18, 2025
720342f
chore: styled-components 설치 및 스타일 가이드 세팅
DefineXX Mar 18, 2025
ceb2085
chore: vite-plugin-svgr 설치 및 세팅
DefineXX Mar 18, 2025
7f31b3b
chore: 폰트 및 글로벌 스타일 세팅
DefineXX Mar 18, 2025
182b3a6
chore: 폰트 및 글로벌 스타일 세팅
DefineXX Mar 18, 2025
72f74aa
Merge branch 'DefineXX' of https://github.com/DefineXX/react-todo-21t…
DefineXX Mar 19, 2025
77cf062
style: 스타일 가이드 수정
DefineXX Mar 19, 2025
2be3c9b
feat: 캘린더 기본 UI 구현
DefineXX Mar 19, 2025
a77cea8
feat: date-fns 설치 및 캘린더 생성 로직 구현
DefineXX Mar 20, 2025
12b4cb8
feat: Task 등록 UI 구현
DefineXX Mar 21, 2025
d86960a
feat: 포스트잇 컴포넌트 구현 및 Register 컴포넌트 refactor
DefineXX Mar 21, 2025
9a426d0
feat: ToDo 및 Done 컴포넌트 UI 구현
DefineXX Mar 21, 2025
4fb4844
feat: Task Item UI 구현
DefineXX Mar 21, 2025
c34b6f1
feat: 선택된 날짜에 대한 전역 상태 관리 구현
DefineXX Mar 21, 2025
517b393
feat: 선택 날짜에 따른 Task List 렌더링 및 add & toggle 로직 구현
DefineXX Mar 21, 2025
698e2f8
fix: 실시간 업데이트된 task 렌더링을 위해 Task 전역 상태 관리 로직 구현
DefineXX Mar 22, 2025
fa3c6bc
feat: 폰트 사이즈에 clamp 함수 적용
DefineXX Mar 22, 2025
757584f
fix: 캘린더 및 ToDoList 관련 컴포넌트 내 렌더링 로직 수정 및 적용
DefineXX Mar 22, 2025
35fd2d9
feat: 반응형 임시 구현
DefineXX Mar 22, 2025
283854d
refactor: 디렉토리 refactor 및 미사용 이미지 제거
DefineXX Mar 22, 2025
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
Prev Previous commit
Next Next commit
feat: date-fns 설치 및 캘린더 생성 로직 구현
DefineXX committed Mar 20, 2025
commit a77cea87f5a50e0df9e666b827e4d29792ea587e
3 changes: 3 additions & 0 deletions bun.lock
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
"": {
"name": "ceos-21th-react-todo",
"dependencies": {
"date-fns": "^4.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"styled-components": "^6.1.16",
@@ -308,6 +309,8 @@

"csstype": ["[email protected]", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],

"date-fns": ["[email protected]", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="],

"debug": ["[email protected]", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],

"deep-is": ["[email protected]", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"date-fns": "^4.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"styled-components": "^6.1.16"
18 changes: 13 additions & 5 deletions src/components/Calendar/Calendar.styled.ts
Original file line number Diff line number Diff line change
@@ -129,7 +129,7 @@ export const CalendarGrid = styled.ul`

display: grid;
grid-template-columns: repeat(7, 1fr);
grid-template-rows: repeat(6, 1fr);
grid-template-rows: auto;
`;

export const CalendarGridItem = styled.li`
@@ -141,7 +141,8 @@ export const CalendarGridItem = styled.li`

export const CalendarGridItemLink = styled.a`
width: 100%;
height: 10rem;

aspect-ratio: 1 / 1;

display: flex;
flex-direction: column;
@@ -150,12 +151,19 @@ export const CalendarGridItemLink = styled.a`
gap: 0.8rem;
`;

export const DayText = styled.span<{ $isSelected: boolean }>`
export const DayTextBox = styled.div<{
$isSelected: boolean;
$isCurrentMonthDay: boolean;
}>`
position: relative;

${({ theme }) => theme.fontStyles.Header2}
color: ${({ $isSelected, theme }) =>
$isSelected ? theme.colors.Grayscale[0] : theme.colors.Grayscale[500]};
color: ${({ $isSelected, $isCurrentMonthDay, theme }) =>
$isSelected
? theme.colors.Grayscale[0]
: $isCurrentMonthDay
? theme.colors.Grayscale[500]
: theme.colors.Grayscale[300]};

&::before {
content: ${({ $isSelected }) => ($isSelected ? '""' : 'none')};
68 changes: 58 additions & 10 deletions src/components/Calendar/Calendar.tsx

Choose a reason for hiding this comment

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

캘린더 직접 구현하신거 대단합니다,,

Original file line number Diff line number Diff line change
@@ -3,17 +3,57 @@ import { useState } from 'react';
import { CalendarIcon } from '@/icons/Calendar';
import { LeftArrowIcon, RightArrowIcon } from '@/icons/Arrow';

import { CALENDAR_DAY_LIST, DAY_LIST } from '@/constants/calendar';
import { DAY_LIST, MONTH_NAMES } from '@/constants/calendar';

import { generateCalendar } from '@/utils/generateCalender';

import * as S from './Calendar.styled';

Choose a reason for hiding this comment

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

이렇게 스타일 구현할 수 있다는 걸 처음 알았습니다... 신기하네용


const Calendar = () => {
const [currentDate, setCurrentDate] = useState({
year: 2025,
month: 'March',
month: 3,
day: 20,
});

const currentMonthName = MONTH_NAMES[currentDate.month - 1];

const calendarDays = generateCalendar(currentDate.year, currentDate.month);

const handlePrevMonth = () => {
if (currentDate.month === 1) {
return setCurrentDate({
...currentDate,
year: currentDate.year - 1,
month: 12,
day: 1,
});
}

setCurrentDate({
...currentDate,
month: currentDate.month - 1,
day: 1,
});
};

const handleNextMonth = () => {
if (currentDate.month === 12) {
return setCurrentDate({
...currentDate,
year: currentDate.year + 1,
month: 1,
day: 1,
});
}

setCurrentDate({
...currentDate,
month: currentDate.month + 1,
day: 1,
});
};

const handleDaySelect = (day: number) => {
setCurrentDate({
...currentDate,
@@ -31,13 +71,13 @@ const Calendar = () => {

{/* Date Picker */}
<S.DatePickerSection>
<S.PreviousMonthButton>
<S.PreviousMonthButton onClick={handlePrevMonth}>
<LeftArrowIcon />
</S.PreviousMonthButton>
<S.CurrentMonthYear>
{currentDate.month}, {currentDate.year}
{currentMonthName}, {currentDate.year}
</S.CurrentMonthYear>
<S.NextMonthButton>
<S.NextMonthButton onClick={handleNextMonth}>
<RightArrowIcon />
</S.NextMonthButton>
</S.DatePickerSection>
@@ -55,12 +95,20 @@ const Calendar = () => {
{/* Calendar Grid */}
<S.CalendarGridSection>
<S.CalendarGrid>
{CALENDAR_DAY_LIST.map((day, index) => (
{calendarDays.map((day, index) => (
<S.CalendarGridItem key={index}>
<S.CalendarGridItemLink onClick={() => handleDaySelect(day)}>
<S.DayText $isSelected={currentDate.day === day}>
{day}
</S.DayText>
<S.CalendarGridItemLink
onClick={() => handleDaySelect(day.date)}
>
<S.DayTextBox
$isCurrentMonthDay={day.monthType === 'current'}
$isSelected={
day.monthType === 'current' &&
currentDate.day === day.date
}
>
{day.date}
</S.DayTextBox>
<S.UnLoggedCircle />
</S.CalendarGridItemLink>
</S.CalendarGridItem>
16 changes: 13 additions & 3 deletions src/constants/calendar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
export const DAY_LIST = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

export const CALENDAR_DAY_LIST = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31,
export const MONTH_NAMES = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];
2 changes: 1 addition & 1 deletion src/pages/Home.styled.ts
Original file line number Diff line number Diff line change
@@ -3,5 +3,5 @@ import styled from 'styled-components';
export const HomeContainer = styled.div`
width: 100%;
height: 100%;
padding: 12rem 9.6rem;
padding: 6rem 9.6rem;
`;
49 changes: 49 additions & 0 deletions src/utils/generateCalender.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { format, getDaysInMonth, startOfMonth, subMonths } from 'date-fns';

export const generateCalendar = (year: number, month: number) => {
const firstDay = startOfMonth(new Date(year, month - 1, 1));
// console.log('특정 달의 1일: ', firstDay);

const startDayOfWeek = firstDay.getDay();
// console.log('특정 달의 첫날의 요일: ', startDayOfWeek); // 0(일) ~ 6(토)

const totalDaysInMonth = getDaysInMonth(firstDay);
// console.log('특정 달의 총 일수: ', totalDaysInMonth);

const prevMonth = subMonths(firstDay, 1);
const prevMonthDays = getDaysInMonth(prevMonth);
// console.log('이전 달의 총 일수: ', prevMonthDays);

const prevDays = Array.from({ length: startDayOfWeek }, (_, i) => ({
date: prevMonthDays - startDayOfWeek + i + 1,
fullDate: format(
new Date(year, month - 2, prevMonthDays - startDayOfWeek + 1 + i),
'yyyy-MM-dd'
),
monthType: 'prev',
}));

const currentDays = Array.from({ length: totalDaysInMonth }, (_, i) => ({
date: i + 1,
fullDate: format(new Date(year, month - 1, i + 1), 'yyyy-MM-dd'),
monthType: 'current',
}));

const totalCells = prevDays.length + currentDays.length;
// console.log('총 달력 Unit의 수: ', totalCells);

const nextDaysCount = totalCells % 7 === 0 ? 0 : 7 - (totalCells % 7);
// console.log('렌더링할 다음 달의 일부 날짜의 수: ', nextDaysCount);

const nextDays = Array.from({ length: nextDaysCount }, (_, i) => ({
date: i + 1,
fullDate: format(new Date(year, month, i + 1), 'yyyy-MM-dd'),
monthType: 'next',
}));

// 최종 달력 날짜 배열
const calendarDays = [...prevDays, ...currentDays, ...nextDays];


return calendarDays;
};