UI and better date generation finished
This commit is contained in:
@@ -1,42 +1 @@
|
||||
#root {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.react:hover {
|
||||
filter: drop-shadow(0 0 2em #61dafbaa);
|
||||
}
|
||||
|
||||
@keyframes logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
a:nth-of-type(2) .logo {
|
||||
animation: logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import "./App.css";
|
||||
import LeftSide from "./components/LeftSide";
|
||||
import RightSide from "./components/RightSide";
|
||||
import Grid from "@mui/material/Grid2";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div>
|
||||
<LeftSide />
|
||||
<RightSide />
|
||||
</div>
|
||||
<Grid container spacing={2}>
|
||||
<Grid size={6}>
|
||||
<LeftSide />
|
||||
</Grid>
|
||||
<Grid size={6}>
|
||||
<RightSide />
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,27 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import api from "../utils/api";
|
||||
import Grid from "@mui/material/Grid2";
|
||||
import {
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
Table,
|
||||
} from "@mui/material";
|
||||
|
||||
const LeftSide = () => {
|
||||
// next prev and sort
|
||||
const [users, setUsers] = useState();
|
||||
const [params, setParams] = useState({ offset: 0, sortby: "f_name" });
|
||||
|
||||
// reset button
|
||||
const [reset, setReset] = useState(true);
|
||||
|
||||
// date
|
||||
const [date, setDate] = useState({ from: "2021-01-01", to: "2028-01-01" });
|
||||
const [dateToSubmit, setDateToSubmit] = useState({});
|
||||
const [dateToSubmit, setDateToSubmit] = useState({
|
||||
from: "2021-01-01",
|
||||
to: "2028-01-01",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
@@ -28,13 +40,7 @@ const LeftSide = () => {
|
||||
fetchData();
|
||||
}, [reset, params, dateToSubmit]);
|
||||
|
||||
const handleButtonClick = () => {
|
||||
// When the button is clicked, update the dateToShow state and trigger a re-render
|
||||
setDateToSubmit(date);
|
||||
};
|
||||
|
||||
const viewProjectHours = (user) => {
|
||||
console.log(user);
|
||||
async function fetchHours() {
|
||||
const resp = await api.get("/getUser", {
|
||||
params: { userid: user },
|
||||
@@ -47,8 +53,8 @@ const LeftSide = () => {
|
||||
|
||||
if (!users) return <></>;
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<Grid container spacing={2}>
|
||||
<Grid size={5}>
|
||||
<label htmlFor="date">From: </label>
|
||||
<input
|
||||
type="date"
|
||||
@@ -65,10 +71,10 @@ const LeftSide = () => {
|
||||
value={date.to}
|
||||
onChange={(event) => setDate({ ...date, to: event.target.value })}
|
||||
/>
|
||||
<button onClick={handleButtonClick}>Submit Date</button>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Select a sort:</h4>
|
||||
<button onClick={() => setDateToSubmit(date)}>Submit Date</button>
|
||||
</Grid>
|
||||
<Grid size={3}>
|
||||
<span>Select a sort:</span>
|
||||
<select
|
||||
value={params.sortby}
|
||||
onChange={(event) =>
|
||||
@@ -84,60 +90,68 @@ const LeftSide = () => {
|
||||
<option value="date">Date</option>
|
||||
<option value="time">Time</option>
|
||||
</select>
|
||||
</div>
|
||||
<button
|
||||
onClick={() =>
|
||||
setParams((prevParams) => {
|
||||
return { ...prevParams, offset: prevParams.offset + 10 };
|
||||
})
|
||||
}
|
||||
>
|
||||
Next users
|
||||
</button>
|
||||
<button
|
||||
onClick={() =>
|
||||
setParams((prevParams) => {
|
||||
return { ...prevParams, offset: prevParams.offset - 10 };
|
||||
})
|
||||
}
|
||||
>
|
||||
Prev users
|
||||
</button>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Email</th>
|
||||
<th>Project name</th>
|
||||
<th>Date</th>
|
||||
<th>Hours</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</Grid>
|
||||
<Grid size={4}></Grid>
|
||||
<Grid size={4}></Grid>
|
||||
<Grid size={4}>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (!params.offset) return;
|
||||
setParams((prevParams) => {
|
||||
return { ...prevParams, offset: prevParams.offset - 10 };
|
||||
});
|
||||
}}
|
||||
>
|
||||
Prev users
|
||||
</button>
|
||||
<button
|
||||
onClick={() =>
|
||||
setParams((prevParams) => {
|
||||
return { ...prevParams, offset: prevParams.offset + 10 };
|
||||
})
|
||||
}
|
||||
>
|
||||
Next users
|
||||
</button>
|
||||
</Grid>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>First Name</TableCell>
|
||||
<TableCell>Last Name</TableCell>
|
||||
<TableCell>Email</TableCell>
|
||||
<TableCell>Project name</TableCell>
|
||||
<TableCell>Date</TableCell>
|
||||
<TableCell>Hours</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{users.length > 0 && Array.isArray(users) ? (
|
||||
users.map((post, idx) => (
|
||||
<tr key={idx}>
|
||||
<td>{post.f_name} </td>
|
||||
<td>{post.l_name} </td>
|
||||
<td>{post.mail} </td>
|
||||
<td>{post.name} </td>
|
||||
<td>{post.date} </td>
|
||||
<td>{post.time} </td>
|
||||
<td>
|
||||
<TableRow key={idx}>
|
||||
<TableCell>{post.f_name} </TableCell>
|
||||
<TableCell>{post.l_name} </TableCell>
|
||||
<TableCell>{post.mail} </TableCell>
|
||||
<TableCell>{post.name} </TableCell>
|
||||
<TableCell>{post.date.slice(0, 10)} </TableCell>
|
||||
<TableCell>{post.time} </TableCell>
|
||||
<TableCell>
|
||||
<button onClick={() => viewProjectHours(post.user)}>
|
||||
View Project Hours
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<div>No posts found...</div>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
<button onClick={() => setReset(!reset)}>RESET</button>
|
||||
</div>
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Grid size={5}></Grid>
|
||||
<Grid size={6}>
|
||||
<button onClick={() => setReset(!reset)}>RESET</button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,22 +3,39 @@ import api from "../utils/api";
|
||||
import { Chart } from "react-google-charts";
|
||||
|
||||
const RightSide = () => {
|
||||
const [topten, setTopten] = useState();
|
||||
// input field
|
||||
const [date, setDate] = useState({ from: "2021-01-01", to: "2028-01-01" });
|
||||
// graph date
|
||||
const [topten, setTopten] = useState({
|
||||
from: "2000-01-01",
|
||||
to: "2100-01-01",
|
||||
});
|
||||
// date input field
|
||||
const [date, setDate] = useState({ from: "2000-01-01", to: "2100-01-01" });
|
||||
const [dateToSubmit, setDateToSubmit] = useState({});
|
||||
// radio
|
||||
// radio button
|
||||
const [selectedOption, setSelectedOption] = useState("project");
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
const resp = await api.get("/gettopten", {
|
||||
params: {
|
||||
to: dateToSubmit.to,
|
||||
from: dateToSubmit.from,
|
||||
to: dateToSubmit.to,
|
||||
filterBy: selectedOption,
|
||||
},
|
||||
});
|
||||
resp.data.unshift(["User", "Hours"]);
|
||||
// turn the data into form suitable to charts
|
||||
if (selectedOption === "project")
|
||||
for (let idx = 1; idx < resp.data.length; idx++) {
|
||||
resp.data[idx] = [resp.data[idx].name, resp.data[idx].total_time];
|
||||
}
|
||||
else if (selectedOption === "user")
|
||||
for (let idx = 1; idx < resp.data.length; idx++) {
|
||||
resp.data[idx] = [
|
||||
resp.data[idx].f_name + " " + resp.data[idx].l_name,
|
||||
resp.data[idx].total_time,
|
||||
];
|
||||
}
|
||||
setTopten(resp.data);
|
||||
}
|
||||
fetchData();
|
||||
@@ -27,29 +44,21 @@ const RightSide = () => {
|
||||
// Chart options
|
||||
const options = {
|
||||
title: "Most comitted hours per user",
|
||||
chartArea: { width: "50%" },
|
||||
chartArea: { width: "70%" },
|
||||
hAxis: {
|
||||
title: "Hours",
|
||||
minValue: 0,
|
||||
},
|
||||
vAxis: {
|
||||
title: "User",
|
||||
title: selectedOption,
|
||||
},
|
||||
};
|
||||
|
||||
const handleButtonClick = () => {
|
||||
// When the button is clicked, update the dateToShow state and trigger a re-render
|
||||
setDateToSubmit(date);
|
||||
};
|
||||
|
||||
// Handle the change when a radio button is selected
|
||||
const handleChange = (event) => {
|
||||
setSelectedOption(event.target.value);
|
||||
};
|
||||
if (!topten) <></>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<div style={{ flex: 1 }}>
|
||||
<>
|
||||
<label htmlFor="date">From: </label>
|
||||
<input
|
||||
type="date"
|
||||
@@ -66,30 +75,28 @@ const RightSide = () => {
|
||||
value={date.to}
|
||||
onChange={(event) => setDate({ ...date, to: event.target.value })}
|
||||
/>
|
||||
<button onClick={handleButtonClick}>Submit Date</button>
|
||||
</div>
|
||||
<div>
|
||||
<button onClick={() => setDateToSubmit(date)}>Submit Date</button>
|
||||
</>
|
||||
<>
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
value="user"
|
||||
checked={selectedOption === "user"}
|
||||
onChange={handleChange}
|
||||
onChange={(event) => setSelectedOption(event.target.value)}
|
||||
/>
|
||||
User
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
value="project"
|
||||
checked={selectedOption === "project"}
|
||||
onChange={handleChange}
|
||||
onChange={(event) => setSelectedOption(event.target.value)}
|
||||
/>
|
||||
Project
|
||||
</label>
|
||||
</div>
|
||||
</>
|
||||
<Chart
|
||||
chartType="BarChart"
|
||||
width="100%"
|
||||
|
||||
Reference in New Issue
Block a user