Fix first-login error, awards performance, filter animation, cache invalidation, and query fixes
- Guard onboarding tRPC queries with session hydration check (fixes UNAUTHORIZED on first login) - Defer expensive queries on awards page until UI elements are opened (dialog/tab) - Fix perPage: 500 exceeding backend Zod max of 100 on awards eligibility query - Add smooth open/close animation to project filters collapsible bar - Fix seeded user status from ACTIVE to INVITED in seed-candidatures.ts - Add router.refresh() cache invalidation across ~22 admin forms - Fix geographic analytics query to use programId instead of round.programId - Fix dashboard queries to scope by programId correctly - Fix project.listPool and round queries for projects outside round context - Add rounds page useEffect for state sync after mutations Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState, useMemo, useEffect } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { trpc } from '@/lib/trpc/client'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
@@ -45,6 +46,8 @@ type Step = 'name' | 'photo' | 'country' | 'bio' | 'phone' | 'tags' | 'preferenc
|
||||
|
||||
export default function OnboardingPage() {
|
||||
const router = useRouter()
|
||||
const { data: session, status: sessionStatus } = useSession()
|
||||
const isAuthenticated = sessionStatus === 'authenticated'
|
||||
const [step, setStep] = useState<Step>('name')
|
||||
const [initialized, setInitialized] = useState(false)
|
||||
|
||||
@@ -59,9 +62,15 @@ export default function OnboardingPage() {
|
||||
'EMAIL' | 'WHATSAPP' | 'BOTH' | 'NONE'
|
||||
>('EMAIL')
|
||||
|
||||
// Fetch current user data to get admin-preset tags
|
||||
const { data: userData, isLoading: userLoading, refetch: refetchUser } = trpc.user.me.useQuery()
|
||||
const { data: avatarUrl } = trpc.avatar.getUrl.useQuery()
|
||||
// Fetch current user data only after session is hydrated
|
||||
const { data: userData, isLoading: userLoading, refetch: refetchUser } = trpc.user.me.useQuery(
|
||||
undefined,
|
||||
{ enabled: isAuthenticated }
|
||||
)
|
||||
const { data: avatarUrl } = trpc.avatar.getUrl.useQuery(
|
||||
undefined,
|
||||
{ enabled: isAuthenticated }
|
||||
)
|
||||
|
||||
// Initialize form with user data
|
||||
useEffect(() => {
|
||||
@@ -95,11 +104,17 @@ export default function OnboardingPage() {
|
||||
}
|
||||
}, [userData, initialized])
|
||||
|
||||
// Fetch feature flags
|
||||
const { data: featureFlags } = trpc.settings.getFeatureFlags.useQuery()
|
||||
// Fetch feature flags only after session is hydrated
|
||||
const { data: featureFlags } = trpc.settings.getFeatureFlags.useQuery(
|
||||
undefined,
|
||||
{ enabled: isAuthenticated }
|
||||
)
|
||||
const whatsappEnabled = featureFlags?.whatsappEnabled ?? false
|
||||
|
||||
const completeOnboarding = trpc.user.completeOnboarding.useMutation()
|
||||
const utils = trpc.useUtils()
|
||||
const completeOnboarding = trpc.user.completeOnboarding.useMutation({
|
||||
onSuccess: () => utils.user.me.invalidate(),
|
||||
})
|
||||
|
||||
// Dynamic steps based on WhatsApp availability
|
||||
const steps: Step[] = useMemo(() => {
|
||||
@@ -162,8 +177,8 @@ export default function OnboardingPage() {
|
||||
}
|
||||
}
|
||||
|
||||
// Show loading while fetching user data
|
||||
if (userLoading || !initialized) {
|
||||
// Show loading while session hydrates or fetching user data
|
||||
if (sessionStatus === 'loading' || userLoading || !initialized) {
|
||||
return (
|
||||
<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 shadow-2xl">
|
||||
|
||||
Reference in New Issue
Block a user