Skip to content

Commit

Permalink
feat: style enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
LinaYahya committed Jul 22, 2024
1 parent 3dd7a57 commit 4925ac2
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 133 deletions.
1 change: 1 addition & 0 deletions src/langs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export const APP = {
REPLACE_IMAGE: 'REPLACE_IMAGE',
ADD_LABEL: 'ADD_LABEL',
UNEXPECTED_ERROR: 'UNEXPECTED_ERROR',
START_ADDING_LABEL_HELPER_TEXT: 'START_ADDING_LABEL_HELPER_TEXT',
};
3 changes: 2 additions & 1 deletion src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
"BACK": "Back",
"REPLACE_IMAGE": "Replace the image",
"ADD_LABEL": "Add",
"UNEXPECTED_ERROR": "Sorry, something went wrong!"
"UNEXPECTED_ERROR": "Sorry, something went wrong!",
"START_ADDING_LABEL_HELPER_TEXT": "To add a new label, simply click on the desired location on the image!"
}
113 changes: 53 additions & 60 deletions src/modules/builder/configuration/AddLabelsStep/AddLabelForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useContext } from 'react';
import { KeepScale } from 'react-zoom-pan-pinch';

import { CloseRounded } from '@mui/icons-material';
import AddIcon from '@mui/icons-material/Add';
import CheckIcon from '@mui/icons-material/Check';
import DeleteIcon from '@mui/icons-material/Delete';
import { Box, IconButton, Stack, TextField, useTheme } from '@mui/material';

