Files
cozsweet-frontend-nextjs/src/app/sidebar/sidebar-screen.tsx
T

180 lines
6.5 KiB
TypeScript

"use client";
import { Download, LogOut, MessageCircleQuestion } from "lucide-react";
import { signOut } from "next-auth/react";
import { BackButton } from "@/app/_components";
import { MobileShell } from "@/app/_components/core";
import {
resolveGlobalRouteContext,
type GlobalReturnToValue,
} from "@/router/global-route-context";
import { useGlobalAppNavigator } from "@/router/use-global-app-navigator";
import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
import { useUserDispatch, useUserState } from "@/stores/user/user-context";
import { SidebarWalletCard, UserHeader } from "./components";
import { getSidebarViewModel } from "./sidebar-view-model";
import { usePwaInstallEntry } from "./use-pwa-install-entry";
import { useSidebarUserBootstrap } from "./use-sidebar-user-bootstrap";
import styles from "./components/sidebar-screen.module.css";
export interface SidebarScreenProps {
returnTo?: GlobalReturnToValue;
}
export function SidebarScreen({ returnTo }: SidebarScreenProps) {
const navigator = useGlobalAppNavigator();
const navigation = resolveGlobalRouteContext(returnTo);
const user = useUserState();
const userDispatch = useUserDispatch();
const auth = useAuthState();
const authDispatch = useAuthDispatch();
const pwaInstallEntry = usePwaInstallEntry();
useSidebarUserBootstrap({ auth, userDispatch });
const handleLogoutClick = () => {
userDispatch({ type: "UserClearLocal" });
authDispatch({ type: "AuthLogoutSubmitted" });
void signOut({ redirect: false });
navigator.replace(navigation.splashUrl, { scroll: false });
};
const view = getSidebarViewModel({
loginStatus: auth.loginStatus,
user,
});
return (
<MobileShell background="#fcf3f4">
<div className={styles.shell}>
<div className={styles.bgOrbOne} aria-hidden="true" />
<div className={styles.bgOrbTwo} aria-hidden="true" />
<div className={styles.topBar}>
<BackButton
href={navigation.chatUrl}
variant="soft"
analyticsKey="sidebar.back_to_chat"
/>
</div>
<section className={`${styles.userSlot} ${styles.revealOne}`}>
<UserHeader
state={view.state}
name={view.name}
avatarUrl={view.avatarUrl}
isLoading={view.isInitializingUser}
onLoginClick={() => navigator.openAuth(navigation.sidebarUrl)}
/>
</section>
<section className={`${styles.cardSlot} ${styles.revealTwo}`}>
<SidebarWalletCard
creditBalance={view.wallet.creditBalance}
dailyFreeChatLimit={view.wallet.dailyFreeChatLimit}
dailyFreeChatRemaining={view.wallet.dailyFreeChatRemaining}
dailyFreePrivateLimit={view.wallet.dailyFreePrivateLimit}
dailyFreePrivateRemaining={view.wallet.dailyFreePrivateRemaining}
onActivateVip={
view.canActivateVip
? () =>
navigator.openSubscription({
type: "vip",
sourceCharacterSlug: navigation.characterSlug,
returnTo: "sidebar",
analytics: {
entryPoint: "sidebar",
triggerReason: "vip_cta",
},
})
: undefined
}
onTopUp={() =>
navigator.openSubscription({
type: "topup",
sourceCharacterSlug: navigation.characterSlug,
returnTo: "sidebar",
analytics: {
entryPoint: "sidebar",
triggerReason: "sidebar_recharge",
},
})
}
onRulesClick={() => navigator.push(navigation.coinsRulesUrl)}
/>
</section>
{view.canShowSettings ? (
<section className={`${styles.settingsSlot} ${styles.revealThree}`}>
<p className={styles.settingsLabel}>Other</p>
<div className={styles.settingsActions}>
<button
type="button"
data-analytics-key="sidebar.open_feedback"
data-analytics-label="Open feedback"
className={`${styles.logoutCard} ${styles.feedbackCard}`}
onClick={() => navigator.push(navigation.feedbackUrl)}
>
<span
className={`${styles.logoutIcon} ${styles.feedbackIcon}`}
aria-hidden="true"
>
<MessageCircleQuestion size={19} strokeWidth={2.2} />
</span>
<span className={styles.logoutText}>
<span className={styles.feedbackTitle}>Feedback</span>
<span className={styles.logoutSubtitle}>
Report a problem or share an idea
</span>
</span>
</button>
{pwaInstallEntry.canInstall ? (
<button
type="button"
className={`${styles.logoutCard} ${styles.installCard}`}
onClick={() => void pwaInstallEntry.installApp()}
>
<span
className={`${styles.logoutIcon} ${styles.installIcon}`}
aria-hidden="true"
>
<Download size={19} strokeWidth={2.2} />
</span>
<span className={styles.logoutText}>
<span className={styles.installTitle}>Install app</span>
<span className={styles.installSubtitle}>
Add CozSweet to your Home Screen
</span>
</span>
</button>
) : null}
<button
type="button"
data-analytics-key="sidebar.logout"
data-analytics-label="Log out"
className={styles.logoutCard}
onClick={handleLogoutClick}
>
<span className={styles.logoutIcon} aria-hidden="true">
<LogOut size={19} strokeWidth={2.2} />
</span>
<span className={styles.logoutText}>
<span className={styles.logoutTitle}>Log out</span>
<span className={styles.logoutSubtitle}>
End the current session safely
</span>
</span>
</button>
</div>
</section>
) : null}
</div>
</MobileShell>
);
}