132 lines
4.1 KiB
JavaScript
132 lines
4.1 KiB
JavaScript
import { useQuery } from "@apollo/client";
|
|
import { Card, Col, Space, Statistic, Typography } from "antd";
|
|
import moment from "moment";
|
|
import { useMemo } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { connect } from "react-redux";
|
|
import { createStructuredSelector } from "reselect";
|
|
import { QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE } from "../../graphql/timetickets.queries";
|
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
|
import AlertComponent from "../alert/alert.component";
|
|
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
|
const { Title } = Typography;
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
technician: selectTechnician,
|
|
});
|
|
const mapDispatchToProps = (dispatch) => ({});
|
|
|
|
const TechJobStatistics = ({ technician }) => {
|
|
const { t } = useTranslation();
|
|
|
|
const startDate = moment().startOf("week");
|
|
const endDate = moment().endOf("week");
|
|
|
|
const { loading, error, data } = useQuery(
|
|
QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE,
|
|
{
|
|
variables: {
|
|
start: startDate.format("YYYY-MM-DD"),
|
|
end: endDate.format("YYYY-MM-DD"),
|
|
fixedStart: moment().startOf("month").format("YYYY-MM-DD"),
|
|
fixedEnd: moment().endOf("month").format("YYYY-MM-DD"),
|
|
employeeid: technician.id,
|
|
},
|
|
fetchPolicy: "network-only",
|
|
nextFetchPolicy: "network-only",
|
|
}
|
|
);
|
|
|
|
const totals = useMemo(() => {
|
|
if (data && data.timetickets && data.fixedperiod) {
|
|
const week = data.timetickets.reduce(
|
|
(acc, val) => {
|
|
acc.productivehrs = acc.productivehrs + val.productivehrs;
|
|
acc.actualhrs = acc.actualhrs + val.actualhrs;
|
|
return acc;
|
|
},
|
|
{ productivehrs: 0, actualhrs: 0 }
|
|
);
|
|
|
|
const month = data.fixedperiod.reduce(
|
|
(acc, val) => {
|
|
acc.productivehrs = acc.productivehrs + val.productivehrs;
|
|
acc.actualhrs = acc.actualhrs + val.actualhrs;
|
|
return acc;
|
|
},
|
|
{ productivehrs: 0, actualhrs: 0 }
|
|
);
|
|
|
|
return {
|
|
week,
|
|
month,
|
|
};
|
|
}
|
|
|
|
return {
|
|
week: { productivehrs: 0, actualhrs: 0 },
|
|
month: { productivehrs: 0, actualhrs: 0 },
|
|
};
|
|
}, [data]);
|
|
|
|
if (loading) return <LoadingSpinner />;
|
|
if (error) return <AlertComponent message={error.message} type="error" />;
|
|
|
|
return (
|
|
<Card title={t("scoreboard.labels.productivestatistics")}>
|
|
<Space size={100}>
|
|
<Col>
|
|
<Title level={5}>{t("scoreboard.labels.thisweek")}</Title>
|
|
<Space size={20}>
|
|
<Statistic
|
|
title={t("timetickets.fields.productivehrs")}
|
|
value={totals.week.productivehrs.toFixed(2)}
|
|
/>
|
|
<Statistic
|
|
title={t("timetickets.fields.actualhrs")}
|
|
value={totals.week.actualhrs.toFixed(2)}
|
|
/>
|
|
<Statistic
|
|
title={t("timetickets.labels.efficiency")}
|
|
value={
|
|
totals.week.actualhrs
|
|
? `${(
|
|
(totals.week.productivehrs / totals.week.actualhrs) *
|
|
100
|
|
).toFixed(2)}%`
|
|
: "0%"
|
|
}
|
|
/>
|
|
</Space>
|
|
</Col>
|
|
<Col>
|
|
<Title level={5}>{t("scoreboard.labels.thismonth")}</Title>
|
|
<Space size={20}>
|
|
<Statistic
|
|
title={t("timetickets.fields.productivehrs")}
|
|
value={totals.month.productivehrs.toFixed(2)}
|
|
/>
|
|
<Statistic
|
|
title={t("timetickets.fields.actualhrs")}
|
|
value={totals.month.actualhrs.toFixed(2)}
|
|
/>
|
|
<Statistic
|
|
title={t("timetickets.labels.efficiency")}
|
|
value={
|
|
totals.month.actualhrs
|
|
? `${(
|
|
(totals.month.productivehrs / totals.month.actualhrs) *
|
|
100
|
|
).toFixed(2)}%`
|
|
: "0%"
|
|
}
|
|
/>
|
|
</Space>
|
|
</Col>
|
|
</Space>
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(TechJobStatistics);
|