Skip to content

Commit

Permalink
refactor: Calendar 컴포넌트 수정
Browse files Browse the repository at this point in the history
- date 유틸 분리
- 구조 리팩토링
- 조건 로직 간편화
  • Loading branch information
junghaesung79 committed Jun 15, 2024
1 parent 3b9d4ad commit 15abb86
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 210 deletions.
1 change: 1 addition & 0 deletions src/models/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Day = '일' | '월' | '화' | '수' | '목' | '금' | '토';
154 changes: 62 additions & 92 deletions src/pages/Coop/components/Calendar/Calendar.module.scss
Original file line number Diff line number Diff line change
@@ -1,109 +1,79 @@
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 24px 24px 10px;
background-color: #fff;
}

.day {
width: 28px;
height: 55px;
display: flex;
flex-direction: column;
justify-content:space-between;
align-items: center;
background-color: transparent;
cursor: pointer;
}

.day-of-week {
font-family: Pretendard, sans-serif;
margin-top: 24px;
gap: 10px;
font-size: 13px;
font-weight: 400;
line-height: 20.8px;
text-align: center;
color: #8e8e8e;

&__calendar {
display: flex;
flex-direction: column;
font-family: Pretendard, sans-serif;
padding-top: 24px;
padding-bottom: 8px;
gap: 16px;
background-color: #fff;
&--after,
&--selected {
color: #4b4b4b;
}
}

&__week {
display: flex;
justify-content: space-around;
text-align: center;
color: #8e8e8e;
font-size: 13px;
font-weight: 400;
padding: 0 16px;
}
.date {
position: relative;
display: flex;
justify-content: center;
align-items: center;
font-family: Pretendard, sans-serif;
font-size: 16px;
font-weight: 500;
line-height: 25.6px;
text-align: center;
color: #000;
width: 28px;
height: 28px;
border-radius: 99px;
background-color: transparent;
border: none;
padding-top: 2px;
box-sizing: border-box;

&__date {
display: flex;
justify-content: space-around;
align-items: center;
text-align: center;
&--previous {
color: #8e8e8e;
font-size: 16px;
font-weight: 500;
padding: 0 16px;

&--future {
color: #000;
}

&--today-font {
color: #175c8e;
}
}

&--selected {
display: flex;
width: 28px;
height: 28px;
padding: 4px;
margin: -8px;
border-radius: 999px;
background-color: #175c8e;
justify-content: center;
align-items: center;
font-size: 16px;
font-weight: 500;
color: #fff;
-webkit-tap-highlight-color: rgb(0 0 0 / 0%);
-webkit-tap-highlight-color: transparent;
}
&--today {
font-size: 15px;
line-height: 24px;
color: #175c8e;
border: 1px solid #175c8e;

&--today {
display: flex;
width: 28px;
height: 28px;
padding: 2px;
margin: -7px;
&::after {
content: '';
position: absolute;
bottom: -9px;
border: 1px solid #175c8e;
border-radius: 999px;
justify-content: center;
align-items: center;
font-size: 16px;
font-weight: 500;
width: 11.5px;
border-radius: 10px;
}

&--common {
width: 20px;
height: 20px;
}

&--wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 4px;
}
}

&__today--border {
display: flex;
width: 12px;
margin-top: 10px;
border-bottom: 2px solid #175c8e;
border-radius: 999px;
}

&__common--border {
display: flex;
border-color: none;
margin-top: 10px;
border-bottom: 2px solid none;
&--selected {
font-size: 15px;
line-height: 24px;
color: #fff;
background-color: #175c8e;
}
}

.cursor-pointer {
cursor: pointer;
}
88 changes: 35 additions & 53 deletions src/pages/Coop/components/Calendar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,49 @@
import { getDayOfWeek } from 'pages/Coop/hook/useGetDayOfWeek';
import cn from 'utils/className';
import { getDayOfWeek } from 'utils/date';

import dayjs from 'dayjs';

import styles from './Calendar.module.scss';

interface DateProps {
selectedDate: string;
interface Props {
selectedDate: string; // .format('YYYY-MM-DD') 형식
setSelectedDate: (dateType: string) => void;
}
export default function Calendar({ selectedDate, setSelectedDate }: DateProps) {
export default function Calendar({ selectedDate, setSelectedDate }: Props) {
const today = dayjs();
const weekDays = Array.from({ length: 7 }, (_, i) => today.add(i - 3, 'day'));
const weekDays = Array.from(
{ length: 7 },
(_, i) => today.add(i - 3, 'day').format('YYYY-MM-DD'),
);

return (
<div className={styles.container__calendar}>
<div className={styles.container__week}>
{weekDays.map((day) => (
<div key={day.format('YYYY-MM-DD')}>
<div className={styles['container__date--common']}>{getDayOfWeek(day.format('YYYY-MM-DD'))}</div>
</div>
))}
</div>
<div className={styles.container__date}>
{weekDays.map((day) => {
const dayFormat = day.format('YYYY-MM-DD');
return (
<div
key={dayFormat}
tabIndex={0}
role="button"
onClick={() => setSelectedDate(dayFormat)}
className={cn({
[styles['container__date--wrapper']]: true,
[styles['container__date--future']]: day.isAfter(today, 'day'),
[styles['container__date--today-font']]: day.isSame(today, 'day'),
})}
onKeyDown={(event) => {
if (event.key === 'Enter' || event.key === ' ') {
setSelectedDate(dayFormat);
}
}}
>
<div
className={cn({
[styles['container__date--selected']]: dayFormat === selectedDate,
[styles['container__date--common']]: !day.isSame(today, 'day') && dayFormat !== selectedDate,
[styles['cursor-pointer']]: true,
[styles['container__date--wrapper']]: day.isSame(today, 'day'),
[styles['container__date--today']]: day.isSame(today, 'day') && dayFormat !== selectedDate,
})}
>
{day.format('DD')}
</div>
<div className={cn({
[styles['container__today--border']]: day.isSame(today, 'day'),
[styles['container__common--border']]: !day.isSame(today, 'day'),
})}
/>
</div>
);
})}
</div>
<div className={styles.container}>
{weekDays.map((day) => (
<button
key={day}
type="button"
className={styles.day}
onClick={() => setSelectedDate(day)}
>
<span className={cn({
[styles['day-of-week']]: true,
[styles['day-of-week--after']]: dayjs(day).isAfter(today, 'day'),
[styles['day-of-week--selected']]: day === selectedDate,
})}
>
{getDayOfWeek(day)}
</span>
<span className={cn({
[styles.date]: true,
[styles['date--previous']]: dayjs(day).isBefore(today, 'day'),
[styles['date--today']]: day === today.format('YYYY-MM-DD'),
[styles['date--selected']]: day === selectedDate,
})}
>
{dayjs(day).format('DD')}
</span>
</button>
))}
</div>
);
}
14 changes: 7 additions & 7 deletions src/pages/Coop/components/MenuCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,25 @@ import axios from 'axios';
import styles from './MenuCard.module.scss';

interface Props {
selectedMenuType: DiningType;
selectedDate: string;
diningType: DiningType;
date: string;
}

interface FileInfo {
file: File;
presignedUrl: string;
}

export default function MenuCard({ selectedMenuType, selectedDate }: Props) {
export default function MenuCard({ diningType, date }: Props) {
const { uploadDiningImageMutation } = useUploadDiningImage();
const { toggleSoldOut } = useSoldOut();
const fileInputRefs = useRef<{ [key: number]: HTMLInputElement | null }>({});
const [isSoldOutModalOpen, setIsSoldOutModalOpen] = useState(false);
const [selectedMenu, setSelectedMenu] = useState<Dining | null>(null);
const formattedDate = selectedDate.replace('-', '').replace('-', '').substring(2);
const formattedDate = date.replace('-', '').replace('-', '').substring(2);
const { data: dinings } = useGetDinings(formattedDate);
const [openMenu, setOpenMenu] = useState<OperatingStatus>(
getOpenMenuType(selectedMenuType, formattedDate),
getOpenMenuType(diningType, formattedDate),
);

const uploadImage = async ({ presignedUrl, file }: FileInfo) => {
Expand Down Expand Up @@ -97,8 +97,8 @@ export default function MenuCard({ selectedMenuType, selectedDate }: Props) {
};

useEffect(() => {
setOpenMenu(getOpenMenuType(selectedMenuType, formattedDate));
}, [selectedMenuType, formattedDate]);
setOpenMenu(getOpenMenuType(diningType, formattedDate));
}, [diningType, formattedDate]);

return (
<Suspense fallback={<div />}>
Expand Down
30 changes: 15 additions & 15 deletions src/pages/Coop/components/MenuType/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,44 @@ import cn from 'utils/className';
import styles from './MenuType.module.scss';

interface MenuTypeProps {
selectedMenuType: DiningType;
setSelectedMenuType: (menuType: DiningType) => void;
diningType: DiningType;
setDiningType: (diningType: DiningType) => void;
}

export default function MenuType({ selectedMenuType, setSelectedMenuType }: MenuTypeProps) {
export default function MenuType({ diningType, setDiningType }: MenuTypeProps) {
return (
<div className={styles.place__container}>
<button
className={cn({
[styles['place__button--selected']]: selectedMenuType === 'BREAKFAST',
[styles.place__button]: selectedMenuType !== 'BREAKFAST',
[styles['place__button--selected']]: diningType === 'BREAKFAST',
[styles.place__button]: diningType !== 'BREAKFAST',
})}
onClick={() => setSelectedMenuType('BREAKFAST')}
onKeyDown={(e) => e.key === 'Enter' && setSelectedMenuType('BREAKFAST')}
onClick={() => setDiningType('BREAKFAST')}
onKeyDown={(e) => e.key === 'Enter' && setDiningType('BREAKFAST')}
type="button"
tabIndex={0}
>
아침
</button>
<button
className={cn({
[styles['place__button--selected']]: selectedMenuType === 'LUNCH',
[styles.place__button]: selectedMenuType !== 'LUNCH',
[styles['place__button--selected']]: diningType === 'LUNCH',
[styles.place__button]: diningType !== 'LUNCH',
})}
onClick={() => setSelectedMenuType('LUNCH')}
onKeyDown={(e) => e.key === 'Enter' && setSelectedMenuType('LUNCH')}
onClick={() => setDiningType('LUNCH')}
onKeyDown={(e) => e.key === 'Enter' && setDiningType('LUNCH')}
type="button"
tabIndex={0}
>
점심
</button>
<button
className={cn({
[styles['place__button--selected']]: selectedMenuType === 'DINNER',
[styles.place__button]: selectedMenuType !== 'DINNER',
[styles['place__button--selected']]: diningType === 'DINNER',
[styles.place__button]: diningType !== 'DINNER',
})}
onClick={() => setSelectedMenuType('DINNER')}
onKeyDown={(e) => e.key === 'Enter' && setSelectedMenuType('DINNER')}
onClick={() => setDiningType('DINNER')}
onKeyDown={(e) => e.key === 'Enter' && setDiningType('DINNER')}
type="button"
tabIndex={0}
>
Expand Down
Loading

0 comments on commit 15abb86

Please sign in to comment.