feat(public_page): allow unauthenticated browsing with auth-gated interactivity
- Add get_optional_user dependency; dashboard returns guest-safe payload - AuthGuard only redirects /following and /notifications for guests - Sidebar hides auth-required nav items and shows Sign In/Register for guests - Dashboard shows trending bills as "Most Popular" for unauthenticated visitors - FollowButton opens AuthModal instead of acting when not signed in - Members page pins followed members at the top for quick unfollowing - useFollows skips API call and invalidates dashboard on follow/unfollow Authored-By: Jack Levy
This commit is contained in:
@@ -6,7 +6,8 @@ import { useAuthStore } from "@/stores/authStore";
|
||||
import { Sidebar } from "./Sidebar";
|
||||
import { MobileHeader } from "./MobileHeader";
|
||||
|
||||
const PUBLIC_PATHS = ["/login", "/register"];
|
||||
const NO_SHELL_PATHS = ["/login", "/register"];
|
||||
const AUTH_REQUIRED = ["/following", "/notifications"];
|
||||
|
||||
export function AuthGuard({ children }: { children: React.ReactNode }) {
|
||||
const router = useRouter();
|
||||
@@ -22,22 +23,24 @@ export function AuthGuard({ children }: { children: React.ReactNode }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (!hydrated) return;
|
||||
if (!token && !PUBLIC_PATHS.includes(pathname)) {
|
||||
const needsAuth = AUTH_REQUIRED.some((p) => pathname.startsWith(p));
|
||||
if (!token && needsAuth) {
|
||||
router.replace("/login");
|
||||
}
|
||||
}, [hydrated, token, pathname, router]);
|
||||
|
||||
if (!hydrated) return null;
|
||||
|
||||
// Public pages (login/register) render without the app shell
|
||||
if (PUBLIC_PATHS.includes(pathname)) {
|
||||
// Login/register pages render without the app shell
|
||||
if (NO_SHELL_PATHS.includes(pathname)) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
// Not logged in yet — blank while redirecting
|
||||
if (!token) return null;
|
||||
// Auth-required pages: blank while redirecting
|
||||
const needsAuth = AUTH_REQUIRED.some((p) => pathname.startsWith(p));
|
||||
if (!token && needsAuth) return null;
|
||||
|
||||
// Authenticated: render the full app shell
|
||||
// Authenticated or guest browsing: render the full app shell
|
||||
return (
|
||||
<div className="flex h-screen bg-background">
|
||||
{/* Desktop sidebar — hidden on mobile */}
|
||||
|
||||
Reference in New Issue
Block a user