update login page
This commit is contained in:
@@ -1,23 +1,13 @@
|
|||||||
import type { Metadata } from "next";
|
|
||||||
import Providers from '@/app/providers/getQueryServer'
|
import Providers from '@/app/providers/getQueryServer'
|
||||||
import { NextIntlClientProvider, hasLocale } from 'next-intl';
|
import { NextIntlClientProvider, hasLocale } from 'next-intl';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
import { getQueryClient } from '@/app/providers/getQueryClient';
|
|
||||||
import { HydrationBoundary, dehydrate } from '@tanstack/react-query';
|
|
||||||
import { prefetchLayoutQueries } from '@/app/lib/prefetch-queries';
|
|
||||||
import { routing } from '@/i18n/routing';
|
import { routing } from '@/i18n/routing';
|
||||||
import AdminLayoutWrapper from '@/app/components/admin-layout-wrapper';
|
|
||||||
|
|
||||||
// @ts-expect-error - CSS modules types not defined
|
// @ts-expect-error - CSS modules types not defined
|
||||||
import "../styles/globals.css";
|
import "../styles/globals.css";
|
||||||
// @ts-expect-error - CSS modules types not defined
|
// @ts-expect-error - CSS modules types not defined
|
||||||
import "../styles/global-styles.scss"
|
import "../styles/global-styles.scss"
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
title: "Admin panel no copy",
|
|
||||||
description: "Admin panel no copy",
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function generateStaticParams() {
|
export async function generateStaticParams() {
|
||||||
return routing.locales.map((locale: any) => ({ locale }));
|
return routing.locales.map((locale: any) => ({ locale }));
|
||||||
}
|
}
|
||||||
@@ -30,16 +20,12 @@ export default async function RootLayout({
|
|||||||
params: Promise<{ locale: string }>;
|
params: Promise<{ locale: string }>;
|
||||||
}>) {
|
}>) {
|
||||||
const { locale } = await params;
|
const { locale } = await params;
|
||||||
|
|
||||||
if (!hasLocale(routing.locales, locale)) {
|
if (!hasLocale(routing.locales, locale)) {
|
||||||
notFound();
|
notFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryClient = getQueryClient();
|
|
||||||
await prefetchLayoutQueries(queryClient);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang={locale}>
|
||||||
<body>
|
<body>
|
||||||
<NextIntlClientProvider>
|
<NextIntlClientProvider>
|
||||||
<Providers>
|
<Providers>
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
import { hasLocale } from 'next-intl';
|
|
||||||
import { notFound } from 'next/navigation';
|
|
||||||
import { getQueryClient } from '@/app/providers/getQueryClient';
|
|
||||||
import { prefetchLayoutQueries } from '@/app/lib/prefetch-queries';
|
|
||||||
import { routing } from '@/i18n/routing';
|
|
||||||
|
|
||||||
export default async function RootLayout({
|
|
||||||
children,
|
|
||||||
params
|
|
||||||
}: Readonly<{
|
|
||||||
children: React.ReactNode;
|
|
||||||
params: Promise<{ locale: string }>;
|
|
||||||
}>) {
|
|
||||||
const { locale } = await params;
|
|
||||||
if (!hasLocale(routing.locales, locale)) {
|
|
||||||
notFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
const queryClient = getQueryClient();
|
|
||||||
await prefetchLayoutQueries(queryClient);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="">
|
|
||||||
<main className="main-containter">
|
|
||||||
{children}
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,13 @@
|
|||||||
import LoginForm from '@/app/ui/forms/login-form';
|
import LoginForm from '@/app/ui/forms/login-form';
|
||||||
import Link from 'next/link';
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div
|
||||||
|
className="login-page"
|
||||||
|
>
|
||||||
<LoginForm />
|
<LoginForm />
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<Link
|
|
||||||
href={'/pages/'}
|
|
||||||
>
|
|
||||||
link
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ export default async function RootLayout({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const queryClient = getQueryClient();
|
const queryClient = getQueryClient();
|
||||||
await prefetchLayoutQueries(queryClient);
|
await prefetchLayoutQueries(queryClient);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HydrationBoundary state={dehydrate(queryClient)}>
|
<HydrationBoundary state={dehydrate(queryClient)}>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
'use server';
|
'use server';
|
||||||
|
|
||||||
/* import 'server-only'; */
|
/* import 'server-only'; */
|
||||||
import { cookies } from 'next/headers'
|
import { cookies } from 'next/headers';
|
||||||
import { SignJWT, jwtVerify } from 'jose'
|
import { SignJWT, jwtVerify } from 'jose';
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
import { headers } from 'next/headers';
|
||||||
|
|
||||||
/* const secretKey = process.env.SESSION_SECRET */
|
/* const secretKey = process.env.SESSION_SECRET */
|
||||||
const secretKey = 'AAA+sq1yKte/gMgUUu/B/OyXqr45/LMYplPVOlWc+uo='
|
const secretKey = 'AAA+sq1yKte/gMgUUu/B/OyXqr45/LMYplPVOlWc+uo='
|
||||||
|
|||||||
@@ -88,6 +88,38 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-page {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.show-password-button {
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 0px;
|
||||||
|
padding: 10px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 16px;
|
||||||
|
color: var(--secondary-hover);
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--primary-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
svg {
|
||||||
|
color: var(--primary-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.admin-panel {
|
.admin-panel {
|
||||||
.admin-sidebar {
|
.admin-sidebar {
|
||||||
width: var(--side-bar-width);
|
width: var(--side-bar-width);
|
||||||
|
|||||||
@@ -39,6 +39,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-wrapper {
|
||||||
|
max-width: 640px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.form-group {
|
.form-group {
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
@@ -83,7 +89,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #374151;
|
color: #2563eb;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +176,7 @@
|
|||||||
.btn {
|
.btn {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
background: linear-gradient(135deg, #6366f1, #8b5cf6);
|
background: #2563eb;
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
@@ -182,7 +188,7 @@
|
|||||||
margin: 20px 0 0 0;
|
margin: 20px 0 0 0;
|
||||||
|
|
||||||
&:hover:not(:disabled) {
|
&:hover:not(:disabled) {
|
||||||
transform: translateY(-2px);
|
background: #1d4ed8;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
|
|||||||
@@ -28,7 +28,10 @@ export default function LoginForm() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form action={formAction}>
|
<form
|
||||||
|
className={`${styles['form-wrapper']}`}
|
||||||
|
action={formAction}
|
||||||
|
>
|
||||||
<div className={`${styles['form-group']}`}>
|
<div className={`${styles['form-group']}`}>
|
||||||
<label className={`${styles['form-label']}`}>
|
<label className={`${styles['form-label']}`}>
|
||||||
{t('email-adress')}
|
{t('email-adress')}
|
||||||
@@ -83,7 +86,7 @@ export default function LoginForm() {
|
|||||||
{t(state?.error.server)}
|
{t(state?.error.server)}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<div className={`${styles['form-options']}`}>
|
{/* <div className={`${styles['form-options']}`}>
|
||||||
<div className={`${styles['form-checkbox']}`}>
|
<div className={`${styles['form-checkbox']}`}>
|
||||||
<input type="checkbox" id="remember" name="remember" ref={checkBoxRememberMe} />
|
<input type="checkbox" id="remember" name="remember" ref={checkBoxRememberMe} />
|
||||||
<label
|
<label
|
||||||
@@ -97,10 +100,7 @@ export default function LoginForm() {
|
|||||||
{t('remember-me')}
|
{t('remember-me')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<a href="forgot-password" className={`${styles['forgot-password']}`} >
|
</div> */}
|
||||||
{t('forgot-password')}?
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className={`${styles['btn']}`}
|
className={`${styles['btn']}`}
|
||||||
|
|||||||
+27
-22
@@ -9,40 +9,45 @@ const intlMiddleware = createIntlMiddleware(routing);
|
|||||||
export default async function proxy(request: NextRequest) {
|
export default async function proxy(request: NextRequest) {
|
||||||
const path = request.nextUrl.pathname;
|
const path = request.nextUrl.pathname;
|
||||||
|
|
||||||
const cookie = (await cookies()).get('session')?.value;
|
|
||||||
const session = await decrypt(cookie);
|
|
||||||
console.log(session);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
path.startsWith('/_next') ||
|
path.startsWith('/_next') ||
|
||||||
path.includes('.')
|
path.includes('/api/')
|
||||||
) {
|
) {
|
||||||
return NextResponse.next()
|
return NextResponse.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestHeaders = new Headers(request.headers);
|
const pathname = request.nextUrl.pathname;
|
||||||
requestHeaders.set('x-pathname', path);
|
const locale = pathname.split('/')[1];
|
||||||
|
const isValidLocale = routing.locales.includes(locale as any);
|
||||||
|
|
||||||
|
if (!isValidLocale && !path.includes('/login')) {
|
||||||
|
const defaultLocale = routing.defaultLocale;
|
||||||
|
const newUrl = new URL(`/${defaultLocale}${path}`, request.url);
|
||||||
|
return NextResponse.redirect(newUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
const isLoginPage = path.includes(`/${locale}/login`) || path === '/login';
|
||||||
|
const isPublicPage = isLoginPage || path.includes('/api/');
|
||||||
|
|
||||||
|
if (!isPublicPage) {
|
||||||
|
const cookie = (await cookies()).get('session')?.value;
|
||||||
|
const session = await decrypt(cookie);
|
||||||
|
|
||||||
|
if (!session?.token) {
|
||||||
|
const targetLocale = isValidLocale ? locale : routing.defaultLocale;
|
||||||
|
const loginUrl = new URL(`/${targetLocale}/login`, request.url);
|
||||||
|
return NextResponse.redirect(loginUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const intlResponse = intlMiddleware(request);
|
const intlResponse = intlMiddleware(request);
|
||||||
|
|
||||||
if (intlResponse) {
|
if (intlResponse) {
|
||||||
const response = new NextResponse(intlResponse.body, intlResponse);
|
const response = new NextResponse(intlResponse.body, intlResponse);
|
||||||
response.headers.set('x-pathname', path);
|
response.headers.set('x-pathname', path);
|
||||||
|
return response;
|
||||||
/* if (!session?.token) {
|
|
||||||
const loginUrl = new URL('/login', request.nextUrl)
|
|
||||||
loginUrl.searchParams.set('locale', request.nextUrl.locale || 'ru')
|
|
||||||
return NextResponse.redirect(loginUrl)
|
|
||||||
} */
|
|
||||||
|
|
||||||
return intlResponse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.next({
|
return NextResponse.next();
|
||||||
request: {
|
|
||||||
headers: requestHeaders,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
|
|||||||
Reference in New Issue
Block a user