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