349 lines
15 KiB
React
349 lines
15 KiB
React
import {useEffect, useState} from "react";
|
|
import {CalenderEntry} from "@/components/CalenderEntry";
|
|
|
|
let entries = {mo: [], tu: [], we: [], th: [], fr: [], sa: []}
|
|
let grabbed = null;
|
|
let grabbedUp = false;
|
|
let mouseDown = false;
|
|
|
|
let selectedElement = null;
|
|
let selectedOffsetTop = 0;
|
|
let selectedOffsetBottom = 0;
|
|
let selectedListID = "";
|
|
|
|
const cellHeight = 25;
|
|
|
|
export default function CalenderView(p) {
|
|
const [t, setT] = useState(false)
|
|
|
|
useEffect(() => {
|
|
window.addEventListener("contextmenu", (e) => (e.preventDefault()))
|
|
})
|
|
|
|
function mouse_move(e) {
|
|
if (mouseDown) {
|
|
let y_window = e.clientY;
|
|
let y_target_offset = e.currentTarget.getBoundingClientRect().top;
|
|
let id = e.currentTarget.id;
|
|
let row = Math.floor((y_window - y_target_offset) / cellHeight) + 1
|
|
|
|
if (grabbed != null) {
|
|
|
|
if (row >= 0 && row <= 96) {
|
|
if (grabbedUp) {
|
|
|
|
if (row < grabbed.end_point - 1) {
|
|
grabbed.start_point = row;
|
|
}
|
|
} else {
|
|
if (row > grabbed.start_point) {
|
|
grabbed.end_point = row + 1;
|
|
}
|
|
}
|
|
}
|
|
} else if (selectedElement != null) {
|
|
if (selectedListID !== id) {
|
|
let index = -1;
|
|
let currentList = entries[selectedListID];
|
|
let temp = [];
|
|
for (let i = 0; i < currentList.length; i++) {
|
|
if (selectedElement !== currentList[i]) {
|
|
temp.push(currentList[i]);
|
|
}
|
|
}
|
|
entries[selectedListID] = temp;
|
|
entries[id].push(selectedElement);
|
|
selectedListID = id;
|
|
}
|
|
|
|
if (row - selectedOffsetTop > 0 && row + selectedOffsetBottom <= 97) {
|
|
selectedElement.start_point = row - selectedOffsetTop;
|
|
selectedElement.end_point = row + selectedOffsetBottom;
|
|
}
|
|
}
|
|
}
|
|
|
|
setT(!t);
|
|
}
|
|
|
|
function mouse_up(e) {
|
|
mouseDown = false;
|
|
let y_window = e.clientY;
|
|
let y_target_offset = e.currentTarget.getBoundingClientRect().top;
|
|
let row = Math.floor((y_window - y_target_offset) / cellHeight) + 1
|
|
let current_list = entries[e.currentTarget.id];
|
|
|
|
if (grabbed != null) {
|
|
grabbed = null;
|
|
}
|
|
if (selectedElement != null) {
|
|
selectedElement = null;
|
|
}
|
|
|
|
setT(!t);
|
|
}
|
|
|
|
function mouse_down(e) {
|
|
|
|
let y_window = e.clientY;
|
|
let y_target_offset = e.currentTarget.getBoundingClientRect().top;
|
|
let row = Math.floor((y_window - y_target_offset) / cellHeight) + 1;
|
|
let current_list = entries[e.currentTarget.id];
|
|
|
|
if (e.button === 2) {
|
|
|
|
let current = null;
|
|
for (let i = 0; i < current_list.length; i++) {
|
|
current = current_list[i];
|
|
if (current.start_point <= row && current.end_point >= row) {
|
|
break;
|
|
}
|
|
current = null;
|
|
}
|
|
|
|
if (current != null) {
|
|
let temp = []
|
|
for (let i = 0; i < current_list.length; i++) {
|
|
if (current_list[i] !== current) {
|
|
temp.push(current_list[i]);
|
|
}
|
|
}
|
|
|
|
entries[e.currentTarget.id] = temp;
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
mouseDown = true;
|
|
|
|
if (e.target.id === "grab") {
|
|
let entry = e.target.parentElement;
|
|
let rowStart = parseInt(window.getComputedStyle(entry).gridRowStart);
|
|
|
|
for (let i = 0; i < current_list.length; i++) {
|
|
let current = current_list[i];
|
|
if (current.start_point === row || current.end_point === row + 1) {
|
|
grabbed = current;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (row === rowStart) {
|
|
grabbedUp = true;
|
|
} else {
|
|
grabbedUp = false;
|
|
}
|
|
} else if (e.target.id === "entry") {
|
|
for (let i = 0; i < current_list.length; i++) {
|
|
let current = current_list[i];
|
|
if (current.start_point <= row && current.end_point >= row) {
|
|
selectedElement = current;
|
|
selectedListID = e.currentTarget.id;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
selectedOffsetTop = row - parseInt(window.getComputedStyle(e.target).gridRowStart);
|
|
selectedOffsetBottom = parseInt(window.getComputedStyle(e.target).gridRowEnd) - row;
|
|
} else {
|
|
if (row < 96) {
|
|
let free = true;
|
|
for (let i = 0; i < current_list.length; i++) {
|
|
let current = current_list[i];
|
|
|
|
for (let r = row; r < row + 2; r++) {
|
|
for (let s = current.start_point; s < current.end_point; s++) {
|
|
if (s === r) {
|
|
free = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (free) {
|
|
current_list.push(new CalenderEntry(row, row + 3));
|
|
setT(!t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function internal_to_time(internal) {
|
|
internal -= 1
|
|
internal /= 4
|
|
let integer = Math.floor(internal)
|
|
let decimal = internal.toFixed(2);
|
|
let minutes = Math.floor((decimal - integer) * 60);
|
|
let minutes_string = minutes.toString().length === 1 ? "0" + minutes : minutes
|
|
return integer + ":" + minutes_string;
|
|
}
|
|
|
|
let temp = []
|
|
for (let i = 2; i <= 96; i += 2) {
|
|
temp.push(i);
|
|
}
|
|
|
|
return (
|
|
<div id={t} style={{border: "5px solid #363636", borderRadius: 10}}>
|
|
<div style={{backgroundColor: "#363636"}}>
|
|
<div className={"wochen-tag-container"}>
|
|
<div className={"wochen-tag font-big"}>Montag</div>
|
|
<div className={"wochen-tag font-big"}>Dienstag</div>
|
|
<div className={"wochen-tag font-big"}>Mittwoch</div>
|
|
<div className={"wochen-tag font-big"}>Donnerstag</div>
|
|
<div className={"wochen-tag font-big"}>Freitag</div>
|
|
<div className={"wochen-tag font-big"}>Samstag</div>
|
|
</div>
|
|
</div>
|
|
<div className={"calender-container"}>
|
|
|
|
<div className={"calender-view content"}>
|
|
|
|
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
|
|
id={"mo"}>
|
|
|
|
|
|
{entries["mo"].map(d => (<div className={"entry"} style={{
|
|
width: "100%",
|
|
gridRowStart: d.start_point,
|
|
gridRowEnd: d.end_point,
|
|
gridColumnStart: 0,
|
|
gridColumnEnd: 0
|
|
}} id={"entry"}>
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
|
|
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p>
|
|
<p>Moduel etc.</p>
|
|
<p>Mehr Infos</p>
|
|
<p>Raum</p>
|
|
</div>
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
</div>))}
|
|
</div>
|
|
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
|
|
id={"tu"}>
|
|
|
|
{entries["tu"].map(d => (<div className={"entry"} style={{
|
|
width: "100%",
|
|
gridRowStart: d.start_point,
|
|
gridRowEnd: d.end_point
|
|
}} id={"entry"}>
|
|
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
|
|
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p>
|
|
<p>Moduel etc.</p>
|
|
<p>Mehr Infos</p>
|
|
<p>Raum</p>
|
|
</div>
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
</div>))}
|
|
</div>
|
|
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
|
|
id={"we"}>
|
|
|
|
|
|
{entries["we"].map(d => (<div className={"entry"} style={{
|
|
width: "100%",
|
|
gridRowStart: d.start_point,
|
|
gridRowEnd: d.end_point
|
|
}} id={"entry"}>
|
|
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
|
|
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p>
|
|
<p>Moduel etc.</p>
|
|
<p>Mehr Infos</p>
|
|
<p>Raum</p>
|
|
</div>
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
</div>))}
|
|
</div>
|
|
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
|
|
id={"th"}>
|
|
|
|
{entries["th"].map(d => (<div className={"entry"} style={{
|
|
width: "100%",
|
|
gridRowStart: d.start_point,
|
|
gridRowEnd: d.end_point
|
|
}} id={"entry"}>
|
|
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
|
|
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p>
|
|
<p>Moduel etc.</p>
|
|
<p>Mehr Infos</p>
|
|
<p>Raum</p>
|
|
</div>
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
</div>))}
|
|
</div>
|
|
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
|
|
id={"fr"}>
|
|
|
|
|
|
{entries["fr"].map(d => (<div className={"entry"} style={{
|
|
width: "100%",
|
|
gridRowStart: d.start_point,
|
|
gridRowEnd: d.end_point
|
|
}} id={"entry"}>
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
|
|
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p>
|
|
<p>Moduel etc.</p>
|
|
<p>Mehr Infos</p>
|
|
<p>Raum</p>
|
|
</div>
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
</div>))}
|
|
</div>
|
|
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
|
|
id={"sa"}>
|
|
|
|
|
|
{entries["sa"].map(d => (<div className={"entry"} style={{
|
|
width: "100%",
|
|
gridRowStart: d.start_point,
|
|
gridRowEnd: d.end_point
|
|
}} id={"entry"}>
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
|
|
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p>
|
|
<p>Moduel etc.</p>
|
|
<p>Mehr Infos</p>
|
|
<p>Raum</p>
|
|
</div>
|
|
<div className={"resize-grab"} id={"grab"}></div>
|
|
</div>))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className={"overlay"} style={{backgroundColor: "rgba(0, 0, 0, 0)"}}>
|
|
{temp.map(i => (<div style={{
|
|
width: "100%",
|
|
height: cellHeight * 2,
|
|
borderBottom: "1px solid #363636",
|
|
display: "flex",
|
|
flexDirection: "row",
|
|
justifyContent: "space-around",
|
|
alignItems: "center",
|
|
}} className={"no-pointer-events"}>
|
|
|
|
<p style={{color: "gray", marginTop: 30, marginRight: 120, fontSize: 12, textAlign: "center"}}>{internal_to_time(i+1)}</p>
|
|
<p style={{color: "gray", marginTop: 30, marginRight: 120, fontSize: 12, textAlign: "center"}}>{internal_to_time(i+1)}</p>
|
|
<p style={{color: "gray", marginTop: 30, marginRight: 120, fontSize: 12, textAlign: "center"}}>{internal_to_time(i+1)}</p>
|
|
<p style={{color: "gray", marginTop: 30, marginRight: 120, fontSize: 12, textAlign: "center"}}>{internal_to_time(i+1)}</p>
|
|
<p style={{color: "gray", marginTop: 30, marginRight: 120, fontSize: 12, textAlign: "center"}}>{internal_to_time(i+1)}</p>
|
|
<p style={{color: "gray", marginTop: 30, marginRight: 120, fontSize: 12, textAlign: "center"}}>{internal_to_time(i+1)}</p>
|
|
</div>))}
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
)
|
|
} |