diff --git a/app/collections/favorites/page.tsx b/app/collections/favorites/page.tsx new file mode 100644 index 0000000..628070e --- /dev/null +++ b/app/collections/favorites/page.tsx @@ -0,0 +1,10 @@ +import { CollectionsFullPage } from "#/pages/CollectionsFull"; + +export const metadata = { + title: "Избранные коллекции", + description: "Просмотр избранных коллекций", +}; + +export default function Collections() { + return ; +} diff --git a/app/components/CollectionLink/CollectionLink.tsx b/app/components/CollectionLink/CollectionLink.tsx index e60caca..d760eb4 100644 --- a/app/components/CollectionLink/CollectionLink.tsx +++ b/app/components/CollectionLink/CollectionLink.tsx @@ -13,18 +13,18 @@ export const CollectionLink = (props: any) => { }} >
- {props.is_favorite && ( -
- -
- )} + + {props.is_private && (
)} - - + {props.is_favorite && ( +
+ +
+ )}

{props.title} diff --git a/app/components/CollectionsSection/CollectionsSection.tsx b/app/components/CollectionsSection/CollectionsSection.tsx new file mode 100644 index 0000000..c7b0775 --- /dev/null +++ b/app/components/CollectionsSection/CollectionsSection.tsx @@ -0,0 +1,33 @@ +import { CollectionLink } from "../CollectionLink/CollectionLink"; +import { AddCollectionLink } from "../AddCollectionLink/AddCollectionLink"; + +export const CollectionsSection = (props: { + sectionTitle?: string; + content: any; + isMyCollections?: boolean; +}) => { + return ( +

+ {props.sectionTitle && ( +
+

+ {props.sectionTitle} +

+
+ )} +
+
+ {props.isMyCollections && } + {props.content.map((collection) => { + return ( +
+ +
+ ); + })} + {props.content.length == 1 && !props.isMyCollections &&
} +
+
+
+ ); +}; diff --git a/app/pages/CollectionsFull.tsx b/app/pages/CollectionsFull.tsx new file mode 100644 index 0000000..5fce7b2 --- /dev/null +++ b/app/pages/CollectionsFull.tsx @@ -0,0 +1,116 @@ +"use client"; +import useSWRInfinite from "swr/infinite"; +import { CollectionsSection } from "#/components/CollectionsSection/CollectionsSection"; +import { Spinner } from "#/components/Spinner/Spinner"; +import { useState, useEffect } from "react"; +import { useScrollPosition } from "#/hooks/useScrollPosition"; +import { useUserStore } from "../store/auth"; +import { Button } from "flowbite-react"; +import { ENDPOINTS } from "#/api/config"; +import { useRouter } from "next/navigation"; + +const fetcher = async (url: string) => { + const res = await fetch(url); + + if (!res.ok) { + const error = new Error( + `An error occurred while fetching the data. status: ${res.status}` + ); + error.message = await res.json(); + throw error; + } + + return res.json(); +}; + +export function CollectionsFullPage(props: { + type: "favorites" | "profile" | "release"; + title: string; + profile_id?: number; + release_id?: number; +}) { + const userStore = useUserStore(); + const [isLoadingEnd, setIsLoadingEnd] = useState(false); + const router = useRouter(); + + const getKey = (pageIndex: number, previousPageData: any) => { + if (previousPageData && !previousPageData.content.length) return null; + if (userStore.token) { + if (props.type == "favorites") { + return `${ENDPOINTS.collection.favoriteCollections}/all/${pageIndex}?token=${userStore.token}`; + } else if (props.type == "profile") { + return `${ENDPOINTS.collection.userCollections}/${props.profile_id}/${pageIndex}?token=${userStore.token}`; + } else if (props.type == "release") { + return `${ENDPOINTS.collection.releaseInCollections}/${props.release_id}/${pageIndex}?token=${userStore.token}`; + } + } + }; + + const { data, error, isLoading, size, setSize } = useSWRInfinite( + getKey, + fetcher, + { initialSize: 2 } + ); + + const [content, setContent] = useState(null); + useEffect(() => { + if (data) { + let allReleases = []; + for (let i = 0; i < data.length; i++) { + allReleases.push(...data[i].content); + } + setContent(allReleases); + setIsLoadingEnd(true); + } + }, [data]); + + const scrollPosition = useScrollPosition(); + useEffect(() => { + if (scrollPosition >= 98 && scrollPosition <= 99) { + setSize(size + 1); + } + }, [scrollPosition]); + + useEffect(() => { + if (userStore.state === "finished" && !userStore.token) { + router.push(`/login?redirect=/collections/favorites`); + } + }, [userStore.state, userStore.token]); + + return ( +
+ {content && content.length > 0 ? ( + + ) : !isLoadingEnd || isLoading ? ( +
+ +
+ ) : ( +
+ +

Тут пока ничего нет...

+
+ )} + {data && + data[data.length - 1].current_page < + data[data.length - 1].total_page_count && ( + + )} +
+ ); +} diff --git a/app/profile/[id]/collections/page.tsx b/app/profile/[id]/collections/page.tsx new file mode 100644 index 0000000..3f91c2b --- /dev/null +++ b/app/profile/[id]/collections/page.tsx @@ -0,0 +1,42 @@ +import { CollectionsFullPage } from "#/pages/CollectionsFull"; +import { fetchDataViaGet } from "#/api/utils"; +import type { Metadata, ResolvingMetadata } from "next"; + +export async function generateMetadata( + { params }, + parent: ResolvingMetadata +): Promise { + const id: string = params.id; + const profile: any = await fetchDataViaGet( + `https://api.anixart.tv/profile/${id}` + ); + const previousOG = (await parent).openGraph; + + return { + title: "Коллекции - " + profile.profile.login, + description: profile.profile.status, + openGraph: { + ...previousOG, + images: [ + { + url: profile.profile.avatar, // Must be an absolute URL + width: 600, + height: 600, + }, + ], + }, + }; +} + +export default async function Collections({ params }) { + const profile: any = await fetchDataViaGet( + `https://api.anixart.tv/profile/${params.id}` + ); + return ( + + ); +} diff --git a/app/release/[id]/collections/page.tsx b/app/release/[id]/collections/page.tsx new file mode 100644 index 0000000..09d9097 --- /dev/null +++ b/app/release/[id]/collections/page.tsx @@ -0,0 +1,40 @@ +import { CollectionsFullPage } from "#/pages/CollectionsFull"; +import { fetchDataViaGet } from "#/api/utils"; +import type { Metadata, ResolvingMetadata } from "next"; + +export async function generateMetadata( + { params }, + parent: ResolvingMetadata +): Promise { + const id = params.id; + const release = await fetchDataViaGet(`https://api.anixart.tv/release/${id}`); + const previousOG = (await parent).openGraph; + + return { + title: release.release.title_ru + " - в коллекциях", + description: release.release.description, + openGraph: { + ...previousOG, + images: [ + { + url: release.release.image, // Must be an absolute URL + width: 600, + height: 800, + }, + ], + }, + }; +} + +export default async function Collections({ params }) { + const release: any = await fetchDataViaGet( + `https://api.anixart.tv/release/${params.id}` + ); + return ( + + ); +}