feat(adminsite): create and renew a free instance

Adds the create form with a live slug preview, a renew action inside the
seven-day window, and a deletion countdown that renders only when the
backend has actually promised a date.

The progress bar denominator now follows the tier; a 30-day Free licence
was rendering as an 8% sliver against the hardcoded 365.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mrhid6
2026-07-26 13:30:42 +01:00
co-authored by Claude Opus 5
parent a940390791
commit cb90ed12fb
5 changed files with 177 additions and 29 deletions
+4 -1
View File
@@ -57,7 +57,7 @@ const post = <T,>(path: string, payload?: unknown) =>
export type Deployment = "cloud" | "self_hosted";
export type Tier = "free" | "professional" | "self_hosted";
export type InstanceStatus = "awaiting_link" | "active" | "lapsed" | "cancelled";
export type InstanceStatus = "awaiting_link" | "active" | "lapsed" | "cancelled" | "deleted";
export interface Session {
kind: "staff" | "customer";
@@ -91,6 +91,7 @@ export interface Instance {
current_license?: string;
relink_count: number;
inject_failed_at?: string | null;
notices_sent?: string[];
created_at: string;
}
@@ -187,6 +188,8 @@ export const api = {
account: () => req<AccountResponse>("/api/account"),
link: (instance_id: string, name: string) =>
post<Instance>("/api/instances/link", { instance_id, name }),
createInstance: (name: string) => post<Instance>("/api/instances", { name }),
renewInstance: (id: string) => post<License>(`/api/instances/${id}/renew`, {}),
relink: (id: string, instance_id: string) =>
post<License>(`/api/instances/${id}/relink`, { instance_id }),
license: (id: string) => req<License & { blob?: string }>(`/api/instances/${id}/license`),