diff --git a/frontend/app/(urls)/search/components/SearchCard.tsx b/frontend/app/(urls)/search/components/SearchCard.tsx
index dc3e547..56af4b9 100644
--- a/frontend/app/(urls)/search/components/SearchCard.tsx
+++ b/frontend/app/(urls)/search/components/SearchCard.tsx
@@ -1,8 +1,13 @@
-import React from 'react'
+'use client'
+
+import React, { useState } from 'react'
import Image from 'next/image'
import Button from '@/components/ui/Button'
import { SearchCardProps } from '@/app/types'
import noPhoto from '../../../../public/images/noPhoto.png'
+import LeadPopup from '@/components/popups/LeadPopup'
+import useUserStore from '@/app/store/userStore'
+import { useRouter } from 'next/navigation'
const formatDateTime = (dateTimeString: string): string => {
const date = new Date(dateTimeString)
@@ -41,6 +46,18 @@ const SearchCard = ({
country_from_icon,
country_to_icon,
}: SearchCardProps) => {
+ const [isLeadPopupOpen, setIsLeadPopupOpen] = useState(false)
+ const { isAuthenticated } = useUserStore()
+ const router = useRouter()
+
+ const handleLeadClick = () => {
+ if (!isAuthenticated) {
+ router.push('/login')
+ return
+ }
+ setIsLeadPopupOpen(true)
+ }
+
const getUserRequestStyles = () => {
if (owner_type === 'customer') {
return 'text-[#065bff]'
@@ -88,6 +105,7 @@ const SearchCard = ({
@@ -204,7 +222,7 @@ const SearchCard = ({
{userRequest}
- Тип посылки: {formatted_cargo_type}
+ {formatted_cargo_type}
@@ -243,7 +261,7 @@ const SearchCard = ({
-
-
Дата доставки: {formatted_arrival}
+
+
Дата доставки: {formatDateTime(formatted_arrival)}
@@ -280,7 +298,7 @@ const SearchCard = ({
{formatDateTime(formatted_arrival)}
)}
+
+
+
+
+ setIsLeadPopupOpen(false)}
+ onSuccess={() => {
+ setIsLeadPopupOpen(false)
+ }}
+ />
>
)
}
diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx
index 972dedb..023e499 100644
--- a/frontend/app/page.tsx
+++ b/frontend/app/page.tsx
@@ -4,7 +4,6 @@ import AddressSelector from '@/components/AddressSelector'
import SearchCard from '@/app/(urls)/search/components/SearchCard'
import FAQ from '@/components/FAQ'
import { routes } from '@/app/constants'
-import Button from '@/components/ui/Button'
import News from '@/components/News'
import { getFAQs } from '@/lib/main/fetchFAQ'
import { getNews } from '@/lib/main/fetchNews'
@@ -71,7 +70,6 @@ export default async function Home() {
- {/* первые пять серч карточек -- бекенд??? */}
{Array.isArray(latestRoutes) && latestRoutes.length > 0 ? (
@@ -81,10 +79,12 @@ export default async function Home() {
)}
-
+ >
+ Разместить объявление
+
@@ -154,10 +154,12 @@ export default async function Home() {
-
+ >
+ Отправить посылку
+
diff --git a/frontend/components/popups/LeadPopup.tsx b/frontend/components/popups/LeadPopup.tsx
new file mode 100644
index 0000000..e73f1b9
--- /dev/null
+++ b/frontend/components/popups/LeadPopup.tsx
@@ -0,0 +1,139 @@
+import React, { useEffect } from 'react'
+import Modal from '../ui/Modal'
+import Button from '../ui/Button'
+import { useForm } from '@/app/hooks/useForm'
+import showToast from '../ui/Toast'
+import TextInput from '../ui/TextInput'
+import TextAreaInput from '../ui/TextAreaInput'
+import PhoneInput from '../ui/PhoneInput'
+import useUserStore from '@/app/store/userStore'
+
+const validationRules = {
+ name: { required: true },
+ phone_number: { required: true },
+ email: { required: true },
+ price: { required: false },
+ deliveryTime: { required: false },
+ comment: { required: false },
+}
+
+interface LeadPopupProps {
+ id: number
+ isOpen: boolean
+ onClose: () => void
+ onSuccess: () => void
+}
+
+const LeadPopup = ({ id, isOpen, onClose, onSuccess }: LeadPopupProps) => {
+ const { user } = useUserStore()
+
+ const { values, handleChange, handleSubmit, setValues } = useForm(
+ {
+ name: user?.name || '',
+ phone_number: user?.phone_number || '',
+ email: user?.email || '',
+ price: '',
+ deliveryTime: '',
+ comment: '',
+ id: id,
+ },
+ validationRules,
+ async values => {
+ try {
+ // await sendLead(values)
+ showToast({
+ type: 'success',
+ message: 'Сообщение отправлено!',
+ })
+ onSuccess()
+ } catch {
+ showToast({
+ type: 'error',
+ message: 'Упс, что то пошло не так...',
+ })
+ }
+ }
+ )
+
+ //форма инициализируется до того, как данные пользователя загружаются из стора, поэтому нужно обновлять значения формы при загрузке данных пользователя
+ useEffect(() => {
+ if (user) {
+ setValues({
+ ...values,
+ name: user.name,
+ phone_number: user.phone_number || '',
+ email: user.email || '',
+ })
+ }
+ }, [user])
+
+ return (
+
+
+
+ )
+}
+
+export default LeadPopup
diff --git a/frontend/components/ui/Modal.tsx b/frontend/components/ui/Modal.tsx
new file mode 100644
index 0000000..04c5746
--- /dev/null
+++ b/frontend/components/ui/Modal.tsx
@@ -0,0 +1,67 @@
+'use client'
+
+import React, { useEffect } from 'react'
+import { IoClose } from 'react-icons/io5'
+
+interface ModalProps {
+ isOpen: boolean
+ onClose: () => void
+ title: string
+ children: React.ReactNode
+}
+
+const Modal: React.FC = ({ isOpen, onClose, title, children }) => {
+ useEffect(() => {
+ const handleEscape = (e: KeyboardEvent) => {
+ if (e.key === 'Escape') {
+ onClose()
+ }
+ }
+
+ if (isOpen) {
+ document.addEventListener('keydown', handleEscape)
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth
+ document.body.style.paddingRight = `${scrollbarWidth}px`
+ document.body.style.overflow = 'hidden'
+ }
+
+ return () => {
+ document.removeEventListener('keydown', handleEscape)
+ document.body.style.paddingRight = '0px'
+ document.body.style.overflow = 'unset'
+ }
+ }, [isOpen, onClose])
+
+ if (!isOpen) return null
+
+ return (
+
+
+
+
+
+
+
{title}
+
+
+
+ {children}
+
+
+
+ )
+}
+
+export default Modal