diff --git a/src/components/calendar-options.tsx b/src/components/calendar-options.tsx index 90abcba..07c0954 100644 --- a/src/components/calendar-options.tsx +++ b/src/components/calendar-options.tsx @@ -1,19 +1,20 @@ "use client"; -import { useContext, useRef, useState, createContext, useEffect } from "react"; import TabsGroup, { PanelContainer, Tab, TabPanel, TabsContainer, } from "./tabs"; -import { ScheduleContext } from "@/contexts/schedule-provider"; -import AnimatedOptionsSection from "./animated-options-section"; -import { twMerge } from "tailwind-merge"; -import clsx from "clsx"; -import { IShiftsSorted } from "@/lib/types"; +import { createContext, useContext, useEffect, useRef, useState } from "react"; +import AnimatedOptionsSection from "./animated-options-section"; import CustomDisclosure from "./disclosure"; +import ExportButton from "@/components/calendar/export-button"; +import { IShiftsSorted } from "@/lib/types"; +import { ScheduleContext } from "@/contexts/schedule-provider"; +import clsx from "clsx"; +import { twMerge } from "tailwind-merge"; interface ICalendarOptionsProvider { removeShift: (id: string) => void; @@ -276,6 +277,9 @@ export default function CalendarOptions({

{schedule ? "Schedule" : "Calendar"}

+
+ +
+ + )} + +
+
+ {url} +
+
+ {isCopied ? "Copied!" : "Click to copy"} +
+
+ +
+ {sections.map((section) => ( +
+ +
+
{section.content}
+
+
+ ))} +
+ +
+ + lightbulb + + + You can also{" "} + + download as .ics file + + . + +
+ + + + + + ); +} diff --git a/src/components/calendar/event-modal.tsx b/src/components/calendar/event-modal.tsx index 8c40330..fdf4fde 100644 --- a/src/components/calendar/event-modal.tsx +++ b/src/components/calendar/event-modal.tsx @@ -5,10 +5,11 @@ import { Transition, TransitionChild, } from "@headlessui/react"; -import moment from "moment"; -import Link from "next/link"; -import { Fragment } from "react"; + import { Event } from "react-big-calendar"; +import { Fragment } from "react"; +import Link from "next/link"; +import moment from "moment"; interface IModalCommonProps { selectedEvent: Event; diff --git a/src/components/calendar/export-button.tsx b/src/components/calendar/export-button.tsx new file mode 100644 index 0000000..7c24710 --- /dev/null +++ b/src/components/calendar/export-button.tsx @@ -0,0 +1,54 @@ +"use client"; + +import React, { useState } from "react"; + +import CalendarExportModal from "@/components/calendar/calendar-export-modal"; +import { api } from "@/lib/api"; +import { useMutation } from "@tanstack/react-query"; + +export default function ExportButton() { + const [modalState, setModalState] = useState(false); + const [exportUrl, setExportUrl] = useState(""); + const [buttonLabel, setButtonLabel] = useState("Export"); + + const mutation = useMutation({ + mutationFn: async () => { + const res = await api.get("/export/student/calendar-url"); + return res.data.calendar_url; + }, + onSuccess: (url) => { + if (!url) { + setButtonLabel("Failed to export"); + return; + } + setExportUrl(url); + setModalState(true); + setButtonLabel("Export"); + }, + onError: (error) => { + console.error("Export failed:", error); + setButtonLabel("Failed to export"); + }, + }); + + return ( + <> + + + + + ); +} diff --git a/src/components/exchange/utils/modal.tsx b/src/components/exchange/utils/modal.tsx index 2975297..72109df 100644 --- a/src/components/exchange/utils/modal.tsx +++ b/src/components/exchange/utils/modal.tsx @@ -1,9 +1,10 @@ import { - Transition, - TransitionChild, Dialog, DialogPanel, + Transition, + TransitionChild, } from "@headlessui/react"; + import { Fragment } from "react"; export default function ExchangeModal({ @@ -49,13 +50,6 @@ export default function ExchangeModal({

{title}

-
{children}
diff --git a/src/lib/api.ts b/src/lib/api.ts index 5be822c..9affc2f 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,5 +1,5 @@ -import { useAuthStore } from "@/stores/authStore"; import axios from "axios"; +import { useAuthStore } from "@/stores/authStore"; export const api = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL,