Refactor: Centralized Supabase Auth and implemented Auth Guards to prevent 401 errors
This commit is contained in:
@@ -12,6 +12,7 @@ import DramOfTheDay from "@/components/DramOfTheDay";
|
||||
import LanguageSwitcher from "@/components/LanguageSwitcher";
|
||||
import OfflineIndicator from "@/components/OfflineIndicator";
|
||||
import { useI18n } from "@/i18n/I18nContext";
|
||||
import { useAuth } from "@/context/AuthContext";
|
||||
import { useSession } from "@/context/SessionContext";
|
||||
import TastingHub from "@/components/TastingHub";
|
||||
import { Sparkles, X, Loader2 } from "lucide-react";
|
||||
@@ -25,8 +26,8 @@ export default function Home() {
|
||||
const supabase = createClient();
|
||||
const router = useRouter();
|
||||
const [bottles, setBottles] = useState<any[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [user, setUser] = useState<any>(null);
|
||||
const { user, isLoading: isAuthLoading } = useAuth();
|
||||
const [isInternalLoading, setIsInternalLoading] = useState(false);
|
||||
const [fetchError, setFetchError] = useState<string | null>(null);
|
||||
const { t } = useI18n();
|
||||
const { activeSession } = useSession();
|
||||
@@ -46,39 +47,15 @@ export default function Home() {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Check session
|
||||
const checkUser = async () => {
|
||||
try {
|
||||
// Proactively get session - this will trigger a refresh if needed
|
||||
const { data: { session }, error } = await supabase.auth.getSession();
|
||||
|
||||
if (session) {
|
||||
console.log('[Auth] Valid session found:', {
|
||||
userId: session.user.id,
|
||||
expiry: new Date(session.expires_at! * 1000).toLocaleString()
|
||||
});
|
||||
} else {
|
||||
console.log('[Auth] No active session found.');
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error('[Auth] Session check error:', error);
|
||||
}
|
||||
|
||||
setUser(session?.user ?? null);
|
||||
if (session?.user) {
|
||||
fetchCollection();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[Auth] Unexpected error during session check:', err);
|
||||
setUser(null);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
checkUser();
|
||||
// Only fetch if auth is ready and user exists
|
||||
if (!isAuthLoading && user) {
|
||||
fetchCollection();
|
||||
} else if (!isAuthLoading && !user) {
|
||||
setBottles([]);
|
||||
}
|
||||
}, [user, isAuthLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch public splits if guest
|
||||
getActiveSplits().then(res => {
|
||||
if (res.success && res.splits) {
|
||||
@@ -86,33 +63,6 @@ export default function Home() {
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for visibility change (wake up from sleep)
|
||||
const handleVisibilityChange = () => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
console.log('[Auth] App became visible, refreshing session...');
|
||||
checkUser();
|
||||
}
|
||||
};
|
||||
document.addEventListener('visibilitychange', handleVisibilityChange);
|
||||
|
||||
// Listen for auth changes
|
||||
const { data: { subscription } } = supabase.auth.onAuthStateChange((event: string, session: any) => {
|
||||
console.log('[Auth] State change event:', event, {
|
||||
hasSession: !!session,
|
||||
userId: session?.user?.id,
|
||||
email: session?.user?.email
|
||||
});
|
||||
|
||||
setUser(session?.user ?? null);
|
||||
if (session?.user) {
|
||||
if (event === 'SIGNED_IN' || event === 'INITIAL_SESSION' || event === 'TOKEN_REFRESHED') {
|
||||
fetchCollection();
|
||||
}
|
||||
} else {
|
||||
setBottles([]);
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for collection updates (e.g., after offline sync completes)
|
||||
const handleCollectionUpdated = () => {
|
||||
console.log('[Home] Collection update event received, refreshing...');
|
||||
@@ -121,14 +71,12 @@ export default function Home() {
|
||||
window.addEventListener('collection-updated', handleCollectionUpdated);
|
||||
|
||||
return () => {
|
||||
subscription.unsubscribe();
|
||||
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
||||
window.removeEventListener('collection-updated', handleCollectionUpdated);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const fetchCollection = async () => {
|
||||
setIsLoading(true);
|
||||
setIsInternalLoading(true);
|
||||
try {
|
||||
// Fetch bottles with their latest tasting date
|
||||
const { data, error } = await supabase
|
||||
@@ -194,7 +142,7 @@ export default function Home() {
|
||||
setFetchError(errorMessage);
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
setIsInternalLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -249,6 +197,8 @@ export default function Home() {
|
||||
);
|
||||
}
|
||||
|
||||
const isLoading = isAuthLoading || isInternalLoading;
|
||||
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center gap-6 md:gap-12 p-4 md:p-24 bg-[var(--background)] pb-32">
|
||||
<div className="z-10 max-w-5xl w-full flex flex-col items-center gap-12">
|
||||
|
||||
Reference in New Issue
Block a user