Skip to content

Commit

Permalink
student dashboard final draft
Browse files Browse the repository at this point in the history
  • Loading branch information
home0712 committed Apr 26, 2024
2 parents 3e2c030 + 615c1e2 commit 07595ce
Show file tree
Hide file tree
Showing 15 changed files with 1,108 additions and 134 deletions.
612 changes: 612 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@google-cloud/pubsub": "^4.3.3",
"@googleapis/forms": "^2.0.5",
"@headlessui/react": "^1.7.18",
"@types/nodemailer": "^6.4.14",
"canvas": "^2.11.2",
"firebase": "^10.8.1",
"fs": "^0.0.1-security",
Expand All @@ -23,6 +24,7 @@
"react": "^18",
"react-dom": "^18",
"react-konva": "^18.2.10",
"request": "^2.88.2",
"save-dev": "^0.0.1-security",
"tls": "^0.0.1",
"webpack": "^5.90.3",
Expand Down
13 changes: 13 additions & 0 deletions src/app/api/email/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { NextRequest, NextResponse } from "next/server";
import { sendEmail } from "@/lib/firebase/database/email";

export async function POST(req: NextRequest) {
try {
const body = await req.json();
await sendEmail(body);
return NextResponse.json({message: 'Emails successfully sent'}, {status: 200});
} catch (err) {
console.error("Error in POST request:", err);
return NextResponse.json({error: 'Error sending email'}, {status: 500});
}
}
23 changes: 23 additions & 0 deletions src/app/api/surveys/assign/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { NextRequest, NextResponse } from 'next/server';
import { assignSurveys } from '@/lib/firebase/database/users';

export async function POST(req: NextRequest) {
try {
if (!req.body) {
return NextResponse.json({ error: 'Missing Request Body' }, { status: 400 });
}

// IMPORTANT: Assumes userIds, surveyIds are string arrays!
const { userIds, surveyIds } = await req.json();

try {
await assignSurveys(userIds, surveyIds);
return NextResponse.json({ message: 'Successfully assigned Surveys'}, { status: 200 });
} catch {
return NextResponse.json({ error: 'Error with Assigning Surveys' }, { status: 404 });
}

} catch (error) {
return NextResponse.json({ error: 'Failed to Load Data' }, { status: 500 });
}
}
23 changes: 23 additions & 0 deletions src/app/api/surveys/remove/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { NextRequest, NextResponse } from 'next/server';
import { removeSurveys } from '@/lib/firebase/database/users';

export async function POST(req: NextRequest) {
try {
if (!req.body) {
return NextResponse.json({ error: 'Missing Request Body' }, { status: 400 });
}

// IMPORTANT: Assumes userIds, surveyIds are string arrays!
const { userIds, surveyIds } = await req.json();

try {
await removeSurveys(userIds, surveyIds);
return NextResponse.json({ message: 'Successfully assigned Surveys'}, { status: 200 });
} catch {
return NextResponse.json({ error: 'Error with Assigning Surveys' }, { status: 404 });
}

} catch (error) {
return NextResponse.json({ error: 'Failed to Load Data' }, { status: 500 });
}
}
11 changes: 10 additions & 1 deletion src/app/api/surveys/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { NextRequest, NextResponse } from "next/server";
import { createSurvey } from "@/lib/firebase/database/surveys";
import { createSurvey, getAllSurveys } from "@/lib/firebase/database/surveys";

export async function GET() {
try {
const allSurveys = await getAllSurveys();
return NextResponse.json({ surveys: allSurveys }, { status: 200 });
} catch (error) {
return NextResponse.json({ error: 'error getting all surveys' }, { status: 500 })
}
}

