;
}
diff --git a/app/history/page.tsx b/app/history/page.tsx
index 2815aa3..21bac4b 100644
--- a/app/history/page.tsx
+++ b/app/history/page.tsx
@@ -4,6 +4,8 @@ export const metadata = {
import { HistoryPage } from "#/pages/History";
+export const dynamic = "force-static";
+
export default function Index() {
return
;
}
diff --git a/app/login/page.tsx b/app/login/page.tsx
index dae1809..cca130c 100644
--- a/app/login/page.tsx
+++ b/app/login/page.tsx
@@ -5,6 +5,8 @@ export const metadata = {
description: "Вход в аккаунт anixart",
}
+export const dynamic = "force-static";
+
export default function Login() {
return
;
}
diff --git a/app/menu/page.tsx b/app/menu/page.tsx
index 1350fbc..61305cc 100644
--- a/app/menu/page.tsx
+++ b/app/menu/page.tsx
@@ -4,6 +4,8 @@ export const metadata = {
import { MenuPage } from "#/pages/MobileMenuPage";
+export const dynamic = "force-static";
+
export default function Index() {
return
;
}
diff --git a/app/page.tsx b/app/page.tsx
index b54ae5b..6731436 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,5 +1,7 @@
import { IndexPage } from "./pages/Index";
+export const dynamic = "force-static";
+
export default function Index() {
return
;
}
diff --git a/app/pages/Search.tsx b/app/pages/Search.tsx
index bba699e..b06d000 100644
--- a/app/pages/Search.tsx
+++ b/app/pages/Search.tsx
@@ -1,138 +1,258 @@
"use client";
-import useSWRInfinite from "swr/infinite";
-import { ReleaseSection } from "#/components/ReleaseSection/ReleaseSection";
-import { RelatedSection } from "#/components/RelatedSection/RelatedSection";
-import { Spinner } from "#/components/Spinner/Spinner";
+
import { useState, useEffect } from "react";
-import { useScrollPosition } from "#/hooks/useScrollPosition";
-import { useRouter } from "next/navigation";
import { useSearchParams } from "next/navigation";
-import { useUserStore } from "../store/auth";
-import { Button, Dropdown, DropdownItem, Modal, ModalBody, ModalFooter, ModalHeader } from "flowbite-react";
-import { CollectionsSection } from "#/components/CollectionsSection/CollectionsSection";
+import { useRouter } from "next/navigation";
+
+import { Dropdown, DropdownItem } from "flowbite-react";
+import { useUserStore } from "#/store/auth";
+import { ENDPOINTS } from "#/api/config";
+import { tryCatchAPI } from "#/api/utils";
+import useSWRInfinite from "swr/infinite";
+import { Spinner } from "#/components/Spinner/Spinner";
+import { ReleaseSection } from "#/components/ReleaseSection/ReleaseSection";
import { UserSection } from "#/components/UserSection/UserSection";
-import { useSWRfetcher } from "#/api/utils";
+import { CollectionsSection } from "#/components/CollectionsSection/CollectionsSection";
+import { useScrollPosition } from "#/hooks/useScrollPosition";
+import { RelatedSection } from "#/components/RelatedSection/RelatedSection";
-const ListsMapping = {
- watching: {
- name: "Смотрю",
- id: 1,
- },
- planned: {
- name: "В планах",
- id: 2,
- },
- watched: {
- name: "Просмотрено",
- id: 3,
- },
- delayed: {
- name: "Отложено",
- id: 4,
- },
- abandoned: {
- name: "Заброшено",
- id: 5,
- },
+const postFetcher = async (url: string, payload: string) => {
+ const { data, error } = await tryCatchAPI(
+ fetch(url, {
+ method: "POST",
+ headers: {
+ "Api-Version": "v2",
+ "Content-Type": "application/json",
+ },
+ body: payload,
+ })
+ );
+
+ if (error) {
+ throw error;
+ }
+ return data;
};
-const TagMapping = {
- name: {
- name: "Названию",
- id: 0,
+const whereMapping = [
+ {
+ id: "releases",
+ label: "Релизах",
+ auth: false,
},
- studio: {
- name: "Студии",
- id: 1,
+ {
+ id: "profiles",
+ label: "Профилях",
+ auth: false,
},
- director: {
- name: "Режиссёру",
- id: 2,
+ {
+ id: "list",
+ label: "Списках",
+ auth: true,
},
- author: {
- name: "Автору",
- id: 3,
+ {
+ id: "history",
+ label: "Истории",
+ auth: true,
},
- tag: {
- name: "Тегу",
- id: 4,
+ {
+ id: "favorites",
+ label: "Избранном",
+ auth: true,
},
-};
+ {
+ id: "collections",
+ label: "Коллекциях",
+ auth: true,
+ },
+];
-const WhereMapping = {
- releases: "Релизах",
- list: "Списках",
- history: "Истории",
- favorites: "Избранном",
- collections: "Коллекциях",
- profiles: "Профилях",
+const searchByMapping = {
+ releases: [
+ {
+ id: "name",
+ label: "Названию",
+ value: 0,
+ },
+ {
+ id: "studio",
+ label: "Студии",
+ value: 1,
+ },
+ {
+ id: "director",
+ label: "Режиссёру",
+ value: 2,
+ },
+ {
+ id: "author",
+ label: "Автору",
+ value: 3,
+ },
+ {
+ id: "tag",
+ label: "Тегу",
+ value: 4,
+ },
+ ],
+ list: [
+ {
+ id: "watching",
+ label: "Смотрю",
+ value: 1,
+ },
+ {
+ id: "planned",
+ label: "В планах",
+ value: 2,
+ },
+ {
+ id: "watched",
+ label: "Просмотрено",
+ value: 3,
+ },
+ {
+ id: "delayed",
+ label: "Отложено",
+ value: 4,
+ },
+ {
+ id: "abandoned",
+ label: "Заброшено",
+ value: 5,
+ },
+ ],
+ none: [{ id: "none", label: "Нет", value: 0 }],
};
export function SearchPage() {
const router = useRouter();
const searchParams = useSearchParams();
- const [query, setQuery] = useState(searchParams.get("q") || "");
- const [searchVal, setSearchVal] = useState(searchParams.get("q") || "");
- const [where, setWhere] = useState(searchParams.get("where") || "releases");
- const [searchBy, setSearchBy] = useState(
- searchParams.get("searchBy") || "name"
- );
- const [list, setList] = useState(searchParams.get("list") || "watching");
- const [filtersModalOpen, setFiltersModalOpen] = useState(false);
-
const userStore = useUserStore();
+ const [query, setQuery] = useState(searchParams.get("query") || "");
+ const [params, setParams] = useState(null);
+ const [content, setContent] = useState(null);
+
+ const [HeaderH, setHeaderH] = useState(null);
+
+ useEffect(() => {
+ const queryParams = searchParams.get("params");
+
+ if (queryParams) {
+ try {
+ setParams(JSON.parse(queryParams));
+ } catch (e) {
+ setParams({
+ where: "releases",
+ searchBy: "name",
+ });
+ }
+ } else {
+ setParams({
+ where: "releases",
+ searchBy: "name",
+ });
+ }
+
+ if (window) {
+ setHeaderH(document.querySelector("header").clientHeight);
+ }
+
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ useEffect(() => {
+ if (!params) return;
+
+ const url = new URL(`/search`, window.location.origin);
+ url.searchParams.set("query", query);
+ url.searchParams.set("params", JSON.stringify(params));
+ router.replace(url.toString());
+ setContent(null);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [params]);
+
+ useEffect(() => {
+ setContent(null);
+
+ const url = new URL(`/search`, window.location.origin);
+ url.searchParams.set("query", query);
+ url.searchParams.set("params", JSON.stringify(params));
+ router.replace(url.toString());
+ }, [query]);
const getKey = (pageIndex: number, previousPageData: any) => {
- if (where == "releases") {
- if (previousPageData && !previousPageData.releases.length) return null;
- } else {
- if (previousPageData && !previousPageData.content.length) return null;
+ if (!params) return null;
+ if (!query) return null;
+
+ if (previousPageData) {
+ if (params.where == "releases") {
+ if (!previousPageData.releases.length) return null;
+ } else {
+ if (!previousPageData.content.length) return null;
+ }
}
- const url = new URL("/api/search", window.location.origin);
- url.searchParams.set("page", pageIndex.toString());
+ let url = null;
+ switch (params.where) {
+ case "releases":
+ url = `${ENDPOINTS.search.releases}/${pageIndex}`;
+ break;
+ case "profiles":
+ url = `${ENDPOINTS.search.profiles}/${pageIndex}`;
+ break;
+ case "list":
+ const list = searchByMapping[params.where].find(
+ (item) => item.id == params.searchBy
+ );
+ if (!list) break;
+ url = `${ENDPOINTS.search.profileList}/${list.value}/${pageIndex}`;
+ break;
+ case "history":
+ url = `${ENDPOINTS.search.profileHistory}/${pageIndex}`;
+ break;
+ case "favorites":
+ url = `${ENDPOINTS.search.profileFavorites}/${pageIndex}`;
+ break;
+ case "collections":
+ url = `${ENDPOINTS.search.profileFavoriteCollection}/${pageIndex}`;
+ break;
+ }
if (userStore.token) {
- url.searchParams.set("token", userStore.token);
+ url += `?token=${userStore.token}`;
}
- if (where) {
- url.searchParams.set("where", where);
+ let searchBy = null;
+ const _sbym = searchByMapping[params.where];
+ if (_sbym) {
+ searchBy = _sbym.find((item) => item.id == params.searchBy).value;
+ } else {
+ searchBy = searchByMapping["none"][0].value;
}
- if (where == "list" && list && ListsMapping.hasOwnProperty(list)) {
- url.searchParams.set("list", ListsMapping[list].id);
- }
-
- url.searchParams.set("searchBy", TagMapping[searchBy].id);
-
- if (query) {
- url.searchParams.set("q", query);
- return url.toString();
- }
- return;
+ return [url, JSON.stringify({ query, searchBy })];
};
- const { data, error, isLoading, size, setSize } = useSWRInfinite(
+ const { data, error, isLoading, size, setSize, mutate } = useSWRInfinite(
getKey,
- useSWRfetcher,
- { initialSize: 2, revalidateFirstPage: false }
+ ([url, payload]) => postFetcher(url, payload),
+ { initialSize: 2 }
);
- const [content, setContent] = useState(null);
useEffect(() => {
if (data) {
- let allReleases = [];
- if (where == "releases") {
+ let _content = [];
+ if (params.where == "releases") {
for (let i = 0; i < data.length; i++) {
- allReleases.push(...data[i].releases);
+ _content.push(...data[i].releases);
}
} else {
for (let i = 0; i < data.length; i++) {
- allReleases.push(...data[i].content);
+ _content.push(...data[i].content);
}
}
- setContent(allReleases);
+ setContent(_content);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data]);
@@ -145,52 +265,22 @@ export function SearchPage() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [scrollPosition]);
- function _executeSearch(value: string) {
- const Params = new URLSearchParams(window.location.search);
- Params.set("q", value);
- const url = new URL(`/search?${Params.toString()}`, window.location.origin);
- setContent(null);
- setQuery(value);
- router.push(url.toString());
- }
-
- useEffect(() => {
- if (searchVal && searchVal.length % 4 == 1) {
- _executeSearch(searchVal.trim());
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [searchVal]);
-
- if (error)
- return (
-
-
-
Ошибка
-
- Произошла ошибка поиска. Попробуйте обновить страницу или зайдите
- позже.
-
-
-
- );
+ if (!params) return <>>;
return (
- <>
-