fixed login
This commit is contained in:
parent
99e7325edb
commit
576416e905
|
|
@ -6,6 +6,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="format-detection" content="telephone=no"/>
|
<meta name="format-detection" content="telephone=no"/>
|
||||||
<meta name="darkreader-lock">
|
<meta name="darkreader-lock">
|
||||||
|
<meta name="description" content="Minesweeper Endless is a game where you have to clear the board without getting hit by mines. You can win the game by getting the highest score.">
|
||||||
<title>Minesweeper</title>
|
<title>Minesweeper</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
"tailwind-merge": "^2.5.2",
|
"tailwind-merge": "^2.5.2",
|
||||||
"tailwindcss": "^4.0.0-alpha.24",
|
"tailwindcss": "^4.0.0-alpha.24",
|
||||||
"use-sound": "^4.0.3",
|
"use-sound": "^4.0.3",
|
||||||
|
"vite-imagetools": "^7.0.4",
|
||||||
"wouter": "^3.3.5",
|
"wouter": "^3.3.5",
|
||||||
"zod": "^3.23.8",
|
"zod": "^3.23.8",
|
||||||
"zustand": "^4.5.5"
|
"zustand": "^4.5.5"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
User-agent: *
|
||||||
|
Disallow: /
|
||||||
|
|
@ -48,11 +48,11 @@ const Shell: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
transition={{ type: "tween" }}
|
transition={{ type: "tween" }}
|
||||||
>
|
>
|
||||||
<div className="w-full p-2 flex flex-col gap-6">
|
<div className="w-full p-2 flex flex-col gap-6">
|
||||||
<h1 className="[background:var(--bg-brand)] [-webkit-text-fill-color:transparent] font-black [-webkit-background-clip:text!important] font-mono text-3xl">
|
<h2 className="[background:var(--bg-brand)] [-webkit-text-fill-color:transparent] font-black [-webkit-background-clip:text!important] font-mono text-3xl">
|
||||||
Minesweeper
|
|
||||||
<br />
|
|
||||||
Business
|
Business
|
||||||
</h1>
|
<br />
|
||||||
|
Minesweeper
|
||||||
|
</h2>
|
||||||
<Hr />
|
<Hr />
|
||||||
<NavLink href="/">
|
<NavLink href="/">
|
||||||
<Home />
|
<Home />
|
||||||
|
|
@ -82,6 +82,7 @@ const Shell: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
className="absolute left-4 bg-black border-white/10 border-y-1 border-r-1 rounded-l-none"
|
className="absolute left-4 bg-black border-white/10 border-y-1 border-r-1 rounded-l-none"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={() => setIsOpen((isOpen) => !isOpen)}
|
onClick={() => setIsOpen((isOpen) => !isOpen)}
|
||||||
|
aria-label="Menu"
|
||||||
>
|
>
|
||||||
<Menu />
|
<Menu />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,9 @@ const LoginButton = () => {
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
setToken(res.token);
|
setToken(res.token);
|
||||||
await wsClient.dispatch("user.loginWithToken", {
|
await wsClient.dispatch("user.loginWithToken", {
|
||||||
token: JSON.parse(res.token),
|
token: res.token,
|
||||||
});
|
});
|
||||||
queryClient.invalidateQueries();
|
await queryClient.resetQueries();
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
setError(e);
|
setError(e);
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,9 @@ const RegisterButton = () => {
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
setToken(res.token);
|
setToken(res.token);
|
||||||
await wsClient.dispatch("user.loginWithToken", {
|
await wsClient.dispatch("user.loginWithToken", {
|
||||||
token: JSON.parse(res.token),
|
token: res.token,
|
||||||
});
|
});
|
||||||
queryClient.invalidateQueries();
|
await queryClient.resetQueries();
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
setError(e);
|
setError(e);
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,17 @@ import LoginButton from "./Auth/LoginButton";
|
||||||
import { useWSMutation, useWSQuery } from "../hooks";
|
import { useWSMutation, useWSQuery } from "../hooks";
|
||||||
import RegisterButton from "./Auth/RegisterButton";
|
import RegisterButton from "./Auth/RegisterButton";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
import { useAtom } from "jotai";
|
||||||
|
import { loginTokenAtom } from "../atoms";
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
const [, setLocation] = useLocation();
|
const [, setLocation] = useLocation();
|
||||||
const { data: username } = useWSQuery("user.getSelf", null);
|
const { data: username } = useWSQuery("user.getSelf", null);
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
const [, setToken] = useAtom(loginTokenAtom);
|
||||||
const logout = useWSMutation("user.logout", () => {
|
const logout = useWSMutation("user.logout", () => {
|
||||||
queryClient.invalidateQueries();
|
setToken(undefined);
|
||||||
|
queryClient.resetQueries();
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ import { useWSQuery } from "../../hooks";
|
||||||
import { Tag } from "../../components/Tag";
|
import { Tag } from "../../components/Tag";
|
||||||
import RegisterButton from "../../components/Auth/RegisterButton";
|
import RegisterButton from "../../components/Auth/RegisterButton";
|
||||||
import { Button } from "../../components/Button";
|
import { Button } from "../../components/Button";
|
||||||
import defusing from "../../assets/illustrations/defusing.png";
|
import defusing from "../../assets/illustrations/defusing.png?aspect=4:3&w=100;200;300;400&format=webp&quality=100&as=metadata";
|
||||||
import lootbox1 from "../../assets/illustrations/lootbox1.png";
|
import lootbox1 from "../../assets/illustrations/lootbox1.png?aspect=1:1&w=100;200;300;400&format=webp&quality=100&as=metadata";
|
||||||
import mine from "../../assets/illustrations/mine.png";
|
import mine from "../../assets/illustrations/mine.png?aspect=1:1&w=100;200;300;400&format=webp&quality=100&as=metadata";
|
||||||
import Section from "./Section";
|
import Section from "./Section";
|
||||||
import Hr from "../../components/Hr";
|
import Hr from "../../components/Hr";
|
||||||
import { Link } from "wouter";
|
import { Link } from "wouter";
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,30 @@ import {
|
||||||
useScroll,
|
useScroll,
|
||||||
useTransform,
|
useTransform,
|
||||||
} from "framer-motion";
|
} from "framer-motion";
|
||||||
import { useRef } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { cn } from "../../lib/utils";
|
import { cn } from "../../lib/utils";
|
||||||
|
|
||||||
interface SectionProps {
|
interface SectionProps {
|
||||||
text: string;
|
text: string;
|
||||||
image: string;
|
image: OutputMetadata[];
|
||||||
left?: boolean;
|
left?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Section = ({ text, image, left }: SectionProps) => {
|
const Section = ({ text, image, left }: SectionProps) => {
|
||||||
const ref = useRef<HTMLImageElement>(null);
|
const ref = useRef<HTMLImageElement>(null);
|
||||||
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [width, setWidth] = useState(0);
|
||||||
|
useEffect(() => {
|
||||||
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
|
if (wrapperRef.current) {
|
||||||
|
setWidth(wrapperRef.current.clientWidth);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (wrapperRef.current) {
|
||||||
|
resizeObserver.observe(wrapperRef.current);
|
||||||
|
}
|
||||||
|
return () => resizeObserver.disconnect();
|
||||||
|
}, []);
|
||||||
const { scrollYProgress } = useScroll({
|
const { scrollYProgress } = useScroll({
|
||||||
target: ref,
|
target: ref,
|
||||||
});
|
});
|
||||||
|
|
@ -43,8 +56,16 @@ const Section = ({ text, image, left }: SectionProps) => {
|
||||||
duration: 4,
|
duration: 4,
|
||||||
ease: "easeInOut",
|
ease: "easeInOut",
|
||||||
}}
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
ref={wrapperRef}
|
||||||
|
style={{
|
||||||
|
aspectRatio: `${image[0].width / image[0].height}`,
|
||||||
|
}}
|
||||||
|
className="h-[80%] min-h-36"
|
||||||
>
|
>
|
||||||
<motion.img
|
<motion.img
|
||||||
|
alt=""
|
||||||
ref={ref}
|
ref={ref}
|
||||||
style={{
|
style={{
|
||||||
translateY,
|
translateY,
|
||||||
|
|
@ -53,9 +74,12 @@ const Section = ({ text, image, left }: SectionProps) => {
|
||||||
type: "just",
|
type: "just",
|
||||||
delay: 0.5,
|
delay: 0.5,
|
||||||
}}
|
}}
|
||||||
src={image}
|
srcSet={image.map((i) => `${i.src} ${i.width}w`).join(", ")}
|
||||||
|
sizes={`${width}px`}
|
||||||
|
loading="lazy"
|
||||||
className="h-[80%]"
|
className="h-[80%]"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1 +1,27 @@
|
||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
interface OutputMetadata {
|
||||||
|
src: string; // URL of the generated image
|
||||||
|
width: number; // Width of the image
|
||||||
|
height: number; // Height of the image
|
||||||
|
format: string; // Format of the generated image
|
||||||
|
|
||||||
|
// The following options are the same as sharps input options
|
||||||
|
space: string; // Name of colour space interpretation
|
||||||
|
channels: number; // Number of bands e.g. 3 for sRGB, 4 for CMYK
|
||||||
|
density: number; // Number of pixels per inch
|
||||||
|
depth: string; // Name of pixel depth format
|
||||||
|
hasAlpha: boolean; // presence of an alpha transparency channel
|
||||||
|
hasProfile: boolean; // presence of an embedded ICC profile
|
||||||
|
isProgressive: boolean; // indicating whether the image is interlaced using a progressive scan
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "*&as=metadata" {
|
||||||
|
const outputs: OutputMetadata[];
|
||||||
|
export default outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "*?as=metadata" {
|
||||||
|
const outputs: OutputMetadata[];
|
||||||
|
export default outputs;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import react from "@vitejs/plugin-react-swc";
|
import react from "@vitejs/plugin-react-swc";
|
||||||
import tailwindcss from "@tailwindcss/vite";
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
|
import { imagetools } from "vite-imagetools";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), tailwindcss()],
|
plugins: [react(), tailwindcss(), imagetools()],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue