diff --git a/client/src/components/form-items-formatted/email-form-item.component.jsx b/client/src/components/form-items-formatted/email-form-item.component.jsx
index bb51094ca..c007b6bb3 100644
--- a/client/src/components/form-items-formatted/email-form-item.component.jsx
+++ b/client/src/components/form-items-formatted/email-form-item.component.jsx
@@ -5,9 +5,13 @@ function FormItemEmail(props, ref) {
+ props.email ? (
+
+
+
+ ) : (
-
+ )
}
/>
);
diff --git a/client/src/components/owner-detail-form/owner-detail-form.component.jsx b/client/src/components/owner-detail-form/owner-detail-form.component.jsx
new file mode 100644
index 000000000..37eb40385
--- /dev/null
+++ b/client/src/components/owner-detail-form/owner-detail-form.component.jsx
@@ -0,0 +1,106 @@
+import { Button, Col, Form, Input, Row, Switch } from "antd";
+import React from "react";
+import { useTranslation } from "react-i18next";
+import FormItemEmail from "../form-items-formatted/email-form-item.component";
+import FormItemPhone from "../form-items-formatted/phone-form-item.component";
+import ResetForm from "../form-items-formatted/reset-form-item.component";
+
+export default function OwnerDetailFormComponent({ form, owner }) {
+ const { t } = useTranslation();
+ const {
+ isFieldsTouched,
+ resetFields,
+ getFieldDecorator,
+ getFieldValue
+ } = form;
+
+ return (
+
+ {isFieldsTouched() ? : null}
+
+
+
+
+ {getFieldDecorator("ownr_ln", {
+ initialValue: owner.ownr_ln
+ })()}
+
+
+ {getFieldDecorator("ownr_fn", {
+ initialValue: owner.ownr_fn
+ })()}
+
+
+ {getFieldDecorator("allow_text_message", {
+ initialValue: owner.allow_text_message,
+ valuePropName: "checked"
+ })()}
+
+
+ {getFieldDecorator("ownr_addr1", {
+ initialValue: owner.ownr_addr1
+ })()}
+
+
+ {getFieldDecorator("ownr_addr2", {
+ initialValue: owner.ownr_addr2
+ })()}
+
+
+ {getFieldDecorator("ownr_city", {
+ initialValue: owner.ownr_city
+ })()}
+
+
+ {getFieldDecorator("ownr_ctry", {
+ initialValue: owner.ownr_ctry
+ })()}
+
+
+
+ {" "}
+
+ {getFieldDecorator("ownr_ea", {
+ initialValue: owner.ownr_ea,
+ rules: [
+ {
+ type: "email",
+ message: "This is not a valid email address."
+ }
+ ]
+ })(
+
+ )}
+
+
+ {getFieldDecorator("ownr_ph1", {
+ initialValue: owner.ownr_ph1
+ })()}
+
+
+ {getFieldDecorator("ownr_st", {
+ initialValue: owner.ownr_st
+ })()}
+
+
+ {getFieldDecorator("ownr_zip", {
+ initialValue: owner.ownr_zip
+ })()}
+
+
+ {getFieldDecorator("preferred_contact", {
+ initialValue: owner.preferred_contact
+ })()}
+
+
+ {getFieldDecorator("ownr_title", {
+ initialValue: owner.ownr_title
+ })()}
+
+
+
+
+ );
+}
diff --git a/client/src/components/owner-detail-form/owner-detail-form.container.jsx b/client/src/components/owner-detail-form/owner-detail-form.container.jsx
new file mode 100644
index 000000000..a58168463
--- /dev/null
+++ b/client/src/components/owner-detail-form/owner-detail-form.container.jsx
@@ -0,0 +1,46 @@
+import { Form, notification } from "antd";
+import React from "react";
+import { useMutation } from "react-apollo";
+import { useTranslation } from "react-i18next";
+import { UPDATE_OWNER } from "../../graphql/owners.queries";
+import OwnerDetailFormComponent from "./owner-detail-form.component";
+
+function OwnerDetailFormContainer({ form, owner, refetch }) {
+ const { t } = useTranslation();
+
+ const [updateOwner] = useMutation(UPDATE_OWNER);
+
+ const handleSubmit = e => {
+ e.preventDefault();
+
+ form.validateFieldsAndScroll((err, values) => {
+ if (err) {
+ notification["error"]({
+ message: t("owners.errors.validationtitle"),
+ description: t("owners.errors.validation")
+ });
+ }
+ if (!err) {
+ updateOwner({
+ variables: { ownerId: owner.id, owner: values }
+ }).then(r => {
+ notification["success"]({
+ message: t("owners.successes.save")
+ });
+ //TODO: Better way to reset the field decorators?
+ if (refetch) refetch().then();
+ form.resetFields();
+ });
+ }
+ });
+ };
+
+ return (
+
+ );
+}
+export default Form.create({ name: "OwnerDetailFormContainer" })(
+ OwnerDetailFormContainer
+);
diff --git a/client/src/components/owner-detail-jobs/owner-detail-jobs.component.jsx b/client/src/components/owner-detail-jobs/owner-detail-jobs.component.jsx
new file mode 100644
index 000000000..2f26506dd
--- /dev/null
+++ b/client/src/components/owner-detail-jobs/owner-detail-jobs.component.jsx
@@ -0,0 +1,59 @@
+import React from "react";
+import { Table } from "antd";
+import { useTranslation } from "react-i18next";
+import { Link } from "react-router-dom";
+import CurrencyFormatter from "../../utils/CurrencyFormatter";
+export default function OwnerDetailJobsComponent({ owner }) {
+ const { t } = useTranslation();
+ const columns = [
+ {
+ title: t("jobs.fields.ro_number"),
+ dataIndex: "ro_number",
+ key: "ro_number",
+ ellipsis: true,
+ render: (text, record) => (
+
+ {record.ro_number ? record.ro_number : `EST ${record.est_number}`}
+
+ )
+ },
+ {
+ title: t("jobs.fields.vehicle"),
+ dataIndex: "owner",
+ key: "owner",
+ render: (text, record) => (
+
+ {`${record.vehicle.v_model_yr} ${record.vehicle.v_make_desc} ${record.vehicle.v_model_desc}`}
+
+ )
+ },
+ {
+ title: t("jobs.fields.clm_no"),
+ dataIndex: "clm_no",
+ key: "clm_no"
+ },
+ {
+ title: t("jobs.fields.status"),
+ dataIndex: "status",
+ key: "status"
+ },
+
+ {
+ title: t("jobs.fields.clm_total"),
+ dataIndex: "clm_total",
+ key: "clm_total",
+ render: (text, record) => (
+ {record.clm_total}
+ )
+ }
+ ];
+
+ return (
+ ({ ...item }))}
+ rowKey="id"
+ dataSource={owner.jobs}
+ />
+ );
+}
diff --git a/client/src/graphql/owners.queries.js b/client/src/graphql/owners.queries.js
index 0945e48b0..0a86d4f90 100644
--- a/client/src/graphql/owners.queries.js
+++ b/client/src/graphql/owners.queries.js
@@ -18,3 +18,50 @@ export const QUERY_SEARCH_OWNER_BY_IDX = gql`
}
}
`;
+
+export const QUERY_OWNER_BY_ID = gql`
+ query QUERY_OWNER_BY_ID($id: uuid!) {
+ owners_by_pk(id: $id) {
+ id
+ allow_text_message
+ ownr_addr1
+ ownr_addr2
+ ownr_co_nm
+ ownr_city
+ ownr_ctry
+ ownr_ea
+ ownr_fn
+ ownr_ph1
+ ownr_ln
+ ownr_ph2
+ ownr_st
+ ownr_title
+ ownr_zip
+ preferred_contact
+ jobs {
+ id
+ ro_number
+ est_number
+ clm_no
+ status
+ clm_total
+ vehicle {
+ id
+ v_model_yr
+ v_model_desc
+ v_make_desc
+ }
+ }
+ }
+ }
+`;
+
+export const UPDATE_OWNER = gql`
+ mutation UPDATE_OWNER($ownerId: uuid!, $owner: owners_set_input!) {
+ update_owners(where: { id: { _eq: $ownerId } }, _set: $owner) {
+ returning {
+ id
+ }
+ }
+ }
+`;
diff --git a/client/src/graphql/vehicles.queries.js b/client/src/graphql/vehicles.queries.js
index 2dcc10303..0ca51d30a 100644
--- a/client/src/graphql/vehicles.queries.js
+++ b/client/src/graphql/vehicles.queries.js
@@ -2,7 +2,7 @@ import { gql } from "apollo-boost";
export const QUERY_VEHICLE_BY_ID = gql`
query QUERY_VEHICLE_BY_ID($id: uuid!) {
- vehicles(where: { id: { _eq: $id } }) {
+ vehicles_by_pk(id: $id) {
created_at
db_v_code
id
diff --git a/client/src/pages/owners-detail/owners-detail.page.component.jsx b/client/src/pages/owners-detail/owners-detail.page.component.jsx
index 122d88f1a..89c274134 100644
--- a/client/src/pages/owners-detail/owners-detail.page.component.jsx
+++ b/client/src/pages/owners-detail/owners-detail.page.component.jsx
@@ -1,5 +1,11 @@
import React from "react";
-
-export default function OwnersDetailComponent() {
- return Owner Detail
;
+import OwnerDetailForm from "../../components/owner-detail-form/owner-detail-form.container";
+import OwnerDetailJobsComponent from "../../components/owner-detail-jobs/owner-detail-jobs.component";
+export default function OwnersDetailComponent({ owner, refetch }) {
+ return (
+
+
+
+
+ );
}
diff --git a/client/src/pages/owners-detail/owners-detail.page.container.jsx b/client/src/pages/owners-detail/owners-detail.page.container.jsx
index bc7b94f4b..f2adcb24a 100644
--- a/client/src/pages/owners-detail/owners-detail.page.container.jsx
+++ b/client/src/pages/owners-detail/owners-detail.page.container.jsx
@@ -1,8 +1,28 @@
import React from "react";
import OwnersDetailComponent from "./owners-detail.page.component";
-
+import { useTranslation } from "react-i18next";
+import { useQuery } from "react-apollo";
+import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
+import AlertComponent from "../../components/alert/alert.component";
+import { QUERY_OWNER_BY_ID } from "../../graphql/owners.queries";
export default function OwnersDetailContainer({ match }) {
const { ownerId } = match.params;
- console.log("ownerId", ownerId);
- return ;
+ const { t } = useTranslation();
+
+ const { loading, data, error, refetch } = useQuery(QUERY_OWNER_BY_ID, {
+ variables: { id: ownerId },
+ fetchPolicy: "network-only"
+ });
+
+ if (loading) return ;
+ if (error) return ;
+
+ if (data.owners_by_pk)
+ return (
+
+ );
+ else
+ return (
+
+ );
}
diff --git a/client/src/pages/vehicles-detail/vehicles-detail.page.component.jsx b/client/src/pages/vehicles-detail/vehicles-detail.page.component.jsx
index 8af261cf5..3cc260675 100644
--- a/client/src/pages/vehicles-detail/vehicles-detail.page.component.jsx
+++ b/client/src/pages/vehicles-detail/vehicles-detail.page.component.jsx
@@ -5,8 +5,6 @@ import VehicleDetailJobsComponent from "../../components/vehicle-detail-jobs/veh
export default function VehicleDetailComponent({ vehicle, refetch }) {
return (
- Veh detail
{vehicle.v_vin}
-
Vehicle Fields
diff --git a/client/src/pages/vehicles-detail/vehicles-detail.page.container.jsx b/client/src/pages/vehicles-detail/vehicles-detail.page.container.jsx
index 5df581377..a2a7b2ca3 100644
--- a/client/src/pages/vehicles-detail/vehicles-detail.page.container.jsx
+++ b/client/src/pages/vehicles-detail/vehicles-detail.page.container.jsx
@@ -17,8 +17,8 @@ export default function VehicleDetailContainer({ match }) {
useEffect(() => {
document.title = t("titles.vehicledetail", {
vehicle:
- data && data.vehicles[0]
- ? `${data.vehicles[0].v_model_yr} ${data.vehicles[0].v_make_desc} ${data.vehicles[0].v_model_desc}`
+ data && data.vehicles_by_pk
+ ? `${data.vehicles_by_pk.v_model_yr} ${data.vehicles_by_pk.v_make_desc} ${data.vehicles_by_pk.v_model_desc}`
: ""
});
}, [t, data]);
@@ -26,9 +26,9 @@ export default function VehicleDetailContainer({ match }) {
if (loading) return ;
if (error) return ;
- if (data.vehicles[0])
+ if (data.vehicles_by_pk)
return (
-
+
);
else
return (
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 0dc6852df..1e32c1895 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -291,16 +291,29 @@
}
},
"owners": {
+ "errors": {
+ "noaccess": "The record does not exist or you do not have access to it. "
+ },
"fields": {
+ "allow_text_message": "Permission to Text?",
"ownr_addr1": "Address",
+ "ownr_addr2": "Address 2",
"ownr_city": "City",
+ "ownr_ctry": "Country",
"ownr_ea": "Email",
"ownr_fn": "First Name",
"ownr_ln": "Last Name",
- "ownr_ph1": "Phone 1"
+ "ownr_ph1": "Phone 1",
+ "ownr_st": "State/Province",
+ "ownr_title": "Title",
+ "ownr_zip": "Zip/Postal Code",
+ "preferred_contact": "Preferred Contact Method"
},
"labels": {
"existing_owners": "Existing Owners"
+ },
+ "successes": {
+ "save": "Owner saved successfully."
}
},
"profile": {
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 3db448c3a..3b3bbe1d5 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -291,16 +291,29 @@
}
},
"owners": {
+ "errors": {
+ "noaccess": "El registro no existe o no tiene acceso a él."
+ },
"fields": {
+ "allow_text_message": "Permiso de texto?",
"ownr_addr1": "Dirección",
+ "ownr_addr2": "Dirección 2",
"ownr_city": "ciudad",
+ "ownr_ctry": "País",
"ownr_ea": "Email",
"ownr_fn": "Nombre de pila",
"ownr_ln": "Apellido",
- "ownr_ph1": ""
+ "ownr_ph1": "Teléfono 1",
+ "ownr_st": "Provincia del estado",
+ "ownr_title": "Título",
+ "ownr_zip": "código postal",
+ "preferred_contact": "Método de Contacto Preferido"
},
"labels": {
"existing_owners": "Propietarios existentes"
+ },
+ "successes": {
+ "save": "Propietario guardado con éxito."
}
},
"profile": {
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index 1feadd201..ae349c18b 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -291,16 +291,29 @@
}
},
"owners": {
+ "errors": {
+ "noaccess": "L'enregistrement n'existe pas ou vous n'y avez pas accès."
+ },
"fields": {
+ "allow_text_message": "Autorisation de texte?",
"ownr_addr1": "Adresse",
+ "ownr_addr2": "Adresse 2 ",
"ownr_city": "Ville",
+ "ownr_ctry": "Pays",
"ownr_ea": "Email",
"ownr_fn": "Prénom",
"ownr_ln": "Nom de famille",
- "ownr_ph1": ""
+ "ownr_ph1": "Téléphone 1",
+ "ownr_st": "Etat / Province",
+ "ownr_title": "Titre",
+ "ownr_zip": "Zip / code postal",
+ "preferred_contact": "Méthode de contact préférée"
},
"labels": {
"existing_owners": "Propriétaires existants"
+ },
+ "successes": {
+ "save": "Le propriétaire a bien enregistré."
}
},
"profile": {