Skip to content

Commit

Permalink
feat: fetching request card metadata
Browse files Browse the repository at this point in the history
Co-authored-by: pfpo <[email protected]>
Co-authored-by: eduardooliveiraps <[email protected]>
Co-authored-by: joaonevesf <[email protected]>
  • Loading branch information
4 people committed Sep 12, 2024
1 parent 634f30a commit 82b387b
Show file tree
Hide file tree
Showing 18 changed files with 211 additions and 139 deletions.
2 changes: 1 addition & 1 deletion src/@types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,5 @@ export type MarketplaceRequest = {

export type Student = {
name: string,
mecNumber: string
mecNumber: number
}
20 changes: 17 additions & 3 deletions src/api/services/exchangeRequestService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BareFetcher } from "swr";
import { BareFetcher, Key } from "swr";
import { SWRInfiniteConfiguration } from "swr/dist/infinite";
import { CreateRequestData, MarketplaceRequest } from "../../@types";
import api from "../backend";
Expand All @@ -11,7 +11,7 @@ const isDirectExchange = (requests: IterableIterator<CreateRequestData>) => {
return true;
}

const submitExchangeRequest = async (requests: Map<string, CreateRequestData>) => {
const submitExchangeRequest = async (requests: Map<number, CreateRequestData>) => {
const formData = new FormData();

for (const request of requests.values()) {
Expand All @@ -38,9 +38,23 @@ const retrieveMarketplaceRequest = async (url: string): Promise<MarketplaceReque
})
}

const retrieveRequestCardMetadata = async (courseUnitId: Key) => {
return fetch(`${api.BACKEND_URL}/course_unit/${courseUnitId}/exchange/metadata`).then(async (res) => {
if (res.ok) {
return await res.json();
}

return [];
}).catch((e) => {
console.error(e);
return [];
});
}

const exchangeRequestService = {
submitExchangeRequest,
retrieveMarketplaceRequest
retrieveMarketplaceRequest,
retrieveRequestCardMetadata
}

export default exchangeRequestService;
13 changes: 13 additions & 0 deletions src/components/auth/LoginButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ArrowLeftEndOnRectangleIcon } from "@heroicons/react/24/outline"
import api from "../../api/backend"
import { Button } from "../ui/button"

