Skip to content

Commit 2a19170

Browse files
committed
fix: incorrect lambda status due to 503 code
1 parent 11d8c9b commit 2a19170

5 files changed

Lines changed: 140 additions & 33 deletions

File tree

.github/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Unofficial real-time status page for Cfx.re services — monitors FiveM, RedM, F
44

55
[![Build status](https://github.com/FixFXOSS/cfxstat.us/actions/workflows/test-build.yml/badge.svg)](https://github.com/FixFXOSS/cfxstat.us/actions)
66
[![Lint status](https://github.com/FixFXOSS/cfxstat.us/actions/workflows/validate-linting.yml/badge.svg)](https://github.com/FixFXOSS/cfxstat.us/actions)
7-
[![Format status](https://github.com/FixFXOSS/cfxstat.us/actions/workflows/validate-formatting.yml/badge.svg)](https://github.com/FixFXOSS/cfxstat.us/actions)
87
[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](LICENSE)
98
[![Deployed on Cloudflare Workers](https://img.shields.io/badge/Deployed%20on-Cloudflare%20Workers-orange.svg)](https://workers.cloudflare.com/)
109

.github/workflows/validate-formatting.yml

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/components/layouts/StatusPageLayout.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { Clock, Loader2, RefreshCw } from "lucide-react";
1+
import { Clock, RefreshCw } from "lucide-react";
22
import { useCallback, useEffect, useRef, useState } from "react";
33
import { StatusFooter } from "@/components/StatusFooter";
44
import { StatusHeader } from "@/components/StatusHeader";
55
import { BackgroundEffects } from "@/components/ui/BackgroundEffects";
6+
import { InitialLoader } from "@/components/ui/InitialLoader";
67
import { OverallBanner } from "@/components/ui/OverallBanner";
78
import { ServiceCategoryCard } from "@/components/ui/ServiceCategoryCard";
89
import type { StatusSummary } from "@/types/status";
@@ -74,11 +75,7 @@ export default function StatusPageLayout() {
7475

7576
<main className="flex-1 mx-auto w-full max-w-4xl px-4 py-8 md:px-6 md:py-12 space-y-8">
7677
{!data ? (
77-
/* Loading skeleton — shown on first paint */
78-
<div className="flex flex-col items-center justify-center py-20 gap-4">
79-
<Loader2 size={32} className="animate-spin text-blue-400" />
80-
<p className="text-sm text-gray-400">Checking services…</p>
81-
</div>
78+
<InitialLoader />
8279
) : (
8380
<>
8481
{/* Overall banner */}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { Activity, CheckCircle2, Loader2, Radio } from "lucide-react";
2+
import { useEffect, useState } from "react";
3+
import { serviceCategories } from "@/data/services";
4+
import { cn } from "@/utils/cn";
5+
6+
const totalServices = serviceCategories.reduce(
7+
(sum, cat) => sum + cat.services.length,
8+
0,
9+
);
10+
11+
/** How long each step lingers before moving to the next. */
12+
const STEP_INTERVAL_MS = 1_800;
13+
14+
/**
15+
* Engaging initial loader shown while the first status check runs.
16+
* Cycles through service categories to show what's being probed.
17+
*/
18+
export function InitialLoader() {
19+
const [activeStep, setActiveStep] = useState(0);
20+
const [dots, setDots] = useState("");
21+
22+
// Cycle through categories
23+
useEffect(() => {
24+
const interval = setInterval(() => {
25+
setActiveStep((prev) => {
26+
if (prev >= serviceCategories.length - 1) return prev;
27+
return prev + 1;
28+
});
29+
}, STEP_INTERVAL_MS);
30+
return () => clearInterval(interval);
31+
}, []);
32+
33+
// Animate ellipsis
34+
useEffect(() => {
35+
const interval = setInterval(() => {
36+
setDots((prev) => (prev.length >= 3 ? "" : `${prev}.`));
37+
}, 400);
38+
return () => clearInterval(interval);
39+
}, []);
40+
41+
return (
42+
<div className="flex flex-col items-center justify-center py-16 gap-8 animate-in fade-in duration-500">
43+
{/* Pulse icon */}
44+
<div className="relative">
45+
<div className="absolute inset-0 rounded-full bg-blue-500/20 animate-ping" />
46+
<div className="relative flex h-16 w-16 items-center justify-center rounded-full bg-blue-500/10 border border-blue-500/20">
47+
<Activity size={28} className="text-blue-400" />
48+
</div>
49+
</div>
50+
51+
{/* Title */}
52+
<div className="text-center space-y-2">
53+
<h2 className="text-lg font-semibold text-white">
54+
Running Status Checks{dots}
55+
</h2>
56+
<p className="text-sm text-gray-500 max-w-xs">
57+
Probing {totalServices} endpoints across {serviceCategories.length}{" "}
58+
categories. This may take a few seconds.
59+
</p>
60+
</div>
61+
62+
{/* Category checklist */}
63+
<div className="w-full max-w-sm space-y-2">
64+
{serviceCategories.map((cat, idx) => {
65+
const isDone = idx < activeStep;
66+
const isCurrent = idx === activeStep;
67+
68+
return (
69+
<div
70+
key={cat.id}
71+
className={cn(
72+
"flex items-center gap-3 rounded-lg border px-4 py-2.5 transition-all duration-500",
73+
isDone &&
74+
"border-emerald-500/15 bg-emerald-500/5 text-emerald-400",
75+
isCurrent &&
76+
"border-blue-500/20 bg-blue-500/5 text-blue-400 shadow-sm shadow-blue-500/5",
77+
!isDone &&
78+
!isCurrent &&
79+
"border-white/5 bg-white/2 text-gray-600",
80+
)}
81+
>
82+
{/* Icon */}
83+
<div className="shrink-0">
84+
{isDone ? (
85+
<CheckCircle2 size={16} className="text-emerald-400" />
86+
) : isCurrent ? (
87+
<Loader2 size={16} className="animate-spin text-blue-400" />
88+
) : (
89+
<Radio size={16} className="text-gray-600" />
90+
)}
91+
</div>
92+
93+
{/* Label */}
94+
<span
95+
className={cn(
96+
"text-sm font-medium transition-colors duration-300",
97+
isDone && "text-emerald-400/80",
98+
isCurrent && "text-blue-300",
99+
!isDone && !isCurrent && "text-gray-600",
100+
)}
101+
>
102+
{cat.name}
103+
</span>
104+
105+
{/* Service count */}
106+
<span
107+
className={cn(
108+
"ml-auto text-xs tabular-nums",
109+
isDone && "text-emerald-500/50",
110+
isCurrent && "text-blue-500/50",
111+
!isDone && !isCurrent && "text-gray-700",
112+
)}
113+
>
114+
{cat.services.length}{" "}
115+
{cat.services.length === 1 ? "service" : "services"}
116+
</span>
117+
</div>
118+
);
119+
})}
120+
</div>
121+
122+
{/* Subtle footer */}
123+
<p className="text-[11px] text-gray-600 text-center">
124+
Checks run concurrently with retry &amp; rate-limit handling
125+
</p>
126+
</div>
127+
);
128+
}

src/data/services.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,15 @@ export const serviceCategories: ServiceCategory[] = [
164164
name: "Lambda",
165165
url: "https://lambda.fivem.net",
166166
description: "lambda.fivem.net — validation endpoint",
167-
acceptRange: true,
167+
validateResponse: (_status, body) => {
168+
// Lambda returns 503 but is operational if it has a valid version field
169+
try {
170+
const json = JSON.parse(body);
171+
return typeof json.version === "string" && json.version.length > 0;
172+
} catch {
173+
return false;
174+
}
175+
},
168176
},
169177
{
170178
id: "idms",

0 commit comments

Comments
 (0)