Skip to content

Commit

Permalink
Merge pull request #24 from Lorg0n/feature/CharacterTooltip
Browse files Browse the repository at this point in the history
Feature/character tooltip
  • Loading branch information
olexh authored May 16, 2024
2 parents 0f75c26 + 46904f4 commit 0c9da0c
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 10 deletions.
3 changes: 1 addition & 2 deletions components/content-card/components/anime-tooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use client';

import * as React from 'react';
import { FC, PropsWithChildren, memo } from 'react';

import Link from 'next/link';
Expand Down Expand Up @@ -75,7 +74,7 @@ const TooltipData: FC<TooltipDataProps> = ({ slug }) => {
) : null}
</div>
{synopsis && (
<MDViewer className="mb-2 line-clamp-4 text-sm">
<MDViewer className="mb-2 line-clamp-4 text-sm text-muted-foreground">
{synopsis}
</MDViewer>
)}
Expand Down
120 changes: 120 additions & 0 deletions components/content-card/components/character-tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
'use client';

import { FC, PropsWithChildren, memo } from 'react';

import ContentCard from '@/components/content-card/content-card';
import MDViewer from '@/components/markdown/viewer/MD-viewer';
import {
HoverCard,
HoverCardArrow,
HoverCardContent,
HoverCardPortal,
HoverCardTrigger,
} from '@/components/ui/hover-card';
import { Label } from '@/components/ui/label';
import useSession from '@/services/hooks/auth/useSession';
import useCharacterAnime from '@/services/hooks/characters/useCharacterAnime';
import useCharacterInfo from '@/services/hooks/characters/useCharacterInfo';

interface TooltipDataProps {
slug: string;
}

interface Props extends PropsWithChildren {
slug?: string;
withTrigger?: boolean;
}

const TooltipData: FC<TooltipDataProps> = ({ slug }) => {
const { user: loggedUser } = useSession();
const { data } = useCharacterInfo({ slug });
const { list } = useCharacterAnime({ slug });

const characterAnime = list?.sort(
(a, b) => b.anime.score - a.anime.score,
)[0];

if (!data) {
return (
<div className="flex w-96 animate-pulse gap-4 text-left">
<div className="h-28 w-20 rounded-lg bg-secondary/60" />
<div className="flex w-full flex-1 flex-col gap-2">
<div className="flex flex-col gap-2">
<div className="flex w-full flex-1 flex-col gap-2">
<div className="h-5 w-20 rounded-lg bg-secondary/60" />
<div className="h-2 w-full rounded-lg bg-secondary/60" />
<div className="h-2 w-full rounded-lg bg-secondary/60" />
<div className="h-2 w-full rounded-lg bg-secondary/60" />
</div>
</div>
</div>
<div className="flex flex-col gap-2">
<div className="h-14 w-10 rounded-lg bg-secondary/60" />
</div>
</div>
);
}

return (
<div className="flex w-96 gap-4 text-left">
<ContentCard
className="w-20"
poster={data.image}
containerRatio={0.7}
href={'/characters/' + data.slug}
/>
<div className="flex w-full flex-1 flex-col gap-2">
<div className="flex items-center gap-2">
<Label className="line-clamp-2 font-bold">
{data.name_ua || data.name_en || data.name_ja}
</Label>
</div>
<div className="flex flex-col gap-2">
<div className="flex items-center gap-2">
<MDViewer className="whitespace-normal break-normal text-sm text-muted-foreground md:line-clamp-3">
{data.description_ua}
</MDViewer>
</div>
</div>
</div>
{characterAnime && (
<div className="flex flex-col gap-2">
<ContentCard
className="w-10"
poster={characterAnime.anime.poster}
containerRatio={0.7}
href={'/anime/' + characterAnime.anime.slug}
/>
</div>
)}
</div>
);
};

const CharacterTooltip: FC<Props> = ({
slug,
children,
withTrigger,
...props
}) => {
if (!slug) {
return null;
}

return (
<HoverCard openDelay={500} closeDelay={100}>
<HoverCardTrigger asChild>{children}</HoverCardTrigger>
<HoverCardPortal>
<HoverCardContent
side="right"
className="hidden min-w-min flex-col gap-4 p-4 md:flex"
>
<HoverCardArrow />
<TooltipData slug={slug} />
</HoverCardContent>
</HoverCardPortal>
</HoverCard>
);
};

export default memo(CharacterTooltip);
3 changes: 3 additions & 0 deletions components/content-card/content-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import MaterialSymbolsImageNotSupportedOutlineRounded from '~icons/material-symb
import Link from 'next/link';

import AnimeTooltip from '@/components/content-card/components/anime-tooltip';
import CharacterTooltip from '@/components/content-card/components/character-tooltip';
import P from '@/components/typography/p';
import Image from '@/components/ui/image';
import { Label } from '@/components/ui/label';
Expand Down Expand Up @@ -58,6 +59,8 @@ const Tooltip: FC<TooltipProps> = ({ children, content_type, slug }) => {
switch (content_type) {
case 'anime':
return <AnimeTooltip slug={slug}>{children}</AnimeTooltip>;
case 'character':
return <CharacterTooltip slug={slug}>{children}</CharacterTooltip>;
default:
return <Fragment>{children}</Fragment>;
}
Expand Down
12 changes: 12 additions & 0 deletions components/markdown/viewer/components/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import MaterialSymbolsLinkRounded from '~icons/material-symbols/link-rounded';
import NextLink from 'next/link';

import AnimeTooltip from '@/components/content-card/components/anime-tooltip';
import CharacterTooltip from '@/components/content-card/components/character-tooltip';
import P from '@/components/typography/p';
import {
AlertDialog,
Expand Down Expand Up @@ -44,6 +45,17 @@ const Link: FC<PropsWithChildren<Props>> = ({ children, href, className }) => {
</AnimeTooltip>
);
}
}
if (href.includes("/characters")) {
const link = href.split('/characters/')[1]?.split('/')[0];

if (link) {
return (
<CharacterTooltip slug={link}>
<NextLink href={href}>{children}</NextLink>
</CharacterTooltip>
);
}
}

return <NextLink href={href}>{children}</NextLink>;
Expand Down
4 changes: 2 additions & 2 deletions components/ui/hover-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;

export {
HoverCard,
HoverCardTrigger,
HoverCardArrow,
HoverCardContent,
HoverCardPortal,
HoverCardArrow,
HoverCardTrigger,
};
6 changes: 3 additions & 3 deletions next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import bundleAnalyzer from '@next/bundle-analyzer';
import Icons from 'unplugin-icons/webpack';

import bundleAnalyzer from '@next/bundle-analyzer';

/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: {
Expand Down Expand Up @@ -31,7 +32,7 @@ const nextConfig = {
async rewrites() {
return [
{
source: "/api/:path*",
source: '/api/:path*',
destination: `${process.env.API_URL}/:path*`,
},
];
Expand All @@ -41,5 +42,4 @@ const withBundleAnalyzer = bundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
});


export default withBundleAnalyzer(nextConfig);
5 changes: 2 additions & 3 deletions services/api/characters/getCharacterAnime.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {
BaseFetchRequestProps,
FetchRequestProps,
fetchRequest,
} from '@/services/api/fetchRequest';

export interface Response extends API.WithPagination<Anime> {}
export interface Response extends API.WithPagination<CharacterAnime> {}

export type Anime = {
export type CharacterAnime = {
main: boolean;
anime: API.Anime;
};
Expand Down

0 comments on commit 0c9da0c

Please sign in to comment.