feat(status): add public repair status page

This commit is contained in:
Schubert Ferenc 2026-07-04 21:06:43 +02:00
parent a284bbc188
commit efdc4d5be1
6 changed files with 425 additions and 4 deletions

70
lib/olympus/status.ts Normal file
View file

@ -0,0 +1,70 @@
import "server-only";
export type OlympusRepairStatusHistoryItem = {
status: string;
status_label: string;
created_at: string;
};
export type OlympusRepairStatus = {
repair_number: string;
public_status_label: string;
device_manufacturer: string;
device_model: string;
status_history_public: OlympusRepairStatusHistoryItem[];
updated_at: string;
};
export type RepairStatusResult =
| { ok: true; status: OlympusRepairStatus }
| { ok: false; reason: "invalid" | "unavailable" };
function getStatusApiBaseUrl() {
return process.env.OLYMPUS_PUBLIC_STATUS_API_URL?.replace(/\/$/, "") ?? "";
}
function getStatusApiToken() {
return process.env.OLYMPUS_PUBLIC_STATUS_API_TOKEN ?? "";
}
export async function fetchOlympusRepairStatus(token: string): Promise<RepairStatusResult> {
const baseUrl = getStatusApiBaseUrl();
if (!baseUrl || !token.trim()) {
return { ok: false, reason: "unavailable" };
}
const headers: HeadersInit = {
Accept: "application/json",
};
const apiToken = getStatusApiToken();
if (apiToken) {
headers.Authorization = `Bearer ${apiToken}`;
}
let response: Response;
try {
response = await fetch(`${baseUrl}/public/repairs/status/${encodeURIComponent(token)}`, {
headers,
cache: "no-store",
});
} catch {
return { ok: false, reason: "unavailable" };
}
if (response.status === 401 || response.status === 403 || response.status === 404) {
return { ok: false, reason: "invalid" };
}
if (!response.ok) {
return { ok: false, reason: "unavailable" };
}
try {
return { ok: true, status: await response.json() as OlympusRepairStatus };
} catch {
return { ok: false, reason: "unavailable" };
}
}