Expand Down Expand Up @@ -36,77 +35,71 @@ const AddLabelForm = ({
zIndex: 500,
top: position.y,
left: position.x,
background: 'black',
padding: 1,
}}
gap={1}
>
<KeepScale
style={{
background: 'black',
opacity: '0.8',
padding: 8,
}}
>
<Box sx={{ position: 'relative' }}>
<Box sx={{ position: 'relative' }}>
<IconButton
color="primary"
sx={{
position: 'absolute',
top: -26,
right: -8,
padding: '2px',
borderRadius: '50%',
color: 'white',
background: 'black',
'&:hover': {
background: 'black',
color: 'white',
},
}}
onClick={onClose}
>
<CloseRounded />
</IconButton>
<Box
display="flex"
alignItems="center"
sx={{ border: `1px solid ${theme.palette.primary.main}` }}
>
<TextField
autoFocus
size="small"
value={value}
onChange={onChange}
sx={{
background: 'white',
opacity: 1,
border: 0,
width: '15ch',
}}
multiline
/>
<IconButton
color="primary"
onClick={onSubmit}
sx={{
position: 'absolute',
top: -22,
right: -8,
padding: '2px',
borderRadius: '50%',
background: 'black',
'&:hover': {
background: 'black',
color: 'white',
},
background: theme.palette.primary.main,
borderRadius: 0,
}}
onClick={onClose}
>
<CloseRounded />
<CheckIcon sx={{ color: 'white' }} />
</IconButton>
<Box display="flex" alignItems="center">
<TextField
autoFocus
size="small"
value={value}
onChange={onChange}
sx={{
background: 'white',
opacity: 1,
border: 0,
width: '15ch',
}}
multiline
/>
{labelToDelete && (
<IconButton
onClick={onSubmit}
sx={{
background: theme.palette.primary.main,
borderRadius: 0,
outline: `1px solid ${theme.palette.primary.main}`,
onClick={() => {
deleteLabel(labelToDelete.id);
onClose();
}}
sx={{ borderRadius: 0 }}
>
<AddIcon sx={{ color: 'white' }} />
<DeleteIcon color="primary" sx={{ color: 'white' }} />
</IconButton>
{labelToDelete && (
<IconButton
onClick={() => {
deleteLabel(labelToDelete.id);
onClose();
}}
sx={{
outline: `1px solid ${theme.palette.primary.main}`,
borderRadius: 0,
boxSizing: 'border-box',
}}
>
<DeleteIcon color="primary" sx={{ color: 'white' }} />
</IconButton>
)}
</Box>
)}
</Box>
</KeepScale>
</Box>
</Stack>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import {
useControls,
} from 'react-zoom-pan-pinch';

import { Box, styled } from '@mui/material';
import { Alert, Box, styled } from '@mui/material';

import { useLocalContext } from '@graasp/apps-query-client';
import { PermissionLevel } from '@graasp/sdk';

import { v4 } from 'uuid';

import { Label } from '@/@types';
import { Label, Position } from '@/@types';
import {
ADD_LABEL_FRAME_HEIGHT,
ADD_LABEL_FRAME_WIDTH,
} from '@/config/constants';
import { useAppTranslation } from '@/config/i18n';
import { APP } from '@/langs/constants';
import { LabelsContext } from '@/modules/context/LabelsContext';

import AddLabelForm from './AddLabelForm';
Expand All @@ -38,57 +40,30 @@ const Container = styled('div')(() => ({
left: '0px',
}));

const AddLabelWithinFrame = (): JSX.Element => {
const { labels, saveLabelsChanges, isDragging, openForm, setOpenForm } =
useContext(LabelsContext);
type Props = {
setFormPosition: (p: Position) => void;
setContent: (s: string) => void;
setLabelToEdit: (l: Label | null) => void;
};
const AddLabelWithinFrame = ({
setFormPosition,
setContent,
setLabelToEdit,
}: Props): JSX.Element => {
const { labels, isDragging, setOpenForm } = useContext(LabelsContext);

const { instance } = useControls();
const { permission } = useLocalContext();
const [content, setContent] = useState('');
const [labelToEdit, setLabelToEdit] = useState<Label | null>(null);
const [formPosition, setFormPosition] = useState({
y: 0,
x: 0,
});

const { scale, positionX, positionY } = instance.transformState;

const handleFormInputChange = (
event: React.ChangeEvent<HTMLInputElement>,
): void => {
setContent(event.target.value);
};

const handleFormSubmit = (): void => {
if (labelToEdit) {
const newLabel = {
...labelToEdit,
content,
};
saveLabelsChanges(newLabel);
} else {
const id = v4();
const p = {
y: (formPosition.y - positionY) / scale,
x: (formPosition.x - positionX) / scale,
};
const newLabel = { ...p, id, content };
saveLabelsChanges(newLabel);
}

setOpenForm(false);
setContent('');
setLabelToEdit(null);
};

const showLabelForm = (
event: React.MouseEvent<HTMLImageElement, MouseEvent>,
): void => {
if (!isDragging) {
const { offsetX, offsetY } = event.nativeEvent;
setFormPosition({
y: offsetY,
x: offsetX,
y: offsetY * scale + positionY,
x: offsetX * scale + positionX,
});

setOpenForm(true);
Expand Down Expand Up @@ -116,18 +91,8 @@ const AddLabelWithinFrame = (): JSX.Element => {
width: ADD_LABEL_FRAME_WIDTH,
}}
>
{permission === PermissionLevel.Admin && openForm && !isDragging && (
<AddLabelForm
value={content}
position={formPosition}
onChange={handleFormInputChange}
onSubmit={handleFormSubmit}
onClose={() => setOpenForm(false)}
labelToDelete={labelToEdit}
/>
)}
<ImageFrame />
<Container onClick={showLabelForm}>
<Container onClick={showLabelForm} sx={{ cursor: 'crosshair' }}>
{labels.map((ele) => (
<DraggableLabel
key={ele.id}
Expand All @@ -141,28 +106,90 @@ const AddLabelWithinFrame = (): JSX.Element => {
};

const AddLabelWithinFrameWrapper = (): JSX.Element => {
const { isDragging, openForm } = useContext(LabelsContext);
const { t } = useAppTranslation();

const { isDragging, openForm, setOpenForm, saveLabelsChanges, labels } =
useContext(LabelsContext);
const disabled = isDragging || openForm;

const { permission } = useLocalContext();
const [content, setContent] = useState('');
const [labelToEdit, setLabelToEdit] = useState<Label | null>(null);
const [formPosition, setFormPosition] = useState({
y: 0,
x: 0,
});

const handleFormInputChange = (
event: React.ChangeEvent<HTMLInputElement>,
): void => {
setContent(event.target.value);
};

const handleShowLabelForm = (show: boolean): void => {
setOpenForm(show);
setContent('');
setLabelToEdit(null);
};

const handleFormSubmit = (): void => {
if (labelToEdit) {
const newLabel = {
...labelToEdit,
content,
};
saveLabelsChanges(newLabel);
} else {
const id = v4();
const p = {
y: formPosition.y,
x: formPosition.x,
};
const newLabel = { ...p, id, content };
saveLabelsChanges(newLabel);
}
handleShowLabelForm(false);
};

return (
<TransformContainer
doubleClick={{ disabled: true }}
centerOnInit
panning={{ disabled }}
pinch={{ disabled }}
wheel={{ disabled }}
zoomAnimation={{ disabled }}
alignmentAnimation={{ disabled }}
velocityAnimation={{ disabled }}
>
<TransformComponent
wrapperStyle={{
maxWidth: '100%',
maxHeight: '100%',
}}
<Box sx={{ position: 'relative' }}>
{labels.length === 0 && (
<Alert severity="info">{t(APP.START_ADDING_LABEL_HELPER_TEXT)}</Alert>
)}
{permission === PermissionLevel.Admin && openForm && !isDragging && (
<AddLabelForm
value={content}
position={formPosition}
onChange={handleFormInputChange}
onSubmit={handleFormSubmit}
onClose={() => setOpenForm(false)}
labelToDelete={labelToEdit}
/>
)}
<TransformContainer
doubleClick={{ disabled: true }}
centerOnInit
panning={{ disabled }}
pinch={{ disabled }}
wheel={{ disabled }}
zoomAnimation={{ disabled }}
alignmentAnimation={{ disabled }}
velocityAnimation={{ disabled }}
>
<AddLabelWithinFrame />
</TransformComponent>
</TransformContainer>
<TransformComponent
wrapperStyle={{
maxWidth: '100%',
maxHeight: '100%',
}}
>
<AddLabelWithinFrame
setContent={setContent}
setFormPosition={setFormPosition}
setLabelToEdit={setLabelToEdit}
/>
</TransformComponent>
</TransformContainer>
</Box>
);
};
export default AddLabelWithinFrameWrapper;

0 comments on commit 4925ac2

Please sign in to comment.