import { Button, Card, CardContent, TextField, Typography } from "@material-ui/core"; import { CollectionErrorFragment } from "@saleor/fragments/types/CollectionErrorFragment"; import { PageErrorFragment } from "@saleor/fragments/types/PageErrorFragment"; import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment"; import { makeStyles } from "@saleor/theme"; import { getFieldError, getProductErrorMessage } from "@saleor/utils/errors"; import getPageErrorMessage from "@saleor/utils/errors/page"; import classNames from "classnames"; import React from "react"; import { defineMessages, FormattedMessage, useIntl } from "react-intl"; import slugify from "slugify"; import CardTitle from "../CardTitle"; import FormSpacer from "../FormSpacer"; enum SeoField { slug = "slug", title = "seoTitle", description = "seoDescription" } const SLUG_REGEX = /^[a-zA-Z0-9\-\_]+$/; const maxSlugLength = 255; const maxTitleLength = 70; const maxDescriptionLength = 300; const useStyles = makeStyles( theme => ({ addressBar: { color: "#006621", fontSize: "13px", lineHeight: "16px", marginBottom: "2px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, container: { width: "100%" }, descriptionBar: { color: "#545454", fontSize: "13px", lineHeight: "18px", overflowWrap: "break-word" }, helperText: { marginBottom: theme.spacing(3) }, label: { flex: 1 }, labelContainer: { "& span": { paddingRight: 30 }, display: "flex" }, preview: { minHeight: theme.spacing(10) }, title: { padding: 0 }, titleBar: { color: "#1a0dab", fontSize: "18px", lineHeight: "21px", overflowWrap: "break-word", textDecoration: "none", wordWrap: "break-word" } }), { name: "SeoForm" } ); interface SeoFormProps { description?: string; descriptionPlaceholder: string; disabled?: boolean; errors?: Array< PageErrorFragment | ProductErrorFragment | CollectionErrorFragment >; loading?: boolean; helperText?: string; allowEmptySlug?: boolean; title: string; slug: string; slugPlaceholder?: string; titlePlaceholder: string; onChange(event: any); onClick?(); } const SeoForm: React.FC = props => { const { description, descriptionPlaceholder, disabled, errors = [], helperText, allowEmptySlug = false, loading, title, slug, slugPlaceholder, titlePlaceholder, onChange } = props; const classes = useStyles(props); const intl = useIntl(); const [expanded, setExpansionStatus] = React.useState(false); const toggleExpansion = () => setExpansionStatus(!expanded); const shouldDisplayHelperText = helperText && !expanded; const { seoFieldMessage } = defineMessages({ seoFieldMessage: { defaultMessage: "If empty, the preview shows what will be autogenerated." } }); const getSlugHelperMessage = () => { const error = !!getError(SeoField.slug); if (allowEmptySlug && !error) { return intl.formatMessage(seoFieldMessage); } return error ? getSlugErrorMessage() : ""; }; const getSlugErrorMessage = () => { const error = getError(SeoField.slug); const { __typename: type } = error; return type === "ProductError" ? getProductErrorMessage(error as ProductErrorFragment, intl) : getPageErrorMessage(error as PageErrorFragment, intl); }; const handleSlugChange = (event: React.ChangeEvent) => { const { value } = event.target; if (value === "" || SLUG_REGEX.test(value)) { onChange(event); } }; const getError = (fieldName: SeoField) => getFieldError(errors, fieldName); return ( } /> {shouldDisplayHelperText && ( {helperText} )} {expanded && (
maxSlugLength} name={SeoField.slug} label={
{slug?.length > 0 && ( )}
} InputProps={{ inputProps: { maxLength: maxSlugLength } }} helperText={getSlugHelperMessage()} value={slug} disabled={loading || disabled} placeholder={slug || slugify(slugPlaceholder, { lower: true })} onChange={handleSlugChange} fullWidth /> maxTitleLength} name={SeoField.title} label={
{title?.length > 0 && ( )}
} InputProps={{ inputProps: { maxLength: maxTitleLength } }} helperText={intl.formatMessage(seoFieldMessage)} value={title} disabled={loading || disabled} placeholder={titlePlaceholder} onChange={onChange} fullWidth /> maxDescriptionLength} name={SeoField.description} label={
{description?.length > 0 && ( )}
} helperText={intl.formatMessage(seoFieldMessage)} InputProps={{ inputProps: { maxLength: maxDescriptionLength } }} value={description} onChange={onChange} disabled={loading || disabled} fullWidth multiline placeholder={descriptionPlaceholder} rows={10} />
)}
); }; SeoForm.displayName = "SeoForm"; export default SeoForm;