This commit is contained in:
parent
a86dbe5045
commit
d92e5220fd
46
package-lock.json
generated
46
package-lock.json
generated
@ -22,7 +22,8 @@
|
|||||||
"react-country-flag": "^3.1.0",
|
"react-country-flag": "^3.1.0",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"sharp": "^0.32.6",
|
"sharp": "^0.32.6",
|
||||||
"winston": "^3.11.0"
|
"winston": "^3.11.0",
|
||||||
|
"zustand": "^4.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
@ -618,13 +619,13 @@
|
|||||||
"version": "15.7.8",
|
"version": "15.7.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz",
|
||||||
"integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==",
|
"integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.2.29",
|
"version": "18.2.29",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.29.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.29.tgz",
|
||||||
"integrity": "sha512-Z+ZrIRocWtdD70j45izShRwDuiB4JZqDegqMFW/I8aG5DxxLKOzVNoq62UIO82v9bdgi+DO1jvsb9sTEZUSm+Q==",
|
"integrity": "sha512-Z+ZrIRocWtdD70j45izShRwDuiB4JZqDegqMFW/I8aG5DxxLKOzVNoq62UIO82v9bdgi+DO1jvsb9sTEZUSm+Q==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
"@types/scheduler": "*",
|
||||||
@ -644,7 +645,7 @@
|
|||||||
"version": "0.16.4",
|
"version": "0.16.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz",
|
||||||
"integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==",
|
"integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/triple-beam": {
|
"node_modules/@types/triple-beam": {
|
||||||
"version": "1.3.4",
|
"version": "1.3.4",
|
||||||
@ -1558,7 +1559,7 @@
|
|||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
|
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/damerau-levenshtein": {
|
"node_modules/damerau-levenshtein": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
@ -5722,6 +5723,14 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-sync-external-store": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
@ -5962,6 +5971,33 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"zod": "^3.20.2"
|
"zod": "^3.20.2"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/zustand": {
|
||||||
|
"version": "4.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.3.tgz",
|
||||||
|
"integrity": "sha512-oRy+X3ZazZvLfmv6viIaQmtLOMeij1noakIsK/Y47PWYhT8glfXzQ4j0YcP5i0P0qI1A4rIB//SGROGyZhx91A==",
|
||||||
|
"dependencies": {
|
||||||
|
"use-sync-external-store": "1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.7.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": ">=16.8",
|
||||||
|
"immer": ">=9.0",
|
||||||
|
"react": ">=16.8"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"immer": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
"react-country-flag": "^3.1.0",
|
"react-country-flag": "^3.1.0",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"sharp": "^0.32.6",
|
"sharp": "^0.32.6",
|
||||||
"winston": "^3.11.0"
|
"winston": "^3.11.0",
|
||||||
|
"zustand": "^4.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
|
@ -100,10 +100,10 @@ export default function Player({ params }: { params: { id: string } }) {
|
|||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<Container>
|
<Container>
|
||||||
<div className="mt-2 flex w-full flex-row justify-center rounded-sm bg-neutral-800 md:flex-col">
|
<div className="mt-2 flex w-full flex-row justify-center rounded-sm bg-neutral-800 xs:flex-col">
|
||||||
<div className="flex flex-col items-center gap-3 p-3 md:flex-row md:items-start">
|
<div className="flex flex-col items-center gap-3 p-3 xs:flex-row xs:items-start">
|
||||||
<Avatar url={playerData.profilePicture} label="Avatar" />
|
<Avatar url={playerData.profilePicture} label="Avatar" />
|
||||||
<div className="flex flex-col items-center gap-2 md:items-start">
|
<div className="flex flex-col items-center gap-2 xs:items-start">
|
||||||
<p className="text-2xl">{playerData.name}</p>
|
<p className="text-2xl">{playerData.name}</p>
|
||||||
|
|
||||||
<div className="flex gap-3 text-xl">
|
<div className="flex gap-3 text-xl">
|
||||||
@ -129,11 +129,32 @@ export default function Player({ params }: { params: { id: string } }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Labels */}
|
{/* Labels */}
|
||||||
<div>
|
<div className="flex flex-col gap-2">
|
||||||
<Label
|
<div className="flex gap-2">
|
||||||
title="Total play count"
|
<Label
|
||||||
value={formatNumber(playerData.scoreStats.totalPlayCount)}
|
title="Total play count"
|
||||||
/>
|
className="bg-blue-500"
|
||||||
|
value={formatNumber(playerData.scoreStats.totalPlayCount)}
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
title="Total score"
|
||||||
|
className="bg-blue-500"
|
||||||
|
value={formatNumber(playerData.scoreStats.totalScore)}
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
title="Avg ranked acc"
|
||||||
|
className="bg-blue-500"
|
||||||
|
value={`${playerData.scoreStats.averageRankedAccuracy.toFixed(
|
||||||
|
2,
|
||||||
|
)}%`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Label
|
||||||
|
title="Replays watched"
|
||||||
|
value={formatNumber(playerData.scoreStats.replaysWatched)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
|
|
||||||
type LabelProps = {
|
type LabelProps = {
|
||||||
title: string;
|
title: string;
|
||||||
value: string;
|
value: string;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Label({ title, value }: LabelProps) {
|
export default function Label({
|
||||||
|
title,
|
||||||
|
value,
|
||||||
|
className = "bg-neutral-700",
|
||||||
|
}: LabelProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col justify-center rounded-md bg-neutral-700">
|
<div className={clsx("flex flex-col justify-center rounded-md", className)}>
|
||||||
<div className="flex items-center gap-2 p-[0.3rem]">
|
<div className="flex items-center gap-2 p-[0.3rem]">
|
||||||
<p>{title}</p>
|
<p>{title}</p>
|
||||||
<div className="h-4 w-[1px] bg-neutral-100"></div>
|
<div className="h-4 w-[1px] bg-neutral-100"></div>
|
||||||
|
19
src/store/settingsStore.ts
Normal file
19
src/store/settingsStore.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { create } from "zustand";
|
||||||
|
import { createJSONStorage, persist } from "zustand/middleware";
|
||||||
|
|
||||||
|
export const useSettingsStore = create(
|
||||||
|
persist(
|
||||||
|
(set: any, get: any) => ({
|
||||||
|
userId: null,
|
||||||
|
|
||||||
|
setUserId: (userId: string) => set({ userId: userId }),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: "settings", // name of the item in the storage (must be unique)
|
||||||
|
storage: createJSONStorage(() => sessionStorage), // (optional) by default, 'localStorage' is used
|
||||||
|
skipHydration: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
@ -1,5 +1,4 @@
|
|||||||
import { connectMongo } from "@/database/mongo";
|
import { connectMongo } from "@/database/mongo";
|
||||||
import { PlayerSchema } from "@/database/schemas/player";
|
|
||||||
import { logger } from "@/logger";
|
import { logger } from "@/logger";
|
||||||
import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
|
import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
|
||||||
import { ScoresaberPlayerScore } from "@/schemas/scoresaber/playerScore";
|
import { ScoresaberPlayerScore } from "@/schemas/scoresaber/playerScore";
|
||||||
@ -55,12 +54,6 @@ export async function getPlayerInfo(
|
|||||||
apiOnly = false,
|
apiOnly = false,
|
||||||
): Promise<ScoresaberPlayer | undefined | null> {
|
): Promise<ScoresaberPlayer | undefined | null> {
|
||||||
await connectMongo();
|
await connectMongo();
|
||||||
const isPlayerInDb = await PlayerSchema.exists({ _id: playerId });
|
|
||||||
if (isPlayerInDb && !apiOnly) {
|
|
||||||
const player = await PlayerSchema.findById({ _id: playerId });
|
|
||||||
return player.scoresaber;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetchQueue.fetch(
|
const response = await fetchQueue.fetch(
|
||||||
formatString(GET_PLAYER_DATA_FULL, playerId),
|
formatString(GET_PLAYER_DATA_FULL, playerId),
|
||||||
);
|
);
|
||||||
|
16
yarn.lock
16
yarn.lock
@ -297,7 +297,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@^18":
|
"@types/react@*", "@types/react@^18", "@types/react@>=16.8":
|
||||||
version "18.2.29"
|
version "18.2.29"
|
||||||
resolved "https://registry.npmjs.org/@types/react/-/react-18.2.29.tgz"
|
resolved "https://registry.npmjs.org/@types/react/-/react-18.2.29.tgz"
|
||||||
integrity sha512-Z+ZrIRocWtdD70j45izShRwDuiB4JZqDegqMFW/I8aG5DxxLKOzVNoq62UIO82v9bdgi+DO1jvsb9sTEZUSm+Q==
|
integrity sha512-Z+ZrIRocWtdD70j45izShRwDuiB4JZqDegqMFW/I8aG5DxxLKOzVNoq62UIO82v9bdgi+DO1jvsb9sTEZUSm+Q==
|
||||||
@ -2626,7 +2626,7 @@ react-is@^16.13.1:
|
|||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
"react@^16.8.0 || ^17.0.0 || ^18", react@^18, react@^18.0.0, react@^18.2.0, "react@>= 16", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16:
|
"react@^16.8.0 || ^17.0.0 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18, react@^18.0.0, react@^18.2.0, "react@>= 16", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16, react@>=16.8:
|
||||||
version "18.2.0"
|
version "18.2.0"
|
||||||
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
||||||
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
||||||
@ -3322,6 +3322,11 @@ uri-js@^4.2.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode "^2.1.0"
|
punycode "^2.1.0"
|
||||||
|
|
||||||
|
use-sync-external-store@1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"
|
||||||
|
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
|
||||||
|
|
||||||
util-deprecate@^1.0.1, util-deprecate@^1.0.2:
|
util-deprecate@^1.0.1, util-deprecate@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
||||||
@ -3485,3 +3490,10 @@ zod@^3.20.2, zod@3.22.3:
|
|||||||
version "3.22.3"
|
version "3.22.3"
|
||||||
resolved "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz"
|
resolved "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz"
|
||||||
integrity sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==
|
integrity sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==
|
||||||
|
|
||||||
|
zustand@^4.4.3:
|
||||||
|
version "4.4.3"
|
||||||
|
resolved "https://registry.npmjs.org/zustand/-/zustand-4.4.3.tgz"
|
||||||
|
integrity sha512-oRy+X3ZazZvLfmv6viIaQmtLOMeij1noakIsK/Y47PWYhT8glfXzQ4j0YcP5i0P0qI1A4rIB//SGROGyZhx91A==
|
||||||
|
dependencies:
|
||||||
|
use-sync-external-store "1.2.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user