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 ( + <> +
+
+ + +
+ +
+ +
+ + +
+
+ {/*
+ +
*/} +