feat: update Setup Wizard for Gitea tokens and URLs

This commit is contained in:
plenarius
2026-04-20 23:06:55 -04:00
parent b85f70dc95
commit 2a97af5ce8
+48 -18
View File
@@ -5,7 +5,7 @@ import { api } from "../services/api";
const STEP_NAMES = [ const STEP_NAMES = [
"Welcome", "Welcome",
"Prerequisites", "Prerequisites",
"GitHub PAT", "Gitea Token",
"Workspace", "Workspace",
"NWN Home", "NWN Home",
"Fork Repos", "Fork Repos",
@@ -118,7 +118,7 @@ function WelcomeStep({ onNext }: StepProps) {
Welcome to Layonara Forge Welcome to Layonara Forge
</h2> </h2>
<p className="mt-4" style={{ color: "var(--forge-text-secondary)" }}> <p className="mt-4" style={{ color: "var(--forge-text-secondary)" }}>
This wizard will walk you through setting up your local NWN development environment &mdash; Docker, GitHub This wizard will walk you through setting up your local NWN development environment &mdash; Docker, Gitea
access, workspace initialization, repository cloning, and database seeding. access, workspace initialization, repository cloning, and database seeding.
</p> </p>
<div className="mt-8"> <div className="mt-8">
@@ -183,8 +183,8 @@ function PrerequisitesStep({ onNext, onBack }: StepProps) {
); );
} }
function GitHubPatStep({ onNext, onBack }: StepProps) { function GiteaTokenStep({ onNext, onBack }: StepProps) {
const [pat, setPat] = useState(""); const [token, setToken] = useState("");
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [error, setError] = useState(""); const [error, setError] = useState("");
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@@ -193,9 +193,9 @@ function GitHubPatStep({ onNext, onBack }: StepProps) {
setLoading(true); setLoading(true);
setError(""); setError("");
try { try {
const { login } = await api.github.validatePat(pat); const { login } = await api.github.validatePat(token);
setUsername(login); setUsername(login);
await api.workspace.updateConfig({ githubPat: pat }); await api.workspace.updateConfig({ githubPat: token });
} catch (err) { } catch (err) {
setError(err instanceof Error ? err.message : "Validation failed"); setError(err instanceof Error ? err.message : "Validation failed");
} finally { } finally {
@@ -206,17 +206,25 @@ function GitHubPatStep({ onNext, onBack }: StepProps) {
return ( return (
<div> <div>
<h2 className="text-xl font-bold" style={{ color: "var(--forge-text)" }}> <h2 className="text-xl font-bold" style={{ color: "var(--forge-text)" }}>
GitHub Personal Access Token Gitea Access Token
</h2> </h2>
<p className="mt-2 text-sm" style={{ color: "var(--forge-text-secondary)" }}> <p className="mt-2 text-sm" style={{ color: "var(--forge-text-secondary)" }}>
A PAT with <code>repo</code> scope is needed to fork and push to Layonara repositories. A Gitea token is needed to fork and push to Layonara repositories. Generate one at{" "}
<a
href="https://gitea.layonara.com/user/settings/applications"
target="_blank"
rel="noreferrer"
style={{ color: "var(--forge-accent)" }}
>
gitea.layonara.com/user/settings/applications
</a>
</p> </p>
<div className="mt-4 flex gap-2"> <div className="mt-4 flex gap-2">
<input <input
type="password" type="password"
value={pat} value={token}
onChange={(e) => setPat(e.target.value)} onChange={(e) => setToken(e.target.value)}
placeholder="ghp_..." placeholder="Enter your Gitea token"
className="flex-1 rounded px-3 py-2 text-sm" className="flex-1 rounded px-3 py-2 text-sm"
style={{ style={{
backgroundColor: "var(--forge-bg)", backgroundColor: "var(--forge-bg)",
@@ -226,7 +234,7 @@ function GitHubPatStep({ onNext, onBack }: StepProps) {
/> />
<button <button
onClick={validate} onClick={validate}
disabled={!pat || loading} disabled={!token || loading}
className="rounded px-4 py-2 text-sm font-semibold disabled:opacity-40" className="rounded px-4 py-2 text-sm font-semibold disabled:opacity-40"
style={{ backgroundColor: "var(--forge-accent)", color: "#000" }} style={{ backgroundColor: "var(--forge-accent)", color: "#000" }}
> >
@@ -328,7 +336,7 @@ function NwnHomeStep({ onNext, onBack }: StepProps) {
} }
function ForkReposStep({ onNext, onBack }: StepProps) { function ForkReposStep({ onNext, onBack }: StepProps) {
const repos = ["nwn-module", "nwn-haks", "unified"]; const forkableRepos = ["nwn-module", "nwn-haks"];
const [forkStatus, setForkStatus] = useState<Record<string, "idle" | "forking" | "forked" | "error">>({}); const [forkStatus, setForkStatus] = useState<Record<string, "idle" | "forking" | "forked" | "error">>({});
const [errors, setErrors] = useState<Record<string, string>>({}); const [errors, setErrors] = useState<Record<string, string>>({});
@@ -361,10 +369,10 @@ function ForkReposStep({ onNext, onBack }: StepProps) {
Fork Repositories Fork Repositories
</h2> </h2>
<p className="mt-2 text-sm" style={{ color: "var(--forge-text-secondary)" }}> <p className="mt-2 text-sm" style={{ color: "var(--forge-text-secondary)" }}>
Fork the Layonara repositories to your GitHub account. Fork the Layonara repositories to your Gitea account.
</p> </p>
<div className="mt-4 space-y-3"> <div className="mt-4 space-y-3">
{repos.map((repo) => ( {forkableRepos.map((repo) => (
<div <div
key={repo} key={repo}
className="flex items-center justify-between rounded p-4" className="flex items-center justify-between rounded p-4"
@@ -372,7 +380,7 @@ function ForkReposStep({ onNext, onBack }: StepProps) {
> >
<div> <div>
<p className="font-mono text-sm" style={{ color: "var(--forge-text)" }}> <p className="font-mono text-sm" style={{ color: "var(--forge-text)" }}>
Layonara/{repo} layonara/{repo}
</p> </p>
{errors[repo] && ( {errors[repo] && (
<p className="mt-1 text-xs" style={{ color: "#fca5a5" }}> <p className="mt-1 text-xs" style={{ color: "#fca5a5" }}>
@@ -394,6 +402,22 @@ function ForkReposStep({ onNext, onBack }: StepProps) {
</button> </button>
</div> </div>
))} ))}
<div
className="flex items-center justify-between rounded p-4"
style={{ backgroundColor: "var(--forge-bg)" }}
>
<div>
<p className="font-mono text-sm" style={{ color: "var(--forge-text)" }}>
plenarius/unified
</p>
<p className="mt-1 text-xs" style={{ color: "var(--forge-text-secondary)" }}>
Read-only from GitHub (no fork needed)
</p>
</div>
<span className="text-xs" style={{ color: "var(--forge-text-secondary)" }}>
Read-only
</span>
</div>
</div> </div>
<StepNav onNext={onNext} onBack={onBack} step={5} /> <StepNav onNext={onNext} onBack={onBack} step={5} />
</div> </div>
@@ -430,7 +454,8 @@ function CloneReposStep({ onNext, onBack }: StepProps) {
Clone Repositories Clone Repositories
</h2> </h2>
<p className="mt-2 text-sm" style={{ color: "var(--forge-text-secondary)" }}> <p className="mt-2 text-sm" style={{ color: "var(--forge-text-secondary)" }}>
Clone all forked repositories into the workspace. Clone all repositories into the workspace. Gitea repos clone from your fork; unified clones directly from
GitHub (public, read-only).
</p> </p>
<div className="mt-4 space-y-2"> <div className="mt-4 space-y-2">
{repos.map((repo) => ( {repos.map((repo) => (
@@ -447,6 +472,11 @@ function CloneReposStep({ onNext, onBack }: StepProps) {
<span className="font-mono text-sm" style={{ color: "var(--forge-text)" }}> <span className="font-mono text-sm" style={{ color: "var(--forge-text)" }}>
{repo} {repo}
</span> </span>
{repo === "unified" && (
<span className="text-xs" style={{ color: "var(--forge-text-secondary)" }}>
(GitHub, read-only)
</span>
)}
{errors[repo] && ( {errors[repo] && (
<span className="text-xs" style={{ color: "#fca5a5" }}> <span className="text-xs" style={{ color: "#fca5a5" }}>
{errors[repo]} {errors[repo]}
@@ -665,7 +695,7 @@ export function Setup() {
const stepComponents = [ const stepComponents = [
<WelcomeStep key="welcome" onNext={next} onBack={back} />, <WelcomeStep key="welcome" onNext={next} onBack={back} />,
<PrerequisitesStep key="prereqs" onNext={next} onBack={back} />, <PrerequisitesStep key="prereqs" onNext={next} onBack={back} />,
<GitHubPatStep key="pat" onNext={next} onBack={back} />, <GiteaTokenStep key="token" onNext={next} onBack={back} />,
<WorkspaceStep key="workspace" onNext={next} onBack={back} />, <WorkspaceStep key="workspace" onNext={next} onBack={back} />,
<NwnHomeStep key="nwnhome" onNext={next} onBack={back} />, <NwnHomeStep key="nwnhome" onNext={next} onBack={back} />,
<ForkReposStep key="fork" onNext={next} onBack={back} />, <ForkReposStep key="fork" onNext={next} onBack={back} />,