diff --git a/.env.sample b/.env.sample index 736b828..b82b40d 100644 --- a/.env.sample +++ b/.env.sample @@ -1,4 +1,4 @@ NEXT_PUBLIC_API_URL=http://localhost:4000/v1 UMAMI_URL= UMAMI_WEBSITE_ID= -PROD_DOMAIN= +PROD_DOMAIN= \ No newline at end of file diff --git a/.gitignore b/.gitignore index 74213a0..c685bfd 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,4 @@ next-env.d.ts *storybook.log storybook-static -certificates \ No newline at end of file +certificates diff --git a/bun.lock b/bun.lock index c92e606..7e561d0 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "astra", diff --git a/src/components/exchange/cards-section.tsx b/src/components/exchange/cards-section.tsx index d904dba..86c46b6 100644 --- a/src/components/exchange/cards-section.tsx +++ b/src/components/exchange/cards-section.tsx @@ -8,6 +8,18 @@ import { useGetExchangeDate } from "@/lib/queries/exchange"; import { twMerge } from "tailwind-merge"; import { clsx } from "clsx"; +interface ShiftProps { + shift: string; + professor?: string; + timeslots: { + weekday: string; + start_hour: string; + end_hour: string; + room: string; + building: string; + }[]; +} + interface ICardSectionProps { title?: string; drafts?: boolean; @@ -15,8 +27,8 @@ interface ICardSectionProps { completed?: boolean; data?: { uc: string; - from: string; - to: string; + from: ShiftProps; + to: ShiftProps; state: string; exchange_id: string; }[]; diff --git a/src/components/exchange/exchange-state-content.tsx b/src/components/exchange/exchange-state-content.tsx index eb24f1c..9da2a77 100644 --- a/src/components/exchange/exchange-state-content.tsx +++ b/src/components/exchange/exchange-state-content.tsx @@ -1,7 +1,36 @@ +import { DateLocalizer, momentLocalizer } from "react-big-calendar"; +import moment from "moment"; + function isEqual({ n, x }: { n: number; x: number }) { return n === x; } +const localizer = momentLocalizer(moment); + +export function formatWeekday(weekdayString: string): string { + const date = moment(weekdayString, "dddd").toDate(); + return localizer.format(date, "ddd"); +} + +function firstAndLastName(fullName: string) { + const words = fullName.trim().split(/\s+/); + if (words.length === 1) return words[0]; + + return `${words[0]} ${words[words.length - 1]}`; +} + +interface ShiftProps { + shift: string; + professor?: string; + timeslots: { + weekday: string; + start: string; + end: string; + room: string; + building: string; + }[]; +} + export default function ExchangeStateContent({ uc, from, @@ -10,8 +39,8 @@ export default function ExchangeStateContent({ status, }: { uc: string; - from: string; - to: string; + from: ShiftProps; + to: ShiftProps; shift: string; status: "pending" | "completed"; }) { @@ -34,19 +63,77 @@ export default function ExchangeStateContent({

Exchange request information

