refactor front end hooks

This commit is contained in:
miloschwartz
2026-02-09 20:50:36 -08:00
parent 10be9bcd56
commit 69c2212ea0
27 changed files with 82 additions and 183 deletions

View File

@@ -46,7 +46,7 @@ import IdpTypeBadge from "@app/components/IdpTypeBadge";
import { useTranslations } from "next-intl";
import { AxiosResponse } from "axios";
import { ListRolesResponse } from "@server/routers/role";
import AutoProvisionConfigWidget from "@app/components/private/AutoProvisionConfigWidget";
import AutoProvisionConfigWidget from "@app/components/AutoProvisionConfigWidget";
export default function GeneralPage() {
const { env } = useEnvContext();

View File

@@ -1,6 +1,6 @@
"use client";
import AutoProvisionConfigWidget from "@app/components/private/AutoProvisionConfigWidget";
import AutoProvisionConfigWidget from "@app/components/AutoProvisionConfigWidget";
import {
SettingsContainer,
SettingsSection,

View File

@@ -2,7 +2,7 @@ import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies";
import { AxiosResponse } from "axios";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import IdpTable, { IdpRow } from "@app/components/private/OrgIdpTable";
import IdpTable, { IdpRow } from "@app/components/OrgIdpTable";
import { getTranslations } from "next-intl/server";
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";

View File

@@ -23,9 +23,6 @@ import {
} from "@server/routers/remoteExitNode/types";
import { useRemoteExitNodeContext } from "@app/hooks/useRemoteExitNodeContext";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import { useSubscriptionStatusContext } from "@app/hooks/useSubscriptionStatusContext";
import { useLicenseStatusContext } from "@app/hooks/useLicenseStatusContext";
import { build } from "@server/build";
import {
InfoSection,
InfoSectionContent,
@@ -36,6 +33,8 @@ import CopyToClipboard from "@app/components/CopyToClipboard";
import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
import { InfoIcon } from "lucide-react";
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
export default function CredentialsPage() {
const { env } = useEnvContext();
@@ -45,6 +44,8 @@ export default function CredentialsPage() {
const t = useTranslations();
const { remoteExitNode } = useRemoteExitNodeContext();
const { isPaidUser } = usePaidStatus();
const [modalOpen, setModalOpen] = useState(false);
const [credentials, setCredentials] =
useState<PickRemoteExitNodeDefaultsResponse | null>(null);
@@ -57,16 +58,6 @@ export default function CredentialsPage() {
const [showCredentialsAlert, setShowCredentialsAlert] = useState(false);
const [shouldDisconnect, setShouldDisconnect] = useState(true);
const { licenseStatus, isUnlocked } = useLicenseStatusContext();
const subscription = useSubscriptionStatusContext();
const isSecurityFeatureDisabled = () => {
const isEnterpriseNotLicensed = build === "enterprise" && !isUnlocked();
const isSaasNotSubscribed =
build === "saas" && !subscription?.isSubscribed();
return isEnterpriseNotLicensed || isSaasNotSubscribed;
};
const handleConfirmRegenerate = async () => {
try {
const response = await api.get<
@@ -203,7 +194,7 @@ export default function CredentialsPage() {
setShouldDisconnect(false);
setModalOpen(true);
}}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.rotateCredentials)}
>
{t("regenerateCredentialsButton")}
</Button>
@@ -212,7 +203,7 @@ export default function CredentialsPage() {
setShouldDisconnect(true);
setModalOpen(true);
}}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.rotateCredentials)}
>
{t("remoteExitNodeRegenerateAndDisconnect")}
</Button>

View File

@@ -47,7 +47,8 @@ import { ListIdpsResponse } from "@server/routers/idp";
import { useTranslations } from "next-intl";
import { build } from "@server/build";
import Image from "next/image";
import { useSubscriptionStatusContext } from "@app/hooks/useSubscriptionStatusContext";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
type UserType = "internal" | "oidc";
@@ -75,7 +76,7 @@ export default function Page() {
const api = createApiClient({ env });
const t = useTranslations();
const subscription = useSubscriptionStatusContext();
const { hasSaasSubscription } = usePaidStatus();
const [selectedOption, setSelectedOption] = useState<string | null>(
"internal"
@@ -237,7 +238,7 @@ export default function Page() {
}
async function fetchIdps() {
if (build === "saas" && !subscription?.subscribed) {
if (build === "saas" && !hasSaasSubscription(tierMatrix.orgOidc)) {
return;
}

View File

@@ -19,9 +19,6 @@ import { useTranslations } from "next-intl";
import { PickClientDefaultsResponse } from "@server/routers/client";
import { useClientContext } from "@app/hooks/useClientContext";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import { useLicenseStatusContext } from "@app/hooks/useLicenseStatusContext";
import { useSubscriptionStatusContext } from "@app/hooks/useSubscriptionStatusContext";
import { build } from "@server/build";
import {
InfoSection,
InfoSectionContent,
@@ -33,6 +30,8 @@ import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
import { InfoIcon } from "lucide-react";
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
import { OlmInstallCommands } from "@app/components/olm-install-commands";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
export default function CredentialsPage() {
const { env } = useEnvContext();
@@ -54,17 +53,7 @@ export default function CredentialsPage() {
const [showCredentialsAlert, setShowCredentialsAlert] = useState(false);
const [shouldDisconnect, setShouldDisconnect] = useState(true);
const { licenseStatus, isUnlocked } = useLicenseStatusContext();
const subscription = useSubscriptionStatusContext();
const isSecurityFeatureDisabled = () => {
const isEnterpriseNotLicensed = build === "enterprise" && !isUnlocked();
const isSaasNotSubscribed =
build === "saas" && !subscription?.isSubscribed();
return (
isEnterpriseNotLicensed || isSaasNotSubscribed || build === "oss"
);
};
const { isPaidUser } = usePaidStatus();
const handleConfirmRegenerate = async () => {
try {
@@ -191,7 +180,7 @@ export default function CredentialsPage() {
setShouldDisconnect(false);
setModalOpen(true);
}}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.rotateCredentials)}
>
{t("regenerateCredentialsButton")}
</Button>
@@ -200,7 +189,7 @@ export default function CredentialsPage() {
setShouldDisconnect(true);
setModalOpen(true);
}}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.rotateCredentials)}
>
{t("clientRegenerateAndDisconnect")}
</Button>

View File

@@ -1,5 +1,5 @@
import AuthPageBrandingForm from "@app/components/AuthPageBrandingForm";
import AuthPageSettings from "@app/components/private/AuthPageSettings";
import AuthPageSettings from "@app/components/AuthPageSettings";
import { SettingsContainer } from "@app/components/Settings";
import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies";

View File

@@ -13,14 +13,13 @@ import { ArrowUpRight, Key, User } from "lucide-react";
import Link from "next/link";
import { ColumnFilter } from "@app/components/ColumnFilter";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { useSubscriptionStatusContext } from "@app/hooks/useSubscriptionStatusContext";
import { useLicenseStatusContext } from "@app/hooks/useLicenseStatusContext";
import { build } from "@server/build";
import { Alert, AlertDescription } from "@app/components/ui/alert";
import { getSevenDaysAgo } from "@app/lib/getSevenDaysAgo";
import axios from "axios";
import { useStoredPageSize } from "@app/hooks/useStoredPageSize";
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
export default function GeneralPage() {
const router = useRouter();
@@ -28,8 +27,8 @@ export default function GeneralPage() {
const api = createApiClient(useEnvContext());
const t = useTranslations();
const { orgId } = useParams();
const subscription = useSubscriptionStatusContext();
const { isUnlocked } = useLicenseStatusContext();
const { isPaidUser } = usePaidStatus();
const [rows, setRows] = useState<any[]>([]);
const [isRefreshing, setIsRefreshing] = useState(false);
@@ -208,11 +207,7 @@ export default function GeneralPage() {
}
) => {
console.log("Date range changed:", { startDate, endDate, page, size });
if (
(build == "saas" && !subscription?.subscribed) ||
(build == "enterprise" && !isUnlocked()) ||
build === "oss"
) {
if (!isPaidUser(tierMatrix.accessLogs) || build === "oss") {
console.log(
"Access denied: subscription inactive or license locked"
);
@@ -642,11 +637,7 @@ export default function GeneralPage() {
// Row expansion props
expandable={true}
renderExpandedRow={renderExpandedRow}
disabled={
(build == "saas" && !subscription?.subscribed) ||
(build == "enterprise" && !isUnlocked()) ||
build === "oss"
}
disabled={!isPaidUser(tierMatrix.accessLogs) || build === "oss"}
/>
</>
);

View File

@@ -4,15 +4,14 @@ import { DateTimeValue } from "@app/components/DateTimePicker";
import { LogDataTable } from "@app/components/LogDataTable";
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { Alert, AlertDescription } from "@app/components/ui/alert";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { useLicenseStatusContext } from "@app/hooks/useLicenseStatusContext";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { useStoredPageSize } from "@app/hooks/useStoredPageSize";
import { useSubscriptionStatusContext } from "@app/hooks/useSubscriptionStatusContext";
import { toast } from "@app/hooks/useToast";
import { createApiClient } from "@app/lib/api";
import { getSevenDaysAgo } from "@app/lib/getSevenDaysAgo";
import { build } from "@server/build";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
import { ColumnDef } from "@tanstack/react-table";
import axios from "axios";
import { Key, User } from "lucide-react";
@@ -26,8 +25,8 @@ export default function GeneralPage() {
const t = useTranslations();
const { orgId } = useParams();
const searchParams = useSearchParams();
const subscription = useSubscriptionStatusContext();
const { isUnlocked } = useLicenseStatusContext();
const { isPaidUser } = usePaidStatus();
const [rows, setRows] = useState<any[]>([]);
const [isRefreshing, setIsRefreshing] = useState(false);
@@ -195,10 +194,7 @@ export default function GeneralPage() {
}
) => {
console.log("Date range changed:", { startDate, endDate, page, size });
if (
(build == "saas" && !subscription?.subscribed) ||
(build == "enterprise" && !isUnlocked())
) {
if (!isPaidUser(tierMatrix.actionLogs)) {
console.log(
"Access denied: subscription inactive or license locked"
);
@@ -496,11 +492,7 @@ export default function GeneralPage() {
// Row expansion props
expandable={true}
renderExpandedRow={renderExpandedRow}
disabled={
(build == "saas" && !subscription?.subscribed) ||
(build == "enterprise" && !isUnlocked()) ||
build === "oss"
}
disabled={!isPaidUser(tierMatrix.actionLogs) || build === "oss"}
/>
</>
);

View File

@@ -1,54 +1,3 @@
"use client";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import AuthPageSettings, {
AuthPageSettingsRef
} from "@app/components/private/AuthPageSettings";
import { Button } from "@app/components/ui/button";
import { useOrgContext } from "@app/hooks/useOrgContext";
import { userOrgUserContext } from "@app/hooks/useOrgUserContext";
import { toast } from "@app/hooks/useToast";
import { useState, useRef } from "react";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { createApiClient } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { formatAxiosError } from "@app/lib/api";
import { AxiosResponse } from "axios";
import { DeleteOrgResponse, ListUserOrgsResponse } from "@server/routers/org";
import { useRouter } from "next/navigation";
import {
SettingsContainer,
SettingsSection,
SettingsSectionHeader,
SettingsSectionTitle,
SettingsSectionDescription,
SettingsSectionBody,
SettingsSectionForm,
SettingsSectionFooter
} from "@app/components/Settings";
import { useUserContext } from "@app/hooks/useUserContext";
import { useTranslations } from "next-intl";
import { build } from "@server/build";
export default function GeneralPage() {
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const router = useRouter();
const api = createApiClient(useEnvContext());
const t = useTranslations();
const { env } = useEnvContext();
return <p>dfas</p>;
return null;
}

View File

@@ -50,9 +50,6 @@ import { useActionState, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import z from "zod";
import { build } from "@server/build";
import { useLicenseStatusContext } from "@app/hooks/useLicenseStatusContext";
import { useSubscriptionStatusContext } from "@app/hooks/useSubscriptionStatusContext";
import { Alert, AlertDescription } from "@app/components/ui/alert";
import { RadioGroup, RadioGroupItem } from "@app/components/ui/radio-group";
import {
@@ -64,6 +61,7 @@ import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
import { GetResourceResponse } from "@server/routers/resource/getResource";
import type { ResourceContextType } from "@app/contexts/resourceContext";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
type MaintenanceSectionFormProps = {
resource: GetResourceResponse;
@@ -77,8 +75,6 @@ function MaintenanceSectionForm({
const { env } = useEnvContext();
const t = useTranslations();
const api = createApiClient({ env });
const { isUnlocked } = useLicenseStatusContext();
const subscription = useSubscriptionStatusContext();
const { isPaidUser } = usePaidStatus();
const MaintenanceFormSchema = z.object({
@@ -159,15 +155,6 @@ function MaintenanceSectionForm({
}
}
const isSecurityFeatureDisabled = () => {
const isEnterpriseNotLicensed = build === "enterprise" && !isUnlocked();
const isSaasNotSubscribed =
build === "saas" && !subscription?.isSubscribed();
return (
isEnterpriseNotLicensed || isSaasNotSubscribed || build === "oss"
);
};
if (!resource.http) {
return null;
}
@@ -197,7 +184,7 @@ function MaintenanceSectionForm({
name="maintenanceModeEnabled"
render={({ field }) => {
const isDisabled =
isSecurityFeatureDisabled() ||
isPaidUser(tierMatrix.maintencePage) ||
resource.http === false;
return (
@@ -264,7 +251,7 @@ function MaintenanceSectionForm({
defaultValue={
field.value
}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.maintencePage)}
className="flex flex-col space-y-1"
>
<FormItem className="flex items-start space-x-3 space-y-0">
@@ -337,7 +324,7 @@ function MaintenanceSectionForm({
<FormControl>
<Input
{...field}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.maintencePage)}
placeholder="We'll be back soon!"
/>
</FormControl>
@@ -363,7 +350,7 @@ function MaintenanceSectionForm({
<Textarea
{...field}
rows={4}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.maintencePage)}
placeholder={t(
"maintenancePageMessagePlaceholder"
)}
@@ -392,7 +379,7 @@ function MaintenanceSectionForm({
<FormControl>
<Input
{...field}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.maintencePage)}
placeholder={t(
"maintenanceTime"
)}

View File

@@ -20,9 +20,6 @@ import { PickSiteDefaultsResponse } from "@server/routers/site";
import { useSiteContext } from "@app/hooks/useSiteContext";
import { generateKeypair } from "../wireguardConfig";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import { useLicenseStatusContext } from "@app/hooks/useLicenseStatusContext";
import { useSubscriptionStatusContext } from "@app/hooks/useSubscriptionStatusContext";
import { build } from "@server/build";
import {
InfoSection,
InfoSectionContent,
@@ -40,6 +37,8 @@ import {
import { QRCodeCanvas } from "qrcode.react";
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
import { NewtSiteInstallCommands } from "@app/components/newt-install-commands";
import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
export default function CredentialsPage() {
const { env } = useEnvContext();
@@ -65,17 +64,7 @@ export default function CredentialsPage() {
const [loadingDefaults, setLoadingDefaults] = useState(false);
const [shouldDisconnect, setShouldDisconnect] = useState(true);
const { licenseStatus, isUnlocked } = useLicenseStatusContext();
const subscription = useSubscriptionStatusContext();
const isSecurityFeatureDisabled = () => {
const isEnterpriseNotLicensed = build === "enterprise" && !isUnlocked();
const isSaasNotSubscribed =
build === "saas" && !subscription?.isSubscribed();
return (
isEnterpriseNotLicensed || isSaasNotSubscribed || build === "oss"
);
};
const { isPaidUser } = usePaidStatus();
// Fetch site defaults for wireguard sites to show in obfuscated config
useEffect(() => {
@@ -279,7 +268,7 @@ export default function CredentialsPage() {
setShouldDisconnect(false);
setModalOpen(true);
}}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.rotateCredentials)}
>
{t("regenerateCredentialsButton")}
</Button>
@@ -288,7 +277,7 @@ export default function CredentialsPage() {
setShouldDisconnect(true);
setModalOpen(true);
}}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.rotateCredentials)}
>
{t("siteRegenerateAndDisconnect")}
</Button>
@@ -389,7 +378,7 @@ export default function CredentialsPage() {
<SettingsSectionFooter>
<Button
onClick={() => setModalOpen(true)}
disabled={isSecurityFeatureDisabled()}
disabled={isPaidUser(tierMatrix.rotateCredentials)}
>
{t("siteRegenerateAndDisconnect")}
</Button>

View File

@@ -14,7 +14,7 @@ import {
LoadLoginPageResponse
} from "@server/routers/loginPage/types";
import { GetSessionTransferTokenRenponse } from "@server/routers/auth/types";
import ValidateSessionTransferToken from "@app/components/private/ValidateSessionTransferToken";
import ValidateSessionTransferToken from "@app/components/ValidateSessionTransferToken";
import { isOrgSubscribed } from "@app/lib/api/isOrgSubscribed";
import { OrgSelectionForm } from "@app/components/OrgSelectionForm";
import OrgLoginPage from "@app/components/OrgLoginPage";

View File

@@ -5,7 +5,7 @@ import { ThemeProvider } from "@app/providers/ThemeProvider";
import EnvProvider from "@app/providers/EnvProvider";
import { pullEnv } from "@app/lib/pullEnv";
import ThemeDataProvider from "@app/providers/ThemeDataProvider";
import SplashImage from "@app/components/private/SplashImage";
import SplashImage from "@app/components/SplashImage";
import SupportStatusProvider from "@app/providers/SupporterStatusProvider";
import { priv } from "@app/lib/api";
import { AxiosResponse } from "axios";