Skip to content
Merged

Dev #53

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
65 changes: 65 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@fullcalendar/core": "^6.1.19",
"@fullcalendar/daygrid": "^6.1.19",
"@fullcalendar/list": "^6.1.19",
"@fullcalendar/react": "^6.1.19",
"@fullcalendar/timegrid": "^6.1.19",
"@tanstack/react-query": "^5.83.0",
"@tanstack/react-query-devtools": "^5.83.0",
"axios": "^1.11.0",
Expand Down
70 changes: 70 additions & 0 deletions src/app/(afterLogin)/schedule/_components/calendar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"use client";

import { useState } from "react";
import { useSchedule } from "@/hooks/useSchedule";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import listPlugin from "@fullcalendar/list";
import LoadingSpinner from "@/app/_components/loadingSpinner";
import koLocale from "@fullcalendar/core/locales/ko";

export default function Calendar() {
function formatDateToApiString(date: Date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = "00";
const minutes = "00";
const seconds = "00";
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;
}

const [dateRange, setDateRange] = useState(() => {
const today = new Date();
const startOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
const endOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
return {
start: formatDateToApiString(startOfMonth),
end: formatDateToApiString(endOfMonth),
};
});

const { data: scheduleData, isLoading: scheduleLoading } = useSchedule(
dateRange.start,
dateRange.end
);

const events =
scheduleData?.data.content
.filter((schedule: { memo: string }) => schedule.memo === "마감일")
.map((schedule: { title: string; dateTime: string }) => ({
title: schedule.title,
date: schedule.dateTime,
})) || [];

const handleDatesSet = (arg: { start: Date; end: Date }) => {
const newStartDate = formatDateToApiString(arg.start);
const newEndDate = formatDateToApiString(arg.end);

setDateRange({ start: newStartDate, end: newEndDate });
};

return (
<FullCalendar
plugins={[dayGridPlugin, timeGridPlugin, listPlugin]}
initialView="dayGridMonth"
headerToolbar={{
left: "prev,next today",
center: "title",
right: "dayGridMonth,timeGridWeek,timeGridDay",
}}
locale={koLocale}
dayMaxEvents={true}
events={events}
displayEventTime={false}
datesSet={handleDatesSet}
loading={scheduleLoading ? () => <LoadingSpinner /> : undefined}
/>
);
}
69 changes: 69 additions & 0 deletions src/app/(afterLogin)/schedule/_components/sideSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"use client";

import CalendarCheck from "@/assets/CalendarCheck.svg";
import { useSchedule } from "@/hooks/useSchedule";
import { Schedule } from "@/type/schedule";
import LoadingSpinner from "@/app/_components/loadingSpinner";

export default function SideSection() {
function formatDateToApiString(date: Date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;
}

const startDate = formatDateToApiString(new Date());
const endDate = formatDateToApiString(
new Date(new Date().setDate(new Date().getDate() + 7))
);

function getDDay(dateTime: string) {
const today = new Date();
const targetDate = new Date(dateTime);

const todayOnly = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate()
);
const targetOnly = new Date(
targetDate.getFullYear(),
targetDate.getMonth(),
targetDate.getDate()
);

const diffTime = targetOnly.getTime() - todayOnly.getTime();
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));

if (diffDays > 0) return `D-${diffDays}`;
else if (diffDays === 0) return `D-Day`;
else return `D+${Math.abs(diffDays)}`;
}

const { data: scheduleData, isLoading: scheduleLoading } = useSchedule(
startDate,
endDate
);

if (scheduleLoading) return <LoadingSpinner />;

return (
<div className="flex-1/3 flex flex-col gap-5">
{scheduleData?.data.content.map((schedule: Schedule) => (
<div key={schedule.id} className="py-4 px-5 border border-[#E7E7E7] rounded-lg">
<div className="flex flex-row gap-2 items-center">
<CalendarCheck />
<span className="text-xl font-medium">{schedule.title}</span>
<span className="text-xs ml-2 bg-[#FFF2E3] text-main rounded-full py-px px-2">
{getDDay(schedule.dateTime)}
</span>
</div>
</div>
))}
</div>
);
}
14 changes: 14 additions & 0 deletions src/app/(afterLogin)/schedule/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Calendar from "./_components/calendar";
import SideSection from "./_components/sideSection";

export default function SchedulePage() {
return (
<div className="flex flex-row gap-5 h-full mt-16 pb-14">
<div className="flex-2/3">
<Calendar />
</div>
<SideSection />
</div>
);
}

1 change: 1 addition & 0 deletions src/hooks/useApplications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const useUpdateApplication = () => {
mutationFn: updateApplication,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["applications"] });
queryClient.invalidateQueries({ queryKey: ["schedule"] });
},
});
};
Expand Down
3 changes: 2 additions & 1 deletion src/hooks/useSchedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { useQuery } from "@tanstack/react-query";

export const useSchedule = (startDate: string, endDate: string) => {
return useQuery({
queryKey: ["schedule"],
queryKey: ["schedule", startDate, endDate],
queryFn: () => fetchAllSchedules(startDate, endDate),
staleTime: 1000 * 60 * 60,
});
};