avatar to main merge

I have completed the character creation screen on the avatar branch and am preparing to merge it into main.
This commit is contained in:
pricewowen
2026-05-23 23:24:36 -06:00
parent 8957ecb81d
commit 61f98866e8
39 changed files with 2361 additions and 436 deletions

View File

@@ -3,6 +3,8 @@
import { useEffect, useState } from "react";
import { AppNav } from "@/components/layout/app-nav";
import { HABIT_PET_DATA_UPDATED_EVENT } from "@/lib/app-events";
import { getOnboardingStatusClient } from "@/lib/onboarding-status";
import { createClient } from "@/lib/supabase/client";
export function GlobalBottomNav() {
@@ -16,9 +18,13 @@ export function GlobalBottomNav() {
data: { user },
} = await supabase.auth.getUser();
setShowNav(
!!user && user.user_metadata?.onboarding_completed === true,
);
if (!user) {
setShowNav(false);
return;
}
const status = await getOnboardingStatusClient();
setShowNav(status?.appComplete === true);
}
void syncNavState();
@@ -29,7 +35,12 @@ export function GlobalBottomNav() {
void syncNavState();
});
return () => subscription.unsubscribe();
window.addEventListener(HABIT_PET_DATA_UPDATED_EVENT, syncNavState);
return () => {
subscription.unsubscribe();
window.removeEventListener(HABIT_PET_DATA_UPDATED_EVENT, syncNavState);
};
}, []);
if (!showNav) {

View File

@@ -1,18 +1,12 @@
import { redirect } from "next/navigation";
import {
getSessionUser,
hasCompletedOnboarding,
} from "@/lib/auth-helpers";
import { routes } from "@/lib/routes";
import { getOnboardingRedirectPath, getSessionUser } from "@/lib/auth-helpers";
export async function LoggedInRedirect() {
const user = await getSessionUser();
if (user) {
redirect(
hasCompletedOnboarding(user) ? routes.avatar : routes.onboardingQuiz,
);
redirect(await getOnboardingRedirectPath());
}
return null;

View File

@@ -1,10 +1,9 @@
import { redirect } from "next/navigation";
import {
hasCompletedOnboarding,
requireSessionUser,
} from "@/lib/auth-helpers";
import { requireSessionUser } from "@/lib/auth-helpers";
import { fetchOnboardingStatusForUser } from "@/lib/onboarding-status";
import { routes } from "@/lib/routes";
import { createClient } from "@/lib/supabase/server";
type OnboardingAuthGateProps = {
children: React.ReactNode;
@@ -12,8 +11,10 @@ type OnboardingAuthGateProps = {
export async function OnboardingAuthGate({ children }: OnboardingAuthGateProps) {
const user = await requireSessionUser();
const supabase = await createClient();
const status = await fetchOnboardingStatusForUser(user.id, supabase);
if (hasCompletedOnboarding(user)) {
if (status.appComplete) {
redirect(routes.avatar);
}

View File

@@ -0,0 +1,30 @@
import { redirect } from "next/navigation";
import { requireSessionUser } from "@/lib/auth-helpers";
import {
fetchOnboardingStatusForUser,
} from "@/lib/onboarding-status";
import { routes } from "@/lib/routes";
import { createClient } from "@/lib/supabase/server";
type OnboardingCustomizeAuthGateProps = {
children: React.ReactNode;
};
export async function OnboardingCustomizeAuthGate({
children,
}: OnboardingCustomizeAuthGateProps) {
const user = await requireSessionUser();
const supabase = await createClient();
const status = await fetchOnboardingStatusForUser(user.id, supabase);
if (status.appComplete) {
redirect(routes.avatar);
}
if (!status.quizComplete) {
redirect(routes.onboardingQuiz);
}
return children;
}

View File

@@ -0,0 +1,26 @@
import { redirect } from "next/navigation";
import { requireSessionUser } from "@/lib/auth-helpers";
import {
fetchOnboardingStatusForUser,
getRedirectPathFromStatus,
} from "@/lib/onboarding-status";
import { createClient } from "@/lib/supabase/server";
type OnboardingQuizAuthGateProps = {
children: React.ReactNode;
};
export async function OnboardingQuizAuthGate({
children,
}: OnboardingQuizAuthGateProps) {
const user = await requireSessionUser();
const supabase = await createClient();
const status = await fetchOnboardingStatusForUser(user.id, supabase);
if (status.quizComplete) {
redirect(getRedirectPathFromStatus(status));
}
return children;
}