2019-06-19 14:40:52 +00:00
|
|
|
import Card from "@material-ui/core/Card";
|
|
|
|
import CardContent from "@material-ui/core/CardContent";
|
|
|
|
import TextField from "@material-ui/core/TextField";
|
2019-09-09 14:07:09 +00:00
|
|
|
import Typography from "@material-ui/core/Typography";
|
2019-06-19 14:40:52 +00:00
|
|
|
import CardTitle from "@saleor/components/CardTitle";
|
2020-09-03 10:25:16 +00:00
|
|
|
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
|
|
|
import Hr from "@saleor/components/Hr";
|
2019-09-16 01:00:38 +00:00
|
|
|
import RadioSwitchField from "@saleor/components/RadioSwitchField";
|
2020-09-03 10:25:16 +00:00
|
|
|
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
2020-09-03 14:14:23 +00:00
|
|
|
import { ChangeEvent } from "@saleor/hooks/useForm";
|
2021-03-30 07:40:18 +00:00
|
|
|
import { makeStyles } from "@saleor/theme";
|
2020-02-24 14:14:48 +00:00
|
|
|
import { UserError } from "@saleor/types";
|
|
|
|
import { getFieldError } from "@saleor/utils/errors";
|
2020-09-03 10:25:16 +00:00
|
|
|
import classNames from "classnames";
|
2020-10-19 09:19:07 +00:00
|
|
|
import React from "react";
|
2020-05-14 09:30:32 +00:00
|
|
|
import { useIntl } from "react-intl";
|
|
|
|
|
2019-06-19 14:40:52 +00:00
|
|
|
import { DateContext } from "../Date/DateContext";
|
2020-01-31 13:48:39 +00:00
|
|
|
import FormSpacer from "../FormSpacer";
|
2020-10-19 09:19:07 +00:00
|
|
|
import DateVisibilitySelector from "./DateVisibilitySelector";
|
2019-06-19 14:40:52 +00:00
|
|
|
|
2019-12-03 15:28:40 +00:00
|
|
|
const useStyles = makeStyles(
|
|
|
|
theme => ({
|
2020-09-03 10:25:16 +00:00
|
|
|
checkbox: {
|
|
|
|
alignItems: "flex-start",
|
|
|
|
marginTop: 10
|
|
|
|
},
|
2019-12-03 15:28:40 +00:00
|
|
|
children: {
|
|
|
|
"& button": {
|
|
|
|
margin: "0 9px"
|
|
|
|
},
|
|
|
|
"& label": {
|
|
|
|
marginTop: theme.spacing(2.5)
|
|
|
|
}
|
2019-09-16 12:03:37 +00:00
|
|
|
},
|
2019-12-03 15:28:40 +00:00
|
|
|
date: {
|
|
|
|
"& svg": {
|
|
|
|
fill: theme.palette.primary.main
|
|
|
|
},
|
2020-10-19 09:19:07 +00:00
|
|
|
marginTop: theme.spacing(1)
|
2019-12-03 15:28:40 +00:00
|
|
|
},
|
|
|
|
label: {
|
2020-09-03 10:25:16 +00:00
|
|
|
lineHeight: 1.2,
|
|
|
|
marginBottom: 5,
|
|
|
|
marginTop: 0
|
|
|
|
},
|
|
|
|
listingLabel: {
|
|
|
|
marginTop: 9
|
2019-10-30 14:34:24 +00:00
|
|
|
},
|
2019-12-03 15:28:40 +00:00
|
|
|
secondLabel: {
|
2020-09-03 10:25:16 +00:00
|
|
|
color: theme.palette.text.hint,
|
2020-10-19 09:19:07 +00:00
|
|
|
fontSize: 12,
|
|
|
|
marginBottom: theme.spacing(2)
|
2019-12-03 15:28:40 +00:00
|
|
|
},
|
2020-10-19 09:19:07 +00:00
|
|
|
switchField: {
|
|
|
|
marginTop: theme.spacing(1)
|
2019-12-03 15:28:40 +00:00
|
|
|
}
|
|
|
|
}),
|
|
|
|
{ name: "VisibilityCard" }
|
|
|
|
);
|
2019-06-19 14:40:52 +00:00
|
|
|
|
2020-09-03 10:25:16 +00:00
|
|
|
interface Message {
|
|
|
|
visibleLabel: string;
|
|
|
|
hiddenLabel: string;
|
|
|
|
visibleSecondLabel?: string;
|
|
|
|
hiddenSecondLabel: string;
|
|
|
|
availableLabel?: string;
|
|
|
|
unavailableLabel?: string;
|
|
|
|
availableSecondLabel?: string;
|
|
|
|
setAvailabilityDateLabel?: string;
|
|
|
|
}
|
2020-10-21 09:06:32 +00:00
|
|
|
|
|
|
|
export interface DateFields {
|
|
|
|
publicationDate: string;
|
|
|
|
availableForPurchase?: string;
|
|
|
|
}
|
|
|
|
|
2020-09-03 10:25:16 +00:00
|
|
|
export interface VisibilityCardProps {
|
2019-06-19 14:40:52 +00:00
|
|
|
children?: React.ReactNode | React.ReactNodeArray;
|
2020-10-21 09:06:32 +00:00
|
|
|
data: DateFields & {
|
2020-09-03 10:25:16 +00:00
|
|
|
isAvailableForPurchase?: boolean;
|
2019-06-19 14:40:52 +00:00
|
|
|
isPublished: boolean;
|
2020-09-03 10:25:16 +00:00
|
|
|
visibleInListings?: boolean;
|
2019-06-19 14:40:52 +00:00
|
|
|
};
|
2020-02-24 14:14:48 +00:00
|
|
|
errors: UserError[];
|
2019-06-19 14:40:52 +00:00
|
|
|
disabled?: boolean;
|
2020-09-03 10:25:16 +00:00
|
|
|
messages: Message;
|
2020-09-03 14:14:23 +00:00
|
|
|
onChange: (event: ChangeEvent) => void;
|
2019-06-19 14:40:52 +00:00
|
|
|
}
|
|
|
|
|
2019-10-30 14:34:24 +00:00
|
|
|
export const VisibilityCard: React.FC<VisibilityCardProps> = props => {
|
|
|
|
const {
|
2019-06-19 14:40:52 +00:00
|
|
|
children,
|
2020-09-03 10:25:16 +00:00
|
|
|
data: {
|
|
|
|
availableForPurchase,
|
|
|
|
isAvailableForPurchase: isAvailable,
|
|
|
|
isPublished,
|
|
|
|
publicationDate,
|
|
|
|
visibleInListings
|
|
|
|
},
|
2019-06-19 14:40:52 +00:00
|
|
|
errors,
|
|
|
|
disabled,
|
2020-09-03 10:25:16 +00:00
|
|
|
messages,
|
|
|
|
onChange
|
2019-10-30 14:34:24 +00:00
|
|
|
} = props;
|
|
|
|
const classes = useStyles(props);
|
|
|
|
const intl = useIntl();
|
2020-09-03 10:25:16 +00:00
|
|
|
const localizeDate = useDateLocalize();
|
|
|
|
const dateNow = React.useContext(DateContext);
|
|
|
|
const hasAvailableProps =
|
|
|
|
isAvailable !== undefined && availableForPurchase !== undefined;
|
|
|
|
|
|
|
|
const visibleMessage = (date: string) =>
|
|
|
|
intl.formatMessage(
|
|
|
|
{
|
|
|
|
defaultMessage: "since {date}",
|
|
|
|
description: "date"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
date: localizeDate(date, "L")
|
|
|
|
}
|
|
|
|
);
|
2019-10-30 14:34:24 +00:00
|
|
|
|
2020-10-21 09:06:32 +00:00
|
|
|
const handleRadioFieldChange = (type: keyof DateFields) => (
|
|
|
|
e: ChangeEvent
|
|
|
|
) => {
|
|
|
|
const { value } = e.target;
|
|
|
|
if (!value) {
|
|
|
|
onChange({
|
|
|
|
target: {
|
|
|
|
name: type,
|
|
|
|
value: null
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return onChange(e);
|
|
|
|
};
|
|
|
|
|
2019-10-30 14:34:24 +00:00
|
|
|
return (
|
|
|
|
<Card>
|
|
|
|
<CardTitle
|
|
|
|
title={intl.formatMessage({
|
|
|
|
defaultMessage: "Visibility",
|
|
|
|
description: "section header"
|
|
|
|
})}
|
|
|
|
/>
|
|
|
|
<CardContent>
|
|
|
|
<RadioSwitchField
|
|
|
|
disabled={disabled}
|
2020-02-24 14:14:48 +00:00
|
|
|
error={!!getFieldError(errors, "isPublished")}
|
2019-10-30 14:34:24 +00:00
|
|
|
firstOptionLabel={
|
2019-06-19 14:40:52 +00:00
|
|
|
<>
|
2020-09-03 10:25:16 +00:00
|
|
|
<p className={classes.label}>{messages.visibleLabel}</p>
|
|
|
|
{isPublished &&
|
|
|
|
publicationDate &&
|
|
|
|
Date.parse(publicationDate) < dateNow && (
|
|
|
|
<span className={classes.secondLabel}>
|
|
|
|
{messages.visibleSecondLabel ||
|
|
|
|
visibleMessage(publicationDate)}
|
|
|
|
</span>
|
|
|
|
)}
|
2019-06-19 14:40:52 +00:00
|
|
|
</>
|
2019-10-30 14:34:24 +00:00
|
|
|
}
|
|
|
|
name={"isPublished" as keyof FormData}
|
|
|
|
secondOptionLabel={
|
|
|
|
<>
|
2020-09-03 10:25:16 +00:00
|
|
|
<p className={classes.label}>{messages.hiddenLabel}</p>
|
|
|
|
{publicationDate &&
|
|
|
|
!isPublished &&
|
|
|
|
Date.parse(publicationDate) >= dateNow && (
|
|
|
|
<span className={classes.secondLabel}>
|
|
|
|
{messages.hiddenSecondLabel}
|
|
|
|
</span>
|
|
|
|
)}
|
2019-10-30 14:34:24 +00:00
|
|
|
</>
|
|
|
|
}
|
|
|
|
value={isPublished}
|
2020-10-21 09:06:32 +00:00
|
|
|
onChange={handleRadioFieldChange("publicationDate")}
|
2019-10-30 14:34:24 +00:00
|
|
|
/>
|
|
|
|
{!isPublished && (
|
2020-10-19 09:19:07 +00:00
|
|
|
<DateVisibilitySelector
|
|
|
|
buttonText={intl.formatMessage({
|
|
|
|
defaultMessage: "Set publication date"
|
|
|
|
})}
|
|
|
|
onInputClose={() =>
|
|
|
|
onChange({ target: { name: "publicationDate", value: null } })
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<TextField
|
|
|
|
error={!!getFieldError(errors, "publicationDate")}
|
|
|
|
disabled={disabled}
|
|
|
|
label={intl.formatMessage({
|
|
|
|
defaultMessage: "Publish on",
|
|
|
|
description: "publish on date"
|
2020-09-03 10:25:16 +00:00
|
|
|
})}
|
2020-10-19 09:19:07 +00:00
|
|
|
name="publicationDate"
|
|
|
|
type="date"
|
|
|
|
fullWidth={true}
|
|
|
|
helperText={getFieldError(errors, "publicationDate")?.message}
|
|
|
|
value={publicationDate ? publicationDate : ""}
|
|
|
|
onChange={onChange}
|
|
|
|
className={classes.date}
|
|
|
|
InputLabelProps={{
|
|
|
|
shrink: true
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</DateVisibilitySelector>
|
2019-10-30 14:34:24 +00:00
|
|
|
)}
|
2020-02-24 14:14:48 +00:00
|
|
|
{getFieldError(errors, "isPublished") && (
|
2020-01-31 13:48:39 +00:00
|
|
|
<>
|
|
|
|
<FormSpacer />
|
2020-02-24 14:14:48 +00:00
|
|
|
<Typography color="error">
|
|
|
|
{getFieldError(errors, "isPublished")?.message}
|
|
|
|
</Typography>
|
2020-01-31 13:48:39 +00:00
|
|
|
</>
|
|
|
|
)}
|
2020-09-03 10:25:16 +00:00
|
|
|
{hasAvailableProps && (
|
|
|
|
<>
|
|
|
|
<Hr />
|
|
|
|
<RadioSwitchField
|
2020-10-19 09:19:07 +00:00
|
|
|
className={classes.switchField}
|
2020-09-03 10:25:16 +00:00
|
|
|
disabled={disabled}
|
|
|
|
error={!!getFieldError(errors, "isAvailableForPurchase")}
|
|
|
|
firstOptionLabel={
|
|
|
|
<>
|
|
|
|
<p className={classes.label}>{messages.availableLabel}</p>
|
|
|
|
{isAvailable &&
|
|
|
|
availableForPurchase &&
|
|
|
|
Date.parse(availableForPurchase) < dateNow && (
|
|
|
|
<span className={classes.secondLabel}>
|
|
|
|
{visibleMessage(availableForPurchase)}
|
|
|
|
</span>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
}
|
|
|
|
name={"isAvailableForPurchase" as keyof FormData}
|
|
|
|
secondOptionLabel={
|
|
|
|
<>
|
|
|
|
<p className={classes.label}>{messages.unavailableLabel}</p>
|
|
|
|
{availableForPurchase && !isAvailable && (
|
|
|
|
<span className={classes.secondLabel}>
|
|
|
|
{messages.availableSecondLabel}
|
|
|
|
</span>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
}
|
|
|
|
value={isAvailable}
|
2020-10-21 09:06:32 +00:00
|
|
|
onChange={handleRadioFieldChange("availableForPurchase")}
|
2020-09-03 10:25:16 +00:00
|
|
|
/>
|
|
|
|
{!isAvailable && (
|
2020-10-19 09:19:07 +00:00
|
|
|
<DateVisibilitySelector
|
|
|
|
buttonText={messages.setAvailabilityDateLabel}
|
|
|
|
onInputClose={() =>
|
|
|
|
onChange({
|
|
|
|
target: { name: "availableForPurchase", value: null }
|
|
|
|
})
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<TextField
|
|
|
|
error={!!getFieldError(errors, "startDate")}
|
|
|
|
disabled={disabled}
|
|
|
|
label={intl.formatMessage({
|
|
|
|
defaultMessage: "Set available on",
|
|
|
|
description: "available on date"
|
|
|
|
})}
|
|
|
|
name="availableForPurchase"
|
|
|
|
type="date"
|
|
|
|
fullWidth={true}
|
|
|
|
helperText={getFieldError(errors, "startDate")?.message}
|
|
|
|
value={availableForPurchase ? availableForPurchase : ""}
|
|
|
|
onChange={onChange}
|
|
|
|
className={classes.date}
|
|
|
|
InputLabelProps={{
|
|
|
|
shrink: true
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</DateVisibilitySelector>
|
2020-09-03 10:25:16 +00:00
|
|
|
)}
|
|
|
|
{getFieldError(errors, "isAvailableForPurchase") && (
|
|
|
|
<>
|
|
|
|
<FormSpacer />
|
|
|
|
<Typography color="error">
|
|
|
|
{getFieldError(errors, "isAvailableForPurchase")?.message}
|
|
|
|
</Typography>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
{visibleInListings !== undefined && (
|
|
|
|
<>
|
|
|
|
<Hr />
|
|
|
|
<ControlledCheckbox
|
|
|
|
className={classes.checkbox}
|
|
|
|
name="visibleInListings"
|
|
|
|
checked={visibleInListings}
|
|
|
|
disabled={disabled}
|
|
|
|
label={
|
|
|
|
<>
|
|
|
|
<p
|
|
|
|
className={classNames(classes.label, classes.listingLabel)}
|
|
|
|
>
|
|
|
|
{intl.formatMessage({
|
|
|
|
defaultMessage: "Show in product listings"
|
|
|
|
})}
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<span className={classes.secondLabel}>
|
|
|
|
{intl.formatMessage({
|
|
|
|
defaultMessage:
|
|
|
|
"Disabling this checkbox will remove product from search and category pages. It will be available on collection pages."
|
|
|
|
})}
|
|
|
|
</span>
|
|
|
|
</>
|
|
|
|
}
|
|
|
|
onChange={onChange}
|
|
|
|
/>
|
|
|
|
</>
|
|
|
|
)}
|
2019-10-30 14:34:24 +00:00
|
|
|
<div className={classes.children}>{children}</div>
|
|
|
|
</CardContent>
|
|
|
|
</Card>
|
|
|
|
);
|
|
|
|
};
|
2019-06-19 14:40:52 +00:00
|
|
|
VisibilityCard.displayName = "VisibilityCard";
|
|
|
|
export default VisibilityCard;
|