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 1a92019 commit 9cda076
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 25 deletions.
66 changes: 53 additions & 13 deletions src/components/CalendarInfoModal.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import axios from "axios";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { FaXmark } from "react-icons/fa6";
import { FaTrashCan, FaXmark } from "react-icons/fa6";

import {
FaCheck,
Expand All @@ -10,9 +10,10 @@ import {
FaRegCopy,
FaToggleOff,
FaToggleOn,
FaTrash,
} from "react-icons/fa";

export default function CalendarInfo({ calendar, onClose }) {
export default function CalendarInfo({ calendar, onClose, userId }) {
// 초기 값 설정
const [title, setTitle] = useState(calendar.calendar_name);
const [detailMemo, setDetailMemo] = useState(calendar.calendar_description);
Expand All @@ -31,6 +32,12 @@ export default function CalendarInfo({ calendar, onClose }) {
const toggleIsEdit = () => setIsEdit(!isEdit);
const toggleIsPublic = () => setNewPublic(!newPublic);

// 컴포넌트가 마운트될 때 creator_id와 userId 확인
useEffect(() => {
console.log("Calendar Creator ID:", calendar.creator_id);
console.log("Current User ID:", userId);
}, [calendar.creator_id, userId]);

// 저장
const save = async () => {
try {
Expand Down Expand Up @@ -75,6 +82,31 @@ export default function CalendarInfo({ calendar, onClose }) {
toggleIsEdit();
};

// 삭제
const handleDelete = async () => {
try {
const token = localStorage.getItem("token"); // 토큰 가져오기
const response = await axios.delete(
`/api/calendars/${calendar.calendar_id}`,
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
},
);

if (response.status === 200) {
// 삭제가 성공적으로 완료되었을 때
alert("캘린더가 성공적으로 삭제되었습니다.");
onClose(); // 삭제 후 모달 닫기
}
} catch (error) {
console.error("캘린더 삭제 실패:", error);
alert("캘린더 삭제에 실패했습니다. 다시 시도해 주세요.");
}
};

return (
<div className="flex h-[29rem] w-[43rem] translate-x-[3rem] justify-center rounded-[1.25rem] bg-eventoWhite p-[2.8rem] shadow-xl shadow-lightGray/50">
<FaXmark
Expand Down Expand Up @@ -104,7 +136,7 @@ export default function CalendarInfo({ calendar, onClose }) {
<div className="mb-[0.75rem] text-[1rem] font-bold text-eventoPurple">
멤버
</div>
<div className="w-[40rem] text-[1.1rem] font-bold text-darkGray">
<div className="w-[40rem] text-[1.1rem] font-semibold text-darkGray">
호도니, 뚜디니, 때용이 + 10
</div>
</div>
Expand All @@ -121,7 +153,7 @@ export default function CalendarInfo({ calendar, onClose }) {
<input
type="text"
value={newDetail}
className="mb-[3rem] mr-[2rem] h-[1.3rem] w-[18rem] rounded-md bg-lightGray/20 text-[1.1rem] font-bold text-darkGray"
className="mb-[3rem] mr-[2rem] h-[1.3rem] w-[18rem] rounded-md bg-lightGray/20 text-[1.1rem] font-semibold text-darkGray"
onChange={(e) => setNewDetail(e.target.value)}
/>
<div className="flex h-[2rem] w-[10rem] items-center">
Expand Down Expand Up @@ -149,7 +181,7 @@ export default function CalendarInfo({ calendar, onClose }) {
</div>
) : (
<div className="flex">
<div className="mb-[3rem] h-[1.3rem] w-[20rem] text-[1.1rem] font-bold text-darkGray">
<div className="mb-[3rem] h-[1.3rem] w-[20rem] text-[1.1rem] font-semibold text-darkGray">
{detailMemo}
</div>
<div
Expand All @@ -170,7 +202,7 @@ export default function CalendarInfo({ calendar, onClose }) {
<>
<div className="flex space-x-[6.5rem]">
<div className="flex items-center space-x-[1rem] text-center">
<div className="text-[1.1rem] font-bold text-darkGray">
<div className="text-[1.1rem] font-semibold text-darkGray">
비공개 캘린더로 설정하기
</div>
{newPublic ? (
Expand All @@ -187,18 +219,18 @@ export default function CalendarInfo({ calendar, onClose }) {
/>
)}
</div>
<div className="pr-[0.5rem] text-[1.1rem] font-bold text-darkGray">
<div className="pr-[0.5rem] text-[1.1rem] font-semibold text-darkGray">
{visitCode}
</div>
</div>
</>
) : (
<>
<div className="flex">
<div className="w-[20rem] text-[1.1rem] font-bold text-darkGray">
<div className="w-[20rem] text-[1.1rem] font-semibold text-darkGray">
{isPublic ? "공개" : "비공개"}
</div>
<div className="pr-[0.5rem] text-[1.1rem] font-bold text-darkGray">
<div className="pr-[0.5rem] text-[1.1rem] font-semibold text-darkGray">
{visitCode}
</div>
<CopyToClipboard
Expand Down Expand Up @@ -227,10 +259,18 @@ export default function CalendarInfo({ calendar, onClose }) {
</button>
</div>
) : (
<FaPen
className="absolute bottom-[3rem] right-[3rem] text-[1.5rem] text-darkGray"
onClick={toggleIsEdit}
/>
<div className="absolute bottom-[3rem] right-[3rem] flex space-x-[0.5rem]">
<FaPen
className="cursor-pointer text-[1.5rem] text-darkGray"
onClick={toggleIsEdit}
/>
{calendar.creator_id === userId && (
<FaTrashCan
className="cursor-pointer text-[1.5rem] text-darkGray"
onClick={handleDelete}
/>
)}
</div>
)}
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/CreateCalendarModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function CreateCalendar({ onClose }) {
};

// 색상
const [calColor, setCalColor] = useState("#FF5C5C"); // 초기 값은 빨간색
const [calColor, setCalColor] = useState("#FF5C5C"); // 초기

// 에러 메시지 상태 추가
const [errorMessage, setErrorMessage] = useState("");
Expand Down Expand Up @@ -68,7 +68,7 @@ export default function CreateCalendar({ onClose }) {
className="absolute right-[1.2rem] top-[1.2rem] cursor-pointer text-darkGray"
onClick={onClose}
/>
<div className="flex w-full flex-col">
<div className="flex flex-col w-full">
<div className="mb-[2.8rem] flex items-center justify-between">
<input
type="text"
Expand Down
26 changes: 22 additions & 4 deletions src/components/SideBarLeft.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import {
export default function SideBarLeft() {
const [isCalendarInfoOpen, setCalendarInfoOpen] = useState(false);
const [selectedCalendar, setSelectedCalendar] = useState(null);
const [myCalendars, setMyCalendars] = useState([]);
const [myUserId, setMyUserId] = useState(null); // 사용자 ID를 저장할 상태 추가
const navigate = useNavigate();
const [checked, setChecked] = useState({});
const [isInviteOpen, setIsInviteOpen] = useState(false);
const [isCreateCalendarOpen, setIsCreateCalendarOpen] = useState(false);
const [myCalendars, setMyCalendars] = useState([]);

// 내 캘린더 데이터 가져오기
useEffect(() => {
Expand All @@ -41,10 +42,26 @@ export default function SideBarLeft() {
}
}

// 수정 및 생성 모달이 닫힐 때 캘린더 목록 새로고침
if (!isCalendarInfoOpen && !isCreateCalendarOpen) {
fetchCalendars();
async function fetchUser() {
try {
const token = localStorage.getItem("token"); // 토큰 가져오기
const response = await axios.get("/api/users/me", {
headers: {
Authorization: `Bearer ${token}`,
},
});

if (response.status === 200) {
setMyUserId(response.data.user_id); // 사용자 ID 설정
}
} catch (error) {
console.error("사용자 정보를 가져오는 중 오류 발생:", error);
}
}

// 사용자 정보와 캘린더 정보 모두 가져오기
fetchCalendars();
fetchUser();
}, [isCalendarInfoOpen, isCreateCalendarOpen]);

const handleToggle = (id) => {
Expand Down Expand Up @@ -212,6 +229,7 @@ export default function SideBarLeft() {
calendar={selectedCalendar}
onClose={() => setCalendarInfoOpen(false)}
onSave={handleSaveCalendar}
userId={myUserId} // 현재 로그인한 사용자 ID 전달
/>
</div>
)}
Expand Down
51 changes: 45 additions & 6 deletions src/mocks/handlers/calendarHandlers.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { rest } from "msw";

// 기존의 캘린더 데이터 (가짜 데이터)
let mockCalendars = [
{
calendar_id: 1,
calendar_name: "PoodingDev",
calendar_description: "개발 프로젝트 캘린더",
calendar_name: "내가 만든 캘린더",
calendar_description: "삭제 권한 있음",
calendar_color: "#FFC960",
is_public: false,
creator_id: 1,
invitation_code: "GW3HR4",
},
{
calendar_id: 2,
calendar_name: "헬린이의 삶",
calendar_description: "하체 뿌셔",
calendar_name: "관리자로 있는 캘린더",
calendar_description: "삭제 권한 없음",
calendar_color: "#6D87D5",
is_public: true,
creator_id: 2,
Expand Down Expand Up @@ -65,7 +64,7 @@ export const calendarHandlers = [
calendar_color: calendar_color, // 클라이언트에서 전달된 색상 값 사용
is_public: is_public || false,
creator_id: 1,
invitation_code: "ABC123", // 생성된 초대 코드 (고정된 가짜 코드)
invitation_code: "ABC123", // 생성된 초대 코드
};

// 가짜 데이터 목록에 새 캘린더 추가
Expand Down Expand Up @@ -126,4 +125,44 @@ export const calendarHandlers = [
// 200 OK 응답 반환
return res(ctx.status(200), ctx.json(mockCalendars[calendarIndex]));
}),

// 캘린더 삭제 핸들러 추가
rest.delete("/api/calendars/:calendarId", async (req, res, ctx) => {
const token = req.headers.get("Authorization");
const { calendarId } = req.params;

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.splice(calendarIndex, 1);

// 200 OK 응답 반환
return res(
ctx.status(200),
ctx.json({ message: "캘린더가 성공적으로 삭제되었습니다." }),
);
}),
];

0 comments on commit 9cda076

Please sign in to comment.