Files
cv4/resources/js/Pages/Comic/Chapters.jsx
2024-12-27 21:20:40 -05:00

162 lines
7.8 KiB
JavaScript

import { useState } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import { Moon, Plus, Star, ArrowDownNarrowWide, ArrowUpNarrowWide } from 'lucide-react';
import AppLayout from '@/Layouts/AppLayout.jsx';
import { BreadcrumbItem, BreadcrumbPage, BreadcrumbSeparator } from '@/components/ui/breadcrumb';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { useToast } from '@/hooks/use-toast';
import { Badge } from "@/components/ui/badge.jsx";
export default function Chapters({ auth, comic, chapters }) {
const [group, setGroup] = useState('default');
const [favourites, setFavourites] = useState(auth.user.favourites);
const [ascending, setAscending] = useState(true);
const { toast } = useToast();
const favouriteOnClickHandler = (pathword) => {
axios.post(route('comics.postFavourite'), { pathword: pathword }).then(res => {
setFavourites(res.data);
});
toast({
title: "All set",
description: `${comic.comic.name} is now in / remove your favorite list.`,
});
}
const groupOnClickHandler = (pathword) => {
router.get(`/comic/${ comic.comic.path_word }?group=${ pathword }`, {}, {
only: ['chapters'],
preserveState: true
});
setGroup(pathword);
setAscending(true);
}
const ComicChapterLink = (props) => {
const isNew = Date.now() - Date.parse(props.datetime_created) < 6.048e+8;
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button className="" size="sm" variant="outline" asChild>
<Link className="relative" href={ `/comic/${ comic.comic.path_word }/${ props.uuid }` }>
{ props.name }
{ isNew && <Plus size={ 16 } className="text-xs absolute right-0 top-0" /> }
</Link>
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Updated: { props.datetime_created }</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
const toggleAscending = (e) => {
setAscending(!ascending);
}
return (
<AppLayout auth={ auth } header={
<>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>{ comic.comic.name }</BreadcrumbPage>
</BreadcrumbItem>
</>
}>
<Head>
<title>{ comic.comic.name }</title>
</Head>
<div className="p-3 pt-1">
<Card>
<CardHeader>
<CardTitle className="flex flex-row content-end items-center">
<Button onClick={ () => favouriteOnClickHandler(comic.comic.path_word) } size="icon" variant="ghost">
<Star fill={ favourites.includes(comic.comic.path_word) ? 'yellow': 'white' } />
</Button>
<span>{ comic.comic.name }</span>
</CardTitle>
</CardHeader>
<CardContent className="flex justify-start justify-items-stretch content-start items-start gap-5 flex-wrap">
<div className="basis-full lg:basis-2/12">
<img className="block object-fill w-full" src={ "/image/" + btoa(comic.comic.cover) }
alt={ comic.comic.name } />
</div>
<div className="basis-full lg:basis-9/12">
<table className="table-fixed w-full text-sm">
<tbody>
<tr>
<td className="text-right w-24 pr-3">Alias</td>
<td>{ comic.comic.alias }</td>
</tr>
<tr>
<td className="text-right pr-3">Category</td>
<td>
{ comic.comic.theme.map(t =>
<Badge key={ t.path_word } className="m-2" variant="outline">
<Link href={ route("comics.index", { tag: t.path_word }) }>{ t.name }</Link>
</Badge>
) }
</td>
</tr>
<tr>
<td className="text-right pr-3">Authors</td>
<td>{ comic.comic.author.map(a => <Badge key={ a.path_word } className="m-2" variant="outline"><Link>{ a.name }</Link></Badge>) }</td>
</tr>
<tr>
<td className="text-right pr-3">Description</td>
<td>{ comic.comic.brief }</td>
</tr>
<tr>
<td className="text-right pr-3">Updated At</td>
<td>{ comic.comic.datetime_updated }</td>
</tr>
</tbody>
</table>
</div>
</CardContent>
<CardContent>
<Tabs defaultValue={ group } className="w-full">
<div className="flex">
<TabsList className={ `grid w-full grid-cols-${ Object.entries(comic.groups).length } ` }>
{ Object.entries(comic.groups).map((g, i) => (
<TabsTrigger onClick={ () => groupOnClickHandler(g[1].path_word) }
key={ g[1].path_word }
value={ g[1].path_word }>
{ g[1].name }
</TabsTrigger>
)) }
</TabsList>
<div>
<Button variant="link" size="icon" onClick={ () => toggleAscending() }>
{ ascending ? <ArrowDownNarrowWide /> : <ArrowUpNarrowWide /> }
</Button>
</div>
</div>
<TabsContent value={ group }>
<div className="w-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 xl:grid-cols-12 gap-1">
{ chapters.list.sort((a, b) => ascending ? (a.index - b.index) : (b.index - a.index)).map(c => (
<ComicChapterLink key={ c.uuid } { ...c } />
) ) }
</div>
</TabsContent>
</Tabs>
</CardContent>
</Card>
</div>
</AppLayout>
);
}