update and polish
This commit is contained in:
+74
-25
@@ -1,35 +1,84 @@
|
||||
import { SWAPIPlanet, SWAPIStarship, Planet, Starship } from "@/types/swapi";
|
||||
|
||||
const BASE_URL = "https://swapi.dev/api";
|
||||
const CACHE_KEY = "smugglers_run_cache";
|
||||
const CACHE_DURATION = 1000 * 60 * 60 * 24; // Cache TTL 24 hrs
|
||||
|
||||
export async function fetchPlanets(): Promise<Planet[]> {
|
||||
const res = await fetch(`${BASE_URL}/planets/`);
|
||||
if (!res.ok) throw new Error("Galaxy data unavailable");
|
||||
const data = await res.json();
|
||||
|
||||
return data.results.map(
|
||||
(p: SWAPIPlanet): Planet => ({
|
||||
...p,
|
||||
id: p.url,
|
||||
// Add random x/y coordinates for galaxy map
|
||||
x: Math.floor(Math.random() * 80) + 10,
|
||||
y: Math.floor(Math.random() * 70) + 15,
|
||||
}),
|
||||
);
|
||||
interface GameCache {
|
||||
planets: Planet[];
|
||||
starships: Starship[];
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export async function fetchStarships(): Promise<Starship[]> {
|
||||
const res = await fetch(`${BASE_URL}/starships/`);
|
||||
if (!res.ok) throw new Error("Imperial records unavailable");
|
||||
const data = await res.json();
|
||||
async function fetchAllPages<T>(endpoint: string): Promise<T[]> {
|
||||
let allResults: T[] = [];
|
||||
let nextUrl = `${BASE_URL}/${endpoint}/`;
|
||||
|
||||
return data.results.map((s: SWAPIStarship): Starship => {
|
||||
// Add difficulty score based on ship cost
|
||||
while (nextUrl) {
|
||||
const res = await fetch(nextUrl);
|
||||
if (!res.ok) throw new Error(`${endpoint} data unavailable`);
|
||||
const data = await res.json();
|
||||
allResults = [...allResults, ...data.results];
|
||||
nextUrl = data.next;
|
||||
}
|
||||
return allResults;
|
||||
}
|
||||
|
||||
export async function fetchGameData(): Promise<{
|
||||
planets: Planet[];
|
||||
starships: Starship[];
|
||||
}> {
|
||||
// Try load from localstorage as simple cache
|
||||
const cachedData =
|
||||
typeof window !== "undefined" ? localStorage.getItem(CACHE_KEY) : null;
|
||||
|
||||
if (cachedData) {
|
||||
const parsedCache: GameCache = JSON.parse(cachedData);
|
||||
const isExpired = Date.now() - parsedCache.timestamp > CACHE_DURATION;
|
||||
|
||||
if (!isExpired) {
|
||||
console.log("data loaded from cache");
|
||||
|
||||
return { planets: parsedCache.planets, starships: parsedCache.starships };
|
||||
}
|
||||
}
|
||||
|
||||
// If not in cache or outdated, fetch from Swapi
|
||||
console.log("data not in cache. fetching from swapi...");
|
||||
|
||||
const [rawPlanets, rawStarships] = await Promise.all([
|
||||
fetchAllPages<SWAPIPlanet>("planets"),
|
||||
fetchAllPages<SWAPIStarship>("starships"),
|
||||
]);
|
||||
|
||||
const planets: Planet[] = rawPlanets.map((p) => ({
|
||||
...p,
|
||||
id: p.url,
|
||||
x: Math.floor(Math.random() * 80) + 10,
|
||||
y: Math.floor(Math.random() * 70) + 15,
|
||||
}));
|
||||
|
||||
const starships: Starship[] = rawStarships.map((s) => {
|
||||
const cost = parseInt(s.cost_in_credits);
|
||||
let ds = 8;
|
||||
if (isNaN(cost) || cost > 1000000) ds = 12;
|
||||
else if (cost > 100000) ds = 10;
|
||||
|
||||
return { ...s, id: s.url, ds };
|
||||
let ds = 8,
|
||||
hp = 2;
|
||||
if (isNaN(cost) || cost > 1000000) {
|
||||
ds = 12;
|
||||
hp = 6;
|
||||
} else if (cost > 100000) {
|
||||
ds = 10;
|
||||
hp = 4;
|
||||
}
|
||||
return { ...s, id: s.url, ds, hp };
|
||||
});
|
||||
|
||||
// Save to localstorage
|
||||
const cacheToSave: GameCache = {
|
||||
planets,
|
||||
starships,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
localStorage.setItem(CACHE_KEY, JSON.stringify(cacheToSave));
|
||||
|
||||
return { planets, starships };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user