From 40f4520458291a425e88da9f15b534ae29c0996a Mon Sep 17 00:00:00 2001 From: powermaker450 Date: Thu, 29 Aug 2024 03:19:21 +0000 Subject: [PATCH] Implement the (mostly) functional side of things --- src/App.tsx | 92 ++++++++++++++++++++++++++++++++-- src/components/ButtonRow.tsx | 11 +++- src/components/ReviewField.tsx | 44 ++++++++++++---- 3 files changed, 134 insertions(+), 13 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index b4972c4..989c4ce 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,26 +1,112 @@ +import { Alert, Collapse, Rating, Typography } from "@mui/material"; import "./App.css"; import ButtonRow, { ActionProps } from "./components/ButtonRow"; -import ReviewField from "./components/ReviewField"; +import ReviewField, { ReviewFieldProps } from "./components/ReviewField"; +import { useState } from "react"; function App() { + const [rating, setNewRating] = useState(0); + const [showAlert, changeAlert] = useState(false); + const [alertText, changeAlertText] = useState(""); + + const fields: ReviewFieldProps[] = [ + { + name: "Name", + dynamicState: useState("") + }, + { + name: "Title", + dynamicState: useState("") + }, + { + name: "Content", + dynamicState: useState("") + } + ]; + + const clearValues = () => { + fields.forEach((field) => { + field.dynamicState[1](""); + }); + + setNewRating(null); + } + + const showThenHide = async () => { + const response = await fetch("http://localhost:8080/post", { + method: "POST", + body: JSON.stringify({ + rating: rating, + username: fields[0].dynamicState[0], + title: fields[1].dynamicState[0], + content: fields[2].dynamicState[0] + }) + }).then((response) => response.json()); + + response.error ? changeAlertText(`${response.error.type}: ${response.error.message}`) : changeAlertText(`Success: ${response.message}`); + + if (showAlert) { + return; + } + + changeAlert(true); + + setTimeout(() => { + changeAlert(false); + }, 3000); + } + const buttons: ActionProps[] = [ { - name: "Cancel", + name: "Clear", type: "outlined", + action: clearValues }, { name: "Submit", type: "contained", + action: showThenHide }, ]; + const alert = ( + + {alertText} + + ); + return ( <> - + + Simple Review Client + + +
+ + { + setNewRating(newRating); + }} + /> + +
+
+ +
+ +
+ + + {alert} + ); } diff --git a/src/components/ButtonRow.tsx b/src/components/ButtonRow.tsx index 49605cc..53dea9c 100644 --- a/src/components/ButtonRow.tsx +++ b/src/components/ButtonRow.tsx @@ -4,6 +4,7 @@ import React, { ReactNode } from "react"; export interface ActionProps { name: string; type: "outlined" | "text" | "contained"; + action?: () => void; } interface ActionButtonProps { @@ -14,7 +15,15 @@ const ButtonRow = ({ buttons }: ActionButtonProps) => { return ( {buttons.map((button) => { - return ; + return ( + + ); })} ); diff --git a/src/components/ReviewField.tsx b/src/components/ReviewField.tsx index 6832c3c..a4eac8c 100644 --- a/src/components/ReviewField.tsx +++ b/src/components/ReviewField.tsx @@ -1,15 +1,41 @@ -import { Box, Grid2, TextField } from "@mui/material"; -import React from "react"; +import { Box, Stack, TextField } from "@mui/material"; +import React, { useState } from "react"; + +export interface ReviewFieldProps { + name: string; + dynamicState: [string, React.Dispatch>]; + variant?: "outlined" | "filled" | "standard"; + help?: string; +} + +interface ReviewFieldOpts { + fields: ReviewFieldProps[]; +} + +const ReviewField = ({ fields }: ReviewFieldOpts) => { -const ReviewField = () => { return ( - - - - - - + + { + fields.map((field) => { + return ( + { + field.dynamicState[1](target.value); + })} + variant={field.variant ?? "outlined"} + helperText={field.help} + autoComplete="off" + /> + ) + }) + } + ); };