"use client";
import { useState, useTransition } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { clsx } from "clsx";
import {
addCollectionAction,
addTitleToUniverseAction,
createOrderAction,
createUniverseAction,
deleteOrderAction,
setDefaultOrderAction,
shareUniverseAction,
trashUniverseAction,
unshareUniverseAction,
} from "@/app/actions/universes";
import { useToasts } from "@/components/Toasts";
import type { UniverseView } from "@/lib/universes";
/** Formular für ein neues Universum. */
export function NewUniverseForm() {
const router = useRouter();
const { report } = useToasts();
const [pending, startTransition] = useTransition();
return (
);
}
/** Umschalter zwischen den Reihenfolgen eines Universums. */
export function OrderTabs({
universe,
canWrite,
}: {
universe: UniverseView;
canWrite: boolean;
}) {
const router = useRouter();
const params = useSearchParams();
const { report } = useToasts();
const [adding, setAdding] = useState(false);
const [, startTransition] = useTransition();
function select(orderId: string) {
const next = new URLSearchParams(params.toString());
next.set("reihenfolge", orderId);
router.replace(`/universen/${universe.id}?${next}`, { scroll: false });
}
const active = universe.orders.find((order) => order.id === universe.activeOrderId);
return (
{universe.orders.map((order) => {
const isActive = order.id === universe.activeOrderId;
return (
);
})}
{canWrite && (
<>
{adding ? (
) : (
)}
{active && !active.isDefault && (
)}
{active && active.kind === "CUSTOM" && (
)}
>
)}
);
}
/** Titel aus der eigenen Bibliothek aufnehmen — mit Tippfilter. */
export function AddTitles({
universeId,
candidates,
collections,
}: {
universeId: string;
candidates: { id: string; title: string; type: string; year: number | null }[];
collections: { id: number; name: string }[];
}) {
const router = useRouter();
const { report } = useToasts();
const [query, setQuery] = useState("");
const [pending, startTransition] = useTransition();
const filtered = query.trim()
? candidates
.filter((item) => item.title.toLocaleLowerCase("de-DE").includes(query.toLocaleLowerCase("de-DE")))
.slice(0, 8)
: candidates.slice(0, 8);
return (
{collections.length > 0 && (
Aus einer TMDB-Reihe übernehmen
{collections.map((collection) => (
))}
)}
Aus der Bibliothek aufnehmen
{candidates.length === 0 ? (
Alles aus deiner Bibliothek ist schon in diesem Universum.
) : (
<>
setQuery(event.target.value)}
placeholder="Titel filtern …"
aria-label="Titel filtern"
className="fl-input mb-2"
/>
{filtered.map((item) => (
-
))}
{filtered.length === 0 && (
- Kein Treffer.
)}
>
)}
);
}
/** Freigabe an andere Konten der Instanz. */
export function SharePanel({ universe }: { universe: UniverseView }) {
const router = useRouter();
const { report } = useToasts();
const [permission, setPermission] = useState<"READ" | "WRITE">("READ");
const [pending, startTransition] = useTransition();
return (
{universe.members.length > 0 && (
{universe.members.map((member) => (
-
{member.name}
{member.permission === "WRITE" ? "pflegt mit" : "liest mit"}
))}
)}
);
}
/** Universum löschen — mit Rückfrage. */
export function DeleteUniverse({ universeId, name }: { universeId: string; name: string }) {
const router = useRouter();
const { report } = useToasts();
const [confirming, setConfirming] = useState(false);
const [pending, startTransition] = useTransition();
if (!confirming) {
return (
);
}
return (
„{name}" wirklich löschen?
);
}