diff --git a/package-lock.json b/package-lock.json index cc70e83..8b8c886 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,8 @@ "react-hook-form": "^7.52.2", "sass": "^1.77.8", "tailwind-merge": "^2.5.2", - "zod": "^3.23.8" + "zod": "^3.23.8", + "zustand": "^4.5.5" }, "devDependencies": { "@types/node": "^20", @@ -540,13 +541,13 @@ "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true + "devOptional": true }, "node_modules/@types/react": { "version": "18.3.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "dev": true, + "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1324,7 +1325,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "devOptional": true }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -5166,6 +5167,14 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5419,6 +5428,33 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "node_modules/zustand": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.5.tgz", + "integrity": "sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==", + "dependencies": { + "use-sync-external-store": "1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index 034eaf0..93513d0 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "react-hook-form": "^7.52.2", "sass": "^1.77.8", "tailwind-merge": "^2.5.2", - "zod": "^3.23.8" + "zod": "^3.23.8", + "zustand": "^4.5.5" }, "devDependencies": { "@types/node": "^20", diff --git a/src/app/[locale]/tenders/page.tsx b/src/app/[locale]/tenders/page.tsx new file mode 100644 index 0000000..56d3a89 --- /dev/null +++ b/src/app/[locale]/tenders/page.tsx @@ -0,0 +1,14 @@ +import { Container, Title } from "@/shared/ui"; +import TendersList from "@/widgets/TendersList/TendersList"; +import React from "react"; + +const Tenders = () => { + return ( + + + <TendersList /> + </Container> + ); +}; + +export default Tenders; diff --git a/src/shared/types/fetch-type.ts b/src/shared/types/fetch-type.ts new file mode 100644 index 0000000..576ae3f --- /dev/null +++ b/src/shared/types/fetch-type.ts @@ -0,0 +1,5 @@ +export interface IFetch { + error: string; + data?: any; + isLoading: boolean; +} diff --git a/src/shared/types/list-type.ts b/src/shared/types/list-type.ts new file mode 100644 index 0000000..b425a68 --- /dev/null +++ b/src/shared/types/list-type.ts @@ -0,0 +1,5 @@ +export interface IList { + count: number; + previous: string | null; + next: string | null; +} diff --git a/src/shared/types/tenders-type.ts b/src/shared/types/tenders-type.ts new file mode 100644 index 0000000..6990de8 --- /dev/null +++ b/src/shared/types/tenders-type.ts @@ -0,0 +1,17 @@ +import { IList } from "./list-type"; + +export interface ITenders { + id: number; + id_of_card: string; + data_rk: string; + name_of_organization: string; + type_of_buy: string; + name_of_buy: string; + date_of_publication_datetime: string; + date_of_offer_datetime: string; + current_timestamp: string; +} + +export interface ITendersList extends IList { + results: ITenders[]; +} diff --git a/src/widgets/Navbar/NavAuth/NavAuth.tsx b/src/widgets/Navbar/NavAuth/NavAuth.tsx index 26264c1..162f5f9 100644 --- a/src/widgets/Navbar/NavAuth/NavAuth.tsx +++ b/src/widgets/Navbar/NavAuth/NavAuth.tsx @@ -14,7 +14,7 @@ const NavAuth: React.FC<INavAuthProps> = ({ }: INavAuthProps) => { const t = useTranslations("navigation"); const session = useSession(); - const auth = session.status === "authenticated"; + const auth = session.status === "authenticated" ? true : false; const pathname = usePathname(); const isActiveProfile = pathname === "/profile"; diff --git a/src/widgets/Navbar/NavMenu/NavMenu.tsx b/src/widgets/Navbar/NavMenu/NavMenu.tsx index 33b7b2b..a8f07b6 100644 --- a/src/widgets/Navbar/NavMenu/NavMenu.tsx +++ b/src/widgets/Navbar/NavMenu/NavMenu.tsx @@ -1,12 +1,9 @@ import { LINKS } from "@/shared/variables/links"; -// import NavAuth from "../NavAuth/NavAuth"; import { Link, usePathname } from "@/shared/config/navigation"; import { useEffect, useState, useTransition } from "react"; import { useParams, useRouter } from "next/navigation"; import chevron_down from "./icons/chevron_down.svg"; import Image from "next/image"; -import logo from "@/shared/assets/logo.svg"; -import cross from "./icons/cross.svg"; import NavAuth from "../NavAuth/NavAuth"; interface INavMenuProps { diff --git a/src/widgets/TendersList/TendersList.tsx b/src/widgets/TendersList/TendersList.tsx new file mode 100644 index 0000000..44e0b3d --- /dev/null +++ b/src/widgets/TendersList/TendersList.tsx @@ -0,0 +1,18 @@ +"use client"; +import React, { useEffect, useState } from "react"; +import { useTendersStore } from "./tendersStore"; +import { data } from "autoprefixer"; + +interface Props {} +const TendersList = () => { + const [ordering, setOrdering] = useState<number>(1); + const { data: tenders, getTenders, isLoading, error } = useTendersStore(); + + useEffect(() => { + getTenders(ordering); + }, []); + console.log(data); + return <div>df</div>; +}; + +export default TendersList; diff --git a/src/widgets/TendersList/tendersStore.ts b/src/widgets/TendersList/tendersStore.ts new file mode 100644 index 0000000..8c274eb --- /dev/null +++ b/src/widgets/TendersList/tendersStore.ts @@ -0,0 +1,37 @@ +import { apiInstance } from "@/shared/config/apiConfig"; +import { IFetch } from "@/shared/types/fetch-type"; +import { ITendersList } from "@/shared/types/tenders-type"; +import { AxiosError } from "axios"; +import { create } from "zustand"; + +interface useTendersStore extends IFetch { + data: ITendersList; + getTenders: (ordering: number) => void; +} + +export const useTendersStore = create<useTendersStore>((set) => ({ + data: { + count: 0, + previous: null, + next: null, + results: [], + }, + error: "", + isLoading: false, + getTenders: async (ordering: number) => { + try { + set({ isLoading: true }); + + const res = await apiInstance.get(`/procurements/?ordering${ordering}`); + set({ data: res.data.results }); + } catch (error: unknown) { + if (error instanceof AxiosError) { + set({ error: error.message }); + } else { + set({ error: "An error occured" }); + } + } finally { + set({ isLoading: false }); + } + }, +}));