Skip to content

Commit

Permalink
add vote to collections
Browse files Browse the repository at this point in the history
  • Loading branch information
olexh committed Mar 22, 2024
1 parent f9c4f77 commit 958abac
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 97 deletions.
7 changes: 5 additions & 2 deletions app/(pages)/anime/[slug]/_components/cover.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import FavoriteButton from '@/components/favorite-button';
import EntryCard from '@/components/entry-card/entry-card';
import FavoriteButton from '@/components/favorite-button';

interface Props {
anime?: API.AnimeInfo;
Expand All @@ -13,7 +13,10 @@ const Component = ({ anime }: Props) => {
return (
<div className="flex items-center px-16 md:px-48 lg:px-0">
<EntryCard poster={anime.poster}>
<FavoriteButton slug={anime.slug} content_type="anime" />
<div className="absolute bottom-2 right-2 z-[1]">
<FavoriteButton slug={anime.slug} content_type="anime" />
</div>

<div className="absolute bottom-0 left-0 h-24 w-full bg-gradient-to-t from-black to-transparent" />
</EntryCard>
</div>
Expand Down
12 changes: 7 additions & 5 deletions app/(pages)/characters/[slug]/_components/cover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import { useParams } from 'next/navigation';

import FavoriteButton from '@/components/favorite-button';
import EntryCard from '@/components/entry-card/entry-card';
import FavoriteButton from '@/components/favorite-button';
import useCharacterInfo from '@/services/hooks/characters/useCharacterInfo';

const Component = () => {
Expand All @@ -18,10 +18,12 @@ const Component = () => {
return (
<div className="flex items-center px-16 md:px-48 lg:px-0">
<EntryCard poster={character.image}>
<FavoriteButton
slug={character.slug}
content_type="character"
/>
<div className="absolute bottom-2 right-2 z-[1]">
<FavoriteButton
slug={character.slug}
content_type="character"
/>
</div>
<div className="absolute bottom-0 left-0 h-24 w-full bg-gradient-to-t from-black to-transparent" />
</EntryCard>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { memo } from 'react';
import IconamoonCommentFill from '~icons/iconamoon/comment-fill';
import MaterialSymbolsGridViewRounded from '~icons/material-symbols/grid-view-rounded';
import MaterialSymbolsMoreHoriz from '~icons/material-symbols/more-horiz';
import BxBxsUpvote from '~icons/bx/bxs-upvote';

import Link from 'next/link';

Expand Down Expand Up @@ -63,6 +64,10 @@ const Component = ({ collection }: Props) => {
<IconamoonCommentFill />
<Small>{collection.comments_count}</Small>
</div>
<div className="flex gap-1">
<BxBxsUpvote />
<Small>{collection.vote_score}</Small>
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
'use client';

import React from 'react';
import React, { memo } from 'react';



import SubHeader from '@/components/sub-header';
import EntryCard from '@/components/entry-card/entry-card';
import {
Group as CollectionGroup,
useCollectionContext,
} from '@/services/providers/collection-provider';
import SubHeader from '@/components/sub-header';
import { Group as CollectionGroup, useCollectionContext } from '@/services/providers/collection-provider';


interface Props {
group: CollectionGroup;
Expand All @@ -16,11 +16,7 @@ interface Props {
const Component = ({ group }: Props) => {
const { groups, setState: setCollectionState } = useCollectionContext();

const items = groups.find((g) => g.id === group.id)?.items;

if (!items) {
return null;
}
const items = groups.find((g) => g.id === group.id)?.items || []

return (
<div className="flex flex-col gap-4">
Expand Down Expand Up @@ -55,4 +51,4 @@ const Component = ({ group }: Props) => {
);
};

export default Component;
export default memo(Component);
164 changes: 114 additions & 50 deletions app/(pages)/collections/[reference]/_components/collection-info.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
'use client';

import React from 'react';
import BxBxsDownvote from '~icons/bx/bxs-downvote';
import BxBxsUpvote from '~icons/bx/bxs-upvote';
import BxDownvote from '~icons/bx/downvote';
import BxUpvote from '~icons/bx/upvote';
import MaterialSymbolsDeleteForeverRounded from '~icons/material-symbols/delete-forever-rounded';

import Link from 'next/link';
import { useParams } from 'next/navigation';

import { useQueryClient } from '@tanstack/react-query';

import FavoriteButton from '@/components/favorite-button';
import SubHeader from '@/components/sub-header';
import H5 from '@/components/typography/h5';
Expand All @@ -26,12 +32,16 @@ import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import vote from '@/services/api/vote/vote';
import useCollection from '@/services/hooks/collections/useCollection';
import useDeleteCollection from '@/services/hooks/collections/useDeleteCollection';
import useLoggedUser from '@/services/hooks/user/useLoggedUser';
import { useAuthContext } from '@/services/providers/auth-provider';
import { useCollectionContext } from '@/services/providers/collection-provider';

const Component = () => {
const queryClient = useQueryClient();
const { secret } = useAuthContext();
const params = useParams();
const { nsfw, spoiler, tags } = useCollectionContext();

Expand All @@ -50,54 +60,82 @@ const Component = () => {
loggedUser?.role === 'admin' ||
loggedUser?.role === 'moderator';

const handleCollectionVote = async (score: -1 | 1) => {
if (!collection) return;

const updated = collection?.my_score === score ? 0 : score;

await vote({
secret: String(secret),
slug: collection.reference,
score: updated,
content_type: 'collection',
});

await queryClient.invalidateQueries({
queryKey: ['collection', collection.reference, { secret }],
exact: false,
});
};

if (!collection) {
return null;
}

return (
<div className="flex w-full flex-col items-start gap-8">
<SubHeader title="Деталі" />
<div className="flex w-full flex-col gap-6 rounded-md border border-secondary/60 bg-secondary/30 p-4">
<div className="flex flex-col gap-4">
<Label className="text-muted-foreground">Автор</Label>
<div className="flex w-full gap-4">
<Link href={`/u/${collection?.author.username}`}>
<Avatar className="size-12 rounded-md">
<AvatarImage
className="rounded-md"
src={collection?.author.avatar}
alt={collection?.author.username}
/>
<AvatarFallback className="rounded-md">
{collection?.author.username[0]}
</AvatarFallback>
</Avatar>
</Link>
<div className="flex flex-1 flex-col">
<Link href={'/u/' + collection?.author.username}>
<H5>{collection?.author.username}</H5>
<div className="flex w-full flex-col gap-4">
<div className="flex w-full flex-col gap-6 rounded-md border border-secondary/60 bg-secondary/30 p-4">
<div className="flex flex-col gap-4">
<Label className="text-muted-foreground">Автор</Label>
<div className="flex w-full gap-4">
<Link href={`/u/${collection?.author.username}`}>
<Avatar className="size-12 rounded-md">
<AvatarImage
className="rounded-md"
src={collection?.author.avatar}
alt={collection?.author.username}
/>
<AvatarFallback className="rounded-md">
{collection?.author.username[0]}
</AvatarFallback>
</Avatar>
</Link>
<div className="flex flex-1 flex-col">
<Link
href={'/u/' + collection?.author.username}
>
<H5>{collection?.author.username}</H5>
</Link>
</div>
</div>
</div>
</div>
{tags.length > 0 && (
<div className="flex items-center gap-2">
{tags.map((tag) => (
<Badge key={tag} variant="secondary">
{tag.toLowerCase()}
</Badge>
))}
{tags.length > 0 && (
<div className="flex items-center gap-2">
{tags.map((tag) => (
<Badge key={tag} variant="secondary">
{tag.toLowerCase()}
</Badge>
))}
</div>
)}
<div className="flex items-center justify-between gap-4">
<Label htmlFor="nsfw" className="text-muted-foreground">
Контент +18
</Label>
<Switch checked={nsfw} id="nsfw" />
</div>
)}
<div className="flex items-center justify-between gap-4">
<Label htmlFor="nsfw" className="text-muted-foreground">
Контент +18
</Label>
<Switch checked={nsfw} id="nsfw" />
</div>
<div className="flex items-center justify-between gap-4">
<Label htmlFor="spoiler" className="text-muted-foreground">
Спойлери
</Label>
<Switch checked={spoiler} id="spoiler" />
</div>
<div className="flex flex-col gap-4">
<div className="flex items-center justify-between gap-4">
<Label
htmlFor="spoiler"
className="text-muted-foreground"
>
Спойлери
</Label>
<Switch checked={spoiler} id="spoiler" />
</div>

{access && (
<div className="flex gap-2">
<Button
Expand Down Expand Up @@ -149,17 +187,43 @@ const Component = () => {
</AlertDialog>
</div>
)}
{collection && (
<FavoriteButton
slug={collection.reference}
content_type="collection"
size="default"
</div>

<div className="flex w-full items-center gap-2">
<div className="flex flex-1 items-center justify-between gap-4 rounded-md border border-secondary/60 bg-secondary/30 p-1">
<Button
onClick={() => handleCollectionVote(1)}
size="icon-md"
variant="secondary"
className=""
disabled={!secret}
>
Улюблене
</FavoriteButton>
)}
{collection?.my_score === 1 ? (
<BxBxsUpvote className="text-success" />
) : (
<BxUpvote />
)}
</Button>
<Label>{collection?.vote_score}</Label>
<Button
onClick={() => handleCollectionVote(-1)}
size="icon-md"
variant="secondary"
disabled={!secret}
>
{collection?.my_score === -1 ? (
<BxBxsDownvote className="text-destructive" />
) : (
<BxDownvote />
)}
</Button>
</div>
<FavoriteButton
disabled={!secret}
slug={collection.reference}
content_type="collection"
size="icon"
variant="secondary"
/>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import IconamoonCommentFill from '~icons/iconamoon/comment-fill';
import MaterialSymbolsGridViewRounded from '~icons/material-symbols/grid-view-rounded';
import BxBxsUpvote from '~icons/bx/bxs-upvote';

import Link from 'next/link';

Expand All @@ -8,6 +9,7 @@ import EntryCard from '@/components/entry-card/entry-card';
import { Label } from '@/components/ui/label';
import { cn } from '@/utils';
import parseTextFromMarkDown from '@/utils/parseTextFromMarkDown';
import React from 'react';

interface Props {
data: API.Collection;
Expand Down Expand Up @@ -65,6 +67,10 @@ const Component = ({ data, className }: Props) => {
<IconamoonCommentFill />
<Small>{data.comments_count}</Small>
</div>
<div className="flex gap-1">
<BxBxsUpvote />
<Small>{data.vote_score}</Small>
</div>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 958abac

Please sign in to comment.