Skip to content

Commit

Permalink
Forms (#113)
Browse files Browse the repository at this point in the history
* description: text -> textarea

* fix Password label on Login

* fix login label

* refactor new/edit robot logic

* Semantic improvements to RobotForm

* format

* refactor Parts form

* remove unnecessary Row from RobotForm

* get rid of prop validation

typescript is strictly stronger

* Slight improvements to form UI
  • Loading branch information
chennisden authored Jun 12, 2024
1 parent b74144a commit 91e8906
Show file tree
Hide file tree
Showing 10 changed files with 309 additions and 447 deletions.
1 change: 1 addition & 0 deletions frontend/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default [
rules: {
...pluginReactConfig.rules,
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
},
}),
];
21 changes: 9 additions & 12 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,14 @@ body {
transition: color 0.1s ease;
}

/* .custom-button {
color: var(--button-color);
background-color: var(--button-bg-color);
border-color: var(--button-border-color);
padding: 10px;
width: 100%;
transition: all 0.3s ease;
form {
max-width: 500px;
}

form textarea {
height: 10rem;
}

.custom-button:hover {
color: var(--button-hover-color);
background-color: var(--button-hover-bg-color);
border-color: var(--button-hover-border-color);
} */
form button {
width: 100%;
}
8 changes: 4 additions & 4 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import EditRobotForm from "pages/EditRobotForm";
import Home from "pages/Home";
import Login from "pages/Login";
import Logout from "pages/Logout";
import NewPart from "pages/NewPart";
import NewRobot from "pages/NewRobot";
import NotFound from "pages/NotFound";
import PartDetails from "pages/PartDetails";
import PartForm from "pages/PartForm";
import Parts from "pages/Parts";
import Register from "pages/Register";
import RobotDetails from "pages/RobotDetails";
import RobotForm from "pages/RobotForm";
import Robots from "pages/Robots";
import VerifyEmail from "pages/VerifyEmail";
import YourParts from "pages/YourParts";
Expand Down Expand Up @@ -46,8 +46,8 @@ const App = () => {
/>
<Route path="/logout" element={<Logout />} />
<Route path="/robots/" element={<Robots />} />
<Route path="/robots/add" element={<RobotForm />} />
<Route path="/parts/add" element={<PartForm />} />
<Route path="/robots/add" element={<NewRobot />} />
<Route path="/parts/add" element={<NewPart />} />
<Route path="/robot/:id" element={<RobotDetails />} />
<Route path="/edit-robot/:id" element={<EditRobotForm />} />
<Route path="/parts/" element={<Parts />} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
import { api, Image, Part } from "hooks/api";
import { useAuthentication } from "hooks/auth";
import React, { ChangeEvent, FormEvent, useState } from "react";
import { Image } from "hooks/api";
import { ChangeEvent, Dispatch, FormEvent, SetStateAction } from "react";
import { Button, Col, Form, Row } from "react-bootstrap";
import { useNavigate } from "react-router-dom";

const PartForm: React.FC = () => {
const auth = useAuthentication();
const auth_api = new api(auth.api);
const [message, setMessage] = useState<string | null>(null);
const [part_name, setName] = useState<string>("");
const [part_description, setDescription] = useState<string>("");
const [part_images, setImages] = useState<Image[]>([]);
interface PartFormProps {
title: string;
message: string;
part_name: string;
setName: Dispatch<SetStateAction<string>>;
part_description: string;
setDescription: Dispatch<SetStateAction<string>>;
part_images: Image[];
setImages: Dispatch<SetStateAction<Image[]>>;
handleSubmit: (event: FormEvent<HTMLFormElement>) => void;
}

const PartForm: React.FC<PartFormProps> = ({
title,
message,
part_name,
setName,
part_description,
setDescription,
part_images,
setImages,
handleSubmit,
}) => {
const handleImageChange = (
index: number,
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
Expand All @@ -30,73 +43,53 @@ const PartForm: React.FC = () => {
const newImages = part_images.filter((_, i) => i !== index);
setImages(newImages);
};
const navigate = useNavigate();
const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (part_images.length === 0) {
setMessage("Please upload at least one image.");
return;
}
const newFormData: Part = {
part_id: "",
part_name: part_name,
description: part_description,
owner: "Bob",
images: part_images,
};
try {
await auth_api.addPart(newFormData);
setMessage(`Part added successfully.`);
navigate("/parts/your/");
} catch (error) {
setMessage("Error adding Part ");
}
};

return (
<Row>
<h2>Add a New Part</h2>
<>
<h1>{title}</h1>
{message && <p>{message}</p>}
<Form onSubmit={handleSubmit} className="mb-3">
Name:
<label htmlFor="name">Name</label>
<Form.Control
id="name"
className="mb-3"
type="text"
placeholder="Part Name:"
onChange={(e) => {
setName(e.target.value);
}}
value={part_name}
required
/>
Description:
<label htmlFor="desc">Description</label>
<Form.Control
id="desc"
className="mb-3"
type="text"
placeholder="Part Description:"
as="textarea"
onChange={(e) => {
setDescription(e.target.value);
}}
value={part_description}
required
/>
Images:
<h2>Images</h2>
{part_images.map((image, index) => (
<Row key={index} className="mb-3">
<Col md={12}>
<label htmlFor={"url-" + index}>URL</label>
<Form.Control
id={"url-" + index}
className="mb-1"
type="text"
placeholder="Image URL"
name="url"
value={image.url}
onChange={(e) => handleImageChange(index, e)}
required
/>
<label htmlFor={"caption-" + index}>Caption</label>
<Form.Control
id={"caption-" + index}
className="mb-1"
type="text"
placeholder="Image Caption"
name="caption"
value={image.caption}
onChange={(e) => handleImageChange(index, e)}
Expand All @@ -105,8 +98,7 @@ const PartForm: React.FC = () => {
</Col>
<Col md={12}>
<Button
className="mb-3"
size="sm"
className="mt-2 mb-2"
variant="danger"
onClick={() => handleRemoveImage(index)}
>
Expand All @@ -115,17 +107,16 @@ const PartForm: React.FC = () => {
</Col>
</Row>
))}
<Col md={6}>
<Button className="mb-3" variant="primary" onClick={handleAddImage}>
<Col md={12}>
<Button className="mb-3" variant="secondary" onClick={handleAddImage}>
Add Image
</Button>
</Col>
Submit:
<Col md={6}>
<Button type="submit">Add Part!</Button>
<Col md={12}>
<Button type="submit">Submit</Button>
</Col>
</Form>
</Row>
</>
);
};

Expand Down
Loading

0 comments on commit 91e8906

Please sign in to comment.