diff --git a/components/atoms/ColorLabel.tsx b/components/atoms/ColorLabel.tsx
new file mode 100644
index 000000000..aed3712e5
--- /dev/null
+++ b/components/atoms/ColorLabel.tsx
@@ -0,0 +1,24 @@
+import { Box, Flex } from "@chakra-ui/react";
+
+import { CustomColor } from "../../types/globals/interaction";
+import PointCircle from "./PointCircle";
+
+export interface ColorLabelProps {
+ color?: CustomColor;
+ colorText?: string;
+ //이후 colorText를 color로 변경
+ text: string;
+}
+
+function ColorLabel({ text, color, colorText }: ColorLabelProps) {
+ return (
+
+
+
+ {text}
+
+
+ );
+}
+
+export default ColorLabel;
diff --git a/components/atoms/LocationSelector.tsx b/components/atoms/LocationSelector.tsx
index eec5cf27e..19525d2ba 100644
--- a/components/atoms/LocationSelector.tsx
+++ b/components/atoms/LocationSelector.tsx
@@ -1,7 +1,7 @@
import { Select } from "@chakra-ui/react";
import { ChangeEvent, useEffect, useRef, useState } from "react";
-import { LOCATION_CONVERT } from "../../constants/location";
+import { LOCATION_TO_FULLNAME } from "../../constants/location";
import { DispatchType } from "../../types/hooks/reactTypes";
import { ActiveLocation } from "../../types/services/locationTypes";
import { isLocationType } from "../../utils/validationUtils";
@@ -57,7 +57,7 @@ export default function LocationSelector({
>
{options.map((option, idx) => (
))}
diff --git a/components/atoms/MonthNav.tsx b/components/atoms/MonthNav.tsx
index e63628145..f23a4dac0 100644
--- a/components/atoms/MonthNav.tsx
+++ b/components/atoms/MonthNav.tsx
@@ -1,42 +1,30 @@
+import { Box, Flex } from "@chakra-ui/react";
import { Dayjs } from "dayjs";
-import styled from "styled-components";
import { DispatchType } from "../../types/hooks/reactTypes";
-interface IMonthNav {
- month: number;
- setNavMonth: DispatchType;
+interface MonthNavProps {
+ monthNum: number;
+ changeMonth: DispatchType;
}
-function MonthNav({ month, setNavMonth }: IMonthNav) {
- const onClick = (dir: "left" | "right") => {
- if (dir === "left") setNavMonth((old) => old.subtract(1, "month"));
- else setNavMonth((old) => old.add(1, "month"));
+function MonthNav({ monthNum, changeMonth }: MonthNavProps) {
+ const handleMonthChange = (dir: "left" | "right") => {
+ if (dir === "left") changeMonth((old) => old.subtract(1, "month"));
+ else changeMonth((old) => old.add(1, "month"));
};
return (
-
- onClick("left")}>
+
+ handleMonthChange("left")}>
-
- {month + 1}월
- onClick("right")}>
+
+ {monthNum + 1}월
+ handleMonthChange("right")}>
-
-
+
+
);
}
-const Layout = styled.div`
- display: flex;
- align-items: center;
-
- font-size: 20px;
- font-weight: 700;
-`;
-
-const IconWrapper = styled.button`
- padding: 0 var(--gap-1);
-`;
-
export default MonthNav;
diff --git a/components/atoms/PointCircle.tsx b/components/atoms/PointCircle.tsx
index d17ee17e9..edde14d02 100644
--- a/components/atoms/PointCircle.tsx
+++ b/components/atoms/PointCircle.tsx
@@ -4,12 +4,13 @@ import { CustomColor } from "../../types/globals/interaction";
interface PointCircleProps {
color?: CustomColor;
+ colorText?: string;
}
-function PointCircle({ color = "mint" }: PointCircleProps) {
+function PointCircle({ color = "mint", colorText }: PointCircleProps) {
return (
-
+
);
}
diff --git a/components/atoms/PointCircleText.tsx b/components/atoms/PointCircleText.tsx
deleted file mode 100644
index 974448313..000000000
--- a/components/atoms/PointCircleText.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Box, Flex } from "@chakra-ui/react";
-
-import { CustomColor } from "../../types/globals/interaction";
-import PointCircle from "./PointCircle";
-
-export interface PointCircleTextProps {
- color?: CustomColor;
- text: string;
-}
-
-function PointCircleText({ text, color }: PointCircleTextProps) {
- return (
-
-
-
- {text}
-
-
- );
-}
-
-export default PointCircleText;
diff --git a/components/molecules/PointCircleTextRow.tsx b/components/molecules/PointCircleTextRow.tsx
deleted file mode 100644
index 3c3316b61..000000000
--- a/components/molecules/PointCircleTextRow.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Box, Flex } from "@chakra-ui/react";
-
-import PointCircleText, { PointCircleTextProps } from "../atoms/PointCircleText";
-
-interface PointCircleTextRowProps {
- props: PointCircleTextProps[];
-}
-
-function PointCircleTextRow({ props }: PointCircleTextRowProps) {
- return (
-
- {props.map((prop, idx) => (
-
-
-
- ))}
-
- );
-}
-
-export default PointCircleTextRow;
diff --git a/components/molecules/groups/ButtonGroups.tsx b/components/molecules/groups/ButtonGroups.tsx
index c7a24658a..b2fc08987 100644
--- a/components/molecules/groups/ButtonGroups.tsx
+++ b/components/molecules/groups/ButtonGroups.tsx
@@ -1,44 +1,64 @@
import { Button, Flex } from "@chakra-ui/react";
import styled from "styled-components";
-export interface IButtonOptions {
+export interface ButtonOptionsProps {
text: string;
func: () => void;
+ color?: string;
}
export interface IButtonGroups {
- buttonItems: IButtonOptions[];
+ buttonOptionsArr: ButtonOptionsProps[];
currentValue: string;
size?: "sm" | "md";
isWrap?: boolean;
isEllipse?: boolean;
+ type?: "block" | "text";
}
export default function ButtonGroups({
- buttonItems,
+ buttonOptionsArr,
currentValue,
size,
isWrap = false,
isEllipse = false,
+ type = "block",
}: IButtonGroups) {
+ console.log(buttonOptionsArr, currentValue);
return (
- {buttonItems.map((buttonData, idx) => (
-
-
+ {buttonOptionsArr.map((buttonOptions, idx) => (
+
+ {type === "block" ? (
+
+ ) : (
+
+ )}
))}
diff --git a/components/molecules/rows/ColorLabelRow.tsx b/components/molecules/rows/ColorLabelRow.tsx
new file mode 100644
index 000000000..6d830b787
--- /dev/null
+++ b/components/molecules/rows/ColorLabelRow.tsx
@@ -0,0 +1,21 @@
+import { Box, Flex } from "@chakra-ui/react";
+
+import ColorLabel, { ColorLabelProps } from "../../atoms/ColorLabel";
+
+interface ColorLabelRowProps {
+ props: ColorLabelProps[];
+}
+
+function ColorLabelRow({ props }: ColorLabelRowProps) {
+ return (
+
+ {props.map((prop, idx) => (
+
+
+
+ ))}
+
+ );
+}
+
+export default ColorLabelRow;
diff --git a/components/organisms/Calendar.tsx b/components/organisms/Calendar.tsx
new file mode 100644
index 000000000..38d8353b0
--- /dev/null
+++ b/components/organisms/Calendar.tsx
@@ -0,0 +1,200 @@
+import { Box, Flex, Grid } from "@chakra-ui/react";
+import dayjs, { Dayjs } from "dayjs";
+import styled from "styled-components";
+
+import { COLOR_TABLE } from "../../constants/colorConstants";
+import { CalendarContentProps } from "../../constants/contents/calendarSchedule";
+import { DAYS_OF_WEEK } from "../../constants/util/util";
+
+interface CalendarProps {
+ monthFirstDate: Dayjs;
+ calendarContents: CalendarContentProps[];
+}
+
+export interface CalendarScheduleProps {
+ content: string;
+ color: string;
+ isFirst: boolean;
+ isLast: boolean;
+ blockIdx: number;
+}
+
+export interface DaySchedules {
+ first: string | null;
+ second: string | null;
+ third: string | null;
+}
+
+const DAY_BLOCK_WIDTH = 50;
+
+const CALENDAR_DAY_COLOR = {
+ sun: "var(--color-red)",
+ sat: "var(--color-blue)",
+};
+
+const SCHEDULE_TYPE_TO_COLOR = {
+ main: COLOR_TABLE[0],
+ schedule: COLOR_TABLE[5],
+ event: COLOR_TABLE[3],
+};
+
+const generateCalendarDates = (monthFirstDate: Dayjs) => {
+ const daysInMonth = monthFirstDate.daysInMonth();
+ const frontBlankDate = monthFirstDate.day();
+ const totalDate = daysInMonth + frontBlankDate;
+ const rowsInMonth = totalDate <= 35 ? 5 : 6;
+ return Array.from({ length: 7 * rowsInMonth }, (_, idx) =>
+ idx < frontBlankDate || idx >= totalDate ? null : idx - frontBlankDate + 1,
+ );
+};
+
+function Calendar({ monthFirstDate, calendarContents }: CalendarProps) {
+ const calendarDates = generateCalendarDates(monthFirstDate);
+ let endingSchedules = [];
+
+ const daySchedules: DaySchedules = {
+ first: null,
+ second: null,
+ third: null,
+ };
+
+ const getDaySchedules = (date: number): CalendarScheduleProps[] => {
+ return calendarContents.reduce((acc: CalendarScheduleProps[], schedule) => {
+ const isFirstDay = date === schedule.start;
+ const isEndDay = date === schedule.end;
+ if (schedule.start <= date && date <= schedule.end) {
+ acc.push({
+ content: schedule.content,
+ color: SCHEDULE_TYPE_TO_COLOR[schedule.type],
+ isFirst: isFirstDay,
+ isLast: isEndDay,
+ blockIdx: schedule?.blockIdx,
+ });
+ if (isFirstDay) fillSchedule(schedule.content);
+ if (isEndDay) endingSchedules.push(schedule.content);
+ }
+ return acc;
+ }, []);
+ };
+
+ const deleteSchedule = (content: string) => {
+ for (const key in daySchedules) {
+ if (daySchedules[key] === content) daySchedules[key] = null;
+ }
+ };
+
+ const fillSchedule = (content: string) => {
+ const availableKey = Object.keys(daySchedules).find((key) => !daySchedules[key]);
+ if (availableKey) daySchedules[availableKey] = content;
+ };
+
+ return (
+
+
+ {DAYS_OF_WEEK.map((day) => (
+
+ {day}
+
+ ))}
+
+
+ {calendarDates?.map((item, idx) => {
+ const day = idx % 7 === 0 ? "sun" : idx % 7 === 6 ? "sat" : null;
+ const isToday = monthFirstDate.date(item).isSame(dayjs(), "day");
+ const contentArr = getDaySchedules(item);
+ const dateInfo = Object.values(daySchedules).map((title) =>
+ contentArr?.find((c) => c.content === title),
+ );
+
+ endingSchedules.forEach((item) => deleteSchedule(item));
+ endingSchedules = [];
+
+ return (
+
+
+ {!isToday ? (
+ item
+ ) : (
+
+ {item}
+
+ )}
+
+ <>
+ {dateInfo.map((item, idx2) => {
+ return (
+
+ {item?.isFirst ? item?.content : "\u00A0"}
+
+ );
+ })}
+ >
+
+ );
+ })}
+
+
+ );
+}
+
+const EventBlock = styled.div<{
+ color: string;
+ isFirst: boolean;
+ isLast: boolean;
+}>`
+ font-size: 10px;
+ margin-bottom: 2px;
+ font-weight: 400;
+ white-space: nowrap;
+ color: white;
+ background-color: ${(props) => props.color};
+ position: relative;
+ z-index: ${(props) => (props.isFirst ? 4 : 0)};
+ padding-left: ${(props) => (props.isFirst ? "var(--gap-1)" : 0)};
+ padding-right: ${(props) => (props.isLast ? "var(--gap-1)" : 0)};
+`;
+
+export default Calendar;
diff --git a/constants/settingValue/eventContents.ts b/constants/contents/calendarSchedule.ts
similarity index 59%
rename from constants/settingValue/eventContents.ts
rename to constants/contents/calendarSchedule.ts
index 6ec359373..9ce228b28 100644
--- a/constants/settingValue/eventContents.ts
+++ b/constants/contents/calendarSchedule.ts
@@ -1,42 +1,40 @@
-import { TABLE_COLORS } from "../styles";
-
-type Content = {
+export interface CalendarContentProps {
content: string;
start: number;
end: number;
- color: string;
- text: string;
+ type: "event" | "schedule" | "main";
+ text?: string;
blockIdx?: number;
-};
+}
-export const EVENT_CONTENT_2023: Record = {
+export const EVENT_CONTENT_2023: Record = {
10: [
{
content: "[10월] 에타 홍보 이벤트 추첨",
start: 22,
end: 24,
- color: TABLE_COLORS[2],
+ type: "event",
text: "에타에 동아리 홍보글을 올려주시면 100 포인트와 추첨을 통해 치킨 기프티콘을 드려요!",
},
{
content: "[시험기간] 랜덤선물 이벤트",
start: 16,
end: 22,
- color: TABLE_COLORS[0],
+ type: "event",
text: "항상 돌아오는 시험기간 파이팅 이벤트... 매일 단톡방에서 랜덤한 선착순 선물을 뿌립니다!",
},
{
content: "[시험기간] 스터디 투표 2배 이벤트 ",
start: 16,
end: 22,
- color: TABLE_COLORS[3],
+ type: "event",
text: "시험 기간에 스터디에 투표하면 점수를 2배로 받아요!",
},
{
content: "[오프라인] 번개 이벤트",
start: 29,
end: 31,
- color: TABLE_COLORS[6],
+ type: "event",
text: "진행 예정",
},
],
@@ -45,21 +43,21 @@ export const EVENT_CONTENT_2023: Record = {
content: "수원/안양 정기모임",
start: 17,
end: 18,
- color: TABLE_COLORS[2],
+ type: "schedule",
text: "정기모임",
},
{
content: "양천/강남",
start: 18,
end: 18,
- color: TABLE_COLORS[0],
+ type: "schedule",
text: "정기모임",
},
{
content: "정기 모임",
start: 19,
end: 19,
- color: TABLE_COLORS[0],
+ type: "schedule",
text: "정기모임",
blockIdx: 1,
},
@@ -67,7 +65,7 @@ export const EVENT_CONTENT_2023: Record = {
content: "11월 홍보 이벤트 당첨자 선별",
start: 26,
end: 30,
- color: TABLE_COLORS[3],
+ type: "event",
text: "11월 홍보 이벤트 당첨자 선별",
},
],
@@ -76,61 +74,61 @@ export const EVENT_CONTENT_2023: Record = {
content: "시험 기간 이벤트",
start: 4,
end: 8,
- color: TABLE_COLORS[0],
+ type: "event",
text: "이벤트",
},
{
content: "홍보 이벤트 추첨",
start: 22,
end: 24,
- color: TABLE_COLORS[1],
+ type: "event",
text: "이벤트",
},
{
content: "수원/강남 펭귄 핫팩",
start: 17,
end: 31,
- color: TABLE_COLORS[2],
+ type: "event",
text: "이벤트",
},
],
};
-export const EVENT_CONTENT_2024: Record = {
+export const EVENT_CONTENT_2024: Record = {
6: [
{
content: "시험기간 응원 선물 이벤트",
start: 10,
end: 14,
- color: "var(--color-blue)",
+ type: "event",
text: "시험기간 응원 기념으로 매일 단톡방에서 기프티콘을 뿌립니다!",
},
{
content: "동아리 1차 용인 MT",
start: 25,
end: 26,
- color: "var(--color-mint)",
+ type: "schedule",
text: "",
},
{
content: "모임 활성화 이벤트",
start: 19,
end: 20,
- color: "var(--color-blue)",
+ type: "event",
text: "이제 종강하고 동아리 내에서 본격적으로 다양한 모임을 진행해보려고 하는데요! 모임을 개최하고 진행해주시는 분께는 매번 5000원의 지원금을 드립니다!",
},
{
content: "소모임 개설 기간",
start: 24,
end: 30,
- color: "var(--color-orange)",
+ type: "main",
text: "방학동안 스터디 뿐만 아니라 다양한 장르의 그룹을 활성화 해보려고 해요! 토익, 자격증 등의 스터디 뿐만 아니라 카페 탐방, 영화 관람, 보드게임, 러닝, 취미 활동 등 모든 모임 개설이 가능합니다. 모임장에게는 2만원씩 지원 혜택이 있습니다.",
},
{
content: "홍보 이벤트",
start: 24,
end: 30,
- color: "var(--color-blue)",
+ type: "event",
text: "에타 홍보에 참여하고 상품 받아가세요! 총 10만원 쏩니다!",
},
],
@@ -139,84 +137,170 @@ export const EVENT_CONTENT_2024: Record = {
content: "동아리 2차 대성리 MT",
start: 3,
end: 4,
- color: "var(--color-mint)",
+ type: "schedule",
text: "",
},
{
content: "소모임 편성",
start: 6,
end: 7,
- color: "var(--color-orange)",
+ type: "main",
text: "",
},
{
content: "모임 활성화 이벤트",
start: 8,
end: 9,
- color: "var(--color-blue)",
+ type: "event",
text: "",
},
{
content: "알고리즘 공모전",
start: 11,
end: 12,
- color: "var(--color-blue)",
+ type: "event",
text: "",
},
{
content: "정기모임 진행 주간",
- start: 19,
+ start: 18,
end: 21,
- color: "var(--color-mint)",
+ type: "schedule",
text: "",
},
{
content: "라운지 및 피드, 채팅, 인스타 기능 출시",
- start: 29,
+ start: 28,
end: 31,
- color: "var(--color-mint)",
+ type: "main",
text: "",
},
],
8: [
{
- content: "조모임 진행 기간",
+ content: "월간 체크",
+ start: 1,
+ end: 1,
+ type: "main",
+ text: "",
+ },
+ {
+ content: "조모임 진행 주간",
start: 8,
end: 11,
- color: "var(--color-orange)",
+ type: "schedule",
text: "",
},
{
content: "커뮤니티 출시",
start: 5,
end: 6,
- color: "var(--color-mint)",
+ type: "main",
text: "",
},
{
- content: "지역별 정기모임 기간",
- start: 15,
- end: 18,
- color: "var(--color-orange)",
+ content: "에브리타임 홍보 이벤트 시작 ~ ",
+ start: 13,
+ end: 15,
+ type: "event",
+ text: "",
+ },
+ {
+ content: "지역 정기모임 주간",
+ start: 14,
+ end: 17,
+ type: "schedule",
+ text: "",
+ },
+
+ {
+ content: "온라인 스터디 오픈",
+ start: 20,
+ end: 22,
+ type: "main",
text: "",
},
{
content: "추억의 뽑기 이벤트",
start: 22,
end: 23,
- color: "var(--color-blue)",
+ type: "event",
text: "",
},
{
content: "동아리 정비 기간",
start: 26,
end: 30,
- color: "var(--color-mint)",
+ type: "schedule",
+ text: "",
+ },
+ {
+ content: "한줄 카피라이팅 이벤트",
+ start: 28,
+ end: 30,
+ type: "event",
+ text: "",
+ },
+ ],
+ 9: [
+ {
+ content: "동아리 리뉴얼 ~ ",
+ start: 2,
+ end: 4,
+ type: "main",
+ text: "에브리타임에 홍보하면 매주 2분께 올리브영 기프티콘을 드려요!",
+ },
+ {
+ content: "에타 홍보 이벤트 ~ ",
+ start: 3,
+ end: 5,
+ type: "event",
+ text: "에브리타임에 홍보하면 매주 2분께 올리브영 기프티콘을 드려요!",
+ },
+ {
+ content: "디스코드 오픈 이벤트 ~ ",
+ start: 10,
+ end: 12,
+ type: "event",
+ text: "동아리 스터디 디스코드 채널이 생겼습니다! 같이 공부하고 이벤트 상품 받아가세요!",
+ },
+ {
+ content: "열공 스터디 이벤트 ~ ",
+ start: 9,
+ end: 11,
+ type: "event",
+ text: "동아리 스터디 디스코드 채널이 생겼습니다! 같이 공부하고 이벤트 상품 받아가세요!",
+ },
+ {
+ content: "유령인원 정리 기간",
+ start: 16,
+ end: 17,
+ type: "main",
+ text: "",
+ },
+ {
+ content: "동아리 전체 정기모임",
+ start: 13,
+ end: 14,
+ type: "main",
+ text: "",
+ },
+ {
+ content: "지역 정기모임 주간",
+ start: 19,
+ end: 22,
+ type: "schedule",
+ text: "",
+ },
+ {
+ content: "ABOUT 빙고판 이벤트",
+ start: 17,
+ end: 28,
+ type: "event",
text: "",
},
],
- 9: [],
10: [],
11: [],
12: [],
diff --git a/constants/contentsText/accordionContents.ts b/constants/contentsText/accordionContents.ts
index 0a486fc73..88baeeef8 100644
--- a/constants/contentsText/accordionContents.ts
+++ b/constants/contentsText/accordionContents.ts
@@ -1,5 +1,5 @@
import { IAccordionContent } from "../../components/molecules/Accordion";
-import { EVENT_ALWAYS, EVENT_CONTENT_2024 } from "../../constants/settingValue/eventContents";
+import { EVENT_ALWAYS, EVENT_CONTENT_2024 } from "../contents/calendarSchedule";
//회원가입 질문 컨텐츠
export const ACCORDION_CONTENT_FEE: IAccordionContent[] = [
diff --git a/constants/location.ts b/constants/location.ts
index 6e40f0d35..b8a30ba04 100644
--- a/constants/location.ts
+++ b/constants/location.ts
@@ -2,11 +2,12 @@ import {
ActiveLocation,
InactiveLocation,
Location,
- LocationEn,
+ LocationEn
} from "../types/services/locationTypes";
-import { TABLE_COLORS } from "./styles";
+import { COLOR_TABLE } from "./colorConstants";
+
+export const LOCATION_OPEN: ActiveLocation[] = ["수원", "양천", "강남", "동대문", "인천", "안양"];
-export const LOCATION_OPEN: ActiveLocation[] = ["수원", "양천", "안양", "강남", "동대문", "인천"];
export const LOCATION_RECRUITING: InactiveLocation[] = [
"마포",
"성남",
@@ -23,7 +24,7 @@ export const LOCATION_RECRUITING: InactiveLocation[] = [
export const LOCATION_ALL = [...LOCATION_OPEN, ...LOCATION_RECRUITING];
-export const LOCATION_CONVERT: Record = {
+export const LOCATION_TO_FULLNAME: Record = {
수원: "수원시",
양천: "양천구 · 영등포구",
안양: "안양 인근 지역",
@@ -76,15 +77,6 @@ export const LOCATION_MEMBER_CNT: {
시흥: { member: 7, new: 2 },
};
-export const LOCATION_TABLE_COLOR: Record = {
- 수원: TABLE_COLORS[0],
- 양천: TABLE_COLORS[3],
- 안양: TABLE_COLORS[2],
- 강남: TABLE_COLORS[1],
- 인천: TABLE_COLORS[4],
- 동대문: TABLE_COLORS[5],
-};
-
export const krToEnMapping: Record = {
수원: "suw",
강남: "gan",
@@ -124,3 +116,12 @@ export const enToKrMapping: Record = {
buc: "부천",
sih: "시흥",
};
+
+export const LOCATION_TO_COLOR: Record = {
+ 수원: COLOR_TABLE[0],
+ 양천: COLOR_TABLE[1],
+ 강남: COLOR_TABLE[3],
+ 동대문: COLOR_TABLE[4],
+ 인천: COLOR_TABLE[2],
+ 안양: COLOR_TABLE[5],
+};
diff --git a/constants/serviceConstants/studyConstants/studyLocationConstants.ts b/constants/serviceConstants/studyConstants/studyLocationConstants.ts
index 68645e127..c8b78f57d 100644
--- a/constants/serviceConstants/studyConstants/studyLocationConstants.ts
+++ b/constants/serviceConstants/studyConstants/studyLocationConstants.ts
@@ -208,7 +208,6 @@ export const PLACE_TO_LOCATION = createPlaceToLocationMap(LOCATION_TO_PLACE);
function createPlaceToLocationMap(obj: LocationToPlace) {
const placeToLocationMap: { [key: string]: ActiveLocation } = {};
-
Object.entries(obj).forEach(([location, ids]) => {
ids.forEach((id) => {
placeToLocationMap[id] = location as ActiveLocation;
diff --git a/modals/InviteUserModal.tsx b/modals/InviteUserModal.tsx
index 739ef7b14..95b97b96b 100644
--- a/modals/InviteUserModal.tsx
+++ b/modals/InviteUserModal.tsx
@@ -61,7 +61,7 @@ export default function InviteUserModal({ setIsModal }: IInviteUserModal) {
},
};
- const buttonItems = [
+ const buttonOptionsArr = [
{
text: "수원",
func: () => setLocation("수원"),
@@ -90,7 +90,7 @@ export default function InviteUserModal({ setIsModal }: IInviteUserModal) {
return (
-
+
onClickButton("전체"),
@@ -64,7 +64,7 @@ export default function GatherLocationFilter() {
return (
{
+ buttonOptionsArr={buttonOptionsArr.sort((x, y) => {
if (x.text === "전체") return -1;
if (y.text === "전체") return 1;
if (x.text === defaultLocation) return -1;
diff --git a/pageTemplates/home/HomeCalendarSection.tsx b/pageTemplates/home/HomeCalendarSection.tsx
new file mode 100644
index 000000000..d12547e84
--- /dev/null
+++ b/pageTemplates/home/HomeCalendarSection.tsx
@@ -0,0 +1,50 @@
+import { Box, Flex } from "@chakra-ui/react";
+import dayjs from "dayjs";
+import { useState } from "react";
+
+import { ColorLabelProps } from "../../components/atoms/ColorLabel";
+import MonthNav from "../../components/atoms/MonthNav";
+import Accordion from "../../components/molecules/Accordion";
+import ColorLabelRow from "../../components/molecules/rows/ColorLabelRow";
+import Calendar from "../../components/organisms/Calendar";
+import { COLOR_TABLE } from "../../constants/colorConstants";
+import { EVENT_CONTENT_2024 } from "../../constants/contents/calendarSchedule";
+import { ACCORDION_CONTENT_EVENT } from "../../constants/contentsText/accordionContents";
+
+const SCHEDULE_CATEGORIES: ColorLabelProps[] = [
+ {
+ text: "공식 행사",
+ colorText: COLOR_TABLE[0],
+ },
+ {
+ text: "이벤트",
+ colorText: COLOR_TABLE[3],
+ },
+ {
+ text: "일정",
+ colorText: COLOR_TABLE[5],
+ },
+];
+
+function HomeCalendarSection() {
+ const [monthFirstDate, setMonthFirstDate] = useState(dayjs().startOf("month"));
+ const monthNum = monthFirstDate.month();
+
+ const calendarContents =
+ monthFirstDate.year() === 2024 ? EVENT_CONTENT_2024[monthFirstDate.month() + 1] : null;
+ return (
+ <>
+
+
+
+
+
+
+ 일정 상세정보
+
+
+ >
+ );
+}
+
+export default HomeCalendarSection;
diff --git a/pageTemplates/home/HomeClubSection.tsx b/pageTemplates/home/HomeClubSection.tsx
deleted file mode 100644
index 8206ded7b..000000000
--- a/pageTemplates/home/HomeClubSection.tsx
+++ /dev/null
@@ -1,272 +0,0 @@
-import { Box, Flex } from "@chakra-ui/react";
-import dayjs from "dayjs";
-import { Fragment, useState } from "react";
-import styled from "styled-components";
-
-import MonthNav from "../../components/atoms/MonthNav";
-import { PointCircleTextProps } from "../../components/atoms/PointCircleText";
-import Accordion from "../../components/molecules/Accordion";
-import PointCircleTextRow from "../../components/molecules/PointCircleTextRow";
-import { ACCORDION_CONTENT_EVENT } from "../../constants/contentsText/accordionContents";
-import { EVENT_CONTENT_2024 } from "../../constants/settingValue/eventContents";
-import { DAYS_OF_WEEK } from "../../constants/util/util";
-const DAYS_TITLE = ["포인트 2배", null, null, null, null, null, "점수 2배"];
-
-interface IEventContent {
- content: string;
- color: string;
- isFirst: boolean;
- isLast: boolean;
- blockIdx?: number;
-}
-
-function HomeClubSection() {
- const [navMonth, setNavMonth] = useState(dayjs().startOf("month"));
-
- const getFilledDates = (navMonth: dayjs.Dayjs) => {
- const daysInMonth = navMonth.daysInMonth();
- const frontBlankDate = navMonth.day();
- const totalDate = daysInMonth + frontBlankDate;
- const rowsInMonth = totalDate <= 35 ? 5 : 6;
- return Array.from({ length: 7 * rowsInMonth }, (_, idx) =>
- idx < frontBlankDate || idx >= totalDate ? null : idx - frontBlankDate + 1,
- );
- };
-
- const filledDates = getFilledDates(navMonth);
-
- const eventBlocks: { [key: string]: string } = {
- first: null,
- second: null,
- third: null,
- };
-
- let endBlocks = [];
-
- const filledContents = (date: number) => {
- const eventArr = navMonth.year() === 2024 ? EVENT_CONTENT_2024[navMonth.month() + 1] : null;
-
- if (!eventArr) return;
- return eventArr.reduce((acc: IEventContent[], event) => {
- const isFirstDay = date === event.start;
- const isEndDay = date === event.end;
- if (event.start <= date && date <= event.end) {
- acc.push({
- content: event.content,
- color: event.color,
- isFirst: isFirstDay,
- isLast: isEndDay,
- blockIdx: event?.blockIdx,
- });
- if (isFirstDay) fillEventDate(event.content);
- if (isEndDay) endBlocks.push(event.content);
- }
- return acc;
- }, []);
- };
-
- const fillEventDate = (content: string) => {
- const availableKey = Object.keys(eventBlocks).find((key) => !eventBlocks[key]);
- if (availableKey) eventBlocks[availableKey] = content;
- };
-
- const deleteEventDate = (content: string) => {
- for (const key in eventBlocks) {
- if (eventBlocks[key] === content) eventBlocks[key] = null;
- }
- };
-
- const textRowObj: PointCircleTextProps[] = [
- {
- text: "공식 행사",
- color: "mint",
- },
- {
- text: "이벤트",
- color: "blue",
- },
- {
- text: "일정",
- color: "orange",
- },
- ];
-
- return (
- <>
-
-
-
-
-
-
- {DAYS_TITLE.map((day, idx) => (
- {day}
- ))}
-
-
- {DAYS_OF_WEEK.map((day) => (
- {day}
- ))}
-
-
- {filledDates?.map((item, idx) => {
- const day = idx % 7 === 0 ? "sun" : idx % 7 === 6 ? "sat" : null;
- const isToday = navMonth.date(item).isSame(dayjs(), "day");
-
- const contentArr = filledContents(item);
- const dateInfo = Object.values(eventBlocks).map((title) =>
- contentArr?.find((c) => c.content === title),
- );
-
- endBlocks.forEach((item) => deleteEventDate(item));
- endBlocks = [];
-
- return (
-
-
- {!isToday ? item : {item}}
-
-
- {dateInfo.map((item, idx2) => {
- return (
-
- {item?.blockIdx !== undefined && (
-
-
-
- )}
-
- {item?.isFirst ? item?.content : "\u00A0"}
-
-
- );
- })}
-
-
- );
- })}
-
-
-
- 이벤트 상세정보
-
-
- >
- );
-}
-
-const Calendar = styled.div`
- width: 364px;
- margin: 0 auto;
- display: flex;
- flex-direction: column;
-`;
-
-const WeekTitleHeader = styled.div`
- display: flex;
- justify-content: space-between;
- font-size: 10px;
- color: var(--color-mint);
-
- margin-bottom: var(--gap-1);
- font-weight: 600;
- > div {
- flex: 1;
- text-align: center;
- }
-`;
-
-const DayOfWeek = styled.div`
- display: flex;
- justify-content: space-between;
- background-color: var(--gray-200);
- padding: var(--gap-1) 0;
- font-size: 12px;
- > div {
- flex: 1;
- text-align: center;
- }
- > div:first-child {
- color: var(--color-red);
- }
- > div:last-child {
- color: #6bafff;
- }
-`;
-
-const CalendarDates = styled.div`
- display: grid;
- background-color: white;
- grid-template-columns: repeat(7, 1fr);
- border: var(--border);
- border-radius: var(--rounded);
- > div:first-child {
- color: var(--color-red);
- }
-`;
-
-const DateBlock = styled.div`
- width: 52px;
- padding-top: var(--gap-1);
- font-size: 12px;
- font-weight: 600;
- text-align: center;
- flex: 1;
- border-top: var(--border);
-`;
-
-const Date = styled.div<{ day: "sun" | "sat"; isToday: boolean }>`
- position: relative;
- height: 18px;
- margin-bottom: var(--gap-1);
- color: ${(props) =>
- props.isToday
- ? "white"
- : props.day === "sun"
- ? "var(--color-red)"
- : props.day === "sat"
- ? "var(--color-blue)"
- : null};
-`;
-
-const DateContent = styled.div``;
-
-const EventBlock = styled.div<{
- color: string;
- isFirst: boolean;
- isLast: boolean;
-}>`
- font-size: 10px;
- margin-bottom: 2px;
- font-weight: 400;
- white-space: nowrap;
- color: white;
- background-color: ${(props) => props.color};
- position: relative;
-
- z-index: ${(props) => (props.isFirst ? 4 : 0)};
- padding-left: ${(props) => (props.isFirst ? "var(--gap-1)" : 0)};
- padding-right: ${(props) => (props.isLast ? "var(--gap-1)" : 0)};
-`;
-
-const TodayCircle = styled.div`
- position: absolute;
- top: 50%;
- left: 50%;
- width: 18px;
- height: 18px;
- border-radius: 50%;
- transform: translate(-50%, -50%);
- background-color: var(--gray-800);
- color: white;
-`;
-
-export default HomeClubSection;
diff --git a/pageTemplates/home/HomeRankingSection.tsx b/pageTemplates/home/HomeRankingSection.tsx
index 351edc77e..7f42d2d77 100644
--- a/pageTemplates/home/HomeRankingSection.tsx
+++ b/pageTemplates/home/HomeRankingSection.tsx
@@ -1,5 +1,5 @@
import RecommendationBannerCard from "../../components/organisms/cards/RecommendationBannerCard";
-import { HOME_RECOMMENDATION_TAB_CONTENTS } from "../../constants/contents/HomeRecommendationTab";
+import { HOME_RECOMMENDATION_TAB_CONTENTS } from "../../constants/contents/homeRecommendationTab";
function HomeRankingSection() {
return (
diff --git a/pageTemplates/home/HomeReviewSection.tsx b/pageTemplates/home/HomeReviewSection.tsx
index 00025e037..e52454a15 100644
--- a/pageTemplates/home/HomeReviewSection.tsx
+++ b/pageTemplates/home/HomeReviewSection.tsx
@@ -24,7 +24,7 @@ export default function HomeReviewSection() {
}
+ rightComponent={}
/>
{imageArr && }
diff --git a/pageTemplates/home/study/HomeStudyChart.tsx b/pageTemplates/home/study/HomeStudyChart.tsx
index e321becac..f5768632d 100644
--- a/pageTemplates/home/study/HomeStudyChart.tsx
+++ b/pageTemplates/home/study/HomeStudyChart.tsx
@@ -1,11 +1,11 @@
import { Box } from "@chakra-ui/react";
import dayjs from "dayjs";
import dynamic from "next/dynamic";
-import { useRouter } from "next/navigation";
import HighlightedTextButton from "../../../components/atoms/buttons/HighlightedTextButton";
import SectionBar from "../../../components/molecules/bars/SectionBar";
import { ChartStudyOptions } from "../../../components/organisms/chart/ChartOptions";
+import { useToast } from "../../../hooks/custom/CustomToast";
import { VoteCntProps } from "../../../types/models/studyTypes/studyRecords";
interface HomeStudyChartProps {
@@ -13,7 +13,8 @@ interface HomeStudyChartProps {
}
function HomeStudyChart({ voteCntArr }: HomeStudyChartProps) {
- const router = useRouter();
+ // const router = useRouter();
+ const toast = useToast();
const ApexCharts = dynamic(() => import("react-apexcharts"), { ssr: false });
const filtered: VoteCntProps[] = voteCntArr?.reduce((acc, cur) => {
@@ -35,13 +36,15 @@ function HomeStudyChart({ voteCntArr }: HomeStudyChartProps) {
xArr.push(dayjs(obj.date).date() + "");
});
+ const onClick = () => {
+ toast("warning", "24년 9월 5일 오픈");
+ };
+
return (
<>
router.push("/calendar")} />
- }
+ rightComponent={}
/>
-
-
-
- {filterData?.map((item, idx) => {
- const arrivedInfo = item?.arrivedInfoList;
+function RecordCalendar({ filterData, monthFirstDate }: IRecordCalendar) {
+ console.log(2, filterData);
+ const calendarContents: CalendarContentProps[] = filterData.flatMap((data) => {
+ const arrivedInfo = data?.arrivedInfoList;
+ const date = data?.date;
+ const dayjsDate = date && dayjsToStr(monthFirstDate.date(date));
+ let openLocation = null;
+ for (const key in LOCATION_OPEN_DATE) {
+ if (LOCATION_OPEN_DATE[key] === dayjsDate) openLocation = key;
+ }
+ const openStudyLocation: Set<{
+ location: string;
+ cnt: number;
+ }> = new Set();
+ arrivedInfo?.forEach((place) => {
+ openStudyLocation.add({
+ location: PLACE_TO_LOCATION[place.placeId],
+ cnt: place.arrivedInfo.length,
+ });
+ });
+ console.log(24, arrivedInfo, openLocation, openStudyLocation);
+ let tempCnt = 0;
- const date = item?.date;
- const dayjsDate = date && dayjsToStr(navMonth.date(date));
- let openLocation = null;
- for (const key in LOCATION_OPEN_DATE) {
- if (LOCATION_OPEN_DATE[key] === dayjsDate) openLocation = key;
- }
- const openStudyLocation: Set<{
- location: string;
- cnt: number;
- }> = new Set();
- arrivedInfo?.forEach((place) => {
- openStudyLocation.add({
- location: PLACE_TO_LOCATION[place.placeId],
- cnt: place.arrivedInfo.length,
- });
- });
- let tempCnt = 0;
- return (
-
- {!openLocation ? (
- {date}
- ) : (
- {date}
- )}
- {Array.from(openStudyLocation).map((location, idx) => {
- if (idx > 2 || location.cnt < 2) return null;
- tempCnt++;
- return (
-
- {tempCnt < 4 || openStudyLocation.size <= 3 ? (
- "Open"
- ) : (
-
- )}
-
- );
- })}
-
- );
- })}
-
-
+ const resData = Array.from(openStudyLocation)
+ .map((location, idx) => {
+ if (idx > 2 || location.cnt < 2) return null;
+ tempCnt++;
+ return {
+ content: "오픈",
+ start: date,
+ end: date,
+ type: "main" as "main" | "event" | "schedule",
+ blockIdx: tempCnt - 1,
+ };
+ })
+ .filter((place) => place !== null);
+ return resData;
+ // {
+ // Array.from(openStudyLocation).map((location, idx) => {
+ // if (idx > 2 || location.cnt < 2) return null;
+ // tempCnt++;
+ // return (
+ //
+ // {tempCnt < 4 || openStudyLocation.size <= 3 ? (
+ // "스터디 오픈"
+ // ) : (
+ //
+ // )}
+ //
+ // );
+ // });
+ // }
+ });
+ console.log(calendarContents);
+ return (
+
+
+
+ //
+ //
+ //
+ // {filterData?.map((data, idx) => {
+ //
+ // return (
+ //
+ // {!openLocation ? (
+ // {date}
+ // ) : (
+ // {date}
+ // )}
+ // {Array.from(openStudyLocation).map((location, idx) => {
+ // if (idx > 2 || location.cnt < 2) return null;
+ // tempCnt++;
+ // return (
+ //
+ // {tempCnt < 4 || openStudyLocation.size <= 3 ? (
+ // "스터디 오픈"
+ // ) : (
+ //
+ // )}
+ //
+ // );
+ // })}
+ //
+ // );
+ // })}
+ //
+ //
);
}
function DayOfWeek() {
@@ -104,7 +150,7 @@ const LocationOpen = styled.div<{ location: Location }>`
display: flex;
justify-content: center;
align-items: center;
- border: ${(props) => `2px solid ${LOCATION_TABLE_COLOR[props.location]}`};
+ border: ${(props) => `2px solid ${LOCATION_TO_COLOR[props.location]}`};
width: 24px;
height: 24px;
border-radius: 50%;
@@ -112,7 +158,7 @@ const LocationOpen = styled.div<{ location: Location }>`
const Open = styled.div<{ location: Location }>`
font-size: 10px;
- color: ${(props) => LOCATION_TABLE_COLOR[props.location] || "var(--gray-500)"};
+ color: ${(props) => LOCATION_TO_COLOR[props.location]};
`;
const DayLine = styled.div`
diff --git a/pageTemplates/record/RecordCalendarSetting.tsx b/pageTemplates/record/RecordCalendarSetting.tsx
index 4c9a8c189..0c10caa35 100644
--- a/pageTemplates/record/RecordCalendarSetting.tsx
+++ b/pageTemplates/record/RecordCalendarSetting.tsx
@@ -1,6 +1,7 @@
import dayjs, { Dayjs } from "dayjs";
import { useEffect } from "react";
+import { ALL_스터디인증 } from "../../constants/serviceConstants/studyConstants/studyPlaceConstants";
import { useErrorToast } from "../../hooks/custom/CustomToast";
import { useStudyAttendRecordQuery } from "../../hooks/study/queries";
import { DispatchBoolean, DispatchType } from "../../types/hooks/reactTypes";
@@ -40,11 +41,17 @@ function RecordCalendarSetting({
? null
: { date: idx - frontBlankDate + 1, arrivedInfoList: [] },
);
- studyRecords.forEach((item) => {
- const filledIdx = dayjs(item.date).date() + frontBlankDate - 1;
- const data = filledDates[filledIdx];
- if (data) data.arrivedInfoList = item.arrivedInfoList;
- });
+
+ studyRecords
+ .map((study) => ({
+ arrivedInfoList: study.arrivedInfoList.filter((item) => item.placeId !== ALL_스터디인증),
+ date: study.date,
+ }))
+ .forEach((item) => {
+ const filledIdx = dayjs(item.date).date() + frontBlankDate - 1;
+ const data = filledDates[filledIdx];
+ if (data) data.arrivedInfoList = item.arrivedInfoList;
+ });
setArrivedCalendar(filledDates);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoading, navMonth, studyRecords]);
diff --git a/pageTemplates/record/RecordLocationCategory.tsx b/pageTemplates/record/RecordLocationCategory.tsx
index ebc25eb9e..93f17287d 100644
--- a/pageTemplates/record/RecordLocationCategory.tsx
+++ b/pageTemplates/record/RecordLocationCategory.tsx
@@ -1,11 +1,12 @@
+import { Box } from "@chakra-ui/react";
import { useEffect, useState } from "react";
-import styled from "styled-components";
-import { LOCATION_CONVERT, LOCATION_OPEN, LOCATION_TABLE_COLOR } from "../../constants/location";
+import ButtonGroups from "../../components/molecules/groups/ButtonGroups";
+import { LOCATION_OPEN, LOCATION_TO_COLOR, LOCATION_TO_FULLNAME } from "../../constants/location";
import { PLACE_TO_LOCATION } from "../../constants/serviceConstants/studyConstants/studyLocationConstants";
import { DispatchType } from "../../types/hooks/reactTypes";
import { IArrivedData } from "../../types/models/studyTypes/studyRecords";
-import { Location, LocationFilterType } from "../../types/services/locationTypes";
+import { ActiveLocationAll } from "../../types/services/locationTypes";
interface IRecordLocationCategory {
initialData: IArrivedData[];
@@ -13,12 +14,7 @@ interface IRecordLocationCategory {
}
function RecordLocationCategory({ initialData, setFilterData }: IRecordLocationCategory) {
- const [category, setCategory] = useState("전체");
-
- const onClickBadge = (value: Location) => {
- if (value === category) setCategory("전체");
- else setCategory(value);
- };
+ const [category, setCategory] = useState("전체");
useEffect(() => {
if (!initialData) return;
@@ -35,58 +31,31 @@ function RecordLocationCategory({ initialData, setFilterData }: IRecordLocationC
}
}, [category, initialData, setFilterData]);
+ const buttonOptionsArr = (["전체", ...LOCATION_OPEN] as ActiveLocationAll[]).map((location) => ({
+ text: LOCATION_TO_FULLNAME[location] || "전체",
+ func: () => {
+ if (location === category) setCategory("전체");
+ else setCategory(location);
+ },
+ color: LOCATION_TO_COLOR[location],
+ }));
+
return (
-
-
- {LOCATION_OPEN.map((location) => (
-
- ))}
-
-
+
+
+
);
}
-const Layout = styled.div`
- padding: 0 var(--gap-4);
- height: 36px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- background-color: var(--gray-200);
- border-top: 1px solid var(--gray-300);
- border-bottom: 1px solid var(--gray-300);
- > div {
- display: flex;
- align-items: center;
- }
- > span:last-child {
- font-size: 10px;
- color: var(--gray-600);
- }
-`;
-
-const SpaceBadge = styled.section`
- display: flex;
- align-items: center;
-`;
-
-const Button = styled.button<{
- location: Location;
- category: LocationFilterType;
-}>`
- margin-right: var(--gap-3);
- font-weight: 600;
- color: ${(props) => LOCATION_TABLE_COLOR[props.location]};
- font-size: ${(props) => (props.category === props.location ? "14px" : "12px")};
- opacity: ${(props) =>
- props.category !== "전체" && props.category !== props.location ? "0.7" : "1"};
-`;
-
export default RecordLocationCategory;
diff --git a/pageTemplates/record/RecordOverview.tsx b/pageTemplates/record/RecordOverview.tsx
index 238200092..ca529a676 100644
--- a/pageTemplates/record/RecordOverview.tsx
+++ b/pageTemplates/record/RecordOverview.tsx
@@ -107,7 +107,6 @@ const MyRecordItem = styled.div`
flex-direction: column;
justify-content: space-around;
height: 100%;
-
> div {
display: flex;
align-items: center;
diff --git a/pageTemplates/record/RecordSkeleton.tsx b/pageTemplates/record/RecordSkeleton.tsx
deleted file mode 100644
index cec0e61e6..000000000
--- a/pageTemplates/record/RecordSkeleton.tsx
+++ /dev/null
@@ -1,300 +0,0 @@
-import dayjs from "dayjs";
-import styled from "styled-components";
-
-import Skeleton from "../../components/atoms/skeleton/Skeleton";
-import { LOCATION_CONVERT, LOCATION_OPEN, LOCATION_TABLE_COLOR } from "../../constants/location";
-import { Location } from "../../types/services/locationTypes";
-
-interface IRecordSkeleton {
- isCalendar: boolean;
-}
-
-function RecordSkeleton({ isCalendar }: IRecordSkeleton) {
- const blankDate = Array.from(
- {
- length: dayjs().date(1).day(),
- },
- (_, i) => i + 1,
- );
-
- const totalDate = Array.from(
- {
- length: dayjs().daysInMonth(),
- },
- (_, i) => i + 1,
- );
- return (
-
-
-
-
-
- 스터디 오픈
-
- temp
-
-
-
- 참여한 인원
-
- temp
-
-
-
-
-
- 내 참여 횟수
-
- temp
-
-
-
- 내 최근 참여
-
- temp
-
-
-
-
-
-
-
- {LOCATION_OPEN.map((location) => (
-
- {LOCATION_CONVERT[location]}
-
- ))}
-
-
- {isCalendar ? (
-
-
-
- {blankDate?.map((item) => )}
-
- {totalDate?.map((item, idx) => (
-
- {item}
-
- Open
-
-
- ))}
-
-
- ) : (
-
- {new Array(6).fill(0).map((_, idx) => (
-
-
- temp
-
-
- {new Array(2).fill(0).map((_, idx2) => (
-
-
-
- tempte
-
-
- temp
-
-
-
- {new Array(3).fill(0).map((who, idx3) => (
-
- temp
-
- ))}
-
-
- ))}
-
-
- ))}
-
- )}
-
- );
-}
-function DayOfWeek() {
- return (
-
- 일
- 월
- 화
- 수
- 목
- 금
- 토
-
- );
-}
-
-const Layout = styled.div``;
-
-/** overview */
-const RecordOverview = styled.div`
- padding: var(--gap-3) var(--gap-4);
- display: flex;
- justify-content: space-between;
- align-items: center;
- height: 80px;
-`;
-
-const MyRecord = styled.div`
- display: flex;
- height: 100%;
- > div:first-child {
- width: 125px;
- }
- > div:last-child {
- width: 140px;
- }
-`;
-
-const MyRecordItem = styled.div`
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- height: 100%;
-
- > div {
- display: flex;
- align-items: center;
- }
-`;
-const ContentName = styled.span`
- margin-right: var(--gap-2);
- color: var(--gray-600);
- font-size: 13px;
-`;
-
-const ContentValue = styled.span`
- font-weight: 700;
- font-size: 14px;
- color: var(--gray-700);
-`;
-const SpaceBadge = styled.section`
- display: flex;
- align-items: center;
-`;
-
-const Button2 = styled.button<{
- location: Location;
-}>`
- margin-right: var(--gap-3);
- font-weight: 600;
- color: ${(props) => LOCATION_TABLE_COLOR[props.location]};
- font-size: 12px;
-`;
-
-/** category */
-const Category = styled.div`
- padding: 0 var(--gap-4);
- height: 36px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- background-color: var(--gray-200);
- border-top: 1px solid var(--gray-300);
- border-bottom: 1px solid var(--gray-300);
- > div {
- display: flex;
- align-items: center;
- }
- > span:last-child {
- font-size: 10px;
- color: var(--gray-600);
- }
-`;
-
-/** calendar */
-
-const Calendar = styled.div``;
-
-const CallenderDays = styled.div`
- display: grid;
- grid-auto-rows: 72px;
- grid-template-columns: repeat(7, 1fr);
- margin: 0 var(--gap-1);
- font-size: 14px;
-`;
-const DayItem = styled.div`
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- border: 1px solid var(--gray-200);
-`;
-
-const DayItemDate = styled.span<{ isToday: boolean }>`
- color: ${(props) => (props.isToday ? "var(--color-mint)" : null)};
- font-weight: ${(props) => (props.isToday ? "600" : null)};
- font-size: ${(props) => (props.isToday ? "15px" : null)};
-`;
-
-const Open = styled.div`
- font-size: 10px;
-`;
-
-const DayLine = styled.div`
- margin: var(--gap-2) 24px;
- display: flex;
- justify-content: space-between;
- color: var(--gray-600);
- font-size: 12px;
-`;
-
-/** detail */
-
-export const Detail = styled.div`
- display: flex;
- flex-direction: column;
-`;
-const Block = styled.div`
- border-top: 4px solid var(--gray-200);
- padding: var(--gap-3) var(--gap-4);
- padding-bottom: 0;
-`;
-const Date = styled.div`
- margin-bottom: var(--gap-3);
- font-size: 13px;
- color: var(--gray-700);
-`;
-const StudyInfo = styled.div`
- font-size: 12px;
- color: var(--gray-700);
-`;
-const PlaceInfo = styled.div`
- margin-bottom: var(--gap-3);
-`;
-
-const PlaceName = styled.div`
- display: flex;
- align-items: center;
- color: var(--gray-700);
- font-size: 14px;
- > span:first-child {
- font-weight: 600;
- margin-right: var(--gap-1);
- }
-`;
-const OpenLocation = styled.span`
- font-size: 11px;
-`;
-
-const MemberWrapper = styled.div`
- margin-top: var(--gap-3);
-
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(20%, auto));
- align-items: center;
- line-height: 2;
-`;
-
-const Member = styled.span`
- margin-right: var(--gap-1);
- color: var(--gray-600);
-`;
-export default RecordSkeleton;
diff --git a/pageTemplates/record/detail/RecordDetailStudyBlock.tsx b/pageTemplates/record/detail/RecordDetailStudyBlock.tsx
index ab569113e..29522d8e2 100644
--- a/pageTemplates/record/detail/RecordDetailStudyBlock.tsx
+++ b/pageTemplates/record/detail/RecordDetailStudyBlock.tsx
@@ -1,7 +1,7 @@
import { Fragment } from "react";
import styled from "styled-components";
-import { LOCATION_TABLE_COLOR } from "../../../constants/location";
+import { LOCATION_TO_COLOR } from "../../../constants/location";
import { PLACE_TO_NAME } from "../../../constants/serviceConstants/studyConstants/studyCafeNameConstants";
import { PLACE_TO_LOCATION } from "../../../constants/serviceConstants/studyConstants/studyLocationConstants";
import { Location } from "../../../types/services/locationTypes";
@@ -59,7 +59,7 @@ const PlaceInfo = styled.div<{ location: Location }>`
width: 148px;
flex-shrink: 0;
margin-bottom: var(--gap-4);
- border: ${(props) => `1px solid ${LOCATION_TABLE_COLOR[props.location]}`};
+ border: ${(props) => `1px solid ${LOCATION_TO_COLOR[props.location]}`};
border-radius: var(--rounded-lg);
padding: var(--gap-2);
@@ -79,7 +79,7 @@ const PlaceName = styled.div`
const OpenLocation = styled.span<{ location: Location }>`
font-size: 11px;
- color: ${(props) => LOCATION_TABLE_COLOR[props.location]};
+ color: ${(props) => LOCATION_TO_COLOR[props.location]};
`;
const MemberWrapper = styled.div`
diff --git a/pageTemplates/register/location/LocationMember.tsx b/pageTemplates/register/location/LocationMember.tsx
index 90ba38724..d1e82cfe0 100644
--- a/pageTemplates/register/location/LocationMember.tsx
+++ b/pageTemplates/register/location/LocationMember.tsx
@@ -1,12 +1,12 @@
import styled from "styled-components";
-import { LOCATION_CONVERT, LOCATION_MEMBER_CNT } from "../../../constants/location";
+import { LOCATION_MEMBER_CNT, LOCATION_TO_FULLNAME } from "../../../constants/location";
import { Location } from "../../../types/services/locationTypes";
function LocationMember({ location }: { location: Location }) {
return (
- {LOCATION_CONVERT[location]}
+ {LOCATION_TO_FULLNAME[location]}
{LOCATION_MEMBER_CNT[location].new}
diff --git a/pageTemplates/square/SecretSquare/SecretSquareCategories.tsx b/pageTemplates/square/SecretSquare/SecretSquareCategories.tsx
index 57648b426..70face7c4 100644
--- a/pageTemplates/square/SecretSquare/SecretSquareCategories.tsx
+++ b/pageTemplates/square/SecretSquare/SecretSquareCategories.tsx
@@ -1,7 +1,9 @@
import { Box } from "@chakra-ui/react";
import { Dispatch, SetStateAction } from "react";
-import ButtonGroups, { IButtonOptions } from "../../../components/molecules/groups/ButtonGroups";
+import ButtonGroups, {
+ ButtonOptionsProps,
+} from "../../../components/molecules/groups/ButtonGroups";
import { type SecretSquareCategoryWithAll } from "../../../types/models/square";
const SECRET_SQUARE_CATEGORY: SecretSquareCategoryWithAll[] = [
@@ -21,7 +23,7 @@ function SecretSquareCategories({
category: selectedCategory,
setCategory,
}: SecretSquareCategoryProps) {
- const buttonItems: IButtonOptions[] = SECRET_SQUARE_CATEGORY.map((category) => ({
+ const buttonOptionsArr: ButtonOptionsProps[] = SECRET_SQUARE_CATEGORY.map((category) => ({
text: `#${category}`,
func: () => setCategory(category),
}));
@@ -29,7 +31,7 @@ function SecretSquareCategories({
return (
{
- return {
- text: `${textObj[category]}`,
- func: () => {
- newSearchParams.set("category", category);
- router.replace(`/square?${newSearchParams}`);
- setCategory(category);
- },
- };
- },
- );
-
-
+ const buttonOptionsArr: ButtonOptionsProps[] = (
+ ["all", "gather", "group"] as (FeedType | "all")[]
+ ).map((category) => {
+ return {
+ text: `${textObj[category]}`,
+ func: () => {
+ newSearchParams.set("category", category);
+ router.replace(`/square?${newSearchParams}`);
+ setCategory(category);
+ },
+ };
+ });
return (
-
-
+
+
- {!isLoading ? (
+ {!isLoading && (
<>
{isCalendar ? (
-
+
) : (
)}
>
- ) : (
-
)}
diff --git a/pages/eventCalendar.tsx b/pages/eventCalendar.tsx
deleted file mode 100644
index 156ae2c8e..000000000
--- a/pages/eventCalendar.tsx
+++ /dev/null
@@ -1,278 +0,0 @@
-import { Box, Flex } from "@chakra-ui/react";
-import dayjs from "dayjs";
-import { Fragment, useState } from "react";
-import styled from "styled-components";
-
-import MonthNav from "../components/atoms/MonthNav";
-import { PointCircleTextProps } from "../components/atoms/PointCircleText";
-import Header from "../components/layouts/Header";
-import Slide from "../components/layouts/PageSlide";
-import Accordion from "../components/molecules/Accordion";
-import PointCircleTextRow from "../components/molecules/PointCircleTextRow";
-import { ACCORDION_CONTENT_EVENT } from "../constants/contentsText/accordionContents";
-import { EVENT_CONTENT_2024 } from "../constants/settingValue/eventContents";
-import { DAYS_OF_WEEK } from "../constants/util/util";
-const DAYS_TITLE = ["포인트 2배", null, null, null, null, null, "점수 2배"];
-
-interface IEventContent {
- content: string;
- color: string;
- isFirst: boolean;
- isLast: boolean;
- blockIdx?: number;
-}
-
-function EventCalendar() {
- const [navMonth, setNavMonth] = useState(dayjs().startOf("month"));
-
- const getFilledDates = (navMonth: dayjs.Dayjs) => {
- const daysInMonth = navMonth.daysInMonth();
- const frontBlankDate = navMonth.day();
- const totalDate = daysInMonth + frontBlankDate;
- const rowsInMonth = totalDate <= 35 ? 5 : 6;
- return Array.from({ length: 7 * rowsInMonth }, (_, idx) =>
- idx < frontBlankDate || idx >= totalDate ? null : idx - frontBlankDate + 1,
- );
- };
-
- const filledDates = getFilledDates(navMonth);
-
- const eventBlocks: { [key: string]: string } = {
- first: null,
- second: null,
- third: null,
- };
-
- let endBlocks = [];
-
- const filledContents = (date: number) => {
- const eventArr = navMonth.year() === 2024 ? EVENT_CONTENT_2024[navMonth.month() + 1] : null;
-
- if (!eventArr) return;
- return eventArr.reduce((acc: IEventContent[], event) => {
- const isFirstDay = date === event.start;
- const isEndDay = date === event.end;
- if (event.start <= date && date <= event.end) {
- acc.push({
- content: event.content,
- color: event.color,
- isFirst: isFirstDay,
- isLast: isEndDay,
- blockIdx: event?.blockIdx,
- });
- if (isFirstDay) fillEventDate(event.content);
- if (isEndDay) endBlocks.push(event.content);
- }
- return acc;
- }, []);
- };
-
- const fillEventDate = (content: string) => {
- const availableKey = Object.keys(eventBlocks).find((key) => !eventBlocks[key]);
- if (availableKey) eventBlocks[availableKey] = content;
- };
-
- const deleteEventDate = (content: string) => {
- for (const key in eventBlocks) {
- if (eventBlocks[key] === content) eventBlocks[key] = null;
- }
- };
-
- const textRowObj: PointCircleTextProps[] = [
- {
- text: "공식 행사",
- color: "mint",
- },
- {
- text: "이벤트",
- color: "blue",
- },
- {
- text: "일정",
- color: "orange",
- },
- ];
-
- return (
- <>
-
-
-
-
-
-
-
-
- {DAYS_TITLE.map((day, idx) => (
- {day}
- ))}
-
-
- {DAYS_OF_WEEK.map((day) => (
- {day}
- ))}
-
-
- {filledDates?.map((item, idx) => {
- const day = idx % 7 === 0 ? "sun" : idx % 7 === 6 ? "sat" : null;
- const isToday = navMonth.date(item).isSame(dayjs(), "day");
-
- const contentArr = filledContents(item);
- const dateInfo = Object.values(eventBlocks).map((title) =>
- contentArr?.find((c) => c.content === title),
- );
-
- endBlocks.forEach((item) => deleteEventDate(item));
- endBlocks = [];
-
- return (
-
-
- {!isToday ? item : {item}}
-
-
- {dateInfo.map((item, idx2) => {
- return (
-
- {item?.blockIdx !== undefined && (
-
-
-
- )}
-
- {item?.isFirst ? item?.content : "\u00A0"}
-
-
- );
- })}
-
-
- );
- })}
-
-
-
- 이벤트 상세정보
-
-
-
- >
- );
-}
-
-const Calendar = styled.div`
- width: 364px;
- margin: 0 auto;
- display: flex;
- flex-direction: column;
-`;
-
-const WeekTitleHeader = styled.div`
- display: flex;
- justify-content: space-between;
- font-size: 10px;
- color: var(--color-mint);
-
- margin-bottom: var(--gap-1);
- font-weight: 600;
- > div {
- flex: 1;
- text-align: center;
- }
-`;
-
-const DayOfWeek = styled.div`
- display: flex;
- justify-content: space-between;
- background-color: var(--gray-200);
- padding: var(--gap-1) 0;
- font-size: 12px;
- > div {
- flex: 1;
- text-align: center;
- }
- > div:first-child {
- color: var(--color-red);
- }
- > div:last-child {
- color: #6bafff;
- }
-`;
-
-const CalendarDates = styled.div`
- display: grid;
- background-color: white;
- grid-template-columns: repeat(7, 1fr);
- border: var(--border);
- border-radius: var(--rounded);
- > div:first-child {
- color: var(--color-red);
- }
-`;
-
-const DateBlock = styled.div<{ isToday: boolean }>`
- width: 52px;
- padding-top: var(--gap-1);
- font-size: 12px;
- font-weight: 600;
- text-align: center;
- flex: 1;
- border-top: var(--border);
- background-color: ${(props) => (props.isToday ? "var(--gray-200)" : null)};
-`;
-
-const Date = styled.div<{ day: "sun" | "sat"; isToday: boolean }>`
- position: relative;
- height: 18px;
- margin-bottom: var(--gap-1);
- color: ${(props) =>
- props.isToday
- ? "white"
- : props.day === "sun"
- ? "var(--color-red)"
- : props.day === "sat"
- ? "var(--color-blue)"
- : null};
-`;
-
-const DateContent = styled.div``;
-
-const EventBlock = styled.div<{
- color: string;
- isFirst: boolean;
- isLast: boolean;
-}>`
- font-size: 10px;
- margin-bottom: 2px;
- font-weight: 400;
- white-space: nowrap;
- color: white;
- background-color: ${(props) => props.color};
- position: relative;
-
- z-index: ${(props) => (props.isFirst ? 4 : 0)};
- padding-left: ${(props) => (props.isFirst ? "var(--gap-1)" : 0)};
- padding-right: ${(props) => (props.isLast ? "var(--gap-1)" : 0)};
-`;
-
-const TodayCircle = styled.div`
- position: absolute;
- top: 50%;
- left: 50%;
- width: 18px;
- height: 18px;
- border-radius: 50%;
- transform: translate(-50%, -50%);
- background-color: var(--gray-800);
- color: white;
-`;
-
-export default EventCalendar;
diff --git a/pages/home/index.tsx b/pages/home/index.tsx
index 09c55ad0b..d55eaf779 100644
--- a/pages/home/index.tsx
+++ b/pages/home/index.tsx
@@ -2,7 +2,7 @@ import { Box } from "@chakra-ui/react";
import { useState } from "react";
import Slide from "../../components/layouts/PageSlide";
-import HomeClubSection from "../../pageTemplates/home/HomeClubSection";
+import HomeCalendarSection from "../../pageTemplates/home/HomeCalendarSection";
import HomeGatherSection from "../../pageTemplates/home/HomeGatherSection";
import HomeHeader from "../../pageTemplates/home/homeHeader/HomeHeader";
import HomeInitialSetting from "../../pageTemplates/home/HomeInitialSetting";
@@ -26,7 +26,7 @@ function Home() {
) : tab === "번개" ? (
) : tab === "캘린더" ? (
-
+
) : tab === "추천" ? (
) : null}
diff --git a/pages/review/index.tsx b/pages/review/index.tsx
index 086fc1c85..21a77f2ae 100644
--- a/pages/review/index.tsx
+++ b/pages/review/index.tsx
@@ -10,7 +10,7 @@ import KakaoShareBtn from "../../components/atoms/Icons/KakaoShareBtn";
import { MainLoading } from "../../components/atoms/loaders/MainLoading";
import Header from "../../components/layouts/Header";
import Slide from "../../components/layouts/PageSlide";
-import ButtonGroups, { IButtonOptions } from "../../components/molecules/groups/ButtonGroups";
+import ButtonGroups, { ButtonOptionsProps } from "../../components/molecules/groups/ButtonGroups";
import { LOCATION_OPEN } from "../../constants/location";
import { WEB_URL } from "../../constants/system";
import { useErrorToast } from "../../hooks/custom/CustomToast";
@@ -109,7 +109,7 @@ function Review() {
setVisibleCnt((old) => old + 8);
};
- const buttonArr: IButtonOptions[] = ["전체", ...LOCATION_OPEN].map((location) => ({
+ const buttonArr: ButtonOptionsProps[] = ["전체", ...LOCATION_OPEN].map((location) => ({
text: location,
func: () =>
location === "전체"
@@ -136,7 +136,7 @@ function Review() {
<>
diff --git a/pages/study/writing/place.tsx b/pages/study/writing/place.tsx
index 94e1cdcee..593d2439d 100644
--- a/pages/study/writing/place.tsx
+++ b/pages/study/writing/place.tsx
@@ -7,10 +7,12 @@ import styled from "styled-components";
import BottomNav from "../../../components/layouts/BottomNav";
import Header from "../../../components/layouts/Header";
import Slide from "../../../components/layouts/PageSlide";
-import ButtonGroups, { IButtonOptions } from "../../../components/molecules/groups/ButtonGroups";
+import ButtonGroups, {
+ ButtonOptionsProps,
+} from "../../../components/molecules/groups/ButtonGroups";
import ProgressStatus from "../../../components/molecules/ProgressStatus";
import SearchLocation from "../../../components/organisms/SearchLocation";
-import { LOCATION_CONVERT, LOCATION_OPEN } from "../../../constants/location";
+import { LOCATION_OPEN, LOCATION_TO_FULLNAME } from "../../../constants/location";
import { useFailToast } from "../../../hooks/custom/CustomToast";
import RegisterLayout from "../../../pageTemplates/register/RegisterLayout";
import RegisterOverview from "../../../pageTemplates/register/RegisterOverview";
@@ -60,8 +62,8 @@ function WritingStudyPlace() {
router.push(`/study/writing/content`);
};
- const buttonItems: IButtonOptions[] = LOCATION_OPEN.map((locationInfo) => ({
- text: LOCATION_CONVERT[locationInfo],
+ const buttonOptionsArr: ButtonOptionsProps[] = LOCATION_OPEN.map((locationInfo) => ({
+ text: LOCATION_TO_FULLNAME[locationInfo],
func: () => setLocation(locationInfo),
}));
@@ -77,8 +79,8 @@ function WritingStudyPlace() {