Add WhatsApp feature flag and improve onboarding
Build and Push Docker Image / build (push) Failing after 2m59s Details

- Add getFeatureFlags endpoint to check if WhatsApp is enabled
- Skip phone step in onboarding when WhatsApp is disabled
- Hide WhatsApp notification options when disabled
- Add ExpertiseSelect component with predefined ocean conservation tags
- Fix onboarding layout to fill viewport on desktop

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Matt 2026-02-04 00:58:22 +01:00
parent 4f0531d2ee
commit 41a36f72b3
2 changed files with 48 additions and 15 deletions

View File

@ -1,6 +1,6 @@
'use client' 'use client'
import { useState } from 'react' import { useState, useMemo } from 'react'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import { trpc } from '@/lib/trpc/client' import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
@ -48,10 +48,23 @@ export default function OnboardingPage() {
'EMAIL' | 'WHATSAPP' | 'BOTH' | 'NONE' 'EMAIL' | 'WHATSAPP' | 'BOTH' | 'NONE'
>('EMAIL') >('EMAIL')
// Fetch feature flags
const { data: featureFlags } = trpc.settings.getFeatureFlags.useQuery()
const whatsappEnabled = featureFlags?.whatsappEnabled ?? false
const completeOnboarding = trpc.user.completeOnboarding.useMutation() const completeOnboarding = trpc.user.completeOnboarding.useMutation()
const steps: Step[] = ['name', 'phone', 'tags', 'preferences', 'complete'] // Dynamic steps based on WhatsApp availability
const steps: Step[] = useMemo(() => {
if (whatsappEnabled) {
return ['name', 'phone', 'tags', 'preferences', 'complete']
}
// Skip phone step if WhatsApp is disabled
return ['name', 'tags', 'preferences', 'complete']
}, [whatsappEnabled])
const currentIndex = steps.indexOf(step) const currentIndex = steps.indexOf(step)
const totalVisibleSteps = steps.length - 1 // Exclude 'complete' from count
const goNext = () => { const goNext = () => {
if (step === 'name' && !name.trim()) { if (step === 'name' && !name.trim()) {
@ -92,8 +105,8 @@ export default function OnboardingPage() {
} }
return ( return (
<div className="min-h-screen flex items-center justify-center p-4 bg-gradient-to-br from-[#053d57] to-[#557f8c]"> <div className="absolute inset-0 -m-4 flex items-center justify-center p-4 md:p-8 bg-gradient-to-br from-[#053d57] to-[#557f8c]">
<Card className="w-full max-w-lg"> <Card className="w-full max-w-lg max-h-[85vh] overflow-y-auto shadow-2xl">
{/* Progress indicator */} {/* Progress indicator */}
<div className="px-6 pt-6"> <div className="px-6 pt-6">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -112,7 +125,7 @@ export default function OnboardingPage() {
))} ))}
</div> </div>
<p className="text-sm text-muted-foreground mt-2"> <p className="text-sm text-muted-foreground mt-2">
Step {currentIndex + 1} of {steps.length - 1} Step {currentIndex + 1} of {totalVisibleSteps}
</p> </p>
</div> </div>
@ -148,8 +161,8 @@ export default function OnboardingPage() {
</> </>
)} )}
{/* Step 2: Phone */} {/* Step 2: Phone (only if WhatsApp enabled) */}
{step === 'phone' && ( {step === 'phone' && whatsappEnabled && (
<> <>
<CardHeader> <CardHeader>
<CardTitle className="flex items-center gap-2"> <CardTitle className="flex items-center gap-2">
@ -248,16 +261,20 @@ export default function OnboardingPage() {
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="EMAIL">Email only</SelectItem> <SelectItem value="EMAIL">Email only</SelectItem>
<SelectItem value="WHATSAPP" disabled={!phoneNumber}> {whatsappEnabled && (
WhatsApp only <>
</SelectItem> <SelectItem value="WHATSAPP" disabled={!phoneNumber}>
<SelectItem value="BOTH" disabled={!phoneNumber}> WhatsApp only
Both Email and WhatsApp </SelectItem>
</SelectItem> <SelectItem value="BOTH" disabled={!phoneNumber}>
Both Email and WhatsApp
</SelectItem>
</>
)}
<SelectItem value="NONE">No notifications</SelectItem> <SelectItem value="NONE">No notifications</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
{!phoneNumber && ( {whatsappEnabled && !phoneNumber && (
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
Add a phone number to enable WhatsApp notifications Add a phone number to enable WhatsApp notifications
</p> </p>
@ -270,7 +287,7 @@ export default function OnboardingPage() {
<p> <p>
<span className="text-muted-foreground">Name:</span> {name} <span className="text-muted-foreground">Name:</span> {name}
</p> </p>
{phoneNumber && ( {whatsappEnabled && phoneNumber && (
<p> <p>
<span className="text-muted-foreground">Phone:</span>{' '} <span className="text-muted-foreground">Phone:</span>{' '}
{phoneNumber} {phoneNumber}

View File

@ -19,6 +19,22 @@ function categorizeModel(modelId: string): string {
} }
export const settingsRouter = router({ export const settingsRouter = router({
/**
* Get public feature flags (no auth required)
* These are non-sensitive settings that can be exposed to any user
*/
getFeatureFlags: protectedProcedure.query(async ({ ctx }) => {
const [whatsappEnabled] = await Promise.all([
ctx.prisma.systemSettings.findUnique({
where: { key: 'whatsapp_enabled' },
}),
])
return {
whatsappEnabled: whatsappEnabled?.value === 'true',
}
}),
/** /**
* Get all settings by category * Get all settings by category
*/ */