mirror of
https://github.com/Buriburizaem0n/admin-frontend-domain.git
synced 2026-09-19 09:40:13 +00:00
feat: custom domain management, responsive server layout, and config editor integration
This commit is contained in:
+6
-3
@@ -29,12 +29,15 @@
|
||||
"typescript/no-unnecessary-type-constraint": "error",
|
||||
"typescript/no-unsafe-function-type": "error",
|
||||
"react/rules-of-hooks": "error",
|
||||
"react/exhaustive-deps": "warn",
|
||||
"typescript/no-explicit-any": "off",
|
||||
"react/only-export-components": "off",
|
||||
// React Compiler lint stays opt-in until the compiler is adopted.
|
||||
"react/react-compiler": "off"
|
||||
"react/immutability": "off",
|
||||
"react/set-state-in-effect": "off",
|
||||
"react/incompatible-library": "off",
|
||||
"react/refs": "off"
|
||||
},
|
||||
|
||||
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
|
||||
Generated
+3120
-2853
File diff suppressed because it is too large
Load Diff
@@ -87,14 +87,13 @@ export const BatchEditNoteIcon: React.FC<BatchEditNoteIconProps> = ({
|
||||
// For batch, usually we only override if they typed something.
|
||||
// We can provide a checkbox or just update if not empty.
|
||||
// Let's just update if not empty for safety.
|
||||
let updatePayload = { ...server }
|
||||
if (values.note && values.note.trim() !== "") {
|
||||
updatePayload.note = values.note
|
||||
}
|
||||
if (values.public_note && values.public_note.trim() !== "") {
|
||||
updatePayload.public_note = values.public_note
|
||||
const updatePayload = {
|
||||
...server,
|
||||
note: values.note && values.note.trim() !== "" ? values.note : server.note,
|
||||
public_note: values.public_note && values.public_note.trim() !== "" ? values.public_note : server.public_note,
|
||||
}
|
||||
|
||||
|
||||
// Clean up non-API fields
|
||||
return updateServer(id, {
|
||||
name: updatePayload.name,
|
||||
|
||||
+16
-2
@@ -62,7 +62,14 @@ const resources = {
|
||||
}
|
||||
|
||||
const getStoredLanguage = () => {
|
||||
return localStorage.getItem("language") || "en-US"
|
||||
try {
|
||||
if (typeof window !== "undefined" && window.localStorage) {
|
||||
return window.localStorage.getItem("language") || "en-US"
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return "en-US"
|
||||
}
|
||||
|
||||
i18n.use(initReactI18next).init({
|
||||
@@ -75,7 +82,14 @@ i18n.use(initReactI18next).init({
|
||||
})
|
||||
|
||||
i18n.on("languageChanged", (lng) => {
|
||||
localStorage.setItem("language", lng)
|
||||
try {
|
||||
if (typeof window !== "undefined" && window.localStorage) {
|
||||
window.localStorage.setItem("language", lng)
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
export default i18n
|
||||
|
||||
+4
-3
@@ -129,10 +129,10 @@ export default function NATPage() {
|
||||
|
||||
return (
|
||||
<div className="px-3">
|
||||
<div className="flex mt-6 mb-4">
|
||||
<h1 className="flex-1 text-3xl font-bold tracking-tight"> {t("NATT")}</h1>
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between w-full gap-4 mt-6 mb-4">
|
||||
<h1 className="text-3xl font-bold tracking-tight shrink-0">{t("NATT")}</h1>
|
||||
<HeaderButtonGroup
|
||||
className="flex ml-auto self-end sm:self-auto gap-2 flex-wrap shrink-0"
|
||||
className="flex items-center gap-2 flex-wrap shrink-0 sm:ml-auto"
|
||||
delete={{
|
||||
fn: deleteNAT,
|
||||
id: selectedRows.map((r) => r.original.id!),
|
||||
@@ -143,6 +143,7 @@ export default function NATPage() {
|
||||
</HeaderButtonGroup>
|
||||
</div>
|
||||
|
||||
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
|
||||
@@ -198,10 +198,10 @@ export default function ServerPage() {
|
||||
|
||||
return (
|
||||
<div className="px-3">
|
||||
<div className="flex mt-6 mb-4">
|
||||
<h1 className="text-3xl font-bold tracking-tight">{t("Server")}</h1>
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between w-full gap-4 mt-6 mb-4">
|
||||
<h1 className="text-3xl font-bold tracking-tight shrink-0">{t("Server")}</h1>
|
||||
<HeaderButtonGroup
|
||||
className="flex-2 flex ml-auto gap-2"
|
||||
className="flex items-center gap-2 flex-wrap shrink-0 sm:ml-auto"
|
||||
delete={{
|
||||
fn: deleteServer,
|
||||
id: selectedRows.map((r) => r.original.id).filter(Boolean) as number[],
|
||||
@@ -254,6 +254,7 @@ export default function ServerPage() {
|
||||
<InstallCommandsMenu className="shadow-[inset_0_1px_0_rgba(255,255,255,0.2)] bg-blue-700 text-white hover:bg-blue-600 dark:hover:bg-blue-800 rounded-lg" />
|
||||
</HeaderButtonGroup>
|
||||
</div>
|
||||
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
|
||||
@@ -69,9 +69,11 @@ const settingFormSchema = z.object({
|
||||
admin_email: asOptionalField(z.string()),
|
||||
domain_expiry_notification_days: asOptionalField(z.string()),
|
||||
server_expiry_notification_days: asOptionalField(z.string()),
|
||||
expiry_notification_group_id: z.coerce.number().int().min(0),
|
||||
expiry_notification_group_id: asOptionalField(z.coerce.number().int().min(0)),
|
||||
enable_mcp: asOptionalField(z.boolean()),
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
export default function SettingsPage() {
|
||||
|
||||
Reference in New Issue
Block a user