Skip to content

Commit

Permalink
Merge pull request #77 from SARDONYX-sard/feature/refactor-convrt-form
Browse files Browse the repository at this point in the history
feat(front): impl `infer` & change design
  • Loading branch information
SARDONYX-sard authored Oct 21, 2024
2 parents 91df885 + 91d1b47 commit a732d1c
Show file tree
Hide file tree
Showing 26 changed files with 734 additions and 534 deletions.
4 changes: 2 additions & 2 deletions gui/backend/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
"windows": [
{
"fullscreen": false,
"height": 920,
"height": 790,
"resizable": true,
"theme": "Dark",
"title": "DAR to OAR Converter",
"transparent": true,
"visible": false,
"width": 825,
"width": 980,
"windowEffects": {
"effects": ["micaDark"]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,56 @@
import { Button, type ButtonProps, Tooltip } from '@mui/material';
import { useEffect, useRef, useState } from 'react';

import type { ReactNode } from 'react';

type Props = {
buttonName: ReactNode;
tooltipTitle?: ReactNode;
icon?: ReactNode;
minWidth?: number;
minScreenWidth?: number;
} & ButtonProps;

export const ButtonWithToolTip = ({ buttonName, sx, tooltipTitle, ...props }: Props) => (
<Tooltip placement='bottom' title={tooltipTitle}>
<Button
sx={{
height: '60%',
marginTop: '9px',
width: '100%',
...sx,
}}
variant='outlined'
{...props}
>
{buttonName}
</Button>
</Tooltip>
);
export const ButtonWithToolTip = ({
buttonName,
tooltipTitle,
icon,
minWidth = 97,
minScreenWidth = 890, // Set default value for minimum screen width
...props
}: Props) => {
const buttonRef = useRef<HTMLButtonElement>(null);
const [canShowText, setCanShowText] = useState(true); // Default to showing icon

useEffect(() => {
const updateShowText = () => {
if (buttonRef.current) {
setCanShowText(window.innerWidth > minScreenWidth);
}
};

updateShowText();
window.addEventListener('resize', updateShowText);

return () => window.removeEventListener('resize', updateShowText);
}, [minScreenWidth]);

return (
<Tooltip placement='top' title={tooltipTitle}>
<Button
ref={buttonRef}
startIcon={canShowText ? icon : undefined}
sx={{
height: '55px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
variant='outlined'
{...props}
>
{canShowText ? buttonName : icon}
</Button>
</Tooltip>
);
};
61 changes: 54 additions & 7 deletions gui/frontend/src/components/atoms/ConvertButton/ConvertButton.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,79 @@
import ConvertIcon from '@mui/icons-material/Transform';
import LoadingButton, { type LoadingButtonProps } from '@mui/lab/LoadingButton';
import { useEffect, useState } from 'react';

import { CircularProgressWithLabel } from '@/components/atoms/CircularProgressWithLabel';
import { useTranslation } from '@/components/hooks/useTranslation';

type Props = LoadingButtonProps;
type Props = LoadingButtonProps & { progress: number };

/**
*
* Icon ref
* - https://mui.com/material-ui/material-icons/
*/
export function ConvertButton({ loading, ...props }: Props) {
export function ConvertButton({ loading, progress, ...props }: Props) {
const { t } = useTranslation();

// State to track when loading is complete
const [isComplete, setIsComplete] = useState(false);

useEffect(() => {
if (!loading && progress === 100) {
setIsComplete(true);

// Keep the "Converted 100%" text visible for 1 second
const completeTimer = setTimeout(() => {
setIsComplete(false); // Reset the background
}, 500);

return () => {
clearTimeout(completeTimer);
};
}
}, [loading, progress]);

return (
<LoadingButton
endIcon={<ConvertIcon />}
disabled={loading || isComplete}
endIcon={loading || isComplete ? <CircularProgressWithLabel value={progress} /> : <ConvertIcon />}
loading={loading}
loadingPosition='end'
sx={{
height: '40px',
minWidth: '100%',
height: '55px',
minWidth: '40%',
position: 'relative',
overflow: 'hidden',
transition: 'all 0.8s ease', // Smooth transition for button state change
...(loading || isComplete
? {
'&:before': {
content: '""',
position: 'absolute',
top: 0,
left: 0,
width: `${progress}%`, // Progress-based width
height: '100%',
backgroundColor: '#1e1f1e57',
zIndex: 0,
transition: 'width 0.5s ease-in-out',
transform: `scaleX(${progress / 100})`,
transformOrigin: 'left',
},
'& .MuiButton-label': {
position: 'relative',
zIndex: 1, // Keep label above background
opacity: loading ? 0.8 : 1,
transition: 'opacity 0.5s ease',
},
}
: {}),
}}
type='button'
type='submit'
variant='contained'
{...props}
>
<span>{loading ? t('converting-btn') : t('convert-btn')}</span>
<span>{loading ? t('converting-btn') : isComplete ? 'OK' : t('convert-btn')}</span>
</LoadingButton>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export const LogDirButton = ({ ...props }: Props) => {
<ButtonWithToolTip
{...props}
buttonName={t('open-log-dir-btn')}
icon={<FolderOpenIcon />}
onClick={handleClick}
startIcon={<FolderOpenIcon />}
tooltipTitle={t('open-log-dir-tooltip')}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export const LogFileButton = () => {
return (
<ButtonWithToolTip
buttonName={t('open-log-btn')}
icon={<FileOpen />}
onClick={handleClick}
startIcon={<FileOpen />}
tooltipTitle={t('open-log-tooltip')}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Checkbox, FormControlLabel, Box, Tooltip } from '@mui/material';
import { Controller, useFormContext } from 'react-hook-form';

import { STORAGE } from '@/lib/storage';

import type { FormProps } from './';
import type { ReactNode } from 'react';

type PickBooleans<T> = {
[K in keyof T as T[K] extends boolean ? K : never]: T[K];
};

type BoolFormProps = PickBooleans<FormProps>;

type CheckboxFieldProps = {
name: Exclude<keyof BoolFormProps, 'loading'>;
label: string;
icon?: ReactNode;
tooltipText: ReactNode;
};

export const CheckboxField = ({ name, label, tooltipText, icon }: CheckboxFieldProps) => {
const { control } = useFormContext<FormProps>();

return (
<Controller
control={control}
name={name}
render={({ field: { value, onChange } }) => (
<Tooltip title={tooltipText}>
<FormControlLabel
control={
<Checkbox
aria-label={label}
checked={value}
onClick={() => {
const newValue = !value;
STORAGE.set(name, `${newValue}`);
onChange(newValue);
}}
/>
}
label={
<Box component='div' sx={{ display: 'flex' }}>
{icon}
{label}
</Box>
}
/>
</Tooltip>
)}
/>
);
};
Loading

0 comments on commit a732d1c

Please sign in to comment.