Use this page when people edit the configuration of a whole workspace, account or integration and save it in one go, such as a workspace's name, timezone and default sender. It names the screen and its scope in the header and keeps the fields in a narrow column, with Cancel and Save changes at the end of the form. Add a panel per group of related settings as the page grows.
Set how this workspace identifies itself and the defaults its messages start from.
import {
Button,
Checkbox,
Form,
FormLayout,
FormLayoutGroup,
Page,
PageBody,
PageHeader,
PageHeaderDescription,
PageHeaderTitle,
Panel,
PanelActions,
PanelDescription,
PanelFooter,
PanelHeader,
PanelSection,
PanelTitle,
Select,
TextField,
} from '@customerio/pluma-components/react';
const timezoneOptions = [
{ value: 'America/New_York', label: 'Eastern Time (US & Canada)' },
{ value: 'America/Chicago', label: 'Central Time (US & Canada)' },
{ value: 'America/Denver', label: 'Mountain Time (US & Canada)' },
{ value: 'America/Los_Angeles', label: 'Pacific Time (US & Canada)' },
{ value: 'Etc/UTC', label: 'Coordinated Universal Time (UTC)' },
{ value: 'Europe/London', label: 'London' },
{ value: 'Europe/Paris', label: 'Paris' },
{ value: 'Europe/Berlin', label: 'Berlin' },
{ value: 'Asia/Singapore', label: 'Singapore' },
{ value: 'Asia/Tokyo', label: 'Tokyo' },
{ value: 'Australia/Sydney', label: 'Sydney' },
];
const languageOptions = [
{ value: 'en', label: 'English' },
{ value: 'es', label: 'Spanish' },
{ value: 'fr', label: 'French' },
{ value: 'de', label: 'German' },
{ value: 'pt-BR', label: 'Portuguese (Brazil)' },
{ value: 'ja', label: 'Japanese' },
];
export interface SettingsFormValues {
workspaceName: string;
/** An IANA timezone name, such as `America/New_York`. */
timezone: string;
/** A language code, such as `en`. */
language: string;
senderEmail: string;
sendWeeklySummary: boolean;
}
export interface SettingsFormProps {
/** The current value of every field. */
settings: SettingsFormValues;
/** Called on every keystroke in the workspace name field. */
onWorkspaceNameInput: (event: Event & { target: HTMLInputElement }) => void;
/** Called with the timezone the user picks. */
onTimezoneChange: (timezone: string | null) => void;
/** Called with the language the user picks. */
onLanguageChange: (language: string | null) => void;
/** Called on every keystroke in the sender email field. */
onSenderEmailInput: (event: Event & { target: HTMLInputElement }) => void;
/** Called when the weekly summary checkbox is toggled. */
onSendWeeklySummaryChange: (isChecked: boolean) => void;
/** Called when the form is submitted. Return a promise to lock the fields until it settles. */
onSave: () => void | Promise<void>;
/** Called when the user discards their changes. */
onCancel: () => void;
}
export function SettingsForm({
settings,
onWorkspaceNameInput,
onTimezoneChange,
onLanguageChange,
onSenderEmailInput,
onSendWeeklySummaryChange,
onSave,
onCancel,
}: SettingsFormProps) {
return (
<Page isFullScreen bodyContentWidth="narrow">
<PageHeader>
<PageHeaderTitle>Workspace settings</PageHeaderTitle>
<PageHeaderDescription>
Set how this workspace identifies itself and the defaults its messages start from.
</PageHeaderDescription>
</PageHeader>
<PageBody>
<Form onSubmit={onSave}>
<Panel>
<PanelHeader>
<PanelTitle>General</PanelTitle>
<PanelDescription>These settings apply to everyone who works in this workspace.</PanelDescription>
</PanelHeader>
<PanelSection>
<FormLayout>
<TextField
label="Workspace name"
description="Appears in the workspace switcher and in notifications sent to your team."
value={settings.workspaceName}
onInput={onWorkspaceNameInput}
/>
<FormLayoutGroup>
<Select
label="Timezone"
description="Schedules and reports use this timezone."
placeholder="Select a timezone"
searchPlaceholder="Search timezones"
isSearchable
options={timezoneOptions}
value={settings.timezone}
onChange={onTimezoneChange}
/>
<Select
label="Default language"
description="Messages without a translation fall back to this language."
placeholder="Select a language"
options={languageOptions}
value={settings.language}
onChange={onLanguageChange}
/>
</FormLayoutGroup>
<TextField
label="Default sender email"
description="New campaigns and broadcasts send from this address until you change it."
type="email"
value={settings.senderEmail}
onInput={onSenderEmailInput}
/>
<Checkbox
label="Send a weekly delivery summary to admins"
description="Sent on Mondays with deliveries, opens, and bounces from the past week"
isChecked={settings.sendWeeklySummary}
onCheckedChange={onSendWeeklySummaryChange}
/>
</FormLayout>
</PanelSection>
<PanelFooter>
<PanelActions>
<Button variant="tertiary" size="sm" onClick={onCancel}>
Cancel
</Button>
<Button variant="primary" size="sm" type="submit">
Save changes
</Button>
</PanelActions>
</PanelFooter>
</Panel>
</Form>
</PageBody>
</Page>
);
}
Copy this recipe into your app with the Pluma CLI. Replace <dest-dir> with the folder the file goes in, and add --name <Name> to rename the component and its file.
pluma-cli scaffold settings-form <dest-dir> --framework reactThis recipe uses these components. Each one's docs page lists its props.