linter fixes
This commit is contained in:
@@ -10,16 +10,13 @@ import ClientView from './ClientView'
|
||||
const LoginPage = () => {
|
||||
const router = useRouter()
|
||||
const { isAuthenticated } = useUserStore()
|
||||
const [isClient, setIsClient] = useState(true)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
// проверяем логин
|
||||
if (isAuthenticated) {
|
||||
// распределяем
|
||||
if (isClient) {
|
||||
router.replace('/account')
|
||||
}
|
||||
router.replace('/account')
|
||||
return
|
||||
}
|
||||
|
||||
@@ -28,18 +25,18 @@ const LoginPage = () => {
|
||||
}, 300)
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
}, [isAuthenticated, router, isClient])
|
||||
}, [isAuthenticated, router])
|
||||
|
||||
if (isLoading) {
|
||||
return <Loader />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center py-8 ">
|
||||
<div className="flex w-full max-w-xl flex-col gap-4 bg-white rounded-2xl shadow-lg p-6">
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<div className="flex w-full max-w-xl flex-col gap-4 rounded-2xl bg-white p-6 shadow-lg">
|
||||
<div className="flex flex-col items-center py-4">
|
||||
<h1 className="text-2xl font-medium pb-1">Рады видеть Вас снова!</h1>
|
||||
<p className="text-base font-medium text-center">
|
||||
<h1 className="pb-1 text-2xl font-medium">Рады видеть Вас снова!</h1>
|
||||
<p className="text-center text-base font-medium">
|
||||
Пожалуйста, авторизуйтесь, чтобы продолжить
|
||||
</p>
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5,27 +5,35 @@ import Link from 'next/link'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import useUserStore from '@/app/store/userStore'
|
||||
import ClientRegistrationForm from './components/ClientRegistrationForm'
|
||||
import Loader from '@/components/ui/Loader'
|
||||
|
||||
const RegisterPage = () => {
|
||||
const router = useRouter()
|
||||
const { isAuthenticated } = useUserStore()
|
||||
const [isClient, setIsClient] = useState(true)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
// проверяем логин
|
||||
if (isAuthenticated) {
|
||||
// распределяем
|
||||
if (isClient) {
|
||||
router.replace('/account')
|
||||
}
|
||||
router.replace('/account')
|
||||
return
|
||||
}
|
||||
}, [isAuthenticated, router, isClient])
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
setIsLoading(false)
|
||||
}, 300)
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
}, [isAuthenticated, router])
|
||||
|
||||
if (isLoading) {
|
||||
return <Loader />
|
||||
}
|
||||
return (
|
||||
<div className="flex items-center justify-center p-12">
|
||||
<div className="flex w-full max-w-xl md:max-w-3xl lg:max-w-3xl flex-col gap-4 bg-white rounded-2xl shadow-lg p-6">
|
||||
<h1 className="text-2xl py-1">Давайте познакомимся поближе!</h1>
|
||||
<div className="flex w-full max-w-xl flex-col gap-4 rounded-2xl bg-white p-6 shadow-lg md:max-w-3xl lg:max-w-3xl">
|
||||
<h1 className="py-1 text-2xl">Давайте познакомимся поближе!</h1>
|
||||
|
||||
<ClientRegistrationForm />
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import React from 'react'
|
||||
import type { Metadata } from 'next'
|
||||
import SearchCard from '../../components/SearchCard'
|
||||
import { SearchCardProps, RouteSearchPageProps } from '@/app/types'
|
||||
import SearchFilters from '../../components/SearchFilters'
|
||||
import { RouteSearchPageProps } from '@/app/types'
|
||||
import ClientResults from '../../components/ClientResults'
|
||||
|
||||
async function fetchSearch(category: string, from: string, to: string) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import SearchCard from '../components/SearchCard'
|
||||
import { SearchCardProps, SearchPageProps } from '@/app/types'
|
||||
import { fetchRoutes } from '@/lib/search/fetchRoutes'
|
||||
import SearchFilters from '../components/SearchFilters'
|
||||
import AddressSelector from '@/components/AddressSelector'
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
return {
|
||||
@@ -56,8 +57,11 @@ export default async function SearchPage(props: SearchPageProps) {
|
||||
return (
|
||||
<div className="container mx-auto p-4">
|
||||
<h1 className="mb-4 text-2xl font-bold">
|
||||
{params.category === 'mover' ? 'Поиск перевозчика' : 'Поиск посылки'}
|
||||
{params.category === 'mover'
|
||||
? 'Поиск перевозчика - все предложения'
|
||||
: 'Поиск посылки - все предложения'}
|
||||
</h1>
|
||||
<AddressSelector is_search={true} />
|
||||
<SearchFilters />
|
||||
<Suspense fallback={<div>Загрузка результатов...</div>}>
|
||||
<div className="space-y-4">
|
||||
|
||||
@@ -34,6 +34,7 @@ export async function POST(req: NextRequest) {
|
||||
const result = await response.json()
|
||||
return new Response(JSON.stringify(result), { status: 200 })
|
||||
} catch (error) {
|
||||
console.error('POST /api/account/create-route error:', error)
|
||||
return new Response(JSON.stringify({ error: 'Internal Server Error' }), {
|
||||
status: 500,
|
||||
})
|
||||
|
||||
@@ -39,6 +39,7 @@ export async function PATCH(req: NextRequest) {
|
||||
const result = await response.json()
|
||||
return new Response(JSON.stringify(result), { status: 200 })
|
||||
} catch (error) {
|
||||
console.error('PATCH /api/account/main error:', error)
|
||||
return new Response(JSON.stringify({ error: 'Internal Server Error' }), {
|
||||
status: 500,
|
||||
})
|
||||
|
||||
@@ -2,7 +2,7 @@ import { NextRequest } from 'next/server'
|
||||
import { getServerSession } from 'next-auth'
|
||||
import { authOptions } from '@/app/api/auth/[...nextauth]/route'
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
export async function GET() {
|
||||
try {
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/plans/`, {
|
||||
method: 'GET',
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { NextRequest } from 'next/server'
|
||||
import { getServerSession } from 'next-auth'
|
||||
import { authOptions } from '@/app/api/auth/[...nextauth]/route'
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
export async function GET() {
|
||||
try {
|
||||
const session = await getServerSession(authOptions)
|
||||
if (!session) {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { NextRequest } from 'next/server'
|
||||
import { getServerSession } from 'next-auth'
|
||||
import { authOptions } from '@/app/api/auth/[...nextauth]/route'
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
export async function GET() {
|
||||
try {
|
||||
const session = await getServerSession(authOptions)
|
||||
if (!session) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import NextAuth, { NextAuthOptions } from 'next-auth'
|
||||
import GoogleProvider from 'next-auth/providers/google'
|
||||
import CredentialsProvider from 'next-auth/providers/credentials'
|
||||
import { JWT } from 'next-auth/jwt'
|
||||
|
||||
@@ -75,21 +74,18 @@ export const authOptions: NextAuthOptions = {
|
||||
throw new Error('Все поля обязательны для заполнения')
|
||||
}
|
||||
|
||||
const res = await fetch(
|
||||
`${process.env.BACKEND_URL}/register/clients/`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
email: credentials.email,
|
||||
password: credentials.password,
|
||||
name: credentials.name,
|
||||
surname: credentials.surname,
|
||||
phone_number: credentials.phone_number,
|
||||
privacy_accepted: credentials.privacy_accepted === 'true',
|
||||
}),
|
||||
}
|
||||
)
|
||||
const res = await fetch(`${process.env.BACKEND_URL}/register/clients/`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
email: credentials.email,
|
||||
password: credentials.password,
|
||||
name: credentials.name,
|
||||
surname: credentials.surname,
|
||||
phone_number: credentials.phone_number,
|
||||
privacy_accepted: credentials.privacy_accepted === 'true',
|
||||
}),
|
||||
})
|
||||
|
||||
const data = await res.json()
|
||||
|
||||
@@ -126,17 +122,14 @@ export const authOptions: NextAuthOptions = {
|
||||
},
|
||||
async authorize(credentials) {
|
||||
try {
|
||||
const res = await fetch(
|
||||
`${process.env.BACKEND_URL}/auth/login/clients/`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
email: credentials?.email,
|
||||
password: credentials?.password,
|
||||
}),
|
||||
}
|
||||
)
|
||||
const res = await fetch(`${process.env.BACKEND_URL}/auth/login/clients/`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
email: credentials?.email,
|
||||
password: credentials?.password,
|
||||
}),
|
||||
})
|
||||
|
||||
const data = await res.json()
|
||||
|
||||
|
||||
@@ -113,8 +113,8 @@ export default async function Home() {
|
||||
</div>
|
||||
<div className="px-2 text-center text-sm text-gray-600 sm:px-4 sm:text-base md:px-7">
|
||||
В форме поиска укажите откуда и куда Вам нужно доставить посылку, нажмите кнопку
|
||||
"найти перевозчика". Если по вашему запросу ничего не найдено - Вы можете сами
|
||||
разместить объявление и тогда перевозчики Вас найдут.
|
||||
"найти перевозчика". Если по вашему запросу ничего не найдено - Вы можете
|
||||
сами разместить объявление и тогда перевозчики Вас найдут.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -210,8 +210,8 @@ export default async function Home() {
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="text-center text-xl font-semibold sm:text-left">Экономия времени</div>
|
||||
<span className="text-center text-base text-gray-600 sm:text-left">
|
||||
Не нужно искать группы, чаты, и кидать "клич", а просто достаточно разместить
|
||||
объявление на сайте.
|
||||
Не нужно искать группы, чаты, и кидать "клич", а просто достаточно
|
||||
разместить объявление на сайте.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { StaticImageData } from 'next/image'
|
||||
import { IconType } from 'react-icons'
|
||||
|
||||
export interface TextInputProps {
|
||||
@@ -248,13 +247,13 @@ export interface Lead {
|
||||
name: string
|
||||
phone_number: string
|
||||
email: string
|
||||
route: Route
|
||||
moving_user: number
|
||||
route?: Route
|
||||
moving_user?: number
|
||||
moving_price: string
|
||||
moving_date: string
|
||||
comment?: string
|
||||
created_at: string
|
||||
status: 'actual' | 'canceled' | 'completed'
|
||||
created_at?: string
|
||||
status?: 'actual' | 'canceled' | 'completed'
|
||||
}
|
||||
|
||||
export interface LeadPageProps extends Lead {
|
||||
|
||||
@@ -5,7 +5,11 @@ import TextInput from './ui/TextInput'
|
||||
import axios from 'axios'
|
||||
import { useRouter } from 'next/navigation'
|
||||
|
||||
export default function AddressSelector() {
|
||||
interface AddressSelectorProps {
|
||||
is_search?: boolean
|
||||
}
|
||||
|
||||
export default function AddressSelector({ is_search }: AddressSelectorProps) {
|
||||
const router = useRouter()
|
||||
const [fromAddress, setFromAddress] = useState('')
|
||||
const [toAddress, setToAddress] = useState('')
|
||||
@@ -75,6 +79,7 @@ export default function AddressSelector() {
|
||||
|
||||
return (
|
||||
<div className="my-2 w-full rounded-xl bg-white p-4 shadow-lg sm:my-4 sm:p-6">
|
||||
{is_search && <h2 className="mb-4 text-lg font-bold">Может поищем по городу?</h2>}
|
||||
<div className="flex flex-col gap-4 sm:flex-row sm:items-end sm:gap-3">
|
||||
<div className="w-full min-w-0 sm:flex-[3] sm:px-1">
|
||||
<TextInput
|
||||
@@ -109,7 +114,7 @@ export default function AddressSelector() {
|
||||
<button
|
||||
onClick={() => handleSearch('mover')}
|
||||
disabled={isLoading}
|
||||
className={`w-full rounded-2xl p-4 text-center whitespace-nowrap text-white sm:w-auto sm:flex-1 ${
|
||||
className={`w-full cursor-pointer rounded-2xl p-4 text-center whitespace-nowrap text-white sm:w-auto sm:flex-1 ${
|
||||
isLoading ? 'bg-orange/50 cursor-not-allowed' : 'bg-orange hover:bg-orange/80'
|
||||
}`}
|
||||
>
|
||||
@@ -118,7 +123,7 @@ export default function AddressSelector() {
|
||||
<button
|
||||
onClick={() => handleSearch('customer')}
|
||||
disabled={isLoading}
|
||||
className={`w-full rounded-2xl p-4 text-center whitespace-nowrap sm:w-auto sm:flex-1 ${
|
||||
className={`w-full cursor-pointer rounded-2xl p-4 text-center whitespace-nowrap sm:w-auto sm:flex-1 ${
|
||||
isLoading
|
||||
? 'cursor-not-allowed bg-gray-100 text-gray-400'
|
||||
: 'bg-gray-100 text-gray-800 hover:bg-gray-200'
|
||||
|
||||
@@ -62,14 +62,14 @@ const LeadPopup = ({ id, isOpen, onClose, onSuccess }: LeadPopupProps) => {
|
||||
//форма инициализируется до того, как данные пользователя загружаются из стора, поэтому нужно обновлять значения формы при загрузке данных пользователя
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
setValues({
|
||||
...values,
|
||||
setValues(prev => ({
|
||||
...prev,
|
||||
name: user.name,
|
||||
phone_number: user.phone_number || '',
|
||||
email: user.email || '',
|
||||
})
|
||||
}))
|
||||
}
|
||||
}, [user])
|
||||
}, [user, setValues])
|
||||
|
||||
return (
|
||||
<Modal title="Откликнуться на заявку" isOpen={isOpen} onClose={onClose}>
|
||||
|
||||
Reference in New Issue
Block a user