initiate drf app
This commit is contained in:
308
frontend/app/(urls)/search/components/SearchCard.tsx
Normal file
308
frontend/app/(urls)/search/components/SearchCard.tsx
Normal file
@@ -0,0 +1,308 @@
|
||||
import React from 'react'
|
||||
import Image, { StaticImageData } from 'next/image'
|
||||
import Button from '@/components/ui/Button'
|
||||
import { SearchCardProps } from '@/app/types/index'
|
||||
|
||||
const SearchCard = ({
|
||||
id,
|
||||
username,
|
||||
userImg,
|
||||
start_point,
|
||||
country_from,
|
||||
country_from_icon,
|
||||
country_from_code,
|
||||
end_point,
|
||||
country_to,
|
||||
country_to_icon,
|
||||
country_to_code,
|
||||
cargo_type,
|
||||
user_request,
|
||||
user_comment,
|
||||
moving_type,
|
||||
estimated_date,
|
||||
day_out,
|
||||
day_in,
|
||||
}: SearchCardProps) => {
|
||||
const getUserRequestStyles = () => {
|
||||
if (user_request === 'Нужен перевозчик') {
|
||||
return 'text-[#065bff]'
|
||||
}
|
||||
return 'text-[#45c226]'
|
||||
}
|
||||
|
||||
const setMovingTypeIcon = () => {
|
||||
if (moving_type === 'Авиатранспорт') {
|
||||
return '/images/airplane.png'
|
||||
}
|
||||
return '/images/car.png'
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* десктоп */}
|
||||
<div className="hidden sm:block">
|
||||
<div className="bg-white rounded-xl shadow-lg p-6 w-full my-4">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-5">
|
||||
<div className="w-16 h-16 bg-gray-200 rounded-full flex items-center justify-center">
|
||||
<Image
|
||||
src={userImg}
|
||||
alt={username}
|
||||
width={52}
|
||||
height={52}
|
||||
className="rounded-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="text-base font-semibold">{username}</div>
|
||||
<div className="text-gray-500">|</div>
|
||||
<div
|
||||
className={`text-base font-semibold ${getUserRequestStyles()}`}
|
||||
>
|
||||
{user_request}
|
||||
</div>
|
||||
<div className="ml-1">
|
||||
Тип посылки:{' '}
|
||||
<span className="text-orange font-semibold ml-1">
|
||||
{cargo_type}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
text="Откликнуться"
|
||||
className="bg-orange hover:bg-orange/80 text-white px-10 py-3 text-base font-semibold transition-colors cursor-pointer"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="bg-[#f8f8f8] rounded-lg p-5">
|
||||
<div className="flex items-baseline gap-2">
|
||||
<span className="text-gray-600">{user_comment}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-gray-500 text-sm flex justify-end pt-2">
|
||||
Объявление № {id}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between mt-6">
|
||||
<div className="flex flex-col">
|
||||
{user_request === 'Нужен перевозчик' ? (
|
||||
<span className="text-gray-500">Забрать из:</span>
|
||||
) : (
|
||||
<span className="text-gray-500">Выезжаю из:</span>
|
||||
)}
|
||||
<div className="flex flex-col">
|
||||
<div className="flex items-center">
|
||||
<Image
|
||||
src={country_from_icon}
|
||||
width={26}
|
||||
height={13}
|
||||
alt={country_from_code}
|
||||
/>
|
||||
<span className="text-gray-400 pr-2 pl-1">
|
||||
{country_from_code}
|
||||
</span>
|
||||
<span className="text-base font-semibold">
|
||||
{start_point} / {country_from}
|
||||
</span>
|
||||
</div>
|
||||
{user_request === 'Могу перевезти' && (
|
||||
<div className="text-sm text-gray-500 mt-1">
|
||||
<span className="text-sm font-normal">Отправление:</span>{' '}
|
||||
<span className="text-sm font-semibold">
|
||||
{day_out?.toLocaleDateString()}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<span className="text-base font-semibold">{moving_type}</span>
|
||||
<Image
|
||||
src={setMovingTypeIcon()}
|
||||
width={15}
|
||||
height={15}
|
||||
alt="route vector"
|
||||
className="w-[15px] h-[15px] object-contain"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between w-[500px] mx-auto my-1">
|
||||
<Image
|
||||
src="/images/vector.svg"
|
||||
width={500}
|
||||
height={6}
|
||||
alt="route vector"
|
||||
className="absolute"
|
||||
/>
|
||||
<div className="w-5 h-5 rounded-full bg-white border-3 border-[#065bff] relative z-10" />
|
||||
<div className="w-5 h-5 rounded-full bg-white border-3 border-[#45c226] relative z-10" />
|
||||
</div>
|
||||
|
||||
{user_request === 'Нужен перевозчик' && (
|
||||
<div className="text-sm text-gray-500">
|
||||
<span className="text-sm font-normal">Дата доставки:</span>{' '}
|
||||
<span className="text-sm font-semibold">
|
||||
{estimated_date.toLocaleDateString()}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col -mb-[14px]">
|
||||
{user_request === 'Нужен перевозчик' ? (
|
||||
<div className="text-base text-gray-500">Доставить в:</div>
|
||||
) : (
|
||||
<div className="text-base text-gray-500">Прибываю в:</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col">
|
||||
<div className="flex items-center">
|
||||
<Image
|
||||
src={country_to_icon}
|
||||
width={26}
|
||||
height={13}
|
||||
alt={country_to_code}
|
||||
/>
|
||||
<span className="text-gray-400 pr-2 pl-1">
|
||||
{country_to_code}
|
||||
</span>
|
||||
<span className="text-base font-semibold">
|
||||
{end_point} / {country_to}
|
||||
</span>
|
||||
</div>
|
||||
{user_request === 'Могу перевезти' && (
|
||||
<div className="text-sm text-gray-500">
|
||||
<span className="text-sm font-normal">Прибытие:</span>{' '}
|
||||
<span className="text-sm font-semibold">
|
||||
{day_in?.toLocaleDateString()}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* мобилка */}
|
||||
<div className="block sm:hidden">
|
||||
<div className="bg-white rounded-xl shadow-lg p-4 w-full my-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className={`text-sm font-semibold ${getUserRequestStyles()}`}>
|
||||
{user_request}
|
||||
</div>
|
||||
<div className="text-sm font-semibold">
|
||||
Тип посылки: <span className="text-orange">{cargo_type}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row items-center justify-between mt-5 mb-2 gap-3">
|
||||
<div className="min-w-[64px] w-16 h-16 bg-gray-200 rounded-full flex items-center justify-center shrink-0">
|
||||
<Image
|
||||
src={userImg}
|
||||
alt={username}
|
||||
width={52}
|
||||
height={52}
|
||||
className="rounded-full object-cover aspect-square w-[52px] h-[52px]"
|
||||
/>
|
||||
</div>
|
||||
<div className="bg-[#f8f8f8] rounded-lg text-sm font-normal p-4 flex-1">
|
||||
{user_comment}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-gray-500 text-xs flex justify-end">
|
||||
Объявление № {id}
|
||||
</div>
|
||||
|
||||
{user_request === 'Нужен перевозчик' ? (
|
||||
<span className="text-gray-500 pl-7 text-sm">Забрать из:</span>
|
||||
) : (
|
||||
<span className="text-gray-500 pl-7 text-sm">Выезжаю из:</span>
|
||||
)}
|
||||
<div className="flex flex-row items-stretch mt-4 mb-2 gap-4">
|
||||
<div className="flex flex-col items-center h-[150px] relative">
|
||||
<div className="h-full w-[10px] flex items-center justify-center relative">
|
||||
<Image
|
||||
src="/images/vectormob.png"
|
||||
width={6}
|
||||
height={100}
|
||||
alt="route vector"
|
||||
className="absolute h-[150px] w-auto"
|
||||
/>
|
||||
<div className="absolute -top-[10px] w-4 h-4 rounded-full bg-white border-3 border-[#065bff] z-10" />
|
||||
<div className="absolute -bottom-[10px] w-4 h-4 rounded-full bg-white border-3 border-[#45c226] z-10" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 flex flex-col justify-between">
|
||||
<div className="flex items-center -mt-[14px]">
|
||||
<Image
|
||||
src={country_from_icon}
|
||||
width={26}
|
||||
height={13}
|
||||
alt={country_from_code}
|
||||
/>
|
||||
<span className="text-gray-400 text-sm pr-2 pl-1">
|
||||
{country_from_code}
|
||||
</span>
|
||||
<span className="text-base font-semibold">
|
||||
{start_point} / {country_from}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col ">
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-base">{moving_type}</span>
|
||||
<Image
|
||||
src={setMovingTypeIcon()}
|
||||
width={15}
|
||||
height={15}
|
||||
alt="route vector"
|
||||
className="w-[15px] h-[15px] object-contain"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-[165px] h-[2px] bg-gray-200 my-2" />
|
||||
<div className="text-sm">
|
||||
Дата доставки: {estimated_date.toLocaleDateString()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col -mb-[14px]">
|
||||
{user_request === 'Нужен перевозчик' ? (
|
||||
<div className="text-sm text-gray-500">Доставить в:</div>
|
||||
) : (
|
||||
<div className="text-sm text-gray-500">Прибываю в:</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-center">
|
||||
<Image
|
||||
src={country_to_icon}
|
||||
width={26}
|
||||
height={13}
|
||||
alt={country_to_code}
|
||||
/>
|
||||
<span className="text-gray-400 pr-2 pl-1">
|
||||
{country_to_code}
|
||||
</span>
|
||||
<span className="text-base font-semibold">
|
||||
{end_point} / {country_to}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{user_request === 'Могу перевезти' && (
|
||||
<div className="text-sm text-gray-500 mt-3 ml-7">
|
||||
<span className="text-sm font-normal">Прибытие:</span>{' '}
|
||||
<span className="text-sm font-semibold">
|
||||
{day_in?.toLocaleDateString()}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SearchCard
|
||||
7
frontend/app/(urls)/search/page.tsx
Normal file
7
frontend/app/(urls)/search/page.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import React from 'react'
|
||||
|
||||
const SearchPage = () => {
|
||||
return <div>SearchPage</div>
|
||||
}
|
||||
|
||||
export default SearchPage
|
||||
BIN
frontend/app/favicon.ico
Normal file
BIN
frontend/app/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
27
frontend/app/globals.css
Normal file
27
frontend/app/globals.css
Normal file
@@ -0,0 +1,27 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
:root {
|
||||
--background: #eeebeb;
|
||||
--foreground: #171717;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--color-orange: #ff613a;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--background: #eeebeb;
|
||||
--foreground: #171717;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
37
frontend/app/layout.tsx
Normal file
37
frontend/app/layout.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { Geist, Geist_Mono } from 'next/font/google'
|
||||
import './globals.css'
|
||||
import Header from '@/components/Header'
|
||||
import Footer from '@/components/Footer'
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: '--font-geist-sans',
|
||||
subsets: ['latin'],
|
||||
})
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: '--font-geist-mono',
|
||||
subsets: ['latin'],
|
||||
})
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Отправка посылок в любую точку мира | TripWB',
|
||||
description:
|
||||
'Международная отправка посылок ✓ Отправка посылки в любую точку планеты ✓ Приемлемая цена отправки посылки ✓ Доставка в кратчайшие сроки ➡️ Обращайтесь к нам',
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en" className={`${geistSans.variable} ${geistMono.variable}`}>
|
||||
<body className="min-h-screen flex flex-col">
|
||||
<Header />
|
||||
<main className="flex-grow">{children}</main>
|
||||
<Footer />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
245
frontend/app/page.tsx
Normal file
245
frontend/app/page.tsx
Normal file
@@ -0,0 +1,245 @@
|
||||
import React from 'react'
|
||||
import Image from 'next/image'
|
||||
import AddressSelector from '@/components/AddressSelector'
|
||||
import SearchCard from '@/app/(urls)/search/components/SearchCard'
|
||||
import FAQ from '@/components/FAQ'
|
||||
import { data } from '@/app/staticData'
|
||||
import { routes } from '@/app/staticData'
|
||||
import Button from '@/components/ui/Button'
|
||||
import News from '@/components/News'
|
||||
import { getFAQs } from '@/lib/fetchFAQ'
|
||||
|
||||
export default async function Home() {
|
||||
const faqs = await getFAQs()
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center max-w-[93%] mx-auto">
|
||||
{/* main */}
|
||||
<div className="flex items-center justify-center space-x-16">
|
||||
<div>
|
||||
<Image
|
||||
src="/images/box1.png"
|
||||
alt="main"
|
||||
width={220}
|
||||
height={220}
|
||||
className="hidden sm:block"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center space-y-5">
|
||||
<h1 className="text-3xl sm:text-4xl text-center font-bold">
|
||||
<div className="pb-1">
|
||||
Сервис по <span className="text-orange">поиску</span>{' '}
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-orange">перевозчиков</span> посылок
|
||||
</div>
|
||||
</h1>
|
||||
<p className="text-base sm:text-lg text-center pb-3">
|
||||
Доставка посылок с попутчиками: от документов до крупногабаритных
|
||||
грузов
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<Image
|
||||
src="/images/box2.png"
|
||||
alt="main"
|
||||
width={220}
|
||||
height={220}
|
||||
className="hidden sm:block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* форма на серч */}
|
||||
<AddressSelector />
|
||||
|
||||
<div className="text-lg font-normal text-[#272424] underline decoration-orange underline-offset-4 mb-20 hover:text-orange transition-colors cursor-pointer">
|
||||
Я могу взять с собой посылку
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center justify-center mb-8">
|
||||
<h2 className="text-4xl text-center font-bold">Все объявления</h2>
|
||||
<div className="text-base my-3">
|
||||
На нашем сайте размещено уже{' '}
|
||||
<span className="text-orange">{routes}</span> объявлений по отправке и
|
||||
перевозке посылок
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* первые пять серч карточек -- бекенд??? */}
|
||||
<div className="w-full max-w-[1250px] mx-auto">
|
||||
<div className="grid grid-cols-1 gap-4 w-full">
|
||||
{data.map((card) => (
|
||||
<SearchCard key={card.id} {...card} />
|
||||
))}
|
||||
</div>
|
||||
<div className="flex justify-center py-4">
|
||||
<Button
|
||||
text="Разместить объявление"
|
||||
className=" bg-orange text-white text-xl font-semibold px-6 py-3 rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* how it works */}
|
||||
<div className="w-full max-w-[1250px] mx-auto my-20">
|
||||
<h2 className="text-4xl text-center font-bold">Как это работает</h2>
|
||||
<div className="flex flex-col items-center justify-center text-base font-medium text-center py-4 mb-4">
|
||||
<span>
|
||||
TWB - это сервис, созданный для того, чтобы отправитель и перевозчик
|
||||
нашли друг-друга!
|
||||
</span>
|
||||
<span>
|
||||
Наш сервис предлагает вам прямые контакты, а не является посредником
|
||||
!
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col sm:flex-row justify-center items-center sm:items-start sm:space-x-4 md:space-x-8 lg:space-x-20 space-y-8 sm:space-y-0">
|
||||
<div className="flex flex-col items-center w-full sm:w-1/3 px-4 sm:px-2">
|
||||
<div className="flex flex-col items-center h-[260px] sm:h-[300px]">
|
||||
<Image
|
||||
src="/images/laptop.png"
|
||||
alt="laptop"
|
||||
width={230}
|
||||
height={230}
|
||||
className="mb-6 w-[180px] h-[180px] sm:w-[230px] sm:h-[230px]"
|
||||
/>
|
||||
<div className="text-xl sm:text-2xl font-semibold text-center">
|
||||
Найдите перевозчика
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm sm:text-base text-gray-600 text-center px-2 sm:px-4 md:px-7">
|
||||
В форме поиска укажите откуда и куда Вам нужно доставить посылку,
|
||||
нажмите кнопку "найти перевозчика". Если по вашему запросу ничего
|
||||
не найдено - Вы можете сами разместить объявление и тогда
|
||||
перевозчики Вас найдут.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center w-full sm:w-1/3 px-4 sm:px-2">
|
||||
<div className="flex flex-col items-center h-[260px] sm:h-[300px]">
|
||||
<Image
|
||||
src="/images/phone.png"
|
||||
alt="phone"
|
||||
width={230}
|
||||
height={230}
|
||||
className="mb-6 w-[180px] h-[180px] sm:w-[230px] sm:h-[230px]"
|
||||
/>
|
||||
<div className="text-xl sm:text-2xl font-semibold text-center">
|
||||
Свяжитесь с перевозчиком
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm sm:text-base text-gray-600 text-center px-2 sm:px-4 md:px-7">
|
||||
Нажмите на кнопку «ОТКЛИКНУТЬСЯ», свяжитесь и договоритесь о месте
|
||||
встречи и условиях перевозки
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center w-full sm:w-1/3 px-4 sm:px-2">
|
||||
<div className="flex flex-col items-center h-[260px] sm:h-[300px]">
|
||||
<Image
|
||||
src="/images/package.png"
|
||||
alt="package"
|
||||
width={230}
|
||||
height={230}
|
||||
className="mb-6 w-[180px] h-[180px] sm:w-[230px] sm:h-[230px]"
|
||||
/>
|
||||
<div className="text-xl sm:text-2xl font-semibold text-center">
|
||||
Передайте посылку
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm sm:text-base text-gray-600 text-center px-2 sm:px-4 md:px-7">
|
||||
Встречайтесь, знакомьтесь и передавайте посылку
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-center pt-8 sm:pt-10">
|
||||
<Button
|
||||
text="Отправить посылку"
|
||||
className="bg-orange hover:bg-orange/80 text-white text-base sm:text-lg px-8 sm:px-12 py-2.5 sm:py-3 rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* преимущества */}
|
||||
<div className="w-full max-w-[1250px] mx-auto my-10 px-4 sm:px-6">
|
||||
<h2 className="text-3xl sm:text-4xl text-center font-bold mb-12">
|
||||
Преимущества сервиса
|
||||
</h2>
|
||||
<div className="flex flex-col lg:flex-row items-center justify-between gap-6 lg:gap-4">
|
||||
<div className="flex flex-col w-full lg:w-1/4 space-y-4">
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="text-xl text-center sm:text-left font-semibold">
|
||||
Прямой контакт
|
||||
</div>
|
||||
<span className="text-base text-center sm:text-left text-gray-600">
|
||||
Общаешься напрямую с перевозчиком, никаких посредников
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="text-xl text-center sm:text-left font-semibold">
|
||||
Своя цена
|
||||
</div>
|
||||
<span className="text-base text-center sm:text-left text-gray-600">
|
||||
Стоимость перевозки самостоятельно обговариваете с перевозчиком.
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="text-xl text-center sm:text-left font-semibold">
|
||||
Нет доп. расходов
|
||||
</div>
|
||||
<span className="text-base text-center sm:text-left text-gray-600">
|
||||
Никаких комиссий, переплат и дополнительных расходов за
|
||||
отправку.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full lg:w-auto px-4 sm:px-0">
|
||||
<Image
|
||||
src="/images/advantage.svg"
|
||||
alt="advantages"
|
||||
width={648}
|
||||
height={403}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col w-full lg:w-1/4 space-y-4">
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="text-xl text-center sm:text-left font-semibold">
|
||||
Уведомления
|
||||
</div>
|
||||
<span className="text-base text-center sm:text-left text-gray-600">
|
||||
Можешь самостоятельно найти перевозчиков или разместить
|
||||
объявление на сайте.
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="text-xl text-center sm:text-left font-semibold">
|
||||
Удобный поиск
|
||||
</div>
|
||||
<span className="text-base text-center sm:text-left text-gray-600">
|
||||
Как только по твоему объявлению найдется перевозчик мы сообщим
|
||||
на E-mail.
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-1">
|
||||
<div className="text-xl text-center sm:text-left font-semibold">
|
||||
Экономия времени
|
||||
</div>
|
||||
<span className="text-base text-center sm:text-left text-gray-600">
|
||||
Не нужно искать группы, чаты, и кидать "клич", а просто
|
||||
достаточно разместить объявление на сайте.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* FAQ */}
|
||||
<FAQ faqs={faqs} />
|
||||
|
||||
{/* новости */}
|
||||
<News />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
77
frontend/app/staticData/index.ts
Normal file
77
frontend/app/staticData/index.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import avatar from '../../public/images/avatar.png'
|
||||
import belarusIcon from '../../public/images/belarus.png'
|
||||
import russiaIcon from '../../public/images/russia.png'
|
||||
|
||||
const userImg = avatar
|
||||
const blIcon = belarusIcon
|
||||
const ruIcon = russiaIcon
|
||||
|
||||
export const routes = 12845
|
||||
|
||||
export const data = [
|
||||
{
|
||||
id: 1123,
|
||||
username: 'John Doe',
|
||||
userImg: userImg,
|
||||
start_point: 'Минск',
|
||||
country_from: 'Беларусь',
|
||||
end_point: 'Москва',
|
||||
country_to: 'Россия',
|
||||
cargo_type: 'Документы',
|
||||
user_request: 'Нужен перевозчик',
|
||||
user_comment: 'Нужно перевезти документы из Минска в Москву',
|
||||
country_from_icon: blIcon,
|
||||
country_to_icon: ruIcon,
|
||||
country_from_code: 'BY',
|
||||
country_to_code: 'RU',
|
||||
moving_type: 'Авиатранспорт',
|
||||
estimated_date: new Date(2025, 4, 15),
|
||||
},
|
||||
{
|
||||
id: 2423,
|
||||
username: 'John Doe',
|
||||
userImg: userImg,
|
||||
start_point: 'Минск',
|
||||
country_from: 'Беларусь',
|
||||
end_point: 'Москва',
|
||||
country_to: 'Россия',
|
||||
cargo_type: 'Документы',
|
||||
user_request: 'Могу перевезти',
|
||||
user_comment: 'Нужно перевезти документы из Минска в Москву',
|
||||
moving_type: 'Автоперевозка',
|
||||
estimated_date: new Date(2025, 5, 18),
|
||||
country_from_icon: blIcon,
|
||||
country_to_icon: ruIcon,
|
||||
country_from_code: 'BY',
|
||||
country_to_code: 'RU',
|
||||
day_out: new Date(2025, 5, 21),
|
||||
day_in: new Date(2025, 5, 25),
|
||||
},
|
||||
]
|
||||
|
||||
export const news = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Высокий уровень вовлечения представителей целевой аудитории',
|
||||
description:
|
||||
'Значимость этих проблем настолько очевидна, что экономическая повестка сегодняшнего дня не оставляет шанса для',
|
||||
image: '/images/news.svg',
|
||||
slug: 'vysoki-uroven-vlezheniya-predstaviteley-tselyovoi-auditorii',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Высокий уровень вовлечения представителей целевой аудитории',
|
||||
description:
|
||||
'Значимость этих проблем настолько очевидна, что экономическая повестка сегодняшнего дня не оставляет шанса для',
|
||||
image: '/images/news.svg',
|
||||
slug: 'vysoki-uroven-vlezheniya-predstaviteley-tselyovoi-auditorii',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Высокий уровень вовлечения представителей целевой аудитории',
|
||||
description:
|
||||
'Значимость этих проблем настолько очевидна, что экономическая повестка сегодняшнего дня не оставляет шанса дляЗначимость этих проблем настолько очевидна, что экономическая повестка сегодняшнего дня не оставляет шанса дляЗначимость этих проблем настолько очевидна, что экономическая повестка сегодняшнего дня не оставляет шанса дляЗначимость этих проблем настолько очевидна, что экономическая повестка сегодняшнего дня не оставляет шанса для',
|
||||
image: '/images/news.svg',
|
||||
slug: 'vysoki-uroven-vlezheniya-predstaviteley-tselyovoi-auditorii',
|
||||
},
|
||||
]
|
||||
56
frontend/app/types/index.ts
Normal file
56
frontend/app/types/index.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import Image, { StaticImageData } from 'next/image'
|
||||
|
||||
export interface TextInputProps {
|
||||
value: string
|
||||
handleChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
|
||||
label?: string
|
||||
placeholder?: string
|
||||
name: string
|
||||
type?: 'text' | 'email' | 'password'
|
||||
className?: string
|
||||
maxLength?: number
|
||||
tooltip?: string | React.ReactNode
|
||||
}
|
||||
|
||||
export interface ButtonProps {
|
||||
onClick?: () => void
|
||||
className?: string
|
||||
text?: string
|
||||
type?: 'button'
|
||||
}
|
||||
|
||||
export interface SearchCardProps {
|
||||
id: number
|
||||
username: string
|
||||
userImg: string | StaticImageData
|
||||
start_point: string
|
||||
country_from: string
|
||||
country_from_icon: string | StaticImageData
|
||||
country_from_code: string
|
||||
end_point: string
|
||||
country_to: string
|
||||
country_to_icon: string | StaticImageData
|
||||
country_to_code: string
|
||||
cargo_type: string
|
||||
user_request: string
|
||||
moving_type: string
|
||||
estimated_date: Date
|
||||
user_comment: string
|
||||
day_out?: Date
|
||||
day_in?: Date
|
||||
}
|
||||
|
||||
export interface AccordionProps {
|
||||
title: string
|
||||
content: string | React.ReactNode
|
||||
}
|
||||
|
||||
export interface FAQ {
|
||||
id: number
|
||||
title: string
|
||||
content: string | React.ReactNode
|
||||
}
|
||||
|
||||
export interface FAQProps {
|
||||
faqs: FAQ[]
|
||||
}
|
||||
Reference in New Issue
Block a user