Skip to content

Commit 0963d10

Browse files
committed
Add query string p= for allycode input, Terms, Recent Searches, and more
1 parent 5c4cdeb commit 0963d10

13 files changed

Lines changed: 409 additions & 3 deletions

File tree

site/about/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,9 @@
4949
assets</li>
5050
</ul>
5151
<p>There are more plans for the future, but for now I think thats all. MTFBWY</p>
52+
<script>
53+
document.querySelector(".menu-toggle").addEventListener("click", () => {
54+
document.querySelector(".nav-links").classList.toggle("show");
55+
});
56+
</script>
5257
</body>

site/account-viewer/index.html

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ <h2>Enter AllyCode</h2>
3131
<p id="inputError" style="display: none;">Please enter a valid 9-digit Ally Code</p>
3232
</section>
3333

34+
<section class="recent-searches card">
35+
<h2>Recent Searches</h2>
36+
<ul id="recentSearchList"></ul>
37+
<p id="noRecent" class="no-recent">No recent searches</p>
38+
</section>
39+
3440
<section class="loading-screen card hidden" id="loadingScreen">
3541
<h2>Loading player data...</h2>
3642
</section>
@@ -88,7 +94,31 @@ <h3>GAC Stats (ALPHA)</h3>
8894
</section>
8995
</main>
9096

97+
<footer>
98+
<section id="termsModal" class="modal hidden">
99+
<div class="modal-content card">
100+
<h2>Terms and Conditions</h2>
101+
<div class="modal-body"></div>
102+
<div class="modal-actions">
103+
<button id="acceptTerms" class="primary-btn">I Agree</button>
104+
<button id="closeTerms" class="secondary-btn">I Do Not Agree</button>
105+
</div>
106+
</div>
107+
</section>
108+
109+
<section class="disclaimer">
110+
<p>Copyright 2025 LegoFan9</p>
111+
<p>This site is not affiliated with EA, Capital Games, Disney or Lucasfilm LTD.</p>
112+
<a href="#" id="openTerms">Terms</a>
113+
</section>
114+
</footer>
115+
91116
<script type="module" src="/src/account-viewer/main.ts"></script>
117+
<script>
118+
document.querySelector(".menu-toggle").addEventListener("click", () => {
119+
document.querySelector(".nav-links").classList.toggle("show");
120+
});
121+
</script>
92122
</body>
93123

94124
</html>

site/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ <h1>Welcome to LegoFan9's SWGoH Tools</h1>
124124
</a>
125125
<div style="height: 20px"></div>
126126
<p>By using this site you agree to allow useage of Google Analytics</p>
127+
<script>
128+
document.querySelector(".menu-toggle").addEventListener("click", () => {
129+
document.querySelector(".nav-links").classList.toggle("show");
130+
});
131+
</script>
127132
</body>
128133

129134
</html>

site/src/account-viewer/listBuilder.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { getSpeedModCount, getPipCount, countOffensePercentRolls } from "./mods.
55
import { ULLocation, relicChart, gearChart, starChart, activeChart } from "./locations.ts"
66
import { getWins } from "./grand-arena/main.ts"
77
import { getInstanceIds } from "./grand-arena/getRecentRounds.ts"
8+
import { saveRecentSearch } from "./recentSearches.ts"
89

910
function handleLastSeen(player: PlayerResp): void {
1011
let lastSeen = new Date(Number(player.lastActivityTime)).toLocaleString();
@@ -225,7 +226,9 @@ export async function FillList(allyCode: string) {
225226
await handleGACWins(player);
226227
break;
227228
default:
228-
console.error(`Found unknown playerMappings key: ${key}`)
229+
console.error(`Found unknown playerMappings key: ${key}`);
229230
}
230231
}
232+
233+
saveRecentSearch(allyCode, player.name);
231234
}

site/src/account-viewer/main.ts

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import '/src/nav-bar.css'
33
import { FillList } from "./listBuilder.ts";
44
import { cleanAllyCode, wakeServer } from "./requestMaker.ts"
55
import { Chart } from "chart.js"
6+
import { getRecentSearches } from "./recentSearches.ts";
7+
import {populateTermsModal} from "./terms.ts"
68

79
wakeServer();
810

@@ -11,12 +13,31 @@ const submitBtn = document.getElementById("submitAllyCode") as HTMLButtonElement
1113
const inputError = document.getElementById("inputError") as HTMLParagraphElement;
1214
const loadingScreen = document.getElementById("loadingScreen") as HTMLElement;
1315
const backBtn = document.getElementById("backToInput") as HTMLButtonElement;
16+
const recentSearchList = document.getElementById("recentSearchList") as HTMLUListElement;
17+
const noRecent = document.getElementById("noRecent") as HTMLParagraphElement;
18+
const termsModal = document.getElementById("termsModal") as HTMLElement;
19+
const acceptBtn = document.getElementById("acceptTerms") as HTMLButtonElement;
20+
const closeBtn = document.getElementById("closeTerms") as HTMLButtonElement;
21+
const openTerms = document.getElementById("openTerms") as HTMLAnchorElement;
1422

1523
const dashboardSections = document.querySelectorAll<HTMLElement>(
1624
".player-info, .stats-grid, .charts-grid, .stats-grid-2, .back" //, .gac-info
1725
);
1826

