Add frontend spec
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# Account
|
||||
|
||||
The account page lets an authenticated tenant manage billing settings and review invoice history.
|
||||
|
||||
```pug
|
||||
page(path="/account", auth="required", shell="app")
|
||||
header
|
||||
title My Account
|
||||
|
||||
section(id="status")
|
||||
heading Account Status
|
||||
badge tenant
|
||||
|
||||
section(id="billing")
|
||||
heading Recurring Billing
|
||||
description Enable automatic payments by providing your Nostr Wallet Connect URL.
|
||||
input(name="nwc_url", placeholder="nostr+walletconnect://...")
|
||||
button Save
|
||||
error_message(on="save_failure")
|
||||
|
||||
section(id="invoices")
|
||||
heading Invoice History
|
||||
loading_state(message="Loading invoices...")
|
||||
list(empty="No invoices yet")
|
||||
item
|
||||
status
|
||||
created_at
|
||||
bolt11
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
# Admin Relay Detail
|
||||
|
||||
The admin relay detail page exposes relay state and controls with admin-level editing and deactivation.
|
||||
|
||||
```pug
|
||||
page(path="/admin/relays/:id", auth="required", role="admin", shell="app")
|
||||
back_link(href="/admin/relays", label="Relays")
|
||||
|
||||
loading_state(message="Loading relay...")
|
||||
error_state(message="Failed to load relay.")
|
||||
|
||||
relay_detail_card(edit_href="/admin/relays/:id/edit", show_tenant=true, enforce_plan_limits=false, show_plan_actions=false)
|
||||
actions
|
||||
button(action="admin_deactivate_relay") Deactivate
|
||||
toggles
|
||||
toggle(name="policy_public_join") Public join
|
||||
toggle(name="policy_strip_signatures") Strip signatures
|
||||
toggle(name="groups_enabled") Groups
|
||||
toggle(name="management_enabled") Management API
|
||||
toggle(name="blossom_enabled") Media storage
|
||||
toggle(name="livekit_enabled") LiveKit support
|
||||
toggle(name="push_enabled") Push notifications
|
||||
|
||||
error_message(on="mutation_failure")
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
# Admin Relay Edit
|
||||
|
||||
The admin relay edit page updates relay metadata and returns to the admin relay detail view.
|
||||
|
||||
```pug
|
||||
page(path="/admin/relays/:id/edit", auth="required", role="admin", shell="app")
|
||||
back_link(href="/admin/relays/:id", label="Back")
|
||||
header
|
||||
title Edit Relay (Admin)
|
||||
|
||||
loading_state(message="Loading relay...")
|
||||
error_state(message="Failed to load relay.")
|
||||
|
||||
form(action="admin_update_relay")
|
||||
field(name="name", label="Relay Name", required=true)
|
||||
field(name="subdomain", label="Subdomain", required=true)
|
||||
field(name="icon", label="Icon URL", type="url")
|
||||
field(name="description", label="Description", type="textarea")
|
||||
submit_button(default="Save Changes", loading="Saving...")
|
||||
error_message(on="submit_failure")
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
# Admin Relay List
|
||||
|
||||
The admin relay list page shows all relays with search for operators.
|
||||
|
||||
```pug
|
||||
page(path="/admin/relays", auth="required", role="admin", shell="app")
|
||||
header
|
||||
title Relays
|
||||
|
||||
controls
|
||||
input(type="search", name="query", placeholder="Search relays...")
|
||||
|
||||
loading_state(message="Loading relays...")
|
||||
error_state(message="Failed to load relays.")
|
||||
|
||||
list(empty="No relays found")
|
||||
item(link="/admin/relays/:id")
|
||||
title relay.info_name || relay.subdomain
|
||||
subtitle {relay.subdomain}.spaces.coracle.social
|
||||
tenant relay.tenant
|
||||
status relay.status
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
# Admin Tenant Detail
|
||||
|
||||
The admin tenant detail page shows tenant status and all relays for a selected tenant.
|
||||
|
||||
```pug
|
||||
page(path="/admin/tenants/:id", auth="required", role="admin", shell="app")
|
||||
back_link(href="/admin/tenants", label="Tenants")
|
||||
header
|
||||
title Tenant :id
|
||||
|
||||
loading_state(message="Loading tenant...")
|
||||
error_state(message="Failed to load tenant.")
|
||||
|
||||
section(id="status")
|
||||
heading Status
|
||||
text Current: tenant
|
||||
|
||||
section(id="relays")
|
||||
heading Relays
|
||||
list(empty="No relays")
|
||||
item(link="/admin/relays/:id")
|
||||
title relay.info_name || relay.subdomain
|
||||
subtitle {relay.subdomain}.spaces.coracle.social
|
||||
status relay.status
|
||||
```
|
||||
@@ -0,0 +1,23 @@
|
||||
# Admin Tenant List
|
||||
|
||||
The admin tenant list page shows all tenants with profile-enriched search results.
|
||||
|
||||
```pug
|
||||
page(path="/admin/tenants", auth="required", role="admin", shell="app")
|
||||
header
|
||||
title Tenants
|
||||
|
||||
controls
|
||||
input(type="search", name="query", placeholder="Search tenants...")
|
||||
|
||||
loading_state(message="Loading tenants...")
|
||||
error_state(message="Failed to load tenants.")
|
||||
|
||||
list(empty="No tenants found")
|
||||
item(link="/admin/tenants/:pubkey")
|
||||
avatar(profile.picture)
|
||||
title profile.name || shortened_pubkey
|
||||
subtitle profile.about || "No profile bio"
|
||||
meta tenant.pubkey
|
||||
badge tenant
|
||||
```
|
||||
@@ -0,0 +1,86 @@
|
||||
# Home
|
||||
|
||||
The home page is a marketing page with CTAs to create a relay or log in (if the user isn't logged in). If the user is logged in, "Sign in" actions are replaced with "Dashboard" and route to `/relays`.
|
||||
|
||||
```pug
|
||||
page(path="/")
|
||||
nav(sticky=true)
|
||||
brand(name="Caravel", logo="/caravel.png")
|
||||
if(authenticated)
|
||||
link(href="/relays") Dashboard
|
||||
else
|
||||
link(href="/login") Sign in
|
||||
|
||||
section(id="hero")
|
||||
badge Nostr-native relay hosting
|
||||
hero
|
||||
title Your community, your relay.
|
||||
description Spin up private, managed infrastructure for your community in minutes. Full control over membership, access, and policies — no DevOps required.
|
||||
actions
|
||||
button(variant="primary", href="/relays/new") Get started free
|
||||
if(authenticated)
|
||||
button(variant="neutral", href="/relays") Dashboard
|
||||
else
|
||||
button(variant="neutral", href="/login") Sign in
|
||||
|
||||
section(id="features")
|
||||
heading
|
||||
title Everything you need
|
||||
description Caravel takes care of the infrastructure so you can focus on building your community.
|
||||
grid(columns=3)
|
||||
card(icon="hosting")
|
||||
title Managed hosting
|
||||
description We handle uptime, backups, and updates. Your relay stays online so your community never misses a beat.
|
||||
card(icon="membership")
|
||||
title Membership control
|
||||
description Approve members with Nostr pubkeys. Keep your space invite-only or open — you decide.
|
||||
card(icon="shield")
|
||||
title Access policies
|
||||
description Fine-grained write and read permissions. Moderate content without touching any server config.
|
||||
card(icon="storage")
|
||||
title Blossom storage
|
||||
description Attach media files to your relay with integrated Blossom server support on paid plans.
|
||||
card(icon="video")
|
||||
title LiveKit video
|
||||
description Built-in video room support via LiveKit. Host voice and video calls directly within your community.
|
||||
card(icon="lightning")
|
||||
title Pay with sats
|
||||
description Lightning-native billing. No credit cards, no bank accounts — just sats, straight from your wallet.
|
||||
|
||||
section(id="connect")
|
||||
heading
|
||||
title Connect with your community
|
||||
description Once your relay is live, these Nostr-native platforms let your members connect, chat, and collaborate — all powered by your relay.
|
||||
grid(columns=2)
|
||||
product(name="Flotilla", href="https://flotilla.social", domain="flotilla.social")
|
||||
description A community platform built on Nostr. Flotilla gives your members channels, threads, and a rich social experience — all connected to your relay.
|
||||
bullets
|
||||
item Nostr-native channels & threads
|
||||
item Works directly with your relay
|
||||
item Open source & self-sovereign
|
||||
product(name="Chachi", href="https://chachi.chat", domain="chachi.chat")
|
||||
description A group chat app built on top of Nostr. Chachi makes it easy for your community to have real-time conversations, all flowing through your own relay.
|
||||
bullets
|
||||
item Real-time group messaging
|
||||
item Bring your own relay
|
||||
item No accounts — just your Nostr key
|
||||
|
||||
section(id="pricing")
|
||||
heading
|
||||
title Simple pricing
|
||||
description Pay in sats. Upgrade or cancel any time.
|
||||
pricing_table(cta_href="/relays/new")
|
||||
|
||||
section(id="cta")
|
||||
heading
|
||||
title Ready to launch your relay?
|
||||
description Join communities already running on Caravel. Set up in minutes, pay in sats.
|
||||
button(variant="primary", href="/relays/new") Create your relay
|
||||
|
||||
footer
|
||||
brand(name="Caravel", logo="/caravel.png")
|
||||
copyright © {currentYear} Caravel. Built on Nostr.
|
||||
links
|
||||
link(href="https://flotilla.social") Flotilla
|
||||
link(href="https://chachi.chat") Chachi
|
||||
```
|
||||
@@ -0,0 +1,67 @@
|
||||
# Login
|
||||
|
||||
The login page authenticates users with Nostr via extension, remote signer (NIP-46), or key material, then redirects to `/relays`.
|
||||
|
||||
```pug
|
||||
page(path="/login")
|
||||
hero
|
||||
badge Secure Nostr Login
|
||||
title Welcome back
|
||||
description Connect your Nostr account to manage relay hosting, billing, and access in one place.
|
||||
bullets
|
||||
item Own your identity with cryptographic sign-in.
|
||||
item No passwords or email required.
|
||||
item Get fast access to your relays.
|
||||
|
||||
auth_card
|
||||
section(id="method_select")
|
||||
title Log in / Sign up
|
||||
description Use any Nostr signer method. New users are automatically onboarded.
|
||||
tabs
|
||||
tab(id="nip07") Extension
|
||||
tab(id="nip46") Signer
|
||||
tab(id="key") Key
|
||||
|
||||
when(tab="nip07")
|
||||
button Continue with extension
|
||||
|
||||
when(tab="nip46")
|
||||
button Continue with signer
|
||||
|
||||
when(tab="key")
|
||||
button Continue with key
|
||||
|
||||
screen(id="nip46")
|
||||
back_button Back
|
||||
title Log in with signer
|
||||
tabs
|
||||
tab(id="qr") Use QR Code
|
||||
tab(id="paste") Paste Link
|
||||
when(tab="qr")
|
||||
qr_code
|
||||
copyable_input(name="nostrconnect_uri")
|
||||
when(tab="paste")
|
||||
input(name="bunker_url", placeholder="bunker://...")
|
||||
button Scan QR code
|
||||
button Connect to Signer
|
||||
|
||||
screen(id="key")
|
||||
back_button Back
|
||||
title Log in with key
|
||||
tabs
|
||||
tab(id="plaintext") Plaintext
|
||||
tab(id="encrypted") Encrypted
|
||||
when(tab="plaintext")
|
||||
input(name="nsec", placeholder="nsec1...")
|
||||
when(tab="encrypted")
|
||||
input(name="ncryptsec", placeholder="ncryptsec1...")
|
||||
input(type="password", name="password", placeholder="Password")
|
||||
button Log in
|
||||
|
||||
error_message
|
||||
|
||||
help_text Having trouble? Make sure your signer is unlocked and connected.
|
||||
modal(id="scanner")
|
||||
title Scan QR Code
|
||||
camera_preview
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
# Relay Detail
|
||||
|
||||
The relay detail page shows relay status and settings for an authenticated tenant, with inline toggles and plan changes.
|
||||
|
||||
```pug
|
||||
page(path="/relays/:id", auth="required", shell="app")
|
||||
back_link(href="/relays", label="Relays")
|
||||
|
||||
loading_state(message="Loading relay...")
|
||||
error_state(message="Failed to load relay.")
|
||||
|
||||
relay_detail_card(edit_href="/relays/:id/edit")
|
||||
actions
|
||||
button(action="deactivate_relay") Deactivate
|
||||
toggles
|
||||
toggle(name="policy_public_join") Public join
|
||||
toggle(name="policy_strip_signatures") Strip signatures
|
||||
toggle(name="groups_enabled") Groups
|
||||
toggle(name="management_enabled") Management API
|
||||
toggle(name="blossom_enabled") Media storage
|
||||
toggle(name="livekit_enabled") LiveKit support
|
||||
toggle(name="push_enabled") Push notifications
|
||||
plan_selector(action="update_plan")
|
||||
member_count(source="relay_url")
|
||||
|
||||
error_message(on="mutation_failure")
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
# Relay Edit
|
||||
|
||||
The relay edit page lets an authenticated tenant update relay metadata and returns to relay detail on success.
|
||||
|
||||
```pug
|
||||
page(path="/relays/:id/edit", auth="required", shell="app")
|
||||
back_link(href="/relays/:id", label="Back")
|
||||
header
|
||||
title Edit Relay
|
||||
|
||||
loading_state(message="Loading relay...")
|
||||
error_state(message="Failed to load relay.")
|
||||
|
||||
form(action="update_tenant_relay")
|
||||
field(name="name", label="Relay Name", required=true)
|
||||
field(name="subdomain", label="Subdomain", required=true)
|
||||
field(name="icon", label="Icon URL", type="url")
|
||||
field(name="description", label="Description", type="textarea")
|
||||
submit_button(default="Save Changes", loading="Saving...")
|
||||
error_message(on="submit_failure")
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
# Relay List
|
||||
|
||||
The relay list page shows an authenticated tenant's relays with search and status filtering.
|
||||
|
||||
```pug
|
||||
page(path="/relays", auth="required", shell="app")
|
||||
header
|
||||
title My Relays
|
||||
button(href="/relays/new") Add Relay
|
||||
|
||||
controls
|
||||
input(type="search", name="query", placeholder="Search by name or subdomain")
|
||||
select(name="status")
|
||||
option(value="all") All statuses
|
||||
option(value="active") Active
|
||||
option(value="pending") Pending
|
||||
option(value="deactivated") Deactivated
|
||||
option(value="provisioning_failed") Provisioning failed
|
||||
option(value="suspended") Suspended
|
||||
|
||||
loading_state(message="Loading relays...")
|
||||
error_state(message="Failed to load relays.")
|
||||
|
||||
list(empty="No relays found")
|
||||
item(link="/relays/:id")
|
||||
title relay.info_name || relay.subdomain
|
||||
subtitle https://{relay.subdomain}.spaces.coracle.social
|
||||
status relay.status
|
||||
```
|
||||
@@ -0,0 +1,32 @@
|
||||
# Relay New
|
||||
|
||||
The new relay page lets an authenticated tenant configure and create a relay, then navigates to its detail page.
|
||||
|
||||
```pug
|
||||
page(path="/relays/new", auth="required", shell="app")
|
||||
header
|
||||
title New Relay
|
||||
|
||||
form(action="create_tenant_relay")
|
||||
field(name="name", label="Relay Name", required=true, placeholder="My Community")
|
||||
field(name="subdomain", label="Subdomain", required=true, suffix=".spaces.coracle.social", placeholder="my-community")
|
||||
field(name="icon", label="Icon URL", type="url", placeholder="https://example.com/icon.png")
|
||||
field(name="description", label="Description", type="textarea", placeholder="A community for...")
|
||||
|
||||
field(name="plan", label="Plan")
|
||||
option(value="free")
|
||||
title Free
|
||||
price Free
|
||||
members Up to 10 members
|
||||
option(value="basic")
|
||||
title Basic
|
||||
price 10,000 sats/mo
|
||||
members Up to 100 members
|
||||
option(value="growth")
|
||||
title Growth
|
||||
price 50,000 sats/mo
|
||||
members Unlimited members
|
||||
|
||||
tooltip_error(field="subdomain")
|
||||
submit_button(default="Create Relay", loading="Creating...")
|
||||
```
|
||||
Reference in New Issue
Block a user