diff --git a/src/app/(pages)/(content)/anime/[slug]/page.tsx b/src/app/(pages)/(content)/anime/[slug]/page.tsx index e684c6d2..e8c1a9ec 100644 --- a/src/app/(pages)/(content)/anime/[slug]/page.tsx +++ b/src/app/(pages)/(content)/anime/[slug]/page.tsx @@ -3,11 +3,11 @@ import { FC } from 'react'; import Characters from '@/features/anime/anime-view/characters/characters.component'; import Description from '@/features/anime/anime-view/description.component'; import Details from '@/features/anime/anime-view/details/details.component'; -import Followings from '@/features/anime/anime-view/followings/followings.component'; import Links from '@/features/anime/anime-view/links/links.component'; import Media from '@/features/anime/anime-view/media/media.component'; import Staff from '@/features/anime/anime-view/staff.component'; import WatchStats from '@/features/anime/anime-view/watch-stats/watch-stats.component'; +import Followings from '@/features/followings/followings.component'; import Franchise from '@/features/franchise/franchise.component'; import getAnimeInfo, { @@ -43,17 +43,17 @@ const AnimePage: FC = async ({ params }) => {
- - - + + +
- - - + + +
diff --git a/src/app/(pages)/(content)/manga/[slug]/page.tsx b/src/app/(pages)/(content)/manga/[slug]/page.tsx index 7ca583c0..1dfe43c3 100644 --- a/src/app/(pages)/(content)/manga/[slug]/page.tsx +++ b/src/app/(pages)/(content)/manga/[slug]/page.tsx @@ -1,5 +1,6 @@ import { FC } from 'react'; +import Followings from '@/features/followings/followings.component'; import Franchise from '@/features/franchise/franchise.component'; import Characters from '@/features/manga/manga-view/characters/characters.component'; import Description from '@/features/manga/manga-view/description.component'; @@ -24,6 +25,7 @@ const MangaPage: FC = async ({ params }) => {
+
@@ -31,6 +33,7 @@ const MangaPage: FC = async ({ params }) => {
+
diff --git a/src/app/(pages)/(content)/novel/[slug]/page.tsx b/src/app/(pages)/(content)/novel/[slug]/page.tsx index 788942ac..73d9df31 100644 --- a/src/app/(pages)/(content)/novel/[slug]/page.tsx +++ b/src/app/(pages)/(content)/novel/[slug]/page.tsx @@ -1,5 +1,6 @@ import { FC } from 'react'; +import Followings from '@/features/followings/followings.component'; import Franchise from '@/features/franchise/franchise.component'; import Characters from '@/features/novel/novel-view/characters/characters.component'; import Description from '@/features/novel/novel-view/description.component'; @@ -24,6 +25,7 @@ const NovelPage: FC = async ({ params }) => {
+
@@ -31,6 +33,7 @@ const NovelPage: FC = async ({ params }) => {
+
diff --git a/src/features/anime/anime-view/followings/followings-modal.tsx b/src/features/anime/anime-view/followings/followings-modal.tsx deleted file mode 100644 index bfb990a3..00000000 --- a/src/features/anime/anime-view/followings/followings-modal.tsx +++ /dev/null @@ -1,40 +0,0 @@ -'use client'; - -import { useParams } from 'next/navigation'; - -import LoadMoreButton from '@/components/load-more-button'; - -import useFollowingWatchList from '@/services/hooks/watch/use-following-watch-list'; - -import FollowingItem from './following-item'; - -const FollowingsModal = () => { - const params = useParams(); - - const { list, hasNextPage, isFetchingNextPage, fetchNextPage, ref } = - useFollowingWatchList({ slug: String(params.slug) }); - - return ( -
- {list && - list.map((item) => ( - - ))} - {hasNextPage && ( -
- -
- )} -
- ); -}; - -export default FollowingsModal; diff --git a/src/features/anime/anime-view/followings/followings.component.tsx b/src/features/anime/anime-view/followings/followings.component.tsx deleted file mode 100644 index d00d3961..00000000 --- a/src/features/anime/anime-view/followings/followings.component.tsx +++ /dev/null @@ -1,56 +0,0 @@ -'use client'; - -import { useParams } from 'next/navigation'; - -import Block from '@/components/ui/block'; -import Header from '@/components/ui/header'; - -import useFollowingWatchList from '@/services/hooks/watch/use-following-watch-list'; -import { useModalContext } from '@/services/providers/modal-provider'; - -import FollowingItem from './following-item'; -import FollowingsModal from './followings-modal'; - -const Followings = () => { - const params = useParams(); - const { openModal } = useModalContext(); - - const { list } = useFollowingWatchList({ slug: String(params.slug) }); - - if (!list || list.length === 0) { - return null; - } - - const filteredFollowings = list?.slice(0, 3); - - const handleOpenFollowingsModal = () => { - openModal({ - type: 'sheet', - title: 'Відстежується', - side: 'right', - content: , - }); - }; - - const title = ( - - Відстежується{' '} - {list && ( - ({list.length}) - )} - - ); - - return ( - -
-
- {filteredFollowings.map((item) => ( - - ))} -
- - ); -}; - -export default Followings; diff --git a/src/features/followings/following-read-item.tsx b/src/features/followings/following-read-item.tsx new file mode 100644 index 00000000..08c8362c --- /dev/null +++ b/src/features/followings/following-read-item.tsx @@ -0,0 +1,52 @@ +import Link from 'next/link'; +import { FC } from 'react'; +import MaterialSymbolsStarRounded from '~icons/material-symbols/star-rounded'; + +import P from '@/components/typography/p'; +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; +import { Label } from '@/components/ui/label'; + +import { READ_STATUS } from '@/utils/constants'; +import { cn } from '@/utils/utils'; + +interface Props { + data: { + read: API.Read[]; + } & API.User; + className?: string; +} + +const FollowingReadItem: FC = ({ data, className }) => { + return ( +
+ + + + + + +
+ + +

+ {READ_STATUS[data.read[0].status].title_ua} +

+
+ {data.read[0].score > 0 && ( +
+ + +
+ )} +
+ ); +}; + +export default FollowingReadItem; diff --git a/src/features/anime/anime-view/followings/following-item.tsx b/src/features/followings/following-watch-item.tsx similarity index 92% rename from src/features/anime/anime-view/followings/following-item.tsx rename to src/features/followings/following-watch-item.tsx index 93a8b1a6..b1428c0a 100644 --- a/src/features/anime/anime-view/followings/following-item.tsx +++ b/src/features/followings/following-watch-item.tsx @@ -1,5 +1,5 @@ import Link from 'next/link'; -import React, { FC } from 'react'; +import { FC } from 'react'; import MaterialSymbolsStarRounded from '~icons/material-symbols/star-rounded'; import P from '@/components/typography/p'; @@ -16,7 +16,7 @@ interface Props { className?: string; } -const FollowingItem: FC = ({ data, className }) => { +const FollowingWatchItem: FC = ({ data, className }) => { return (
@@ -49,4 +49,4 @@ const FollowingItem: FC = ({ data, className }) => { ); }; -export default FollowingItem; +export default FollowingWatchItem; diff --git a/src/features/followings/followings-modal.tsx b/src/features/followings/followings-modal.tsx new file mode 100644 index 00000000..621aef02 --- /dev/null +++ b/src/features/followings/followings-modal.tsx @@ -0,0 +1,70 @@ +'use client'; + +import { useParams } from 'next/navigation'; +import { FC } from 'react'; + +import LoadMoreButton from '@/components/load-more-button'; + +import useFollowingReadList from '@/services/hooks/read/use-following-read-list'; +import useFollowingWatchList from '@/services/hooks/watch/use-following-watch-list'; + +import FollowingReadItem from './following-read-item'; +import FollowingWatchItem from './following-watch-item'; + +interface Props { + content_type: API.ContentType; +} + +const FollowingsModal: FC = ({ content_type }) => { + const params = useParams(); + + const watchListQuery = useFollowingWatchList( + { + slug: String(params.slug), + }, + { enabled: content_type === 'anime' }, + ); + + const readListQuery = useFollowingReadList( + { + slug: String(params.slug), + content_type: content_type as 'manga' | 'novel', + }, + { enabled: content_type !== 'anime' }, + ); + + const { list, hasNextPage, isFetchingNextPage, fetchNextPage, ref } = + content_type === 'anime' ? watchListQuery : readListQuery; + + return ( +
+ {list && + list.map((item) => + 'watch' in item ? ( + + ) : ( + + ), + )} + {hasNextPage && ( +
+ +
+ )} +
+ ); +}; + +export default FollowingsModal; diff --git a/src/features/followings/followings.component.tsx b/src/features/followings/followings.component.tsx new file mode 100644 index 00000000..3776d150 --- /dev/null +++ b/src/features/followings/followings.component.tsx @@ -0,0 +1,83 @@ +'use client'; + +import { useParams } from 'next/navigation'; +import { FC } from 'react'; + +import Block from '@/components/ui/block'; +import Header from '@/components/ui/header'; + +import useFollowingReadList from '@/services/hooks/read/use-following-read-list'; +import useFollowingWatchList from '@/services/hooks/watch/use-following-watch-list'; +import { useModalContext } from '@/services/providers/modal-provider'; + +import FollowingReadItem from './following-read-item'; +import FollowingWatchItem from './following-watch-item'; +import FollowingsModal from './followings-modal'; + +interface Props { + content_type: API.ContentType; +} + +const Followings: FC = ({ content_type }) => { + const params = useParams(); + const { openModal } = useModalContext(); + + const watchListQuery = useFollowingWatchList( + { + slug: String(params.slug), + }, + { enabled: content_type === 'anime' }, + ); + + const readListQuery = useFollowingReadList( + { + slug: String(params.slug), + content_type: content_type as 'manga' | 'novel', + }, + { enabled: content_type !== 'anime' }, + ); + + const list = + content_type === 'anime' ? watchListQuery.list : readListQuery.list; + + if (!list || list.length === 0) { + return null; + } + + const filteredFollowings = list?.slice(0, 3); + + const handleOpenFollowingsModal = () => { + openModal({ + type: 'sheet', + title: 'Відстежується', + side: 'right', + content: , + }); + }; + + const title = ( + + Відстежується{' '} + {list && ( + ({list.length}) + )} + + ); + + return ( + +
+
+ {filteredFollowings.map((item) => + 'watch' in item ? ( + + ) : ( + + ), + )} +
+ + ); +}; + +export default Followings; diff --git a/src/services/api/read/getFollowingReadList.ts b/src/services/api/read/getFollowingReadList.ts index 73029e41..dc8b5938 100644 --- a/src/services/api/read/getFollowingReadList.ts +++ b/src/services/api/read/getFollowingReadList.ts @@ -23,7 +23,7 @@ export default async function req({ }: BaseFetchRequestProps): Promise { return fetchRequest({ ...props, - path: `/read/${params?.slug}/${params?.content_type}/following`, + path: `/read/${params?.content_type}/${params?.slug}/following`, method: 'get', page, size, diff --git a/src/services/hooks/read/use-following-read-list.ts b/src/services/hooks/read/use-following-read-list.ts index e9481af3..6220c296 100644 --- a/src/services/hooks/read/use-following-read-list.ts +++ b/src/services/hooks/read/use-following-read-list.ts @@ -15,10 +15,13 @@ export const key = (params: Params) => [ params.content_type, ]; -const useFollowingReadList = (props: { - slug: string; - content_type: 'manga' | 'novel'; -}) => { +const useFollowingReadList = ( + props: { + slug: string; + content_type: 'manga' | 'novel'; + }, + options?: Hikka.QueryOptions, +) => { const params = paramsBuilder(props); return useInfiniteList({ @@ -28,6 +31,7 @@ const useFollowingReadList = (props: { params, page: pageParam, }), + ...options, }); }; diff --git a/src/services/hooks/watch/use-following-watch-list.ts b/src/services/hooks/watch/use-following-watch-list.ts index 6fc9627e..b128bac7 100644 --- a/src/services/hooks/watch/use-following-watch-list.ts +++ b/src/services/hooks/watch/use-following-watch-list.ts @@ -10,7 +10,7 @@ export const paramsBuilder = (props: Params): Params => ({ export const key = (params: Params) => ['following-watch-list', params.slug]; -const useFollowingWatchList = (props: Params) => { +const useFollowingWatchList = (props: Params, options?: Hikka.QueryOptions) => { const params = paramsBuilder(props); return useInfiniteList({ @@ -21,6 +21,7 @@ const useFollowingWatchList = (props: Params) => { page: pageParam, }), refetchOnWindowFocus: false, + ...options, }); };