- Created Card type

- Implemented drag and drop for the server list section
This commit is contained in:
Shemy Gan committed 2024-12-09 11:33:30 -05:00
1 parent 03ce805e9f
commit b1f056809f
4 files changed
+137 -26

No files matched your search

@@ -0,0 +1,4 @@
export default {
CARD: 'card',
}
@@ -1,5 +1,5 @@
import TextInput from "../../../Inputs/TextInput";
import { ServerStartAdornment, ServerEndAdornment } from "../../../Inputs/TextInput/Adornments";
import TextInput from "../../../../Inputs/TextInput";
import { ServerStartAdornment, ServerEndAdornment } from "../../../../Inputs/TextInput/Adornments";
const Server = ({ id, removeItem, value }) => {
@@ -0,0 +1,90 @@
import React, { useRef } from "react";
import { useDrag, useDrop } from "react-dnd";
import ItemTypes from "./ItemTypes";
import Card from "@mui/material/Card";
import CardActionArea from "@mui/material/CardActionArea";
import CardContent from "@mui/material/CardContent";
import Server from "./Server"
const CustomCard = React.forwardRef((props, ref) => (
<Card ref={ref}>
<CardActionArea>
<CardContent>
<Server
id={props.id}
removeItem={props.removeCard}
value={props.value}
/>
</CardContent>
</CardActionArea>
</Card>
));
const MyCard = ({ id, index, moveCard, removeCard, value }) => {
const ref = useRef(null);
const [, drop] = useDrop({
accept: ItemTypes.CARD,
hover(item, monitor) {
if (!ref.current) {
return;
}
const dragIndex = item.index;
const hoverIndex = index;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
// Determine rectangle on screen
const hoverBoundingRect = ref.current.getBoundingClientRect();
// Get vertical middle
const hoverMiddleY =
(hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
// Determine mouse position
const clientOffset = monitor.getClientOffset();
// Get pixels to the top
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
// Only perform the move when the mouse has crossed half of the items height
// When dragging downwards, only move when the cursor is below 50%
// When dragging upwards, only move when the cursor is above 50%
// Dragging downwards
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
}
// Dragging upwards
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
}
// Time to actually perform the action
moveCard(dragIndex, hoverIndex);
// Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches.
item.index = hoverIndex;
}
});
const [ {isDragging}, drag] = useDrag({
type: ItemTypes.CARD,
item: {id: id, index:index},
collect: monitor => ({
isDragging: monitor.isDragging()
})
});
drag(drop(ref));
return (
<CustomCard
ref={ref}
id={id}
removeCard={removeCard}
value={value}
/>
);
};
export default MyCard;
@@ -1,21 +1,24 @@
import { useState } from "react";
import { useState, useCallback } from "react";
import { Button, Box, Stack, Typography } from "@mui/material";
import { ConfigBox } from "../../../Pages/Settings/styled";
import { useTheme } from "@emotion/react";
import TabPanel from "@mui/lab/TabPanel";
import {
publicPageGeneralSettingsValidation,
} from "../../../Validation/validation";
import { publicPageGeneralSettingsValidation } from "../../../Validation/validation";
import { buildErrors } from "../../../Validation/error";
import { hasValidationErrors } from "../../../Validation/error";
import Server from "./Server"
import Card from "./Card";
import update from "immutability-helper";
const ContentPanel = () => {
const theme = useTheme();
const [errors, setErrors] = useState({});
// Local state for form data, errors, and file handling
const [localData, setLocalData] = useState({
monitors: []
monitors: [],
});
const [cards, setCards] = useState(localData.monitors);
// Clears specific error from errors state
const clearError = (err) => {
setErrors((prev) => {
@@ -25,6 +28,21 @@ const ContentPanel = () => {
});
};
const moveCard = useCallback(
(dragIndex, hoverIndex) => {
const dragCard = cards[dragIndex];
setCards(
update(cards, {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragCard],
],
})
);
},
[cards]
);
const handleChange = (event) => {
event.preventDefault();
const { value, id } = event.target;
@@ -41,16 +59,11 @@ const ContentPanel = () => {
};
const handleAddNew = () => {
let arr = localData.monitors;
arr.push({ id: "" + Math.random() });
setLocalData({ ...localData, monitors: arr });
}
const removeItem = (id) =>{
const currentMonitors = localData.monitors.filter(m => m.id !=id)
setLocalData({...localData, monitors: currentMonitors})
}
setCards([...cards, { id: "" + Math.random() }]);
};
const removeCard = (id) => {
setCards(cards.filter((c) => c?.id != id));
};
const handleBlur = (event) => {
event.preventDefault();
const { value, id } = event.target;
@@ -122,22 +135,26 @@ const ContentPanel = () => {
</Typography>
<Button onClick={handleAddNew}>Add New</Button>
</Stack>
{localData.monitors.length > 0 && (
{cards.length > 0 && (
<Stack
direction="column"
alignItems="center"
gap={theme.spacing(6)}
sx={{ml: theme.spacing(4),
sx={{
ml: theme.spacing(4),
mr: theme.spacing(8),
mb: theme.spacing(8)
mb: theme.spacing(8),
}}
>
{localData.monitors.map((m, idx) => (
<Server
{cards.map((card, idx) => (
<Card
key={idx}
id={m.id ?? "" + Math.random()}
removeItem={removeItem}
value={m.url}
index={idx}
id={card?.id ?? "" + Math.random()}
text={"" + idx}
moveCard={moveCard}
removeCard={removeCard}
value={card?.url ?? card?.id}
/>
))}
</Stack>