This commit is contained in:
User
2025-01-04 13:02:50 -05:00
parent da807296f3
commit 489e054614
20 changed files with 377 additions and 61 deletions

View File

@@ -1,6 +1,6 @@
import { useState } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import { Plus, Star, ArrowDownNarrowWide, ArrowUpNarrowWide, ChevronsLeft, ChevronsRight } from 'lucide-react';
import { Plus, Star, ArrowDownNarrowWide, ArrowUpNarrowWide, ChevronsLeft, ChevronsRight, Trash2 } from 'lucide-react';
import AppLayout from '@/Layouts/AppLayout.jsx';
@@ -23,11 +23,27 @@ export default function Chapters({ auth, comic, chapters, histories, offset }) {
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.`,
});
});
}
toast({
title: "All set",
description: `${comic.comic.name} is now in / remove your favorite list.`,
const removeAllHistoriesOnClickHandler = (pathword) => {
router.visit(route('comics.destroyHistory', { pathword: pathword }), {
method: 'DELETE',
replace: false,
preserveScroll: true,
preserveState: true,
showProgress: false,
only: ['histories'],
onSuccess: () => {
toast({
title: "All set",
description: `All histories have been removed.`,
});
}
});
}
@@ -101,6 +117,12 @@ export default function Chapters({ auth, comic, chapters, histories, offset }) {
<td className="text-right w-24 pr-3">Alias</td>
<td>{ comic.comic.alias }</td>
</tr>
<tr>
<td className="text-right pr-3">Status</td>
<td>
{ comic.comic.region.display } / { comic.comic.status.display }
</td>
</tr>
<tr>
<td className="text-right pr-3">Category</td>
<td>
@@ -115,9 +137,9 @@ export default function Chapters({ auth, comic, chapters, histories, offset }) {
<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 href={ route('comics.author', [a.path_word]) }>{ a.name }</Link>
</Badge>
<Badge key={ a.path_word } className="m-2" variant="outline">
<Link href={ route('comics.author', [a.path_word]) }>{ a.name }</Link>
</Badge>
) ) }
</td>
</tr>
@@ -149,10 +171,32 @@ export default function Chapters({ auth, comic, chapters, histories, offset }) {
</TabsTrigger>
)) }
</TabsList>
<div>
<Button variant="link" size="icon" onClick={ () => toggleAscending() }>
{ ascending ? <ArrowDownNarrowWide /> : <ArrowUpNarrowWide /> }
</Button>
<div className="flex justify-end">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="link" size="icon" onClick={ () => toggleAscending() }>
{ ascending ? <ArrowDownNarrowWide /> : <ArrowUpNarrowWide /> }
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Set order as { ascending ? 'Descending' : 'Ascending' }</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="link" size="icon" onClick={ () => removeAllHistoriesOnClickHandler(comic.comic.path_word) }>
<Trash2 />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Remove all histories for this comic</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</div>
<TabsContent value={ group }>

View File

@@ -2,6 +2,8 @@ import { useState } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import AppLayout from '@/Layouts/AppLayout.jsx';
import { DateTime } from "luxon";
import { BreadcrumbItem, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";
import { Button } from '@/components/ui/button';
import Checkbox from "@/components/Checkbox";
@@ -25,19 +27,11 @@ export default function Histories({ auth, histories }) {
}
const datetimeConversion = (iso8601) => {
const date = new Date(iso8601);
const year = date.getUTCFullYear();
const month = String(date.getUTCMonth() + 1).padStart(2, '0'); // Months are 0-based
const day = String(date.getUTCDate()).padStart(2, '0');
const hours = String(date.getUTCHours()).padStart(2, '0');
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}`;
return DateTime.fromISO(iso8601).setZone(auth.user.settings.timezone).toFormat('dd-MM-yyyy HH:mm');
}
const deleteButtonOnClickHandler = () => {
router.visit(route('comics.destroyHistories'), {
router.visit(route('comics.patchHistories'), {
data: (ids.length > 0) ? { ids: ids } : { ids: 'all' },
method: "PATCH",
only: ['histories'],
@@ -50,6 +44,20 @@ export default function Histories({ auth, histories }) {
});
}
const removeDuplicatedButtonOnClickHandler = () => {
router.visit(route('comics.destroyHistories'), {
data: (ids.length > 0) ? { ids: ids } : { ids: 'all' },
method: "DELETE",
only: ['histories'],
onSuccess: data => {
toast({
title: "All set",
description: `The duplicated records has been deleted.`,
});
}
});
}
return (
<AppLayout auth={ auth } header={
<>
@@ -67,6 +75,10 @@ export default function Histories({ auth, histories }) {
<Button size="sm" variant="destructive" onClick={ () => deleteButtonOnClickHandler() }>
{ ids.length > 0 ? `Delete selected (${ids.length})` : "Delete All" }
</Button>
<Button size="sm" variant="destructive" onClick={ () => removeDuplicatedButtonOnClickHandler() }>
Remove duplicates
</Button>
</div>
<Table>
<TableHeader>
@@ -74,7 +86,7 @@ export default function Histories({ auth, histories }) {
<TableHead>Select</TableHead>
<TableHead>Chapter</TableHead>
<TableHead>Comic</TableHead>
<TableHead className="hidden lg:block">Read at</TableHead>
<TableHead className="invisible lg:visible">Read at</TableHead>
</TableRow>
</TableHeader>
<TableBody>
@@ -97,7 +109,7 @@ export default function Histories({ auth, histories }) {
{ h.comic.name }
</Link>
</TableCell>
<TableCell className="hidden lg:block">{ datetimeConversion(h.read_at) }</TableCell>
<TableCell className="invisible lg:visible">{ datetimeConversion(h.pivot.created_at) }</TableCell>
</TableRow>
)) }
</TableBody>

View File

@@ -14,7 +14,7 @@ export default function Index({ comics, offset, auth }) {
const url = new URL(window.location); //searchParams
const [favourites, setFavourites] = useState(auth.user.favourites);
const [favourites, setFavourites] = useState(auth.user?.favourites);
const { toast } = useToast();
const favouriteOnClickHandler = (pathword) => {