Add WhatsApp feature flag and improve onboarding
Build and Push Docker Image / build (push) Failing after 2m59s
Details
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:
parent
4f0531d2ee
commit
41a36f72b3
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue