mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-29 14:50:13 -05:00
Extra infos on user page
This commit is contained in:
@@ -9,6 +9,7 @@ import { TwitchIcon } from "~/components/icons/Twitch";
|
||||
import { TwitterIcon } from "~/components/icons/Twitter";
|
||||
import { YouTubeIcon } from "~/components/icons/YouTube";
|
||||
import { Main } from "~/components/Main";
|
||||
import { rawSensToString } from "~/utils/strings";
|
||||
import type { Unpacked } from "~/utils/types";
|
||||
import { assertUnreachable } from "~/utils/types";
|
||||
import { badgeExplanationText } from "../badges/$id";
|
||||
@@ -52,6 +53,7 @@ export default function UserInfoPage() {
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<ExtraInfos />
|
||||
<BadgeContainer badges={data.badges} />
|
||||
{data.bio && <article>{data.bio}</article>}
|
||||
</div>
|
||||
@@ -111,6 +113,40 @@ function SocialLinkIcon({ type }: Pick<SocialLinkProps, "type">) {
|
||||
}
|
||||
}
|
||||
|
||||
function ExtraInfos() {
|
||||
const { t } = useTranslation(["user"]);
|
||||
const [, parentRoute] = useMatches();
|
||||
invariant(parentRoute);
|
||||
const data = parentRoute.data as UserPageLoaderData;
|
||||
|
||||
const motionSensText =
|
||||
typeof data.motionSens === "number"
|
||||
? ` / ${t("user:motion")} ${rawSensToString(data.motionSens)}`
|
||||
: "";
|
||||
|
||||
if (!data.inGameName && typeof data.stickSens !== "number") {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="u__extra-infos">
|
||||
{data.inGameName && (
|
||||
<div className="u__extra-info">
|
||||
<span className="u__extra-info__heading">{t("user:ign.short")}</span>{" "}
|
||||
{data.inGameName}
|
||||
</div>
|
||||
)}
|
||||
{typeof data.stickSens === "number" && (
|
||||
<div className="u__extra-info">
|
||||
<span className="u__extra-info__heading">{t("user:sens")}</span>{" "}
|
||||
{t("user:stick")} {rawSensToString(data.stickSens)}
|
||||
{motionSensText}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function BadgeContainer(props: { badges: UserPageLoaderData["badges"] }) {
|
||||
const { t } = useTranslation("badges");
|
||||
const [badges, setBadges] = React.useState(props.badges);
|
||||
|
||||
@@ -86,6 +86,26 @@
|
||||
fill: #9146ff;
|
||||
}
|
||||
|
||||
.u__extra-infos {
|
||||
display: flex;
|
||||
max-width: 24rem;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--s-2-5);
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.u__extra-info {
|
||||
padding: var(--s-1) var(--s-1-5);
|
||||
background-color: var(--bg-darker);
|
||||
border-radius: var(--rounded);
|
||||
font-size: var(--fonts-xxs);
|
||||
}
|
||||
|
||||
.u__extra-info__heading {
|
||||
color: var(--theme);
|
||||
font-weight: var(--bold);
|
||||
}
|
||||
|
||||
.u__badges {
|
||||
display: flex;
|
||||
max-width: 24rem;
|
||||
|
||||
@@ -21,3 +21,6 @@ export function placementString(placement: number) {
|
||||
export function semiRandomId() {
|
||||
return String(Math.random());
|
||||
}
|
||||
|
||||
export const rawSensToString = (sens: number) =>
|
||||
`${sens > 0 ? "+" : ""}${sens / 10}`;
|
||||
|
||||
@@ -61,6 +61,8 @@ export function undefinedToNull(value: unknown): unknown {
|
||||
}
|
||||
|
||||
export function actualNumber(value: unknown) {
|
||||
if (value === "") return undefined;
|
||||
|
||||
const parsed = Number(value);
|
||||
|
||||
return Number.isNaN(parsed) ? undefined : parsed;
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
{
|
||||
"customUrl": "Custom URL",
|
||||
"ign": "In-game name",
|
||||
"ign.short": "IGN",
|
||||
"country": "Country",
|
||||
"bio": "Bio",
|
||||
"stickSens": "R-stick sens",
|
||||
"motionSens": "Motion sens",
|
||||
"motion": "Motion",
|
||||
"stick": "Stick",
|
||||
"sens": "Sens",
|
||||
|
||||
"results.placing": "Placing",
|
||||
"results.team": "Team",
|
||||
|
||||
Reference in New Issue
Block a user