Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified bun.lockb
Binary file not shown.
11 changes: 5 additions & 6 deletions src/Shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@ import { useMediaQuery } from "@uidotdev/usehooks";
import Header from "./components/Header";
import { Tag } from "./components/Tag";
import Feed from "./components/Feed/Feed";
import { useAtom } from "jotai";
import { loginTokenAtom } from "./atoms";
import { useWSQuery } from "./hooks";

const drawerWidth = 256;
const drawerWidthWithPadding = drawerWidth;

const Shell: React.FC<PropsWithChildren> = ({ children }) => {
const [isOpen, setIsOpen] = useState(false);
const drawerRef = useRef<HTMLDivElement>(null);
const [loginToken] = useAtom(loginTokenAtom);
const { data: username } = useWSQuery("user.getSelf", null);

const x = isOpen ? 0 : -drawerWidthWithPadding;
const width = isOpen ? drawerWidthWithPadding : 0;
Expand Down Expand Up @@ -82,7 +81,7 @@ const Shell: React.FC<PropsWithChildren> = ({ children }) => {
<Play />
Play
</NavLink>
{loginToken && (
{username && (
<NavLink href="/history">
<History />
History
Expand All @@ -92,13 +91,13 @@ const Shell: React.FC<PropsWithChildren> = ({ children }) => {
<Store />
Store
</NavLink>
{loginToken && (
{username && (
<NavLink href="/collection">
<Library />
Collection <Tag size="sm">NEW</Tag>
</NavLink>
)}
{loginToken && (
{username && (
<NavLink href="/settings">
<Settings />
Settings
Expand Down
4 changes: 2 additions & 2 deletions src/components/Auth/RegisterButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useQueryClient } from "@tanstack/react-query";
import PasswordInput from "./PasswordInput";
import { wsClient } from "../../wsClient";

const RegisterButton = () => {
const RegisterButton = ({ label }: { label?: string }) => {
const [isOpen, setIsOpen] = useState(false);
const [isLoginMode, setIsLoginMode] = useState(false);
const [username, setUsername] = useState("");
Expand All @@ -36,7 +36,7 @@ const RegisterButton = () => {
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogTrigger asChild>
<Button variant="primary" className="self-start">
Register
{label ?? "Register"}
</Button>
</DialogTrigger>
<DialogContent>
Expand Down
40 changes: 36 additions & 4 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,49 @@ import Collection from "./views/collection/Collection.tsx";
import { AnimatePresence } from "motion/react";
import Store from "./views/store/Store.tsx";
import Profile from "./views/profile/Profile.tsx";
import { useWSQuery } from "./hooks.ts";
import RegisterButton from "./components/Auth/RegisterButton.tsx";

const ProtectedRoute: React.FC<{
component: React.ComponentType<any>;
path: string;
}> = ({ component: Component, path }) => {
const { data: username, isLoading } = useWSQuery("user.getSelf", null);

return (
<Route path={path}>
{(params) => {
if (isLoading) return null;
if (!username) {
return (
<div className="flex flex-col items-center justify-center py-24 gap-6">
<h2 className="text-white/90 text-2xl font-bold">
This page is only available to logged-in users.
</h2>
<RegisterButton label="Login to access" />
</div>
);
}
return <Component {...params} />;
}}
</Route>
);
};

const setup = async () => {
const token = localStorage.getItem("loginToken");

if (token) {
try {
await wsClient.dispatch("user.loginWithToken", {
const res = await wsClient.dispatch("user.loginWithToken", {
token: JSON.parse(token),
});
if (!res.success) {
localStorage.removeItem("loginToken");
}
} catch (e) {
console.error(e);
localStorage.removeItem("loginToken");
}
}
};
Expand All @@ -41,9 +73,9 @@ setup().then(() => {
<Route path="/play/:gameId?">
{(params) => <Endless gameId={params.gameId} />}
</Route>
<Route path="/history" component={MatchHistory} />
<Route path="/settings" component={Settings} />
<Route path="/collection" component={Collection} />
<ProtectedRoute path="/history" component={MatchHistory} />
<ProtectedRoute path="/settings" component={Settings} />
<ProtectedRoute path="/collection" component={Collection} />
<Route path="/store" component={Store} />
<Route path="/profile/:username?">
{(params) => <Profile username={params.username} />}
Expand Down
7 changes: 3 additions & 4 deletions src/views/endless/Endless.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useWSMutation, useWSQuery } from "../../hooks";
import { useAtom } from "jotai";
import { gameIdAtom, loginTokenAtom } from "../../atoms";
import { gameIdAtom } from "../../atoms";
import { Button } from "../../components/Button";
import LeaderboardButton from "../../components/LeaderboardButton";
import { ShareButton } from "../../components/ShareButton";
Expand All @@ -15,7 +15,6 @@ interface EndlessProps {

const Endless: React.FC<EndlessProps> = (props) => {
const [gameId, setGameId] = useAtom(gameIdAtom);
const [loginToken] = useAtom(loginTokenAtom);
const { data: game } = useWSQuery("game.getGameState", gameId!, !!gameId);
const { data: settings } = useWSQuery("user.getSettings", null);
const { data: currentUsername } = useWSQuery("user.getSelf", null);
Expand Down Expand Up @@ -93,7 +92,7 @@ const Endless: React.FC<EndlessProps> = (props) => {
<div className="w-full grid md:grid-cols-[350px_1fr]">
<div className="flex flex-col md:border-r-white/10 md:border-r-1 gap-8 pr-12">
<h2 className="text-white/90 text-xl">Minesweeper Endless</h2>
{loginToken ? (
{currentUsername ? (
<Button
className="w-fit"
variant="primary"
Expand All @@ -107,7 +106,7 @@ const Endless: React.FC<EndlessProps> = (props) => {
Start Game
</Button>
) : (
<RegisterButton />
<RegisterButton label="Sign in to Play" />
)}
<h2 className="text-white/80 text-lg mt-8">How to play</h2>
<p className="text-white/90">
Expand Down
32 changes: 20 additions & 12 deletions src/views/store/Store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ import { useEffect } from "react";
import { initParticlesEngine, Particles as ParticlesComponent } from "@tsparticles/react";
import { motion } from "motion/react";
import BounceImg from "../../components/BounceImg";
import RegisterButton from "../../components/Auth/RegisterButton";

const Store = () => {
const openLootbox = useWSMutation("user.openLootbox");
const [lootboxResult, setLootboxResult] = useAtom(lootboxResultAtom);
const currentLootbox = lootboxes.find((l) => l.id === lootboxResult?.lootbox);
const { data: username } = useWSQuery("user.getSelf", null);
const { refetch } = useWSQuery("user.getOwnGems", null);

// this should be run only once per application lifetime
Expand Down Expand Up @@ -184,18 +186,24 @@ const Store = () => {
</Dialog>
</div>
<BounceImg src={lootbox.image} className="w-[360px]" />
<Button
variant="outline"
size="default"
className="mx-auto items-center"
onClick={() => {
openLootbox
.mutateAsync({ id: lootbox.id })
.then(() => refetch());
}}
>
Buy for <b>{lootbox.priceText}</b> <GemsIcon />
</Button>
{username ? (
<Button
variant="outline"
size="default"
className="mx-auto items-center"
onClick={() => {
openLootbox
.mutateAsync({ id: lootbox.id })
.then(() => refetch());
}}
>
Buy for <b>{lootbox.priceText}</b> <GemsIcon />
</Button>
) : (
<div className="flex justify-center">
<RegisterButton label="Login to Buy" />
</div>
)}
</div>
))}
</div>
Expand Down
Loading