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:
parent
b0b16c91dc
commit
a7e9dbb94d
@ -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)
|
||||
}
|
||||
}
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
@ -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">
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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) });
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user