web: fix up
All checks were successful
continuous-integration/drone/push Build is passing

When possible you should not use inline styling and instead use SCSS files for following convention and keeping consistency, Grid is also a deprecated React component in Material UI
You should also separate components that are client only to its own .tsx module rather than having it be mixed with components that aren't required for being client only
This commit is contained in:
rhpidfyre 2024-12-19 02:24:38 -05:00
parent b0b16c91dc
commit a7e9dbb94d
7 changed files with 77 additions and 66 deletions

View File

@ -11,9 +11,14 @@
position: relative;
}
a { color:rgb(255, 255, 255) }
a {
color:rgb(255, 255, 255);
a:visited { text-decoration: none; color:rgb(255, 255, 255); }
a:hover { text-decoration: none; color:rgb(255, 255, 255); }
a:focus { text-decoration: none; color:rgb(255, 255, 255); }
a:hover, a:active { text-decoration: none; color:rgb(192, 192, 192) }
&:visited, &:hover, &:focus {
text-decoration: none;
color: rgb(255, 255, 255);
}
&:active {
color: rgb(192, 192, 192)
}
}

View File

@ -1,16 +1,18 @@
import { Button, ButtonOwnProps } from "@mui/material";
import { SubmissionInfo } from "@/app/ts/Submission";
type Review = "Completed" | "Submit" | "Reject" | "Revoke" | "Accept" | "Validate" | "Upload"
type Action = "completed" | "submit" | "reject" | "revoke" | "trigger-validate" | "trigger-upload"
type Actions = "Completed" | "Submit" | "Reject" | "Revoke"
type Review = Actions | "Accept" | "Validate" | "Upload"
type Action = Lowercase<Actions> | "trigger-validate" | "trigger-upload"
interface ReviewButton {
name: Review,
action: Action,
submissionId: number,
submissionId: string,
color: ButtonOwnProps["color"]
}
function ReviewButtonClicked(action: Action, submissionId: number) {
function ReviewButtonClicked(action: Action, submissionId: string) {
fetch(`/api/submissions/${submissionId}/status/${action}`, {
method: "POST",
headers: {
@ -27,15 +29,17 @@ function ReviewButton(props: ReviewButton) {
}
export default function ReviewButtons(props: SubmissionInfo) {
const submissionId = props.ID.toString()
return (
<section className="review-set">
<ReviewButton color="info" name="Submit" action="submit" submissionId={props.ID}/>
<ReviewButton color="info" name="Revoke" action="revoke" submissionId={props.ID}/>
<ReviewButton color="info" name="Accept" action="trigger-validate" submissionId={props.ID}/>
<ReviewButton color="info" name="Validate" action="trigger-validate" submissionId={props.ID}/>
<ReviewButton color="error" name="Reject" action="reject" submissionId={props.ID}/>
<ReviewButton color="info" name="Upload" action="trigger-upload" submissionId={props.ID}/>
<ReviewButton color="info" name="Completed" action="completed" submissionId={props.ID}/>
<ReviewButton color="info" name="Submit" action="submit" submissionId={submissionId}/>
<ReviewButton color="info" name="Revoke" action="revoke" submissionId={submissionId}/>
<ReviewButton color="info" name="Accept" action="trigger-validate" submissionId={submissionId}/>
<ReviewButton color="info" name="Validate" action="trigger-validate" submissionId={submissionId}/>
<ReviewButton color="error" name="Reject" action="reject" submissionId={submissionId}/>
<ReviewButton color="info" name="Upload" action="trigger-upload" submissionId={submissionId}/>
<ReviewButton color="info" name="Completed" action="completed" submissionId={submissionId}/>
</section>
)
}

View File

@ -71,22 +71,22 @@ export default function SubmissionInfoPage() {
const dynamicId = useParams<{submissionId: string}>()
const [submission, setSubmission] = useState<SubmissionInfo | null>(null)
useEffect(() => { // needs to be client sided since server doesn't have a session, nextjs got mad at me for exporting an async function: (https://nextjs.org/docs/messages/no-async-client-component)
async function getSubmission() {
const res = await fetch(`/api/submissions/${dynamicId.submissionId}`)
const data = await res.json()
setSubmission(data)
if (res.ok) {
setSubmission(await res.json())
}
}
getSubmission()
}, [dynamicId.submissionId])
if (!submission) return (
<Webpage>
{/* TODO: Add skeleton loading thingy ? Maybe ? (https://mui.com/material-ui/react-skeleton/) */}
</Webpage>
)
if (!submission) {
return <Webpage>
{/* TODO: Add skeleton loading thingy ? Maybe ? (https://mui.com/material-ui/react-skeleton/) */}
</Webpage>
}
return (
<Webpage>
<main className="map-page-main">

View File

@ -3,22 +3,22 @@ import Image from "next/image";
import Link from "next/link";
interface SubmissionCardProps {
id: number;
assetId: number;
displayName: string;
author: string;
assetId: number;
rating: number;
author: string;
id: number;
}
export default function SubmissionCard({ id, displayName, author, rating }: SubmissionCardProps) {
export default function SubmissionCard(props: SubmissionCardProps) {
return (
<Link href={`/submissions/${id}`}>
<Link href={`/submissions/${props.id}`}>
<div className="submissionCard">
{/* TODO: Grab image of model */}
<Image height={200} width={200} priority={true} src="https://api.ic3.space/strafe/map-images/11222350808" style={{ width: `100%` }} alt={displayName} />
<h3>{displayName}</h3>
<p>By {author}</p>
<p> {rating}</p> {/* TODO: paste the star element from submission/1 page */}
<Image height={200} width={200} priority={true} src="https://api.ic3.space/strafe/map-images/11222350808" style={{ width: `100%` }} alt={props.displayName} />
<h3>{props.displayName}</h3>
<p>By {props.author}</p>
<p> {props.rating}</p> {/* TODO: paste the star element from submission/1 page */}
</div>
</Link>
);

View File

@ -1,22 +1,25 @@
//This can all be solved using 0 JavaScript,
//display: grid, ->1fr unit<-
import React, { useState, useEffect } from 'react';
import { Grid, Skeleton } from '@mui/material';
const SkeletonGrid = () => {
const elementWidth = 220;
function calculateSkeletonCount(setState: React.Dispatch<React.SetStateAction<number>>) {
const viewportWidth = window.innerWidth - 100 * 2;
setState(Math.floor(viewportWidth / elementWidth) * 2);
};
function SkeletonGrid() {
const [skeletonCount, setSkeletonCount] = useState(0);
const calculateSkeletonCount = () => {
const viewportWidth = window.innerWidth - 100 * 2;
const elementWidth = 220;
const count = Math.floor(viewportWidth / elementWidth);
setSkeletonCount(count * 2);
};
useEffect(() => {
calculateSkeletonCount();
window.addEventListener('resize', calculateSkeletonCount);
calculateSkeletonCount(setSkeletonCount);
window.addEventListener('resize', () => { calculateSkeletonCount(setSkeletonCount) });
return () => {
window.removeEventListener('resize', calculateSkeletonCount);
window.removeEventListener('resize', () => { calculateSkeletonCount(setSkeletonCount) });
};
}, []);

View File

@ -1,18 +1,16 @@
interface WindowStruct {
children: React.ReactNode,
className: string,
title: string,
children: React.ReactNode
}
export default function Window(window: WindowStruct) {
return (
<section className={window.className}>
<header>
<p>{window.title}</p>
</header>
<main>{window.children}</main>
</section>
)
return <section className={window.className}>
<header>
<p>{window.title}</p>
</header>
<main>{window.children}</main>
</section>
}
export {

View File

@ -1,35 +1,36 @@
'use client'
import React, { useState, useEffect } from 'react'
import Webpage from "@/app/_components/webpage";
import { SubmissionInfo } from '../ts/Submission';
import { Grid2 as Grid } from '@mui/material';
import SubmissionCard from "./_card";
import SkeletonGrid from './_loading';
import Webpage from "@/app/_components/webpage";
import "./(styles)/page.scss";
import { SubmissionInfo } from '../ts/Submission';
export default function SubmissionInfoPage() {
const [submissions, setSubmissions] = useState<SubmissionInfo[]>([])
useEffect(() => { // needs to be client sided since server doesn't have a session, nextjs got mad at me for exporting an async function: (https://nextjs.org/docs/messages/no-async-client-component)
async function fetchSubmissions() {
const res = await fetch('/api/submissions?Page=1&Limit=100')
const data = await res.json()
setSubmissions(data)
if (res.ok) {
setSubmissions(await res.json())
}
}
setTimeout(() => { // testing loading screen made by chatGerbertPT
fetchSubmissions()
}, 250);
}, [])
if (!submissions) return (
<Webpage>
<main style={{ display: 'flex', justifyContent: 'center', padding: '1rem' }}>
<SkeletonGrid />
</main>
</Webpage>
)
if (!submissions) {
return <Webpage>
<main style={{ display: 'flex', justifyContent: 'center', padding: '1rem' }}>
<SkeletonGrid />
</main>
</Webpage>
}
return (
// TODO: Add filter settings & searchbar & page selector