Added kebab for delete widgets

This commit is contained in:
Nalvazhuthi
2025-03-27 10:54:40 +05:30
parent 5ffb952637
commit a73c893040
11 changed files with 580 additions and 155 deletions

View File

@@ -511,3 +511,99 @@ export function AI_Icon() {
</svg>
);
}
export const KebabIcon = () => {
return (
<svg
width="13"
height="3"
viewBox="0 0 13 3"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<ellipse
cx="1.54798"
cy="1.35112"
rx="1.4993"
ry="1.27477"
fill="#E1E1E1"
/>
<ellipse
cx="6.04868"
cy="1.35131"
rx="1.4993"
ry="1.27477"
fill="#E1E1E1"
/>
<ellipse
cx="10.5476"
cy="1.35131"
rx="1.4993"
ry="1.27477"
fill="#E1E1E1"
/>
</svg>
);
};
export const DublicateIcon = () => {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M14.3125 11.375C14.3125 11.7545 14.0045 12.0625 13.625 12.0625H8.125C7.7455 12.0625 7.4375 11.7545 7.4375 11.375V5.875C7.4375 5.4955 7.7455 5.1875 8.125 5.1875H13.625C14.0045 5.1875 14.3125 5.4955 14.3125 5.875V11.375ZM13.625 4.5H8.125C7.36566 4.5 6.75 5.11566 6.75 5.875V11.375C6.75 12.1343 7.36566 12.75 8.125 12.75H13.625C14.3843 12.75 15 12.1343 15 11.375V5.875C15 5.11566 14.3843 4.5 13.625 4.5ZM11.5625 14.125C11.5625 14.5045 11.2545 14.8125 10.875 14.8125H5.375C4.9955 14.8125 4.6875 14.5045 4.6875 14.125V8.625C4.6875 8.2455 4.9955 7.9375 5.375 7.9375H6.0625V7.25H5.375C4.61566 7.25 4 7.86566 4 8.625V14.125C4 14.8843 4.61566 15.5 5.375 15.5H10.875C11.6343 15.5 12.25 14.8843 12.25 14.125V13.4375H11.5625V14.125Z"
fill="#6F42C1"
/>
</svg>
);
};
export const DeleteIcon = () => {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8.33301 10V13.3334"
stroke="#5D5F63"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M11 10V13.3334"
stroke="#5D5F63"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M4.33301 6.66406H15"
stroke="#5D5F63"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M5.66699 8.66406V13.9976C5.66699 15.1022 6.56245 15.9976 7.66705 15.9976H11.6672C12.7718 15.9976 13.6672 15.1022 13.6672 13.9976V8.66406"
stroke="#5D5F63"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M7.66699 5.33337C7.66699 4.59697 8.26396 4 9.00037 4H10.3337C11.0702 4 11.6671 4.59697 11.6671 5.33337V6.66675H7.66699V5.33337Z"
stroke="#5D5F63"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
);
};

View File

