Files
dnsmasq-admin/app/records/_components/ApplyButton.tsx
T
siujamo 97ad09ad8a feat: add dnsmasq DNS record admin UI
- store records in SQLite via built-in node:sqlite, no native deps
- wrap DB reads in await io() so they stay out of the static shell
- add CRUD pages backed by Server Actions with per-request data
- generate managed config and restart container via Docker socket
- add /resolve page to query dnsmasq for A and CNAME records
- add Dockerfile and compose setup with shared config volume
2026-10-09 16:47:31 +08:00

38 lines
1.2 KiB
TypeScript

"use client"
import { useActionState } from "react"
import type { ActionState } from "@/lib/action-state"
export interface ApplyButtonProps {
action: (prev: ActionState, formData: FormData) => Promise<ActionState>
}
export function ApplyButton({ action }: ApplyButtonProps) {
const [state, formAction, pending] = useActionState<ActionState, FormData>(action, { ok: false })
return (
<div className="space-y-2">
<form action={formAction}>
<button
type="submit"
disabled={pending}
className="rounded-md bg-zinc-900 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-zinc-700 disabled:opacity-50 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-white">
{pending ? "应用中…" : "应用并重启 dnsmasq"}
</button>
</form>
{state.message ? (
<div className="space-y-1 text-sm">
<p
className={state.ok ? "text-emerald-700 dark:text-emerald-400" : "text-red-600 dark:text-red-400"}>
{state.message}
</p>
{state.detail ? (
<p className="text-xs text-zinc-500 dark:text-zinc-400">{state.detail}</p>
) : null}
</div>
) : null}
</div>
)
}