Skip to content

Commit

Permalink
Merge pull request #1773 from acm-ucr/stormyy00/schoolstats
Browse files Browse the repository at this point in the history
adding stats for shirts, diet, schools
  • Loading branch information
stormyy00 authored Sep 18, 2024
2 parents 2eea968 + 529fca3 commit 5f12d72
Show file tree
Hide file tree
Showing 8 changed files with 1,757 additions and 3,018 deletions.
4,407 changes: 1,484 additions & 2,923 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"clsx": "^2.1.1",
"compressorjs": "^1.2.1",
"firebase": "^10.13.1",
"firebase-admin": "^11.4.1",
"firebase-admin": "^12.5.0",
"gray-matter": "^4.0.3",
"input-otp": "^1.2.4",
"jszip": "^3.10.1",
Expand Down
30 changes: 22 additions & 8 deletions src/app/api/dashboard/[type]/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ export const POST = async (req, { params }) => {
[`roles.${params.type}`]: 0,
}),
updateDoc(doc(db, "statistics", "statistics"), {
[`${params.type}.0`]: increment(1),
[`${params.type}.status.0`]: increment(1),
[`${params.type}.shirt.0.${element.size}`]: increment(1),
[`${params.type}.diet.0.${element.diet}`]: increment(1),
[`${params}.participants.school.0.${element.school}`]: increment(1),
}),
send({
email: user.email,
Expand Down Expand Up @@ -167,7 +170,6 @@ export const GET = async (req, { params }) => {
const total = countFromServer.data().count;
const lastDoc = output.length > 0 ? output[output.length - 1].uid : "";
const firstDoc = output.length > 0 ? output[0].uid : "";

return res.json(
{
message: "OK",
Expand Down Expand Up @@ -228,19 +230,31 @@ export const PUT = async (req, { params }) => {
});

const size = object.shirt;
const diet = object.diet;
const school = object.school;

status === 1 &&
(await updateDoc(doc(db, "statistics", "statistics"), {
[`${params.type}.1`]: increment(1),
[`${params.type}.0`]: increment(-1),
[`${params.type}.${size}`]: increment(1),
[`${params.type}.status.1`]: increment(1),
[`${params.type}.status.0`]: increment(-1),
[`${params.type}.shirt.1.${size}`]: increment(1),
[`${params.type}.shirt.0${size}`]: increment(-1),
[`${params.type}.diet.1.${diet}`]: increment(1),
[`${params.type}.diet.0${diet}`]: increment(-1),
[`${params}.participants.school.1.${school}`]: increment(1),
[`${params}.participants.school.0.${school}`]: increment(-1),
}));

status === -1 &&
(await updateDoc(doc(db, "statistics", "statistics"), {
[`${params.type}.-1`]: increment(1),
[`${params.type}.0`]: increment(-1),
[`${params.type}.${size}`]: increment(-1),
[`${params.type}.status.-1`]: increment(1),
[`${params.type}.status.0`]: increment(-1),
[`${params.type}.shirt.-1.${size}`]: increment(1),
[`${params.type}.shirt.0.${size}`]: increment(-1),
[`${params.type}.diet.-1.${diet}`]: increment(1),
[`${params.type}.diet.0.${diet}`]: increment(-1),
[`${params}.participants.school.-1.${school}`]: increment(1),
[`${params}.participants.school.0.${school}`]: increment(-1),
}));
}),
);
Expand Down
112 changes: 107 additions & 5 deletions src/app/api/settings/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,37 @@ const syncStatsWithDatabase = async () => {
updateRoleCounts("teams"),
]);
};
const getRoleCount = async (role, value) => {
const getRoleCount = async (role, value, subType, subValue) => {
if (role === "teams") {
return (
await getCountFromServer(
query(collection(db, "teams"), where(`status`, "==", value)),
)
).data().count;
}

if (subType) {
return (
await getCountFromServer(
query(
collection(db, "users"),
where(`${subType}`, "==", subValue),
where(`roles.${role}`, "==", value),
),
)
).data().count;
}
if (role === "participants" && subType === "school") {
return (
await getCountFromServer(
query(
collection(db, "users"),
where(`school`, "==", subValue),
where(`roles.${role}`, "==", value),
),
)
).data().count;
}
return (
await getCountFromServer(
query(collection(db, "users"), where(`roles.${role}`, "==", value)),
Expand All @@ -44,11 +67,90 @@ const updateRoleCounts = async (role) => {
getRoleCount(role, 1),
]);

await updateDoc(doc(db, "statistics", "statistics"), {
[`${role}.-1`]: roleMinusOneCount,
[`${role}.0`]: roleZeroCount,
[`${role}.1`]: roleOneCount,
const shirtSizes = ["XS", "S", "M", "L", "XL", "XXL"];
const dietOptions = [
"Halal",
"Vegan",
"Vegetarian",
"Nut Allergy",
"No Gluten",
"Lactose Intolerant",
];
const schoolOptions = [
"University of California, Riverside",
"New York University",
];

const [schoolMinusOneCount, schoolZeroCount, schoolOneCount] =
await Promise.all([
Promise.all(
schoolOptions.map((school) =>
getRoleCount("participants", -1, "school", school),
),
),
Promise.all(
schoolOptions.map((school) =>
getRoleCount("participants", 0, "school", school),
),
),
Promise.all(
schoolOptions.map((school) =>
getRoleCount("participants", 1, "school", school),
),
),
]);

const [shirtMinusOneCount, shirtZeroCount, shirtOneCount] = await Promise.all(
[
Promise.all(
shirtSizes.map((size) => getRoleCount(role, -1, "shirt", size)),
),
Promise.all(
shirtSizes.map((size) => getRoleCount(role, 0, "shirt", size)),
),
Promise.all(
shirtSizes.map((size) => getRoleCount(role, 1, "shirt", size)),
),
],
);

const [dietMinusOneCount, dietZeroCount, dietOneCount] = await Promise.all([
Promise.all(
dietOptions.map((option) => getRoleCount(role, -1, "diet", option)),
),
Promise.all(
dietOptions.map((option) => getRoleCount(role, 0, "diet", option)),
),
Promise.all(
dietOptions.map((option) => getRoleCount(role, 1, "diet", option)),
),
]);

const updateData = {
[`${role}.status.-1`]: roleMinusOneCount,
[`${role}.status.0`]: roleZeroCount,
[`${role}.status.1`]: roleOneCount,
};

schoolOptions.forEach((school, index) => {
updateData[`participants.school.-1.${school}`] = schoolMinusOneCount[index];
updateData[`participants.school.0.${school}`] = schoolZeroCount[index];
updateData[`participants.school.1.${school}`] = schoolOneCount[index];
});

shirtSizes.forEach((size, index) => {
updateData[`${role}.shirt.-1.${size}`] = shirtMinusOneCount[index];
updateData[`${role}.shirt.0.${size}`] = shirtZeroCount[index];
updateData[`${role}.shirt.1.${size}`] = shirtOneCount[index];
});

dietOptions.forEach((option, index) => {
updateData[`${role}.diet.-1.${option}`] = dietMinusOneCount[index];
updateData[`${role}.diet.0.${option}`] = dietZeroCount[index];
updateData[`${role}.diet.1.${option}`] = dietOneCount[index];
});

await updateDoc(doc(db, "statistics", "statistics"), updateData);
};
export const GET = async () => {
const res = NextResponse;
Expand Down
40 changes: 29 additions & 11 deletions src/components/admin/services/statistics/Chart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import * as React from "react";
import { Label, Pie, PieChart } from "recharts";
import { ROLES, SIZES } from "@/data/admin/Statistics";
import { ROLES, SIZES, DIETS, SCHOOLS } from "@/data/admin/Statistics";

import { Card, CardContent } from "@/components/ui/card";
import {
Expand All @@ -11,17 +11,27 @@ import {
ChartTooltipContent,
} from "@/components/ui/chart";

const Chart = ({ title, data }) => {
const ITEMS = { ...ROLES, ...SIZES };
const Chart = ({ title, status = null, data }) => {
const ITEMS = { ...ROLES, ...SIZES, ...DIETS, ...SCHOOLS };

const chartData = Object.entries(data)
.filter(([type]) => ROLES[type])
.map(([type, value]) => ({
type: ITEMS[type].label,
value: value,
className: ITEMS[type].className,
fill: ITEMS[type].fill,
}));
const statusData =
status !== null
? [
{
type: ROLES[status].label,
value: 1,
className: ROLES[status].className,
fill: ROLES[status].fill,
},
]
: [];

const chartData = Object.entries(data).map(([type, value]) => ({
type: ITEMS[type].label,
value: value,
className: ITEMS[type].className,
fill: ITEMS[type].fill,
}));

const chartConfig = Object.entries(data).map(([type, value]) => {
const label = ITEMS[type].label;
Expand Down Expand Up @@ -103,6 +113,14 @@ const Chart = ({ title, data }) => {
}}
/>
</Pie>
<Pie
data={statusData}
dataKey="value"
nameKey="type"
innerRadius={55}
outerRadius={60}
strokeWidth={5}
/>
</PieChart>
</ChartContainer>
</CardContent>
Expand Down
58 changes: 47 additions & 11 deletions src/components/admin/services/statistics/Charts.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,54 @@
import Title from "../../Title";
import Chart from "./Chart";

const Charts = ({ counts }) => {
const order = ["status", "shirt", "diet", "school"];

return (
<div className="grid w-full grid-cols-2 gap-4 p-4 md:grid-cols-4">
{Object.entries(counts).map(([category, data]) =>
Object.entries(data)
.filter(([title, sizes]) =>
Object.values(sizes).some((count) => count > 0),
)
.map(([title, data], index) => (
<Chart key={index} title={title} data={data} />
)),
)}
</div>
<>
{order.map((title) => (
<div key={title}>
<Title title={title} />
<div className="mt-3 grid w-full grid-cols-2 gap-4 p-4 md:grid-cols-4">
{Object.entries(counts).map(([category, data]) =>
Object.entries(data)
.filter(([key]) => key === title)
.map(([key, data], index) => {
if (key !== "status") {
return Object.entries(data)
.filter(([statusType, sizeData]) =>
Object.values(sizeData).some((count) => count > 0),
)
.map(([type, sizeData], idx) => {
const data = Object.entries(sizeData).reduce(
(acc, [size, count]) => {
acc[size] = (acc[size] || 0) + count;
return acc;
},
{},
);
return (
<Chart
key={idx}
status={type}
title={category}
data={data}
/>
);
});
} else if (
key === "status" &&
Object.values(data).some((count) => count > 0)
) {
return <Chart key={index} title={category} data={data} />;
}
return null;
}),
)}
</div>
</div>
))}
</>
);
};

Expand Down
Loading

0 comments on commit 5f12d72

Please sign in to comment.