import Button from "@material-ui/core/Button"; import Card from "@material-ui/core/Card"; import CardContent from "@material-ui/core/CardContent"; import { makeStyles } from "@material-ui/core/styles"; import TextField from "@material-ui/core/TextField"; import Typography from "@material-ui/core/Typography"; import { PageErrorFragment } from "@saleor/fragments/types/PageErrorFragment"; import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment"; import { PageErrorCode, ProductErrorCode } from "@saleor/types/globalTypes"; import { getProductErrorMessage } from "@saleor/utils/errors"; import getPageErrorMessage from "@saleor/utils/errors/page"; import classNames from "classnames"; import React from "react"; import { 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 DEFAULT_INPUT_MESSAGE = "If empty, the preview shows what will be autogenerated."; interface Error { __typename: "ProductError" | "PageError"; field: string | null; code: ProductErrorCode | PageErrorCode; } const SLUG_REGEX = /^[a-z0-9]+(?:[\-a-z0-9]+)*$/; 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?: ProductErrorFragment[] | PageErrorFragment[]; loading?: boolean; helperText?: string; isCreating?: boolean; title: string; slug: string; slugPlaceholder?: string; titlePlaceholder: string; onChange(event: any); onClick?(); } const SeoForm: React.FC = props => { const { description, descriptionPlaceholder, disabled, errors, helperText, isCreating = 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 getFilteredErrors = () => (errors as Error[])?.filter(({ field }) => Object.keys(SeoField).includes(field) ) || []; const getError = (fieldName: SeoField) => getFilteredErrors().find(({ field }) => fieldName === field); const isError = (fieldName: SeoField) => !!getError(fieldName); const getSlugHelperText = () => { const error = isError(SeoField.slug); if (isCreating && !error) { return intl.formatMessage({ defaultMessage: DEFAULT_INPUT_MESSAGE }); } if (error) { return getSlugErrorText(); } return ""; }; const getSlugErrorText = () => { 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 => { const { value } = event.target; if (value === "" || !!value.match(SLUG_REGEX)) { onChange(event); } }; return ( } /> {shouldDisplayHelperText && ( {helperText} )} {expanded && (
{slug?.length > 0 && ( )}
} helperText={getSlugHelperText()} value={slug?.slice(0, 69)} disabled={loading || disabled} placeholder={slug || slugify(slugPlaceholder, { lower: true })} onChange={handleSlugChange} fullWidth />
{title?.length > 0 && ( )} } helperText={intl.formatMessage({ defaultMessage: DEFAULT_INPUT_MESSAGE })} value={title?.slice(0, 69)} disabled={loading || disabled} placeholder={titlePlaceholder} onChange={onChange} fullWidth />
{description?.length > 0 && ( )} } helperText={intl.formatMessage({ defaultMessage: DEFAULT_INPUT_MESSAGE })} value={description?.slice(0, 299)} onChange={onChange} disabled={loading || disabled} fullWidth multiline placeholder={descriptionPlaceholder} rows={10} /> )}
); }; SeoForm.displayName = "SeoForm"; export default SeoForm;