feat: implementing nextauth config

This commit is contained in:
Orace.A 2025-03-25 14:40:49 +01:00
parent b7e3b56739
commit ae7f66aa78
45 changed files with 222 additions and 19 deletions

View File

@ -11,7 +11,9 @@
"dependencies": {
"@tanstack/react-query": "^5.69.0",
"axios": "^1.8.4",
"jwt-decode": "^4.0.0",
"next": "15.2.3",
"next-auth": "^4.24.11",
"nextjs-toploader": "^3.8.15",
"nuqs": "^2.4.1",
"react": "^19.0.0",

136
pnpm-lock.yaml generated
View File

@ -14,9 +14,15 @@ importers:
axios:
specifier: ^1.8.4
version: 1.8.4
jwt-decode:
specifier: ^4.0.0
version: 4.0.0
next:
specifier: 15.2.3
version: 15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.86.0)
next-auth:
specifier: ^4.24.11
version: 4.24.11(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.86.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
nextjs-toploader:
specifier: ^3.8.15
version: 3.8.15(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.86.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@ -73,6 +79,10 @@ packages:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
'@babel/runtime@7.27.0':
resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==}
engines: {node: '>=6.9.0'}
'@emnapi/core@1.3.1':
resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==}
@ -318,6 +328,9 @@ packages:
resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
engines: {node: '>=12.4.0'}
'@panva/hkdf@1.2.1':
resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==}
'@parcel/watcher-android-arm64@2.5.1':
resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==}
engines: {node: '>= 10.0.0'}
@ -770,6 +783,10 @@ packages:
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
cookie@0.7.2:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@ -1277,6 +1294,9 @@ packages:
resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
hasBin: true
jose@4.15.9:
resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==}
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -1301,6 +1321,10 @@ packages:
resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
engines: {node: '>=4.0'}
jwt-decode@4.0.0:
resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==}
engines: {node: '>=18'}
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@ -1390,6 +1414,10 @@ packages:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
lru-cache@6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'}
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
@ -1434,6 +1462,20 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
next-auth@4.24.11:
resolution: {integrity: sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw==}
peerDependencies:
'@auth/core': 0.34.2
next: ^12.2.5 || ^13 || ^14 || ^15
nodemailer: ^6.6.5
react: ^17.0.2 || ^18 || ^19
react-dom: ^17.0.2 || ^18 || ^19
peerDependenciesMeta:
'@auth/core':
optional: true
nodemailer:
optional: true
next@15.2.3:
resolution: {integrity: sha512-x6eDkZxk2rPpu46E1ZVUWIBhYCLszmUY6fvHBFcbzJ9dD+qRX6vcHusaqqDlnY+VngKzKbAiG2iRCkPbmi8f7w==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
@ -1486,10 +1528,17 @@ packages:
react-router-dom:
optional: true
oauth@0.9.15:
resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==}
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
object-hash@2.2.0:
resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==}
engines: {node: '>= 6'}
object-inspect@1.13.4:
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
engines: {node: '>= 0.4'}
@ -1518,6 +1567,13 @@ packages:
resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==}
engines: {node: '>= 0.4'}
oidc-token-hash@5.1.0:
resolution: {integrity: sha512-y0W+X7Ppo7oZX6eovsRkuzcSM40Bicg2JEJkDJ4irIt1wsYAP5MLSNv+QAogO8xivMffw/9OvV3um1pxXgt1uA==}
engines: {node: ^10.13.0 || >=12.0.0}
openid-client@5.7.1:
resolution: {integrity: sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==}
optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
@ -1572,10 +1628,21 @@ packages:
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
engines: {node: ^10 || ^12 || >=14}
preact-render-to-string@5.2.6:
resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==}
peerDependencies:
preact: '>=10'
preact@10.26.4:
resolution: {integrity: sha512-KJhO7LBFTjP71d83trW+Ilnjbo+ySsaAgCfXOXUlmGzJ4ygYPWmysm77yg4emwfmoz3b22yvH5IsVFHbhUaH5w==}
prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
pretty-format@3.8.0:
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
@ -1615,6 +1682,9 @@ packages:
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
engines: {node: '>= 0.4'}
regenerator-runtime@0.14.1:
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
regexp.prototype.flags@1.5.4:
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
engines: {node: '>= 0.4'}
@ -1842,6 +1912,10 @@ packages:
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true
which-boxed-primitive@1.1.1:
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
engines: {node: '>= 0.4'}
@ -1867,6 +1941,9 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
@ -1878,6 +1955,10 @@ snapshots:
'@alloc/quick-lru@5.2.0': {}
'@babel/runtime@7.27.0':
dependencies:
regenerator-runtime: 0.14.1
'@emnapi/core@1.3.1':
dependencies:
'@emnapi/wasi-threads': 1.0.1
@ -2077,6 +2158,8 @@ snapshots:
'@nolyfill/is-core-module@1.0.39': {}
'@panva/hkdf@1.2.1': {}
'@parcel/watcher-android-arm64@2.5.1':
optional: true
@ -2535,6 +2618,8 @@ snapshots:
concat-map@0.0.1: {}
cookie@0.7.2: {}
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
@ -3197,6 +3282,8 @@ snapshots:
jiti@2.4.2: {}
jose@4.15.9: {}
js-tokens@4.0.0: {}
js-yaml@4.1.0:
@ -3220,6 +3307,8 @@ snapshots:
object.assign: 4.1.7
object.values: 1.2.1
jwt-decode@4.0.0: {}
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@ -3290,6 +3379,10 @@ snapshots:
dependencies:
js-tokens: 4.0.0
lru-cache@6.0.0:
dependencies:
yallist: 4.0.0
math-intrinsics@1.1.0: {}
merge2@1.4.1: {}
@ -3323,6 +3416,21 @@ snapshots:
natural-compare@1.4.0: {}
next-auth@4.24.11(next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.86.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@babel/runtime': 7.27.0
'@panva/hkdf': 1.2.1
cookie: 0.7.2
jose: 4.15.9
next: 15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.86.0)
oauth: 0.9.15
openid-client: 5.7.1
preact: 10.26.4
preact-render-to-string: 5.2.6(preact@10.26.4)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
uuid: 8.3.2
next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.86.0):
dependencies:
'@next/env': 15.2.3
@ -3369,8 +3477,12 @@ snapshots:
optionalDependencies:
next: 15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.86.0)
oauth@0.9.15: {}
object-assign@4.1.1: {}
object-hash@2.2.0: {}
object-inspect@1.13.4: {}
object-keys@1.1.1: {}
@ -3411,6 +3523,15 @@ snapshots:
define-properties: 1.2.1
es-object-atoms: 1.1.1
oidc-token-hash@5.1.0: {}
openid-client@5.7.1:
dependencies:
jose: 4.15.9
lru-cache: 6.0.0
object-hash: 2.2.0
oidc-token-hash: 5.1.0
optionator@0.9.4:
dependencies:
deep-is: 0.1.4
@ -3464,8 +3585,17 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
preact-render-to-string@5.2.6(preact@10.26.4):
dependencies:
preact: 10.26.4
pretty-format: 3.8.0
preact@10.26.4: {}
prelude-ls@1.2.1: {}
pretty-format@3.8.0: {}
prop-types@15.8.1:
dependencies:
loose-envify: 1.4.0
@ -3504,6 +3634,8 @@ snapshots:
get-proto: 1.0.1
which-builtin-type: 1.2.1
regenerator-runtime@0.14.1: {}
regexp.prototype.flags@1.5.4:
dependencies:
call-bind: 1.0.8
@ -3819,6 +3951,8 @@ snapshots:
dependencies:
punycode: 2.3.1
uuid@8.3.2: {}
which-boxed-primitive@1.1.1:
dependencies:
is-bigint: 1.1.0
@ -3866,6 +4000,8 @@ snapshots:
word-wrap@1.2.5: {}
yallist@4.0.0: {}
yocto-queue@0.1.0: {}
zod@3.24.2: {}

