移除不需要的文件
Some checks failed
build / build (api, amd64, linux) (push) Failing after -51s
build / build (api, arm64, linux) (push) Failing after -51s
build / build (api.exe, amd64, windows) (push) Failing after -51s

This commit is contained in:
CN-JS-HuiBai
2026-04-18 20:14:03 +08:00
parent f4af50299c
commit 9d95a7c650
333 changed files with 3 additions and 498637 deletions

View File

@@ -1,284 +0,0 @@
import React, { useEffect, useState } from "../../../recovery-preview/node_modules/react/index.js";
import { requestJson } from "../../runtime/client.js";
function Wot({ children }) {
return <div className="flex h-full w-full flex-col">{children}</div>;
}
function Hot({ children }) {
return (
<div className="flex h-[var(--header-height)] flex-none items-center justify-between gap-4 bg-background p-4 md:px-8">
{children}
</div>
);
}
function zot({ children }) {
return <div className="flex-1 overflow-hidden px-4 py-6 md:px-8">{children}</div>;
}
function Card({ title, description, children }) {
return (
<div className="rounded-xl border bg-card text-card-foreground shadow">
<div className="flex flex-col space-y-1.5 p-6">
<h3 className="font-semibold leading-none tracking-tight">{title}</h3>
<p className="text-sm text-muted-foreground">{description}</p>
</div>
<div className="p-6 pt-0">{children}</div>
</div>
);
}
function Field({ label, description, children, span = 1 }) {
return (
<div className={span === 2 ? "space-y-2 md:col-span-2" : "space-y-2"}>
<label className="text-sm font-medium leading-none">{label}</label>
{children}
<p className="text-[0.8rem] text-muted-foreground">{description}</p>
</div>
);
}
const defaults = {
nebula_theme_color: "aurora",
nebula_hero_slogan: "",
nebula_welcome_target: "",
nebula_register_title: "",
nebula_background_url: "",
nebula_metrics_base_url: "",
nebula_default_theme_mode: "system",
nebula_light_logo_url: "",
nebula_dark_logo_url: "",
nebula_custom_html: "",
nebula_static_cdn_url: "",
};
const themeColorOptions = [
{ value: "aurora", label: "Aurora" },
{ value: "sunset", label: "Sunset" },
{ value: "ember", label: "Ember" },
{ value: "violet", label: "Violet" },
];
const themeModeOptions = [
{ value: "system", label: "Follow system" },
{ value: "dark", label: "Prefer dark" },
{ value: "light", label: "Prefer light" },
];
function QKt() {
const [form, setForm] = useState(defaults);
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [message, setMessage] = useState("");
const [messageType, setMessageType] = useState("");
useEffect(() => {
(async () => {
try {
const payload = await requestJson("/config/fetch?key=nebula");
const nebula = payload?.data?.nebula || payload?.nebula || {};
setForm((prev) => ({ ...prev, ...nebula }));
} catch (error) {
setMessage(error?.message || "Failed to load Nebula settings");
setMessageType("error");
} finally {
setLoading(false);
}
})();
}, []);
const updateField = (key, value) => {
setForm((prev) => ({ ...prev, [key]: value ?? "" }));
};
const save = async () => {
setSaving(true);
setMessage("");
setMessageType("");
try {
await requestJson("/config/save", { method: "POST", body: form });
setMessage("Nebula settings saved");
setMessageType("success");
} catch (error) {
setMessage(error?.message || "Failed to save Nebula settings");
setMessageType("error");
} finally {
setSaving(false);
}
};
return (
<Wot>
<Hot>
<div />
<div className="flex items-center gap-3">
<button
type="button"
className="inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow transition-colors hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-50"
onClick={save}
disabled={loading || saving}
>
{saving ? "Saving..." : "Save settings"}
</button>
</div>
</Hot>
<zot>
<div className="space-y-6">
<header className="space-y-2">
<h1 className="text-2xl font-bold tracking-tight">Nebula Theme</h1>
<p className="text-muted-foreground">
Configure Nebula theme colors, copywriting, branding assets, and custom injections.
</p>
</header>
{message ? (
<div
className={
messageType === "success"
? "rounded-lg border border-emerald-500/30 bg-emerald-500/10 px-4 py-3 text-sm text-emerald-600"
: "rounded-lg border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive"
}
>
{message}
</div>
) : null}
<Card
title="Display"
description="Set the primary color, theme mode, and hero copy shown by Nebula."
>
{loading ? (
<div className="rounded-lg border border-dashed bg-muted/30 px-4 py-8 text-sm text-muted-foreground">
Loading Nebula settings...
</div>
) : (
<div className="grid gap-4 md:grid-cols-2">
<Field label="Theme palette" description="Controls the default Nebula color palette.">
<select
className="flex h-9 w-full appearance-none rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_theme_color}
onChange={(event) => updateField("nebula_theme_color", event.target.value)}
>
{themeColorOptions.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</select>
</Field>
<Field
label="Theme mode"
description="Applied when a user opens the Nebula frontend for the first time."
>
<select
className="flex h-9 w-full appearance-none rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_default_theme_mode}
onChange={(event) =>
updateField("nebula_default_theme_mode", event.target.value)
}
>
{themeModeOptions.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</select>
</Field>
<Field label="Hero slogan" description="Shown as the main title in the hero area.">
<input
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_hero_slogan}
onChange={(event) => updateField("nebula_hero_slogan", event.target.value)}
/>
</Field>
<Field label="Welcome target" description="Appended after the Welcome to heading.">
<input
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_welcome_target}
onChange={(event) => updateField("nebula_welcome_target", event.target.value)}
/>
</Field>
<Field label="Register title" description="Displayed at the top of the register panel.">
<input
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_register_title}
onChange={(event) => updateField("nebula_register_title", event.target.value)}
/>
</Field>
<Field
label="Metrics API URL"
description="Base URL used when Nebula shows public metrics before login."
>
<input
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_metrics_base_url}
onChange={(event) => updateField("nebula_metrics_base_url", event.target.value)}
/>
</Field>
</div>
)}
</Card>
<Card
title="Branding"
description="Set background assets, logo URLs, CDN roots, and custom HTML."
>
<div className="grid gap-4 md:grid-cols-2">
<Field label="Background URL" description="Used by the Nebula login or landing background.">
<input
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_background_url}
onChange={(event) => updateField("nebula_background_url", event.target.value)}
/>
</Field>
<Field label="Static CDN URL" description="Root CDN path for Nebula static assets.">
<input
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_static_cdn_url}
onChange={(event) => updateField("nebula_static_cdn_url", event.target.value)}
/>
</Field>
<Field label="Light logo URL" description="Displayed while the light theme is active.">
<input
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_light_logo_url}
onChange={(event) => updateField("nebula_light_logo_url", event.target.value)}
/>
</Field>
<Field label="Dark logo URL" description="Displayed while the dark theme is active.">
<input
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_dark_logo_url}
onChange={(event) => updateField("nebula_dark_logo_url", event.target.value)}
/>
</Field>
<Field
label="Custom HTML / scripts"
description="Inject custom HTML, scripts, or styles into Nebula pages."
span={2}
>
<textarea
className="min-h-[220px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-xs shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
value={form.nebula_custom_html}
onChange={(event) => updateField("nebula_custom_html", event.target.value)}
/>
</Field>
</div>
</Card>
</div>
</zot>
</Wot>
);
}
export default QKt;