saleor-dashboard/src/attributes/components/AttributeSwatchField/AttributeSwatchField.tsx

122 lines
3.6 KiB
TypeScript
Raw Normal View History

import VerticalSpacer from "@saleor/apps/components/VerticalSpacer";
import { inputTypeMessages } from "@saleor/attributes/components/AttributeDetails/messages";
import { AttributeValueEditDialogFormData } from "@saleor/attributes/utils/data";
import { ColorPicker } from "@saleor/components/ColorPicker";
import FileUploadField from "@saleor/components/FileUploadField";
import { RadioGroupField } from "@saleor/components/RadioGroupField";
Use graphql-codegen (#1874) * Use generated hooks in apps * Remove unused files * Use proper types in apps * Use generated hooks in attributes * Use generated hooks in auth module * Use generated hooks in categories * Use generated hooks in channels * Use generated types in collections * Remove legacy types from background tasks * Use generated hooks in customers * Use generated hooks in discounts * Use generated hook in file upload * Use generated types in gift cards * Use generated types in home * Use generated hooks in navigation * Use generated hooks in orders * Use generated hooks in pages * Use generated hooks in page types * Use generated hooks in permission groups * Use generated hooks in plugins * Use generated hooks in products * Use fragment to mark product variants * Improve code a bit * Use generated hooks in page types * Use generated types in searches * Use generated hooks in shipping * Use generated hooks in site settings * Use generated hooks in staff members * Use generated hooks in taxes * Place all gql generated files in one directory * Use generated hooks in translations * Use global types from new generated module * Use generated hooks in warehouses * Use generated hooks in webhooks * Use generated fragment types * Unclutter types * Remove hoc components * Split hooks and types * Fetch introspection file * Delete obsolete schema file * Fix rebase artifacts * Fix autoreplace * Fix auth provider tests * Fix urls * Remove leftover types * Fix rebase artifacts
2022-03-09 08:56:55 +00:00
import { useFileUploadMutation } from "@saleor/graphql";
import { UseFormResult } from "@saleor/hooks/useForm";
import useNotifier from "@saleor/hooks/useNotifier";
import { errorMessages } from "@saleor/intl";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { swatchFieldMessages } from "./messages";
import { useStyles } from "./styles";
type AttributeSwatchFieldProps<T> = Pick<
UseFormResult<T>,
"setError" | "set" | "errors" | "clearErrors" | "data"
>;
type SwatchType = "picker" | "image";
const AttributeSwatchField: React.FC<AttributeSwatchFieldProps<
AttributeValueEditDialogFormData
>> = ({ set, ...props }) => {
const { data } = props;
const notify = useNotifier();
const intl = useIntl();
const { formatMessage } = useIntl();
const classes = useStyles();
const [processing, setProcessing] = useState(false);
const [uploadFile] = useFileUploadMutation({});
const [type, setType] = useState<SwatchType>(
data.fileUrl ? "image" : "picker",
);
const handleColorChange = (hex: string) =>
set({ value: hex, fileUrl: undefined, contentType: undefined });
const handleFileUpload = async (file: File) => {
setProcessing(true);
const {
data: { fileUpload },
} = await uploadFile({ variables: { file } });
if (fileUpload.errors?.length) {
notify({
status: "error",
title: intl.formatMessage(errorMessages.imgageUploadErrorTitle),
text: intl.formatMessage(errorMessages.imageUploadErrorText),
});
} else {
set({
fileUrl: fileUpload.uploadedFile.url,
contentType: fileUpload.uploadedFile.contentType,
value: undefined,
});
}
setProcessing(false);
};
const handleFileDelete = () =>
set({
fileUrl: undefined,
contentType: undefined,
value: undefined,
});
return (
<>
<VerticalSpacer spacing={2} />
<RadioGroupField
choices={[
{
label: formatMessage(swatchFieldMessages.picker),
value: "picker",
},
{
label: formatMessage(swatchFieldMessages.image),
value: "image",
},
]}
variant="inline"
label={<FormattedMessage {...inputTypeMessages.swatch} />}
name="swatch"
value={type}
onChange={event => setType(event.target.value)}
data-test-id="swatch-radio"
/>
{type === "image" ? (
<>
<FileUploadField
disabled={processing}
loading={processing}
file={{ label: null, value: null, file: null }}
onFileUpload={handleFileUpload}
onFileDelete={handleFileDelete}
inputProps={{
accept: "image/*",
}}
/>
{data.fileUrl && (
<div
className={classes.filePreview}
style={{ backgroundImage: `url(${data.fileUrl})` }}
/>
)}
</>
) : (
<ColorPicker {...props} onColorChange={handleColorChange} />
)}
</>
);
};
AttributeSwatchField.displayName = "AttributeSwatchField";
export default AttributeSwatchField;