diff --git a/web/src/app/_components/webpage.tsx b/web/src/app/_components/webpage.tsx index c3f2a34..6119987 100644 --- a/web/src/app/_components/webpage.tsx +++ b/web/src/app/_components/webpage.tsx @@ -1,10 +1,8 @@ import Header from "./header"; export default function Webpage({children}: Readonly<{children?: React.ReactNode}>) { - return ( - <> - <Header/> - {children} - </> - ) + return (<> + <Header/> + {children} + </>) } \ No newline at end of file diff --git a/web/src/app/submissions/[submissionId]/(styles)/page.scss b/web/src/app/submissions/[submissionId]/(styles)/page.scss index 918b693..9001461 100644 --- a/web/src/app/submissions/[submissionId]/(styles)/page.scss +++ b/web/src/app/submissions/[submissionId]/(styles)/page.scss @@ -1,8 +1,9 @@ +@forward "./page/commentWindow.scss"; +@forward "./page/reviewStatus.scss"; +@forward "./page/ratingWindow.scss"; +@forward "./page/reviewButtons.scss"; @forward "./page/comments.scss"; @forward "./page/review.scss"; -@forward "./page/rating_window.scss"; -@forward "./page/leave_comment_window.scss"; -@forward "./page/review_status.scss"; @forward "./page/map.scss"; @use "../../../globals.scss"; diff --git a/web/src/app/submissions/[submissionId]/(styles)/page/leave_comment_window.scss b/web/src/app/submissions/[submissionId]/(styles)/page/commentWindow.scss similarity index 100% rename from web/src/app/submissions/[submissionId]/(styles)/page/leave_comment_window.scss rename to web/src/app/submissions/[submissionId]/(styles)/page/commentWindow.scss diff --git a/web/src/app/submissions/[submissionId]/(styles)/page/rating_window.scss b/web/src/app/submissions/[submissionId]/(styles)/page/ratingWindow.scss similarity index 97% rename from web/src/app/submissions/[submissionId]/(styles)/page/rating_window.scss rename to web/src/app/submissions/[submissionId]/(styles)/page/ratingWindow.scss index bcc9260..bb5fa65 100644 --- a/web/src/app/submissions/[submissionId]/(styles)/page/rating_window.scss +++ b/web/src/app/submissions/[submissionId]/(styles)/page/ratingWindow.scss @@ -3,7 +3,6 @@ .rating-window { @include globals.border-with-radius; width: 100%; - height: 225px; .rating-type { display: flex; diff --git a/web/src/app/submissions/[submissionId]/(styles)/page/reviewButtons.scss b/web/src/app/submissions/[submissionId]/(styles)/page/reviewButtons.scss new file mode 100644 index 0000000..ccc6ecd --- /dev/null +++ b/web/src/app/submissions/[submissionId]/(styles)/page/reviewButtons.scss @@ -0,0 +1,13 @@ +@use "../../../../globals.scss"; + +.review-set { + @include globals.border-with-radius; + display: grid; + align-items: center; + gap: 10px; + padding: 10px; + + button { + width: 100%; + } +} \ No newline at end of file diff --git a/web/src/app/submissions/[submissionId]/(styles)/page/review_status.scss b/web/src/app/submissions/[submissionId]/(styles)/page/reviewStatus.scss similarity index 100% rename from web/src/app/submissions/[submissionId]/(styles)/page/review_status.scss rename to web/src/app/submissions/[submissionId]/(styles)/page/reviewStatus.scss diff --git a/web/src/app/submissions/[submissionId]/_comments.tsx b/web/src/app/submissions/[submissionId]/_comments.tsx new file mode 100644 index 0000000..276e59e --- /dev/null +++ b/web/src/app/submissions/[submissionId]/_comments.tsx @@ -0,0 +1,66 @@ +import type { SubmissionInfo } from "@/app/ts/Submission"; +import { Button } from "@mui/material" +import Window from "./_window"; +import SendIcon from '@mui/icons-material/Send'; +import Image from "next/image"; + +interface CommentersProps { + comments_data: CreatorAndReviewStatus +} + +interface CreatorAndReviewStatus { + creator: SubmissionInfo["DisplayName"], + review: SubmissionInfo["StatusID"], + comments: Comment[], + name: string +} + +interface Comment { + picture?: string, //TEMP + comment: string, + date: string, + name: string +} + +function AddComment(comment: Comment) { + const IsBhopMaptest = comment.name == "BhopMaptest" //Highlighted commenter + + return ( + <div className="commenter" data-highlighted={IsBhopMaptest}> + <Image src={comment.picture as string} alt={`${comment.name}'s comment`}/> + <div className="details"> + <header> + <p className="name">{comment.name}</p> + <p className="date">{comment.date}</p> + </header> + <p className="comment">{comment.comment}</p> + </div> + </div> + ); +} + +function LeaveAComment() { + return ( + <Window title="Leave a Comment:" className="leave-comment-window"> + <textarea name="comment-box" id="comment-text-field"></textarea> + <Button variant="outlined" endIcon={<SendIcon/>}>Submit</Button> + </Window> + ) +} + +export default function Comments(stats: CommentersProps) { + return (<> + <section className="comments"> + {stats.comments_data.comments.length===0 + && <p className="no-comments">There are no comments.</p> + || stats.comments_data.comments.map(comment => ( + <AddComment key={comment.name} name={comment.name} date={comment.date} comment={comment.comment}/> + ))} + </section> + <LeaveAComment/> + </>) +} + +export { + type CreatorAndReviewStatus +} \ No newline at end of file diff --git a/web/src/app/submissions/[submissionId]/_map.tsx b/web/src/app/submissions/[submissionId]/_map.tsx index 80fc925..425e630 100644 --- a/web/src/app/submissions/[submissionId]/_map.tsx +++ b/web/src/app/submissions/[submissionId]/_map.tsx @@ -8,6 +8,7 @@ import Image from "next/image" interface AssetID { id: SubmissionInfo["AssetID"] } + function MapImage(asset: AssetID) { const [assetImage, setAssetImage] = useState(""); diff --git a/web/src/app/submissions/[submissionId]/_reviewButtons.tsx b/web/src/app/submissions/[submissionId]/_reviewButtons.tsx new file mode 100644 index 0000000..b30ce05 --- /dev/null +++ b/web/src/app/submissions/[submissionId]/_reviewButtons.tsx @@ -0,0 +1,29 @@ +import { Button, ButtonOwnProps } from "@mui/material"; + +type Review = "Completed" | "Submit" | "Reject" | "Revoke" | "Validate" | "Publish" +interface ReviewButton { + name: Review, + color: ButtonOwnProps["color"] +} + +function ReviewButtonClicked(type: Review) { + //magical api requesting goes here, i hope it wont blow up + console.log(type) +} + +function ReviewButton(props: ReviewButton) { + return <Button color={props.color} variant="contained" onClick={() => { ReviewButtonClicked(props.name) }}>{props.name}</Button> +} + +export default function ReviewButtons() { + return ( + <section className="review-set"> + <ReviewButton color="error" name="Reject"/> + <ReviewButton color="info" name="Revoke"/> + <ReviewButton color="info" name="Publish"/> + <ReviewButton color="info" name="Completed"/> + <ReviewButton color="info" name="Submit"/> + <ReviewButton color="info" name="Validate"/> + </section> + ) +} \ No newline at end of file diff --git a/web/src/app/submissions/[submissionId]/_window.tsx b/web/src/app/submissions/[submissionId]/_window.tsx new file mode 100644 index 0000000..866b5a4 --- /dev/null +++ b/web/src/app/submissions/[submissionId]/_window.tsx @@ -0,0 +1,20 @@ +interface WindowStruct { + 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> + ) +} + +export { + type WindowStruct +} \ No newline at end of file diff --git a/web/src/app/submissions/[submissionId]/page.tsx b/web/src/app/submissions/[submissionId]/page.tsx index 226cbb4..e270d77 100644 --- a/web/src/app/submissions/[submissionId]/page.tsx +++ b/web/src/app/submissions/[submissionId]/page.tsx @@ -1,88 +1,51 @@ -'use client' +"use client" -import { SubmissionStatus, SubmissionStatusToString, type SubmissionInfo } from "@/app/ts/Submission"; +import { SubmissionStatus, SubmissionStatusToString } from "@/app/ts/Submission"; +import type { CreatorAndReviewStatus } from "./_comments"; import { MapImage, type AssetID } from "./_map"; -import { Rating, Button } from "@mui/material"; -import SendIcon from '@mui/icons-material/Send'; -import Webpage from "@/app/_components/webpage"; import { useParams } from "next/navigation"; -import Image from "next/image"; +import ReviewButtons from "./_reviewButtons"; +import { Rating } from "@mui/material"; +import Comments from "./_comments"; +import Webpage from "@/app/_components/webpage"; +import Window from "./_window"; import Link from "next/link"; import "./(styles)/page.scss"; -interface Window { - className: string, - title: string, - children: React.ReactNode -} -interface Comment { - picture?: string, //TEMP - comment: string, - date: string, - name: string -} -interface CreatorAndReviewStatus { - creator: SubmissionInfo["DisplayName"], - review: SubmissionInfo["StatusID"], - comments: Comment[], - name: string +function Ratings() { + return ( + <Window className="rating-window" title="Rating"> + <section className="rating-type"> + <aside className="rating-left"> + <p>Quality</p> + <p>Difficulty</p> + <p>Fun</p> + <p>Length</p> + </aside> + <aside className="rating-right"> + <Rating defaultValue={2.5} precision={0.5}/> + <Rating defaultValue={2.5} precision={0.5}/> + <Rating defaultValue={2.5} precision={0.5}/> + <Rating defaultValue={2.5} precision={0.5}/> + </aside> + </section> + </Window> + ) } -function Window(window: Window) { - return ( - <section className={window.className}> - <header> - <p>{window.title}</p> - </header> - <main>{window.children}</main> - </section> - ) -} - -function ImageAndRatings(asset: AssetID) { +function RatingArea(asset: AssetID) { return ( <aside className="review-area"> <section className="map-image-area"> <MapImage id={asset.id}/> </section> - <Window className="rating-window" title="Rating"> - <section className="rating-type"> - <aside className="rating-left"> - <p>Quality</p> - <p>Difficulty</p> - <p>Fun</p> - <p>Length</p> - </aside> - <aside className="rating-right"> - <Rating defaultValue={2.5} precision={0.5}/> - <Rating defaultValue={2.5} precision={0.5}/> - <Rating defaultValue={2.5} precision={0.5}/> - <Rating defaultValue={2.5} precision={0.5}/> - </aside> - </section> - </Window> + <Ratings/> + <ReviewButtons/> </aside> ) } -function Comment(comment: Comment) { - const IsBhopMaptest = comment.name == "BhopMaptest" //Highlighted commenter - - return ( - <div className="commenter" data-highlighted={IsBhopMaptest}> - <Image src={comment.picture as string} alt={`${comment.name}'s comment`}/> - <div className="details"> - <header> - <p className="name">{comment.name}</p> - <p className="date">{comment.date}</p> - </header> - <p className="comment">{comment.comment}</p> - </div> - </div> - ); -} - function TitleAndComments(stats: CreatorAndReviewStatus) { const Review = SubmissionStatusToString(stats.review) @@ -96,48 +59,20 @@ function TitleAndComments(stats: CreatorAndReviewStatus) { </div> <p className="by-creator">by <Link href="" target="_blank">{stats.creator}</Link></p> <span className="spacer"></span> - <section className="comments"> - {stats.comments.length===0 - && <p className="no-comments">There are no comments.</p> - || stats.comments.map(comment => ( - <Comment key={comment.name} name={comment.name} date={comment.date} comment={comment.comment}/> - ))} - </section> - <Window title="Leave a Comment:" className="leave-comment-window"> - <textarea name="comment-box" id="comment-text-field"></textarea> - <Button variant="contained" endIcon={<SendIcon/>}>Submit</Button> - </Window> + <Comments comments_data={stats}/> </main> ) } -// const placeholder_Comments = [ -// { -// comment: "This map has been accepted and is in the game.", -// date: "on Dec 8 '24 at 18:46", -// name: "BhopMaptest" -// }, -// { -// comment: "This map is so mid...", -// date: "on Dec 8 '24 at 18:46", -// name: "vmsize" -// }, -// { -// comment: "I prefer strafe client", -// date: "on Dec 8 '24 at 18:46", -// name: "Quaternions" -// } -// ] - export default function SubmissionInfoPage() { - const params = useParams<{submissionId: string}>() + const dynamicId = useParams<{submissionId: string}>() return ( <Webpage> <main className="map-page-main"> <section className="review-section"> - <ImageAndRatings id={432}/> - <TitleAndComments name={params.submissionId} creator="Quaternions" review={SubmissionStatus.Accepted} comments={[]}/> + <RatingArea id={432}/> + <TitleAndComments name={dynamicId.submissionId} creator="Quaternions" review={SubmissionStatus.Accepted} comments={[]}/> </section> </main> </Webpage>