diff --git a/src/app/[locale]/tenders/[id]/page.tsx b/src/app/[locale]/tenders/[id]/page.tsx new file mode 100644 index 0000000..a201c4c --- /dev/null +++ b/src/app/[locale]/tenders/[id]/page.tsx @@ -0,0 +1,144 @@ +import { apiInstance } from "@/shared/config/apiConfig"; +import { ITenders } from "@/shared/types/tenders-type"; +import { Container, Title } from "@/shared/ui"; + +const TenderDetails = async ({ + params, +}: { + params: { id: string; новость: string }; +}) => { + const getTendersById = async () => { + const response = await apiInstance.get( + `/procurements/${params.id}/` + ); + return response.data; + }; + + const data = await getTendersById(); + + const formatNumber = (number: number | string): string => { + if (typeof number === "string") { + number = parseFloat(number); + } + + if (isNaN(number)) return ""; + + return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " "); + }; + + const months: Record = { + "01": "Январь", + "02": "Февраль", + "03": "Март", + "04": "Апрель", + "05": "Май", + "06": "Июнь", + "07": "Июль", + "08": "Август", + "09": "Сентябрь", + "10": "Октябрь", + "11": "Ноябрь", + "12": "Декабрь", + }; + + return ( + + + <div className="flex flex-col gap-[27px] w-full mb-[83px]"> + <div className="flex gap-[108px]"> + <Title + text="Наименование закупки" + className="text-[18px] text-gray-500 w-[242px]" + /> + <Title + text={data.name_of_buy} + className="text-light-blue text-[20px] leading-8 font-semibold" + /> + </div> + <div className="flex gap-[108px]"> + <Title + text="Закупающая организация" + className="text-[18px] text-gray-500 w-[242px]" + /> + <Title + text={data.name_of_organization} + className="text-light-blue text-[20px] leading-8 font-semibold" + /> + </div> + <div className="flex gap-[108px]"> + <Title + text="Планируемая сумма" + className="text-[18px] text-gray-500 w-[242px]" + /> + <Title + text={formatNumber(data.plan_summ)} + className="text-light-blue text-[20px] leading-8 font-semibold" + /> + </div> + <div className="flex gap-[108px]"> + <Title + text="Статус" + className="text-[18px] text-gray-50 w-[242px] " + /> + <Title text={"Статус"} className=" text-[20px] leading-8" /> + </div> + <div className="flex gap-[108px]"> + <Title + text="Дата публикации" + className="text-[18px] text-gray-500 w-[242px]" + /> + <p className="text-[20px] leading-8"> + {data.date_of_publication_datetime.slice(8, 10)}{" "} + {months[data.date_of_publication_datetime.slice(5, 7)]}{" "} + {data.date_of_publication_datetime.slice(0, 4)} + </p> + {months[data.date_of_publication_datetime.slice(0, 5)]} + </div> + <div className="flex gap-[108px]"> + <Title + text="Окончание приема заявок" + className="text-[18px] text-gray-500 w-[242px]" + /> + <p className="text-[20px] leading-8"> + {data.date_of_publication_datetime.slice(8, 10)}{" "} + {months[data.date_of_publication_datetime.slice(5, 7)]}{" "} + {data.date_of_publication_datetime.slice(0, 4)} + </p> + </div> + <div className="flex gap-[108px]"> + <Title + text="Рабочий телефон" + className="text-[18px] text-gray-500 w-[242px]" + /> + <Title text={data.tel_number} className="text-[20px] leading-8" /> + </div> + <div className="flex gap-[108px]"> + <Title + text="Больше информации" + className="text-[18px] text-gray-500 w-[242px]" + /> + <Title text={data.more_info_url} className="text-[20px] leading-8" /> + </div> + <div className="flex gap-[108px]"> + <Title + text="Больше информации в PDF" + className="text-[18px] text-gray-500 w-[242px]" + /> + <Title text={data.more_info_pdf} className="text-[20px] leading-8" /> + </div> + </div> + + <Title + text={"Лоты"} + size="lg" + className="font-bold text-[24px] mb-[30px]" + /> + </Container> + ); +}; + +export default TenderDetails; diff --git a/src/app/[locale]/tenders/page.tsx b/src/app/[locale]/tenders/page.tsx index bd7c11c..ff1efbd 100644 --- a/src/app/[locale]/tenders/page.tsx +++ b/src/app/[locale]/tenders/page.tsx @@ -2,7 +2,13 @@ import { Container, Title } from "@/shared/ui"; import TendersList from "@/widgets/TendersList/TendersList"; import React from "react"; -const Tenders = () => { +const Tenders = ({ + searchParams, +}: { + searchParams: { + ["страница-тендеров"]: string; + }; +}) => { return ( <div className="bg-[#FAFCFF]"> <Container> @@ -11,7 +17,7 @@ const Tenders = () => { size="md" className="text-lg font-bold mb-[39px] pt-[101px]" /> - <TendersList /> + <TendersList searchParams={searchParams} /> </Container> </div> ); diff --git a/src/entities/TenderCard.tsx b/src/entities/TenderCard.tsx index 7991ee0..4fd54e7 100644 --- a/src/entities/TenderCard.tsx +++ b/src/entities/TenderCard.tsx @@ -1,3 +1,4 @@ +import { Link } from "@/shared/config/navigation"; import { Title } from "@/shared/ui"; import React from "react"; @@ -30,9 +31,13 @@ const TenderCard: React.FC<Props> = ({ text={`№ ${id_of_card}`} className="font-bold text-[24px] mb-[48px]" /> - <h2 className="mb-6 text-[18px] font-semibold leading-6 text-blue"> - {name_of_buy} - </h2> + <Link + href={{ pathname: `/tenders/${id}`, query: { тендер: name_of_buy } }} + > + <h2 className="mb-6 text-[18px] font-semibold leading-6 text-blue"> + {name_of_buy} + </h2> + </Link> <h2 className="text-[18px] leading-6 font-normal "> {name_of_organization} </h2> diff --git a/src/features/Pagination/Pagination.scss b/src/features/Pagination/Pagination.scss index 6ee3836..d19158f 100644 --- a/src/features/Pagination/Pagination.scss +++ b/src/features/Pagination/Pagination.scss @@ -37,12 +37,12 @@ } &__page_active { - background-color: rgb(249, 250, 251) !important; + background-color: rgb(236, 243, 250) !important; } &__page:hover, &__prev:hover, &__next:hover { - background-color: rgb(249, 250, 251); + background-color: rgb(229, 230, 230); } } diff --git a/src/features/SearchForm/SearchForm.tsx b/src/features/SearchForm/SearchForm.tsx index 81fb086..b898e05 100644 --- a/src/features/SearchForm/SearchForm.tsx +++ b/src/features/SearchForm/SearchForm.tsx @@ -4,11 +4,24 @@ import Image from "next/image"; import search from "./icons/search.svg"; import { useTranslations } from "next-intl"; -const SearchForm = () => { +interface ISearchFormProps extends React.InputHTMLAttributes<HTMLInputElement> { + handleSubmit: (e: React.MouseEvent<HTMLFormElement>) => void; +} +const SearchForm: React.FC<ISearchFormProps> = ({ + handleSubmit, + name, + placeholder, + value, + onChange, + style, +}: ISearchFormProps) => { const t = useTranslations("general"); return ( - <form className="mb-8 h-12 w-full relative flex items-center"> + <form + className="mb-8 h-12 w-full relative flex items-center" + onSubmit={handleSubmit} + > <div className="h-full flex flex-1 items-center border border-black rounded-sm bg-white"> <Image className="w-12 h-12 p-2" @@ -16,7 +29,10 @@ const SearchForm = () => { alt="Search button icon" /> <input - placeholder="Ключевое слово или номер" + onChange={onChange} + value={value} + placeholder={placeholder} + name={name} type="text" className="px-3 pl-2 w-full h-full text-lg focus:outline-none focus:ring-2 focus:ring-blue-500" aria-label={t("search")} diff --git a/src/shared/types/tenders-type.ts b/src/shared/types/tenders-type.ts index 6990de8..959b54d 100644 --- a/src/shared/types/tenders-type.ts +++ b/src/shared/types/tenders-type.ts @@ -10,6 +10,10 @@ export interface ITenders { date_of_publication_datetime: string; date_of_offer_datetime: string; current_timestamp: string; + plan_summ: string; + tel_number: string; + more_info_url: string; + more_info_pdf: string; } export interface ITendersList extends IList { diff --git a/src/widgets/TendersList/TendersList.tsx b/src/widgets/TendersList/TendersList.tsx index 354f4f7..56a6e90 100644 --- a/src/widgets/TendersList/TendersList.tsx +++ b/src/widgets/TendersList/TendersList.tsx @@ -1,24 +1,32 @@ "use client"; import React, { useEffect, useState } from "react"; import { useTendersStore } from "./tendersStore"; -import { data } from "autoprefixer"; import TenderCard from "@/entities/TenderCard"; import Pagination from "@/features/Pagination/Pagination"; import SearchForm from "@/features/SearchForm/SearchForm"; -interface Props {} -const TendersList = () => { - const [activePage, setActivePage] = useState<number>(1); - const [ordering, setOrdering] = useState<number>(1); +interface Props { + searchParams: { + ["страница-тендеров"]: string; + }; +} +const TendersList: React.FC<Props> = ({ searchParams }) => { + const [activePage, setActivePage] = useState<number>( + +searchParams["страница-тендеров"] || 1 + ); const { data: tenders, getTenders, isLoading, error } = useTendersStore(); useEffect(() => { - getTenders(ordering); - }, []); - console.log(tenders); + getTenders(activePage); + }, [activePage]); + + const handleSubmit = () => {}; return ( <div> - <SearchForm /> + <SearchForm + placeholder="Введите ключевое слово" + handleSubmit={handleSubmit} + /> <div className="flex flex-col gap-2 pb-[96px] items-center"> {tenders?.results?.map((tender) => ( @@ -42,7 +50,7 @@ const TendersList = () => { next={tenders.next} count={tenders.count as number} current_count={tenders.results.length} - limit={20} + limit={10} /> </div> </div> diff --git a/src/widgets/TendersList/tendersStore.ts b/src/widgets/TendersList/tendersStore.ts index fdeea86..f85a6d8 100644 --- a/src/widgets/TendersList/tendersStore.ts +++ b/src/widgets/TendersList/tendersStore.ts @@ -22,7 +22,9 @@ export const useTendersStore = create<useTendersStore>((set) => ({ try { set({ isLoading: true }); - const res = await apiInstance.get(`/procurements/?ordering=${ordering}`); + const res = await apiInstance.get( + `/procurements/?ordering=${ordering}/?limit=${10}/` + ); set({ data: res.data }); } catch (error: unknown) { if (error instanceof AxiosError) {