add auth form, validation
This commit is contained in:
parent
eb5ddf9f2e
commit
f51cc9cc4d
@ -9,8 +9,11 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vee-validate/zod": "^4.15.0",
|
||||
"vee-validate": "^4.15.0",
|
||||
"vue": "3.5.13",
|
||||
"vue-router": "4.5.0"
|
||||
"vue-router": "4.5.0",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "5.2.1",
|
||||
|
||||
124
pnpm-lock.yaml
generated
124
pnpm-lock.yaml
generated
@ -8,12 +8,21 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@vee-validate/zod':
|
||||
specifier: ^4.15.0
|
||||
version: 4.15.0(vue@3.5.13(typescript@5.7.3))(zod@3.24.1)
|
||||
vee-validate:
|
||||
specifier: ^4.15.0
|
||||
version: 4.15.0(vue@3.5.13(typescript@5.7.3))
|
||||
vue:
|
||||
specifier: 3.5.13
|
||||
version: 3.5.13(typescript@5.7.3)
|
||||
vue-router:
|
||||
specifier: 4.5.0
|
||||
version: 4.5.0(vue@3.5.13(typescript@5.7.3))
|
||||
zod:
|
||||
specifier: ^3.24.1
|
||||
version: 3.24.1
|
||||
devDependencies:
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: 5.2.1
|
||||
@ -364,6 +373,11 @@ packages:
|
||||
'@types/json-schema@7.0.15':
|
||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||
|
||||
'@vee-validate/zod@4.15.0':
|
||||
resolution: {integrity: sha512-MpvIKiyg9X5yD8bJW0no2AU7wtR2T5mrvD9tuPRiie951sU2n6QKgMV38qKKOiqFBCxsMSjIuLLLV3V5kVE4nQ==}
|
||||
peerDependencies:
|
||||
zod: ^3.24.0
|
||||
|
||||
'@vitejs/plugin-vue@5.2.1':
|
||||
resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
@ -398,6 +412,15 @@ packages:
|
||||
'@vue/devtools-api@6.6.4':
|
||||
resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
|
||||
|
||||
'@vue/devtools-api@7.7.1':
|
||||
resolution: {integrity: sha512-Cexc8GimowoDkJ6eNelOPdYIzsu2mgNyp0scOQ3tiaYSb9iok6LOESSsJvHaI+ib3joRfqRJNLkHFjhNuWA5dg==}
|
||||
|
||||
'@vue/devtools-kit@7.7.1':
|
||||
resolution: {integrity: sha512-yhZ4NPnK/tmxGtLNQxmll90jIIXdb2jAhPF76anvn5M/UkZCiLJy28bYgPIACKZ7FCosyKoaope89/RsFJll1w==}
|
||||
|
||||
'@vue/devtools-shared@7.7.1':
|
||||
resolution: {integrity: sha512-BtgF7kHq4BHG23Lezc/3W2UhK2ga7a8ohAIAGJMBr4BkxUFzhqntQtCiuL1ijo2ztWnmusymkirgqUrXoQKumA==}
|
||||
|
||||
'@vue/language-core@2.2.0':
|
||||
resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==}
|
||||
peerDependencies:
|
||||
@ -460,6 +483,9 @@ packages:
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
birpc@0.2.19:
|
||||
resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
|
||||
|
||||
boolbase@1.0.0:
|
||||
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
|
||||
|
||||
@ -487,6 +513,10 @@ packages:
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
|
||||
copy-anything@3.0.5:
|
||||
resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
|
||||
engines: {node: '>=12.13'}
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
@ -635,6 +665,9 @@ packages:
|
||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||
hasBin: true
|
||||
|
||||
hookable@5.5.3:
|
||||
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
||||
|
||||
ignore@5.3.2:
|
||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||
engines: {node: '>= 4'}
|
||||
@ -655,6 +688,10 @@ packages:
|
||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-what@4.1.16:
|
||||
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
|
||||
engines: {node: '>=12.13'}
|
||||
|
||||
isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
@ -698,6 +735,9 @@ packages:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
mitt@3.0.1:
|
||||
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
@ -742,6 +782,9 @@ packages:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
perfect-debounce@1.0.0:
|
||||
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
||||
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
@ -765,6 +808,9 @@ packages:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
rfdc@1.4.1:
|
||||
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
|
||||
|
||||
rollup@4.34.1:
|
||||
resolution: {integrity: sha512-iYZ/+PcdLYSGfH3S+dGahlW/RWmsqDhLgj1BT9DH/xXJ0ggZN7xkdP9wipPNjjNLczI+fmMLmTB9pye+d2r4GQ==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
@ -787,10 +833,18 @@ packages:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
speakingurl@14.0.1:
|
||||
resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
strip-json-comments@3.1.1:
|
||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
superjson@2.2.2:
|
||||
resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
@ -803,6 +857,10 @@ packages:
|
||||
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
type-fest@4.33.0:
|
||||
resolution: {integrity: sha512-s6zVrxuyKbbAsSAD5ZPTB77q4YIdRctkTbJ2/Dqlinwz+8ooH2gd+YA7VA6Pa93KML9GockVvoxjZ2vHP+mu8g==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
typescript@5.7.3:
|
||||
resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
|
||||
engines: {node: '>=14.17'}
|
||||
@ -814,6 +872,11 @@ packages:
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
vee-validate@4.15.0:
|
||||
resolution: {integrity: sha512-PGJh1QCFwCBjbHu5aN6vB8macYVWrajbDvgo1Y/8fz9n/RVIkLmZCJDpUgu7+mUmCOPMxeyq7vXUOhbwAqdXcA==}
|
||||
peerDependencies:
|
||||
vue: ^3.4.26
|
||||
|
||||
vite@6.0.11:
|
||||
resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==}
|
||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||
@ -899,6 +962,9 @@ packages:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
zod@3.24.1:
|
||||
resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@babel/helper-string-parser@7.25.9': {}
|
||||
@ -1107,6 +1173,14 @@ snapshots:
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
|
||||
'@vee-validate/zod@4.15.0(vue@3.5.13(typescript@5.7.3))(zod@3.24.1)':
|
||||
dependencies:
|
||||
type-fest: 4.33.0
|
||||
vee-validate: 4.15.0(vue@3.5.13(typescript@5.7.3))
|
||||
zod: 3.24.1
|
||||
transitivePeerDependencies:
|
||||
- vue
|
||||
|
||||
'@vitejs/plugin-vue@5.2.1(vite@6.0.11)(vue@3.5.13(typescript@5.7.3))':
|
||||
dependencies:
|
||||
vite: 6.0.11
|
||||
@ -1161,6 +1235,24 @@ snapshots:
|
||||
|
||||
'@vue/devtools-api@6.6.4': {}
|
||||
|
||||
'@vue/devtools-api@7.7.1':
|
||||
dependencies:
|
||||
'@vue/devtools-kit': 7.7.1
|
||||
|
||||
'@vue/devtools-kit@7.7.1':
|
||||
dependencies:
|
||||
'@vue/devtools-shared': 7.7.1
|
||||
birpc: 0.2.19
|
||||
hookable: 5.5.3
|
||||
mitt: 3.0.1
|
||||
perfect-debounce: 1.0.0
|
||||
speakingurl: 14.0.1
|
||||
superjson: 2.2.2
|
||||
|
||||
'@vue/devtools-shared@7.7.1':
|
||||
dependencies:
|
||||
rfdc: 1.4.1
|
||||
|
||||
'@vue/language-core@2.2.0(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@volar/language-core': 2.4.11
|
||||
@ -1226,6 +1318,8 @@ snapshots:
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
birpc@0.2.19: {}
|
||||
|
||||
boolbase@1.0.0: {}
|
||||
|
||||
brace-expansion@1.1.11:
|
||||
@ -1252,6 +1346,10 @@ snapshots:
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
|
||||
copy-anything@3.0.5:
|
||||
dependencies:
|
||||
is-what: 4.1.16
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
@ -1434,6 +1532,8 @@ snapshots:
|
||||
|
||||
he@1.2.0: {}
|
||||
|
||||
hookable@5.5.3: {}
|
||||
|
||||
ignore@5.3.2: {}
|
||||
|
||||
import-fresh@3.3.1:
|
||||
@ -1449,6 +1549,8 @@ snapshots:
|
||||
dependencies:
|
||||
is-extglob: 2.1.1
|
||||
|
||||
is-what@4.1.16: {}
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
@ -1490,6 +1592,8 @@ snapshots:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
mitt@3.0.1: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
muggle-string@0.4.1: {}
|
||||
@ -1529,6 +1633,8 @@ snapshots:
|
||||
|
||||
path-key@3.1.1: {}
|
||||
|
||||
perfect-debounce@1.0.0: {}
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
postcss-selector-parser@6.1.2:
|
||||
@ -1548,6 +1654,8 @@ snapshots:
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
rfdc@1.4.1: {}
|
||||
|
||||
rollup@4.34.1:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.6
|
||||
@ -1583,8 +1691,14 @@ snapshots:
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
speakingurl@14.0.1: {}
|
||||
|
||||
strip-json-comments@3.1.1: {}
|
||||
|
||||
superjson@2.2.2:
|
||||
dependencies:
|
||||
copy-anything: 3.0.5
|
||||
|
||||
supports-color@7.2.0:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
@ -1595,6 +1709,8 @@ snapshots:
|
||||
|
||||
type-fest@0.20.2: {}
|
||||
|
||||
type-fest@4.33.0: {}
|
||||
|
||||
typescript@5.7.3: {}
|
||||
|
||||
uri-js@4.4.1:
|
||||
@ -1603,6 +1719,12 @@ snapshots:
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
vee-validate@4.15.0(vue@3.5.13(typescript@5.7.3)):
|
||||
dependencies:
|
||||
'@vue/devtools-api': 7.7.1
|
||||
type-fest: 4.33.0
|
||||
vue: 3.5.13(typescript@5.7.3)
|
||||
|
||||
vite@6.0.11:
|
||||
dependencies:
|
||||
esbuild: 0.24.2
|
||||
@ -1656,3 +1778,5 @@ snapshots:
|
||||
xml-name-validator@4.0.0: {}
|
||||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
zod@3.24.1: {}
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
:is="layout + '-layout'"
|
||||
v-if="layout"
|
||||
/>
|
||||
<RouterView />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
57
src/hooks/useLoginForm.ts
Normal file
57
src/hooks/useLoginForm.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import * as z from 'zod';
|
||||
import { useField, useForm } from 'vee-validate';
|
||||
import { toTypedSchema } from '@vee-validate/zod';
|
||||
import { computed, watch } from 'vue';
|
||||
|
||||
const useLoginForm = () => {
|
||||
const schema = z.object({
|
||||
email: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, 'Обязательное поле')
|
||||
.email('Невалидный email')
|
||||
.default(''),
|
||||
password: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, 'Обязательное поле')
|
||||
.min(6, 'Должно содержать больше 6 символов')
|
||||
.default('')
|
||||
})
|
||||
|
||||
const {handleSubmit, isSubmitting, submitCount} = useForm({
|
||||
validationSchema: toTypedSchema(schema)
|
||||
});
|
||||
|
||||
const onSubmit = handleSubmit((values) => {
|
||||
console.log(values);
|
||||
})
|
||||
|
||||
const {value: email, errorMessage: eError, handleBlur: eBlur} = useField('email');
|
||||
const {value: password, errorMessage: pError, handleBlur: pBlur} = useField('password');
|
||||
|
||||
const isTooManyAttempts = computed(() => submitCount.value > 2);
|
||||
const disabled = computed(() => isSubmitting.value || isTooManyAttempts.value)
|
||||
|
||||
watch(isTooManyAttempts, (value) => {
|
||||
if (value) {
|
||||
setTimeout(() => {
|
||||
submitCount.value = 0;
|
||||
}, 2000)
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
email,
|
||||
eError,
|
||||
eBlur,
|
||||
password,
|
||||
pError,
|
||||
pBlur,
|
||||
disabled,
|
||||
onSubmit,
|
||||
isTooManyAttempts,
|
||||
}
|
||||
};
|
||||
|
||||
export default useLoginForm;
|
||||
@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="card" />
|
||||
<div class="card">
|
||||
<router-view />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<the-navbar />
|
||||
<div class="container with-nav">
|
||||
<div class="card" />
|
||||
<div class="card">
|
||||
<router-view />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -1,13 +1,71 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Auth</h1>
|
||||
</div>
|
||||
<form
|
||||
class="card"
|
||||
@submit.prevent="onSubmit"
|
||||
>
|
||||
<h1>Войти в систему</h1>
|
||||
|
||||
<div
|
||||
class="form-control"
|
||||
:class="{invalid: eError}"
|
||||
>
|
||||
<label for="email">E-mail</label>
|
||||
<input
|
||||
id="email"
|
||||
v-model="email"
|
||||
type="email"
|
||||
:disabled="disabled"
|
||||
@blur="eBlur"
|
||||
>
|
||||
<small v-if="eError">{{ eError }}</small>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="form-control"
|
||||
:class="{invalid: pError}"
|
||||
>
|
||||
<label for="password">Пароль</label>
|
||||
<input
|
||||
id="password"
|
||||
v-model="password"
|
||||
type="password"
|
||||
:disabled="disabled"
|
||||
@blur="pBlur"
|
||||
>
|
||||
<small v-if="pError">{{ pError }}</small>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="btn primary"
|
||||
type="submit"
|
||||
:disabled="disabled"
|
||||
>
|
||||
Войти
|
||||
</button>
|
||||
|
||||
<div
|
||||
v-if="isTooManyAttempts"
|
||||
class="text-danger"
|
||||
>
|
||||
Слишком частые попытки войти в систему
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
<script setup>
|
||||
import useLoginForm from '../hooks/useLoginForm.ts';
|
||||
|
||||
}
|
||||
const {
|
||||
disabled,
|
||||
eBlur,
|
||||
eError,
|
||||
email,
|
||||
onSubmit,
|
||||
password,
|
||||
pBlur,
|
||||
pError,
|
||||
isTooManyAttempts
|
||||
} = useLoginForm();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user