diff --git a/client/src/components/job-search-select/job-search-select.component.jsx b/client/src/components/job-search-select/job-search-select.component.jsx
index 4dd32393d..85c160ad2 100644
--- a/client/src/components/job-search-select/job-search-select.component.jsx
+++ b/client/src/components/job-search-select/job-search-select.component.jsx
@@ -4,7 +4,14 @@ const { Option } = Select;
//To be used as a form element only.
-const JobSearchSelect = ({ value, onChange, options, onBlur, disabled }) => {
+const JobSearchSelect = ({
+ value,
+ onChange,
+ options,
+ onBlur,
+ disabled,
+ loading,
+}) => {
const [option, setOption] = useState(value);
useEffect(() => {
@@ -22,6 +29,7 @@ const JobSearchSelect = ({ value, onChange, options, onBlur, disabled }) => {
style={{
width: 300,
}}
+ loading={loading}
onChange={setOption}
optionFilterProp="children"
onBlur={onBlur}
diff --git a/client/src/components/tech-clock-in/tech-clock-in.component.jsx b/client/src/components/tech-clock-in/tech-clock-in.component.jsx
new file mode 100644
index 000000000..61c916683
--- /dev/null
+++ b/client/src/components/tech-clock-in/tech-clock-in.component.jsx
@@ -0,0 +1,41 @@
+import { useQuery } from "@apollo/react-hooks";
+import React from "react";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { ACTIVE_JOBS_FOR_AUTOCOMPLETE } from "../../graphql/jobs.queries";
+import { selectBodyshop } from "../../redux/user/user.selectors";
+import { selectTechnician } from "../../redux/tech/tech.selectors";
+import JobSearchSelect from "../job-search-select/job-search-select.component";
+import { useTranslation } from "react-i18next";
+import { Form } from "antd";
+const mapStateToProps = createStructuredSelector({
+ bodyshop: selectBodyshop,
+
+ });
+
+export function TechClockInComponent({ form, bodyshop }) {
+ const { t } = useTranslation();
+ const { loading, data } = useQuery(ACTIVE_JOBS_FOR_AUTOCOMPLETE, {
+ variables: {
+ statuses: bodyshop.md_ro_statuses.open_statuses || ["Open"],
+ },
+ });
+
+ return (
+
+
+
+
+
+ );
+}
+export default connect(mapStateToProps, null)(TechClockInComponent);
diff --git a/client/src/components/tech-clock-in/tech-clock-in.container.jsx b/client/src/components/tech-clock-in/tech-clock-in.container.jsx
new file mode 100644
index 000000000..277986354
--- /dev/null
+++ b/client/src/components/tech-clock-in/tech-clock-in.container.jsx
@@ -0,0 +1,44 @@
+import { Form, Button } from "antd";
+import React from "react";
+import { useQuery } from "react-apollo";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { QUERY_ACTIVE_TIME_TICKETS } 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";
+import TechClockInComponent from "./tech-clock-in.component";
+import { useTranslation } from "react-i18next";
+const mapStateToProps = createStructuredSelector({
+ technician: selectTechnician,
+});
+
+export function TechClockInContainer({ technician }) {
+ const { loading, error, data } = useQuery(QUERY_ACTIVE_TIME_TICKETS);
+ const [form] = Form.useForm();
+ const { t } = useTranslation();
+ if (loading) return ;
+ if (error) return ;
+
+ console.log("data", data);
+
+ if (data.timetickets.length > 0) {
+ return already clock into a job.
;
+ }
+
+ const handleFinish = (values) => {
+ console.log("values", values);
+ };
+
+ return (
+
+
+
+ );
+}
+export default connect(mapStateToProps, null)(TechClockInContainer);
diff --git a/client/src/components/tech-lookup-jobs-drawer/tech-lookup-jobs-drawer.component.jsx b/client/src/components/tech-lookup-jobs-drawer/tech-lookup-jobs-drawer.component.jsx
index 989320d19..d4c761808 100644
--- a/client/src/components/tech-lookup-jobs-drawer/tech-lookup-jobs-drawer.component.jsx
+++ b/client/src/components/tech-lookup-jobs-drawer/tech-lookup-jobs-drawer.component.jsx
@@ -1,6 +1,6 @@
import { PrinterFilled } from "@ant-design/icons";
import { useQuery } from "@apollo/react-hooks";
-import { Button, Col, Drawer, Grid, PageHeader, Row, Tag } from "antd";
+import { Button, Col, Drawer, Grid, PageHeader, Row, Tag, Tabs } from "antd";
import queryString from "query-string";
import React from "react";
import { useTranslation } from "react-i18next";
@@ -12,6 +12,9 @@ import AlertComponent from "../alert/alert.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import OwnerTagPopoverComponent from "../owner-tag-popover/owner-tag-popover.component";
import VehicleTagPopoverComponent from "../vehicle-tag-popover/vehicle-tag-popover.component";
+import JobLinesContainer from "../job-detail-lines/job-lines.container";
+import JobsDocumentsGalleryContainer from "../jobs-documents-gallery/jobs-documents-gallery.container";
+import JobNotesContainer from "../jobs-notes/jobs-notes.container";
const mapDispatchToProps = (dispatch) => ({
setPrintCenterContext: (context) =>
@@ -23,7 +26,7 @@ const colBreakPoints = {
span: 24,
},
sm: {
- span: 12,
+ span: 8,
},
};
@@ -115,10 +118,21 @@ export function JobDetailCards({ setPrintCenterContext }) {
}
>
-
-
-
+ What would be good to have here?
+ What would be good to have here?
+ What would be good to have here?
+
+
+
+
+
+
+
+
+
+
+
) : null}
diff --git a/client/src/graphql/accounting.queries.js b/client/src/graphql/accounting.queries.js
index 4202efc27..8e2c6c8ed 100644
--- a/client/src/graphql/accounting.queries.js
+++ b/client/src/graphql/accounting.queries.js
@@ -52,7 +52,7 @@ export const QUERY_INVOICES_FOR_EXPORT = gql`
export const QUERY_PAYMENTS_FOR_EXPORT = gql`
query QUERY_PAYMENTS_FOR_EXPORT {
payments(
- where: { exportedat: { _eq: null } }
+ where: { exportedat: { _is_null: true } }
order_by: { created_at: desc }
) {
id
diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js
index f8ffee563..694109c89 100644
--- a/client/src/graphql/jobs.queries.js
+++ b/client/src/graphql/jobs.queries.js
@@ -371,6 +371,72 @@ export const QUERY_JOB_CARD_DETAILS = gql`
}
`;
+export const QUERY_TECH_JOB_DETAILS = gql`
+ query QUERY_TECH_JOB_DETAILS($id: uuid!) {
+ jobs_by_pk(id: $id) {
+ ownr_fn
+ ownr_ln
+ v_model_yr
+ v_make_desc
+ v_model_desc
+ v_color
+ plate_no
+ actual_completion
+ actual_delivery
+ actual_in
+ est_number
+ id
+ ins_co_nm
+ clm_no
+ status
+ job_totals
+ area_of_damage
+ ro_number
+ scheduled_completion
+ scheduled_in
+ scheduled_delivery
+ date_invoiced
+ date_open
+ date_exported
+ date_closed
+ date_scheduled
+ date_estimated
+ joblines {
+ id
+ unq_seq
+ line_ind
+ tax_part
+ line_desc
+ prt_dsmk_p
+ prt_dsmk_m
+ part_type
+ oem_partno
+ db_price
+ act_price
+ part_qty
+ mod_lbr_ty
+ db_hrs
+ mod_lb_hrs
+ lbr_op
+ lbr_amt
+ op_code_desc
+ }
+ notes {
+ id
+ text
+ critical
+ private
+ created_at
+ }
+ updated_at
+ documents(order_by: { created_at: desc }) {
+ id
+ key
+ }
+ }
+ }
+`;
+
export const UPDATE_JOB = gql`
mutation UPDATE_JOB($jobId: uuid!, $job: jobs_set_input!) {
update_jobs(where: { id: { _eq: $jobId } }, _set: $job) {
diff --git a/client/src/graphql/timetickets.queries.js b/client/src/graphql/timetickets.queries.js
index f4aee3273..58d27bad4 100644
--- a/client/src/graphql/timetickets.queries.js
+++ b/client/src/graphql/timetickets.queries.js
@@ -46,3 +46,18 @@ export const UPDATE_TIME_TICKET = gql`
}
}
`;
+
+export const QUERY_ACTIVE_TIME_TICKETS = gql`
+ query QUERY_ACTIVE_TIME_TICKETS($employeeId: uuid) {
+ timetickets(
+ where: {
+ _and: { clockoff: { _is_null: true }, employeeid: { _eq: $employeeId } }
+ }
+ ) {
+ id
+ job {
+ ro_number
+ }
+ }
+ }
+`;
diff --git a/client/src/pages/tech/tech.page.component.jsx b/client/src/pages/tech/tech.page.component.jsx
index 528f435e9..efaed2e77 100644
--- a/client/src/pages/tech/tech.page.component.jsx
+++ b/client/src/pages/tech/tech.page.component.jsx
@@ -27,6 +27,10 @@ const ProductionListPage = lazy(() =>
const ProductionBoardPage = lazy(() =>
import("../production-board/production-board.container")
);
+const TechClockIn = lazy(() =>
+ import("../../components/tech-clock-in/tech-clock-in.container")
+);
+
const { Content } = Layout;
const mapStateToProps = createStructuredSelector({
@@ -74,6 +78,11 @@ export function TechPage({ technician, match }) {
exact
path={`${match.path}/list`}
component={ProductionListPage}
+ />{" "}
+