-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #77 from SARDONYX-sard/feature/refactor-convrt-form
feat(front): impl `infer` & change design
- Loading branch information
Showing
26 changed files
with
734 additions
and
534 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 47 additions & 16 deletions
63
gui/frontend/src/components/atoms/ButtonWithToolTip/ButtonWithTooltip.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
61
gui/frontend/src/components/atoms/ConvertButton/ConvertButton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
gui/frontend/src/components/organisms/ConvertForm/CheckboxField.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
)} | ||
/> | ||
); | ||
}; |
Oops, something went wrong.