diff --git a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx
index 138e54228..0fc84af6d 100644
--- a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx
+++ b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx
@@ -241,9 +241,11 @@ export default function ScoreboardTimeTickets() {
);
ret.totalEffieciencyOverPeriod =
- (totalActualAndProductive.totalOverPeriod /
- totalActualAndProductive.actualTotalOverPeriod) *
- 100;
+ totalActualAndProductive.actualTotalOverPeriod
+ ? (totalActualAndProductive.totalOverPeriod /
+ totalActualAndProductive.actualTotalOverPeriod) *
+ 100
+ : 0;
roundObject(ret);
roundObject(totals);
diff --git a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx
index e31cec3af..40f3ed32c 100644
--- a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx
+++ b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx
@@ -116,7 +116,7 @@ export function ScoreboardTicketsStats({ data, bodyshop }) {
diff --git a/client/src/components/tech-job-statistics/tech-job-statistics.component.jsx b/client/src/components/tech-job-statistics/tech-job-statistics.component.jsx
new file mode 100644
index 000000000..ec26a8069
--- /dev/null
+++ b/client/src/components/tech-job-statistics/tech-job-statistics.component.jsx
@@ -0,0 +1,136 @@
+import { Card, Col, Space, Statistic, Typography } from "antd";
+import { useLocation } from "react-router-dom";
+import queryString from "query-string";
+import moment from "moment";
+import { useQuery } from "@apollo/client";
+import { QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE } from "../../graphql/timetickets.queries";
+import { createStructuredSelector } from "reselect";
+import { selectTechnician } from "../../redux/tech/tech.selectors";
+import { connect } from "react-redux";
+import AlertComponent from "../alert/alert.component";
+import LoadingSpinner from "../loading-spinner/loading-spinner.component";
+import { useMemo } from "react";
+
+const { Title } = Typography;
+
+const mapStateToProps = createStructuredSelector({
+ technician: selectTechnician,
+});
+const mapDispatchToProps = (dispatch) => ({});
+
+const TechJobStatistics = ({ technician }) => {
+ const searchParams = queryString.parse(useLocation().search);
+ const { start, end } = searchParams;
+
+ const startDate = start
+ ? moment(start)
+ : moment().startOf("week").subtract(7, "days");
+ const endDate = end ? moment(end) : 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 ;
+ if (error) return ;
+
+ return (
+
+
+
+ This Week
+
+
+
+
+
+
+
+ This Month
+
+
+
+
+
+
+
+
+ );
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(TechJobStatistics);
diff --git a/client/src/graphql/timetickets.queries.js b/client/src/graphql/timetickets.queries.js
index fd593a003..e6f04868f 100644
--- a/client/src/graphql/timetickets.queries.js
+++ b/client/src/graphql/timetickets.queries.js
@@ -59,6 +59,81 @@ export const QUERY_TIME_TICKETS_IN_RANGE = gql`
}
`;
+export const QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE = gql`
+ query QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE(
+ $employeeid: uuid!
+ $start: date!
+ $end: date!
+ $fixedStart: date!
+ $fixedEnd: date!
+ ) {
+ timetickets(
+ where: {
+ date: { _gte: $start, _lte: $end }
+ employeeid: { _eq: $employeeid }
+ }
+ order_by: { date: desc_nulls_first }
+ ) {
+ actualhrs
+ ciecacode
+ clockoff
+ clockon
+ cost_center
+ created_at
+ date
+ id
+ rate
+ productivehrs
+ memo
+ jobid
+ flat_rate
+ job {
+ id
+ ro_number
+ }
+ employeeid
+ employee {
+ id
+ employee_number
+ first_name
+ last_name
+ }
+ }
+ fixedperiod: timetickets(
+ where: {
+ date: { _gte: $fixedStart, _lte: $fixedEnd }
+ employeeid: { _eq: $employeeid }
+ }
+ order_by: { date: desc_nulls_first }
+ ) {
+ actualhrs
+ ciecacode
+ clockoff
+ clockon
+ cost_center
+ created_at
+ date
+ id
+ rate
+ productivehrs
+ memo
+ jobid
+ flat_rate
+ job {
+ id
+ ro_number
+ }
+ employeeid
+ employee {
+ id
+ employee_number
+ first_name
+ last_name
+ }
+ }
+ }
+`;
+
export const QUERY_TIME_TICKETS_IN_RANGE_SB = gql`
query QUERY_TIME_TICKETS_IN_RANGE_SB(
$start: date!
diff --git a/client/src/pages/tech-job-clock/tech-job-clock.component.jsx b/client/src/pages/tech-job-clock/tech-job-clock.component.jsx
index 092510b02..0d64068eb 100644
--- a/client/src/pages/tech-job-clock/tech-job-clock.component.jsx
+++ b/client/src/pages/tech-job-clock/tech-job-clock.component.jsx
@@ -2,10 +2,12 @@ import { Divider } from "antd";
import React from "react";
import TechClockInFormContainer from "../../components/tech-job-clock-in-form/tech-job-clock-in-form.container";
import TechClockedInList from "../../components/tech-job-clocked-in-list/tech-job-clocked-in-list.component";
+import TechJobStatistics from "../../components/tech-job-statistics/tech-job-statistics.component";
export default function TechClockComponent() {
return (