desloppify: code health overhaul plus abuse hardening (140 green, strict 87.2)
Build & Push / Lint & Build (pull_request) Failing after 52s
Build & Push / Build & Push Image (pull_request) Skipped
Build & Push / Trigger Deploy (pull_request) Skipped

Honest baseline after removing 45 gaming suppressions. Structural: lib/game plus root hooks extraction, CORS origin echo, DEV_ORIGINS layering. Fixes: error-cause binding, discord 5xx split, null-cache guard, co-located tests, rejecting-fetch coverage, naming and typing cleanup, socket controller, cache bound, cascade helpers, latch resets. Hardening: per-IP rate limit on API routes, deterministic-miss UX, retry cooldown plus cap. Suite 140 green, build plus lint clean.
This commit is contained in:
fristy committed 2026-09-11 23:54:59 +03:00
1 parent 7d6d31265b
commit 864b9226fc
78 files changed
+4908 -1430

No files matched your search

+262
View File
@@ -0,0 +1,262 @@
"use client";
import Image from "next/image";
import { useEffect, useRef } from "react";
import type { GamePricePoint, GameProfile } from "@/lib/game/game-profile-types";
import {
describeProfile,
discountPercent,
formatCount,
formatPrice,
formatRatingPercent,
localizeScore,
type ModalDict,
} from "@/lib/game/game-format";
import { steamdbAppUrl } from "@/lib/game/discord-app";
export function ModalReviews({
profile,
dict,
localeTag,
}: {
profile: GameProfile;
dict: ModalDict;
localeTag: string;
}) {
const { dbRating, hasReviews, metascore, opencritic } = describeProfile(profile);
if (!hasReviews) {
return null;
}
const steamdbRating: { score: number; url: string } | null =
dbRating != null && profile.steamId
? { score: dbRating, url: steamdbAppUrl(profile.steamId) }
: null;
return (
<div className="mt-4">
<p className="font-mono text-xs uppercase tracking-wider text-zinc-500">
{dict.reviews}
</p>
<div className="mt-1.5 grid gap-2 sm:grid-cols-2">
{profile.steamReviews ? (
<a
href={profile.steamReviews.url}
target="_blank"
rel="noopener noreferrer"
className="rounded-xl border border-white/5 bg-white/[0.03] p-3 transition-colors hover:border-white/15"
>
<p className="font-mono text-xs text-zinc-500">{dict.totalReviews}</p>
<p className="mt-1 text-sm font-semibold">
{localizeScore(profile.steamReviews.label, dict)}
</p>
<p className="font-mono text-xs text-zinc-500">
{formatCount(profile.steamReviews.total, localeTag, dict.reviewsUnit)}
</p>
</a>
) : null}
{steamdbRating ? (
<a
href={steamdbRating.url}
target="_blank"
rel="noopener noreferrer"
className="rounded-xl border border-white/5 bg-white/[0.03] p-3 transition-colors hover:border-white/15"
>
<p className="font-mono text-xs text-zinc-500">{dict.steamdbRating}</p>
<p className="mt-1 text-sm font-semibold">
{formatRatingPercent(steamdbRating.score, localeTag)}
</p>
<p className="font-mono text-xs text-zinc-500">steamdb.info ↗</p>
</a>
) : null}
{metascore ? (
<a
href={metascore.url}
target="_blank"
rel="noopener noreferrer"
className="rounded-xl border border-white/5 bg-white/[0.03] p-3 transition-colors hover:border-white/15"
>
<p className="font-mono text-xs text-zinc-500">Metacritic</p>
<p className="mt-1 text-sm font-semibold">
{metascore.score ?? "—"}
{metascore.score != null ? (
<span className="font-normal text-zinc-500">/100</span>
) : null}
</p>
<p className="font-mono text-xs text-zinc-500">
{formatCount(metascore.count, localeTag, dict.reviewsUnit)}
</p>
</a>
) : null}
{opencritic ? (
<a
href={opencritic.url}
target="_blank"
rel="noopener noreferrer"
className="rounded-xl border border-white/5 bg-white/[0.03] p-3 transition-colors hover:border-white/15"
>
<p className="font-mono text-xs text-zinc-500">OpenCritic</p>
<p className="mt-1 text-sm font-semibold">
{opencritic.score ?? "—"}
{opencritic.score != null ? (
<span className="font-normal text-zinc-500">/100</span>
) : null}
</p>
<p className="font-mono text-xs text-zinc-500">
{formatCount(opencritic.count, localeTag, dict.reviewsUnit)}
</p>
</a>
) : null}
</div>
</div>
);
}
export function ModalPrices({
dict,
localeTag,
bestPrice,
historyLow,
isFree,
}: {
dict: ModalDict;
localeTag: string;
bestPrice: GamePricePoint | null;
historyLow: GamePricePoint | null;
isFree: boolean;
}) {
return (
<div className="mt-4">
<p className="font-mono text-xs uppercase tracking-wider text-zinc-500">
{dict.prices}
</p>
{isFree ? (
<p className="mt-1.5 inline-block rounded-full border border-mint/20 bg-mint/5 px-4 py-1.5 text-xs font-semibold text-mint">
{dict.free}
</p>
) : (
<div className="mt-1.5 grid gap-2 sm:grid-cols-2">
{bestPrice ? (
<a
href={bestPrice.url || undefined}
target="_blank"
rel="noopener noreferrer"
className="rounded-xl border border-mint/20 bg-mint/5 p-3 transition-colors hover:border-mint/40"
>
<p className="font-mono text-xs text-mint">
{dict.bestPrice} · {bestPrice.shop}
</p>
<p className="mt-1 text-lg font-bold">
{formatPrice(bestPrice, localeTag)}{" "}
{discountPercent(bestPrice) ? (
<span className="ml-1 rounded bg-mint/15 px-1.5 py-0.5 align-middle font-mono text-xs text-mint">
-%{discountPercent(bestPrice)}
</span>
) : null}
</p>
</a>
) : null}
{historyLow ? (
<div className="rounded-xl border border-white/5 bg-white/[0.03] p-3">
<p className="font-mono text-xs text-zinc-500">
{dict.historyLow} · {historyLow.shop}
</p>
<p className="mt-1 text-lg font-bold text-zinc-200">
{formatPrice(historyLow, localeTag)}
</p>
</div>
) : null}
</div>
)}
</div>
);
}
export function ModalScreenshots({
profile,
dict,
hero,
onPick,
}: {
profile: GameProfile;
dict: ModalDict;
hero: string | null;
onPick: (shot: string) => void;
}) {
const stripRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
const strip = stripRef.current;
if (!strip) {
return;
}
function onWheel(event: WheelEvent): void {
const el = stripRef.current;
if (!el) {
return;
}
if (Math.abs(event.deltaX) >= Math.abs(event.deltaY)) {
return;
}
if (el.scrollWidth <= el.clientWidth + 1) {
return;
}
event.preventDefault();
el.scrollLeft += event.deltaY;
}
strip.addEventListener("wheel", onWheel, { passive: false });
return () => strip.removeEventListener("wheel", onWheel);
}, [profile]);
function scrollStrip(by: number): void {
stripRef.current?.scrollBy({ left: by, behavior: "smooth" });
}
return (
<div className="mt-4">
<div className="flex items-center justify-between">
<p className="font-mono text-xs uppercase tracking-wider text-zinc-500">
{dict.screenshots}
</p>
<div className="flex gap-1.5">
<button
type="button"
onClick={() => scrollStrip(-360)}
aria-label={dict.scrollBack}
className="rounded-full border border-white/10 px-2.5 py-0.5 text-xs text-zinc-400 transition-colors hover:border-white/25 hover:text-white"
>
‹
</button>
<button
type="button"
onClick={() => scrollStrip(360)}
aria-label={dict.scrollForward}
className="rounded-full border border-white/10 px-2.5 py-0.5 text-xs text-zinc-400 transition-colors hover:border-white/25 hover:text-white"
>
›
</button>
</div>
</div>
<div ref={stripRef} className="no-scrollbar mt-1.5 flex gap-2 overflow-x-auto p-1">
{profile.screenshots.map((shot) => (
<button
key={shot}
type="button"
onClick={() => onPick(shot)}
aria-label={dict.screenshots}
className={`shrink-0 overflow-hidden rounded-xl transition-all ${
hero === shot ? "ring-2 ring-blurple" : "opacity-70 hover:opacity-100"
}`}
>
<Image
src={shot}
alt=""
width={320}
height={180}
loading="lazy"
className="h-auto w-56"
/>
</button>
))}
</div>
</div>
);
}