Skip to content

Feature/m UI item component state #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions app/src/components/left/DragDropPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useDispatch, useSelector } from 'react-redux';
import Grid from '@mui/material/Grid';
import HTMLItem from './HTMLItem';
import MUIItem from './MUIItem';
import React from 'react';
import { RootState } from '../../redux/store';
import { deleteElement } from '../../redux/reducers/slice/appStateSlice';
Expand All @@ -10,18 +11,17 @@ import AccordionSummary from '@mui/material/AccordionSummary';
import AccordionDetails from '@mui/material/AccordionDetails';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { makeStyles } from '@mui/styles';
import ComponentDrag from './ComponentDrag';

import ComponentDrag from './ComponentDrag';

const useStyles = makeStyles({
accordion: {
backgroundColor: '#000000', // Set the background color to gray
color: '#ffffff', // Set the text color to white
color: '#ffffff' // Set the text color to white
},
accordionSummary: {
backgroundColor: '#000000', // Set the background color of the summary to gray
color: '#ffffff', // Set the text color of the summary to white
},
color: '#ffffff' // Set the text color of the summary to white
}
});

const DragDropPanel = (props): JSX.Element => {
Expand All @@ -46,9 +46,14 @@ const DragDropPanel = (props): JSX.Element => {
(type) => type.name !== 'separator'
);

const muiTypesToRender = state.MUITypes.filter(
(type) => type.name !== 'separator'
);

return (
<div className={'HTMLItems'}>
<div id="HTMLItemsTopHalf">
{/* Root Components */}
<Accordion className={classes.accordion}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
Expand All @@ -62,6 +67,8 @@ const DragDropPanel = (props): JSX.Element => {
<ComponentDrag isVisible={true} isThemeLight={props.isThemeLight} />
</AccordionDetails>
</Accordion>

{/* HTML Components */}
<Accordion className={classes.accordion}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
Expand Down Expand Up @@ -93,7 +100,7 @@ const DragDropPanel = (props): JSX.Element => {
</Grid>
</AccordionDetails>
</Accordion>

{/* MUI Components */}
<Accordion className={classes.accordion}>
<AccordionSummary
Expand All @@ -106,23 +113,21 @@ const DragDropPanel = (props): JSX.Element => {
</AccordionSummary>
<AccordionDetails>
<Grid container justifyContent="center">
{htmlTypesToRender.map((option) => {
if (option.name === 'MUI') {
return (
<HTMLItem
name={option.name}
key={`html-${option.name}`}
id={option.id}
icon={option.icon}
handleDelete={handleDelete}
/>
);
}
{muiTypesToRender.map((option) => {
return (
<MUIItem
name={option.name}
key={`mui-${option.name}`}
id={option.id}
icon={option.icon}
handleDelete={handleDelete}
/>
);
})}
</Grid>
</AccordionDetails>
</Accordion>

{/* React Router */}
<Accordion className={classes.accordion}>
<AccordionSummary
Expand Down Expand Up @@ -156,7 +161,7 @@ const DragDropPanel = (props): JSX.Element => {
</Grid>
</AccordionDetails>
</Accordion>

{/* Next.js */}
{state.projectType === 'Next.js' ? (
<h3 style={{ color: 'C6C6C6' }}>Next.js</h3>
Expand All @@ -183,4 +188,3 @@ const DragDropPanel = (props): JSX.Element => {
};

export default DragDropPanel;

11 changes: 6 additions & 5 deletions app/src/components/left/HTMLItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import * as Icons from '@mui/icons-material';
import { useDispatch, useSelector } from 'react-redux';
import { addChild } from '../../redux/reducers/slice/appStateSlice';
import { emitEvent } from '../../helperFunctions/socket';
import { RootState } from '../../redux/store';

const useStyles = makeStyles({
HTMLPanelItem: {
height: 'auto',
width: 'auto',
fontSize: 'small',
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
Expand All @@ -40,10 +42,8 @@ const HTMLItem: React.FC<{
}> = ({ name, id, icon, handleDelete }) => {
const IconComponent = Icons[icon];


const roomCode = useSelector((store: RootState) => store.roomSlice.roomCode); // current roomCode


const classes = useStyles();
const [modal, setModal] = useState(null);
const [{ isDragging }, drag] = useDrag({
Expand Down Expand Up @@ -113,7 +113,6 @@ const HTMLItem: React.FC<{
);
};


const dispatch = useDispatch();

const handleClick = () => {
Expand All @@ -140,7 +139,10 @@ const HTMLItem: React.FC<{
{id <= 20 && (
<div
ref={drag}
style={{ backgroundColor: '#2D313A', backgroundImage: 'linear-gradient(160deg, #2D313A 0%, #1E2024 100%)'}}
style={{
backgroundColor: '#2D313A',
backgroundImage: 'linear-gradient(160deg, #2D313A 0%, #1E2024 100%)'
}}
className={`${classes.HTMLPanelItem} ${classes.darkThemeFontColor}`}
id="HTMLItem"
onClick={() => {
Expand Down Expand Up @@ -183,4 +185,3 @@ const HTMLItem: React.FC<{
};

export default HTMLItem;

195 changes: 195 additions & 0 deletions app/src/components/left/MUIItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import React, { useState } from 'react';
import Grid from '@mui/material/Grid';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import makeStyles from '@mui/styles/makeStyles';
import { useDrag } from 'react-dnd';

import { ItemTypes } from '../../constants/ItemTypes';
import { RootState } from '../../redux/store';
import * as Icons from '@mui/icons-material'; // Assuming a collection of MUI icons
import CodeIcon from '@mui/icons-material/Code'; // Default icon if specific icon not provided
import { useDispatch, useSelector } from 'react-redux';
import { addChild } from '../../redux/reducers/slice/appStateSlice';
import createModal from '../right/createModal'; // Modal creation utility
import { emitEvent } from '../../helperFunctions/socket'; // Event emission utility

// Define component styles using MUI styling solutions
const useStyles = makeStyles({
MUIPanelItem: {
height: 'auto',
width: 'auto',
fontSize: 'small',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
alignItems: 'center',
textAlign: 'center',
cursor: 'grab'
},
lightThemeFontColor: {
color: '#8F8F8F'
},
darkThemeFontColor: {
color: '#8F8F8F'
}
});

const MUIItem: React.FC<{
name: string;
id: number;
icon: any;
handleDelete: (id: number) => void;
}> = ({ name, id, icon, handleDelete }) => {
const IconComponent = Icons[icon];

const roomCode = useSelector((store: RootState) => store.roomSlice.roomCode); // current roomCode

// Use drag and drop functionality
const classes = useStyles();
const [modal, setModal] = useState(null);

const item = {
type: ItemTypes.INSTANCE,
newInstance: true,
instanceType: 'MUI Component', // MUI Element? - we should carefully consider what we call this
name,
icon,
instanceTypeId: id
};

// console.log('draggable item', item);

const [{ isDragging }, drag] = useDrag({
item,
collect: (monitor: any) => ({
isDragging: !!monitor.isDragging()
})
});

const closeModal = () => setModal(null);
const deleteAllInstances = (deleteID: number) => {
const children = (
<List className="export-preference">
<ListItem
id="export-modal"
key={`clear${deleteID}`}
onClick={() => handleDelete(deleteID)}
style={{
border: '1px solid #C6C6C6',
marginBottom: '2%',
marginTop: '5%'
}}
>
<ListItemText
primary={'Yes, delete all instances'}
style={{ textAlign: 'center' }}
onClick={closeModal}
/>
</ListItem>
<ListItem
id="export-modal"
key={`close${deleteID}`}
onClick={closeModal}
style={{
border: '1px solid #C6C6C6',
marginBottom: '2%',
marginTop: '5%'
}}
>
<ListItemText
primary={'No, do not delete element'}
style={{ textAlign: 'center' }}
onClick={closeModal}
/>
</ListItem>
</List>
);
setModal(
createModal({
closeModal,
children,
message:
'Deleting this element will delete all instances of this element within the application.\nDo you still wish to proceed?',
primBtnLabel: null,
primBtnAction: null,
secBtnAction: null,
secBtnLabel: null,
open: true
})
);
};

const dispatch = useDispatch();

const handleClick = () => {
const childData = {
type: 'MUI Component',
typeId: id,
childId: null,
contextParam: {
allContext: []
}
};

dispatch(addChild(childData));
if (roomCode) {
// Emit 'addChildAction' event to the server
emitEvent('addChildAction', roomCode, childData);
}
};

// id over/under 20 logic
// html-g{name} - html grid name = item
return (
<Grid item xs={5} key={`mui-g${name}`} id="HTMLgrid">
{id >= 20 && (
<div
ref={drag}
style={{
backgroundColor: '#2D313A',
backgroundImage: 'linear-gradient(160deg, #2D313A 0%, #1E2024 100%)'
}}
className={`${classes.MUIPanelItem} ${classes.darkThemeFontColor}`}
id="MUIItem"
onClick={() => {
handleClick();
}}
>
{typeof IconComponent !== 'undefined' && (
<IconComponent fontSize="small" align-items="center" />
)}
{name}
</div>
)}

{id < 20 && (
<div
ref={drag}
style={{ borderColor: '#C6C6C6' }}
className={`${classes.MUIPanelItem} ${classes.darkThemeFontColor}`}
id="MUIItem"
onClick={() => {
handleClick();
}}
>
{typeof CodeIcon !== 'undefined' && (
<CodeIcon fontSize="small" align-items="center" />
)}
{name}
<button
id="newElement"
style={{ color: '#C6C6C6' }}
onClick={() => deleteAllInstances(id)}
>
X
</button>
</div>
)}
{modal}
</Grid>
);
};

export default MUIItem;
1 change: 1 addition & 0 deletions app/src/components/main/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ const Canvas = forwardRef<HTMLDivElement, CanvasProps>(({ zoom }, ref) => {
}
// if item dropped is going to be a new instance (i.e. it came from the left panel), then create a new child component
if (item.newInstance && item.instanceType !== 'Component') {
console.log('inside not component check', item);
dispatch(
//update state
addChild({
Expand Down
Loading