Skip to content

Commit

Permalink
Feat: #89 캘린더 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
cxaosdev committed Dec 2, 2024
1 parent 6c77726 commit a6de308
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 30 deletions.
81 changes: 59 additions & 22 deletions src/components/CalendarInfoModal.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import React, { useEffect, useState } from "react";
import axios from "axios";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { FaCopy, FaPen, FaToggleOff, FaToggleOn } from "react-icons/fa";
import { FaXmark } from "react-icons/fa6";

import {
FaCheck,
FaCopy,
FaPen,
FaRegCopy,
FaToggleOff,
FaToggleOn,
} from "react-icons/fa";

export default function CalendarInfo({ calendar, onClose }) {
// 초기 값 설정
const [title, setTitle] = useState(calendar.calendar_name);
Expand All @@ -23,12 +32,38 @@ export default function CalendarInfo({ calendar, onClose }) {
const toggleIsPublic = () => setNewPublic(!newPublic);

// 저장
const save = () => {
setTitle(newTitle);
setDetailMemo(newDetail);
setIsPublic(newPublic);
setCalColor(newColor);
toggleIsEdit();
const save = async () => {
try {
const token = localStorage.getItem("token"); // 토큰 가져오기
const response = await axios.patch(
`/api/calendars/${calendar.calendar_id}`,
{
calendar_name: newTitle,
calendar_description: newDetail,
is_public: newPublic,
calendar_color: newColor,
},
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
},
);

if (response.status === 200) {
// 서버 응답 성공 시 상태 업데이트
setTitle(newTitle);
setDetailMemo(newDetail);
setIsPublic(newPublic);
setCalColor(newColor); // 색상 업데이트
toggleIsEdit();
onClose(); // 저장 후 모달 닫기
}
} catch (error) {
console.error("캘린더 수정 실패:", error);
alert("캘린더 수정에 실패했습니다. 다시 시도해 주세요.");
}
};

// 취소
Expand Down Expand Up @@ -91,22 +126,24 @@ export default function CalendarInfo({ calendar, onClose }) {
/>
<div className="flex h-[2rem] w-[10rem] items-center">
{[
"#FF5C5C",
"#FFC960",
"#7DBE7E",
"#9CC9FF",
"#6D87D5",
"#8867DF",
"#B469D3",
].map((color, index) => (
{ color: "#FF5C5C", label: "calendarRed" },
{ color: "#FFC960", label: "calendarYellow" },
{ color: "#7DBE7E", label: "calendarGreen" },
{ color: "#9CC9FF", label: "calendarLightBlue" },
{ color: "#6D87D5", label: "calendarBlue" },
{ color: "#8867DF", label: "calendarDarkPurple" },
{ color: "#B469D3", label: "calendarPurple" },
].map(({ color, label }) => (
<button
key={index}
key={label}
onClick={() => setNewColor(color)}
className={`mr-[0.3rem] h-[1rem] w-[1rem] ${
newColor === color ? "border-[0.1rem] border-darkGray" : ""
}`}
className={`relative mb-[0.25rem] mr-[0.3rem] flex h-[1rem] w-[1rem] items-center justify-center`}
style={{ backgroundColor: color }}
/>
>
{newColor === color && (
<FaCheck className="absolute text-[0.6rem] text-eventoWhite" />
)}
</button>
))}
</div>
</div>
Expand Down Expand Up @@ -165,10 +202,10 @@ export default function CalendarInfo({ calendar, onClose }) {
{visitCode}
</div>
<CopyToClipboard
className="cursor-pointer text-eventoblack active:text-darkGray"
className="cursor-pointer text-eventoPurple active:text-lightGray"
text={visitCode}
>
<FaCopy />
<FaRegCopy />
</CopyToClipboard>
</div>
</>
Expand Down
35 changes: 27 additions & 8 deletions src/components/SideBarLeft.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ import {
export default function SideBarLeft() {
const [isCalendarInfoOpen, setCalendarInfoOpen] = useState(false);
const [selectedCalendar, setSelectedCalendar] = useState(null);
const toggleCalendarInfo = (calendar) => {
setSelectedCalendar(calendar);
setCalendarInfoOpen((prev) => !prev);
};
const navigate = useNavigate();
const [checked, setChecked] = useState({});
const [isInviteOpen, setIsInviteOpen] = useState(false);
Expand All @@ -45,8 +41,11 @@ export default function SideBarLeft() {
}
}

fetchCalendars();
}, [isCreateCalendarOpen]); // 캘린더 생성 모달 닫힌 후 새로고침
// 수정 및 생성 모달이 닫힐 때 캘린더 목록 새로고침
if (!isCalendarInfoOpen && !isCreateCalendarOpen) {
fetchCalendars();
}
}, [isCalendarInfoOpen, isCreateCalendarOpen]);

const handleToggle = (id) => {
setChecked((prev) => ({
Expand All @@ -62,6 +61,25 @@ export default function SideBarLeft() {
setIsCreateCalendarOpen((prev) => !prev);
};

// 캘린더 정보 보기 및 수정 저장 핸들러
const handleViewCalendar = (calendar) => {
setSelectedCalendar(calendar);
setCalendarInfoOpen(true);
};

const handleSaveCalendar = (updatedCalendar) => {
// 수정된 내용을 사이드바에도 즉시 반영
setMyCalendars((prevCalendars) =>
prevCalendars.map((calendar) =>
calendar.calendar_id === updatedCalendar.calendar_id
? updatedCalendar
: calendar,
),
);
// 모달을 닫음
setCalendarInfoOpen(false);
};

return (
<div>
<div className="evento-sidebarleft absolute mt-[5rem] h-[calc(100vh-5rem)] w-[18rem] rounded-tr-[2.5rem] bg-eventoGray pl-[2.25rem] pr-[1.75rem] pt-[1.6rem]">
Expand Down Expand Up @@ -109,7 +127,7 @@ export default function SideBarLeft() {
htmlFor={calendar.calendar_id}
className="cursor-pointer text-[0.9rem]"
style={{ color: calendar.calendar_color }}
onClick={() => toggleCalendarInfo(calendar)}
onClick={() => handleViewCalendar(calendar)}
>
{calendar.calendar_name}
</label>
Expand Down Expand Up @@ -192,7 +210,8 @@ export default function SideBarLeft() {
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-30">
<CalendarInfo
calendar={selectedCalendar}
onClose={toggleCalendarInfo}
onClose={() => setCalendarInfoOpen(false)}
onSave={handleSaveCalendar}
/>
</div>
)}
Expand Down
52 changes: 52 additions & 0 deletions src/mocks/handlers/calendarHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,56 @@ export const calendarHandlers = [
// 201 Created 응답 반환
return res(ctx.status(201), ctx.json(newCalendar));
}),

// 캘린더 수정 핸들러
rest.patch("/api/calendars/:calendarId", async (req, res, ctx) => {
const token = req.headers.get("Authorization");
const { calendarId } = req.params;
const { calendar_name, calendar_description, calendar_color, is_public } =
await req.json();

if (!token || token !== "Bearer fake_token") {
return res(
ctx.status(401),
ctx.json({
error: "인증 실패",
message: "로그인이 필요한 서비스입니다. 다시 로그인해 주세요.",
}),
);
}

// 가짜 데이터에서 해당 캘린더를 찾음
const calendarIndex = mockCalendars.findIndex(
(cal) => cal.calendar_id === parseInt(calendarId),
);

if (calendarIndex === -1) {
return res(
ctx.status(404),
ctx.json({
error: "not_found",
message: "해당 캘린더를 찾을 수 없습니다.",
}),
);
}

// 캘린더 데이터 업데이트
mockCalendars[calendarIndex] = {
...mockCalendars[calendarIndex],
calendar_name:
calendar_name || mockCalendars[calendarIndex].calendar_name,
calendar_description:
calendar_description ||
mockCalendars[calendarIndex].calendar_description,
calendar_color:
calendar_color || mockCalendars[calendarIndex].calendar_color,
is_public:
typeof is_public === "boolean"
? is_public
: mockCalendars[calendarIndex].is_public,
};

// 200 OK 응답 반환
return res(ctx.status(200), ctx.json(mockCalendars[calendarIndex]));
}),
];

0 comments on commit a6de308

Please sign in to comment.