Initial commit: TSS Bot Web Frontend (React/Vite + production server)

This commit is contained in:
clxud
2026-07-02 02:09:34 +00:00
commit 36092f0269
87 changed files with 34597 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
# Static Public Data
The web server serves `/data/*` from the same public data cache used by
`/api/tss/*`, and fills missing snapshots from the matching API route with a
short timeout. The frontend uses `/api/tss/*` by default; set
`VITE_STATIC_DATA=true` only for static-first experiments.
- `/data/leaderboard-teams.json`
- `/data/leaderboard-players.json`
- `/data/home-teams.json`
- `/data/recent-games.json`
- `/data/teams/{key}.json`
- `/data/teams/{key}.games.json`
- `/data/players/{key}.json`
- `/data/games/{key}.json`
- `/data/games/{key}.logs.json`
`{key}` is `encodeURIComponent(value).replace(/%/g, '~')`.
Snapshot files should keep the same response shape as the matching `/api/tss/*`
endpoint. Missing files are fine: the app remembers the miss for the current
browser session and uses the existing API route instead.
Do not generate every possible entity forever. Keep `/data` bounded:
- Always generate the small global snapshots: leaderboards, home teams, recent
games.
- Generate team/player/game detail snapshots only for hot items, such as current
leaderboard entries, recent games, recently viewed pages, or pinned items.
- Prune detail snapshots by age and access. For example: keep recent games for
7-30 days, keep leaderboard teams/players while they remain ranked, and delete
cold files that have not been refreshed recently.
- Write snapshots atomically (`file.tmp` then rename) so readers never see a
partial JSON file.
- Serve compressed responses from the web server/CDN when possible. Keep source
JSON minified unless humans need to inspect a fixture.
+22
View File
@@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96" role="img" aria-labelledby="title">
<title id="title">Toothless' TSS Bot tree icon</title>
<rect width="96" height="96" rx="18" fill="#fefde7"/>
<rect x="7" y="7" width="82" height="82" rx="14" fill="#fff2e6" stroke="#fdca9b" stroke-width="4"/>
<g shape-rendering="crispEdges">
<rect x="43" y="48" width="10" height="26" fill="#c96303"/>
<rect x="39" y="62" width="18" height="10" fill="#c96303"/>
<rect x="34" y="70" width="28" height="5" fill="#c96303"/>
<rect x="18" y="28" width="28" height="14" fill="#ed5145"/>
<rect x="28" y="18" width="28" height="15" fill="#ed5145"/>
<rect x="48" y="24" width="30" height="16" fill="#ed5145"/>
<rect x="28" y="40" width="40" height="16" fill="#ed5145"/>
<rect x="24" y="32" width="18" height="6" fill="#fdb068"/>
<rect x="34" y="22" width="18" height="6" fill="#fdb068"/>
<rect x="54" y="28" width="18" height="6" fill="#fdb068"/>
<rect x="38" y="44" width="20" height="6" fill="#fdb068"/>
<rect x="40" y="25" width="8" height="4" fill="#fee5cd"/>
<rect x="56" y="31" width="8" height="4" fill="#fee5cd"/>
<rect x="46" y="47" width="8" height="4" fill="#fee5cd"/>
<rect x="14" y="76" width="68" height="6" fill="#fdca9b"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

