Files
OpenFrontIO/src/client/Cosmetics.ts
T
Scott Anderson 0a40bcebf0 Enable the sort-imports eslint rule (#1849)
## Description:

Enable the `sort-imports` eslint rule.

Fixes #1784

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
2025-08-17 20:53:44 -04:00

97 lines
2.8 KiB
TypeScript

import { Cosmetics, CosmeticsSchema, Pattern } from "../core/CosmeticSchemas";
import {
StripeCreateCheckoutSessionResponseSchema,
UserMeResponse,
} from "../core/ApiSchemas";
import { getApiBase, getAuthHeader } from "./jwt";
import { z } from "zod";
export async function patterns(
userMe: UserMeResponse | null,
): Promise<Pattern[]> {
const cosmetics = await getCosmetics();
if (cosmetics === undefined) {
return [];
}
const patterns: Pattern[] = [];
const playerFlares = new Set(userMe?.player.flares);
for (const name in cosmetics.patterns) {
const patternData = cosmetics.patterns[name];
const hasAccess = playerFlares.has(`pattern:${name}`);
if (hasAccess) {
// Remove product info because player already has access.
patternData.product = null;
patterns.push(patternData);
} else if (patternData.product !== null) {
// Player doesn't have access, but product is available for purchase.
patterns.push(patternData);
}
// If player doesn't have access and product is null, don't show it.
}
return patterns;
}
export async function handlePurchase(priceId: string) {
const response = await fetch(
`${getApiBase()}/stripe/create-checkout-session`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"authorization": getAuthHeader(),
},
body: JSON.stringify({
priceId: priceId,
successUrl: `${window.location.origin}#purchase-completed=true`,
cancelUrl: `${window.location.origin}#purchase-completed=false`,
}),
},
);
if (!response.ok) {
console.error(
`Error purchasing pattern:${response.status} ${response.statusText}`,
);
if (response.status === 401) {
alert("You are not logged in. Please log in to purchase a pattern.");
} else {
alert("Something went wrong. Please try again later.");
}
return;
}
const json = await response.json();
const parsed = StripeCreateCheckoutSessionResponseSchema.safeParse(json);
if (!parsed.success) {
const error = z.prettifyError(parsed.error);
console.error("Invalid checkout session response:", error);
alert("Checkout failed. Please try again later.");
return;
}
const { url } = parsed.data;
// Redirect to Stripe checkout
window.location.href = url;
}
async function getCosmetics(): Promise<Cosmetics | undefined> {
try {
const response = await fetch(`${getApiBase()}/cosmetics.json`);
if (!response.ok) {
console.error(`HTTP error! status: ${response.status}`);
return;
}
const result = CosmeticsSchema.safeParse(await response.json());
if (!result.success) {
console.error(`Invalid cosmetics: ${result.error.message}`);
return;
}
return result.data;
} catch (error) {
console.error("Error getting cosmetics:", error);
}
}