import Button from "@material-ui/core/Button"; import Card from "@material-ui/core/Card"; import CardContent from "@material-ui/core/CardContent"; import TextField from "@material-ui/core/TextField"; import Typography from "@material-ui/core/Typography"; import { Channel as ChannelList } from "@saleor/channels/utils"; import CardTitle from "@saleor/components/CardTitle"; import ControlledCheckbox from "@saleor/components/ControlledCheckbox"; import Hr from "@saleor/components/Hr"; import RadioSwitchField from "@saleor/components/RadioSwitchField"; import RequirePermissions from "@saleor/components/RequirePermissions"; import { CollectionChannelListingErrorFragment } from "@saleor/fragments/types/CollectionChannelListingErrorFragment"; import { ProductChannelListingErrorFragment } from "@saleor/fragments/types/ProductChannelListingErrorFragment"; import useDateLocalize from "@saleor/hooks/useDateLocalize"; import useUser from "@saleor/hooks/useUser"; import ArrowDropdown from "@saleor/icons/ArrowDropdown"; import { RequireOnlyOne } from "@saleor/misc"; import { PermissionEnum } from "@saleor/types/globalTypes"; import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors"; import classNames from "classnames"; import React, { useState } from "react"; import { useIntl } from "react-intl"; import { DateContext } from "../Date/DateContext"; import { useStyles } from "./styles"; export interface ChannelData { id: string; isPublished: boolean; name: string; publicationDate: string | null; availableForPurchase?: string; isAvailableForPurchase?: boolean; visibleInListings?: boolean; } export interface Message { visibleLabel: string; hiddenLabel: string; visibleSecondLabel?: string; hiddenSecondLabel?: string; availableDateText?: string; availableLabel?: string; unavailableLabel?: string; availableSecondLabel?: string; setAvailabilityDateLabel?: string; } type Error = | ProductChannelListingErrorFragment | CollectionChannelListingErrorFragment; interface Value { availableForPurchase?: string; isAvailableForPurchase?: boolean; isPublished: boolean; publicationDate: string | null; visibleInListings?: boolean; } interface ChannelsAvailability { channels: ChannelData[]; channelsList: ChannelList[]; channelsMessages?: { [id: string]: Message }; errors?: Error[]; selectedChannelsCount: number; allChannelsCount: number; disabled?: boolean; onChange?: (id: string, data: Value) => void; openModal: () => void; } export type ChannelsAvailabilityProps = RequireOnlyOne< ChannelsAvailability, "channels" | "channelsList" >; interface ChannelProps { disabled?: boolean; data: ChannelData; errors: Error[]; messages: Message; onChange: (id: string, data: Value) => void; } const Channel: React.FC = ({ data, disabled, errors, messages, onChange }) => { const { availableForPurchase, isAvailableForPurchase: isAvailable, isPublished, publicationDate, visibleInListings, id, name } = data; const formData = { ...(availableForPurchase !== undefined ? { availableForPurchase } : {}), ...(isAvailable !== undefined ? { isAvailableForPurchase: isAvailable } : {}), isPublished, publicationDate, ...(visibleInListings !== undefined ? { visibleInListings } : {}) }; const dateNow = React.useContext(DateContext); const localizeDate = useDateLocalize(); const hasAvailableProps = isAvailable !== undefined && availableForPurchase !== undefined; const [isPublicationDate, setPublicationDate] = useState( publicationDate === null ? true : false ); const [isAvailableDate, setAvailableDate] = useState(false); const [isOpen, setOpen] = useState(false); const intl = useIntl(); const classes = useStyles({}); const todayDate = localizeDate(new Date(dateNow).toISOString(), "YYYY-MM-DD"); const visibleMessage = (date: string) => intl.formatMessage( { defaultMessage: "since {date}", description: "date" }, { date: localizeDate(date, "L") } ); const formErrors = getFormErrors( ["availableForPurchaseDate", "publicationDate"], errors ); return ( <>
setOpen(open => !open)} >
{name}
{messages.availableDateText}
{isOpen && ( <>

{messages.visibleLabel}

{isPublished && publicationDate && Date.parse(publicationDate) < dateNow && ( {messages.visibleSecondLabel || visibleMessage(publicationDate)} )} } name="isPublished" secondOptionLabel={ <>

{messages.hiddenLabel}

{publicationDate && !isPublished && Date.parse(publicationDate) >= dateNow && ( {messages.hiddenSecondLabel} )} } value={isPublished} onChange={() => { onChange(id, { ...formData, isPublished: !isPublished, publicationDate: !isPublished && !publicationDate ? todayDate : publicationDate }); }} /> {!isPublished && ( <> setPublicationDate(!isPublicationDate)} > {intl.formatMessage({ defaultMessage: "Set publication date" })} {isPublicationDate && ( onChange(id, { ...formData, publicationDate: e.target.value || null }) } className={classes.date} InputLabelProps={{ shrink: true }} /> )} )} {hasAvailableProps && ( <>

{messages.availableLabel}

{isAvailable && availableForPurchase && Date.parse(availableForPurchase) < dateNow && ( {visibleMessage(availableForPurchase)} )} } name={`channel:isAvailableForPurchase:${id}`} secondOptionLabel={ <>

{messages.unavailableLabel}

{availableForPurchase && !isAvailable && ( {messages.availableSecondLabel} )} } value={isAvailable} onChange={e => { const { value } = e.target; return onChange(id, { ...formData, availableForPurchase: !value ? null : availableForPurchase, isAvailableForPurchase: value }); }} /> {!isAvailable && ( <> setAvailableDate(!isAvailableDate)} > {messages.setAvailabilityDateLabel} {isAvailableDate && ( onChange(id, { ...formData, availableForPurchase: e.target.value }) } className={classes.date} InputLabelProps={{ shrink: true }} /> )} )} )} {visibleInListings !== undefined && ( <>

{intl.formatMessage({ defaultMessage: "Show in product listings" })}

{intl.formatMessage({ defaultMessage: "Disabling this checkbox will remove product from search and category pages. It will be available on collection pages." })} } onChange={e => onChange(id, { ...formData, visibleInListings: e.target.value }) } /> )} )}

); }; export const ChannelsAvailability: React.FC = props => { const { channelsList, errors = [], selectedChannelsCount, allChannelsCount, channels, channelsMessages, openModal, onChange } = props; const intl = useIntl(); const classes = useStyles({}); const { user } = useUser(); const channelsAvailabilityText = intl.formatMessage( { defaultMessage: "Available at {selectedChannelsCount} out of {allChannelsCount, plural, one {# channel} other {# channels}}", description: "channels availability text" }, { allChannelsCount, selectedChannelsCount } ); return ( <> } /> {!!channelsAvailabilityText && ( <> {channelsAvailabilityText}
)} {channels ? channels.map(data => { const channelErrors = errors?.filter(error => error.channels.includes(data.id)) || []; return ( ); }) : channelsList ? channelsList.map(data => (
{data.name}

)) : null}
); }; ChannelsAvailability.displayName = "ChannelsAvailability"; export default ChannelsAvailability;