+80
View File
@@ -0,0 +1,80 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630" role="img" aria-labelledby="title description">
<title id="title">Toothless' TSS Bot</title>
<desc id="description">A share card for Toothless' TSS Bot using the pixel tree from the home page.</desc>
<rect width="1200" height="630" fill="#fefde7"/>
<path d="M0 452 120 384l118 42 152-126 168 112 132-76 124 84 174-154 212 176v188H0Z" fill="#fcfbcf"/>
<path d="M0 498 130 430l110 42 142-92 170 102 120-54 132 66 180-112 216 128v120H0Z" fill="#f9f69f"/>
<rect x="72" y="72" width="1056" height="486" rx="28" fill="#fefde7" stroke="#fdca9b" stroke-width="6"/>
<rect x="96" y="96" width="1008" height="438" rx="18" fill="#fff2e6" opacity=".54"/>
<g transform="translate(780 144) scale(.58)" shape-rendering="crispEdges">
<rect x="0" y="0" width="500" height="420" fill="#fefde7" stroke="#fdca9b" stroke-width="6"/>
<path d="M0 372c55-16 116-12 173 3 46 12 101 20 157 4 58-17 112-10 170 5v36H0Z" fill="#fee5cd"/>
<path d="M0 394c54-10 110-8 172 6 54 12 108 10 160-4 58-15 112-10 168 4v20H0Z" fill="#fdca9b"/>
<g fill="#c96303">
<rect x="232" y="248" width="38" height="118"/>
<rect x="224" y="300" width="54" height="72"/>
<rect x="214" y="346" width="76" height="34"/>
<rect x="198" y="366" width="112" height="18"/>
<rect x="196" y="232" width="62" height="16" transform="rotate(-28 196 232)"/>
<rect x="248" y="222" width="64" height="14" transform="rotate(25 248 222)"/>
<rect x="176" y="198" width="88" height="14" transform="rotate(-46 176 198)"/>
<rect x="242" y="188" width="88" height="14" transform="rotate(42 242 188)"/>
<rect x="150" y="164" width="92" height="12" transform="rotate(-20 150 164)"/>
<rect x="270" y="154" width="98" height="12" transform="rotate(18 270 154)"/>
<rect x="212" y="120" width="82" height="12" transform="rotate(-72 212 120)"/>
<rect x="246" y="118" width="78" height="12" transform="rotate(68 246 118)"/>
</g>
<g fill="#ed5145">
<rect x="76" y="110" width="112" height="52"/>
<rect x="114" y="70" width="128" height="62"/>
<rect x="198" y="48" width="116" height="68"/>
<rect x="278" y="76" width="132" height="60"/>
<rect x="334" y="126" width="92" height="54"/>
<rect x="102" y="160" width="116" height="58"/>
<rect x="190" y="134" width="148" height="66"/>
<rect x="278" y="172" width="116" height="58"/>
</g>
<g fill="#fdb068">
<rect x="98" y="124" width="84" height="26"/>
<rect x="138" y="84" width="92" height="30"/>
<rect x="216" y="66" width="82" height="28"/>
<rect x="292" y="92" width="96" height="30"/>
<rect x="354" y="142" width="58" height="24"/>
<rect x="126" y="178" width="78" height="24"/>
<rect x="210" y="150" width="104" height="28"/>
<rect x="300" y="190" width="76" height="24"/>
</g>
<g fill="#fee5cd">
<rect x="150" y="98" width="44" height="16"/>
<rect x="238" y="76" width="38" height="16"/>
<rect x="314" y="104" width="48" height="16"/>
<rect x="230" y="160" width="48" height="16"/>
<rect x="322" y="202" width="36" height="14"/>
</g>
<g fill="#fb7b04">
<rect x="74" y="360" width="6" height="18"/>
<rect x="116" y="366" width="6" height="16"/>
<rect x="342" y="362" width="6" height="20"/>
<rect x="402" y="370" width="6" height="14"/>
<rect x="444" y="364" width="6" height="18"/>
</g>
</g>
<g transform="translate(122 128)">
<text x="0" y="36" fill="#e82517" font-family="Inter, Segoe UI, Arial, sans-serif" font-size="26" font-weight="800" letter-spacing="2">LIVE TSS INTEL</text>
<text x="0" y="132" fill="#000" font-family="Inter, Segoe UI, Arial, sans-serif" font-size="76" font-weight="900">Toothless'</text>
<text x="0" y="216" fill="#000" font-family="Inter, Segoe UI, Arial, sans-serif" font-size="76" font-weight="900">TSS Bot</text>
<text x="0" y="282" fill="#555" font-family="Inter, Segoe UI, Arial, sans-serif" font-size="30" font-weight="600">Leaderboards, battle logs, uptime, and viewer analytics.</text>
</g>
<g transform="translate(122 458)" fill="#000" font-family="Inter, Segoe UI, Arial, sans-serif" font-size="24" font-weight="800">
<rect x="0" y="-34" width="184" height="54" rx="8" fill="#fcfbcf" stroke="#fdca9b"/>
<text x="24" y="2">Teams</text>
<rect x="208" y="-34" width="214" height="54" rx="8" fill="#fcfbcf" stroke="#fdca9b"/>
<text x="232" y="2">Battle Logs</text>
<rect x="446" y="-34" width="154" height="54" rx="8" fill="#fcfbcf" stroke="#fdca9b"/>
<text x="470" y="2">Uptime</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+12
View File
@@ -0,0 +1,12 @@
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 27.04.2017 18:23:39
newmtl wire_022022022
Ns 32
d 1
Tr 0
Tf 1 1 1
illum 2
Ka 0.0863 0.0863 0.0863
Kd 0.0863 0.0863 0.0863
Ks 0.3500 0.3500 0.3500
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB