fix form responsiveness

This commit is contained in:
miloschwartz
2026-06-09 16:52:05 -07:00
parent 96a54fc9cc
commit bdb38db5bc
11 changed files with 672 additions and 740 deletions

View File

@@ -17,7 +17,8 @@ import {
SettingsSectionTitle, SettingsSectionTitle,
SettingsSectionDescription, SettingsSectionDescription,
SettingsSectionBody, SettingsSectionBody,
SettingsSectionFooter SettingsSectionFooter,
SettingsSectionForm
} from "@app/components/Settings"; } from "@app/components/Settings";
import { import {
InfoSection, InfoSection,
@@ -1326,8 +1327,9 @@ export default function BillingPage() {
</SettingsSectionDescription> </SettingsSectionDescription>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
<SettingsSectionForm variant="half">
<SettingsFormGrid> <SettingsFormGrid>
<SettingsFormCell span="half"> <SettingsFormCell span="full">
<div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-4 border rounded-lg p-4"> <div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-4 border rounded-lg p-4">
<div> <div>
<div className="text-sm text-muted-foreground mb-1"> <div className="text-sm text-muted-foreground mb-1">
@@ -1364,6 +1366,7 @@ export default function BillingPage() {
</div> </div>
</SettingsFormCell> </SettingsFormCell>
</SettingsFormGrid> </SettingsFormGrid>
</SettingsSectionForm>
</SettingsSectionBody> </SettingsSectionBody>
</SettingsSection> </SettingsSection>
)} )}

View File

@@ -14,6 +14,7 @@ import {
SettingsSection, SettingsSection,
SettingsSectionBody, SettingsSectionBody,
SettingsSectionDescription, SettingsSectionDescription,
SettingsSectionForm,
SettingsSectionHeader, SettingsSectionHeader,
SettingsSectionTitle SettingsSectionTitle
} from "@app/components/Settings"; } from "@app/components/Settings";
@@ -252,6 +253,7 @@ export default function Page() {
</SettingsSectionTitle> </SettingsSectionTitle>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
<SettingsSectionForm variant="half">
<Form {...form}> <Form {...form}>
<form <form
onKeyDown={(e) => { onKeyDown={(e) => {
@@ -262,7 +264,7 @@ export default function Page() {
id="create-client-form" id="create-client-form"
> >
<SettingsFormGrid> <SettingsFormGrid>
<SettingsFormCell span="quarter"> <SettingsFormCell span="half">
<FormField <FormField
control={form.control} control={form.control}
name="name" name="name"
@@ -308,11 +310,15 @@ export default function Page() {
</Button> </Button>
</SettingsFormCell> </SettingsFormCell>
{showAdvancedSettings && ( {showAdvancedSettings && (
<SettingsFormCell span="quarter"> <SettingsFormCell span="half">
<FormField <FormField
control={form.control} control={
form.control
}
name="subnet" name="subnet"
render={({ field }) => ( render={({
field
}) => (
<FormItem> <FormItem>
<FormLabel> <FormLabel>
{t( {t(
@@ -342,6 +348,7 @@ export default function Page() {
</SettingsFormGrid> </SettingsFormGrid>
</form> </form>
</Form> </Form>
</SettingsSectionForm>
</SettingsSectionBody> </SettingsSectionBody>
</SettingsSection> </SettingsSection>

View File

@@ -243,7 +243,7 @@ function ProxyResourceProtocolForm({
{proxySettingsForm.watch("proxyProtocol") && ( {proxySettingsForm.watch("proxyProtocol") && (
<> <>
<SettingsFormCell span="full"> <SettingsFormCell span="full">
<Alert className="[&>svg]:self-start"> <Alert className="[&>svg]:self-start" variant="neutral">
<AlertTriangle className="h-4 w-4" /> <AlertTriangle className="h-4 w-4" />
<AlertDescription> <AlertDescription>
<strong> <strong>

View File

@@ -1454,6 +1454,7 @@ export default function Page() {
</SettingsSectionDescription> </SettingsSectionDescription>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
<SettingsSectionForm variant="half">
<SettingsFormGrid> <SettingsFormGrid>
<SettingsFormCell span="full"> <SettingsFormCell span="full">
<SettingsSubsectionHeader> <SettingsSubsectionHeader>
@@ -1496,6 +1497,7 @@ export default function Page() {
/> />
</SettingsFormCell> </SettingsFormCell>
</SettingsFormGrid> </SettingsFormGrid>
</SettingsSectionForm>
</SettingsSectionBody> </SettingsSectionBody>
</SettingsSection> </SettingsSection>

View File

@@ -7,6 +7,7 @@ import {
SettingsSection, SettingsSection,
SettingsSectionBody, SettingsSectionBody,
SettingsSectionDescription, SettingsSectionDescription,
SettingsSectionForm,
SettingsSectionHeader, SettingsSectionHeader,
SettingsSectionTitle SettingsSectionTitle
} from "@app/components/Settings"; } from "@app/components/Settings";
@@ -507,7 +508,7 @@ export default function Page() {
/> />
</> </>
)} )}
<SettingsSectionForm variant="half">
<Form {...form}> <Form {...form}>
<form <form
onKeyDown={(e) => { onKeyDown={(e) => {
@@ -518,14 +519,14 @@ export default function Page() {
id="create-site-form" id="create-site-form"
> >
<SettingsFormGrid> <SettingsFormGrid>
<SettingsFormCell span="quarter"> <SettingsFormCell span="half">
<FormField <FormField
control={form.control} control={form.control}
name="name" name="name"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel> <FormLabel>
{t("name")} {t("name")}w
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input <Input
@@ -622,6 +623,7 @@ export default function Page() {
</SettingsFormGrid> </SettingsFormGrid>
</form> </form>
</Form> </Form>
</SettingsSectionForm>
</SettingsSectionBody> </SettingsSectionBody>
</SettingsSection> </SettingsSection>

View File

@@ -7,6 +7,7 @@ import {
SettingsSection, SettingsSection,
SettingsSectionBody, SettingsSectionBody,
SettingsSectionDescription, SettingsSectionDescription,
SettingsSectionForm,
SettingsSectionHeader, SettingsSectionHeader,
SettingsSectionTitle SettingsSectionTitle
} from "@app/components/Settings"; } from "@app/components/Settings";
@@ -200,8 +201,9 @@ export function CreatePolicyForm({}: CreatePolicyFormProps) {
</SettingsSectionDescription> </SettingsSectionDescription>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
<SettingsSectionForm variant="half">
<SettingsFormGrid> <SettingsFormGrid>
<SettingsFormCell span="quarter"> <SettingsFormCell span="half">
<FormField <FormField
control={form.control} control={form.control}
name="name" name="name"
@@ -219,6 +221,7 @@ export function CreatePolicyForm({}: CreatePolicyFormProps) {
/> />
</SettingsFormCell> </SettingsFormCell>
</SettingsFormGrid> </SettingsFormGrid>
</SettingsSectionForm>
</SettingsSectionBody> </SettingsSectionBody>
</SettingsSection> </SettingsSection>

View File

@@ -5,6 +5,7 @@ import {
SettingsSectionBody, SettingsSectionBody,
SettingsSectionDescription, SettingsSectionDescription,
SettingsSectionFooter, SettingsSectionFooter,
SettingsSectionForm,
SettingsSectionHeader, SettingsSectionHeader,
SettingsSectionTitle SettingsSectionTitle
} from "@app/components/Settings"; } from "@app/components/Settings";
@@ -148,10 +149,10 @@ function PolicyAccessRulesSectionLayout({
</SettingsSectionDescription> </SettingsSectionDescription>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
<div className="space-y-4">
{resourceOverlayMode && ( {resourceOverlayMode && (
<SharedPolicyResourceNotice section="rules" /> <SharedPolicyResourceNotice section="rules" />
)} )}
<div className="space-y-4">
<PolicyAccessRulesIntro <PolicyAccessRulesIntro
rulesEnabled={rulesEnabled} rulesEnabled={rulesEnabled}
onRulesEnabledChange={onRulesEnabledChange} onRulesEnabledChange={onRulesEnabledChange}

View File

@@ -0,0 +1,120 @@
"use client";
import {
SettingsFormCell,
SettingsFormGrid,
SettingsSubsectionDescription,
SettingsSubsectionHeader,
SettingsSubsectionTitle
} from "@app/components/Settings";
import { useTranslations } from "next-intl";
import { PolicyAuthMethodRow } from "./PolicyAuthMethodRow";
import type { PolicyAuthMethodId } from "./policy-auth-method-id";
import {
getEmailWhitelistSummary,
getHeaderAuthSummary,
getPasscodeSummary,
getPincodeSummary
} from "./policy-auth-summaries";
export type PolicyAuthOtherMethodsSectionProps = {
pinActive: boolean;
passcodeActive: boolean;
emailWhitelistEnabled: boolean;
headerAuthActive: boolean;
headerAuthUser: string;
emailCount: number;
emailEnabled: boolean;
disabled?: boolean;
onConfigure: (method: PolicyAuthMethodId) => void;
onTogglePincode: (active: boolean) => void;
onTogglePasscode: (active: boolean) => void;
onToggleEmail: (active: boolean) => void;
onToggleHeaderAuth: (active: boolean) => void;
};
export function PolicyAuthOtherMethodsSection({
pinActive,
passcodeActive,
emailWhitelistEnabled,
headerAuthActive,
headerAuthUser,
emailCount,
emailEnabled,
disabled,
onConfigure,
onTogglePincode,
onTogglePasscode,
onToggleEmail,
onToggleHeaderAuth
}: PolicyAuthOtherMethodsSectionProps) {
const t = useTranslations();
return (
<SettingsFormGrid>
<SettingsFormCell span="full">
<SettingsSubsectionHeader>
<SettingsSubsectionTitle>
{t("policyAuthOtherMethodsTitle")}
</SettingsSubsectionTitle>
<SettingsSubsectionDescription>
{t("policyAuthOtherMethodsDescription")}
</SettingsSubsectionDescription>
</SettingsSubsectionHeader>
</SettingsFormCell>
<SettingsFormCell span="full">
<div className="flex flex-col gap-3">
<PolicyAuthMethodRow
id="pincode"
title={t("policyAuthPincodeTitle")}
description={t("policyAuthPincodeDescription")}
summary={getPincodeSummary({ t })}
active={pinActive}
onConfigure={() => onConfigure("pincode")}
onToggle={onTogglePincode}
disabled={disabled}
/>
<PolicyAuthMethodRow
id="passcode"
title={t("policyAuthPasscodeTitle")}
description={t("policyAuthPasscodeDescription")}
summary={getPasscodeSummary({ t })}
active={passcodeActive}
onConfigure={() => onConfigure("passcode")}
onToggle={onTogglePasscode}
disabled={disabled}
/>
<PolicyAuthMethodRow
id="email"
title={t("policyAuthEmailTitle")}
description={t("policyAuthEmailDescription")}
summary={getEmailWhitelistSummary({
t,
count: emailCount
})}
active={emailWhitelistEnabled}
onConfigure={() => onConfigure("email")}
onToggle={onToggleEmail}
disabled={disabled || !emailEnabled}
/>
<PolicyAuthMethodRow
id="header-auth"
title={t("policyAuthHeaderAuthTitle")}
description={t("policyAuthHeaderAuthDescription")}
summary={getHeaderAuthSummary({
t,
headerName: headerAuthUser
})}
active={headerAuthActive}
onConfigure={() => onConfigure("headerAuth")}
onToggle={onToggleHeaderAuth}
disabled={disabled}
/>
</div>
</SettingsFormCell>
</SettingsFormGrid>
);
}

View File

@@ -1,10 +1,6 @@
"use client"; "use client";
import { import { SettingsFormCell, SettingsFormGrid } from "@app/components/Settings";
SettingsFormCell,
SettingsFormGrid,
SettingsSectionForm
} from "@app/components/Settings";
import { SwitchInput } from "@app/components/SwitchInput"; import { SwitchInput } from "@app/components/SwitchInput";
import { Button } from "@app/components/ui/button"; import { Button } from "@app/components/ui/button";
import { import {
@@ -58,7 +54,6 @@ export function PolicyAuthSsoSection({
const idpSelectDisabled = idpDisabled ?? disabled; const idpSelectDisabled = idpDisabled ?? disabled;
return ( return (
<SettingsSectionForm variant="half">
<SettingsFormGrid> <SettingsFormGrid>
<SettingsFormCell span="full"> <SettingsFormCell span="full">
<SwitchInput <SwitchInput
@@ -96,9 +91,7 @@ export function PolicyAuthSsoSection({
disabled={idpSelectDisabled} disabled={idpSelectDisabled}
onClick={() => setShowIdpSelect(true)} onClick={() => setShowIdpSelect(true)}
> >
{t( {t("policyAuthAddDefaultIdentityProvider")}
"policyAuthAddDefaultIdentityProvider"
)}
</Button> </Button>
) : ( ) : (
<FormItem> <FormItem>
@@ -113,9 +106,7 @@ export function PolicyAuthSsoSection({
setShowIdpSelect(false); setShowIdpSelect(false);
return; return;
} }
onSkipToIdpChange( onSkipToIdpChange(parseInt(value));
parseInt(value)
);
}} }}
value={ value={
skipToIdpId skipToIdpId
@@ -158,6 +149,5 @@ export function PolicyAuthSsoSection({
</> </>
)} )}
</SettingsFormGrid> </SettingsFormGrid>
</SettingsSectionForm>
); );
} }

View File

@@ -1,15 +1,11 @@
"use client"; "use client";
import { import {
SettingsFormCell,
SettingsFormGrid,
SettingsSection, SettingsSection,
SettingsSectionBody, SettingsSectionBody,
SettingsSectionDescription, SettingsSectionDescription,
SettingsSectionForm,
SettingsSectionHeader, SettingsSectionHeader,
SettingsSubsectionDescription,
SettingsSubsectionHeader,
SettingsSubsectionTitle,
SettingsSectionTitle SettingsSectionTitle
} from "@app/components/Settings"; } from "@app/components/Settings";
import { RolesSelector } from "@app/components/roles-selector"; import { RolesSelector } from "@app/components/roles-selector";
@@ -25,15 +21,9 @@ import {
PasscodeCredenza, PasscodeCredenza,
PincodeCredenza PincodeCredenza
} from "./PolicyAuthMethodCredenzas"; } from "./PolicyAuthMethodCredenzas";
import { PolicyAuthMethodRow } from "./PolicyAuthMethodRow"; import { PolicyAuthOtherMethodsSection } from "./PolicyAuthOtherMethodsSection";
import { PolicyAuthSsoSection } from "./PolicyAuthSsoSection"; import { PolicyAuthSsoSection } from "./PolicyAuthSsoSection";
import type { PolicyAuthMethodId } from "./policy-auth-method-id"; import type { PolicyAuthMethodId } from "./policy-auth-method-id";
import {
getEmailWhitelistSummary,
getHeaderAuthSummary,
getPasscodeSummary,
getPincodeSummary
} from "./policy-auth-summaries";
export type PolicyAuthStackSectionCreateProps = { export type PolicyAuthStackSectionCreateProps = {
form: UseFormReturn<PolicyFormValues, any, any>; form: UseFormReturn<PolicyFormValues, any, any>;
@@ -105,8 +95,7 @@ export function PolicyAuthStackSectionCreate({
</SettingsSectionDescription> </SettingsSectionDescription>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
<SettingsFormGrid> <SettingsSectionForm variant="half">
<SettingsFormCell span="half">
<PolicyAuthSsoSection <PolicyAuthSsoSection
sso={Boolean(sso)} sso={Boolean(sso)}
onSsoChange={(active) => onSsoChange={(active) =>
@@ -155,61 +144,27 @@ export function PolicyAuthStackSectionCreate({
/> />
} }
/> />
</SettingsFormCell>
</SettingsFormGrid>
<SettingsFormGrid> <PolicyAuthOtherMethodsSection
<SettingsFormCell span="full"> pinActive={pinActive}
<SettingsSubsectionHeader> passcodeActive={passcodeActive}
<SettingsSubsectionTitle> emailWhitelistEnabled={Boolean(emailWhitelistEnabled)}
{t("policyAuthOtherMethodsTitle")} headerAuthActive={headerAuthActive}
</SettingsSubsectionTitle> headerAuthUser={headerAuth?.user ?? ""}
<SettingsSubsectionDescription> emailCount={emails.length}
{t("policyAuthOtherMethodsDescription")} emailEnabled={emailEnabled}
</SettingsSubsectionDescription> onConfigure={setEditingMethod}
</SettingsSubsectionHeader> onTogglePincode={(active) =>
</SettingsFormCell>
<SettingsFormCell span="half">
<div className="flex flex-col gap-3">
<PolicyAuthMethodRow
id="pincode"
title={t("policyAuthPincodeTitle")}
description={t("policyAuthPincodeDescription")}
summary={getPincodeSummary({ t })}
active={pinActive}
onConfigure={() => setEditingMethod("pincode")}
onToggle={(active) =>
handleToggle("pincode", active, () => handleToggle("pincode", active, () =>
parentForm.setValue("pincode", null) parentForm.setValue("pincode", null)
) )
} }
/> onTogglePasscode={(active) =>
<PolicyAuthMethodRow
id="passcode"
title={t("policyAuthPasscodeTitle")}
description={t("policyAuthPasscodeDescription")}
summary={getPasscodeSummary({ t })}
active={passcodeActive}
onConfigure={() => setEditingMethod("passcode")}
onToggle={(active) =>
handleToggle("passcode", active, () => handleToggle("passcode", active, () =>
parentForm.setValue("password", null) parentForm.setValue("password", null)
) )
} }
/> onToggleEmail={(active) =>
<PolicyAuthMethodRow
id="email"
title={t("policyAuthEmailTitle")}
description={t("policyAuthEmailDescription")}
summary={getEmailWhitelistSummary({
t,
count: emails.length
})}
active={Boolean(emailWhitelistEnabled)}
onConfigure={() => setEditingMethod("email")}
onToggle={(active) =>
handleToggle("email", active, () => handleToggle("email", active, () =>
parentForm.setValue( parentForm.setValue(
"emailWhitelistEnabled", "emailWhitelistEnabled",
@@ -217,32 +172,13 @@ export function PolicyAuthStackSectionCreate({
) )
) )
} }
disabled={!emailEnabled} onToggleHeaderAuth={(active) =>
/>
<PolicyAuthMethodRow
id="header-auth"
title={t("policyAuthHeaderAuthTitle")}
description={t(
"policyAuthHeaderAuthDescription"
)}
summary={getHeaderAuthSummary({
t,
headerName: headerAuth?.user ?? ""
})}
active={headerAuthActive}
onConfigure={() =>
setEditingMethod("headerAuth")
}
onToggle={(active) =>
handleToggle("headerAuth", active, () => handleToggle("headerAuth", active, () =>
parentForm.setValue("headerAuth", null) parentForm.setValue("headerAuth", null)
) )
} }
/> />
</div> </SettingsSectionForm>
</SettingsFormCell>
</SettingsFormGrid>
<PincodeCredenza <PincodeCredenza
open={editingMethod === "pincode"} open={editingMethod === "pincode"}

View File

@@ -1,16 +1,12 @@
"use client"; "use client";
import { import {
SettingsFormCell,
SettingsFormGrid,
SettingsSection, SettingsSection,
SettingsSectionBody, SettingsSectionBody,
SettingsSectionDescription, SettingsSectionDescription,
SettingsSectionForm,
SettingsSectionFooter, SettingsSectionFooter,
SettingsSectionHeader, SettingsSectionHeader,
SettingsSubsectionDescription,
SettingsSubsectionHeader,
SettingsSubsectionTitle,
SettingsSectionTitle SettingsSectionTitle
} from "@app/components/Settings"; } from "@app/components/Settings";
import { import {
@@ -50,15 +46,9 @@ import {
PasscodeCredenza, PasscodeCredenza,
PincodeCredenza PincodeCredenza
} from "./PolicyAuthMethodCredenzas"; } from "./PolicyAuthMethodCredenzas";
import { PolicyAuthMethodRow } from "./PolicyAuthMethodRow"; import { PolicyAuthOtherMethodsSection } from "./PolicyAuthOtherMethodsSection";
import { PolicyAuthSsoSection } from "./PolicyAuthSsoSection"; import { PolicyAuthSsoSection } from "./PolicyAuthSsoSection";
import type { PolicyAuthMethodId } from "./policy-auth-method-id"; import type { PolicyAuthMethodId } from "./policy-auth-method-id";
import {
getEmailWhitelistSummary,
getHeaderAuthSummary,
getPasscodeSummary,
getPincodeSummary
} from "./policy-auth-summaries";
import { SharedPolicyResourceNotice } from "./SharedPolicyResourceNotice"; import { SharedPolicyResourceNotice } from "./SharedPolicyResourceNotice";
import z from "zod"; import z from "zod";
@@ -528,12 +518,10 @@ export function PolicyAuthStackSectionEdit({
</SettingsSectionDescription> </SettingsSectionDescription>
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
<div className="space-y-4">
{isResourceOverlay && ( {isResourceOverlay && (
<SharedPolicyResourceNotice section="authentication" /> <SharedPolicyResourceNotice section="authentication" />
)} )}
<SettingsFormGrid> <SettingsSectionForm variant="half">
<SettingsFormCell span="half">
<PolicyAuthSsoSection <PolicyAuthSsoSection
sso={Boolean(sso)} sso={Boolean(sso)}
onSsoChange={(active) => onSsoChange={(active) =>
@@ -553,22 +541,17 @@ export function PolicyAuthStackSectionEdit({
selectedRoles={overlayRoles} selectedRoles={overlayRoles}
onSelectRoles={(selected) => onSelectRoles={(selected) =>
setCombinedRoles( setCombinedRoles(
selected.map( selected.map((role) => ({
(role) => ({
...role, ...role,
isAdmin: isAdmin: Boolean(
Boolean(
role.isAdmin role.isAdmin
) )
}) }))
)
) )
} }
disabled={isLoading} disabled={isLoading}
restrictAdminRole restrictAdminRole
lockedIds={ lockedIds={policyRoleLockedIds}
policyRoleLockedIds
}
/> />
) : ( ) : (
<FormField <FormField
@@ -577,12 +560,8 @@ export function PolicyAuthStackSectionEdit({
render={({ field }) => ( render={({ field }) => (
<RolesSelector <RolesSelector
orgId={orgId} orgId={orgId}
selectedRoles={ selectedRoles={field.value}
field.value onSelectRoles={(selected) =>
}
onSelectRoles={(
selected
) =>
form.setValue( form.setValue(
"roles", "roles",
selected selected
@@ -600,13 +579,9 @@ export function PolicyAuthStackSectionEdit({
<UsersSelector <UsersSelector
orgId={orgId} orgId={orgId}
selectedUsers={overlayUsers} selectedUsers={overlayUsers}
onSelectUsers={ onSelectUsers={setCombinedUsers}
setCombinedUsers
}
disabled={isLoading} disabled={isLoading}
lockedIds={ lockedIds={policyUserLockedIds}
policyUserLockedIds
}
/> />
) : ( ) : (
<FormField <FormField
@@ -615,12 +590,8 @@ export function PolicyAuthStackSectionEdit({
render={({ field }) => ( render={({ field }) => (
<UsersSelector <UsersSelector
orgId={orgId} orgId={orgId}
selectedUsers={ selectedUsers={field.value}
field.value onSelectUsers={(selected) =>
}
onSelectUsers={(
selected
) =>
form.setValue( form.setValue(
"users", "users",
selected selected
@@ -633,150 +604,47 @@ export function PolicyAuthStackSectionEdit({
) )
} }
/> />
</SettingsFormCell>
</SettingsFormGrid>
<SettingsFormGrid> <PolicyAuthOtherMethodsSection
<SettingsFormCell span="full"> pinActive={pinActive}
<SettingsSubsectionHeader> passcodeActive={passcodeActive}
<SettingsSubsectionTitle> emailWhitelistEnabled={Boolean(
{t("policyAuthOtherMethodsTitle")}
</SettingsSubsectionTitle>
<SettingsSubsectionDescription>
{t(
"policyAuthOtherMethodsDescription"
)}
</SettingsSubsectionDescription>
</SettingsSubsectionHeader>
</SettingsFormCell>
<SettingsFormCell span="half">
<div className="flex flex-col gap-3">
<PolicyAuthMethodRow
id="pincode"
title={t("policyAuthPincodeTitle")}
description={t(
"policyAuthPincodeDescription"
)}
summary={getPincodeSummary({ t })}
active={pinActive}
onConfigure={() =>
openMethodEditor("pincode")
}
onToggle={(active) =>
handleToggle(
"pincode",
active,
() => {
setPinActive(false);
form.setValue(
"pincode",
null
);
}
)
}
disabled={authReadonly}
/>
<PolicyAuthMethodRow
id="passcode"
title={t("policyAuthPasscodeTitle")}
description={t(
"policyAuthPasscodeDescription"
)}
summary={getPasscodeSummary({ t })}
active={passcodeActive}
onConfigure={() =>
openMethodEditor("passcode")
}
onToggle={(active) =>
handleToggle(
"passcode",
active,
() => {
setPasscodeActive(
false
);
form.setValue(
"password",
null
);
}
)
}
disabled={authReadonly}
/>
<PolicyAuthMethodRow
id="email"
title={t("policyAuthEmailTitle")}
description={t(
"policyAuthEmailDescription"
)}
summary={getEmailWhitelistSummary({
t,
count: emails.length
})}
active={Boolean(
emailWhitelistEnabled emailWhitelistEnabled
)} )}
onConfigure={() => headerAuthActive={headerAuthActive}
openMethodEditor("email") headerAuthUser={headerAuth?.user ?? ""}
emailCount={emails.length}
emailEnabled={emailEnabled}
disabled={authReadonly}
onConfigure={openMethodEditor}
onTogglePincode={(active) =>
handleToggle("pincode", active, () => {
setPinActive(false);
form.setValue("pincode", null);
})
} }
onToggle={(active) => onTogglePasscode={(active) =>
handleToggle( handleToggle("passcode", active, () => {
"email", setPasscodeActive(false);
active, form.setValue("password", null);
() => })
}
onToggleEmail={(active) =>
handleToggle("email", active, () =>
form.setValue( form.setValue(
"emailWhitelistEnabled", "emailWhitelistEnabled",
false false
) )
) )
} }
disabled={ onToggleHeaderAuth={(active) =>
authReadonly || !emailEnabled handleToggle("headerAuth", active, () => {
setHeaderAuthActive(false);
form.setValue("headerAuth", null);
})
} }
/> />
</SettingsSectionForm>
<PolicyAuthMethodRow
id="header-auth"
title={t(
"policyAuthHeaderAuthTitle"
)}
description={t(
"policyAuthHeaderAuthDescription"
)}
summary={getHeaderAuthSummary({
t,
headerName:
headerAuth?.user ?? ""
})}
active={headerAuthActive}
onConfigure={() =>
openMethodEditor("headerAuth")
}
onToggle={(active) =>
handleToggle(
"headerAuth",
active,
() => {
setHeaderAuthActive(
false
);
form.setValue(
"headerAuth",
null
);
}
)
}
disabled={authReadonly}
/>
</div>
</SettingsFormCell>
</SettingsFormGrid>
</div>
<PincodeCredenza <PincodeCredenza
open={editingMethod === "pincode"} open={editingMethod === "pincode"}