diff --git a/src/App.tsx b/src/App.tsx index 1e440ab..375a829 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,17 +26,9 @@ function App() { /> - } - /> - } + element={} /> + } /> ); } diff --git a/src/components/ButtonRow.tsx b/src/components/ButtonRow.tsx index 5d64038..0abdbb5 100644 --- a/src/components/ButtonRow.tsx +++ b/src/components/ButtonRow.tsx @@ -13,10 +13,7 @@ interface ActionButtonProps { const ButtonRow = ({ buttons }: ActionButtonProps) => { return ( - + {buttons.map((button) => { return ( >; } -const EndpointDialog = ({ endpoint, setEndpoint, secure, setSecure }: EndpointDialogProps) => { +const EndpointDialog = ({ + endpoint, + setEndpoint, + secure, + setSecure, +}: EndpointDialogProps) => { const [open, setOpen] = useState(false); const [error, setError] = useState(false); const [errorText, setErrorText] = useState(""); @@ -45,27 +50,23 @@ const EndpointDialog = ({ endpoint, setEndpoint, secure, setSecure }: EndpointDi const showTheError = () => { setErrorText('Please omit "http://" or "https://" from the endpoint.'); setError(true); - } - + }; + const closeTheError = () => { setErrorText(""); setError(false); - } + }; const isValidEndpoint = () => { return !(endpoint.startsWith("http://") || endpoint.startsWith("https://")); - } + }; const saveEndpoint = () => { localStorage.setItem("apiEndpoint", JSON.stringify(endpoint)); - } + }; const settingsButton = ( - + @@ -76,10 +77,7 @@ const EndpointDialog = ({ endpoint, setEndpoint, secure, setSecure }: EndpointDi <> {settingsButton} - + Endpoint URL { setEndpoint(target.value); - isValidEndpoint() - ? closeTheError() - : showTheError(); + isValidEndpoint() ? closeTheError() : showTheError(); }} placeholder="localhost:8080" error={error} @@ -103,31 +99,32 @@ const EndpointDialog = ({ endpoint, setEndpoint, secure, setSecure }: EndpointDi setSecure(!secure)} - /> + setSecure(!secure)} /> } label="HTTPS" /> - { - if (isValidEndpoint()) { - closeSettings(); - closeTheError(); - saveEndpoint(); + if (isValidEndpoint()) { + closeSettings(); + closeTheError(); + saveEndpoint(); - const fullUri = `${secure ? "https" : "http"}://${endpoint}`; + const fullUri = `${secure ? "https" : "http"}://${endpoint}`; - console.log(`Endpoint set to ${fullUri}.\n\nPOST URI: ${fullUri}/post\nGET URI: ${fullUri}/reviews`); - } else { - showTheError(); - } - }}>Set + console.log( + `Endpoint set to ${fullUri}.\n\nPOST URI: ${fullUri}/post\nGET URI: ${fullUri}/reviews`, + ); + } else { + showTheError(); + } + }} + > + Set + > diff --git a/src/components/PageSwitcher.tsx b/src/components/PageSwitcher.tsx index e13af79..85b1a7e 100644 --- a/src/components/PageSwitcher.tsx +++ b/src/components/PageSwitcher.tsx @@ -1,19 +1,15 @@ -import { Button, ButtonGroup, Tooltip, Zoom } from '@mui/material'; -import React, { useEffect, useState } from 'react' -import { Link } from 'react-router-dom'; +import { Button, ButtonGroup, Tooltip, Zoom } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; function PageSwitcher() { const [selected, changeSelected] = useState(0); useEffect(() => { changeSelected(document.location.pathname === "/" ? 0 : 1); - }) + }); const postReviewsButton = ( - + changeSelected(0)} @@ -43,7 +39,7 @@ function PageSwitcher() { ); return ( - + {postReviewsButton} {seeReviewsButton} diff --git a/src/components/ReviewField.tsx b/src/components/ReviewField.tsx index cba50f4..ed26d43 100644 --- a/src/components/ReviewField.tsx +++ b/src/components/ReviewField.tsx @@ -17,7 +17,7 @@ interface ReviewFieldOpts { const ReviewField = ({ fields }: ReviewFieldOpts) => { return ( - + {fields.map((field) => { const [errorText, setErrorText] = useState(""); @@ -26,12 +26,12 @@ const ReviewField = ({ fields }: ReviewFieldOpts) => { const showTheError = () => { setErrorText(field.errorText); setError(true); - } + }; const hideTheError = () => { setErrorText(""); setError(false); - } + }; return ( { value={field.dynamicState[0]} multiline={field.expandable ?? false} onChange={({ target }) => { - field.dynamicState[1](target.value.length <= field.maxLength ? target.value : field.dynamicState[0]); + field.dynamicState[1]( + target.value.length <= field.maxLength + ? target.value + : field.dynamicState[0], + ); field.validateInput(field.dynamicState[0]) ? hideTheError() diff --git a/src/components/ShowReviews.tsx b/src/components/ShowReviews.tsx index ef5f036..002407a 100644 --- a/src/components/ShowReviews.tsx +++ b/src/components/ShowReviews.tsx @@ -1,6 +1,14 @@ -import { List, ListItem, ListItemText, Paper, Rating, Slide, Typography } from "@mui/material"; +import { + List, + ListItem, + ListItemText, + Paper, + Rating, + Slide, + Typography, +} from "@mui/material"; import { ServerSideReview } from "../types"; -import React from 'react' +import React from "react"; export interface ShowReviewsProps { reviews: ServerSideReview[]; @@ -12,7 +20,7 @@ function ShowReviews({ reviews }: ShowReviewsProps) { <> No reviews yet... @@ -21,22 +29,17 @@ function ShowReviews({ reviews }: ShowReviewsProps) { } return ( - + {reviews.map((review, index) => { return ( - - - + + + {review.username} @@ -46,7 +49,7 @@ function ShowReviews({ reviews }: ShowReviewsProps) { {new Date(review.timestamp).toLocaleString()} @@ -54,7 +57,11 @@ function ShowReviews({ reviews }: ShowReviewsProps) { {review.title} @@ -62,16 +69,17 @@ function ShowReviews({ reviews }: ShowReviewsProps) { {review.content} - - > + + > } /> diff --git a/src/main.tsx b/src/main.tsx index 18fc383..8949425 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -16,5 +16,5 @@ const theme = createTheme({ createRoot(document.getElementById("root")!).render( - + , ); diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 7f55f2d..67bc5cf 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,4 +1,13 @@ -import { Alert, Button, Dialog, DialogActions, DialogContent, Grow, Rating, Typography } from "@mui/material"; +import { + Alert, + Button, + Dialog, + DialogActions, + DialogContent, + Grow, + Rating, + Typography, +} from "@mui/material"; import "../App.css"; import ButtonRow, { ActionProps } from "../components/ButtonRow"; import ReviewField, { ReviewFieldProps } from "../components/ReviewField"; @@ -28,14 +37,14 @@ function Home({ endpoint, setEndpoint, secure, setSecure }: HomeProps) { dynamicState: useState(""), validateInput: ({ length }) => length >= 2 && length <= 30, errorText: "Name must be at least 2 characters", - maxLength: 30 + maxLength: 30, }, { name: "Title", dynamicState: useState(""), validateInput: ({ length }) => !length || length <= 50, errorText: "Title must be less than 50 characters", - maxLength: 50 + maxLength: 50, }, { name: "Content", @@ -43,7 +52,7 @@ function Home({ endpoint, setEndpoint, secure, setSecure }: HomeProps) { expandable: true, validateInput: ({ length }) => !length || length <= 2000, errorText: "Content must be less than 2000 characters", - maxLength: 2000 + maxLength: 2000, }, ]; @@ -71,22 +80,27 @@ function Home({ endpoint, setEndpoint, secure, setSecure }: HomeProps) { return; } - await fetch(endpoint ? `${secure ? "https" : "http"}://${endpoint}/post` : "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], - }), - }) + await fetch( + endpoint + ? `${secure ? "https" : "http"}://${endpoint}/post` + : "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(async (response) => { const result = await response.json(); if (result.error) { changeAlertText(`${result.error.type}: ${result.error.message}`); changeAlert(true); - + setTimeout(() => { changeAlert(false); }, 2000); @@ -94,11 +108,10 @@ function Home({ endpoint, setEndpoint, secure, setSecure }: HomeProps) { changeInfoText(`Success: ${result.message}`); changeInfo(true); - setTimeout(() => { changeInfo(false); }, 2000); - } + } }) .catch((err) => { changeAlertText(err.toString()); @@ -112,16 +125,14 @@ function Home({ endpoint, setEndpoint, secure, setSecure }: HomeProps) { }; const getEmptyFields = () => { - return ( - !endpoint - ? "Endpoint is not set!" - : !rating - ? "You must input a rating!" - : fields[0].dynamicState[0].length < 2 - ? "You must enter a username at least 2 characters long!" - : "" - ); - } + return !endpoint + ? "Endpoint is not set!" + : !rating + ? "You must input a rating!" + : fields[0].dynamicState[0].length < 2 + ? "You must enter a username at least 2 characters long!" + : ""; + }; const buttons: ActionProps[] = [ { @@ -159,9 +170,9 @@ function Home({ endpoint, setEndpoint, secure, setSecure }: HomeProps) { precision={0.5} size="large" value={rating} - sx={{marginTop: "10px"}} + sx={{ marginTop: "10px" }} onChange={(event, newRating) => { - event + event; setNewRating(newRating); }} /> @@ -170,10 +181,7 @@ function Home({ endpoint, setEndpoint, secure, setSecure }: HomeProps) { - + {alert} @@ -183,21 +191,13 @@ function Home({ endpoint, setEndpoint, secure, setSecure }: HomeProps) { - showModal(false)} - > + showModal(false)}> - - {getEmptyFields()} - + {getEmptyFields()} - showModal(false)} - > + showModal(false)}> Ok diff --git a/src/pages/NotFound.tsx b/src/pages/NotFound.tsx index 4bd981c..5d646ca 100644 --- a/src/pages/NotFound.tsx +++ b/src/pages/NotFound.tsx @@ -4,21 +4,15 @@ import { Link } from "react-router-dom"; function NotFound() { return ( - - Not found - + Not found - + Back to home - ) + ); } export default NotFound; diff --git a/src/pages/ReviewsPage.tsx b/src/pages/ReviewsPage.tsx index 2be8f25..6db64cc 100644 --- a/src/pages/ReviewsPage.tsx +++ b/src/pages/ReviewsPage.tsx @@ -1,10 +1,16 @@ -import { CircularProgress, IconButton, Tooltip, Typography, Zoom } from '@mui/material'; +import { + CircularProgress, + IconButton, + Tooltip, + Typography, + Zoom, +} from "@mui/material"; import RefreshIcon from "@mui/icons-material/Refresh"; -import PageSwitcher from '../components/PageSwitcher'; +import PageSwitcher from "../components/PageSwitcher"; import "../index.css"; -import ShowReviews from '../components/ShowReviews'; -import { ServerSideReview } from '../types'; -import { useEffect, useState } from 'react'; +import ShowReviews from "../components/ShowReviews"; +import { ServerSideReview } from "../types"; +import { useEffect, useState } from "react"; interface ReviewsPageProps { endpoint: string; @@ -24,31 +30,27 @@ function ReviewsPage({ endpoint, secure }: ReviewsPageProps) { setStatusText("Loading..."); setStatusTextColor("rgb(140, 140, 140)"); - await fetch(endpoint ? `${secure ? "https" : "http"}://${endpoint}/reviews` : "http://localhost:8080/reviews") - .then(async r => { + await fetch( + endpoint + ? `${secure ? "https" : "http"}://${endpoint}/reviews` + : "http://localhost:8080/reviews", + ) + .then(async (r) => { const response: ServerSideReview[] = await r.json(); setCurrentReviews(response.reverse()); setStatusText(""); setLoading(false); - }) - .catch(err => { + }) + .catch((err) => { setStatusText(err.toString()); setStatusTextColor("rgb(250, 20, 0)"); - }); - + }); }; const refreshButton = ( - - + + @@ -56,29 +58,26 @@ function ReviewsPage({ endpoint, secure }: ReviewsPageProps) { useEffect(() => { loadReviews(); - }, []) + }, []); return ( <> - {loading - ? - : refreshButton - } + {loading ? : refreshButton} - - Simple Review Client - + Simple Review Client - {loading - ? - {statusText} - - : } + {loading ? ( + + {statusText} + + ) : ( + + )} > );