Rebuild every page on a shared set of twui-based primitives with a dense ops-console look, WireGuard red accent and light/dark/system theming. - Add design tokens (WireGuard red accent, zinc neutrals, theme-flipping semantic colours) and a no-flash theme cookie + toggle - Add shared components: page header, panel, sub-nav, data table with mobile card list, stat tile, status dot, key-value list, copy button, inline alert, empty state, form section/actions, confirm dialog and toast providers - New admin shell (sidebar, sticky header, mobile drawer) and a centered shell for auth and 404; strip the public template pages - Unify adding clients at /admin/clients/add with a host picker; tabbed client detail (Overview / Rules / Config & QR) with config copy/download - Re-run client setup after rule changes on the detail page so the firewall matches the DB - Split Setup into status/maintenance/firewall and Settings into profile/password subpages - Replace window.confirm/alert and page reloads with in-app dialogs, toasts and in-place list updates - Fix nested rule form submitting the client form, prefilled signup passwords, hidden submit buttons, fields not updating after "next free" lookups, and TinyMCE white-on-white in dark mode Co-Authored-By: Claude Opus 5.5 <[email protected]>
73 lines
2.8 KiB
TypeScript
73 lines
2.8 KiB
TypeScript
import { RotateCcw, Wrench } from "lucide-react";
|
|
import fetchApi from "@/src/components/twui/utils/fetch/fetchApi";
|
|
import Panel from "@/src/components/general/panel";
|
|
import type { ApiReqParams } from "@/src/types";
|
|
import type { APIResponseObject } from "@moduletrace/bunext/types";
|
|
import type useSystemSetupStatus from "../(hooks)/use-system-setup-status";
|
|
import SetupActionRow from "../(partials)/setup-action-row";
|
|
import SetupUpdateWgUiAction from "../(partials)/setup-update-wg-ui-action";
|
|
|
|
type Props = {
|
|
setup: ReturnType<typeof useSystemSetupStatus>;
|
|
};
|
|
|
|
const WG_TOOL_COMMANDS = [`wg`, `wg-quick`, `ip`, `curl`];
|
|
|
|
export default function SetupActionsSection({ setup }: Props) {
|
|
const setup_status = setup.setup_status;
|
|
|
|
if (!setup_status) {
|
|
return null;
|
|
}
|
|
|
|
const have_wg_tools = setup_status.tools
|
|
.filter((tool) => WG_TOOL_COMMANDS.includes(tool.command))
|
|
.every((tool) => tool.installed);
|
|
|
|
const show_restart = !setup_status.is_dev && setup_status.init_system !== "unknown";
|
|
|
|
return (
|
|
<Panel flush>
|
|
<SetupActionRow
|
|
title="WireGuard tools"
|
|
description="Installs or updates wg, wg-quick and iproute2 with your distro's package manager. Safe to re-run."
|
|
icon={<Wrench size={15} />}
|
|
button_title={have_wg_tools ? "Update tools" : "Install tools"}
|
|
on_run={async () => {
|
|
const res = await fetchApi<ApiReqParams, APIResponseObject>(
|
|
`/api/admin/setup-wireguard-tools`,
|
|
{ method: "POST" },
|
|
);
|
|
setup.refresh();
|
|
return res;
|
|
}}
|
|
/>
|
|
|
|
<SetupUpdateWgUiAction setup={setup} />
|
|
|
|
{show_restart ? (
|
|
<SetupActionRow
|
|
title="Restart service"
|
|
description={`Restarts the ${setup_status.service_name} system service. Use after manual changes.`}
|
|
icon={<RotateCcw size={15} />}
|
|
button_title="Restart"
|
|
confirm_params={{
|
|
title: "Restart wg-ui?",
|
|
message: `The ${setup_status.service_name} service restarts and this dashboard goes briefly offline.`,
|
|
confirm_label: "Restart service",
|
|
tone: "danger",
|
|
}}
|
|
on_run={async () => {
|
|
const res = await fetchApi<ApiReqParams, APIResponseObject>(
|
|
`/api/admin/restart-wg-ui-service`,
|
|
{ method: "POST" },
|
|
);
|
|
setup.refresh();
|
|
return res;
|
|
}}
|
|
/>
|
|
) : null}
|
|
</Panel>
|
|
);
|
|
}
|