diff --git a/src/app/chain/page.tsx b/src/app/chain/page.tsx index 07172ae4..aa4605ba 100644 --- a/src/app/chain/page.tsx +++ b/src/app/chain/page.tsx @@ -1,234 +1,14 @@ -"use client"; - -import { useState } from "react"; -import { useAccount } from "wagmi"; -import { useQuery } from "@tanstack/react-query"; -import { - validateContentLength, - MIN_CONTENT_LENGTH, - MAX_CONTENT_LENGTH, -} from "../../../lib/content"; -import { supabase, type Storyline } from "../../../lib/supabase"; -import { STORY_FACTORY } from "../../../lib/contracts/constants"; -import { useChainPlot } from "../../hooks/useChainPlot"; -import { usePublishIntent } from "../../hooks/usePublishIntent"; -import { RecoveryBanner } from "../../components/RecoveryBanner"; -import type { PublishState } from "../../hooks/usePublish"; -import Link from "next/link"; -import { ConnectWallet } from "../../components/ConnectWallet"; -import { Select } from "../../components/Select"; - -const STATE_LABELS: Record = { - idle: "", - uploading: "Uploading to IPFS...", - confirming: "Confirm in wallet...", - pending: "Publishing to Base...", - indexing: "Indexing...", - published: "Published!", - error: "Error", -}; - -async function fetchWriterStorylines(address: string): Promise { - if (!supabase) return []; - const { data } = await supabase - .from("storylines") - .select("*") - .eq("writer_address", address.toLowerCase()) - .eq("hidden", false) - .eq("sunset", false) - .eq("contract_address", STORY_FACTORY.toLowerCase()) - .order("block_timestamp", { ascending: false }) - .returns(); - return data ?? []; -} - -export default function ChainPlotPage() { - const { address, isConnected } = useAccount(); - const [storylineId, setStorylineId] = useState(null); - const [title, setTitle] = useState(""); - const [content, setContent] = useState(""); - - const { data: storylines = [], isLoading: loadingStorylines } = useQuery({ - queryKey: ["writer-active-storylines", address], - queryFn: () => fetchWriterStorylines(address!), - enabled: isConnected && !!address, - }); - - const { pendingIntent, saveIntent, persistTxHash, clearIntent, attemptRetry } = - usePublishIntent(); - const { state, error, chainPlot, reset } = useChainPlot({ - onIntentSave: saveIntent, - onTxConfirmed: persistTxHash, - onIndexed: clearIntent, - }); - const { valid, charCount } = validateContentLength(content); - const titleValid = title.trim().length > 0; - const canSubmit = - (state === "idle" || state === "error") && - storylineId !== null && - titleValid && - valid; - - if (!isConnected) { - return ( -
-

- Connect your wallet to chain a plot. -

- -
- ); - } - - if (state === "published") { - return ( -
-

Plot chained!

-
- {storylineId && ( - - View story - - )} - -
-
- ); +import { redirect } from "next/navigation"; + +export default async function ChainRedirect({ + searchParams, +}: { + searchParams: Promise>; +}) { + const params = await searchParams; + const sp = new URLSearchParams({ tab: "chain" }); + for (const [key, value] of Object.entries(params)) { + if (key !== "tab") sp.set(key, value); } - - const busy = state !== "idle" && state !== "error"; - const noStoryline = storylineId === null; - - return ( -
-

- Chain Plot -

- - {pendingIntent && ( -
- -
- )} - -
{ - e.preventDefault(); - if (canSubmit) chainPlot(storylineId, content, title); - }} - className="mt-8 space-y-6" - > - {/* Storyline selector */} -
- - {loadingStorylines ? ( -

Loading storylines...

- ) : storylines.length === 0 ? ( -

- No active storylines.{" "} - - Create one - -

- ) : ( - setTitle(e.target.value.slice(0, 100))} - disabled={busy || noStoryline} - placeholder={noStoryline ? "Select a storyline first" : "e.g. The Silent Storm"} - maxLength={100} - className="border-border bg-surface text-foreground placeholder:text-muted w-full rounded border px-3 py-2 text-sm focus:border-accent focus:outline-none disabled:opacity-50" - /> -
- {!titleValid && content.length > 0 ? ( - Title is required - ) : ( - - )} - {title.length} / 100 chars -
-
- - {/* Content */} -
- -