@@ -7,7 +7,16 @@ import { Field } from "@/components/Field";
|
||||
|
||||
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
||||
|
||||
export function LinkForm({ onLinked }: { onLinked: (instanceId: string) => void }) {
|
||||
export function LinkForm({
|
||||
onLinked,
|
||||
claimId,
|
||||
}: {
|
||||
onLinked: (instanceId: string) => void;
|
||||
// When set, this is a PAID placeholder awaiting its real install UUID: claim
|
||||
// it in place rather than creating a fresh (Free) instance. The name was
|
||||
// chosen at checkout, so it is not asked for again.
|
||||
claimId?: string;
|
||||
}) {
|
||||
const [id, setId] = useState("");
|
||||
const [name, setName] = useState("");
|
||||
const [error, setError] = useState<string | undefined>();
|
||||
@@ -28,7 +37,9 @@ export function LinkForm({ onLinked }: { onLinked: (instanceId: string) => void
|
||||
setBusy(true);
|
||||
setError(undefined);
|
||||
try {
|
||||
const inst = await api.link(value, name.trim());
|
||||
const inst = claimId
|
||||
? await api.claimLink(claimId, value)
|
||||
: await api.link(value, name.trim());
|
||||
onLinked(inst.instance_id);
|
||||
} catch (err) {
|
||||
setError(
|
||||
@@ -58,12 +69,14 @@ export function LinkForm({ onLinked }: { onLinked: (instanceId: string) => void
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Field
|
||||
label="Name it (optional)"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
hint="So you can tell it apart from your other installs."
|
||||
/>
|
||||
{!claimId && (
|
||||
<Field
|
||||
label="Name it (optional)"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
hint="So you can tell it apart from your other installs."
|
||||
/>
|
||||
)}
|
||||
<Button type="submit" disabled={busy} className="justify-self-start">
|
||||
{busy ? "Linking…" : "Link and issue licence"}
|
||||
</Button>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { LinkForm } from "./LinkForm";
|
||||
import { PageHeader } from "@/components/PageHeader";
|
||||
@@ -8,6 +8,9 @@ import { PageHeader } from "@/components/PageHeader";
|
||||
export default function LinkPage() {
|
||||
const router = useRouter();
|
||||
const qc = useQueryClient();
|
||||
// A paid placeholder passes its id here so its install is claimed in place
|
||||
// rather than a second, Free instance being created alongside it.
|
||||
const claimId = useSearchParams().get("claim") ?? undefined;
|
||||
|
||||
return (
|
||||
<div className="grid max-w-2xl gap-6">
|
||||
@@ -17,6 +20,7 @@ export default function LinkPage() {
|
||||
subtitle="Every licence is tied to one install, so we need its ID before we can issue yours. Paste it below and your licence is ready on the next screen."
|
||||
/>
|
||||
<LinkForm
|
||||
claimId={claimId}
|
||||
onLinked={(instanceId) => {
|
||||
qc.invalidateQueries({ queryKey: ["account"] });
|
||||
// Straight to the download, not back to a list: the licence is
|
||||
|
||||
Reference in New Issue
Block a user