mirror of
https://github.com/xCyanGrizzly/DragonsStash.git
synced 2026-05-10 22:01:16 +00:00
feat: add skipped/failed packages tab to STL files page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import { useDataTable } from "@/hooks/use-data-table";
|
||||
import { getPackageColumns, type PackageRow } from "./package-columns";
|
||||
import { PackageFilesDrawer } from "./package-files-drawer";
|
||||
import { IngestionStatus } from "./ingestion-status";
|
||||
import { SkippedPackagesTab } from "./skipped-packages-tab";
|
||||
import { DataTable } from "@/components/shared/data-table";
|
||||
import { DataTablePagination } from "@/components/shared/data-table-pagination";
|
||||
import { DataTableViewOptions } from "@/components/shared/data-table-view-options";
|
||||
@@ -20,7 +21,10 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import type { IngestionAccountStatus } from "@/lib/telegram/types";
|
||||
import type { SkippedRow } from "./skipped-columns";
|
||||
import { updatePackageCreator, updatePackageTags } from "../actions";
|
||||
|
||||
interface StlTableProps {
|
||||
@@ -30,6 +34,9 @@ interface StlTableProps {
|
||||
ingestionStatus: IngestionAccountStatus[];
|
||||
availableTags: string[];
|
||||
searchTerm: string;
|
||||
skippedData: SkippedRow[];
|
||||
skippedPageCount: number;
|
||||
skippedTotalCount: number;
|
||||
}
|
||||
|
||||
export function StlTable({
|
||||
@@ -39,6 +46,9 @@ export function StlTable({
|
||||
ingestionStatus,
|
||||
availableTags,
|
||||
searchTerm,
|
||||
skippedData,
|
||||
skippedPageCount,
|
||||
skippedTotalCount,
|
||||
}: StlTableProps) {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
@@ -77,6 +87,22 @@ export function StlTable({
|
||||
[router, pathname, searchParams]
|
||||
);
|
||||
|
||||
const activeTab = searchParams.get("tab") ?? "packages";
|
||||
|
||||
const updateTab = useCallback(
|
||||
(value: string) => {
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
if (value === "packages") {
|
||||
params.delete("tab");
|
||||
} else {
|
||||
params.set("tab", value);
|
||||
}
|
||||
params.set("page", "1");
|
||||
router.push(`${pathname}?${params.toString()}`, { scroll: false });
|
||||
},
|
||||
[router, pathname, searchParams]
|
||||
);
|
||||
|
||||
const columns = getPackageColumns({
|
||||
onViewFiles: (pkg) => setViewPkg(pkg),
|
||||
searchTerm,
|
||||
@@ -125,6 +151,20 @@ export function StlTable({
|
||||
<IngestionStatus initialStatus={ingestionStatus} />
|
||||
</PageHeader>
|
||||
|
||||
<Tabs value={activeTab} onValueChange={updateTab}>
|
||||
<TabsList>
|
||||
<TabsTrigger value="packages">Packages</TabsTrigger>
|
||||
<TabsTrigger value="skipped" className="gap-1.5">
|
||||
Skipped / Failed
|
||||
{skippedTotalCount > 0 && (
|
||||
<Badge variant="secondary" className="text-[10px] ml-1">
|
||||
{skippedTotalCount}
|
||||
</Badge>
|
||||
)}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="packages" className="space-y-4">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<div className="relative flex-1 min-w-[200px] max-w-sm">
|
||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
@@ -158,6 +198,16 @@ export function StlTable({
|
||||
emptyMessage="No packages found. Archives will appear here after ingestion."
|
||||
/>
|
||||
<DataTablePagination table={table} totalCount={totalCount} />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="skipped">
|
||||
<SkippedPackagesTab
|
||||
data={skippedData}
|
||||
pageCount={skippedPageCount}
|
||||
totalCount={skippedTotalCount}
|
||||
/>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
<PackageFilesDrawer
|
||||
pkg={viewPkg}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { auth } from "@/lib/auth";
|
||||
import { redirect } from "next/navigation";
|
||||
import { listPackages, searchPackages, getIngestionStatus, getAllPackageTags } from "@/lib/telegram/queries";
|
||||
import { listPackages, searchPackages, getIngestionStatus, getAllPackageTags, listSkippedPackages, countSkippedPackages } from "@/lib/telegram/queries";
|
||||
import { StlTable } from "./_components/stl-table";
|
||||
|
||||
interface Props {
|
||||
@@ -20,9 +20,10 @@ export default async function StlFilesPage({ searchParams }: Props) {
|
||||
const search = (params.search as string) ?? "";
|
||||
const creator = (params.creator as string) || undefined;
|
||||
const tag = (params.tag as string) || undefined;
|
||||
const tab = (params.tab as string) ?? "packages";
|
||||
|
||||
// Fetch packages, ingestion status, and available tags in parallel
|
||||
const [result, ingestionStatus, availableTags] = await Promise.all([
|
||||
// Fetch packages, ingestion status, tags, and skipped count in parallel
|
||||
const [result, ingestionStatus, availableTags, skippedCount] = await Promise.all([
|
||||
search
|
||||
? searchPackages({
|
||||
query: search,
|
||||
@@ -40,8 +41,14 @@ export default async function StlFilesPage({ searchParams }: Props) {
|
||||
}),
|
||||
getIngestionStatus(),
|
||||
getAllPackageTags(),
|
||||
countSkippedPackages(),
|
||||
]);
|
||||
|
||||
// Fetch skipped packages only if on that tab
|
||||
const skippedResult = tab === "skipped"
|
||||
? await listSkippedPackages({ page, limit: perPage })
|
||||
: null;
|
||||
|
||||
return (
|
||||
<StlTable
|
||||
data={result.items}
|
||||
@@ -50,6 +57,9 @@ export default async function StlFilesPage({ searchParams }: Props) {
|
||||
ingestionStatus={ingestionStatus}
|
||||
availableTags={availableTags}
|
||||
searchTerm={search}
|
||||
skippedData={skippedResult?.items ?? []}
|
||||
skippedPageCount={skippedResult?.pagination.totalPages ?? 0}
|
||||
skippedTotalCount={skippedCount}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user