mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 05:10:31 +00:00
feat: Uploading company logo
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Box, Group } from '@/components';
|
||||
import { Group } from '@/components';
|
||||
import { ElementCustomizeProvider } from './ElementCustomizeProvider';
|
||||
import {
|
||||
ElementCustomizeForm,
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// @ts-nocheck
|
||||
import { useFormikContext } from 'formik';
|
||||
import { FFormGroup } from '@/components';
|
||||
import { CompanyLogoUpload } from './CompanyLogoUpload';
|
||||
|
||||
export function BrandingCompanyLogoUploadField() {
|
||||
const { setFieldValue, values } = useFormikContext();
|
||||
|
||||
return (
|
||||
<FFormGroup name={'companyLogo'} label={''} fastField>
|
||||
<CompanyLogoUpload
|
||||
initialPreview={values.companyLogoUri}
|
||||
onChange={(file) => {
|
||||
const imageUrl = file ? URL.createObjectURL(file) : '';
|
||||
|
||||
setFieldValue('_companyLogoFile', file);
|
||||
setFieldValue('companyLogoUri', imageUrl);
|
||||
}}
|
||||
/>
|
||||
</FFormGroup>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
.root {
|
||||
min-height: 120px;
|
||||
height: 120px;
|
||||
padding: 10px;
|
||||
border: 1px solid;
|
||||
display: flex;
|
||||
border: 1px solid #E1E1E1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
&:hover .removeButton{
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.removeButton{
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
border-radius: 24px;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.contentPrePreview {
|
||||
color: #738091;
|
||||
font-size: 13px;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dropzoneContent{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.previewImage{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// @ts-nocheck
|
||||
import { useRef, useState } from 'react';
|
||||
import { Button, Intent } from '@blueprintjs/core';
|
||||
import { 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 {
|
||||
/** Initial preview uri. */
|
||||
initialPreview?: string;
|
||||
|
||||
/** The initial file object for uploading */
|
||||
initialValue?: File;
|
||||
|
||||
/** The current file object for uploading */
|
||||
value?: File;
|
||||
|
||||
/** Function called when the file is changed */
|
||||
onChange?: (file: File) => void;
|
||||
|
||||
/** Props for the Dropzone component */
|
||||
dropzoneProps?: DropzoneProps;
|
||||
|
||||
/** Icon element for the upload button */
|
||||
uploadIcon?: JSX.Element;
|
||||
|
||||
/** Title displayed in the component */
|
||||
title?: string;
|
||||
|
||||
/** Custom CSS class names for styling */
|
||||
classNames?: Record<string, string>;
|
||||
}
|
||||
|
||||
export function CompanyLogoUpload({
|
||||
initialPreview,
|
||||
initialValue,
|
||||
value,
|
||||
onChange,
|
||||
dropzoneProps,
|
||||
uploadIcon = <Icon icon="download" iconSize={26} />,
|
||||
title = 'Drag images here or click to select files',
|
||||
classNames,
|
||||
}: CompanyLogoUploadProps) {
|
||||
const [localValue, handleChange] = useUncontrolled<File | null>({
|
||||
value,
|
||||
initialValue,
|
||||
finalValue: null,
|
||||
onChange,
|
||||
});
|
||||
const [initialLocalPreview, setInitialLocalPreview] = useState<string | null>(
|
||||
initialPreview || null,
|
||||
);
|
||||
|
||||
const openRef = useRef<() => void>(null);
|
||||
|
||||
const handleRemove = () => {
|
||||
handleChange(null);
|
||||
setInitialLocalPreview(null);
|
||||
};
|
||||
const imagePreviewUrl = localValue
|
||||
? URL.createObjectURL(localValue)
|
||||
: initialLocalPreview || '';
|
||||
|
||||
return (
|
||||
<Dropzone
|
||||
onDrop={(files) => 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}
|
||||
>
|
||||
{imagePreviewUrl ? (
|
||||
<span>
|
||||
<img src={imagePreviewUrl} alt="" className={styles.previewImage} />
|
||||
<Button
|
||||
minimal
|
||||
intent={Intent.DANGER}
|
||||
onClick={handleRemove}
|
||||
icon={<Icon icon={'smallCross'} iconSize={16} />}
|
||||
className={styles?.removeButton}
|
||||
/>
|
||||
</span>
|
||||
) : (
|
||||
<Stack spacing={10} align="center" className={styles.contentPrePreview}>
|
||||
{title && <span className={styles.title}>{title}</span>}
|
||||
<Button
|
||||
intent="none"
|
||||
onClick={() => openRef.current?.()}
|
||||
style={{ pointerEvents: 'all' }}
|
||||
minimal
|
||||
outlined
|
||||
small
|
||||
>
|
||||
{'Upload File'}
|
||||
</Button>
|
||||
</Stack>
|
||||
)}
|
||||
</Dropzone>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user