diff --git a/app/pages/join.vue b/app/pages/join.vue index e1efb0c..80f9cdc 100644 --- a/app/pages/join.vue +++ b/app/pages/join.vue @@ -412,6 +412,86 @@ + + + +
+
+
{{ flowStepLabel }}
+ + + + + + + + + +
+
+
@@ -457,6 +537,14 @@ const errorMessage = ref(""); const successMessage = ref(""); const cadence = ref("monthly"); // 'monthly' | 'annual' +// Flow overlay state — drives the post-submit full-viewport UI. +// 'idle' = overlay hidden; user is editing the form. +// 'creating-customer' | 'opening-payment' | 'processing-payment' +// | 'creating-subscription' = progress states, overlay shows a spinner + label. +// 'success' = overlay shows confirmation, auto-redirect is queued. +// 'error' = overlay shows error + Retry/Back buttons. +const flowState = ref("idle"); + // Helcim state const customerId = ref(null); const customerCode = ref(null); @@ -519,6 +607,23 @@ const selectedTier = computed(() => { return getContributionTierByValue(form.contributionTier); }); +const flowStepLabel = computed(() => { + switch (flowState.value) { + case "creating-customer": + case "opening-payment": + return "Step 2 of 3 — Payment"; + case "processing-payment": + case "creating-subscription": + return "Step 2 of 3 — Finalizing"; + case "success": + return "Step 3 of 3 — Welcome"; + case "error": + return "Something went wrong"; + default: + return ""; + } +}); + // Step 1: Create customer const handleSubmit = async () => { if (isSubmitting.value || !isFormValid.value) return; @@ -678,6 +783,11 @@ const goBack = () => { } }; +const closeFlowOverlay = () => { + flowState.value = "idle"; + errorMessage.value = ""; +}; + // Reset form const resetForm = () => { currentStep.value = 1; @@ -1180,4 +1290,49 @@ onUnmounted(() => { align-items: stretch; } } + +.join-flow-overlay { + position: fixed; + inset: 0; + z-index: 50; + background: rgba(42, 32, 21, 0.72); /* --parch @ 72% */ + backdrop-filter: blur(4px); + display: flex; + align-items: center; + justify-content: center; + padding: 24px; +} + +.join-flow-card { + background: var(--bg); + border: 1px dashed var(--border); + padding: 32px; + max-width: 520px; + width: 100%; + max-height: calc(100vh - 48px); + overflow-y: auto; +} + +.join-flow-step { + font-family: var(--font-body); + font-size: 0.75rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--text-dim); + margin-bottom: 12px; +} + +.join-flow-heading { + font-family: var(--font-display); + font-size: 1.5rem; + color: var(--text-bright); + margin: 0 0 16px; +} + +.join-flow-body { + font-family: var(--font-body); + color: var(--text); + line-height: 1.5; + margin: 0; +}