npm run dev
VITE_ENVIRONMENT = development
const environment = import.meta.env.VITE_ENVIRONMENT;
"dev": "run-p api frontend","api": "json-server --watch ./src/data/db.json --port 4801","frontend": "vite --port 4800 --open",
et711-react-forms-site
(use your own name so you can publish it one-to-one at Vercel)npm i
npm run dev
<title>React Forms</title>
<h1 className="text-3xl mb-3 text-slate-800">React Forms</h1>
export const PageSimpleForm = () => {return (<p>this will be the simple form</p>);};
<li><NavLink to="/simple-form">Simple Form</NavLink></li>
{path: "/simple-form",element: <PageSimpleForm />,},{path: "/",element: <Navigate to="/simple-form" replace />,},
import { FormEvent } from "react";export const PageSimpleForm = () => {const handleFormSubmit = (event: FormEvent<HTMLFormElement>) => {event.preventDefault();const data = new FormData(event.target as HTMLFormElement);console.log(data);};return (<form onSubmit={handleFormSubmit}><fieldset className="border border-gray-500 p-4 w-full sm:w-40 rounded"><legend>New Employee</legend><div className="mb-4 flex gap-2"><label className="w-[10rem]" htmlFor="firstName">First Name:</label><inputtype="text"id="firstName"name="firstName"required/></div><div className="mb-4 flex gap-2"><label className="w-[10rem]" htmlFor="lastName">Last Name:</label><input type="text" id="lastName" name="lastName" required /></div><div className="mb-4 flex gap-2"><label className="w-[10rem]" htmlFor="age">Age:</label><input type="number" id="age" name="age" required /></div><div className="mb-4 flex gap-2"><label className="w-[10rem]" htmlFor="hireDate" >Hire Date:</label><input type="date" id="hireDate" name="hireDate" required /></div><div className="mb-4 flex gap-2"><label className="w-[10rem]" htmlFor="employeeNumber">Employee Number:</label><div><inputtype="text"id="employeeNumber"name="employeeNumber"pattern="^[DSM]-\d{4}$"required/><p className="text-sm">e.g. D-2832, S-7771, M-8123</p></div></div><div className="mb-4 flex gap-2"><label className="w-[10rem]" htmlFor="notes" >Notes:</label><textarea id="notes" name="notes"></textarea></div><div className="mt-5 flex justify-end pr-3"><button>Add Employee</button></div></fieldset></form>);};
{"employees": []}
npm i -D json-server
npm i -D npm-run-all
"dev": "run-p api frontend","api": "json-server --watch ./src/data/db.json --port 4801","frontend": "vite --port 4800 --open",
npm run dev
@url = http://localhost:4801### GET ALL EMPLOYEES{{url}}/employees### ADD AN EMPLOYEEPOST {{url}}/employeescontent-type: application/json{"firstName": "James","lastName": "Tester","age": 55,"hireDate": "2020-01-01","employeeNumber": "D-8811"}
npm i axios
import { FormEvent } from "react";import axios, { AxiosResponse } from "axios";import { useNavigate } from "react-router-dom";export const PageSimpleForm = () => {const navigate = useNavigate();const handleFormSubmit = (event: FormEvent<HTMLFormElement>) => {event.preventDefault();const formData = new FormData(event.target as HTMLFormElement);const employee = JSON.stringify(Object.fromEntries(formData));(async () => {const headers = {"Access-Control-Allow-Origin": "*","Content-Type": "application/json",};try {const response: AxiosResponse = await axios.post("http://localhost:4801/employees",employee,{ headers });if (response.status === 201) {navigate('/employees');} else {console.log(`ERROR: ${response.status}`);}} catch (error: any) {console.log(`ERROR: ${error.message}`);}})();};
export const PageEmployees = () => {return (<p>This is the employees page.</p>)}
<NavLink to="/employees">Employees</NavLink>
{path: "employees",element: <PageEmployees />,},
export interface IEmployee {id: number;firstName: string;lastName: string;age: number;hireDate: string;employeeNumber: string;notes: string;}
import { useState, useEffect } from "react";import { IEmployee } from "../interfaces";import axios from "axios";const url = "http://localhost:4801";export const PageEmployees = () => {const [employees, setEmployees] = useState<IEmployee[]>([]);useEffect(() => {(async () => {setEmployees((await axios.get(`${url}/employees`)).data);})();}, []);return (<>{employees.length === 0 ? (<p>Loading...</p>) : (<><p>There are {employees.length} employees.</p><div className="relative overflow-x-auto mt-4 rounded w-1/2"><table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400"><thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"><tr><th scope="col" className="px-6 py-3">ID</th><th scope="col" className="px-6 py-3">First Name</th><th scope="col" className="px-6 py-3">Last Name</th><th scope="col" className="px-6 py-3">Age</th><th scope="col" className="px-6 py-3">Hire Date</th><th scope="col" className="px-6 py-3">Employee Number</th><th scope="col" className="px-6 py-3">Notes</th></tr></thead><tbody>{employees.map((employee) => {return (<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700"><td className="px-6 py-4">{employee.id}</td><td className="px-6 py-4">{employee.firstName}</td><td className="px-6 py-4">{employee.lastName}</td><td className="px-6 py-4">{employee.age}</td><td className="px-6 py-4">{employee.hireDate}</td><td className="px-6 py-4">{employee.employeeNumber}</td><td className="px-6 py-4">{employee.notes}</td></tr>);})}</tbody></table></div></>)}</>);};
import db from '../data/db.json';const employees = db.employees;
VITE_ENVIRONMENT = development
.env
export const environment = import.meta.env.VITE_ENVIRONMENT;
import * as config from "../config";<p>environment is: [{config.environment}]</p>
VITE_ENVIRONMENT = nnn
{config.environment === "development" && (<li><NavLink to="/simple-form">Simple Form</NavLink></li>)}
VITE_ENVIRONMENT = development
element: config.environment === 'development' ? <Navigate to="/simple-form" replace /> : <Navigate to="/employees" replace />,