feat: add React UI for rpm.lair.cafe
Some checks failed
poll-upstream / check (push) Successful in 1s
deploy-ui / build-and-deploy (push) Failing after 19s

- Vite + React + SWC + TypeScript SPA with react-router and
  react-bootstrap
- Dark/light/system theme with Bootstrap 5.3 data-bs-theme
- Home page with repo setup instructions and copyable code blocks
- Package list and detail pages driven by packages.json
- Python script to generate packages.json from repodata XML
- Nginx config updated for SPA fallback, asset caching, removed
  autoindex
- New deploy-ui workflow triggered on ui/ or nginx config changes,
  requires runners with nvm label
- packages.json generation added to publish job after createrepo_c
- Runner setup docs for nvm and sequoia-sq added to readme

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-27 12:55:38 +03:00
parent a6cebc76ba
commit 7f9e857695
23 changed files with 2577 additions and 4 deletions

View File

@@ -0,0 +1,36 @@
import { useEffect, useState } from "react";
import type { PackagesManifest } from "../types/packages.ts";
const MANIFEST_URL = "/fedora/43/x86_64/packages.json";
export function usePackages() {
const [manifest, setManifest] = useState<PackagesManifest | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
let cancelled = false;
fetch(MANIFEST_URL)
.then((res) => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json() as Promise<PackagesManifest>;
})
.then((data) => {
if (!cancelled) setManifest(data);
})
.catch((err: unknown) => {
if (!cancelled)
setError(err instanceof Error ? err.message : String(err));
})
.finally(() => {
if (!cancelled) setLoading(false);
});
return () => {
cancelled = true;
};
}, []);
return { manifest, loading, error };
}