diff --git a/package-lock.json b/package-lock.json
index d1f2d4d..cfefa06 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "better-tictactoe-front-end",
"version": "0.1.0",
"dependencies": {
+ "@tanstack/react-query": "^5.90.9",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@@ -3399,6 +3400,32 @@
"url": "https://github.com/sponsors/gregberge"
}
},
+ "node_modules/@tanstack/query-core": {
+ "version": "5.90.9",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.9.tgz",
+ "integrity": "sha512-UFOCQzi6pRGeVTVlPNwNdnAvT35zugcIydqjvFUzG62dvz2iVjElmNp/hJkUoM5eqbUPfSU/GJIr/wbvD8bTUw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.90.9",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.9.tgz",
+ "integrity": "sha512-Zke2AaXiaSfnG8jqPZR52m8SsclKT2d9//AgE/QIzyNvbpj/Q2ln+FsZjb1j69bJZUouBvX2tg9PHirkTm8arw==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-core": "5.90.9"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19"
+ }
+ },
"node_modules/@testing-library/dom": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz",
@@ -19048,6 +19075,19 @@
"loader-utils": "^2.0.0"
}
},
+ "@tanstack/query-core": {
+ "version": "5.90.9",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.9.tgz",
+ "integrity": "sha512-UFOCQzi6pRGeVTVlPNwNdnAvT35zugcIydqjvFUzG62dvz2iVjElmNp/hJkUoM5eqbUPfSU/GJIr/wbvD8bTUw=="
+ },
+ "@tanstack/react-query": {
+ "version": "5.90.9",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.9.tgz",
+ "integrity": "sha512-Zke2AaXiaSfnG8jqPZR52m8SsclKT2d9//AgE/QIzyNvbpj/Q2ln+FsZjb1j69bJZUouBvX2tg9PHirkTm8arw==",
+ "requires": {
+ "@tanstack/query-core": "5.90.9"
+ }
+ },
"@testing-library/dom": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz",
diff --git a/package.json b/package.json
index 704ad45..0be4797 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "@tanstack/react-query": "^5.90.9",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
diff --git a/src/App.tsx b/src/App.tsx
index ec0b7f1..90bdbe8 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,16 +1,18 @@
import { Routes, Route, Outlet, Link } from "react-router-dom";
+import CheckAgeForm from "./pages/CheckAgeForm";
import { CheckName } from './pages/CheckName';
import { Home } from './pages/Home';
export default function App() {
return (
-
- }>
- } />
- } />
- } />
-
-
+
+ }>
+ } />
+ } />
+ } />
+ } />
+
+
);
}
@@ -25,6 +27,9 @@ function Layout() {
Check Name
+
+ Check age form
+
@@ -45,4 +50,4 @@ function NoMatch() {
);
-}
\ No newline at end of file
+}
diff --git a/src/index.tsx b/src/index.tsx
index 2edb089..da9b5c5 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -3,13 +3,23 @@ import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from "react-router-dom";
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+
+const queryClient = new QueryClient()
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
-root.render();
+
+root.render(
+
+
+
+
+
+);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
-reportWebVitals();
\ No newline at end of file
+reportWebVitals();
diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts
index 0f5b798..4768f6c 100644
--- a/src/interfaces/index.ts
+++ b/src/interfaces/index.ts
@@ -3,7 +3,7 @@ interface ValidationError {
property: string;
value?: any;
constraints?: {
- [type: string]: string;
+ [type: string]: string;
};
children?: ValidationError[];
contexts?: {
@@ -31,3 +31,12 @@ interface BaseResponseError extends BaseResponseInteface {
}
export type BaseResponse = BaseResponseSuccess | BaseResponseError;
+
+
+export type FormState = {
+ name: string
+ age: number
+ married?: boolean
+ dateOfBirth: Date
+}
+
diff --git a/src/pages/CheckAgeForm.tsx b/src/pages/CheckAgeForm.tsx
new file mode 100644
index 0000000..558aa06
--- /dev/null
+++ b/src/pages/CheckAgeForm.tsx
@@ -0,0 +1,150 @@
+import { useMutation, useQuery } from "@tanstack/react-query";
+import { useState } from "react";
+import { BaseResponse, FormState } from "../interfaces";
+
+
+const CheckAgeForm = () => {
+ const [form, setForm] = useState({
+ name: "",
+ age: 0,
+ dateOfBirth: new Date()
+ })
+ const validate = useMutation({
+ mutationFn: async (data: FormState): Promise => {
+ const res = await fetch('http://localhost:3001/info/validate-form', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ ...data
+ })
+ })
+
+ // TODO: usare axios o altre librerie per avere un minimo di typesafety, qui sto pregando che il risultato sia quello che mi aspetto e sinceramente non so se dia errore fino a quando non prova a chiamare un oggetto annidato
+ const resData: BaseResponse = await res.json()
+ console.log(resData)
+ return resData
+ }
+ })
+
+ const handleSand = async () => {
+ await validate.mutateAsync({
+ ...form
+ })
+ }
+ const handleReset = () => {
+ validate.reset()
+ setForm({
+ name: "",
+ age: 0,
+ dateOfBirth: new Date()
+ })
+ }
+
+ const isAbove18 = form.age >= 18
+
+ if (validate.isError) {
+ return (
+
+
ERRORE INVIO DATI
+
+
+ );
+ }
+
+ if (validate.isPending) {
+ return (
+
+
INVIO IN CORSO
+
+
+ );
+ }
+
+ if (validate.isSuccess) {
+ return (
+
+ {validate.data?.success === true &&
DATI INVIATI VALIDI
}
+ {validate.data?.success === false && DATI INVIATI NON VALIDI
}
+
+
+ );
+ }
+
+
+ return (
+
+ {
+ setForm((prev) => {
+ return {
+ ...prev,
+ name: e.target.value
+ }
+ });
+ }}
+ />
+
+ {
+ setForm((prev) => {
+ const age = Number.parseInt(e.target.value) ?? 0
+ return {
+ ...prev,
+ age
+ }
+ });
+ }}
+ />
+
+ {
+ (isAbove18) && (
+ {
+ setForm((prev) => {
+ return {
+ ...prev,
+ married: !(prev.married ?? false)
+ }
+ });
+ }}
+ />
+ )
+ }
+ {
+ setForm((prev) => {
+ const newDate = new Date(e.target.value);
+ return {
+ ...prev,
+ dateOfBirth: newDate,
+ };
+ });
+ }}
+ />
+
+
+
+
+ )
+}
+
+export default CheckAgeForm
+