feat: change colors in png init

This commit is contained in:
Ibrahima G. Coulibaly
2024-06-24 02:51:22 +01:00
parent 9657e60eca
commit ee6c0293bf
12 changed files with 309 additions and 28 deletions

View File

@@ -0,0 +1,10 @@
import Typography from '@mui/material/Typography';
import React from 'react';
export default function InputHeader({ title }: { title: string }) {
return (
<Typography mb={1} fontSize={30} color={'primary'}>
{title}
</Typography>
);
}

View File

@@ -29,7 +29,7 @@ export default function ToolHeader({
description
}: ToolHeaderProps) {
return (
<Stack direction={'row'} alignItems={'center'} spacing={2} mt={4}>
<Stack direction={'row'} alignItems={'center'} spacing={2} my={4}>
<Box>
<Typography mb={2} fontSize={30} color={'primary'}>
{title}

View File

@@ -0,0 +1,24 @@
import { Stack } from '@mui/material';
import Button from '@mui/material/Button';
import PublishIcon from '@mui/icons-material/Publish';
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
import React from 'react';
export default function InputFooter({
handleImport,
handleCopy
}: {
handleImport: () => void;
handleCopy: () => void;
}) {
return (
<Stack mt={1} direction={'row'} spacing={2}>
<Button onClick={handleImport} startIcon={<PublishIcon />}>
Import from file
</Button>
<Button onClick={handleCopy} startIcon={<ContentPasteIcon />}>
Copy to clipboard
</Button>
</Stack>
);
}

View File

@@ -0,0 +1,114 @@
import { Box, styled, TextField, useTheme } from '@mui/material';
import Typography from '@mui/material/Typography';
import React, { useContext, useEffect, useRef, useState } from 'react';
import InputHeader from '../InputHeader';
import InputFooter from './InputFooter';
import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
import greyPattern from '@assets/grey-pattern.png';
interface ToolFileInputProps {
value: File | null;
onChange: (file: File) => void;
accept: string[];
title?: string;
}
export default function ToolFileInput({
value,
onChange,
accept,
title = 'File'
}: ToolFileInputProps) {
const [preview, setPreview] = useState<string | null>(null);
const theme = useTheme();
const { showSnackBar } = useContext(CustomSnackBarContext);
const fileInputRef = useRef<HTMLInputElement>(null);
const handleCopy = () => {
navigator.clipboard
.writeText(value?.name ?? '')
.then(() => showSnackBar('Text copied', 'success'))
.catch((err) => {
showSnackBar('Failed to copy: ' + err, 'error');
});
};
useEffect(() => {
if (value) {
const objectUrl = URL.createObjectURL(value);
setPreview(objectUrl);
// Clean up memory when the component is unmounted or the file changes
return () => URL.revokeObjectURL(objectUrl);
} else {
setPreview(null);
}
}, [value]);
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) onChange(file);
};
const handleImportClick = () => {
fileInputRef.current?.click();
};
return (
<Box>
<InputHeader title={title} />
<Box
sx={{
width: '100%',
height: 250,
border: preview ? 0 : 1,
borderRadius: 2,
boxShadow: '5'
}}
>
{preview ? (
<Box
width={'100%'}
height={'100%'}
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundImage: `url(${greyPattern})`
}}
>
<img
src={preview}
alt="Preview"
style={{ maxWidth: '100%', maxHeight: 250 }}
/>
</Box>
) : (
<Box
onClick={handleImportClick}
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
padding: 5,
height: '100%',
cursor: 'pointer'
}}
>
<Typography color={theme.palette.grey['600']}>
Click here to select an image from your device, press Ctrl+V to
use an image from your clipboard, drag and drop a file from
desktop
</Typography>
</Box>
)}
</Box>
<InputFooter handleCopy={handleCopy} handleImport={handleImportClick} />
<input
ref={fileInputRef}
style={{ display: 'none' }}
type="file"
accept={accept.join(',')}
onChange={handleFileChange}
/>
</Box>
);
}

View File

@@ -5,6 +5,8 @@ import PublishIcon from '@mui/icons-material/Publish';
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
import React, { useContext, useRef } from 'react';
import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
import InputHeader from '../InputHeader';
import InputFooter from './InputFooter';
export default function ToolTextInput({
value,
@@ -45,9 +47,7 @@ export default function ToolTextInput({
};
return (
<Box id="tool">
<Typography fontSize={30} color={'primary'}>
{title}
</Typography>
<InputHeader title={title} />
<TextField
value={value}
onChange={(event) => onChange(event.target.value)}
@@ -55,14 +55,7 @@ export default function ToolTextInput({
multiline
rows={10}
/>
<Stack mt={1} direction={'row'} spacing={2}>
<Button onClick={handleImportClick} startIcon={<PublishIcon />}>
Import from file
</Button>
<Button onClick={handleCopy} startIcon={<ContentPasteIcon />}>
Copy to clipboard
</Button>
</Stack>
<InputFooter handleCopy={handleCopy} handleImport={handleImportClick} />
<input
type="file"
accept="*"

View File

@@ -0,0 +1,59 @@
import { Box } from '@mui/material';
import React from 'react';
import InputHeader from '../InputHeader';
import greyPattern from '@assets/grey-pattern.png';
export default function ToolFileResult({
title = 'Result',
value
}: {
title?: string;
value: File | null;
}) {
const [preview, setPreview] = React.useState<string | null>(null);
React.useEffect(() => {
if (value) {
const objectUrl = URL.createObjectURL(value);
setPreview(objectUrl);
return () => URL.revokeObjectURL(objectUrl);
} else {
setPreview(null);
}
}, [value]);
return (
<Box>
<InputHeader title={title} />
<Box
sx={{
width: '100%',
height: 250,
border: preview ? 0 : 1,
borderRadius: 2,
boxShadow: '5'
}}
>
{preview && (
<Box
width={'100%'}
height={'100%'}
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundImage: `url(${greyPattern})`
}}
>
<img
src={preview}
alt="Result"
style={{ maxWidth: '100%', maxHeight: 250 }}
/>
</Box>
)}
</Box>
</Box>
);
}

View File

@@ -5,6 +5,7 @@ import DownloadIcon from '@mui/icons-material/Download';
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
import React, { useContext } from 'react';
import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext';
import InputHeader from '../InputHeader';
export default function ToolTextResult({
title = 'Result',
@@ -37,9 +38,7 @@ export default function ToolTextResult({
};
return (
<Box>
<Typography fontSize={30} color={'primary'}>
{title}
</Typography>
<InputHeader title={title} />
<TextField value={value} fullWidth multiline rows={10} />
<Stack mt={1} direction={'row'} spacing={2}>
<Button onClick={handleDownload} startIcon={<DownloadIcon />}>