import FuseLoading from
import FuseLoading from
if (!isValidImage(file)) {
setToastMessage(t('invalidImage'));
return;
}
try {
const uploadedUrl = await uploadImage({rawFile: file});
if (type === 'heroBanner') {
setUploadedImageUrlHero(uploadedUrl);
} else {
setUploadedImageUrlDetails(uploadedUrl);
}
} catch (error) {
setToastMessage(t('uploadError'));
// Log más detalles sobre el error
logger.error('Error uploading image:', error, {
file,
type,
});
}
};
setUploadedImageUrlHero(uploadedHeroUrl);
}}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++
TABLELIST
function LotteryThemesTable() {
const {t, i18n} = useTranslation('lotteryThemePage');
const queryClient = useQueryClient();
useEffect(() => {
if (data) {
// Process data asynchronously
const processData = async () => {
const processedValues = await Promise.all(
data.map(async (value) => {
const lotteryLabel = await fetchLotteryById({
dto: {lotteryId: value.lotteryId},
});
return {...value, name: lotteryLabel.lottery.label};
})
);
setLotteryThemes(processedValues);
};
processData();
}
}, [data]);
useEffect(() => {
const handleInvalidateOnFocus = () => {
queryClient.invalidateQueries({
queryKey: ['lotteryTheme'], // Clave para filtrar consultas
});
};
window.addEventListener('focus', handleInvalidateOnFocus);
return () => window.removeEventListener('focus', handleInvalidateOnFocus);
}, [queryClient]);
if (isLoading || !lotteryThemes) {
return <FuseLoading />;
}
return (
<Paper
className="flex flex-col flex-auto shadow-3 rounded-t-16 overflow-
hidden rounded-b-0 w-full h-full"
elevation={0}
>
<DataTable
initialState={{
density: 'spacious',
columnPinning: {
left: ['mrt-row-expand', 'mrt-row-select'],
right: ['mrt-row-actions'],
},
}}
data={lotteryThemes || []}
columns={columns}
enableRowSelection={false}
enableColumnDragging={false}
rowCount={lotteryThemes.length || 0}
enableRowActions={false}
enableColumnActions={false}
enableToolbarInternalActions={false}
renderTopToolbarCustomActions={() => (
<Box
sx={{
display: 'flex',
justifyContent: 'flex-end',
gap: '1rem',
padding: '8px 16px',
width: '100%',
}}
>
<Button variant="text" color="secondary"
sx={{textTransform: 'uppercase'}} onClick={() => null}>
{t('createJSON')}
</Button>
<Button
variant="text"
color="secondary"
sx={{textTransform: 'uppercase'}}
component={NavLinkAdapter}
to="new"
>
{t('create')}
</Button>
</Box>
)}
/>
</Paper>
);
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++
CreatePage
type TMutationError = {
response?: {
errors: {message: string}[];
};
};
interface IThemeDeviceConfig {
heroBanner: {
src: string | {base64: string; fileName: string} | null;
title: string;
};
detailsImage: {
src: string | {base64: string; fileName: string} | null;
title: string;
};
}
interface ITheme {
lotteryId: string;
desktop?: IThemeDeviceConfig;
mobile?: IThemeDeviceConfig;
}
useEffect(() => {
if (deviceType === 'desktop') {
setUploadedImageUrlHeroDesktop(uploadedImageUrlHeroDesktop);
setUploadedImageUrlDetailsDesktop(uploadedImageUrlDetailsDesktop);
} else {
setUploadedImageUrlHeroMobile(uploadedImageUrlHeroMobile);
setUploadedImageUrlDetailsMobile(uploadedImageUrlDetailsMobile);
}
}, [deviceType]);
return {
url,
deviceType,
imageType,
};
};
try {
const imagesToUpload: Array<Parameters<typeof handleThemeImageUpload>>
= [];
if (uploadedImageUrlHeroDesktop?.base64) {
imagesToUpload.push([lotteryId,
uploadedImageUrlHeroDesktop?.base64, 'desktop', 'hero']);
}
if (uploadedImageUrlDetailsDesktop?.base64) {
imagesToUpload.push([lotteryId,
uploadedImageUrlDetailsDesktop?.base64, 'desktop', 'details']);
}
if (uploadedImageUrlHeroMobile?.base64) {
imagesToUpload.push([lotteryId, uploadedImageUrlHeroMobile?.base64,
'mobile', 'hero']);
}
if (uploadedImageUrlDetailsMobile?.base64) {
imagesToUpload.push([lotteryId,
uploadedImageUrlDetailsMobile?.base64, 'mobile', 'details']);
}
console.log('imagesToUpload: ', uploadedImageUrlHeroDesktop);
// Fetch the current themes to check if one already exists for the
selected lottery
const configuration = await fetchTheme();
const rawConfigurationValue: string = configuration.configuration.value
|| '[]';
let lotteriesThemesList: ITheme[];
try {
lotteriesThemesList = JSON.parse(rawConfigurationValue);
if (!Array.isArray(lotteriesThemesList)) {
//console.error('lotteriesThemesList is not an array:',
lotteriesThemesList);
lotteriesThemesList = [];
}
} catch (parseError) {
//console.error('Error parsing configuration value:', parseError,
rawConfigurationValue);
lotteriesThemesList = [];
}
if (currentTheme) {
// If a theme already exists for this lottery, prevent creating a
new one
setToastMessage(t('themeAlreadyExists'));
return;
}
if (!currentTheme) {
currentTheme = {
lotteryId,
desktop: {
heroBanner: {
src: '',
title: '',
},
detailsImage: {
src: '',
title: '',
},
},
mobile: {
heroBanner: {
src: '',
title: '',
},
detailsImage: {
src: '',
title: '',
},
},
};
case 'details':
accumulator.detailsImage.src = `$
{currentValue.url}?v=${uploadVersion}`;
break;
default:
break;
}
return accumulator;
},
{...currentTheme.desktop}
);
case 'details':
accumulator.detailsImage.src = `$
{currentValue.url}?v=${uploadVersion}`;
break;
default:
break;
}
return accumulator;
},
{...currentTheme.mobile}
);
await createThemeMutation(payload);
setToastMessage(t('createSuccessfully'));
setIsSaved(true);
} catch (error) {
logger.error('Error saving theme:', error);
setToastMessage(t('somethingWrong'));
}
};
useEffect(() => {
if (isSaved) {
setTimeout(() => {
navigate('/lottery-theme');
}, 500);
}
}, [isSaved]);
if (loadingLotteries) {
return <FuseLoading />;
}
return (
<FormProvider {...methods}>
<FusePageCarded
header={<LotteryThemesCreateHeader />}
content={
<Box className="p-16 sm:p-24 max-w-lg">
<Select
name="lotteryId"
value={lotteryId}
labelId="lottery-select-label"
onChange={(e) => {
const selectedValue = e.target.value;
setLotteryId(selectedValue || '');
}}
displayEmpty
sx={{width: '400px', mb: '30px'}}
>
<MenuItem id="lottery-select-label" value="">
{t('lottery')}
</MenuItem>
{renderLotteries}
</Select>
<RadioGroup
name="deviceType"
value={deviceType}
onChange={(e) => setDeviceType(e.target.value as
'desktop' | 'mobile')}
sx={{flexDirection: 'row', m: '0px'}}
>
<FormControlLabel
value="desktop"
control={<Radio />}
label={t('desktop')}
labelPlacement="start"
/>
<FormControlLabel
value="mobile"
control={<Radio />}
label={t('mobile')}
labelPlacement="start"
/>
</RadioGroup>
setUploadedImageUrlHeroDesktop(uploadedImageUrl);
} else {
setUploadedImageUrlHeroMobile(uploadedImageUrl);
}
}
}}
/>
</Button>
)}
/>
</Box>
<Box sx={{mt: '30px'}}>
<Typography className="text-12" color="primary">
{t('details')}
</Typography>
<Controller
name="imageDetails"
control={control}
render={() => (
<Button
variant="outlined"
component="label"
sx={{
mt: 2,
borderRadius: '5px',
border: 'none',
backgroundColor: '#f5f5f5',
pt: (
deviceType === 'desktop'
?
uploadedImageUrlDetailsDesktop
:
uploadedImageUrlDetailsMobile
)
? '90px'
: '30px',
pb: (
deviceType === 'desktop'
?
uploadedImageUrlDetailsDesktop
:
uploadedImageUrlDetailsMobile
)
? '90px'
: '30px',
width: '300px',
height: '150px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
...(deviceType === 'desktop' &&
uploadedImageUrlDetailsDesktop
&& {
width: '100%',
height: '100%',
}),
...(deviceType === 'mobile' &&
uploadedImageUrlDetailsMobile
&& {
width: '100%',
height: '100%',
}),
}}
>
{(
deviceType === 'desktop'
?
uploadedImageUrlDetailsDesktop
: uploadedImageUrlDetailsMobile
) ? (
<img
src={
deviceType === 'desktop'
?
uploadedImageUrlDetailsDesktop.url
:
uploadedImageUrlDetailsMobile.url
}
alt="Uploaded preview"
style={{
maxWidth: '100%',
maxHeight: '100%',
objectFit: 'contain',
borderRadius: '8px',
minWidth: '150px',
minHeight: '150px',
}}
/>
) : (
t('uploadPicture')
)}
<input
accept="image/*"
className="hidden"
id="button-file"
type="file"
onChange={async (e) => {
const file = e.target.files?.
[0];
if (file) {
const uploadedImageUrl =
await readFileAsync(file);
if (deviceType ===
'desktop') {
setUploadedImageUrlDetailsDesktop(uploadedImageUrl);
} else {
setUploadedImageUrlDetailsMobile(uploadedImageUrl);
}
}
}}
/>
</Button>
)}
/>
</Box>
</Box>
<Button
className="mt-40"
variant="contained"
color="primary"
onClick={handleCreateTheme}
disabled={isLoading}
sx={{borderRadius: '5px'}}
>
{isLoading ? <CircularProgress size={24}
color="inherit" /> : t('save')}
</Button>
</Box>
}
/>
<Snackbar
anchorOrigin={{vertical: 'bottom', horizontal: 'center'}}
open={!!toastMessage}
autoHideDuration={3000}
onClose={() => setToastMessage(null)}
message={toastMessage}
/>
</FormProvider>
);
}