diff --git a/mock/db.json b/mock/db.json new file mode 100644 index 0000000..6b1251a --- /dev/null +++ b/mock/db.json @@ -0,0 +1,12 @@ +{ + "cadastro-van": [ + { + "id": 1, + "placa": "DBE2356", + "marca": "Fiat", + "modelo": "Ducatto", + "numPassageiros": 14, + "alugado": false + } + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7300e4a..10c66fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13336,6 +13336,21 @@ "react": "^16.8.0 || ^17 || ^18" } }, + "node_modules/react-hook-form": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.30.0.tgz", + "integrity": "sha512-DzjiM6o2vtDGNMB9I4yCqW8J21P314SboNG1O0obROkbg7KVS0I7bMtwSdKyapnCPjHgnxc3L7E5PEdISeEUcQ==", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -20219,6 +20234,14 @@ "follow-redirects": "^1.14.8" } }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -26462,6 +26485,12 @@ "integrity": "sha512-DzjiM6o2vtDGNMB9I4yCqW8J21P314SboNG1O0obROkbg7KVS0I7bMtwSdKyapnCPjHgnxc3L7E5PEdISeEUcQ==", "requires": {} }, + "react-hook-form": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.30.0.tgz", + "integrity": "sha512-DzjiM6o2vtDGNMB9I4yCqW8J21P314SboNG1O0obROkbg7KVS0I7bMtwSdKyapnCPjHgnxc3L7E5PEdISeEUcQ==", + "requires": {} + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index 39f79ee..7fbbf73 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ }, "scripts": { "start": "react-scripts start", + "start:mock": "json-server --port 8080 --watch ./mock/db.json", "build": "react-scripts build", "test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons)/)'", "eject": "react-scripts eject" diff --git a/src/App.tsx b/src/App.tsx index d2d3f4d..bae94ce 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,10 +10,11 @@ import { setupIonicReact } from '@ionic/react'; import { IonReactRouter } from '@ionic/react-router'; -import Cadastro from './pages/Cadastro/Cadastro'; // importação das páginas import Login from './pages/Login'; +import Cadastro from './pages/Cadastro/Cadastro'; +import CadastroVan from './pages/CadastroVan'; /* Core CSS required for Ionic components to work properly */ import '@ionic/react/css/core.css'; @@ -49,6 +50,7 @@ const routes = ( + diff --git a/src/models/van.model.ts b/src/models/van.model.ts new file mode 100644 index 0000000..ae90e2b --- /dev/null +++ b/src/models/van.model.ts @@ -0,0 +1,8 @@ +export type Van = { + id: number; + carPlate: string; + carBrand: string; + carModel: string; + maxPassengers: number; + isRent: string; +}; diff --git a/src/pages/CadastroVan.css b/src/pages/CadastroVan.css new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/CadastroVan.tsx b/src/pages/CadastroVan.tsx new file mode 100644 index 0000000..4fec045 --- /dev/null +++ b/src/pages/CadastroVan.tsx @@ -0,0 +1,347 @@ +import { + IonToast, + IonItem, + IonLabel, + IonInput, + IonBackButton, + IonButton, + IonButtons, + IonCardTitle, + IonContent, + IonHeader, + IonPage, + IonToolbar, + IonTitle, + IonText, + IonRadioGroup, + IonRadio +} from "@ionic/react"; + +import React, { useState } from "react"; + +import { ApiClient } from "../services/api-client.service"; +import { arrowBack } from "ionicons/icons"; +import "./CadastroVan.css"; + + +const CadastroVan: React.FC = () => { + + const [showToast, setShowToast] = useState(false); + const [toastMessage, setToastMessage] = useState(""); + + const [carPlate, setCarPlate] = useState(""); + const [carBrand, setCarBrand] = useState(""); + const [carModel, setCarModel] = useState(""); + const [maxPassengers, setMaxPassengers] = useState(1); + const [isRent, setIsRent] = useState(false); + const [carRentalName, setCarRentalName] = useState(""); + const [postalCode, setPostalCode] = useState(""); + const [street, setStreet] = useState(""); + const [number, setNumber] = useState(""); + const [complement, setComplement] = useState(""); + const [city, setCity] = useState(""); + const [state, setState] = useState(""); + + const vanForm = { + carPlate, + carBrand, + carModel, + maxPassengers, + isRent, + carRentalName, + carRentalAddress: { + postalCode, + street, + number, + complement, + city, + state + } + }; + + const clearRentalData = () => { + setCarRentalName(""); + setPostalCode(""); + setStreet(""); + setNumber(""); + setComplement(""); + setCity(""); + setState(""); + }; + + const validateForm = (): boolean => { + if ( + !vanForm.carPlate || + vanForm.carPlate.length !== 7 || + !vanForm.carPlate.match(/([A-z0-9]){7}/g) + ) { + setToastMessage("Placa do veículo inválida!"); + setShowToast(true); + return false; + } + + if (!vanForm.carBrand) { + setToastMessage("Marca do veículo é obrigatório"); + setShowToast(true); + return false; + } + + if (!vanForm.carModel) { + setToastMessage("Modelo do veículo é obrigatório"); + setShowToast(true); + return false; + } + + if (!vanForm.maxPassengers || !parseInt(`${vanForm.maxPassengers}`)) { + setToastMessage("Número de passageiros inválido"); + setShowToast(true); + return false; + } + + if (vanForm.isRent) { + return validateRentalForm(); + } else { + clearRentalData(); + } + + return true; + }; + + const validateRentalForm = (): boolean => { + if (!vanForm.carRentalName) { + setToastMessage("Nome do Locador é obrigatório"); + setShowToast(true); + return false; + } + + if ( + !vanForm.carRentalAddress.postalCode || + vanForm.carRentalAddress.postalCode.length !== 8 || + !vanForm.carRentalAddress.postalCode.match(/([0-9]){8}/g) + ) { + setToastMessage("Cep inválido"); + setShowToast(true); + return false; + } + + if ( + !vanForm.carRentalAddress.number || + !parseInt(`${vanForm.carRentalAddress.number}`) + ) { + setToastMessage("Número inválido"); + setShowToast(true); + return false; + } + + if ( + !vanForm.carRentalAddress.city || + !vanForm.carRentalAddress.city.match(/([A-zà-úÀ-Ú])/g) + ) { + setToastMessage("Cidade inválido"); + setShowToast(true); + return false; + } + + if ( + !vanForm.carRentalAddress.state || + !vanForm.carRentalAddress.state.match(/([A-zà-úÀ-Ú])/g) + ) { + setToastMessage("Estado inválido"); + setShowToast(true); + return false; + } + + return true; + }; + + const handleSubmit = async () => { + if (validateForm()) { + await ApiClient.doPost("/cadastro-van", vanForm); + } + }; + + return ( + + + + VanMos App v1.0 + + + Return + + + + + + + + Cadastro do Veículo + + + Placa * + setCarPlate(e.target.value)} + /> + + + + Marca * + setCarBrand(e.target.value)} + /> + + + + Modelo * + setCarModel(e.target.value)} + /> + + + + + Número Máximo de Passageiros * + + setMaxPassengers(e.target.value)} + /> + + + + + + Veículo alugado? + + + setIsRent(e.target.value)} + > + + Sim + + + + + Não + + + + + + + + {isRent && ( + + + Nome do Locador * + setCarRentalName(e.target.value)} + /> + + + + Endereço do Locador + + + CEP* + setPostalCode(e.target.value)} + /> + + + Logradouro* + setStreet(e.target.value)} + /> + + + + Número* + setNumber(e.target.value)} + /> + + + + Complemento* + setComplement(e.target.value)} + /> + + + + Cidade* + setCity(e.target.value)} + /> + + + + Estado* + setState(e.target.value)} + /> + + + + )} + + + + Salvar + + + + setShowToast(false)} + message={toastMessage} + duration={2500} + /> + + + ); +}; + +export default CadastroVan; diff --git a/src/services/api-client.service.ts b/src/services/api-client.service.ts new file mode 100644 index 0000000..970a8f3 --- /dev/null +++ b/src/services/api-client.service.ts @@ -0,0 +1,18 @@ +import axios from "axios"; + +export class ApiClient{ + private static api = axios.create({ + baseURL: "http://localhost:8080" + }); + + public static async doPost (url: string, body: any): Promise { + return await this.api + .post(url, body) + .then(res => { + console.log(res.data); + }) + .catch(error => { + console.log(error); + }); + }; +} \ No newline at end of file