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="format-detection" content="telephone=no"/>
|
||||
<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>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
"tailwind-merge": "^2.5.2",
|
||||
"tailwindcss": "^4.0.0-alpha.24",
|
||||
"use-sound": "^4.0.3",
|
||||
"vite-imagetools": "^7.0.4",
|
||||
"wouter": "^3.3.5",
|
||||
"zod": "^3.23.8",
|
||||
"zustand": "^4.5.5"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
User-agent: *
|
||||
Disallow: /
|
||||
|
|
@ -48,11 +48,11 @@ const Shell: React.FC<PropsWithChildren> = ({ children }) => {
|
|||
transition={{ type: "tween" }}
|
||||
>
|
||||
<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">
|
||||
Minesweeper
|
||||
<br />
|
||||
<h2 className="[background:var(--bg-brand)] [-webkit-text-fill-color:transparent] font-black [-webkit-background-clip:text!important] font-mono text-3xl">
|
||||
Business
|
||||
</h1>
|
||||
<br />
|
||||
Minesweeper
|
||||
</h2>
|
||||
<Hr />
|
||||
<NavLink href="/">
|
||||
<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"
|
||||
variant="ghost"
|
||||
onClick={() => setIsOpen((isOpen) => !isOpen)}
|
||||
aria-label="Menu"
|
||||
>
|
||||
<Menu />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ const LoginButton = () => {
|
|||
.then(async (res) => {
|
||||
setToken(res.token);
|
||||
await wsClient.dispatch("user.loginWithToken", {
|
||||
token: JSON.parse(res.token),
|
||||
token: res.token,
|
||||
});
|
||||
queryClient.invalidateQueries();
|
||||
await queryClient.resetQueries();
|
||||
})
|
||||
.catch((e) => {
|
||||
setError(e);
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ const RegisterButton = () => {
|
|||
.then(async (res) => {
|
||||
setToken(res.token);
|
||||
await wsClient.dispatch("user.loginWithToken", {
|
||||
token: JSON.parse(res.token),
|
||||
token: res.token,
|
||||
});
|
||||
queryClient.invalidateQueries();
|
||||
await queryClient.resetQueries();
|
||||
})
|
||||
.catch((e) => {
|
||||
setError(e);
|
||||
|
|
|
|||
|
|
@ -12,13 +12,17 @@ import LoginButton from "./Auth/LoginButton";
|
|||
import { useWSMutation, useWSQuery } from "../hooks";
|
||||
import RegisterButton from "./Auth/RegisterButton";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useAtom } from "jotai";
|
||||
import { loginTokenAtom } from "../atoms";
|
||||
|
||||
const Header = () => {
|
||||
const [, setLocation] = useLocation();
|
||||
const { data: username } = useWSQuery("user.getSelf", null);
|
||||
const queryClient = useQueryClient();
|
||||
const [, setToken] = useAtom(loginTokenAtom);
|
||||
const logout = useWSMutation("user.logout", () => {
|
||||
queryClient.invalidateQueries();
|
||||
setToken(undefined);
|
||||
queryClient.resetQueries();
|
||||
});
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import { useWSQuery } from "../../hooks";
|
|||
import { Tag } from "../../components/Tag";
|
||||
import RegisterButton from "../../components/Auth/RegisterButton";
|
||||
import { Button } from "../../components/Button";
|
||||
import defusing from "../../assets/illustrations/defusing.png";
|
||||
import lootbox1 from "../../assets/illustrations/lootbox1.png";
|
||||
import mine from "../../assets/illustrations/mine.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?aspect=1:1&w=100;200;300;400&format=webp&quality=100&as=metadata";
|
||||
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 Hr from "../../components/Hr";
|
||||
import { Link } from "wouter";
|
||||
|
|
|
|||
|
|
@ -5,17 +5,30 @@ import {
|
|||
useScroll,
|
||||
useTransform,
|
||||
} from "framer-motion";
|
||||
import { useRef } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { cn } from "../../lib/utils";
|
||||
|
||||
interface SectionProps {
|
||||
text: string;
|
||||
image: string;
|
||||
image: OutputMetadata[];
|
||||
left?: boolean;
|
||||
}
|
||||
|
||||
const Section = ({ text, image, left }: SectionProps) => {
|
||||
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({
|
||||
target: ref,
|
||||
});
|
||||
|
|
@ -44,18 +57,29 @@ const Section = ({ text, image, left }: SectionProps) => {
|
|||
ease: "easeInOut",
|
||||
}}
|
||||
>
|
||||
<motion.img
|
||||
ref={ref}
|
||||
<div
|
||||
ref={wrapperRef}
|
||||
style={{
|
||||
translateY,
|
||||
aspectRatio: `${image[0].width / image[0].height}`,
|
||||
}}
|
||||
transition={{
|
||||
type: "just",
|
||||
delay: 0.5,
|
||||
}}
|
||||
src={image}
|
||||
className="h-[80%]"
|
||||
/>
|
||||
className="h-[80%] min-h-36"
|
||||
>
|
||||
<motion.img
|
||||
alt=""
|
||||
ref={ref}
|
||||
style={{
|
||||
translateY,
|
||||
}}
|
||||
transition={{
|
||||
type: "just",
|
||||
delay: 0.5,
|
||||
}}
|
||||
srcSet={image.map((i) => `${i.src} ${i.width}w`).join(", ")}
|
||||
sizes={`${width}px`}
|
||||
loading="lazy"
|
||||
className="h-[80%]"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1 +1,27 @@
|
|||
/// <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 react from "@vitejs/plugin-react-swc";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import { imagetools } from "vite-imagetools";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react(), tailwindcss()],
|
||||
plugins: [react(), tailwindcss(), imagetools()],
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue