feat(member): account/profile polish + tier upgrade flow

- Timezone: curated USelectMenu dropdown (app/config/timezones.js), preserves unknown saved values
- Profile save now uses useToast() for success/error; remove inline save banner
- Nav onboarding dot nudged down 1px for optical alignment with lowercase text
- Onboarding: skip a suggestion with POST /api/onboarding/track {skip}; member.onboarding.skipped map; does not affect graduation
- CirclePicker takes :saved-value so 'Current' badge stays until save completes
- PrivacyToggle is binary (USwitch labeled Private); member schema enum reduced to ['members','private']; zod coerces legacy 'public'
- New /member/payment-setup page: HelcimPay $0 verify + update-contribution, wired from account.vue via requiresPaymentSetup redirect
- Helcim portal: NUXT_PUBLIC_HELCIM_PORTAL_URL env + account.vue 'Manage billing in Helcim' link
- Migration script: scripts/migrate-privacy-public-to-members.js
This commit is contained in:
Jennie Robinson Faber 2026-04-14 20:35:37 +01:00
parent 08fc3884da
commit 7292b11c0b
18 changed files with 604 additions and 122 deletions

View file

@ -26,6 +26,12 @@
<div class="ow-progress">
<span class="ow-bar"><span class="ow-bar-fill">{{ barFill }}</span><span class="ow-bar-empty">{{ barEmpty }}</span></span>
{{ completedCount }} of 4 explored
<button
v-if="currentSuggestion.key"
type="button"
class="ow-skip"
@click="handleSkip"
>Skip this</button>
</div>
</template>
@ -62,7 +68,12 @@
</template>
<script setup>
const { goals, isComplete, currentSuggestion, trackGoal, loading } = useOnboarding()
const { goals, isComplete, currentSuggestion, trackGoal, skipSuggestion, loading } = useOnboarding()
const handleSkip = () => {
const key = currentSuggestion.value?.key
if (key) skipSuggestion(key)
}
const completedCount = computed(() => {
const g = goals.value
@ -144,4 +155,22 @@ const barEmpty = computed(() => '-'.repeat((4 - completedCount.value) * 2) + ']'
.ow-bar-empty {
color: rgba(237, 228, 208, 0.2);
}
.ow-skip {
margin-left: auto;
background: none;
border: none;
color: var(--parch-text-dim);
font-family: inherit;
font-size: 11px;
cursor: pointer;
padding: 0;
text-decoration: underline;
text-decoration-style: dashed;
text-underline-offset: 2px;
}
.ow-skip:hover {
color: var(--parch-accent);
}
</style>