mirror of
https://github.com/DerTyp7/time-tracking.git
synced 2025-10-29 20:42:10 +01:00
table and entries
This commit is contained in:
58
frontend/package-lock.json
generated
58
frontend/package-lock.json
generated
@@ -13,6 +13,7 @@
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"sass": "^1.51.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
@@ -7991,6 +7992,14 @@
|
||||
"he": "bin/he"
|
||||
}
|
||||
},
|
||||
"node_modules/history": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
|
||||
"integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.7.6"
|
||||
}
|
||||
},
|
||||
"node_modules/hoopy": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
|
||||
@@ -13425,6 +13434,30 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz",
|
||||
"integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==",
|
||||
"dependencies": {
|
||||
"history": "^5.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz",
|
||||
"integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==",
|
||||
"dependencies": {
|
||||
"history": "^5.2.0",
|
||||
"react-router": "6.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-scripts": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||
@@ -21933,6 +21966,14 @@
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
||||
},
|
||||
"history": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
|
||||
"integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.7.6"
|
||||
}
|
||||
},
|
||||
"hoopy": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
|
||||
@@ -25729,6 +25770,23 @@
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
||||
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
|
||||
},
|
||||
"react-router": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz",
|
||||
"integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==",
|
||||
"requires": {
|
||||
"history": "^5.2.0"
|
||||
}
|
||||
},
|
||||
"react-router-dom": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz",
|
||||
"integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==",
|
||||
"requires": {
|
||||
"history": "^5.2.0",
|
||||
"react-router": "6.3.0"
|
||||
}
|
||||
},
|
||||
"react-scripts": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"sass": "^1.51.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
import "./css/App.scss";
|
||||
import "./css/app.scss";
|
||||
import ServerProvider from "./contexts/ServerContext";
|
||||
import Table from "./components/table/Table";
|
||||
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div id="app">
|
||||
<div id="content" className="app-container">
|
||||
<h1>Hello World</h1>
|
||||
<ServerProvider>
|
||||
<div id="app">
|
||||
<div id="content" className="app-container">
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route exact path="/table/:monthYear" element={<Table />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
</div>
|
||||
<div id="sidebar" className="app-container">
|
||||
<h1>Sidebar</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div id="sidebar" className="app-container">
|
||||
<h1>Sidebar</h1>
|
||||
</div>
|
||||
</div>
|
||||
</ServerProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
25
frontend/src/components/table/Header.jsx
Normal file
25
frontend/src/components/table/Header.jsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import "../../css/components/table.scss";
|
||||
|
||||
function Header({ date, checkedIn, checkedOut, ind, norm }) {
|
||||
return (
|
||||
<div className="table-header">
|
||||
<div className="table-cell">
|
||||
<span>{date}</span>
|
||||
</div>
|
||||
<div className="table-cell">
|
||||
<span>{checkedIn}</span>
|
||||
</div>
|
||||
<div className="table-cell">
|
||||
<span>{checkedOut}</span>
|
||||
</div>
|
||||
<div className="table-cell">
|
||||
<span>{ind}</span>
|
||||
</div>
|
||||
<div className="table-cell">
|
||||
<span>{norm}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Header;
|
||||
25
frontend/src/components/table/Row.jsx
Normal file
25
frontend/src/components/table/Row.jsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import "../../css/components/table.scss";
|
||||
|
||||
function Row({ date, checkedIn, checkedOut, ind, norm }) {
|
||||
return (
|
||||
<div className="table-row">
|
||||
<div className="table-cell">
|
||||
<span>{date ? date : "-"}</span>
|
||||
</div>
|
||||
<div className="table-cell">
|
||||
<span>{checkedIn ? checkedIn : "-"}</span>
|
||||
</div>
|
||||
<div className="table-cell">
|
||||
<span>{checkedOut ? checkedOut : "-"}</span>
|
||||
</div>
|
||||
<div className="table-cell">
|
||||
<span>{ind ? ind : "-"}</span>
|
||||
</div>
|
||||
<div className="table-cell">
|
||||
<span>{norm ? norm : "-"}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Row;
|
||||
81
frontend/src/components/table/Table.jsx
Normal file
81
frontend/src/components/table/Table.jsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import React, { useState, useContext, useEffect } from "react";
|
||||
import { ServerContext } from "../../contexts/ServerContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import "../../css/components/table.scss";
|
||||
|
||||
import Row from "./Row";
|
||||
import Header from "./Header";
|
||||
|
||||
function Table() {
|
||||
const params = useParams();
|
||||
const { URL } = useContext(ServerContext);
|
||||
const [entries, setEntries] = useState([]);
|
||||
const [monthYear, setMonthYear] = useState(params.monthYear);
|
||||
|
||||
async function fetchEntries() {
|
||||
let response = await fetch(URL + `/api/entry/all/` + monthYear);
|
||||
let data = await response.json();
|
||||
setEntries(data);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchEntries();
|
||||
}, []);
|
||||
|
||||
function nextMonth() {
|
||||
let month = parseInt(monthYear.split("-")[0]);
|
||||
|
||||
if (month === 12) {
|
||||
window.location.href = `/table/${1}-${
|
||||
parseInt(monthYear.split("-")[1]) + 1
|
||||
}`;
|
||||
} else {
|
||||
window.location.href = `/table/${month + 1}-${monthYear.split("-")[1]}`;
|
||||
}
|
||||
}
|
||||
|
||||
function previousMonth() {
|
||||
let month = parseInt(monthYear.split("-")[0]);
|
||||
|
||||
if (month === 1) {
|
||||
window.location.href = `/table/${12}-${
|
||||
parseInt(monthYear.split("-")[1]) - 1
|
||||
}`;
|
||||
} else {
|
||||
window.location.href = `/table/${month - 1}-${monthYear.split("-")[1]}`;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="table">
|
||||
<div className="table-nav">
|
||||
<div onClick={previousMonth}> </div>
|
||||
<h2>{monthYear}</h2>
|
||||
<div onClick={nextMonth}> </div>
|
||||
</div>
|
||||
<div className="table-container">
|
||||
<Header
|
||||
date="Date"
|
||||
checkedIn="Checked In"
|
||||
checkedOut="Checked Out"
|
||||
ind="Ind."
|
||||
norm="Norm."
|
||||
/>
|
||||
|
||||
{/* ROWS */}
|
||||
{entries.map((entry, index) => (
|
||||
<Row
|
||||
date={entry.date}
|
||||
checkedIn={entry.checkedIn}
|
||||
checkedOut={entry.checkedOut}
|
||||
ind={entry.ind}
|
||||
norm={entry.norm}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Table;
|
||||
14
frontend/src/contexts/ServerContext.jsx
Normal file
14
frontend/src/contexts/ServerContext.jsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React, { createContext } from "react";
|
||||
|
||||
export const ServerContext = createContext();
|
||||
|
||||
const ServerProvider = (props) => {
|
||||
const URL = "http://127.0.0.1:8080";
|
||||
return (
|
||||
<ServerContext.Provider value={{ URL }}>
|
||||
{props.children}
|
||||
</ServerContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServerProvider;
|
||||
59
frontend/src/css/components/table.scss
Normal file
59
frontend/src/css/components/table.scss
Normal file
@@ -0,0 +1,59 @@
|
||||
#table {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.table-nav {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
div {
|
||||
background-color: red;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
padding-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
text-align: center;
|
||||
font-size: 1rem;
|
||||
|
||||
.table-header {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
|
||||
width: 100%;
|
||||
background-color: rgb(28, 28, 28);
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
border-bottom: 2px solid rgb(157, 157, 157);
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
|
||||
width: 100%;
|
||||
background-color: rgb(61, 61, 61);
|
||||
border-top: 1px solid rgb(85, 85, 85);
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
grid-area: auto;
|
||||
padding: 10px;
|
||||
border-right: 1px solid rgb(85, 85, 85);
|
||||
border-left: 1px solid rgb(85, 85, 85);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user