27+
const urlParams = new URLSearchParams(window.location.search);
28+
29+
const TERMS_VERSION = "v0"
30+
1931
submitBtn.addEventListener("click", async () => {
32+
const termsVersion = localStorage.getItem("acceptedTerms");
33+
if (termsVersion !== TERMS_VERSION) {
34+
const agreed = await showTermsModal();
35+
if (!agreed) {
36+
alert("You must agree to the terms to use this site.");
37+
return;
38+
}
39+
}
40+
2041
const rawInput = allyInput.value.trim();
2142
const allyCode = cleanAllyCode(rawInput);
2243

@@ -28,11 +49,16 @@ submitBtn.addEventListener("click", async () => {
2849
inputError.style.display = "none";
2950

3051
(document.querySelector(".allycode-input") as HTMLElement).classList.add("hidden");
52+
(document.querySelector(".recent-searches") as HTMLElement).classList.add("hidden");
3153

3254
loadingScreen.classList.remove("hidden");
3355

3456
await FillList(allyCode);
3557

58+
const url = new URL(window.location.href);
59+
url.searchParams.set("p", allyCode);
60+
window.history.replaceState({}, "", url.toString());
61+
3662
loadingScreen.classList.add("hidden");
3763
dashboardSections.forEach(section => section.classList.remove("hidden"));
3864
});
@@ -73,6 +99,7 @@ export function backButton() {
7399
Object.values(Chart.instances).forEach((chart: any) => chart.destroy());
74100

75101
(document.querySelector(".allycode-input") as HTMLElement).classList.remove("hidden");
102+
(document.querySelector(".recent-searches") as HTMLElement).classList.remove("hidden");
76103

77104
allyInput.value = "";
78105

@@ -82,15 +109,89 @@ export function backButton() {
82109
"pipList",
83110
"modsList",
84111
"offenseModsList",
85-
"profileStatList"
112+
"profileStatList",
113+
"recentSearchList"
86114
];
87115

88116
listsToClear.forEach(id => {
89117
const ul = document.getElementById(id);
90118
if (ul) ul.innerHTML = "";
91119
});
120+
121+
const url = new URL(window.location.href);
122+
url.searchParams.delete("p");
123+
window.history.replaceState({}, "", url.toString());
124+
125+
populateRecentSeen();
92126
}
93127

94128
backBtn.addEventListener("click", () => {
95129
backButton();
130+
});
131+
132+
function populateRecentSeen(): void {
133+
let recentSearch = getRecentSearches();
134+
recentSearch.forEach(search => {
135+
let newButton = document.createElement("button");
136+
newButton.classList.add("recent-item");
137+
newButton.textContent = `${search.playerName}: ${search.allyCode}`;
138+
newButton.addEventListener("click", () => {
139+
allyInput.value = search.allyCode;
140+
submitBtn.click();
141+
});
142+
143+
let newEntry = document.createElement("li");
144+
newEntry.appendChild(newButton);
145+
recentSearchList.append(newEntry);
146+
});
147+
148+
if (recentSearch.length > 0) {
149+
noRecent.classList.add("hidden")
150+
}
151+
}
152+
153+
openTerms.addEventListener("click", async e => {
154+
e.preventDefault();
155+
await showTermsModal();
156+
});
157+
158+
function showTermsModal(): Promise<boolean> {
159+
return new Promise(resolve => {
160+
termsModal.classList.remove("hidden");
161+
162+
const onAccept = () => {
163+
localStorage.setItem("acceptedTerms", TERMS_VERSION);
164+
termsModal.classList.add("hidden");
165+
cleanup();
166+
resolve(true);
167+
};
168+
169+
const onReject = () => {
170+
localStorage.setItem("acceptedTerms", "OPTED_OUT");
171+
termsModal.classList.add("hidden");
172+
cleanup();
173+
resolve(false);
174+
};
175+
176+
const cleanup = () => {
177+
acceptBtn.removeEventListener("click", onAccept);
178+
closeBtn.removeEventListener("click", onReject);
179+
};
180+
181+
acceptBtn.addEventListener("click", onAccept);
182+
closeBtn.addEventListener("click", onReject);
183+
});
184+
}
185+
186+
window.addEventListener("DOMContentLoaded", () => {
187+
setTimeout(() => { }, 1)
188+
189+
const allyCodeUrlQuery = urlParams.get("p");
190+
if (allyCodeUrlQuery) {
191+
allyInput.value = allyCodeUrlQuery;
192+
submitBtn.click();
193+
}
194+
195+
populateRecentSeen();
196+
populateTermsModal();
96197
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
export interface RecentSearch {
2+
playerName: string;
3+
allyCode: string;
4+
timestamp: number;
5+
}
6+
7+
const STORAGE_KEY = "recentSearches";
8+
9+
export function getRecentSearches(): RecentSearch[] {
10+
const raw = localStorage.getItem(STORAGE_KEY);
11+
if (!raw) return [];
12+
try {
13+
return JSON.parse(raw) as RecentSearch[];
14+
} catch {
15+
return [];
16+
}
17+
}
18+
19+
export function deleteRecentSearch(allyCode: string): void {
20+
const existing = getRecentSearches();
21+
const updated = existing.filter(s => s.allyCode !== allyCode);
22+
localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
23+
}
24+
25+
export function saveRecentSearch(allyCode: string, playerName: string): void {
26+
const existing = getRecentSearches();
27+
28+
const filtered = existing.filter(s => s.allyCode !== allyCode);
29+
30+
filtered.unshift({
31+
playerName,
32+
allyCode,
33+
timestamp: Date.now(),
34+
});
35+
36+
const limited = filtered.slice(0, 5);
37+
38+
localStorage.setItem(STORAGE_KEY, JSON.stringify(limited));
39+
}
40+
41+
export function checkIfSearchExists(allyCode: string): boolean {
42+
let recentSearches = getRecentSearches();
43+
let found = false;
44+
recentSearches.forEach(search => {
45+
if (search.allyCode === allyCode) {
46+
found = true;
47+
}
48+
})
49+
50+
return found;
51+
}

0 commit comments

Comments
 (0)