diff --git a/.dev.vars.example b/.dev.vars.example index e90c614..96aeab1 100644 --- a/.dev.vars.example +++ b/.dev.vars.example @@ -12,3 +12,12 @@ REGISTRY_API_URL=https://registry-indexer.fly.dev # The Stellar network this instance targets. Used to label the UI. # Options: testnet | mainnet REGISTRY_NETWORK=testnet + +# The following are for Tansu workarounds. Tansu's UI does not currently allow +# creating the governance proposals needed by Stellar Registry. We are creating +# these via CLI calls on our server, and making simple HTML forms on rgstry.xyz +# that make it easy for community members to hit the server endpoints that +# create those Tansu proposals. +TANSU_ID=CBXKUSLQPVF35FYURR5C42BPYA5UOVDXX2ELKIM2CAJMCI6HXG2BHGZA +REGISTRY_ID=CAF2CLQM5X7SRVHJB2WS5IK33D4CQFFZYCFKDYLR2SCQASFPM3YN7EW7 +MANAGER_ID=CAL4PZO2QDY2ELLLY6I2BUTOOZ4ZNSMZA77L3QOZKQN2XKV3Q6LR2VGI diff --git a/app/components/governance-form.module.css b/app/components/governance-form.module.css new file mode 100644 index 0000000..1c1d86c --- /dev/null +++ b/app/components/governance-form.module.css @@ -0,0 +1,45 @@ +.page { + max-width: 40rem; + margin: 0 auto; + padding: 2.5rem 1.5rem 4rem; +} + +.form { + display: flex; + flex-direction: column; +} + +.fields { + display: flex; + flex-direction: column; + gap: 1.25rem; +} + +.field { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.required { + color: var(--color-destructive); +} + +.error { + font-size: 0.8125rem; + color: var(--color-destructive); + margin: 0; +} + +.successSummary { + font-size: 0.9375rem; + line-height: 1.6; + color: var(--color-foreground); + margin: 0 0 0.75rem; +} + +.successTracking { + font-size: 0.875rem; + color: var(--color-muted-foreground); + margin: 0; +} diff --git a/app/components/governance-form.tsx b/app/components/governance-form.tsx new file mode 100644 index 0000000..1645ac9 --- /dev/null +++ b/app/components/governance-form.tsx @@ -0,0 +1,108 @@ +import { Form, useNavigation } from "react-router" +import { Button } from "./button" +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "./card" +import styles from "./governance-form.module.css" +import { Input } from "./input" +import { Label } from "./label" +import { Textarea } from "./textarea" +import { + type GovernanceActionData, + type GovernanceOperation, +} from "~/lib/governance" + +function GovernanceForm({ + operation, + actionData, +}: { + operation: GovernanceOperation + actionData: GovernanceActionData | undefined +}) { + const navigation = useNavigation() + const isSubmitting = navigation.state === "submitting" + + if (actionData?.ok) { + return ( +
+ + + Proposal captured + + This is a mock submission — nothing was actually sent anywhere + yet. + + + +

{actionData.result.summary}

+

+ Mock tracking id: {actionData.result.trackingId} +

+
+
+
+ ) + } + + const errors = actionData?.ok === false ? actionData.errors : undefined + + return ( +
+
+ + + {operation.title} + {operation.description} + + + {operation.fields.map((field) => { + const errorMessage = errors?.[field.name] + const fieldId = `${operation.id}-${field.name}` + return ( +
+ + {field.type === "textarea" ? ( +