View File

@ -4,7 +4,7 @@ export default function AuthLayout({ children }: { children: React.ReactNode })
return(
<div className="flex flex-col min-h-screen">
<Header />
<div className="flex flex-1 justify-center items-center">
<div className="flex flex-1 justify-center items-center bg-blue-100">
{children}
</div>
</div>

View File

@ -4,7 +4,8 @@ export default function LoginPage() {
return(
<div>
<Form
className="bg-white p-2 w-[28rem]"
title="Connexion"
className="bg-white p-10 shadow-2xl w-3/4 lg:w-lg"
fields={[
{
label: "Email",
@ -20,7 +21,7 @@ export default function LoginPage() {
}
]}
submit={undefined}
child={<button type="submit">Login</button>}
child={<button type="submit" className="btn-auth">Connexion</button>}
/>
</div>
)

View File

@ -0,0 +1,47 @@
import NextAuth, { User } from "next-auth";
import Credentials from "next-auth/providers/credentials";
import axios, { AxiosError } from "axios";
import { jwtDecode } from "jwt-decode";
const handler = NextAuth({
providers: [
Credentials({
credentials: {
email: {},
password: {},
},
async authorize(credentials) {
let user: User | null = null;
const response = axios({
method: 'post',
url: 'private-docs-api.intside.co/users/login/',
data: {
email: credentials?.email,
password: credentials?.password,
}
})
.then(function (response: any) {
const { user_id } = jwtDecode(response.access_token) as {
user_id: string;
};
})
.catch(function (error) {
if (error instanceof AxiosError) {
if (error.status === 401) {
throw new Error("Email ou mot de passe incorrect");
} else {
throw new Error(error.message, error);
}
}
throw new Error("Une erreur est survenue");
});
},
})
]
});
export { handler as GET, handler as POST };

View File

@ -52,3 +52,11 @@ body {
top: 50%;
transform: translateY(-50%);
}
.btn-auth {
border-radius: 9999px;
background-color: #246BFD;
color: white;
width: 100%;
padding: 8px;
}

View File

Before

Width:  |  Height:  |  Size: 927 B

After

Width:  |  Height:  |  Size: 927 B

View File

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 600 B

View File

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 99 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 592 B

View File

Before

Width:  |  Height:  |  Size: 286 B

After

Width:  |  Height:  |  Size: 286 B

View File

Before

Width:  |  Height:  |  Size: 582 KiB

After

Width:  |  Height:  |  Size: 582 KiB

View File

Before

Width:  |  Height:  |  Size: 535 B

After

Width:  |  Height:  |  Size: 535 B

View File

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 523 B

View File

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 191 B

View File

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 191 B

View File

Before

Width:  |  Height:  |  Size: 207 B

After

Width:  |  Height:  |  Size: 207 B

View File

Before

Width:  |  Height:  |  Size: 331 B

After

Width:  |  Height:  |  Size: 331 B

View File

Before

Width:  |  Height:  |  Size: 244 B

After

Width:  |  Height:  |  Size: 244 B

View File

Before

Width:  |  Height:  |  Size: 307 B

After

Width:  |  Height:  |  Size: 307 B

View File

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 750 B

View File

Before

Width:  |  Height:  |  Size: 855 B

After

Width:  |  Height:  |  Size: 855 B

View File

Before

Width:  |  Height:  |  Size: 549 B

After

Width:  |  Height:  |  Size: 549 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 699 B

After

Width:  |  Height:  |  Size: 699 B

View File

Before

Width:  |  Height:  |  Size: 419 B

After

Width:  |  Height:  |  Size: 419 B

View File

Before

Width:  |  Height:  |  Size: 667 B

After

Width:  |  Height:  |  Size: 667 B

View File

Before

Width:  |  Height:  |  Size: 595 B

After

Width:  |  Height:  |  Size: 595 B

View File

Before

Width:  |  Height:  |  Size: 989 B

After

Width:  |  Height:  |  Size: 989 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 737 B

After

Width:  |  Height:  |  Size: 737 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 806 B

After

Width:  |  Height:  |  Size: 806 B

View File

@ -5,10 +5,17 @@ export default function Form({
fields,
submit,
className,
child
child,
title
} : FormProps) {
return (
<form className={className} onSubmit={submit}>
<div className="flex justify-center text-black">
<p className="text-3xl font-bold">{title}</p>
</div>
<div className="gap-2 mt-2">
{
fields.map((item, index) => (
<FloatingLabelInput
@ -24,6 +31,7 @@ export default function Form({
/>
))
}
</div>
{child}
</form>

View File

@ -12,6 +12,7 @@ export interface FloatingLabelInputProps {
}
export interface FormProps {
title?: string,
fields: FloatingLabelInputProps[],
submit: FormEventHandler<HTMLFormElement> | undefined,
className: string,