export async function POST(req: NextRequest) {
const body = await req.json();
Expand Down
233 changes: 126 additions & 107 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,124 +1,143 @@
// This code should be client side
"use client";
import React, { useEffect, useState, useCallback } from "react";

// Import statements
import React, { useEffect, useState, useCallback, useLayoutEffect } from "react";
import "konva/lib/shapes/Line";
import { Stage, Layer, Line } from "react-konva/lib/ReactKonvaCore";
import { Polygon, Dims } from "@/types/konva-types";
import styles from "./LoginPage.module.css";

// Environment check
const isWindow = () => typeof window !== 'undefined';

// Login page
export default function LoginPage() {
const [dims, setDims] = useState<Dims>({ width: 0, height: 0 });
const [polygons, setPolygons] = useState<Polygon[]>([]);
const [polygonOverlay, setPolygonOverlay] = useState<Polygon[]>([]);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
// Determine initial dimensions of the page
const windowDefined = typeof window !== 'undefined';
const initDims: Dims = windowDefined ? { width: window.innerWidth, height: window.innerHeight } : { width: 0, height: 0 };

// Login page states
const [dims, setDims] = useState<Dims>(initDims);
const [polygons, setPolygons] = useState<Polygon[]>([]);
const [polygonOverlay, setPolygonOverlay] = useState<Polygon[]>([]);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");

const updateDims = useCallback(() => {
// Effect to update page dimensions and create polygons on window resize
useLayoutEffect(() => {
function updateDims() {
// Update the dims state based on new window dimensions
setDims({ width: window.innerWidth, height: window.innerHeight });
}, []);

useEffect(() => {
updateDims();
window.addEventListener("resize", updateDims);
return () => window.removeEventListener("resize", updateDims);
}, [updateDims]);
// Dynamically render the background polygons
generatePolygons();
}

// Only run this code client-side(?)
if (isWindow()) {

// Add an event listener to call updateDims on window resize
window.addEventListener('resize', updateDims);
updateDims(); // Call on mount

// Cleanup function
return () => window.removeEventListener('resize', updateDims);
}
}, []);

const generatePolygons = useCallback((dims: Dims) => {
const coords: Polygon[] = [
{
points: [
0,
0,
0,
dims.height / 60,
(50 / 85) * dims.width,
dims.height,
dims.width,
dims.height,
dims.width,
0.45 * dims.height,
dims.height / 60,
0,
],
fill: "#D0D12A",
},
{
points: [
0,
dims.height / 60,
0,
dims.height,
(50 / 85) * dims.width,
dims.height,
],
fill: "#295972",
},
{
points: [
dims.height / 60,
0,
dims.width,
0,
dims.width,
0.45 * dims.height,
],
fill: "#295972",
},
];
setPolygons(coords);
}, []);
// Function to generate new polygon background
const generatePolygons = useCallback(() => {
const polygons: Polygon[] = [
// Background polygons (behind login container)
{
points: [
0,
0,
0,
dims.height / 60,
(50 / 85) * dims.width,
dims.height,
dims.width,
dims.height,
dims.width,
0.45 * dims.height,
dims.height / 60,
0,
],
fill: "#D0D12A",
},
{
points: [
0,
dims.height / 60,
0,
dims.height,
(50 / 85) * dims.width,
dims.height,
],
fill: "#295972",
},
{
points: [
dims.height / 60,
0,
dims.width,
0,
dims.width,
0.45 * dims.height,
],
fill: "#295972",
},
// Overlay ("swapped polygons"...simulated part of the login container)
{
points: [
dims.width / 2,
0.15 * dims.height,
0.875 * dims.width,
0.15 * dims.height,
0.875 * dims.width,
0.39375 * dims.height,
dims.width / 2,
0.225 * dims.height,
],
fill: "#D0D12A",
},
{
points: [
dims.width / 2,
0.225 * dims.height,
0.875 * dims.width,
0.39375 * dims.height,
0.875 * dims.width,
0.85 * dims.height,
0.5 * dims.width,
0.85 * dims.height,
],
fill: "#295972",
},
];

const generatePolygonOverlay = useCallback((dims: Dims) => {
const coords: Polygon[] = [
{
points: [
dims.width / 2,
0.15 * dims.height,
0.875 * dims.width,
0.15 * dims.height,
0.875 * dims.width,
0.39375 * dims.height,
dims.width / 2,
0.225 * dims.height,
],
fill: "#D0D12A",
},
{
points: [
dims.width / 2,
0.225 * dims.height,
0.875 * dims.width,
0.39375 * dims.height,
0.875 * dims.width,
0.85 * dims.height,
0.5 * dims.width,
0.85 * dims.height,
],
fill: "#295972",
},
];
setPolygonOverlay(coords);
}, []);
// Update the polygons state
setPolygons(polygons);
}, []);

useEffect(() => {
if (dims.width && dims.height) {
generatePolygons(dims);
generatePolygonOverlay(dims);
}
}, [dims, generatePolygons]);
// Function to draw a given polygon
const drawPolygon = useCallback((polygon: Polygon) => (
<Line
key={polygon.points.toString()}
points={polygon.points}
fill={polygon.fill}
closed
stroke="black"
strokeWidth={0}
/>
), []);

const drawPolygon = (polygon: Polygon) => (
<Line
key={polygon.points.toString()}
points={polygon.points}
fill={polygon.fill}
closed
stroke="black"
strokeWidth={0}
/>
);

// Include a guard to force code to be executed on client side only
return (
<div className={styles.container}>
isWindow() &&
(<div className={styles.container}>
<div className={styles.background}>
<Stage className={styles.stage} width={dims.width} height={dims.height}>
<Layer>
Expand Down Expand Up @@ -152,6 +171,6 @@ export default function LoginPage() {
/>
</div>
</div>
</div>
</div>)
);
}
Loading

0 comments on commit 07595ce

Please sign in to comment.