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

Api favorites #190

Merged
merged 4 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 16 additions & 13 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import React from "react";
import SideBarLeft from "/src/components/SideBarLeft";
import Subscription from "/src/pages/Subscription";
import { AuthProvider } from "/src/context/AuthContext";
import { CalendarProvider } from "/src/context/CalendarContext";
import { BrowserRouter, Route, Routes } from "react-router-dom";

function Layout({ children }) {
Expand All @@ -38,19 +39,21 @@ function Layout({ children }) {
export default function App() {
return (
<AuthProvider>
<BrowserRouter>
<Layout>
<Routes>
<Route path="/login" element={<LogIn />} />
<Route path="/auth/:platform" element={<LoginPostCode />} />
<Route path="/" element={<OnBoarding />} />
<Route path="/calendar" element={<Calendar />} />
<Route path="/profile" element={<Profile />} />
<Route path="/profile/edit" element={<ProfileEdit />} />
<Route path="/subscription" element={<Subscription />} />
</Routes>
</Layout>
</BrowserRouter>
<CalendarProvider>
<BrowserRouter>
<Layout>
<Routes>
<Route path="/login" element={<LogIn />} />
<Route path="/auth/:platform" element={<LoginPostCode />} />
<Route path="/" element={<OnBoarding />} />
<Route path="/calendar" element={<Calendar />} />
<Route path="/profile" element={<Profile />} />
<Route path="/profile/edit" element={<ProfileEdit />} />
<Route path="/subscription" element={<Subscription />} />
</Routes>
</Layout>
</BrowserRouter>
</CalendarProvider>
</AuthProvider>
);
}
172 changes: 50 additions & 122 deletions src/components/SideBarLeft.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import InviteCodeModal from "./InviteCodeModal";
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { instance } from "../api/axios";
import { useAuth } from "../context/AuthContext";
import { useCalendar } from "../context/CalendarContext";

// import { useAuth } from "context/AuthContext";

import {
FaRegSquare,
Expand All @@ -15,6 +17,7 @@ import {
} from "react-icons/fa";

export default function SideBarLeft() {
const { myCalendars, subscribedCalendars, fetchData } = useCalendar();
const user_id = localStorage.getItem("user_id");
const [isCalendarInfoOpen, setCalendarInfoOpen] = useState(false);
const [selectedCalendar, setSelectedCalendar] = useState(null);
Expand All @@ -24,124 +27,62 @@ export default function SideBarLeft() {
const [isInviteOpen, setIsInviteOpen] = useState(false);
const [isCreateOpen, setIsCreateCalendarOpen] = useState(false);

const [myCalendars, setMyCalendars] = useState([]);
const [subscribedCalendars, setSubscribedCalendars] = useState([]);
const [dday, setDday] = useState([]);

const { loggedIn, userInfo } = useAuth();
const userId = localStorage.getItem("user_id");

useEffect(() => {
async function fetchData() {
async function fetchDdayData() {
try {
const token = localStorage.getItem("token");
const ddayResponse = await instance.get(
`/api/users/${user_id}/favorites/`,
{
headers: { Authorization: `Bearer ${token}` },
},
);

const [myCalendarsResponse, subscribedCalendarsResponse, ddayResponse] =
await Promise.allSettled([
instance.get("/api/calendars/admin/", {
headers: { Authorization: `Bearer ${token}` },
}),
instance.get(`/api/calendars/subscriptions/`, {
headers: { Authorization: `Bearer ${token}` },
}),
instance.get(`/api/users/${user_id}/favorites/`, {
headers: { Authorization: `Bearer ${token}` },
}),
]);

if (myCalendarsResponse.status === "fulfilled") {
setMyCalendars(myCalendarsResponse.value.data);
const initialChecked = myCalendarsResponse.value.data.reduce(
(acc, calendar) => {
acc[calendar.calendar_id] = true;
return acc;
},
{},
);
setChecked(initialChecked);
}

if (subscribedCalendarsResponse.status === "fulfilled") {
setSubscribedCalendars(subscribedCalendarsResponse.value.data);
}

if (ddayResponse.status === "fulfilled") {
// console.log("ddayResponse.value:", ddayResponse.value); // 로그 추가
// console.log("ddayResponse.value.data:", ddayResponse.value?.data);

// favorite_events 배열 추출
const favoriteEvents =
ddayResponse.value?.data?.favorite_events || [];
if (ddayResponse?.status === 200) {
const favoriteEvents = ddayResponse.data.favorite_events || [];
setDday(favoriteEvents);

// console.log("dday (after setDday):", dday);
}
} catch (error) {
console.error("캘린더 데이터를 가져오는 중 오류 발생:", error);
console.error("D-Day 데이터를 가져오는 중 오류 발생:", error);
}
}

if (user_id) {
fetchData();
fetchData(); // Fetch calendars
fetchDdayData(); // Fetch D-Day events
}
}, [isCalendarInfoOpen, isCreateOpen]);

const handleToggle = async (id) => {
try {
const token = localStorage.getItem("token"); // 토큰 가져오기
const response = await instance.patch(
const token = localStorage.getItem("token");
await instance.patch(
`/api/calendars/${id}`,
{ isactive: !checked[id] },
{
calendar_name: myCalendars.name,
calendar_description: myCalendars.description,
is_public: myCalendars.is_public,
calendar_color: myCalendars.color,
admins: myCalendars.admins,
isactive: checked[id],
},
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
headers: { Authorization: `Bearer ${token}` },
},
);
if (response.status === 200) {
// 체크 상태 변경
setChecked((prev) => {
const newChecked = { ...prev, [id]: !prev[id] }; // 현재 id의 체크 상태 반전
// myCalendars의 isactive 값을 업데이트
setMyCalendars((prevCalendars) =>
prevCalendars.map((calendar) =>
calendar.calendar_id === id
? { ...calendar, isactive: newChecked[id] }
: calendar,
),
);
return newChecked;
});
}

setChecked((prev) => ({
...prev,
[id]: !prev[id],
}));
} catch (error) {
console.error("ERROR: ", error);
console.error("캘린더 토글 중 오류:", error);
}
};

const toggleInvite = () => {
setIsInviteOpen((prev) => !prev);
};

const toggleCreateCalendar = () => {
setIsCreateCalendarOpen((prev) => !prev);
};

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

const handleSaveCalendar = (updatedCalendar) => {
// 수정된 내용을 사이드바에도 즉시 반영
setMyCalendars((prevCalendars) =>
prevCalendars.map((calendar) =>
calendar.calendar_id === updatedCalendar.calendar_id
Expand All @@ -151,14 +92,13 @@ export default function SideBarLeft() {
);
setCalendarInfoOpen(false);
};
// console.log(subscribedCalendars);

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]">
<div>
{/* 내 캘린더 */}
<div className="evento-my-calendar">
{/* 제목 */}
<div className="mr-[0.3rem] flex items-center justify-between">
<span className="text-[0.9rem] text-darkGray">내 캘린더</span>
<div className="flex space-x-[0.5rem]">
Expand All @@ -172,7 +112,6 @@ export default function SideBarLeft() {
/>
</div>
</div>
{/* 캘린더 리스트 */}
<ul className="m-[1rem] mt-[1.5rem] space-y-[0.5rem]">
{myCalendars.map((calendar) => (
<li
Expand Down Expand Up @@ -211,15 +150,13 @@ export default function SideBarLeft() {
{/* 구독한 캘린더 */}
<div className="mt-[2rem]">
<div className="evento-subscription">
{/* 제목 */}
<div className="mr-[0.3rem] flex items-center justify-between">
<span className="text-[0.9rem] text-darkGray">구독한 캘린더</span>
<FaPen
className="cursor-pointer text-[0.75rem] text-darkGray"
onClick={() => navigate("/subscription")}
/>
</div>
{/* 캘린더 리스트 */}
<ul className="m-[1rem] mt-[1.5rem] space-y-[0.5rem]">
{subscribedCalendars.map((calendar) => (
<li
Expand Down Expand Up @@ -251,7 +188,26 @@ export default function SideBarLeft() {
</div>
</div>
</div>
{/* 모달들 */}

{/* D-Day */}
<div className="fixed bottom-[3rem] left-[4rem] flex flex-col items-center justify-center">
<ul className="space-y-[.8rem]">
{(Array.isArray(dday) ? dday : []).map((item, index) => {
return (
<li key={index} className="flex items-center">
<span className="flex w-[3rem] items-center text-left text-[.9rem] font-bold text-eventoPurpleDark/70">
{item.d_day}
</span>
<span className="flex flex-1 items-center pl-2 text-left text-[0.8rem] text-darkGray/90">
{item.event_title}
</span>
</li>
);
})}
</ul>
</div>

{/* 모달 */}
{isInviteOpen && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-30">
<InviteCodeModal onClose={toggleInvite} />
Expand All @@ -267,38 +223,10 @@ export default function SideBarLeft() {
<CalendarInfo
calendar={selectedCalendar}
onClose={() => setCalendarInfoOpen(false)}
userId={userId}
userId={user_id}
/>
</div>
)}

<div className="fixed bottom-[3rem] left-[4rem] flex flex-col items-center justify-center">
<ul className="space-y-[.8rem]">
{(Array.isArray(dday) ? dday : []).map((item, index) => {
const today = new Date();
const dDay = new Date(item.d_day);
const differenceInTime = dDay - today;
const differenceInDays = Math.ceil(
differenceInTime / (1000 * 60 * 60 * 24),
);

return (
<li key={index} className="flex items-center">
<span className="flex w-[3rem] items-center text-left text-[.9rem] font-bold text-eventoPurpleDark/70">
{differenceInDays > 0
? `D-${differenceInDays}`
: differenceInDays === 0
? "D-Day"
: `D+${Math.abs(differenceInDays)}`}
</span>
<span className="flex flex-1 items-center pl-2 text-left text-[0.8rem] text-darkGray/90">
{item.event_title}
</span>
</li>
);
})}
</ul>
</div>
</div>
);
}
Loading