@@ -14,6 +14,7 @@ import {
1414 Tooltip ,
1515 InputErrorsTooltip ,
1616 ProBadge ,
17+ TextArea ,
1718} from "@webstudio-is/design-system" ;
1819import { InfoCircleIcon } from "@webstudio-is/icons" ;
1920import { ImageControl } from "./image-control" ;
@@ -44,41 +45,61 @@ const defaultMetaSettings: ProjectMeta = {
4445
4546const Email = z . string ( ) . email ( ) ;
4647
48+ const validateContactEmail = (
49+ contactEmail : string ,
50+ maxContactEmails : number
51+ ) => {
52+ contactEmail = contactEmail . trim ( ) ;
53+ if ( contactEmail . length === 0 ) {
54+ return ;
55+ }
56+ const emails = contactEmail . split ( / \s * , \s * / ) ;
57+ if ( emails . length > maxContactEmails ) {
58+ return `Only ${ maxContactEmails } emails are allowed.` ;
59+ }
60+ if ( emails . every ( ( email ) => Email . safeParse ( email ) . success ) === false ) {
61+ return "Contact email is invalid." ;
62+ }
63+ } ;
64+
65+ const saveSetting = < Name extends keyof ProjectMeta > (
66+ name : keyof ProjectMeta ,
67+ value : ProjectMeta [ Name ]
68+ ) => {
69+ serverSyncStore . createTransaction ( [ $pages ] , ( pages ) => {
70+ if ( pages === undefined ) {
71+ return ;
72+ }
73+ if ( pages . meta === undefined ) {
74+ pages . meta = { } ;
75+ }
76+ pages . meta [ name ] = value ;
77+ } ) ;
78+ } ;
79+
4780export const SectionGeneral = ( ) => {
48- const { allowContactEmail } = useStore ( $userPlanFeatures ) ;
81+ const { maxContactEmails } = useStore ( $userPlanFeatures ) ;
82+ const allowContactEmail = maxContactEmails > 0 ;
4983 const [ meta , setMeta ] = useState (
5084 ( ) => $pages . get ( ) ?. meta ?? defaultMetaSettings
5185 ) ;
5286 const siteNameId = useId ( ) ;
5387 const contactEmailId = useId ( ) ;
54- const contactEmail = ( meta . contactEmail ?? "" ) . trim ( ) ;
55- const contactEmailError =
56- contactEmail . length === 0 ||
57- contactEmail
58- . split ( "," )
59- . every ( ( email ) => Email . safeParse ( email . trim ( ) ) . success )
60- ? undefined
61- : "Contact email is invalid." ;
88+ const contactEmailError = validateContactEmail (
89+ meta . contactEmail ?? "" ,
90+ maxContactEmails
91+ ) ;
6292 const assets = useStore ( $assets ) ;
6393 const asset = assets . get ( meta . faviconAssetId ?? "" ) ;
6494 const favIconUrl = asset ? `${ asset . name } ` : undefined ;
6595 const imageLoader = useStore ( $imageLoader ) ;
6696
67- const handleSave = < Setting extends keyof ProjectMeta > ( setting : Setting ) => {
68- return ( value : ProjectMeta [ Setting ] ) => {
69- setMeta ( {
70- ...meta ,
71- [ setting ] : value ,
72- } ) ;
73- serverSyncStore . createTransaction ( [ $pages ] , ( pages ) => {
74- if ( pages === undefined ) {
75- return ;
76- }
77- if ( pages . meta === undefined ) {
78- pages . meta = { } ;
79- }
80- pages . meta [ setting ] = value ;
81- } ) ;
97+ const handleSave = < Name extends keyof ProjectMeta > (
98+ name : keyof ProjectMeta
99+ ) => {
100+ return ( value : ProjectMeta [ Name ] ) => {
101+ setMeta ( { ...meta , [ name ] : value } ) ;
102+ saveSetting ( name , value ) ;
82103 } ;
83104 } ;
84105
@@ -123,14 +144,19 @@ export const SectionGeneral = () => {
123144 < InputErrorsTooltip
124145 errors = { contactEmailError ? [ contactEmailError ] : undefined }
125146 >
126- < InputField
147+ < TextArea
127148 id = { contactEmailId }
128149 color = { contactEmailError ? "error" : undefined }
129- placeholder = "email@address .com"
150+ placeholder = "[email protected] , jane@company .com" 130151 disabled = { allowContactEmail === false }
152+ autoGrow = { true }
153+ rows = { 1 }
131154 value = { meta . contactEmail ?? "" }
132- onChange = { ( event ) => {
133- handleSave ( "contactEmail" ) ( event . target . value ) ;
155+ onChange = { ( value ) => {
156+ setMeta ( { ...meta , contactEmail : value } ) ;
157+ if ( validateContactEmail ( value , maxContactEmails ) === undefined ) {
158+ saveSetting ( "contactEmail" , value ) ;
159+ }
134160 } }
135161 />
136162 </ InputErrorsTooltip >
0 commit comments