diff --git a/packages/webapp/src/containers/BrandingTemplates/BrandingTemplateForm.tsx b/packages/webapp/src/containers/BrandingTemplates/BrandingTemplateForm.tsx index 7c9920cd8..af94643a1 100644 --- a/packages/webapp/src/containers/BrandingTemplates/BrandingTemplateForm.tsx +++ b/packages/webapp/src/containers/BrandingTemplates/BrandingTemplateForm.tsx @@ -1,4 +1,6 @@ +// @ts-nocheck import * as Yup from 'yup'; +import { useState } from 'react'; import { ElementCustomize, ElementCustomizeProps, @@ -16,6 +18,7 @@ import { } from '@/hooks/query/pdf-templates'; import { FormikHelpers } from 'formik'; import { BrandingTemplateValues } from './types'; +import { useUploadAttachments } from '@/hooks/query/attachments'; interface BrandingTemplateFormProps extends ElementCustomizeProps { resource: string; @@ -37,8 +40,21 @@ export function BrandingTemplateForm({ const { mutateAsync: editPdfTemplate } = useEditPdfTemplate(); const initialValues = useBrandingTemplateFormInitialValues(defaultValues); - - const handleFormSubmit = (values: T, { setSubmitting }: FormikHelpers) => { + const [isUploading, setIsLoading] = useState(false); + + // Uploads the attachments. + const { mutateAsync: uploadAttachments } = useUploadAttachments({ + onSuccess: () => { + setIsLoading(true); + }, + }); + // Handles the form submitting. + // - Uploads the company logos. + // - Push the updated data. + const handleFormSubmit = async ( + values: T, + { setSubmitting }: FormikHelpers, + ) => { const handleSuccess = (message: string) => { AppToaster.show({ intent: Intent.SUCCESS, message }); setSubmitting(false); @@ -49,26 +65,44 @@ export function BrandingTemplateForm({ setSubmitting(false); onError && onError(); }; + + if (values.companyLogoFile) { + isUploading(true); + const formData = new FormData(); + const key = Date.now().toString(); + + formData.append('file', values.companyLogoFile); + formData.append('internalKey', key); + + try { + await uploadAttachments(formData); + setIsLoading(false); + } catch { + handleError('An error occurred while uploading company logo.'); + setIsLoading(false); + return; + } + } if (templateId) { const reqValues = transformToEditRequest(values); setSubmitting(true); - // Edit existing template - editPdfTemplate({ templateId, values: reqValues }) - .then(() => handleSuccess('PDF template updated successfully!')) - .catch(() => - handleError('An error occurred while updating the PDF template.'), - ); + try { + await editPdfTemplate({ templateId, values: reqValues }); + handleSuccess('PDF template updated successfully!'); + } catch { + handleError('An error occurred while updating the PDF template.'); + } } else { const reqValues = transformToNewRequest(values, resource); setSubmitting(true); - // Create new template - createPdfTemplate(reqValues) - .then(() => handleSuccess('PDF template created successfully!')) - .catch(() => - handleError('An error occurred while creating the PDF template.'), - ); + try { + await createPdfTemplate(reqValues); + handleSuccess('PDF template created successfully!'); + } catch { + handleError('An error occurred while creating the PDF template.'); + } } }; diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/CompanyLogoUpload.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/CompanyLogoUpload.tsx new file mode 100644 index 000000000..f59f6e600 --- /dev/null +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/CompanyLogoUpload.tsx @@ -0,0 +1,88 @@ +// @ts-nocheck +import { useRef, useState } from 'react'; +import { Button, Intent } from '@blueprintjs/core'; +import clsx from 'classnames'; +import { Box, Icon, Stack } from '@/components'; +import { Dropzone, DropzoneProps } from '@/components/Dropzone'; +import { MIME_TYPES } from '@/components/Dropzone/mine-types'; +import { useUncontrolled } from '@/hooks/useUncontrolled'; +import styles from './CompanyLogoUpload.module.scss'; + +export interface CompanyLogoUploadProps { + initialValue?: File; + value?: File; + onChange?: (file: File) => void; + dropzoneProps?: DropzoneProps; + uploadIcon?: JSX.Element; + title?: string; + classNames?: Record; +} + +export function CompanyLogoUpload({ + initialValue, + value, + onChange, + dropzoneProps, + uploadIcon = , + title = 'Drag images here or click to select files', + classNames, +}: CompanyLogoUploadProps) { + const [localValue, handleChange] = useUncontrolled({ + value, + initialValue, + finalValue: null, + onChange, + }); + const openRef = useRef<() => void>(null); + + const handleRemove = () => { + handleChange(null); + }; + const imagePreviewUrl = localValue ? URL.createObjectURL(localValue) : ''; + + return ( + handleChange(files[0])} + onReject={(files) => console.log('rejected files', files)} + maxSize={5 * 1024 ** 2} + accept={[MIME_TYPES.png, MIME_TYPES.jpeg]} + classNames={{ root: styles?.root, content: styles.dropzoneContent }} + activateOnClick={false} + openRef={openRef} + {...dropzoneProps} + > + + {localValue ? ( + + + + + )} + + + ); +} diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/InvoiceCustomizeGeneralFields.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/InvoiceCustomizeGeneralFields.tsx index 5ec48a7a1..0efa1a591 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/InvoiceCustomizeGeneralFields.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/InvoiceCustomizeGeneralFields.tsx @@ -12,6 +12,8 @@ import { FColorInput } from '@/components/Forms/FColorInput'; import { CreditCardIcon } from '@/icons/CreditCardIcon'; import { Overlay } from './Overlay'; import { useIsTemplateNamedFilled } from '@/containers/BrandingTemplates/utils'; +import { CompanyLogoUpload } from './CompanyLogoUpload'; +import { useFormikContext } from 'formik'; export function InvoiceCustomizeGeneralField() { const isTemplateNameFilled = useIsTemplateNamedFilled(); @@ -75,6 +77,8 @@ export function InvoiceCustomizeGeneralField() { fastField /> + + @@ -99,7 +103,24 @@ function InvoiceCustomizePaymentManage() { Accept payment methods - Manage + Manage ); } + +function CompanyLogoUploadField() { + const { setFieldValue } = useFormikContext(); + + return ( + + { + const imageUrl = file ? URL.createObjectURL(file) : ''; + + setFieldValue('companyLogoFile', file); + setFieldValue('companyLogo', imageUrl); + }} + /> + + ); +}