Files
TIF22A_AnwProjekt_B/anwendung/src/components/CalenderView.jsx
T
AliGitGut 594c82ce23 Starttime edited
Starttime can be changed now
2023-05-26 14:50:04 +02:00

465 lines
20 KiB
React

import {useEffect, useState} from "react";
import Button from "@/components/Button";
import {list} from "postcss";
import Background from "@/components/Background";
import WeekSelector from "@/components/WeekSelector";
let cellHeight = 20;
let colors = ["#f80000", "#414141"]
let semesterStart;
let currentWeekStartDay;
let currentYear;
let selectedElement;
let grabbedDown;
export default function CalenderView(p) {
const [entries, setEntries] = useState([[], [], [], [], [], []])
const [update, setUpdate] = useState(false)
function readEntries() {
let url = "http://localhost:8080/entries?semesterid=" + localStorage.getItem("currentsid") +
"&daynumber=" + currentWeekStartDay + "&yearnumber=" + currentYear + "&sessionid=" + localStorage.getItem("sessionid");
fetch(url).then(r => r.json()).then(en => {
setEntries(en)
})
}
function pushEntry(currentColumnID, row) {
let url = "http://localhost:8080/entries" + "?sessionid=" + localStorage.getItem("sessionid")
let json = {
"id": 0,
"daynumber": currentWeekStartDay + currentColumnID,
"yearnumber": currentYear,
"semesterid": localStorage.getItem("currentsid"),
"usercreatedbyid": localStorage.getItem("userid"),
"timestart": row,
"timeend": row + 3,
"info": ""
}
fetch(url, {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(json)
}).then(r => {
readEntries()
})
}
function deleteEntry(id) {
let url = "http://localhost:8080/entries?id=" + id + "&sessionid=" + localStorage.getItem("sessionid");
fetch(url, {
method: "DELETE"
}).then(r => readEntries())
}
function checkForElementAtRow(row, column) {
let currentList = entries[column];
for (let i = 0; i < currentList.length; i++) {
if (currentList[i] != null) {
if (row >= currentList[i].timestart && row <= currentList[i].timeend) {
return true;
}
}
}
return false;
}
function getElementInColumn(id, column) {
let currentList = entries[column];
for (let i = 0; i < currentList.length; i++) {
if (currentList[i] != null) {
if (currentList[i].id === id) {
return currentList[i];
}
}
}
return null;
}
function onMouseUp(e) {
if (selectedElement != null) {
let id = selectedElement.id;
let url = "http://localhost:8080/entries?sessionid=" + localStorage.getItem("sessionid");
let json = {
"id": id,
"daynumber": 0,
"yearnumber": 0,
"semesterid": 0,
"usercreatedbyid": 0,
"timestart": selectedElement.timestart,
"timeend": selectedElement.timeend,
"info": ""
}
fetch(url, {
method: "PUT",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(json)
}).then(r => {
readEntries()
})
selectedElement = null;
}
}
function onMouseMove(e) {
if (selectedElement != null) {
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 currentColumnID = parseInt(e.currentTarget.id)
if (grabbedDown)
{
selectedElement.timeend = row + 1;
}else
{
selectedElement.timestart = row + 1;
}
setUpdate(!update);
}
}
function onMouseDown(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 currentColumnID = parseInt(e.currentTarget.id)
let currentId = e.target.id;
if (e.button === 0) {
if (!currentId.includes("e")) {
if (!currentId.includes("grab")) {
if (!checkForElementAtRow(row + 2, currentColumnID)) {
pushEntry(currentColumnID, row)
}
} else {
grabbedDown = currentId.includes("down")
/*
if(currentId.includes("up"))
{
grabbedDown = false;
}else grabbedDown = true;
*/
let parentID = parseInt(e.target.parentElement.id.replace("e", ""));
selectedElement = getElementInColumn(parentID, currentColumnID);
}
}
} else if (e.button === 2) {
if (currentId.includes("e")) {
let id = parseInt(currentId.replace("e", ""))
deleteEntry(id)
}
}
}
function onWeekLeft() {
currentWeekStartDay -= 7;
readEntries()
}
function onWeekRight() {
currentWeekStartDay += 7;
readEntries()
}
useEffect(() => {
semesterStart = 0;
currentWeekStartDay = 0;
currentYear = 2000;
selectedElement = null;
grabbedDown = false;
let url = "http://localhost:8080/semester/id?sessionid=" + localStorage.getItem("sessionid") +
"&id=" + localStorage.getItem("currentsid");
fetch(url).then(r => r.json()).then(s => {
currentWeekStartDay = s.startday - new Date(s.startyear, 0, s.startday).getUTCDay();
currentYear = s.startyear;
semesterStart = s.startday;
}).then(readEntries)
window.addEventListener("contextmenu", (e) => (e.preventDefault()))
setInterval(function(){
if (selectedElement == null){
readEntries()
}
}, 100);
}, [])
//returns internal format (0 - 96) to a string
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 style={{
display: "flex",
height: "100vh",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
}}>
<WeekSelector year={currentYear} startday={currentWeekStartDay} onFunctionLeft={() => onWeekLeft()}
onFunctionRight={() => onWeekRight()}/>
<div id={update} style={{
display: "flex",
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
gap: 5
}}>
<div style={{ borderRadius: 10, padding: 10, backgroundColor: "#f1f1f1"}} className={"box-shadow"}>
<div>
<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"} style={{height: cellHeight * 96 + 10}}>
<div className={"spalte"}
id={"0"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}
onMouseMove={e => onMouseMove(e)}
onMouseUp={e => onMouseUp(e)}>
{entries[0].map(d => (d != null && <div className={"entry"} style={{
width: "100%",
gridRowStart: d.timestart,
gridRowEnd: d.timeend,
backgroundColor: "#77932b"
}} id={d.id + "e"}>
<div className={"resize-grab"} id={"grabup"}></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<p>Modul</p>
</div>
<div className={"resize-grab"} id={"grabdown"}></div>
</div>))}
</div>
<div className={"spalte"}
id={"1"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}
onMouseMove={e => onMouseMove(e)}
onMouseUp={e => onMouseUp(e)}>
{entries[1].map(d => (d != null && <div className={"entry"} style={{
width: "100%",
gridRowStart: d.timestart,
gridRowEnd: d.timeend,
backgroundColor: "#77932b"
}} id={d.id + "e"}>
<div className={"resize-grab"} id={"grabup"}></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<p>Modul</p>
</div>
<div className={"resize-grab"} id={"grabdown"}></div>
</div>))}
</div>
<div className={"spalte"}
id={"2"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}
onMouseMove={e => onMouseMove(e)}
onMouseUp={e => onMouseUp(e)}>
{entries[2].map(d => (d != null && <div className={"entry"} style={{
width: "100%",
gridRowStart: d.timestart,
gridRowEnd: d.timeend,
backgroundColor: "#77932b"
}} id={d.id + "e"}>
<div className={"resize-grab"} id={"grabup"}></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<p>Modul</p>
</div>
<div className={"resize-grab"} id={"grabdown"}></div>
</div>))}
</div>
<div className={"spalte"}
id={"3"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}
onMouseMove={e => onMouseMove(e)}
onMouseUp={e => onMouseUp(e)}>
{entries[3].map(d => (d != null && <div className={"entry"} style={{
width: "100%",
gridRowStart: d.timestart,
gridRowEnd: d.timeend,
backgroundColor: "#77932b"
}} id={d.id + "e"}>
<div className={"resize-grab"} id={"grabup"}></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<p>Moduel etc.</p>
</div>
<div className={"resize-grab"} id={"grabdown"}></div>
</div>))}
</div>
<div className={"spalte"}
id={"4"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}
onMouseMove={e => onMouseMove(e)}
onMouseUp={e => onMouseUp(e)}>
{entries[4].map(d => (d != null && <div className={"entry"} style={{
width: "100%",
gridRowStart: d.timestart,
gridRowEnd: d.timeend,
backgroundColor: "#77932b"
}} id={d.id + "e"}>
<div className={"resize-grab"} id={"grabup"}></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<p>Modul</p>
</div>
<div className={"resize-grab"} id={"grabdown"}></div>
</div>))}
</div>
<div className={"spalte"}
id={"5"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}
onMouseMove={e => onMouseMove(e)}
onMouseUp={e => onMouseUp(e)}>
{entries[5].map(d => (d != null && <div className={"entry"} style={{
width: "100%",
gridRowStart: d.timestart,
gridRowEnd: d.timeend,
backgroundColor: "#77932b"
}} id={d.id + "e"}>
<div className={"resize-grab"} id={"grabup"}></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<p>Modul</p>
</div>
<div className={"resize-grab"} id={"grabdown"}></div>
</div>))}
</div>
</div>
<div className={"overlay"} style={{backgroundColor: "rgba(0, 0, 0, 0)"}}>
{/*maps a list of internal time stamps to lines and time stamps*/}
{temp.map(i => (<div style={{
width: "100%",
height: cellHeight * 2,
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
}} className={"no-pointer-events"}>
<div style={{
borderBottom: "1px solid #363636",
}}><p style={{
color: "gray",
marginTop: cellHeight - 3,
marginRight: 120,
fontSize: 12,
textAlign: "center"
}}>{internal_to_time(i + 1)}</p></div>
<div style={{
borderBottom: "1px solid #363636",
}}><p style={{
color: "gray",
marginTop: cellHeight - 3,
marginRight: 120,
fontSize: 12,
textAlign: "center"
}}>{internal_to_time(i + 1)}</p></div>
<div style={{
borderBottom: "1px solid #363636",
}}><p style={{
color: "gray",
marginTop: cellHeight - 3,
marginRight: 120,
fontSize: 12,
textAlign: "center"
}}>{internal_to_time(i + 1)}</p></div>
<div style={{
borderBottom: "1px solid #363636",
}}><p style={{
color: "gray",
marginTop: cellHeight - 3,
marginRight: 120,
fontSize: 12,
textAlign: "center"
}}>{internal_to_time(i + 1)}</p></div>
<div style={{
borderBottom: "1px solid #363636",
}}><p style={{
color: "gray",
marginTop: cellHeight - 3,
marginRight: 120,
fontSize: 12,
textAlign: "center"
}}>{internal_to_time(i + 1)}</p></div>
<div style={{
borderBottom: "1px solid #363636",
}}><p style={{
color: "gray",
marginTop: cellHeight - 3,
marginRight: 120,
fontSize: 12,
textAlign: "center"
}}>{internal_to_time(i + 1)}</p></div>
</div>))}
</div>
</div>
</div>
</div>
</div>
)
}