@@ -13,7 +13,7 @@ const Visualization = () => {
return (
<div className="visualization-right-sideBar">
<ToggleHeader
options={["Data", "Design"]}
options={["Data"]}
activeOption={activeOption}
handleClick={handleToggleClick}
/>

View File

@@ -53,7 +53,6 @@ const PieChartComponent = ({
.getPropertyValue("--accent-color")
.trim();
console.log("accentColor: ", accentColor);
const options = useMemo(
() => ({
responsive: true,

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useRef } from "react";
import React, { useEffect, useRef, useState, useCallback } from "react";
import { Widget } from "../../../store/useWidgetStore";
// Define the type for `Side`
@@ -51,135 +51,139 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
// Ref for the container element
const containerRef = useRef<HTMLDivElement | null>(null);
// Example state for selectedOption and options (adjust based on your actual use case)
const [selectedOption, setSelectedOption] = React.useState<string | null>(
null
);
// console.log('setSelectedOption: ', setSelectedOption);
const [options, setOptions] = React.useState<string[]>([]);
// console.log('setOptions: ', setOptions);
// State to track overflow visibility
const [showLeftArrow, setShowLeftArrow] = useState(false);
const [showRightArrow, setShowRightArrow] = useState(false);
// Scroll to the selected option when it changes
useEffect(() => {
// Function to calculate overflow state
const updateOverflowState = useCallback(() => {
const container = containerRef.current;
if (container && selectedOption) {
// Handle scrolling to the selected option
const index = options.findIndex((option) => {
const formattedOption = formatOptionName(option);
const selectedFormattedOption =
selectedOption?.split("_")[1] || selectedOption;
return formattedOption === selectedFormattedOption;
});
if (index !== -1) {
const optionElement = container.children[index] as HTMLElement;
if (optionElement) {
optionElement.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "center",
});
}
}
}
}, [selectedOption, options]);
useEffect(() => {
const container = containerRef.current;
const handleWheel = (event: WheelEvent) => {
event.preventDefault();
if (container) {
container.scrollBy({
left: event.deltaY * 2, // Adjust the multiplier for faster scrolling
behavior: "smooth",
});
}
};
let isDragging = false;
let startX: number;
let scrollLeft: number;
const handleMouseDown = (event: MouseEvent) => {
isDragging = true;
startX = event.pageX - (container?.offsetLeft || 0);
scrollLeft = container?.scrollLeft || 0;
};
const handleMouseMove = (event: MouseEvent) => {
if (!isDragging || !container) return;
event.preventDefault();
const x = event.pageX - (container.offsetLeft || 0);
const walk = (x - startX) * 2; // Adjust the multiplier for faster dragging
container.scrollLeft = scrollLeft - walk;
};
const handleMouseUp = () => {
isDragging = false;
};
const handleMouseLeave = () => {
isDragging = false;
};
if (container) {
container.addEventListener("wheel", handleWheel, { passive: false });
container.addEventListener("mousedown", handleMouseDown);
container.addEventListener("mousemove", handleMouseMove);
container.addEventListener("mouseup", handleMouseUp);
container.addEventListener("mouseleave", handleMouseLeave);
}
const isOverflowing = container.scrollWidth > container.clientWidth;
const canScrollLeft = container.scrollLeft > 0;
const canScrollRight =
container.scrollLeft + container.clientWidth < container.scrollWidth;
return () => {
if (container) {
container.removeEventListener("wheel", handleWheel);
container.removeEventListener("mousedown", handleMouseDown);
container.removeEventListener("mousemove", handleMouseMove);
container.removeEventListener("mouseup", handleMouseUp);
container.removeEventListener("mouseleave", handleMouseLeave);
}
};
console.log("isOverflowing:", isOverflowing);
console.log("canScrollLeft:", canScrollLeft);
console.log("canScrollRight:", canScrollRight);
setShowLeftArrow(isOverflowing && canScrollLeft);
setShowRightArrow(isOverflowing && canScrollRight);
}
}, []);
// Helper function to format option names (customize as needed)
const formatOptionName = (option: string): string => {
// Replace underscores with spaces and capitalize the first letter
return option.replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase());
useEffect(() => {
const container = containerRef.current;
if (container) {
// Initial calculation after the DOM has been rendered
const handleInitialRender = () => {
requestAnimationFrame(updateOverflowState);
};
handleInitialRender();
// Update on window resize or scroll
const handleResize = () => updateOverflowState();
const handleScroll = () => updateOverflowState();
// Add mouse wheel listener for horizontal scrolling
const handleWheel = (event: WheelEvent) => {
event.preventDefault(); // Prevent default vertical scrolling
if (container) {
container.scrollBy({
left: event.deltaY * 2, // Translate vertical scroll to horizontal scroll
behavior: "smooth",
});
}
};
container.addEventListener("scroll", handleScroll);
window.addEventListener("resize", handleResize);
container.addEventListener("wheel", handleWheel, { passive: false });
return () => {
container.removeEventListener("scroll", handleScroll);
window.removeEventListener("resize", handleResize);
container.removeEventListener("wheel", handleWheel);
};
}
}, [updateOverflowState]);
// Handle scrolling with navigation arrows
const handleScrollLeft = () => {
const container = containerRef.current;
if (container) {
container.scrollBy({
left: -200, // Scroll left by 200px
behavior: "smooth",
});
}
};
const handleScrollRight = () => {
const container = containerRef.current;
if (container) {
container.scrollBy({
left: 200, // Scroll right by 200px
behavior: "smooth",
});
}
};
return (
<div
ref={containerRef}
className={`zoon-wrapper ${selectedZone.activeSides.includes("bottom") && "bottom"
}`}
>
{Object.keys(zonesData).map((zoneName, index) => (
<div
key={index}
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""
}`}
onClick={() => {
console.log('zoneName: ', zoneName);
<div className="zoon-wrapper">
{/* Left Arrow */}
{showLeftArrow && (
<button className="arrow left-arrow" onClick={handleScrollLeft}>
{"<"}
</button>
)}
setSelectedZone({
zoneName,
activeSides: zonesData[zoneName].activeSides || [],
panelOrder: zonesData[zoneName].panelOrder || [],
lockedPanels: zonesData[zoneName].lockedPanels || [],
widgets: zonesData[zoneName].widgets || [],
})
// setSelectedZone({
// zoneName,
// ...zonesData[zoneName],
// });
console.log(selectedZone);
}}
>
{zoneName}
</div>
))}
{/* Zones Wrapper */}
<div
ref={containerRef}
className="zones-wrapper"
style={{
display: "flex",
gap: "6px",
padding: "4px",
borderRadius: "8px",
overflowX: "auto",
maxWidth: "calc(100% - 10px)", // Uncomment this line if needed
}}
>
{Object.keys(zonesData).map((zoneName, index) => (
<div
key={index}
className={`zone ${
selectedZone.zoneName === zoneName ? "active" : ""
}`}
onClick={() => {
console.log("zoneName: ", zoneName);
setSelectedZone({
zoneName,
activeSides: zonesData[zoneName].activeSides || [],
panelOrder: zonesData[zoneName].panelOrder || [],
lockedPanels: zonesData[zoneName].lockedPanels || [],
widgets: zonesData[zoneName].widgets || [],
});
}}
>
{zoneName}
</div>
))}
</div>
{/* Right Arrow */}
{showRightArrow && (
<button className="arrow right-arrow" onClick={handleScrollRight}>
{">"}
</button>
)}
</div>
);
};

View File

@@ -3,20 +3,58 @@ import ProgressCard from "../realTimeVis/charts/ProgressCard";
import PieGraphComponent from "../realTimeVis/charts/PieGraphComponent";
import BarGraphComponent from "../realTimeVis/charts/BarGraphComponent";
import LineGraphComponent from "../realTimeVis/charts/LineGraphComponent";
import RadarGraphComponent from "../realTimeVis/charts/RadarGraphComponent";
import DoughnutGraphComponent from "../realTimeVis/charts/DoughnutGraphComponent";
import PolarAreaGraphComponent from "../realTimeVis/charts/PolarAreaGraphComponent";
import {
DeleteIcon,
DublicateIcon,
KebabIcon,
} from "../../icons/ExportCommonIcons";
import { useEffect, useRef } from "react";
type Side = "top" | "bottom" | "left" | "right";
interface Widget {
id: string;
type: string;
title: string;
panel: Side;
data: any;
}
export const DraggableWidget = ({
widget,
hiddenPanels, // Add this prop to track hidden panels
index, onReorder
index,
onReorder,
openKebabId,
setOpenKebabId,
selectedZone,
setSelectedZone,
}: {
selectedZone: {
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
widgets: Widget[];
};
setSelectedZone: React.Dispatch<
React.SetStateAction<{
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
widgets: Widget[];
}>
>;
widget: any;
hiddenPanels: string[]; // Array of hidden panel names
index: number; onReorder: (fromIndex: number, toIndex: number) => void
index: number;
onReorder: (fromIndex: number, toIndex: number) => void;
openKebabId: string | null; // ID of the widget with an open kebab menu
setOpenKebabId: (id: string | null) => void; // Function to update the open kebab menu
}) => {
const { selectedChartId, setSelectedChartId } = useWidgetStore();
const handlePointerDown = () => {
@@ -29,7 +67,7 @@ export const DraggableWidget = ({
const isPanelHidden = hiddenPanels.includes(widget.panel);
const handleDragStart = (event: React.DragEvent<HTMLDivElement>) => {
event.dataTransfer.setData('text/plain', index.toString()); // Store the index of the dragged widget
event.dataTransfer.setData("text/plain", index.toString()); // Store the index of the dragged widget
};
const handleDragEnter = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault(); // Allow drop
@@ -41,21 +79,89 @@ export const DraggableWidget = ({
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
const fromIndex = parseInt(event.dataTransfer.getData('text/plain'), 10); // Get the dragged widget's index
const fromIndex = parseInt(event.dataTransfer.getData("text/plain"), 10); // Get the dragged widget's index
const toIndex = index; // The index of the widget where the drop occurred
if (fromIndex !== toIndex) {
onReorder(fromIndex, toIndex); // Call the reorder function passed as a prop
}
};
// Handle kebab icon click to toggle kebab options
const handleKebabClick = (event: React.MouseEvent<HTMLDivElement>) => {
event.stopPropagation(); // Prevent click from propagating to parent elements
if (openKebabId === widget.id) {
// If the current kebab is already open, close it
setOpenKebabId(null);
} else {
// Open the kebab for the clicked widget and close others
setOpenKebabId(widget.id);
}
};
const deleteSelectedChart = () => {
// Filter out the widget to be deleted
const updatedWidgets = selectedZone.widgets.filter(
(w: Widget) => w.id !== widget.id
);
// Update the selectedZone state
setSelectedZone((prevZone: any) => ({
...prevZone,
widgets: updatedWidgets, // Replace the widgets array with the updated one
}));
// Close the kebab menu after deletion
setOpenKebabId(null);
};
const widgetRef = useRef<HTMLDivElement | null>(null);
// Handle click outside to close the kebab menu
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
widgetRef.current &&
!widgetRef.current.contains(event.target as Node)
) {
setOpenKebabId(null); // Close the kebab menu if the click is outside
}
};
document.addEventListener("mousedown", handleClickOutside);
// Cleanup event listener on component unmount
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [setOpenKebabId]);
const duplicateWidget = () => {
// Create a copy of the current widget with a new unique ID
const duplicatedWidget: Widget = {
...widget,
id: `${widget.id}-copy-${Date.now()}`, // Generate a unique ID using a timestamp
};
// Add the duplicated widget to the selectedZone's widgets array
setSelectedZone((prevZone: any) => ({
...prevZone,
widgets: [...prevZone.widgets, duplicatedWidget],
}));
// Close the kebab menu after duplication
setOpenKebabId(null);
console.log("Duplicated widget with ID:", duplicatedWidget.id);
};
return (
<>
<div
draggable
key={widget.id}
className={`chart-container ${selectedChartId?.id === widget.id && "activeChart"
}`}
className={`chart-container ${
selectedChartId?.id === widget.id && "activeChart"
}`}
onPointerDown={handlePointerDown}
onDragStart={handleDragStart}
onDragEnter={handleDragEnter}
@@ -66,6 +172,32 @@ export const DraggableWidget = ({
pointerEvents: isPanelHidden ? "none" : "auto", // Disable interaction when hidden
}}
>
{/* Kebab Icon */}
<div className="icon kebab" onClick={handleKebabClick}>
<KebabIcon />
</div>
{/* Kebab Options */}
{openKebabId === widget.id && (
<div
className="kebab-options"
ref={widgetRef} // Attach the ref to the widget container
>
<div className="edit btn">
<div className="icon">
<DublicateIcon />
</div>
<div className="label">Duplicate</div>
</div>
<div className="edit btn" onClick={deleteSelectedChart}>
<div className="icon">
<DeleteIcon />
</div>
<div className="label">Delete</div>
</div>
</div>
)}
{/* Render charts based on widget type */}
{widget.type === "progress" && (
<ProgressCard title={widget.title} data={widget.data} />

View File

@@ -32,6 +32,7 @@ interface PanelProps {
}>
>;
hiddenPanels: string[];
setZonesData: React.Dispatch<React.SetStateAction<any>>; // Add this line
}
const generateUniqueId = () =>
@@ -41,6 +42,7 @@ const Panel: React.FC<PanelProps> = ({
selectedZone,
setSelectedZone,
hiddenPanels,
setZonesData,
}) => {
const panelRefs = useRef<{ [side in Side]?: HTMLDivElement }>({});
const [panelDimensions, setPanelDimensions] = useState<{
@@ -63,8 +65,9 @@ const Panel: React.FC<PanelProps> = ({
case "top":
case "bottom":
return {
width: `calc(100% - ${(leftActive ? panelSize : 0) + (rightActive ? panelSize : 0)
}px)`,
width: `calc(100% - ${
(leftActive ? panelSize : 0) + (rightActive ? panelSize : 0)
}px)`,
height: `${panelSize - 2}px`,
left: leftActive ? `${panelSize}px` : "0",
right: rightActive ? `${panelSize}px` : "0",
@@ -74,8 +77,9 @@ const Panel: React.FC<PanelProps> = ({
case "right":
return {
width: `${panelSize - 2}px`,
height: `calc(100% - ${(topActive ? panelSize : 0) + (bottomActive ? panelSize : 0)
}px)`,
height: `calc(100% - ${
(topActive ? panelSize : 0) + (bottomActive ? panelSize : 0)
}px)`,
top: topActive ? `${panelSize}px` : "0",
bottom: bottomActive ? `${panelSize}px` : "0",
[side]: "0",
@@ -98,8 +102,8 @@ const Panel: React.FC<PanelProps> = ({
if (currentWidgetsCount >= maxCapacity) return;
console.log('draggedAsset: ', draggedAsset);
console.log('panel: ', panel);
console.log("draggedAsset: ", draggedAsset);
console.log("panel: ", panel);
addWidgetToPanel(draggedAsset, panel);
};
@@ -168,7 +172,7 @@ const Panel: React.FC<PanelProps> = ({
const handleReorder = (fromIndex: number, toIndex: number, panel: Side) => {
if (!selectedZone) return; // Ensure selectedZone is not null
console.log('selectedZone: ', selectedZone);
console.log("selectedZone: ", selectedZone);
setSelectedZone((prev) => {
if (!prev) return prev; // Ensure prev is not null
@@ -191,9 +195,8 @@ const Panel: React.FC<PanelProps> = ({
});
};
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
return (
<>
{selectedZone.activeSides.map((side) => (
@@ -231,6 +234,10 @@ const Panel: React.FC<PanelProps> = ({
onReorder={(fromIndex, toIndex) =>
handleReorder(fromIndex, toIndex, side)
}
openKebabId={openKebabId}
setOpenKebabId={setOpenKebabId}
selectedZone={selectedZone}
setSelectedZone={setSelectedZone}
/>
))}
</div>
@@ -241,5 +248,3 @@ const Panel: React.FC<PanelProps> = ({
};
export default Panel;

View File

@@ -8,7 +8,6 @@ import Scene from "../../../modules/scene/scene";
import useModuleStore from "../../../store/useModuleStore";
import { getZonesApi } from "../../../services/realTimeVisulization/zoneData/getZones";
type Side = "top" | "bottom" | "left" | "right";
type FormattedZoneData = Record<
@@ -41,7 +40,87 @@ const RealTimeVisulization: React.FC = () => {
const { isPlaying } = usePlayButtonStore();
const { activeModule } = useModuleStore();
const [zonesData, setZonesData] = useState<FormattedZoneData>({});
const [zonesData, setZonesData] = useState<{
[key: string]: {
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
widgets: Widget[];
};
}>({
"Manufacturing unit": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
"Assembly unit": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
"Packing unit": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
Warehouse: {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
Inventory: {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
"Inventory 1": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
"Inventory 2": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
"Inventory 3": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
"Inventory 4": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
"Inventory 5": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
"Inventory 6": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
"Inventory 7": {
activeSides: [],
panelOrder: [],
lockedPanels: [],
widgets: [],
},
});
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
// useEffect(() => {
@@ -73,10 +152,7 @@ const RealTimeVisulization: React.FC = () => {
// GetZoneData();
// }, []);
useEffect(() => {
console.log('zonesData: ', zonesData);
}, [zonesData]);
useEffect(() => {}, [zonesData]);
// useEffect(() => {
// setZonesData((prev) => {
@@ -111,7 +187,8 @@ const RealTimeVisulization: React.FC = () => {
style={{
height: "100%",
width: "100%",
borderRadius: isPlaying || activeModule !== "visualization" ? "" : "6px",
borderRadius:
isPlaying || activeModule !== "visualization" ? "" : "6px",
}}
>
<Scene />
@@ -137,6 +214,7 @@ const RealTimeVisulization: React.FC = () => {
selectedZone={selectedZone}
setSelectedZone={setSelectedZone}
hiddenPanels={hiddenPanels}
setZonesData={setZonesData}
/>
</>
)}

View File

@@ -39,7 +39,7 @@ const DropDownList: React.FC<DropDownListProps> = ({
useEffect(() => {
async function GetZoneData() {
const response = await getZonesApi("hexrfactory")
console.log('response: ', response.data);
setZoneDataList([{ id: "1", name: "zone1" },
{ id: "2", name: "Zone 2" },])
}

View File

@@ -8,7 +8,6 @@ interface ListProps {
}
const List: React.FC<ListProps> = ({ items = [] }) => {
console.log('items: ', items);
return (
<>
{items.length > 0 ? (

View File

@@ -8,7 +8,7 @@
flex-direction: column;
gap: 6px;
width: 100%;
min-width: 250px;
// min-width: 1450px;
.header {
display: flex;
justify-content: center;

View File

@@ -1,4 +1,5 @@
@use "../abstracts/variables.scss" as *;
@use "../abstracts/mixins.scss" as *;
// Main Container
.realTime-viz {
@@ -43,15 +44,28 @@
left: 50%;
transform: translate(-50%, 0);
gap: 6px;
padding: 4px;
border-radius: 8px;
max-width: 80%;
overflow: auto;
max-width: calc(100% - 450px);
// max-width: calc(100% - 450px);
&::-webkit-scrollbar {
display: none;
}
.arrow {
background-color: var(--accent-color);
color: var(--background-color);
}
.zones-wrapper {
&::-webkit-scrollbar {
display: none;
}
}
.zone {
width: auto;
background-color: var(--background-color);
@@ -155,7 +169,8 @@
position: relative;
height: 100%;
padding: 10px;
overflow: auto;
display: flex;
flex-direction: column;
gap: 10px;
@@ -176,6 +191,65 @@
box-shadow: 0px 2px 6px 0px rgba(60, 60, 67, 0.1);
padding: 6px 0;
background-color: white;
position: relative;
.kebab {
width: 30px;
height: 30px;
position: absolute;
top: 0px;
right: 0px;
z-index: 10;
@include flex-center;
}
.kebab-options {
position: absolute;
top: 12px;
right: -100px;
transform: translate(0px, 0);
background-color: var(--background-color);
z-index: 10;
display: flex;
flex-direction: column;
gap: 6px;
border-radius: 4px;
box-shadow: var(--box-shadow-medium);
.btn {
display: flex;
gap: 6px;
align-items: center;
padding: 5px 10px;
color: var(--text-color);
.label {
&:hover {
color: var(--accent-color);
}
}
&:hover {
background-color: var(--highlight-accent-color);
width: 100%;
svg {
&:first-child {
fill: var(--accent-color);
}
&:last-child {
fill: auto;
stroke: var(--accent-color);
}
}
}
}
}
}
.close-btn {
@@ -236,11 +310,12 @@
}
}
.playingFlase{
.zoon-wrapper{
.playingFlase {
.zoon-wrapper {
bottom: 300px !important;
}
}
// Side Buttons
.side-button-container {
position: absolute;
@@ -401,3 +476,40 @@
}
}
}
.arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
background-color: rgba(0, 0, 0, 0.5);
color: white;
border: none;
cursor: pointer;
font-size: 20px;
padding: 6px;
z-index: 10;
}
.left-arrow {
left: 0;
}
.right-arrow {
right: 0;
}
.zone {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
cursor: pointer;
}
.zone.active {
background-color: #007bff;
color: white;
}