export const LoginButton = () => {
return <Button>
<a href={`${api.OIDC_LOGIN_URL}`} className="flex flex-row gap-1">
<p>Entrar</p>
<ArrowLeftEndOnRectangleIcon className="w-5 h-5" />
</a>
</Button>

}
28 changes: 5 additions & 23 deletions src/components/exchange/requests/issue/CreateRequest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,12 @@ type Props = {
export const CreateRequest = ({
setCreatingRequest
}: Props) => {
const [requests, setRequests] = useState<Map<string, CreateRequestData>>(new Map());
const { schedule } = useContext(ScheduleContext);
const enrolledCourseUnits = useStudentCourseUnits(schedule);

const requestEligbleCourseUnits: Array<CreateRequestCardMetadata> = [{
courseUnitName: "Inteligência Artifical",
courseUnitAcronym: "IA",
requesterClassName: "3LEIC09",
availableClasses: [
"3LEIC01",
"3LEIC02",
"3LEIC03",
"3LEIC04",
"3LEIC05",
"3LEIC06",
"3LEIC07",
"3LEIC08",
"3LEIC09",
"3LEIC10"
]
}];
const [requests, setRequests] = useState<Map<number, CreateRequestData>>(new Map());
const { exchangeSchedule } = useContext(ScheduleContext);
const enrolledCourseUnits = useStudentCourseUnits(exchangeSchedule);

return <div className="flex flex-col">
<div className="flex flex-col gap-y-4">
<div className="flex flex-col gap-y-4 max-h-screen overflow-y-auto">
<h1 className="font-bold text-xl">Criar pedido</h1>
<div className="flex flex-col gap-y-2">
{Array.from(enrolledCourseUnits).map((courseInfo: CourseInfo) => (
Expand All @@ -48,7 +30,7 @@ export const CreateRequest = ({
))}

{
requestEligbleCourseUnits.length === 0
enrolledCourseUnits.length === 0
? <p className="text-center">Não foram encontradas cadeiras com inscrição tua!</p>
: <></>
}
Expand Down
89 changes: 49 additions & 40 deletions src/components/exchange/requests/issue/cards/CreateRequestCard.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
import { ArrowLeftIcon, ArrowRightIcon, MinusIcon } from "@heroicons/react/24/outline"
import { Dispatch, SetStateAction, useContext, useEffect, useState } from "react"
import { ClassDescriptor, CourseInfo, CreateRequestCardMetadata, CreateRequestData } from "../../../../../@types"
import { ClassDescriptor, CourseInfo, CreateRequestCardMetadata, CreateRequestData, Student } from "../../../../../@types"
import { ScrollArea } from '../../../../ui/scroll-area'
import ScheduleContext from "../../../../../contexts/ScheduleContext"
import useRequestCardCourseMetadata from "../../../../../hooks/useRequestCardCourseMetadata"
import { Button } from "../../../../ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "../../../../ui/card"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../../../ui/dropdown-menu"
import { Switch } from "../../../../ui/switch"

type Props = {
courseInfo: CourseInfo
requestsHook: [Map<string, CreateRequestData>, Dispatch<SetStateAction<Map<string, CreateRequestData>>>]
requestsHook: [Map<number, CreateRequestData>, Dispatch<SetStateAction<Map<number, CreateRequestData>>>]
}

export const CreateRequestCard = ({
courseInfo,
requestsHook
}: Props) => {
const { data: requestMetadata } = useRequestCardCourseMetadata(courseInfo);
const [expanded, setExpanded] = useState<boolean>(false);
const [hasStudentToExchange, setHasStudentToExchange] = useState<boolean>(false);
const [requests, setRequests] = requestsHook;
const [issuerOriginClass, setIssuerOriginClass] = useState<string | null>(null);
const [selectedDestinationClass, setSelectedDestinationClass] = useState<string | null>(null);
const [selectedDestinationStudent, setSelectedDestinationStudent] = useState<string | null>(null);
const { schedule } = useContext(ScheduleContext);

// agora é necessário ir buscar a metadata
const [selectedDestinationStudent, setSelectedDestinationStudent] = useState<Student | null>(null);
const { exchangeSchedule } = useContext(ScheduleContext);

useEffect(() => {
if (schedule) {
if (exchangeSchedule) {
setIssuerOriginClass(
schedule.find((scheduleItem: ClassDescriptor) => scheduleItem.courseInfo.id === courseInfo.id).classInfo.name
exchangeSchedule.find((scheduleItem: ClassDescriptor) => scheduleItem.courseInfo.id === courseInfo.id).classInfo.name
);
}
}, [schedule]);
}, [exchangeSchedule]);

const excludeClass = () => {
setExpanded(false);
if (requests.get(courseInfo.name)) {
if (requests.get(courseInfo.id)) {
const newRequests = new Map(requests);
newRequests.delete(courseInfo.name)
newRequests.delete(courseInfo.id)
setRequests(newRequests);
}

Expand All @@ -59,29 +60,31 @@ export const CreateRequestCard = ({
setHasStudentToExchange(checked);
}

// const addRequest = () => {
// const currentRequest: CreateRequestData = {
// classNameRequesterGoesFrom: requestMetadata.requesterClassName,
// classNameRequesterGoesTo: selectedDestinationClass
// }
//
// if (selectedDestinationStudent) currentRequest.other_student = Number(selectedDestinationStudent);
//
// const newRequests = new Map(requests);
// newRequests.set(requestMetadata.courseUnitName, currentRequest);
// setRequests(newRequests);
// }
const addRequest = () => {
const currentRequest: CreateRequestData = {
classNameRequesterGoesFrom: issuerOriginClass,
classNameRequesterGoesTo: selectedDestinationClass
}

if (selectedDestinationStudent) currentRequest.other_student = selectedDestinationStudent.mecNumber;

const newRequests = new Map(requests);
newRequests.set(courseInfo.id, currentRequest);
setRequests(newRequests);

console.log("current new requests: ", newRequests);
}

return <Card key={courseInfo.name} className="shadow-md">
<CardHeader className="flex flex-row justify-between items-center">
<CardTitle className="text-xl">{courseInfo.name}</CardTitle>
<CardHeader className="flex flex-row justify-between items-center gap-4">
<CardTitle className="text-md">{courseInfo.name}</CardTitle>
{
expanded ?
<div className="flex flex-row items-center gap-x-2">
<Button variant="destructive" className="p-4 h-7" onClick={() => excludeClass()}>
-
</Button>
<Button className="p-4 h-7" onClick={() => { }}>
<Button className="p-4 h-7" onClick={() => { addRequest() }}>
+
</Button>
</div>
Expand All @@ -102,12 +105,14 @@ export const CreateRequestCard = ({
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-full">
{/*requestMetadata.availableClasses.filter((className) => className !== requestMetadata.requesterClassName)
.map((className: string) => (
<DropdownMenuItem className="w-full" onSelect={() => { setSelectedDestinationClass(className) }}>
<p className="w-full">{className}</p>
</DropdownMenuItem>
))*/}
<ScrollArea className="max-h-72 rounded overflow-y-auto">
{requestMetadata?.classes.filter((currentClass) => currentClass.name !== issuerOriginClass)
.map((currentClass) => (
<DropdownMenuItem className="w-full" onSelect={() => { setSelectedDestinationClass(currentClass.name) }}>
<p className="w-full">{currentClass.name}</p>
</DropdownMenuItem>
))}
</ScrollArea>
</DropdownMenuContent>
</DropdownMenu>
</div>
Expand All @@ -123,19 +128,23 @@ export const CreateRequestCard = ({
<DropdownMenu>
<DropdownMenuTrigger className="w-full">
<Button variant="outline" className="w-full">
{selectedDestinationStudent ?? "Escolher estudante..."}
{selectedDestinationStudent ? selectedDestinationStudent.name : "Escolher estudante..."}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-full">
{/*requestMetadata.availableClasses.map((className: string) => (
<DropdownMenuItem className="w-full" onSelect={() => { setSelectedDestinationClass(className) }}>
<p className="w-full">{className}</p>
</DropdownMenuItem>
))*/}
<DropdownMenuContent className="w-full max-h-fit overflow-scroll">
<ScrollArea className="max-h-72 overflow-y-auto rounded">
{requestMetadata?.students.map((student) => (
<DropdownMenuItem className="w-full" onSelect={() => {
setSelectedDestinationStudent({ name: student.nome, mecNumber: Number(student.codigo) })
}}>
<p className="w-full">{student.nome}</p>
</DropdownMenuItem>
))}
</ScrollArea>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</CardContent>
</Card>
</Card >
}
15 changes: 10 additions & 5 deletions src/components/exchange/requests/view/ViewRequests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export const ViewRequests = ({
const requestCardsContainerRef = useRef(null);
const [hiddenRequests, setHiddenRequests] = useState<Set<number>>(new Set());
const [currentRequestTypeFilter, setCurrentRequestTypeFilter] = useState<number>(0);
const [filterCourseUnitNames, setFilterCourseUnitNames] = useState<Set<string>>(new Set());
const [filterCourseUnitNames, setFilterCourseUnitNames] = useState<Set<number>>(new Set());
const { classes, loading } = useSchedule();

const { data, size, setSize, isLoading } = useMarketplaceRequests(requestTypeFilters[currentRequestTypeFilter]);
const { data, size, setSize, isLoading } = useMarketplaceRequests(filterCourseUnitNames, requestTypeFilters[currentRequestTypeFilter]);

const requests = data ? [].concat(...data) : [];

Expand All @@ -47,6 +47,8 @@ export const ViewRequests = ({
}
}, []);

console.log("current requests: ", requests);

return <div className="relative flex flex-row flex-wrap items-center justify-center gap-x-2 gap-y-2 lg:justify-start">
<div className="flex flex-row justify-between items-center w-full">
<h1 className="font-bold text-xl">Pedidos</h1>
Expand All @@ -70,7 +72,6 @@ export const ViewRequests = ({
availableClasses={["3LEIC01", "3LEIC02", "3LEIC03"]}
filterCourseUnitsHook={[filterCourseUnitNames, setFilterCourseUnitNames]}
/>

<div ref={requestCardsContainerRef} className="mt-4 flex flex-col gap-y-3 overflow-y-auto max-h-screen">
{
isLoading
Expand All @@ -90,8 +91,12 @@ export const ViewRequests = ({
}
</div>
</TabsContent>
<TabsContent value="meus-pedidos"></TabsContent>
<TabsContent value="recebidos"></TabsContent>
<TabsContent value="meus-pedidos">

</TabsContent>
<TabsContent value="recebidos">

</TabsContent>
</Tabs>
</div >
;
Expand Down
12 changes: 6 additions & 6 deletions src/components/exchange/requests/view/ViewRequestsFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,29 @@ import { ScrollArea } from "../../../ui/scroll-area"

type Props = {
availableClasses: Array<string>
filterCourseUnitsHook: [Set<string>, Dispatch<SetStateAction<Set<string>>>]
filterCourseUnitsHook: [Set<number>, Dispatch<SetStateAction<Set<number>>>]
}

export const ViewRequestsFilters = ({
availableClasses,
filterCourseUnitsHook
}: Props) => {
const [filterCourseUnits, setFilterCourseUnits] = filterCourseUnitsHook
const { schedule } = useContext(ScheduleContext);
const enrolledCourseUnits = useStudentCourseUnits(schedule);
const { exchangeSchedule } = useContext(ScheduleContext);
const enrolledCourseUnits = useStudentCourseUnits(exchangeSchedule);

return <div className="flex flex-row justify-between w-full">
{/* Course unit filters */}
<div className="flex flex-row gap-2 w-2/3 flex-wrap">
{Array.from(enrolledCourseUnits).map((courseUnit: CourseInfo) => (
<div>
<Badge
className={`${filterCourseUnits.has(courseUnit.acronym) ? "bg-black text-white" : "bg-gray-200 text-gray-700"} cursor-pointer hover:text-white`}
className={`${filterCourseUnits.has(courseUnit.id) ? "bg-black text-white" : "bg-gray-200 text-gray-700"} cursor-pointer hover:text-white`}
onClick={() => {
const newFilterCourseUnits = new Set(filterCourseUnits);

if (newFilterCourseUnits.has(courseUnit.acronym)) newFilterCourseUnits.delete(courseUnit.acronym);
else newFilterCourseUnits.add(courseUnit.acronym);
if (newFilterCourseUnits.has(courseUnit.id)) newFilterCourseUnits.delete(courseUnit.id);
else newFilterCourseUnits.add(courseUnit.id);

setFilterCourseUnits(newFilterCourseUnits);
}}
Expand Down
23 changes: 19 additions & 4 deletions src/components/exchange/requests/view/cards/RequestCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ArchiveBoxIcon, ArrowDownIcon, ArrowRightIcon, ArrowUpIcon, ChevronDownIcon } from "@heroicons/react/24/outline"
import { ChevronUpIcon } from "@heroicons/react/24/solid"
import { Dispatch, SetStateAction, useState } from "react"
import { Dispatch, SetStateAction, useContext, useState } from "react"
import { MarketplaceRequest } from "../../../../../@types"
import ScheduleContext from "../../../../../contexts/ScheduleContext"
import { Badge } from "../../../../ui/badge"
import { Button } from "../../../../ui/button"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "../../../../ui/card"
Expand All @@ -21,6 +22,7 @@ export const RequestCard = ({
hiddenRequests,
setHiddenRequests
}: Props) => {
const { setExchangeSchedule } = useContext(ScheduleContext);
const [open, setOpen] = useState<boolean>(false);
const [hovered, setHovered] = useState<boolean>(false);

Expand Down Expand Up @@ -114,9 +116,22 @@ export const RequestCard = ({
Selecionar todas
</label>
</div>
<Button>
Propôr troca
</Button>
<div className="flex flex-row gap-2">
<Button onClick={() => {
setExchangeSchedule((prev) => {
const newExchangeSchedule = [...prev];
request?.options.forEach((option) => {
// newExchangeSchedule.push()
});
return [];
})
}}>
Prever
</Button>
<Button>
Propôr troca
</Button>
</div>
</div>
</CardFooter>
</Card >
Expand Down
Loading

0 comments on commit 82b387b

Please sign in to comment.