diff --git a/frontend/src/components/RelayDetailCard.tsx b/frontend/src/components/RelayDetailCard.tsx index d287b10..00ef722 100644 --- a/frontend/src/components/RelayDetailCard.tsx +++ b/frontend/src/components/RelayDetailCard.tsx @@ -1,5 +1,6 @@ import { A } from "@solidjs/router" import { Show, createEffect, createSignal, onCleanup } from "solid-js" +import { getProfilePicture } from "applesauce-core/helpers/profile" import type { Relay, PlanId } from "@/lib/api" import menuDotsIcon from "@/assets/menu-dots-2.svg" import ConfirmDialog from "@/components/ConfirmDialog" @@ -8,7 +9,12 @@ import PricingTable from "@/components/PricingTable" import ToggleButton from "@/components/ToggleButton" import ToggleField from "@/components/ToggleField" import { setToastMessage } from "@/components/Toast" -import { plans } from "@/lib/state" +import { primeProfiles } from "@/lib/hooks" +import { eventStore, plans } from "@/lib/state" + +function shortenPubkey(pubkey: string) { + return pubkey.length <= 16 ? pubkey : `${pubkey.slice(0, 8)}...${pubkey.slice(-8)}` +} const STATUS_STYLES: Record = { active: "bg-green-50 text-green-700 border-green-200", @@ -78,6 +84,28 @@ export default function RelayDetailCard(props: RelayDetailCardProps) { const [menuOpen, setMenuOpen] = createSignal(false) const [planId, setPlanId] = createSignal(props.relay.plan_id) const [pendingAction, setPendingAction] = createSignal<"deactivate" | "reactivate" | null>(null) + const [tenantProfile, setTenantProfile] = createSignal<{ name?: string; picture?: string }>({}) + + // Resolve the owning tenant's profile so the Tenant field can show a name and + // avatar instead of a raw pubkey. Only relevant in admin (showTenant) views. + createEffect(() => { + if (!props.showTenant) return + const pubkey = props.relay.tenant_pubkey + if (!pubkey) return + + const sub = eventStore.profile(pubkey).subscribe((metadata) => { + setTenantProfile({ + name: metadata?.name || metadata?.display_name, + picture: getProfilePicture(metadata), + }) + }) + const primeSub = primeProfiles([pubkey]) + + onCleanup(() => { + sub.unsubscribe() + primeSub.unsubscribe() + }) + }) let menuContainerRef: HTMLDivElement | undefined @@ -184,6 +212,21 @@ export default function RelayDetailCard(props: RelayDetailCardProps) { > wss://{r().subdomain}.spaces.coracle.social + + + + {(tenantProfile().name || r().tenant_pubkey).slice(0, 1).toUpperCase()} + + } + > + + + {tenantProfile().name || shortenPubkey(r().tenant_pubkey)} + +

{r().info_description}

@@ -358,11 +401,6 @@ export default function RelayDetailCard(props: RelayDetailCardProps) { {memberLimitLabel()} - - - {r().tenant_pubkey} - - diff --git a/frontend/src/components/RelayForm.tsx b/frontend/src/components/RelayForm.tsx index ffde8e2..fe62adf 100644 --- a/frontend/src/components/RelayForm.tsx +++ b/frontend/src/components/RelayForm.tsx @@ -1,4 +1,4 @@ -import { createEffect, createMemo, createSignal, For } from "solid-js" +import { createEffect, createMemo, createSignal, For, Show } from "solid-js" import type { Relay } from "@/lib/hooks" import { slugify } from "@/lib/slugify" import { validateSubdomainLabel } from "@/lib/subdomain" @@ -10,12 +10,16 @@ export type RelayFormValues = Pick syncSubdomainWithName?: boolean + // The plan can't be changed by editing a relay (only at creation or via the + // detail card), so the edit form hides the selector by passing false here. + showPlanSelector?: boolean onSubmit: (values: RelayFormValues) => Promise | void submitLabel: string submittingLabel: string } export default function RelayForm(props: RelayFormProps) { + const showPlanSelector = () => props.showPlanSelector ?? true const defaultPlanId = createMemo(() => props.initialValues?.plan_id ?? plans()[0]?.id ?? "free") const [planId, setPlanId] = createSignal(defaultPlanId()) const [name, setName] = createSignal(props.initialValues?.info_name ?? "") @@ -27,7 +31,7 @@ export default function RelayForm(props: RelayFormProps) { async function handleSubmit(e: Event) { e.preventDefault() - if (!planId()) { + if (showPlanSelector() && !planId()) { setToastMessage("Please select a plan") return } @@ -105,28 +109,30 @@ export default function RelayForm(props: RelayFormProps) { class="w-full border border-gray-300 rounded-lg px-3 py-2" /> -
- -
- - {(p) => ( - - )} - + +
+ +
+ + {(p) => ( + + )} + +
-
+
diff --git a/frontend/src/pages/relays/RelayEdit.tsx b/frontend/src/pages/relays/RelayEdit.tsx index 75af1d2..294ffc5 100644 --- a/frontend/src/pages/relays/RelayEdit.tsx +++ b/frontend/src/pages/relays/RelayEdit.tsx @@ -33,6 +33,7 @@ export default function RelayEdit(props: { basePath?: string; title?: string })