feat: Sniffies-style map+profiles, guest age-verify without ID, limited access
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect, createContext, useContext, useCallback } from "react";
|
||||
import { useState, useEffect, createContext, useContext, useCallback, useMemo } from "react";
|
||||
import { AgeGate } from "@/components/AgeGate";
|
||||
import { Nav } from "@/components/Nav";
|
||||
import { MobileHeader } from "@/components/MobileHeader";
|
||||
@@ -8,17 +8,30 @@ import { IdVerificationModal } from "@/components/IdVerificationModal";
|
||||
import { SiteFooter } from "@/components/SiteFooter";
|
||||
import { AuthProvider, useAuth } from "@/lib/auth/context";
|
||||
import {
|
||||
mustBlurExplicit,
|
||||
requiresIdVerification,
|
||||
getUserState,
|
||||
isIdVerified,
|
||||
} from "@/lib/id-verification";
|
||||
import {
|
||||
getAccessCapabilities,
|
||||
shouldBlurExplicit,
|
||||
type AccessCapabilities,
|
||||
} from "@/lib/access-tier";
|
||||
|
||||
const ActiveCountContext = createContext<(n: number) => void>(() => {});
|
||||
const VanillaModeContext = createContext(false);
|
||||
const IdBlurContext = createContext(false);
|
||||
const OpenIdVerificationContext = createContext<() => void>(() => {});
|
||||
|
||||
interface AccessContextValue {
|
||||
capabilities: AccessCapabilities;
|
||||
blurExplicit: boolean;
|
||||
}
|
||||
|
||||
const AccessContext = createContext<AccessContextValue>({
|
||||
capabilities: getAccessCapabilities(false),
|
||||
blurExplicit: true,
|
||||
});
|
||||
|
||||
export function useSetActiveCount() {
|
||||
return useContext(ActiveCountContext);
|
||||
}
|
||||
@@ -27,39 +40,53 @@ export function useVanillaMode() {
|
||||
return useContext(VanillaModeContext);
|
||||
}
|
||||
|
||||
export function useIdBlur() {
|
||||
return useContext(IdBlurContext);
|
||||
}
|
||||
|
||||
export function useOpenIdVerification() {
|
||||
return useContext(OpenIdVerificationContext);
|
||||
}
|
||||
|
||||
export function useAccess() {
|
||||
return useContext(AccessContext);
|
||||
}
|
||||
|
||||
/** @deprecated use useAccess().blurExplicit */
|
||||
export function useIdBlur() {
|
||||
return useContext(AccessContext).blurExplicit;
|
||||
}
|
||||
|
||||
interface ProvidersProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function InnerProviders({ children }: ProvidersProps) {
|
||||
const { profile } = useAuth();
|
||||
const { user, profile } = useAuth();
|
||||
const [vanillaMode, setVanillaMode] = useState(false);
|
||||
const [activeCount, setActiveCount] = useState(0);
|
||||
const [idBlur, setIdBlur] = useState(false);
|
||||
const [idModalOpen, setIdModalOpen] = useState(false);
|
||||
|
||||
const isLoggedIn = !!user;
|
||||
const capabilities = useMemo(
|
||||
() => getAccessCapabilities(isLoggedIn, profile?.id_verified),
|
||||
[isLoggedIn, profile?.id_verified]
|
||||
);
|
||||
const blurExplicit = useMemo(
|
||||
() => shouldBlurExplicit(isLoggedIn, profile?.id_verified) || vanillaMode,
|
||||
[isLoggedIn, profile?.id_verified, vanillaMode]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setVanillaMode(localStorage.getItem("eg_vanilla_mode") === "true");
|
||||
setIdBlur(mustBlurExplicit(profile?.id_verified));
|
||||
|
||||
const state = getUserState();
|
||||
if (
|
||||
isLoggedIn &&
|
||||
requiresIdVerification(state) &&
|
||||
!isIdVerified(profile?.id_verified) &&
|
||||
localStorage.getItem("eg_id_verification_prompted") !== "true"
|
||||
) {
|
||||
const timer = setTimeout(() => setIdModalOpen(true), 1500);
|
||||
const timer = setTimeout(() => setIdModalOpen(true), 2000);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
}, [profile?.id_verified]);
|
||||
}, [isLoggedIn, profile?.id_verified]);
|
||||
|
||||
const handleVanillaToggle = (v: boolean) => {
|
||||
setVanillaMode(v);
|
||||
@@ -67,7 +94,6 @@ function InnerProviders({ children }: ProvidersProps) {
|
||||
};
|
||||
|
||||
const handleIdVerified = useCallback(() => {
|
||||
setIdBlur(false);
|
||||
localStorage.setItem("eg_id_verification_prompted", "true");
|
||||
}, []);
|
||||
|
||||
@@ -77,36 +103,38 @@ function InnerProviders({ children }: ProvidersProps) {
|
||||
|
||||
return (
|
||||
<VanillaModeContext.Provider value={vanillaMode}>
|
||||
<IdBlurContext.Provider value={idBlur}>
|
||||
<AccessContext.Provider value={{ capabilities, blurExplicit }}>
|
||||
<OpenIdVerificationContext.Provider value={openIdVerification}>
|
||||
<Nav
|
||||
vanillaMode={vanillaMode}
|
||||
onVanillaToggle={handleVanillaToggle}
|
||||
activeCount={activeCount}
|
||||
onIdVerifyClick={openIdVerification}
|
||||
idBlur={idBlur}
|
||||
/>
|
||||
<MobileHeader
|
||||
vanillaMode={vanillaMode}
|
||||
onVanillaToggle={handleVanillaToggle}
|
||||
activeCount={activeCount}
|
||||
/>
|
||||
<main className="md:pt-14 pt-12 pb-16 md:pb-0 min-h-screen min-h-[100dvh] flex flex-col">
|
||||
<ActiveCountContext.Provider value={setActiveCount}>
|
||||
<div className="flex-1 flex flex-col">{children}</div>
|
||||
<SiteFooter />
|
||||
</ActiveCountContext.Provider>
|
||||
</main>
|
||||
<IdVerificationModal
|
||||
open={idModalOpen}
|
||||
onClose={() => {
|
||||
setIdModalOpen(false);
|
||||
localStorage.setItem("eg_id_verification_prompted", "true");
|
||||
}}
|
||||
onVerified={handleIdVerified}
|
||||
/>
|
||||
<Nav
|
||||
vanillaMode={vanillaMode}
|
||||
onVanillaToggle={handleVanillaToggle}
|
||||
activeCount={activeCount}
|
||||
onIdVerifyClick={openIdVerification}
|
||||
idBlur={blurExplicit && isLoggedIn}
|
||||
isGuest={!isLoggedIn}
|
||||
/>
|
||||
<MobileHeader
|
||||
vanillaMode={vanillaMode}
|
||||
onVanillaToggle={handleVanillaToggle}
|
||||
activeCount={activeCount}
|
||||
isGuest={!isLoggedIn}
|
||||
/>
|
||||
<main className="md:pt-14 pt-12 pb-16 md:pb-0 min-h-screen min-h-[100dvh] flex flex-col">
|
||||
<ActiveCountContext.Provider value={setActiveCount}>
|
||||
<div className="flex-1 flex flex-col">{children}</div>
|
||||
<SiteFooter />
|
||||
</ActiveCountContext.Provider>
|
||||
</main>
|
||||
<IdVerificationModal
|
||||
open={idModalOpen}
|
||||
onClose={() => {
|
||||
setIdModalOpen(false);
|
||||
localStorage.setItem("eg_id_verification_prompted", "true");
|
||||
}}
|
||||
onVerified={handleIdVerified}
|
||||
/>
|
||||
</OpenIdVerificationContext.Provider>
|
||||
</IdBlurContext.Provider>
|
||||
</AccessContext.Provider>
|
||||
</VanillaModeContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user