[go: nahoru, domu]

Skip to content

Commit

Permalink
Merge pull request #29 from Team3256/admin-dashboard-tba
Browse files Browse the repository at this point in the history
Admin dashboard tba
  • Loading branch information
DragonXDev committed Mar 2, 2024
2 parents 300c4f6 + 17f51bb commit aeeac36
Show file tree
Hide file tree
Showing 13 changed files with 950 additions and 140 deletions.
342 changes: 260 additions & 82 deletions apps/nextjs/src/app/dashboard/Assignments.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useState } from "react";
import { useEffect, useState } from "react";
import { Metadata } from "next";
import Image from "next/image";
import { Button } from "@/components/ui/button";
Expand All @@ -19,8 +19,11 @@ import {
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { assignTasks } from "@/lib/utils/autoassign";
import { trpc } from "@/lib/utils/trpc";
import { DndContext, DragOverlay, useDroppable } from "@dnd-kit/core";

import { addAssignment, addMatches, getEmails } from "./actions";
import { AssignmentCard, MemberCard } from "./components/cards";
import { CalendarDateRangePicker } from "./components/date-range-picker";
import { MainNav } from "./components/main-nav";
Expand All @@ -33,96 +36,262 @@ import { UserNav } from "./components/user-nav";
const tags = Array.from({ length: 50 }).map(
(_, i, a) => `v1.2.0-beta.${a.length - i}`,
);

export default function Assignments() {
function autoAssign(
assignments: string[],
members: { [key: string]: string[] },
setMembers: (members: { [key: string]: string[] }) => void,
setAssignments: (assignments: string[]) => void,
) {
// useEffect(() => {
const autoassign = assignTasks(assignments, Object.keys(members));
console.log(autoassign, typeof autoassign);
setMembers(autoassign);
setAssignments([]);
// }, []);
}
function Assignments({ selectedEvent }) {
// XXX: Use real data via tRPC
const [members, setMembers] = useState<{ [key: string]: string[] }>(
Object.fromEntries(tags.map((x) => [`${x}M`, []])),
);
const [assignments, setAssignments] = useState(tags.map((x) => `${x}A`));
// const [members, setMembers] = useState<{ [key: string]: string[] }>(
// Object.fromEntries(tags.map((x) => [`${x}M`, []])),
// );
const [members, setMembers] = useState<{ [key: string]: string[] }>({});
// Object.fromEntries(tags.map((x) => [`${x}M`, []])),

//use useEffect to make a supabase request from the auth tabke to fill it with emails
useEffect(() => {
async function fetchData() {
getEmails(setMembers);
console.log("HEEEEE: ", members);
}
fetchData();
}, []);
const [assignments, setAssignments] = useState<string[]>([]); // Updated t
const [activeId, setActiveId] = useState<string | null>(null);
// Inverted members
const reverseAssignmentToMembers = Object.fromEntries(
Object.entries(members).flatMap(([k, v]) => v.map((x) => [x, k])),
);
// const [parent, setParent] = useState(null);
// const { data, isLoading } = trpc.tba.teamEvents.useQuery({
// teamKey: "frc3256",
// year: 2023,
// });

const { data, isLoading } = trpc.tba.eventMatches.useQuery({
teamKey: "frc3256",
eventKey: selectedEvent,
});
if (!isLoading) {
console.log("DATA: ", data);
console.log("SELECTED EVENT: ", selectedEvent);
}
useEffect(() => {
if (!isLoading && data) {
// Extract relevant information from the data and generate assignments
const matches = data.map((match: any) => ({
match_num: match.match_num,
// match_key: match.match_key,
alliances: match.alliances,
}));
const matchKeys = data.map((match: any) => ({
match_key: match.match_key,
event: selectedEvent,
}));
console.log("MATCHES: ", matchKeys);
// for(int i = 0; i < matchKeys.length; i++) {
// addMatches({ match: matchKeys[i] });
// }
for (let i = 0; i < matchKeys.length; i++) {
addMatches({ match: matchKeys[i] });
}
let newAssignments: string[] = [];
// Iterate over each match object
let count = 0;
let c2 = 1;
// biome-ignore lint/complexity/noForEach: <explanation>
matches.forEach((match: any) => {
// Extract match number and alliances
const { match_num, match_key, alliances } = match;

// Iterate over each alliance (blue and red)
// biome-ignore lint/complexity/noForEach: <explanation>
Object.values(alliances).forEach((alliance: any) => {
// Extract team keys from the alliance
const teamKeys = alliance.team_keys;

// Iterate over each team key
// biome-ignore lint/complexity/noForEach: <explanation>
teamKeys.forEach((teamKey: string) => {
// Construct the assignment string with match number and team number
const assignment = `Match ${c2} - Team ${teamKey}`;
// const assignment = `Match ${match_key} - Team ${teamKey}`;
count++;
if (count % 6 == 0) {
count = 0;
c2++;
}
// Check if the assignment already exists in the assignments array
if (!newAssignments.includes(assignment)) {
// If not, add it to the newAssignments array
newAssignments.push(assignment);
}
});
});
});

// Update the state with the newAssignments array
setAssignments(newAssignments);
}
}, [isLoading, data]);
return (
<DndContext
onDragStart={function handleDragStart(event) {
const active = event.active as { id: string };
console.log("start", active);
setActiveId(active.id);
}}
onDragEnd={function handleDragEnd(event) {
const overId = event.over?.id;
console.log("end", overId, activeId, members, assignments);
if (overId === undefined) {
// Drag action was cancelled
return;
}
if (overId === "ASSIGNMENT_LIST") {
if (assignments.includes(activeId as string)) {
// Assignment already exists in the list
<>
{/* <ModalSelectComponent /> */}

<DndContext
onDragStart={function handleDragStart(event) {
const active = event.active as { id: string };
console.log("start", active);
setActiveId(active.id);
}}
onDragEnd={function handleDragEnd(event) {
const overId = event.over?.id;
console.log(
"end",
"OVERID: ",
overId,
"ACTIVE ID: ",
activeId,
members,
assignments,
);

// Find the match object corresponding to the activeTeamKey
if (activeId && data) {
const activeTeamKey = activeId.split(" ")[4];
const match = data.find((match) => {
// Check if activeTeamKey is part of the blue alliance
if (match.alliances.blue.team_keys.includes(activeTeamKey)) {
return true; // Return true if found in blue alliance
}
// Check if activeTeamKey is part of the red alliance
if (match.alliances.red.team_keys.includes(activeTeamKey)) {
return true; // Return true if found in red alliance
}
return false; // Return false if not found in either alliance
});

// Check if the activeTeamKey is part of the blue alliance or the red alliance
const allianceColor = match.alliances.blue.team_keys.includes(
activeTeamKey,
)
? "blue"
: "red";
console.log("Alliance color:", allianceColor);

// Find the index of the match object within the data array
// const index = data.indexOf(match);
// Find the index of the team key within the blue or red alliance array
let index;
if (allianceColor === "blue") {
index = match.alliances.blue.team_keys.indexOf(activeTeamKey);
} else {
index = match.alliances.red.team_keys.indexOf(activeTeamKey);
}

// If the team key is found, return the corresponding index + 1
if (index !== -1) {
const correspondingIndex = index + 1;
console.log("Corresponding index:", correspondingIndex);
} else {
console.log("Team key not found in data.");
}

const alliance = (allianceColor + (index + 1)) as string;
const matchNumber = parseInt(activeId.split(" ")[1]);

// Make sure index is within the valid range of data array

const currentMatchKey = data[matchNumber - 1].match_key;
const currentTeam = parseInt(activeId.split(" ")[4].slice(-4));

addAssignment({
match: currentMatchKey,
team: currentTeam,
alliance: alliance,
assignee: overId,
});
}

if (overId === undefined) {
// Drag action was cancelled
return;
}
setAssignments((assignments) => [...assignments, activeId as string]);
setMembers((members) => {
const prevMember = reverseAssignmentToMembers[activeId as string];
return {
...members,
[prevMember]: members[prevMember].filter((x) => x !== activeId),
};
});
if (overId === "ASSIGNMENT_LIST") {
if (assignments.includes(activeId as string)) {
// Assignment already exists in the list
return;
}
setAssignments((assignments) => [
...assignments,
activeId as string,
]);
setMembers((members) => {
const prevMember = reverseAssignmentToMembers[activeId as string];
return {
...members,
[prevMember]: members[prevMember].filter((x) => x !== activeId),
};
});
setActiveId(null);
return;
}
if (members[overId].includes(activeId as string)) {
// Assignment already exists in the member's list
return;
}
const prevMember = reverseAssignmentToMembers[activeId as string];
if (prevMember !== undefined) {
setMembers((members) => {
return {
...members,
[overId]: [...members[overId], activeId as string],
[prevMember]: members[prevMember].filter((x) => x !== activeId),
};
});
} else {
setMembers((members) => {
return {
...members,
[overId]: [...members[overId], activeId as string],
};
});
}
setAssignments((assignments) =>
assignments.filter((x) => x !== activeId),
);
setActiveId(null);
return;
}
if (members[overId].includes(activeId as string)) {
// Assignment already exists in the member's list
return;
}
const prevMember = reverseAssignmentToMembers[activeId as string];
if (prevMember !== undefined) {
setMembers((members) => {
return {
...members,
[overId]: [...members[overId], activeId as string],
[prevMember]: members[prevMember].filter((x) => x !== activeId),
};
});
} else {
setMembers((members) => {
return {
...members,
[overId]: [...members[overId], activeId as string],
};
});
}
setAssignments((assignments) =>
assignments.filter((x) => x !== activeId),
);
setActiveId(null);
}}
>
<ResizablePanelGroup
direction="horizontal"
className="max-w-screen h-rounded-lg h-full border"
}}
>
<ResizablePanel defaultSize={50}>
<ScrollArea className="h-full w-full rounded-md border">
<div className="flex flex-wrap">
{Object.entries(members).map(([name, values]) => (
<MemberCard key={name} user={name} assignments={values} />
))}
</div>
</ScrollArea>
</ResizablePanel>
<ResizableHandle withHandle={true} />
<ResizablePanel defaultSize={50}>
<AssignmentList assignments={assignments} />
<DragOverlay>
{activeId && <AssignmentCard assignment={activeId} />}
</DragOverlay>
{/* <ResizablePanelGroup direction="vertical">
<ResizablePanelGroup
direction="horizontal"
className="max-w-screen h-rounded-lg h-full border"
>
<ResizablePanel defaultSize={50}>
<ScrollArea className="h-full w-full rounded-md border">
<div className="flex flex-wrap">
{Object.entries(members).map(([name, values]) => (
<MemberCard key={name} user={name} assignments={values} />
))}
</div>
</ScrollArea>
</ResizablePanel>
<ResizableHandle withHandle={true} />
<ResizablePanel defaultSize={50}>
<AssignmentList assignments={assignments} />
<DragOverlay>
{activeId && <AssignmentCard assignment={activeId} />}
</DragOverlay>
{/* <ResizablePanelGroup direction="vertical">
<ResizablePanel defaultSize={25}>
<div className="flex h-full items-center justify-center p-6">
<span className="font-semibold">Two</span>
Expand All @@ -135,9 +304,17 @@ export default function Assignments() {
</div>
</ResizablePanel>
</ResizablePanelGroup> */}
</ResizablePanel>
</ResizablePanelGroup>
</DndContext>
</ResizablePanel>
</ResizablePanelGroup>
<Button
onClick={() =>
autoAssign(assignments, members, setMembers, setAssignments)
}
>
Auto Assign
</Button>
</DndContext>
</>
);
}
function AssignmentList({ assignments }: { assignments: string[] }) {
Expand All @@ -157,3 +334,4 @@ function AssignmentList({ assignments }: { assignments: string[] }) {
</ScrollArea>
);
}
export default trpc.withTRPC(Assignments);
Loading

0 comments on commit aeeac36

Please sign in to comment.