Skip to content

Commit

Permalink
#3060-created edit logo
Browse files Browse the repository at this point in the history
  • Loading branch information
caiodasilva2005 committed Dec 13, 2024
1 parent e59e07b commit eec9ffd
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 75 deletions.
Binary file added src/frontend/public/default-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/frontend/src/hooks/organizations.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ export const useSetOrganizationLogo = () => {
};

export const useOrganizationLogo = () => {
return useQuery<string, Error>(['organizations', 'logo'], async () => {
return useQuery<{ url: string; blob: Blob }, Error>(['organizations', 'logo'], async () => {
const { data: fileId } = await getOrganizationLogo();

const imageBlob = await downloadGoogleImage(fileId);

return URL.createObjectURL(imageBlob);
return { url: URL.createObjectURL(imageBlob), blob: imageBlob };
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const EditDescription: React.FC = () => {
return (
<Card
sx={{
width: { xs: '100%', md: '50%' },
width: '100%',
background: 'transparent',
padding: 2,
...(isEditMode && {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const EditFeaturedProjects = () => {
return (
<Card
sx={{
width: { xs: '100%', md: '50%' },
width: '100%',
background: 'transparent',
padding: 2,
...(isEditMode && {
Expand Down
75 changes: 66 additions & 9 deletions src/frontend/src/pages/AdminToolsPage/EditGuestView/EditLogo.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,86 @@
import React from 'react';
import { useCurrentOrganization, useSetOrganizationLogo } from '../../../hooks/organizations.hooks';
import React, { useState } from 'react';
import { useCurrentOrganization, useOrganizationLogo, useSetOrganizationLogo } from '../../../hooks/organizations.hooks';
import LoadingIndicator from '../../../components/LoadingIndicator';
import EditLogoForm from './EditLogoForm';
import EditLogoForm, { EditLogoInput } from './EditLogoForm';
import { useToast } from '../../../hooks/toasts.hooks';
import { Box, Card, Typography, useTheme } from '@mui/material';
import LogoDisplay from '../../HomePage/components/LogoDisplay';
import { NERButton } from '../../../components/NERButton';

const EditLogo = () => {
const { data: organization, isLoading: organizationIsLoading } = useCurrentOrganization();
const { mutateAsync } = useSetOrganizationLogo();
const { data: imageData, isLoading: imageDataIsLoading } = useOrganizationLogo();
const { mutateAsync, isLoading } = useSetOrganizationLogo();
const toast = useToast();
const [isEditMode, setIsEditMode] = useState(false);
const theme = useTheme();

if (organizationIsLoading || !organization) return <LoadingIndicator />;
if (isLoading || !mutateAsync || organizationIsLoading || !organization || !imageData || imageDataIsLoading)
return <LoadingIndicator />;

const onSubmitWrapper = async (logoImage: File) => {
const handleClose = () => {
setIsEditMode(false);
};

const onSubmit = async (logoInput: EditLogoInput) => {
try {
await mutateAsync(logoImage);
console.log(logoInput);
if (!logoInput.logoImage) {
handleClose();
return;
}
await mutateAsync(logoInput.logoImage);
toast.success('Logo updated successfully!');
} catch (e) {
if (e instanceof Error) {
toast.error(e.message);
}
}
await mutateAsync(logoImage);
handleClose();
};

return <EditLogoForm onSubmit={onSubmitWrapper} />;
return (
<Card
sx={{
width: '100%',
background: 'transparent',
padding: 2,
...(isEditMode && {
background: theme.palette.background.paper,
padding: 1.9,
variant: 'outlined'
})
}}
variant={isEditMode ? 'outlined' : undefined}
>
<Typography variant="h4" mb={1}>
{organization.name} Logo
</Typography>
{isEditMode ? (
<EditLogoForm
onSubmit={onSubmit}
onHide={handleClose}
orgLogo={new File([imageData.blob], imageData.blob.name, { type: imageData.blob.type })}
/>
) : (
<>
<Box sx={{ display: 'flex', flexDirection: 'column', height: 350, width: 300 }}>
<LogoDisplay imageUrl={imageData ? imageData.url : undefined} />
<Box
sx={{
display: 'flex',
justifyContent: 'end'
}}
>
<NERButton variant="contained" sx={{ my: 2 }} onClick={() => setIsEditMode(true)}>
Update
</NERButton>
</Box>
</Box>
</>
)}
</Card>
);
};

export default EditLogo;
155 changes: 109 additions & 46 deletions src/frontend/src/pages/AdminToolsPage/EditGuestView/EditLogoForm.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,120 @@
import React from 'react';
import { Box, Button, Stack, useTheme } from '@mui/material';
import { Box, Button, FormControl, Stack, Typography } from '@mui/material';
import FileUploadIcon from '@mui/icons-material/FileUpload';
import LogoDisplay from '../../HomePage/components/LogoDisplay';
import { Controller, useForm } from 'react-hook-form';
import NERFailButton from '../../../components/NERFailButton';
import NERSuccessButton from '../../../components/NERSuccessButton';
import ImageIcon from '@mui/icons-material/Image';

export interface EditLogoInput {
logoImage?: File;
}

interface EditLogoFormProps {
onSubmit: (logoImage: File) => Promise<void>;
onSubmit: (logoImage: EditLogoInput) => Promise<void>;
onHide: () => void;
orgLogo: File;
}

const EditLogoForm: React.FC<EditLogoFormProps> = ({ onSubmit }) => {
const theme = useTheme();
return (
<Stack spacing={2}>
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
background: theme.palette.background.paper,
width: 300,
height: 300,
borderRadius: 2,
boxShadow: 3
}}
>
<LogoDisplay />
</Box>
const EditLogoForm: React.FC<EditLogoFormProps> = ({ onSubmit, orgLogo, onHide }) => {
const { handleSubmit, control, reset } = useForm({
defaultValues: {
logoImage: orgLogo
}
});

<Button
variant="contained"
color="error"
component="label"
startIcon={<FileUploadIcon />}
sx={{
width: 'fit-content',
textTransform: 'none',
mt: '9.75px',
color: 'black'
}}
>
Upload
<input
onChange={(e) => {
!!e.target.files && onSubmit(e.target.files[0]);
const onSubmitWrapper = async (data: EditLogoInput) => {
await onSubmit(data);
reset();
};

const onHideWrapper = () => {
onHide();
reset();
};

return (
<form
id="edit-organization-logo"
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
handleSubmit(onSubmit)(e);
reset();
}}
onKeyPress={(e) => {
e.key === 'Enter' && e.preventDefault();
}}
>
<Stack spacing={2}>
<FormControl sx={{ width: '100%' }}>
<Controller
name={'logoImage'}
control={control}
rules={{ required: true }}
render={({ field: { onChange, value } }) => (
<Box
sx={{
display: 'flex',
flexDirection: 'row',
gap: 1
}}
>
<Button
variant="contained"
color="error"
component="label"
startIcon={<FileUploadIcon />}
sx={{
width: 'fit-content',
textTransform: 'none',
mt: '9.75px',
color: 'black'
}}
>
Upload
<input
onChange={(e) => {
onChange(!!e.target.files && e.target.files[0]);
}}
type="file"
id="logo-image"
accept="image/png, image/jpeg"
name="logoImageFile"
multiple
hidden
/>
</Button>
{value.name !== 'undefined' && (
<Stack direction={'row'} spacing={1} mt={2}>
<ImageIcon />
<Typography>{value.name}</Typography>
</Stack>
)}
</Box>
)}
/>
</FormControl>
<Box
sx={{
display: 'flex',
justifyContent: 'end'
}}
type="file"
id="logo-image"
accept="image/png, image/jpeg, application/pdf"
name="logoImageFile"
multiple
hidden
/>
</Button>
</Stack>
>
<NERFailButton sx={{ mx: 1 }} form={'edit-organization-logo'} onClick={onHideWrapper}>
Cancel
</NERFailButton>
<NERSuccessButton
sx={{ mx: 1 }}
type="submit"
form={'edit-organization-logo'}
onClick={handleSubmit(onSubmitWrapper)}
>
Save
</NERSuccessButton>
</Box>
</Stack>
</form>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { Stack } from '@mui/material';
import { Stack, Grid } from '@mui/material';
import EditDescription from './EditDescription';
import EditFeaturedProjects from './EditFeaturedProjects';
import EditLogo from './EditLogo';

const GuestViewConfig: React.FC = () => {
return (
<Stack spacing={2}>
<EditDescription />
<EditFeaturedProjects />
</Stack>
<Grid container spacing={2}>
<Grid item xs={6}>
<Stack spacing={2}>
<EditDescription />
<EditFeaturedProjects />
</Stack>
</Grid>
<Grid item xs={6}>
<EditLogo />
</Grid>
</Grid>
);
};

Expand Down
31 changes: 20 additions & 11 deletions src/frontend/src/pages/HomePage/components/LogoDisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import { Box } from '@mui/material';
import { Box, useTheme, Card } from '@mui/material';
import React from 'react';
import { useOrganizationLogo } from '../../../hooks/organizations.hooks';
import LoadingIndicator from '../../../components/LoadingIndicator';

const LogoDisplay = () => {
const { data: imageUrl, isLoading } = useOrganizationLogo();

if (isLoading) return <LoadingIndicator />;
interface LogoDisplayProps {
imageUrl?: string;
}

const LogoDisplay: React.FC<LogoDisplayProps> = ({ imageUrl = './default-logo.png' }) => {
const theme = useTheme();
return (
<Box
component="img"
src={imageUrl ?? '/logo.png'}
<Card
variant={'outlined'}
sx={{
background: theme.palette.background.paper,
height: '100%',
width: '100%',
borderRadius: 2
}}
/>
>
<Box
component="img"
src={imageUrl}
sx={{
height: '100%',
width: '100%',
borderRadius: 2
}}
/>
</Card>
);
};

Expand Down

0 comments on commit eec9ffd

Please sign in to comment.