-
-
- Curricular Unit - Shift type - Exchange +
+ Curricular Unit + {uc} + + Shift type + {shift} + + Exchange +
+ {from.shift} + + arrow_forward + + {to.shift}
-
- {uc} - {shift} -
- {from} - arrow_forward - {to} + + {from.professor && to.professor && ( + <> + Professor +
+ {firstAndLastName(from.professor)} + + arrow_forward + + {firstAndLastName(to.professor)} +
+ + )} + + Time +
+
+ {from.timeslots.map((slot, index) => ( + + {`${formatWeekday(slot.weekday)}: ${slot.start} - ${slot.end}`} + + ))} +
+ + + arrow_forward + + +
+ {to.timeslots.map((slot, index) => ( + + {`${formatWeekday(slot.weekday)}: ${slot.start} - ${slot.end}`} + + ))} +
+
+ Room +
+
+ {from.timeslots.map((slot, index) => ( + + {`CP${slot.building}-${slot.room}`} + + ))} +
+ + + arrow_forward + + +
+ {to.timeslots.map((slot, index) => ( + + {`CP${slot.building}-${slot.room}`} + + ))}
diff --git a/src/components/exchange/main-section.tsx b/src/components/exchange/main-section.tsx index c35a5a2..b1ebacf 100644 --- a/src/components/exchange/main-section.tsx +++ b/src/components/exchange/main-section.tsx @@ -28,6 +28,14 @@ export interface IExchange { | "theoretical_practical" | "practical_laboratory" | "tutorial_guidance"; + professor: string; + timeslots: { + weekday: string; + start: string; + end: string; + building: string; + room: string; + }[]; number: number; }; to: { @@ -37,6 +45,14 @@ export interface IExchange { | "theoretical_practical" | "practical_laboratory" | "tutorial_guidance"; + professor: string; + timeslots: { + weekday: string; + start: string; + end: string; + building: string; + room: string; + }[]; number: number; }; course: { id: string; name: string }; @@ -44,7 +60,6 @@ export interface IExchange { export default function MainSection() { const { data: response } = useGetExchanges(); - const exchanges = response?.data?.requests ?? []; const pending_exchanges = exchanges .filter((exchange: IExchange) => exchange.status === "pending") @@ -52,8 +67,32 @@ export default function MainSection() { id: exchange.id, uc: exchange.course.name, status: exchange.status, - from: `${getShortShiftType(exchange.from.type)}${exchange.from.number}`, - to: `${getShortShiftType(exchange.to.type)}${exchange.to.number}`, + from: { + shift: `${getShortShiftType(exchange.from.type)}${exchange.from.number}`, + professor: exchange.from.professor, + timeslots: exchange.from.timeslots.map((timeslot) => { + return { + weekday: timeslot.weekday, + start: timeslot.start, + end: timeslot.end, + room: timeslot.room, + building: timeslot.building, + }; + }), + }, + to: { + shift: `${getShortShiftType(exchange.to.type)}${exchange.to.number}`, + professor: exchange.to.professor, + timeslots: exchange.to.timeslots.map((timeslot) => { + return { + weekday: timeslot.weekday, + start: timeslot.start, + end: timeslot.end, + room: timeslot.room, + building: timeslot.building, + }; + }), + }, exchange_id: exchange.id, })); @@ -63,11 +102,34 @@ export default function MainSection() { id: exchange.id, uc: exchange.course.name, status: exchange.status, - from: `${getShortShiftType(exchange.from.type)}${exchange.from.number}`, - to: `${getShortShiftType(exchange.to.type)}${exchange.to.number}`, + from: { + shift: `${getShortShiftType(exchange.from.type)}${exchange.from.number}`, + professor: exchange.from.professor, + timeslots: exchange.from.timeslots.map((timeslot) => { + return { + weekday: timeslot.weekday, + start: timeslot.start, + end: timeslot.end, + room: timeslot.room, + building: timeslot.building, + }; + }), + }, + to: { + shift: `${getShortShiftType(exchange.to.type)}${exchange.to.number}`, + professor: exchange.to.professor, + timeslots: exchange.to.timeslots.map((timeslot) => { + return { + weekday: timeslot.weekday, + start: timeslot.start, + end: timeslot.end, + room: timeslot.room, + building: timeslot.building, + }; + }), + }, exchange_id: exchange.id, })); - return (

Shift Exchange Requests

diff --git a/src/components/exchange/utils/card.tsx b/src/components/exchange/utils/card.tsx index 3f6cee0..488b4ac 100644 --- a/src/components/exchange/utils/card.tsx +++ b/src/components/exchange/utils/card.tsx @@ -7,13 +7,25 @@ import { useDeleteExchange } from "@/lib/mutations/exchange"; interface IExchangeCardProps { uc: string; - from: string; - to: string; + from: ShiftProps; + to: ShiftProps; pending?: boolean; completed?: boolean; exchange_id?: string; } +interface ShiftProps { + shift: string; + professor?: string; + timeslots: { + weekday: string; + start_hour: string; + end_hour: string; + room: string; + building: string; + }[]; +} + const getShift = (shift: string) => { return shift.replace(/[0-9]/g, ""); }; @@ -41,9 +53,9 @@ export default function ExchangeCard({
{uc}
- {from} + {from.shift} arrow_forward - {to} + {to.shift}
@@ -169,7 +181,7 @@ export default function ExchangeCard({ uc={uc} from={from} to={to} - shift={getShift(from)} + shift={getShift(from.shift)} status={pending ? "pending" : "completed"} />