From 757b735d98fdaa29f924e1085ac25baff5392c9b Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Sat, 20 Dec 2025 22:29:22 -0500 Subject: [PATCH] separate maintenance section --- .../resources/proxy/[niceId]/general/page.tsx | 649 ++++++++++-------- 1 file changed, 373 insertions(+), 276 deletions(-) diff --git a/src/app/[orgId]/settings/resources/proxy/[niceId]/general/page.tsx b/src/app/[orgId]/settings/resources/proxy/[niceId]/general/page.tsx index 88bf77c9..897c5d00 100644 --- a/src/app/[orgId]/settings/resources/proxy/[niceId]/general/page.tsx +++ b/src/app/[orgId]/settings/resources/proxy/[niceId]/general/page.tsx @@ -61,6 +61,363 @@ import { TooltipTrigger } from "@app/components/ui/tooltip"; import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert"; +import { GetResourceResponse } from "@server/routers/resource/getResource"; +import type { ResourceContextType } from "@app/contexts/resourceContext"; + +type MaintenanceSectionFormProps = { + resource: GetResourceResponse; + updateResource: ResourceContextType["updateResource"]; +}; + +function MaintenanceSectionForm({ + resource, + updateResource +}: MaintenanceSectionFormProps) { + const { env } = useEnvContext(); + const t = useTranslations(); + const api = createApiClient({ env }); + const { isUnlocked } = useLicenseStatusContext(); + const subscription = useSubscriptionStatusContext(); + + const MaintenanceFormSchema = z.object({ + maintenanceModeEnabled: z.boolean().optional(), + maintenanceModeType: z.enum(["forced", "automatic"]).optional(), + maintenanceTitle: z.string().max(255).optional(), + maintenanceMessage: z.string().max(2000).optional(), + maintenanceEstimatedTime: z.string().max(100).optional() + }); + + const maintenanceForm = useForm({ + resolver: zodResolver(MaintenanceFormSchema), + defaultValues: { + maintenanceModeEnabled: resource.maintenanceModeEnabled || false, + maintenanceModeType: resource.maintenanceModeType || "automatic", + maintenanceTitle: + resource.maintenanceTitle || "We'll be back soon!", + maintenanceMessage: + resource.maintenanceMessage || + "We are currently performing scheduled maintenance. Please check back soon.", + maintenanceEstimatedTime: resource.maintenanceEstimatedTime || "" + }, + mode: "onChange" + }); + + const isMaintenanceEnabled = maintenanceForm.watch( + "maintenanceModeEnabled" + ); + const maintenanceModeType = maintenanceForm.watch("maintenanceModeType"); + + const [, maintenanceFormAction, maintenanceSaveLoading] = useActionState( + onMaintenanceSubmit, + null + ); + + async function onMaintenanceSubmit() { + const isValid = await maintenanceForm.trigger(); + if (!isValid) return; + + const data = maintenanceForm.getValues(); + + const res = await api + .post>( + `resource/${resource?.resourceId}`, + { + maintenanceModeEnabled: data.maintenanceModeEnabled, + maintenanceModeType: data.maintenanceModeType, + maintenanceTitle: data.maintenanceTitle || null, + maintenanceMessage: data.maintenanceMessage || null, + maintenanceEstimatedTime: + data.maintenanceEstimatedTime || null + } + ) + .catch((e) => { + toast({ + variant: "destructive", + title: t("resourceErrorUpdate"), + description: formatAxiosError( + e, + t("resourceErrorUpdateDescription") + ) + }); + }); + + if (res && res.status === 200) { + updateResource({ + maintenanceModeEnabled: data.maintenanceModeEnabled, + maintenanceModeType: data.maintenanceModeType, + maintenanceTitle: data.maintenanceTitle || null, + maintenanceMessage: data.maintenanceMessage || null, + maintenanceEstimatedTime: data.maintenanceEstimatedTime || null + }); + + toast({ + title: t("resourceUpdated"), + description: t("resourceUpdatedDescription") + }); + } + } + + const isSecurityFeatureDisabled = () => { + const isEnterpriseNotLicensed = build === "enterprise" && !isUnlocked(); + const isSaasNotSubscribed = + build === "saas" && !subscription?.isSubscribed(); + return isEnterpriseNotLicensed || isSaasNotSubscribed; + }; + + return ( + + + + {t("maintenanceMode")} + + + {t("maintenanceModeDescription")} + + + + + +
+ + + { + const isDisabled = + isSecurityFeatureDisabled(); + + return ( + +
+ + + + +
+ { + if ( + !isDisabled + ) { + maintenanceForm.setValue( + "maintenanceModeEnabled", + val + ); + } + }} + /> +
+
+
+
+
+
+ +
+ ); + }} + /> + + {isMaintenanceEnabled && ( +
+ ( + + + {t("maintenanceModeType")} + + + + + + + +
+ + + {t( + "automatic" + )} + {" "} + ( + {t( + "recommended" + )} + ) + + + {t( + "automaticModeDescription" + )} + +
+
+ + + + +
+ + + {t( + "forced" + )} + + + + {t( + "forcedModeDescription" + )} + +
+
+
+
+ +
+ )} + /> + + {maintenanceModeType === "forced" && ( + + + + {t("forcedeModeWarning")} + + + )} + + ( + + + {t("pageTitle")} + + + + + + {t("pageTitleDescription")} + + + + )} + /> + + ( + + + {t( + "maintenancePageMessage" + )} + + +