From b91bd87555c43196a69d1ae6d26997a22ea06b73 Mon Sep 17 00:00:00 2001 From: Timofey Date: Mon, 19 May 2025 11:54:30 +0300 Subject: [PATCH] login page --- backend/base/settings.py | 6 ++ frontend/app/(urls)/account/layout.tsx | 57 ++++++++++ frontend/app/(urls)/login/ClientView.tsx | 114 ++++++++++++++++++++ frontend/app/(urls)/login/page.tsx | 61 ++++++++++- frontend/app/(urls)/register/admin/page.tsx | 7 -- frontend/app/(urls)/register/page.tsx | 4 +- frontend/app/types/index.ts | 12 +++ frontend/components/AccountSidebar.tsx | 110 +++++++++++++++++++ frontend/components/Logout.tsx | 43 ++++++++ frontend/components/ui/Loader.tsx | 21 ++++ frontend/middlewares/middleware.ts | 36 +++++++ frontend/public/images/noPhoto.png | Bin 0 -> 516582 bytes 12 files changed, 457 insertions(+), 14 deletions(-) create mode 100644 frontend/app/(urls)/account/layout.tsx create mode 100644 frontend/app/(urls)/login/ClientView.tsx delete mode 100644 frontend/app/(urls)/register/admin/page.tsx create mode 100644 frontend/components/AccountSidebar.tsx create mode 100644 frontend/components/Logout.tsx create mode 100644 frontend/components/ui/Loader.tsx create mode 100644 frontend/middlewares/middleware.ts create mode 100644 frontend/public/images/noPhoto.png diff --git a/backend/base/settings.py b/backend/base/settings.py index 1e7ce41..c59cf32 100644 --- a/backend/base/settings.py +++ b/backend/base/settings.py @@ -53,6 +53,12 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': [ + 'rest_framework_simplejwt.authentication.JWTAuthentication', + 'rest_framework.authentication.SessionAuthentication', + ], +} SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15), diff --git a/frontend/app/(urls)/account/layout.tsx b/frontend/app/(urls)/account/layout.tsx new file mode 100644 index 0000000..954e8b0 --- /dev/null +++ b/frontend/app/(urls)/account/layout.tsx @@ -0,0 +1,57 @@ +'use client' + +import { useEffect, useState } from 'react' +import { useRouter } from 'next/navigation' +import AccountSidebar from '@/components/AccountSidebar' +import Loader from '@/components/ui/Loader' +import { RiUser3Line } from 'react-icons/ri' +import { CgNotes } from 'react-icons/cg' +import { FaStar } from 'react-icons/fa6' +import useUserStore from '@/app/store/userStore' + +export default function AccountLayout({ + children, +}: { + children: React.ReactNode +}) { + const [isLoading, setIsLoading] = useState(true) + const router = useRouter() + const { isAuthenticated, user } = useUserStore() + + useEffect(() => { + if (!isAuthenticated || !user) { + router.replace('/login') + return + } + + const timer = setTimeout(() => { + setIsLoading(false) + }, 300) + + return () => clearTimeout(timer) + }, [isAuthenticated, user, router]) + + if (!isAuthenticated || !user || isLoading) { + return + } + + const userNavigation = [ + { name: 'Профиль', href: '/account', icon: RiUser3Line }, + { name: 'Мои маршруты', href: '/account/routes', icon: CgNotes }, + ] + + return ( +
+
+
+
+
+ +
+
+
{children}
+
+
+
+ ) +} diff --git a/frontend/app/(urls)/login/ClientView.tsx b/frontend/app/(urls)/login/ClientView.tsx new file mode 100644 index 0000000..d0dbd5b --- /dev/null +++ b/frontend/app/(urls)/login/ClientView.tsx @@ -0,0 +1,114 @@ +import React from 'react' +import { useForm } from '@/app/hooks/useForm' +import Button from '@/components/ui/Button' +// import LoginButton from '@/app/components/ui/LoginButton' +import { HiOutlineEye, HiOutlineEyeOff } from 'react-icons/hi' +import showToast from '@/components/ui/Toast' +import { useRouter } from 'next/navigation' +import { signIn } from 'next-auth/react' +// import PasswordRecovery from '@/app/components/ui/PasswordRecovery' + +const validationRules = { + email: { required: true }, + password: { required: true, minLength: 8 }, +} + +const ClientView = () => { + const router = useRouter() + + const { + values, + isVisible, + handleChange, + handleSubmit, + togglePasswordVisibility, + } = useForm( + { + email: '', + password: '', + }, + validationRules, + async (values) => { + try { + const result = await signIn('credentials', { + email: values.email, + password: values.password, + redirect: false, + }) + + if (result?.error) { + showToast({ type: 'error', message: result.error }) + return + } + + showToast({ type: 'success', message: 'Авторизация успешна!' }) + router.push('/account') + } catch { + showToast({ type: 'error', message: 'Ошибка при входе в аккаунт' }) + } + } + ) + + return ( + <> +
+
+ + +
+ +
+ +
+ + +
+
+ {/*
+ +
*/} +