Skip to content
Snippets Groups Projects
Commit 91ea30f7 authored by Bernard Roland (Student Com20)'s avatar Bernard Roland (Student Com20)
Browse files

Added time selection to user and project stats

parent 24ab5af6
No related branches found
No related tags found
No related merge requests found
......@@ -6,7 +6,7 @@ import './tabs.scss';
export interface Tab {
label: string;
route: string;
route: string | string[];
link?: string;
component: ReactNode
}
......@@ -24,7 +24,7 @@ export default function Tabs({ tabs }: Props) {
key={tab.label}
className="tab"
activeClassName="active"
to={tab.link ?? tab.route}
to={tab.link ?? (typeof tab.route === 'string' ? tab.route : tab.route[0])}
isActive={(_, location) =>
matchPath(location.pathname, { path: tab.route, exact: true })
? true
......
import { useEffect, useState } from 'react';
import { useParams } from 'react-router';
import { getTeam } from 'adapters/team';
import { formatDate, subtractTime } from 'timely';
import Dropdown from 'components/navigation/Dropdown';
import DetailGrid from 'components/layout/DetailGrid';
import LoadingScreen from 'components/ui/LoadingScreen';
import { getProjectActivity, Project } from 'adapters/project';
......@@ -11,6 +13,16 @@ import BarChart, { ChartItem, parseActivity } from 'components/graphs/BarChart';
import './project-details.scss';
enum Timespan {
WEEK = 'week',
MONTH = 'month',
YEAR = 'year',
}
interface Params {
time?: Timespan;
}
interface Props {
project: Project
}
......@@ -19,13 +31,34 @@ export default function ProjectDetails({ project }: Props) {
const [teams, setTeams] = useState<string[]>([]);
const [activity, setActivity] = useState<ChartItem[]>([]);
const time = useParams<Params>().time ?? Timespan.WEEK;
const dropdowns = [
{
time: 'week',
label: 'Last week',
route: '/projects/' + project.id + '/stats/week'
},
{
time: 'month',
label: 'Last month',
route: '/projects/' + project.id + '/stats/month'
},
{
time: 'year',
label: 'Last year',
route: '/projects/' + project.id + '/stats/year'
}
];
useEffect(() => {
project.teams.forEach(teamId => {
getTeam(teamId).then((team) => setTeams(prev => [...prev, team.name]));
});
getProjectActivity(project.id, subtractTime(new Date(), 1, 'week'), new Date()).then((a) => setActivity(parseActivity(a)))
Promise.all(project.teams.map(getTeam))
.then(teams => setTeams(teams.map(team => team.name)));
}, [project]);
useEffect(() => {
getProjectActivity(project.id, subtractTime(new Date(), 1, time), new Date()).then((a) => setActivity(parseActivity(a)))
}, [project, time]);
let details = [{
icon: 'group',
title: 'Teams',
......@@ -43,6 +76,12 @@ export default function ProjectDetails({ project }: Props) {
return (
<section className="project-details">
<DetailGrid details={details} />
<Dropdown items={dropdowns.filter(d => d.time !== time)}>
<span className="material-icons icon">
expand_more
</span>
{dropdowns.find(d => d.time === time)?.label}
</Dropdown>
{
activity
? <BarChart unit="h" multiplier={1 / 60 / 60 / 1000} data={activity} />
......
......@@ -35,7 +35,7 @@ export default function ProjectDetail() {
setTabs([
{
label: 'Details',
route: '/projects/' + projectId,
route: ['/projects/' + projectId, '/projects/' + projectId + '/stats/:time'],
component: <ProjectDetails project={project} />
},
{
......
......@@ -7,7 +7,7 @@ import { getUserActivity, getUserCompletion } from 'adapters/user';
import LoadingScreen from 'components/ui/LoadingScreen';
import CompletionGrid from 'components/layout/CompletionGrid';
import Dropdown, { DropDownItem } from 'components/navigation/Dropdown';
import Dropdown from 'components/navigation/Dropdown';
import { CompletionProps, parseCompletion } from 'components/ui/Completion';
import BarChart, { ChartItem, parseActivity } from 'components/graphs/BarChart';
......@@ -23,14 +23,12 @@ interface Params {
time?: Timespan;
}
interface FilterDropdownItem extends DropDownItem {
time: string
}
export default function Tasks() {
const [completions, setCompletions] = useState<CompletionProps[]>();
const [activity, setActivity] = useState<ChartItem[]>();
const [dropdowns] = useState<FilterDropdownItem[]>([
const time = useParams<Params>().time ?? Timespan.WEEK;
const dropdowns = [
{
time: 'week',
label: 'Last week',
......@@ -46,9 +44,7 @@ export default function Tasks() {
label: 'Last year',
route: '/stats/year'
}
]);
const time = useParams<Params>().time ?? Timespan.WEEK;
];
useEffect(() => {
getUserCompletion().then((completion) => setCompletions(parseCompletion(completion)));
......@@ -56,28 +52,30 @@ export default function Tasks() {
}, [time]);
return (
(completions && activity)
? (
<div className="stats-page">
<div className="content-container">
<h1 className="underlined">Stats</h1>
<div className="description-container">
Here are some of your recent statistics.
</div>
<Dropdown items={dropdowns.filter(d => d.time !== time)}>
<span className="material-icons icon">
expand_more
</span>
{dropdowns.find(d => d.time === time)?.label}
</Dropdown>
<h2>Activity</h2>
<BarChart unit="h" multiplier={1 / 60 / 60 / 1000} data={activity} />
<h2>Completion</h2>
<CompletionGrid items={completions} />
</div>
<div className="stats-page">
<div className="content-container">
<h1 className="underlined">Stats</h1>
<div className="description-container">
Here are some of your recent statistics.
</div>
)
: <LoadingScreen />
<Dropdown items={dropdowns.filter(d => d.time !== time)}>
<span className="material-icons icon">
expand_more
</span>
{dropdowns.find(d => d.time === time)?.label}
</Dropdown>
<h2>Activity</h2>
{ activity
? <BarChart unit="h" multiplier={1 / 60 / 60 / 1000} data={activity} />
: <LoadingScreen />
}
<h2>Completion</h2>
{ completions
? <CompletionGrid items={completions} />
: <LoadingScreen />
}
</div>
</div>
);
}
......@@ -7,7 +7,7 @@ import { getTeamActivity, getTeamCompletion } from 'adapters/team';
import LoadingScreen from 'components/ui/LoadingScreen';
import CompletionGrid from 'components/layout/CompletionGrid';
import Dropdown, { DropDownItem } from 'components/navigation/Dropdown';
import Dropdown from 'components/navigation/Dropdown';
import { CompletionProps, parseCompletion } from 'components/ui/Completion';
import BarChart, { ChartItem, parseActivity } from 'components/graphs/BarChart';
......@@ -27,14 +27,13 @@ interface Params {
time: Timespan;
}
interface FilterDropdownItem extends DropDownItem {
time: string
}
export default function TeamsStats({ teamId }: Props) {
const [activity, setActivity] = useState<ChartItem[]>([]);
const [completions, setCompletions] = useState<CompletionProps[]>([]);
const [dropdowns] = useState<FilterDropdownItem[]>([
const history = useHistory();
const { time } = useParams<Params>();
const dropdowns = [
{
time: 'week',
label: 'Last week',
......@@ -50,10 +49,7 @@ export default function TeamsStats({ teamId }: Props) {
label: 'Last year',
route: '/teams/' + teamId + '/stats/year'
}
]);
const history = useHistory();
const { time } = useParams<Params>();
];
useEffect(() => {
getTeamActivity(teamId, subtractTime(new Date(), 1, time), new Date())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment