Skip to content

Commit

Permalink
textarea, user features, not save invalid
Browse files Browse the repository at this point in the history
  • Loading branch information
TrySound committed Nov 8, 2024
1 parent 3aadcba commit bb374ab
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
Tooltip,
InputErrorsTooltip,
ProBadge,
TextArea,
} from "@webstudio-is/design-system";
import { InfoCircleIcon } from "@webstudio-is/icons";
import { ImageControl } from "./image-control";
Expand Down Expand Up @@ -44,41 +45,61 @@ const defaultMetaSettings: ProjectMeta = {

const Email = z.string().email();

const validateContactEmail = (
contactEmail: string,
maxContactEmails: number
) => {
contactEmail = contactEmail.trim();
if (contactEmail.length === 0) {
return;
}
const emails = contactEmail.split(/\s*,\s*/);
if (emails.length > maxContactEmails) {
return `Only ${maxContactEmails} emails are allowed.`;
}
if (emails.every((email) => Email.safeParse(email).success) === false) {
return "Contact email is invalid.";
}
};

const saveSetting = <Name extends keyof ProjectMeta>(
name: keyof ProjectMeta,
value: ProjectMeta[Name]
) => {
serverSyncStore.createTransaction([$pages], (pages) => {
if (pages === undefined) {
return;
}
if (pages.meta === undefined) {
pages.meta = {};
}
pages.meta[name] = value;
});
};

export const SectionGeneral = () => {
const { allowContactEmail } = useStore($userPlanFeatures);
const { maxContactEmails } = useStore($userPlanFeatures);
const allowContactEmail = maxContactEmails > 0;
const [meta, setMeta] = useState(
() => $pages.get()?.meta ?? defaultMetaSettings
);
const siteNameId = useId();
const contactEmailId = useId();
const contactEmail = (meta.contactEmail ?? "").trim();
const contactEmailError =
contactEmail.length === 0 ||
contactEmail
.split(",")
.every((email) => Email.safeParse(email.trim()).success)
? undefined
: "Contact email is invalid.";
const contactEmailError = validateContactEmail(
meta.contactEmail ?? "",
maxContactEmails
);
const assets = useStore($assets);
const asset = assets.get(meta.faviconAssetId ?? "");
const favIconUrl = asset ? `${asset.name}` : undefined;
const imageLoader = useStore($imageLoader);

const handleSave = <Setting extends keyof ProjectMeta>(setting: Setting) => {
return (value: ProjectMeta[Setting]) => {
setMeta({
...meta,
[setting]: value,
});
serverSyncStore.createTransaction([$pages], (pages) => {
if (pages === undefined) {
return;
}
if (pages.meta === undefined) {
pages.meta = {};
}
pages.meta[setting] = value;
});
const handleSave = <Name extends keyof ProjectMeta>(
name: keyof ProjectMeta
) => {
return (value: ProjectMeta[Name]) => {
setMeta({ ...meta, [name]: value });
saveSetting(name, value);
};
};

Expand Down Expand Up @@ -123,14 +144,19 @@ export const SectionGeneral = () => {
<InputErrorsTooltip
errors={contactEmailError ? [contactEmailError] : undefined}
>
<InputField
<TextArea
id={contactEmailId}
color={contactEmailError ? "error" : undefined}
placeholder="email@address.com"
placeholder="[email protected], jane@company.com"
disabled={allowContactEmail === false}
autoGrow={true}
rows={1}
value={meta.contactEmail ?? ""}
onChange={(event) => {
handleSave("contactEmail")(event.target.value);
onChange={(value) => {
setMeta({ ...meta, contactEmail: value });
if (validateContactEmail(value, maxContactEmails) === undefined) {
saveSetting("contactEmail", value);
}
}}
/>
</InputErrorsTooltip>
Expand Down
6 changes: 3 additions & 3 deletions apps/builder/app/shared/db/user-plan-features.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const getUserPlanFeatures = async (
return {
allowShareAdminLinks: true,
allowDynamicData: true,
allowContactEmail: true,
maxContactEmails: 5,
maxDomainsAllowedPerUser: Number.MAX_SAFE_INTEGER,
hasSubscription,
hasProPlan: true,
Expand All @@ -56,7 +56,7 @@ export const getUserPlanFeatures = async (
return {
allowShareAdminLinks: true,
allowDynamicData: true,
allowContactEmail: true,
maxContactEmails: 5,
maxDomainsAllowedPerUser: Number.MAX_SAFE_INTEGER,
hasSubscription: true,
hasProPlan: true,
Expand All @@ -67,7 +67,7 @@ export const getUserPlanFeatures = async (
return {
allowShareAdminLinks: false,
allowDynamicData: false,
allowContactEmail: false,
maxContactEmails: 0,
maxDomainsAllowedPerUser: 1,
hasSubscription: false,
hasProPlan: false,
Expand Down
2 changes: 1 addition & 1 deletion packages/trpc-interface/src/context/context.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type DeploymentContext = {
type UserPlanFeatures = {
allowShareAdminLinks: boolean;
allowDynamicData: boolean;
allowContactEmail: boolean;
maxContactEmails: number;
maxDomainsAllowedPerUser: number;
hasSubscription: boolean;
} & (
Expand Down

0 comments on commit bb374ab

Please sign in to comment.