Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 62 additions & 1 deletion demo/site/src/common/blocks/ContactFormBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,71 @@
"use client";
import { type PropsWithData, withPreview } from "@comet/site-nextjs";
import { type ContactFormBlockData } from "@src/blocks.generated";
import { FormattedMessage, useIntl } from "react-intl";

import { Button } from "../components/Button";
import { CheckboxField } from "../components/form/CheckboxField";
import { SelectField } from "../components/form/SelectField";
import { TextareaField } from "../components/form/TextareaField";
import { TextField } from "../components/form/TextField";

const subjectOptions = [
{ value: "Option 1", label: "Option 1" },
{ value: "Option 2", label: "Option 2" },
{ value: "Option 3", label: "Option 3" },
];

export const ContactFormBlock = withPreview(
({ data }: PropsWithData<ContactFormBlockData>) => {
return <>Contact Form</>;
const intl = useIntl();
return (
<>
<TextField
label={intl.formatMessage({ id: "contactForm.name.label", defaultMessage: "Name" })}
placeholder={intl.formatMessage({ id: "contactForm.name.placeholder", defaultMessage: "First and last name" })}
required
/>
<TextField
label={intl.formatMessage({ id: "contactForm.company.label", defaultMessage: "Company" })}
placeholder={intl.formatMessage({ id: "contactForm.company.placeholder", defaultMessage: "Company name" })}
/>
<TextField
label={intl.formatMessage({ id: "contactForm.email.label", defaultMessage: "Email" })}
placeholder={intl.formatMessage({ id: "contactForm.email.placeholder", defaultMessage: "Your email address" })}
required
/>
<TextField
label={intl.formatMessage({ id: "contactForm.phoneNumber.label", defaultMessage: "Phone Number" })}
placeholder={intl.formatMessage({ id: "contactForm.phoneNumber.placeholder", defaultMessage: "0043123456789" })}
helperText={intl.formatMessage({
id: "contactForm.phoneNumber.helperText",
defaultMessage: "Please enter without special characters and spaces",
})}
/>
<SelectField
label={intl.formatMessage({ id: "contactForm.subject.label", defaultMessage: "Subject" })}
required
placeholder={intl.formatMessage({ id: "contactForm.subject.placeholder", defaultMessage: "Please select" })}
options={subjectOptions}
/>
<TextareaField
label={intl.formatMessage({ id: "contactForm.message.label", defaultMessage: "Message" })}
placeholder={intl.formatMessage({ id: "contactForm.message.placeholder", defaultMessage: "Your message" })}
required
/>
<CheckboxField
label={intl.formatMessage({
id: "contactForm.privacyConsent.label",
defaultMessage:
"I agree that my information from the contact form will be collected and processed to answer my inquiry. Note: You can revoke your consent at any time by email to [email protected]. For more information, please see our privacy policy.",
})}
required
/>
<Button type="submit" variant="contained">
<FormattedMessage id="contactForm.submitButton.label" defaultMessage="Submit" />
</Button>
</>
);
},
{ label: "Contact Form" },
);
17 changes: 17 additions & 0 deletions demo/site/src/common/components/form/CheckboxField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { type ReactNode } from "react";

interface CheckboxFieldProps {
label: ReactNode;
helperText?: ReactNode;
required?: boolean;
}

export function CheckboxField({ label, helperText }: CheckboxFieldProps) {
return (
<div>
<input type="checkbox" />
<label>{label}</label>
{helperText && <div>{helperText}</div>}
</div>
);
}
45 changes: 45 additions & 0 deletions demo/site/src/common/components/form/SelectField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { SvgUse } from "@src/common/helpers/SvgUse";
import { type ReactNode } from "react";
import { FormattedMessage } from "react-intl";

interface SelectFieldProps {
label: ReactNode;
required?: boolean;
helperText?: ReactNode;
options: Array<{ value: string; label: string }>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use ReactNode for the label.

placeholder?: ReactNode;
}

export function SelectField({
label,
required = false,
helperText,
options,
placeholder = <FormattedMessage id="selectField.placeholder" defaultMessage="Select an option" />,
}: SelectFieldProps): React.ReactElement {
return (
<div>
<label>
{label}
{!required && (
<span>
<FormattedMessage id="selectField.optional" defaultMessage="(optional)" />
</span>
)}
</label>
<div>
<button type="button">
<span>{placeholder}</span>
<SvgUse href="/assets/icons/chevron-down.svg#root" width={16} height={16} />
</button>

<div>
{options.map((option) => (
<div key={option.value}>{option.label}</div>
))}
</div>
</div>
{helperText && <div>{helperText}</div>}
</div>
);
}
26 changes: 26 additions & 0 deletions demo/site/src/common/components/form/TextField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { type ReactNode } from "react";
import { FormattedMessage } from "react-intl";

interface InputProps {
label: ReactNode;
required?: boolean;
placeholder?: string;
helperText?: ReactNode;
}

export function TextField({ label, required = false, placeholder, helperText }: InputProps): React.ReactElement {
return (
<div>
<label>
{label}
{!required && (
<span>
<FormattedMessage id="inputField.optional" defaultMessage="(optional)" />
</span>
)}
</label>
<input required={required} placeholder={placeholder} />
{helperText && <div>{helperText}</div>}
</div>
);
}
26 changes: 26 additions & 0 deletions demo/site/src/common/components/form/TextareaField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { type ReactNode } from "react";
import { FormattedMessage } from "react-intl";

interface InputProps {
label: ReactNode;
required?: boolean;
placeholder?: string;
helperText?: ReactNode;
}

export function TextareaField({ label, required = false, placeholder, helperText }: InputProps): React.ReactElement {
return (
<div>
<label>
{label}
{!required && (
<span>
<FormattedMessage id="inputField.optional" defaultMessage="(optional)" />
</span>
)}
</label>
<textarea required={required} placeholder={placeholder} />
{helperText && <div>{helperText}</div>}
</div>
);
}