New Calender View Logic Concept

This commit is contained in:
brausjonas
2023-05-26 00:46:50 +02:00
parent 0c42a5820a
commit f52d4275ba
11 changed files with 587 additions and 490 deletions
@@ -1,9 +0,0 @@
export class CalenderEntry
{
constructor(start_point, end_point)
{
this.start_point = start_point;
this.end_point = end_point;
this.colorID = 0;
}
}
+429 -389
View File
@@ -1,323 +1,375 @@
import {useEffect, useState} from "react"; import {useEffect, useState} from "react";
import {CalenderEntry} from "@/components/CalenderEntry";
import Button from "@/components/Button"; import Button from "@/components/Button";
import {list} from "postcss"; import {list} from "postcss";
//all entries of the current week // //all entries of the current week
let entries = {mo: [], tu: [], we: [], th: [], fr: [], sa: []} // let entries = {mo: [], tu: [], we: [], th: [], fr: [], sa: []}
//a variable that saves the currently grabbed resize bar // //a variable that saves the currently grabbed resize bar
let grabbed = null; // let grabbed = null;
let grabbedUp = false; // let grabbedUp = false;
let grabbed_in_list = null; // let grabbed_in_list = null;
//
//a variable the saves if the mouse is pressed or not // //a variable the saves if the mouse is pressed or not
let mouseDown = false; // let mouseDown = false;
//
//a variable that stores the currently grabbed element to move // //a variable that stores the currently grabbed element to move
let selectedElement = null; // let selectedElement = null;
//move offset from top row to cursor // //move offset from top row to cursor
let selectedOffsetTop = 0; // let selectedOffsetTop = 0;
//move offset from bottom row to cursor // //move offset from bottom row to cursor
let selectedOffsetBottom = 0; // let selectedOffsetBottom = 0;
//the list, the grabbed element to move is currently in // //the list, the grabbed element to move is currently in
let selectedListID = ""; // let selectedListID = "";
//variable for the hight of one cell / row. Important for resizing the calender view //variable for the hight of one cell / row. Important for resizing the calender view
let cellHeight = 25; let cellHeight = 25;
let colors = ["#f80000", "#414141"] let colors = ["#f80000", "#414141"]
export default function CalenderView(p) let semesterStart;
{ let currentWeekStartDay;
//state to update the calender view let currentYear;
const [t, setT] = useState(false)
//a blocker for the right click context menu export default function CalenderView(p) {
useEffect(() =>
const [entries, setEntries] = useState([[], [], [], [], [], []])
function readEntries() {
let url = "http://localhost:8080/entries?semesterid=" + localStorage.getItem("currentsid") +
"&daynumber=" + currentWeekStartDay + "&yearnumber=" + currentYear;
console.log(currentWeekStartDay)
fetch(url).then(r => r.json()).then(en => setEntries(en))
}
function pushEntry(currentColumnID, row)
{ {
let url = "http://localhost:8080/entries"
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;
fetch(url, {
method: "DELETE"
}).then(r => readEntries())
}
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)
{
pushEntry(currentColumnID, row)
}
else if(e.button === 2)
{
if(currentId.includes("e"))
{
let id = parseInt(currentId.replace("e", ""))
deleteEntry(id)
}
}
}
useEffect(() => {
semesterStart = 0;
currentWeekStartDay = 0;
currentYear = 2000;
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())) window.addEventListener("contextmenu", (e) => (e.preventDefault()))
}) }, [])
function does_element_overlap(entry, start, end, search_list) // function does_element_overlap(entry, start, end, search_list)
{ // {
let current = null; // let current = null;
for(let i = 0; i < search_list.length; i++) // for(let i = 0; i < search_list.length; i++)
{ // {
current = search_list[i]; // current = search_list[i];
if(current !== entry) // if(current !== entry)
{ // {
if (start > current.start_point && start < current.end_point) // if (start > current.timestart && start < current.timeend)
{ // {
return true; // return true;
} else if (end > current.start_point && end < current.end_point) // } else if (end > current.timestart && end < current.timeend)
{ // {
return true; // return true;
} else if (start <= current.start_point && end >= current.end_point) // } else if (start <= current.timestart && end >= current.timeend)
{ // {
return true; // return true;
} // }
} // }
} // }
//
return false; // return false;
} // }
//function to delete an elemente and resize the corresponding list in the entries dictionary //function to delete an elemente and resize the corresponding list in the entries dictionary
function delete_element(index, element) // function delete_element(index, element)
{ // {
let currentList = entries[index]; // let currentList = entries[index];
let temp = [] // let temp = []
for (let i = 0; i < currentList.length; i++) // for (let i = 0; i < currentList.length; i++)
{ // {
if (element !== currentList[i]) // if (element !== currentList[i])
{ // {
temp.push(currentList[i]); // temp.push(currentList[i]);
} // }
} // }
entries[index] = temp; // entries[index] = temp;
} // }
//resize a grabbed element to the row paramter //resize a grabbed element to the row paramter
function size_grabbed(row, current_list) // function size_grabbed(row, current_list)
{ // {
if (row >= 0 && row <= 96) // if (row >= 0 && row <= 96)
{ // {
if (grabbedUp) // if (grabbedUp)
{ // {
console.log(grabbed.start_point) // console.log(grabbed.timestart)
//
if (row < grabbed.end_point - 1) // if (row < grabbed.timeend - 1)
{ // {
if(!does_element_overlap(grabbed, row, grabbed.end_point, current_list)) // if(!does_element_overlap(grabbed, row, grabbed.timeend, current_list))
{ // {
grabbed.start_point = row; // grabbed.timestart = row;
} // }
} // }
} else // } else
{ // {
if (row > grabbed.start_point) // if (row > grabbed.timestart)
{ // {
if(!does_element_overlap(grabbed, grabbed.start_point, row + 1, current_list)) // if(!does_element_overlap(grabbed, grabbed.timestart, row + 1, current_list))
{ // {
grabbed.end_point = row + 1; // grabbed.timeend = row + 1;
} // }
} // }
} // }
} // }
} // }
//moves the selected element to row and list with id //moves the selected element to row and list with id
function move_selected(row, id) // function move_selected(row, id)
{ // {
if (selectedListID !== id) // if (selectedListID !== id)
{ // {
if(!does_element_overlap(selectedElement, row - selectedOffsetTop, row + selectedOffsetBottom, entries[id])) // if(!does_element_overlap(selectedElement, row - selectedOffsetTop, row + selectedOffsetBottom, entries[id]))
{ // {
delete_element(selectedListID, selectedElement); // delete_element(selectedListID, selectedElement);
entries[id].push(selectedElement); // entries[id].push(selectedElement);
selectedListID = id; // selectedListID = id;
} // }
} // }
//
if (row - selectedOffsetTop > 0 && row + selectedOffsetBottom <= 97) // if (row - selectedOffsetTop > 0 && row + selectedOffsetBottom <= 97)
{ // {
if(!does_element_overlap(selectedElement, row - selectedOffsetTop, row + selectedOffsetBottom, entries[id])) // if(!does_element_overlap(selectedElement, row - selectedOffsetTop, row + selectedOffsetBottom, entries[id]))
{ // {
selectedElement.start_point = row - selectedOffsetTop; // selectedElement.timestart = row - selectedOffsetTop;
selectedElement.end_point = row + selectedOffsetBottom; // selectedElement.timeend = row + selectedOffsetBottom;
} // }
} // }
} // }
//routine, when mouse is moved //routine, when mouse is moved
function mouse_move(e) // function mouse_move(e)
{ // {
//checks if mouse is still down // //checks if mouse is still down
if (mouseDown) // if (mouseDown)
{ // {
//get the y coordinate of the cursor // //get the y coordinate of the cursor
let y_window = e.clientY; // let y_window = e.clientY;
//get the offset to the calender view // //get the offset to the calender view
let y_target_offset = e.currentTarget.getBoundingClientRect().top; // let y_target_offset = e.currentTarget.getBoundingClientRect().top;
//get the id of the current column // //get the id of the current column
let id = e.currentTarget.id; // let id = e.currentTarget.id;
//calcultes the current row the cursor hovers // //calcultes the current row the cursor hovers
let row = Math.floor((y_window - y_target_offset) / cellHeight) + 1 // let row = Math.floor((y_window - y_target_offset) / cellHeight) + 1
let current_list = entries[e.currentTarget.id]; // let current_list = entries[e.currentTarget.id];
//
//if a edge of an element was grabbed, resize it // //if a edge of an element was grabbed, resize it
if (grabbed != null) // if (grabbed != null)
{ // {
size_grabbed(row, grabbed_in_list); // size_grabbed(row, grabbed_in_list);
//if a whole element was grabbed, move it // //if a whole element was grabbed, move it
} else if (selectedElement != null) // } else if (selectedElement != null)
{ // {
move_selected(row, id); // move_selected(row, id);
} // }
} // }
//
//update the calender view // //update the calender view
setT(!t); // setT(!t);
} // }
//routine when mouse was released //routine when mouse was released
function mouse_up(e) // function mouse_up(e)
{ // {
mouseDown = false; // mouseDown = false;
//
// //remove all selected elements
// if (grabbed != null)
// {
// grabbed.colorID = 0;
// grabbed = null;
// }
// if (selectedElement != null)
// {
// selectedElement.colorID = 0;
// selectedElement = null;
// }
//
// setT(!t);
// }
//remove all selected elements
if (grabbed != null)
{
grabbed.colorID = 0;
grabbed = null;
}
if (selectedElement != null)
{
selectedElement.colorID = 0;
selectedElement = null;
}
setT(!t);
}
//find the current element on row in the selected list (search_list)
function find_current(row, search_list)
{
let current = null;
for (let i = 0; i < search_list.length; i++)
{
current = search_list[i];
if (current.start_point <= row && current.end_point >= row)
{
break;
}
current = null;
}
return current;
}
//places a new entry to the calender //places a new entry to the calender
function place_new_entry(row, list) // function place_new_entry(row, list)
{ // {
if (row < 96) // if (row < 96)
{ // {
let free = true; // let free = true;
for (let i = 0; i < list.length; i++) // for (let i = 0; i < list.length; i++)
{ // {
let current = list[i]; // let current = list[i];
//
for (let r = row; r < row + 3; r++) // for (let r = row; r < row + 3; r++)
{ // {
for (let s = current.start_point; s < current.end_point; s++) // for (let s = current.timestart; s < current.timeend; s++)
{ // {
if (s === r) // if (s === r)
{ // {
free = false; // free = false;
break; // break;
} // }
} // }
} // }
} // }
//
if (free) // if (free)
{ // {
list.push(new CalenderEntry(row, row + 3)); // list.push(new CalenderEntry(row, row + 3));
setT(!t); // setT(!t);
} // }
} // }
} // }
//routine when mouse was pressed //routine when mouse was pressed
function mouse_down(e) // function mouse_down(e)
{ // {
//
//get the cursors y coordinate in the window // //get the cursors y coordinate in the window
let y_window = e.clientY; // let y_window = e.clientY;
//get the offset of the calender view // //get the offset of the calender view
let y_target_offset = e.currentTarget.getBoundingClientRect().top; // let y_target_offset = e.currentTarget.getBoundingClientRect().top;
//calculate the row clicked on // //calculate the row clicked on
let row = Math.floor((y_window - y_target_offset) / cellHeight) + 1; // let row = Math.floor((y_window - y_target_offset) / cellHeight) + 1;
//get the list of entries clicked on // //get the list of entries clicked on
let current_list = entries[e.currentTarget.id]; // let current_list = entries[e.currentTarget.id];
//
//if right clicked // //if right clicked
if (e.button === 2) // if (e.button === 2)
{ // {
//if right clicked on an element / entry delete it // //if right clicked on an element / entry delete it
let current = find_current(row, current_list); // let current = find_current(row, current_list);
//
if (current != null) // if (current != null)
{ // {
delete_element(e.currentTarget.id, current); // delete_element(e.currentTarget.id, current);
} // }
//
} // }
else // else
{ // {
mouseDown = true; // mouseDown = true;
//
//if a resize bar was grabbed // //if a resize bar was grabbed
if (e.target.id === "grab") // if (e.target.id === "grab")
{ // {
//get the entry the resize bar is child of // //get the entry the resize bar is child of
let entry = e.target.parentElement; // let entry = e.target.parentElement;
//get the startRow of the entry // //get the startRow of the entry
let rowStart = parseInt(window.getComputedStyle(entry).gridRowStart); // let rowStart = parseInt(window.getComputedStyle(entry).gridRowStart);
//
grabbed_in_list = current_list; // grabbed_in_list = current_list;
//
//check if the upper or lower resize bar was grabbed // //check if the upper or lower resize bar was grabbed
if (row === rowStart) // if (row === rowStart)
{ // {
//+ / - 1 to avoid select the wrong element when overlapping // //+ / - 1 to avoid select the wrong element when overlapping
grabbed = find_current(row + 1, current_list); // grabbed = find_current(row + 1, current_list);
grabbedUp = true; // grabbedUp = true;
} else // } else
{ // {
grabbed = find_current(row - 1, current_list); // grabbed = find_current(row - 1, current_list);
grabbedUp = false; // grabbedUp = false;
} // }
//
grabbed.colorID = 1; // grabbed.colorID = 1;
//
setT(!t); // setT(!t);
} // }
//if a whole element was clicked to move // //if a whole element was clicked to move
else if (e.target.id === "entry") // else if (e.target.id === "entry")
{ // {
let rowStart = parseInt(window.getComputedStyle(e.target).gridRowStart); // let rowStart = parseInt(window.getComputedStyle(e.target).gridRowStart);
//
selectedListID = e.currentTarget.id; // selectedListID = e.currentTarget.id;
//
if(rowStart === row) // if(rowStart === row)
{ // {
selectedElement = find_current(row + 1, current_list); // selectedElement = find_current(row + 1, current_list);
} // }
else // else
{ // {
selectedElement = find_current(row, current_list); // selectedElement = find_current(row, current_list);
} // }
//
selectedElement.colorID = 1; // selectedElement.colorID = 1;
//
setT(!t); // setT(!t);
//
selectedOffsetTop = row - parseInt(window.getComputedStyle(e.target).gridRowStart); // selectedOffsetTop = row - parseInt(window.getComputedStyle(e.target).gridRowStart);
selectedOffsetBottom = parseInt(window.getComputedStyle(e.target).gridRowEnd) - row; // selectedOffsetBottom = parseInt(window.getComputedStyle(e.target).gridRowEnd) - row;
} // }
//single click places a new entry // //single click places a new entry
else // else
{ // {
place_new_entry(row, current_list) // place_new_entry(row, current_list)
} // }
} // }
} // }
//returns internal format (0 - 96) to a string //returns internal format (0 - 96) to a string
function internal_to_time(internal) function internal_to_time(internal) {
{
internal -= 1 internal -= 1
internal /= 4 internal /= 4
let integer = Math.floor(internal) let integer = Math.floor(internal)
@@ -328,23 +380,17 @@ export default function CalenderView(p)
} }
let temp = [] let temp = []
for (let i = 2; i <= 96; i += 2) for (let i = 2; i <= 96; i += 2) {
{
temp.push(i); temp.push(i);
} }
//html of the calender view
return ( return (
// calender outer container, contains the calender view and resize buttons
<div style={{display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center", gap: 5}}> <div style={{display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center", gap: 5}}>
{/* resize butto*/}
<Button text={"-"} fontSize={25} onClick={() =>
{ <div style={{border: "5px solid #363636", borderRadius: 10}}>
if (cellHeight - 5 >= 10) cellHeight -= 5;
setT(!t);
}} width={50} height={50}/>
{/*shows the day over the columns*/}
<div id={t} style={{border: "5px solid #363636", borderRadius: 10}}>
<div style={{backgroundColor: "#363636"}}> <div style={{backgroundColor: "#363636"}}>
<div className={"wochen-tag-container"}> <div className={"wochen-tag-container"}>
<div className={"wochen-tag font-big"}>Montag</div> <div className={"wochen-tag font-big"}>Montag</div>
@@ -355,53 +401,24 @@ export default function CalenderView(p)
<div className={"wochen-tag font-big"}>Samstag</div> <div className={"wochen-tag font-big"}>Samstag</div>
</div> </div>
</div> </div>
{/*the viewport of the actual calender*/}
<div className={"calender-container"}> <div className={"calender-container"}>
{/*the content of the calender (rows and columns)*/}
<div className={"calender-view content"} style={{height: cellHeight * 96 + 10}}> <div className={"calender-view content"} style={{height: cellHeight * 96 + 10}}>
{/*a row which contains all the entries of monday*/}
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
id={"mo"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}>
{/*maps all monday entries to new visible div elements*/} <div className={"spalte"}
{entries["mo"].map(d => (<div className={"entry"} style={{ id={"0"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}>
{entries[0].map(d => (d != null && <div className={"entry"} style={{
width: "100%", width: "100%",
gridRowStart: d.start_point, gridRowStart: d.timestart,
gridRowEnd: d.end_point, gridRowEnd: d.timeend,
gridColumnStart: 0, backgroundColor: "#77932b"
gridColumnEnd: 0, }} id={d.id + "e"}>
backgroundColor: colors[d.colorID], <div></div>
}} id={"entry"}>
{/*content of the entry / element*/}
{/*upper resize bar*/}
<div className={"resize-grab"} id={"grab"}></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}> <div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
{/*shows the time span of the entry*/} <p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<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>
{/*lower resize bar*/}
<div className={"resize-grab"} id={"grab"}></div>
</div>))}
</div>
{/*same as monday*/}
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
id={"tu"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}>
{entries["tu"].map(d => (<div className={"entry"} style={{
width: "100%",
gridRowStart: d.start_point,
gridRowEnd: d.end_point,
backgroundColor: colors[d.colorID]
}} 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>Moduel etc.</p>
<p>Mehr Infos</p> <p>Mehr Infos</p>
<p>Raum</p> <p>Raum</p>
@@ -409,21 +426,22 @@ export default function CalenderView(p)
<div className={"resize-grab"} id={"grab"}></div> <div className={"resize-grab"} id={"grab"}></div>
</div>))} </div>))}
</div> </div>
{/*same as monday*/}
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
id={"we"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}>
{entries["we"].map(d => (<div className={"entry"} style={{ <div className={"spalte"}
id={"1"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}>
{entries[1].map(d => (d != null && <div className={"entry"} style={{
width: "100%", width: "100%",
gridRowStart: d.start_point, gridRowStart: d.timestart,
gridRowEnd: d.end_point, gridRowEnd: d.timeend,
backgroundColor: colors[d.colorID] backgroundColor: "#77932b"
}} id={"entry"}> }} id={d.id + "e"}>
<div className={"resize-grab"} id={"grab"}></div> <div></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}> <div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p> <p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<p>Moduel etc.</p> <p>Moduel etc.</p>
<p>Mehr Infos</p> <p>Mehr Infos</p>
<p>Raum</p> <p>Raum</p>
@@ -431,20 +449,23 @@ export default function CalenderView(p)
<div className={"resize-grab"} id={"grab"}></div> <div className={"resize-grab"} id={"grab"}></div>
</div>))} </div>))}
</div> </div>
{/*same as monday*/}
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
id={"th"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}>
{entries["th"].map(d => (<div className={"entry"} style={{
<div className={"spalte"}
id={"2"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}>
{entries[2].map(d => (d != null && <div className={"entry"} style={{
width: "100%", width: "100%",
gridRowStart: d.start_point, gridRowStart: d.timestart,
gridRowEnd: d.end_point, gridRowEnd: d.timeend,
backgroundColor: colors[d.colorID] backgroundColor: "#77932b"
}} id={"entry"}> }} id={d.id + "e"}>
<div className={"resize-grab"} id={"grab"}></div> <div></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}> <div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p> <p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<p>Moduel etc.</p> <p>Moduel etc.</p>
<p>Mehr Infos</p> <p>Mehr Infos</p>
<p>Raum</p> <p>Raum</p>
@@ -452,20 +473,22 @@ export default function CalenderView(p)
<div className={"resize-grab"} id={"grab"}></div> <div className={"resize-grab"} id={"grab"}></div>
</div>))} </div>))}
</div> </div>
{/*same as monday*/}
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
id={"fr"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}>
{entries["fr"].map(d => (<div className={"entry"} style={{ <div className={"spalte"}
id={"3"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}>
{entries[3].map(d => (d != null && <div className={"entry"} style={{
width: "100%", width: "100%",
gridRowStart: d.start_point, gridRowStart: d.timestart,
gridRowEnd: d.end_point, gridRowEnd: d.timeend,
backgroundColor: colors[d.colorID] backgroundColor: "#77932b"
}} id={"entry"}> }} id={d.id + "e"}>
<div className={"resize-grab"} id={"grab"}></div>
<div></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}> <div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p> <p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</p>
<p>Moduel etc.</p> <p>Moduel etc.</p>
<p>Mehr Infos</p> <p>Mehr Infos</p>
<p>Raum</p> <p>Raum</p>
@@ -473,20 +496,45 @@ export default function CalenderView(p)
<div className={"resize-grab"} id={"grab"}></div> <div className={"resize-grab"} id={"grab"}></div>
</div>))} </div>))}
</div> </div>
{/*same as monday*/}
<div className={"spalte"} onMouseDown={mouse_down} onMouseUp={mouse_up} onMouseMove={mouse_move}
id={"sa"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}>
{entries["sa"].map(d => (<div className={"entry"} style={{ <div className={"spalte"}
id={"4"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(e)}>
{entries[4].map(d => (d != null && <div className={"entry"} style={{
width: "100%", width: "100%",
gridRowStart: d.start_point, gridRowStart: d.timestart,
gridRowEnd: d.end_point, gridRowEnd: d.timeend,
backgroundColor: colors[d.colorID] backgroundColor: "#77932b"
}} id={"entry"}> }} id={d.id + "e"}>
<div className={"resize-grab"} id={"grab"}></div> <div></div>
<div style={{maxHeight: "60%"}} className={"no-pointer-events"}> <div style={{maxHeight: "60%"}} className={"no-pointer-events"}>
<p>{internal_to_time(d.start_point) + " - " + internal_to_time(d.end_point)}</p> <p>{internal_to_time(d.timestart) + " - " + internal_to_time(d.timeend)}</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"}
id={"5"} style={{gridTemplateRows: `repeat(96, ${cellHeight}px)`}}
onMouseDown={e => onMouseDown(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></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> <p>Moduel etc.</p>
<p>Mehr Infos</p> <p>Mehr Infos</p>
<p>Raum</p> <p>Raum</p>
@@ -496,7 +544,7 @@ export default function CalenderView(p)
</div> </div>
</div> </div>
{/*overlay with timeline*/}
<div className={"overlay"} style={{backgroundColor: "rgba(0, 0, 0, 0)"}}> <div className={"overlay"} style={{backgroundColor: "rgba(0, 0, 0, 0)"}}>
{/*maps a list of internal time stamps to lines and time stamps*/} {/*maps a list of internal time stamps to lines and time stamps*/}
{temp.map(i => (<div style={{ {temp.map(i => (<div style={{
@@ -553,16 +601,8 @@ export default function CalenderView(p)
}}>{internal_to_time(i + 1)}</p> }}>{internal_to_time(i + 1)}</p>
</div>))} </div>))}
</div> </div>
</div> </div>
</div> </div>
{/*the second resize button*/}
<Button text={"+"} fontSize={25} onClick={() =>
{
cellHeight += 5;
setT(!t)
}} width={50} height={50}/>
</div> </div>
) )
} }
+4
View File
@@ -20,6 +20,9 @@ export default function Login() {
if (value != "failed") { if (value != "failed") {
localStorage.setItem("sessionid", value); localStorage.setItem("sessionid", value);
url = "http://localhost:8080/users/check?sessionid=" + value;
fetch(url).then(r => r.json()).then(u => localStorage.setItem("userid", u.id))
await router.push("/semesteroverview") await router.push("/semesteroverview")
} else { } else {
@@ -35,6 +38,7 @@ export default function Login() {
const [backgroundColor, setBackgroundColor] = useState("rgb(255, 255, 255)") const [backgroundColor, setBackgroundColor] = useState("rgb(255, 255, 255)")
const router = useRouter() const router = useRouter()
return ( return (
// <div className="border"> // <div className="border">
<login className={"login-container box-shadow"}> <login className={"login-container box-shadow"}>
+9
View File
@@ -0,0 +1,9 @@
import CalenderView from "@/components/CalenderView";
export default function planning(p)
{
return (
<CalenderView/>
)
}
+2
View File
@@ -25,7 +25,9 @@ export default function SemesterOverview(p)
if(m.target === m.currentTarget) if(m.target === m.currentTarget)
{ {
localStorage.setItem("currentsid", e.id) localStorage.setItem("currentsid", e.id)
router.push("/planning")
} }
} }
function onClickNewSemester() function onClickNewSemester()
+1 -1
View File
@@ -322,7 +322,7 @@ Calender View
justify-content: space-between; justify-content: space-between;
padding: 0 2px; padding: 0 2px;
align-items: center; align-items: center;
cursor: move; /*cursor: move;*/
z-index: 10; z-index: 10;
overflow: hidden; overflow: hidden;
margin-top: 1px; margin-top: 1px;
Binary file not shown.
+30
View File
@@ -270985,3 +270985,33 @@ No data is available [2000-214]
2023-05-25 13:35:45 jdbc[3]: exception 2023-05-25 13:35:45 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214] No data is available [2000-214]
2023-05-26 00:45:38 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
2023-05-26 00:45:38 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
2023-05-26 00:45:39 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
2023-05-26 00:45:39 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
2023-05-26 00:45:42 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
2023-05-26 00:45:43 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
2023-05-26 00:45:46 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
2023-05-26 00:45:47 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
2023-05-26 00:45:49 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
2023-05-26 00:45:49 jdbc[3]: exception
org.h2.jdbc.JdbcSQLNonTransientException: Keine Daten verfügbar
No data is available [2000-214]
@@ -173,58 +173,92 @@ public class DataBaseHandler
/** /**
ENTRIES ENTRIES
*/ */
//method that returns all entries of a day based on the given parameters public void addEntry(Entry entry)
public Entry[] getEntries(int dayinweek, int weeknumber, int semesterid, User user)
{ {
try try
{ {
//search the correct data in the database st.executeUpdate("insert into entries (daynumber, yearnumber, semesterid, usercreatedbyid, timestart, timeend, info) values (" +
ResultSet rs = st.executeQuery("select distinct e.id, e.dayid, e.usercreatedbyid, e.timestart, e.timeend, e.info " + entry.getDaynumber() + ", " + entry.getYearnumber() + ", " + entry.getSemesterid() + ", " +
"from entries e, days d, weeks w, semester s " + entry.getUsercreatedbyid() + ", " + entry.getTimestart() + ", " + entry.getTimeend() + ", '" + entry.getInfo() + "')"
"where e.dayid = d.id and " + );
"d.weekid = w.id and " + }
"w.semesterid = s.id and " + catch(Exception e)
"d.dayinweek = " + dayinweek + " and " +
"w.weeknumber = " + weeknumber + " and " +
"s.id = " + semesterid);
int editable = 0;
//a temporary list to save entry objects in
List<Entry> temp = new ArrayList<>();
//while there a still entries for the day
while(rs.next())
{ {
editable = 0; e.printStackTrace();
//if entry has been created by the requesting user set the entry to editable (or the user is admin) }
if(rs.getInt("usercreatedbyid") == user.getId() || user.getPermissions() == 1)
{
editable = 1;
} }
temp.add( public Entry[][] getEntries(int semesterid, int daynumber, int yearnumber)
new Entry( {
try
{
ResultSet rs = st.executeQuery("select * from entries where " +
"semesterid=" + semesterid +
" and yearnumber=" + yearnumber +
" and daynumber between " + daynumber + " and " + daynumber + 6);
List<Entry> entryList = new ArrayList<>();
Entry current = null;
while((current = resultSetToEntry(rs)) != null)
{
entryList.add(current);
}
Entry[][] entries = new Entry[6][20];
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < entryList.size(); j++)
{
if(entryList.get(j).getDaynumber() == i + daynumber)
{
entries[i][j] = entryList.get(j);
}
}
}
return entries;
}
catch(Exception e)
{
return null;
}
}
public void deleteEntry(int id)
{
try
{
st.executeUpdate("delete from entries where id=" + id);
}
catch (Exception e)
{
}
}
public Entry resultSetToEntry(ResultSet rs)
{
try
{
rs.next();
return new Entry(
rs.getInt("id"), rs.getInt("id"),
rs.getInt("dayid"), rs.getInt("daynumber"),
rs.getInt("yearnumber"),
rs.getInt("usercreatedbyid"), rs.getInt("usercreatedbyid"),
rs.getInt("timestart"), rs.getInt("timestart"),
rs.getInt("timeend"), rs.getInt("timeend"),
rs.getString("info"), rs.getInt("semesterid"),
editable rs.getString("info")
)
); );
} }
catch(Exception e)
//return the temporary list as an array
return temp.toArray(new Entry[0]);
} catch (SQLException e)
{ {
throw new RuntimeException(e); return null;
} }
} }
/** /**
SEMESTER SEMESTER
*/ */
@@ -4,22 +4,24 @@ package com.example.backend.anwprj.Entries;
public class Entry public class Entry
{ {
private int id; private int id;
private int dayid; private int daynumber;
private int yearnumber;
private int usercreatedbyid; private int usercreatedbyid;
private int timestart; private int timestart;
private int timeend; private int timeend;
private int semesterid;
private String info; private String info;
private int editable;
public Entry(int id, int dayid, int usercreatedbyid, int timestart, int timeend, String info, int editable) public Entry(int id, int daynumber, int yearnumber, int usercreatedbyid, int timestart, int timeend, int semesterid, String info)
{ {
this.id = id; this.id = id;
this.dayid = dayid; this.daynumber = daynumber;
this.yearnumber = yearnumber;
this.usercreatedbyid = usercreatedbyid; this.usercreatedbyid = usercreatedbyid;
this.timestart = timestart; this.timestart = timestart;
this.timeend = timeend; this.timeend = timeend;
this.semesterid = semesterid;
this.info = info; this.info = info;
this.editable = editable;
} }
public int getId() public int getId()
@@ -27,9 +29,14 @@ public class Entry
return id; return id;
} }
public int getDayid() public int getDaynumber()
{ {
return dayid; return daynumber;
}
public int getYearnumber()
{
return yearnumber;
} }
public int getUsercreatedbyid() public int getUsercreatedbyid()
@@ -47,33 +54,13 @@ public class Entry
return timeend; return timeend;
} }
public int getSemesterid()
{
return semesterid;
}
public String getInfo() public String getInfo()
{ {
return info; return info;
} }
public void setDayid(int dayid)
{
this.dayid = dayid;
}
public void setTimestart(int timestart)
{
this.timestart = timestart;
}
public void setTimeend(int timeend)
{
this.timeend = timeend;
}
public void setInfo(String info)
{
this.info = info;
}
public int getEditable()
{
return editable;
}
} }
@@ -18,28 +18,28 @@ public class EntriesController
} }
@CrossOrigin @CrossOrigin
@GetMapping("/entries") @PostMapping("/entries")
public ResponseEntity<Entry[]> getEntries( public ResponseEntity<Boolean> postEntry(@RequestBody Entry entry)
@RequestParam(name = "sessionid") String sessionID,
@RequestParam(name = "dayinweek") int dayinweek,
@RequestParam(name = "weeknumber") int weeknumber,
@RequestParam(name = "semesterid") int semesterid)
{ {
User user = UserSessionIDHandler.getUserBySessionID(sessionID); db.addEntry(entry);
return new ResponseEntity<>(true, HttpStatus.OK);
if(user == null)
{
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Entry[] entries = db.getEntries(dayinweek, weeknumber, semesterid, user);
return new ResponseEntity<>(entries, HttpStatus.OK);
} }
@CrossOrigin @CrossOrigin
@PostMapping("/entries") @GetMapping("/entries")
public ResponseEntity<Entry[]> postEntries(@RequestBody Entry[] entries, @RequestParam(name="sessionid") String sessionID) public ResponseEntity<Entry[][]> getEntries(@RequestParam(name="semesterid") int semesterid,
@RequestParam(name="daynumber") int daynumber,
@RequestParam(name="yearnumber") int yearnumber)
{ {
return null;
return new ResponseEntity<>(db.getEntries(semesterid, daynumber, yearnumber), HttpStatus.OK);
}
@CrossOrigin
@DeleteMapping("/entries")
public ResponseEntity<Boolean> deleteEntry(@RequestParam(name="id") int id)
{
db.deleteEntry(id);
return new ResponseEntity<>(true, HttpStatus.OK);
} }
} }