Added react icons. Additional work on Job tombstone page.

This commit is contained in:
Patrick Fic
2020-01-02 11:33:08 -08:00
parent 8969108cc4
commit b72665fc81
12 changed files with 105 additions and 45 deletions

View File

@@ -18,6 +18,7 @@
"react-apollo": "^3.1.3",
"react-dom": "^16.12.0",
"react-i18next": "^11.2.7",
"react-icons": "^3.8.0",
"react-moment": "^0.9.7",
"react-number-format": "^4.3.1",
"react-router-dom": "^5.1.2",

View File

@@ -72,7 +72,6 @@ class AppContainer extends Component {
const token = localStorage.getItem("token");
// return the headers to the context so httpLink can read them
if (token) {
console.log("checking if token should refresh.");
if (shouldRefreshToken) {
refreshToken();
}

View File

@@ -94,15 +94,15 @@ export default () => {
<div>
<Switch>
<ErrorBoundary>
<Suspense fallback={<div>Suspended Loading...</div>}>
<Route exact path="/" component={LandingPage} />
<Route exact path="/unauthorized" component={Unauthorized} />
<Suspense fallback={<div>TODO: Suspense Loading</div>}>
<Route exact path='/' component={LandingPage} />
<Route exact path='/unauthorized' component={Unauthorized} />
<Route
exact
path="/signin"
path='/signin'
render={() =>
HookCurrentUser.data.currentUser ? (
<Redirect to="/manage" />
<Redirect to='/manage' />
) : (
<SignInPage />
)
@@ -110,7 +110,7 @@ export default () => {
/>
<PrivateRoute
isAuthorized={HookCurrentUser.data.currentUser ? true : false}
path="/manage"
path='/manage'
component={ManagePage}
/>
</Suspense>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M23.5 7c.276 0 .5.224.5.5v.511c0 .793-.926.989-1.616.989l-1.086-2h2.202zm-1.441 3.506c.639 1.186.946 2.252.946 3.666 0 1.37-.397 2.533-1.005 3.981v1.847c0 .552-.448 1-1 1h-1.5c-.552 0-1-.448-1-1v-1h-13v1c0 .552-.448 1-1 1h-1.5c-.552 0-1-.448-1-1v-1.847c-.608-1.448-1.005-2.611-1.005-3.981 0-1.414.307-2.48.946-3.666.829-1.537 1.851-3.453 2.93-5.252.828-1.382 1.262-1.707 2.278-1.889 1.532-.275 2.918-.365 4.851-.365s3.319.09 4.851.365c1.016.182 1.45.507 2.278 1.889 1.079 1.799 2.101 3.715 2.93 5.252zm-16.059 2.994c0-.828-.672-1.5-1.5-1.5s-1.5.672-1.5 1.5.672 1.5 1.5 1.5 1.5-.672 1.5-1.5zm10 1c0-.276-.224-.5-.5-.5h-7c-.276 0-.5.224-.5.5s.224.5.5.5h7c.276 0 .5-.224.5-.5zm2.941-5.527s-.74-1.826-1.631-3.142c-.202-.298-.515-.502-.869-.566-1.511-.272-2.835-.359-4.441-.359s-2.93.087-4.441.359c-.354.063-.667.267-.869.566-.891 1.315-1.631 3.142-1.631 3.142 1.64.313 4.309.497 6.941.497s5.301-.184 6.941-.497zm2.059 4.527c0-.828-.672-1.5-1.5-1.5s-1.5.672-1.5 1.5.672 1.5 1.5 1.5 1.5-.672 1.5-1.5zm-18.298-6.5h-2.202c-.276 0-.5.224-.5.5v.511c0 .793.926.989 1.616.989l1.086-2z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,4 +1,5 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
import AlertComponent from "../alert/alert.component";
import {
Form,
@@ -9,12 +10,15 @@ import {
Typography,
PageHeader,
Descriptions,
Tag
Tag,
notification,
Avatar
} from "antd";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { useMutation } from "@apollo/react-hooks";
import FormItemPhone from "../form-items-formatted/phone-form-item.component";
import { useTranslation } from "react-i18next";
import CarImage from "../../assets/car.svg";
const formItemLayout = {
labelCol: {
@@ -33,22 +37,27 @@ function JobTombstone({ job, ...otherProps }) {
const { t } = useTranslation();
if (!job) {
return (
<AlertComponent
message='This job does not exist or you do not have access to it.'
type='error'
/>
);
return <AlertComponent message={t("jobs.errors.noaccess")} type='error' />;
}
const handleSubmit = e => {
e.preventDefault();
otherProps.form.validateFieldsAndScroll((err, values) => {
if (err) {
notification["error"]({
message: t("jobs.errors.validationtitle"),
description: t("jobs.errors.validation")
});
}
if (!err) {
mutationUpdateJob({
variables: { jobId: jobContext.id, job: values }
}).then(r => console.log("result", r));
}).then(r =>
notification["success"]({
message: t("jobs.successes.savetitle")
})
);
}
});
};
@@ -59,13 +68,21 @@ function JobTombstone({ job, ...otherProps }) {
};
const { getFieldDecorator } = otherProps.form;
const tombstoneTitle = (
<div>
<Avatar size='large' alt='Vehicle Image' src={CarImage} />
{t("jobs.fields.ro_number") + " " + jobContext.ro_number ?? "0"}
</div>
);
return (
<Form onSubmit={handleSubmit} {...formItemLayout}>
<PageHeader
style={{
border: "1px solid rgb(235, 237, 240)"
}}
title={"RO " + jobContext.ro_number ?? "0"}
title={tombstoneTitle}
subTitle={
jobContext.owner
? (jobContext.owner?.first_name ?? "") +
@@ -77,15 +94,29 @@ function JobTombstone({ job, ...otherProps }) {
extra={[
<Form.Item key='1'>
<Button type='primary' htmlType='submit'>
Save
{t("general.labels.save")}
</Button>
</Form.Item>
]}>
<Descriptions size='small' column={3}>
<Descriptions.Item label='Claim Total'>
<Descriptions size='small' column={5}>
<Descriptions.Item label={t("jobs.labels.vehicle_info")}>
<Link to={`/manage/vehicles/${jobContext.vehicle?.id}`}>
{jobContext.vehicle?.v_model_yr ?? t("general.labels.na")}{" "}
{jobContext.vehicle?.v_make_desc ?? t("general.labels.na")}{" "}
{jobContext.vehicle?.v_model_desc ?? t("general.labels.na")} |{" "}
{jobContext.vehicle?.plate_no ?? t("general.labels.na")}
</Link>
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.est_number")}>
{jobContext.est_number}
</Descriptions.Item>
<Descriptions.Item label={t("jobs.fields.claim_total")}>
$ {jobContext.claim_total?.toFixed(2)}
</Descriptions.Item>
<Descriptions.Item label='Deductible'>
<Descriptions.Item label={t("jobs.fields.deductible")}>
$ {jobContext.deductible?.toFixed(2)}
</Descriptions.Item>
</Descriptions>
@@ -93,17 +124,13 @@ function JobTombstone({ job, ...otherProps }) {
<Row>
<Typography.Title level={4}>Information</Typography.Title>
<Form.Item label='RO #'>
{getFieldDecorator("ro_number", {
initialValue: jobContext.ro_number
})(<Input name='ro_number' readOnly onChange={handleChange} />)}
</Form.Item>
<Form.Item label='Estimate #'>
{getFieldDecorator("est_number", {
initialValue: jobContext.est_number
})(<Input name='est_number' readOnly onChange={handleChange} />)}
</Form.Item>
{
// <Form.Item label='Estimate #'>
// {getFieldDecorator("est_number", {
// initialValue: jobContext.est_number
// })(<Input name='est_number' readOnly onChange={handleChange} />)}
// </Form.Item>
}
</Row>
<Row>

View File

@@ -4,6 +4,7 @@ import { Menu, Dropdown, Card, Icon, Avatar, Row, Col } from "antd";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
import Moment from "react-moment";
import CarImage from "../../assets/car.svg";
//The following styled div is required because of a smooth-dnd style used by react-trello to prevent wrapping of columns.
const WrappedSpan = styled.span`
@@ -80,11 +81,7 @@ export default function WhiteBoardCard({ metadata }) {
]}>
<Row>
<Col span={6}>
<Avatar
size='large'
alt='Vehicle Image'
src='https://picolio.auto123.com/auto123-media/articles/2017/9/64008/101530569fr.jpg?scaledown=450'
/>
<Avatar size='large' alt='Vehicle Image' src={CarImage} />
</Col>
<Col span={18}>
<Row>
@@ -103,12 +100,14 @@ export default function WhiteBoardCard({ metadata }) {
</Row>
<Row>
<Col span={12}>
{t("general.labels.in")}
<Moment format='MM/DD/YYYY'>{metadata.actual_in}</Moment>
{t("general.labels.in")}:
<Moment format='MM/DD/YYYY'> {metadata.actual_in}</Moment>
</Col>
<Col span={12}>
{t("general.labels.out")}
<Moment format='MM/DD/YYYY'>{metadata.scheduled_completion}</Moment>
{t("general.labels.out")}:
<Moment format='MM/DD/YYYY'>
{metadata.scheduled_completion}
</Moment>
</Col>
</Row>
</Card>

View File

@@ -11,6 +11,7 @@ export default function WhiteBoardKanBan({ data, eventBus }) {
<Board
tagStyle={{ fontSize: "80%" }}
data={data}
style={{ backgroundColor: "none" }}
laneDraggable={false}
eventBusHandle={setEventBus}
components={{ Card: WhiteBoardCard }}

View File

@@ -12,6 +12,7 @@ export const GET_ALL_OPEN_JOBS = gql`
scheduled_completion
scheduled_delivery
vehicle {
id
v_model_yr
v_make_desc
v_model_desc
@@ -38,6 +39,7 @@ export const SUBSCRIPTION_ALL_OPEN_JOBS = gql`
scheduled_completion
scheduled_delivery
vehicle {
id
v_model_yr
v_make_desc
v_model_desc
@@ -62,6 +64,7 @@ export const QUERY_JOBS_IN_PRODUCTION = gql`
scheduled_completion
scheduled_delivery
vehicle {
id
v_model_yr
v_make_desc
v_model_desc
@@ -92,6 +95,7 @@ export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
est_number
ro_number
vehicle {
id
v_model_yr
v_model_desc
v_make_desc
@@ -138,6 +142,7 @@ export const GET_JOB_BY_PK = gql`
claim_total
deductible
vehicle {
id
plate_no
v_vin
v_model_yr

View File

@@ -21,7 +21,6 @@ export function shouldRefreshToken(minutesBeforeShouldRefresh = 45) {
}
export async function refreshToken() {
console.log("Refreshing token.")
try {
if (auth.user) {
const idToken = await auth().currentUser.getIdToken(
@@ -30,7 +29,7 @@ export async function refreshToken() {
const now = new Date();
window.localStorage.setItem(`lastTokenRefreshTime`, now);
localStorage.setItem("token", idToken);
console.log("Token refreshed.")
console.log("Token refreshed.");
}
} catch (err) {
console.error(err);

View File

@@ -0,0 +1,5 @@
import React from "react";
export default function ErrorNotFound() {
return <div>Uh oh, we couldn't find the page you're looking for.</div>;
}

View File

@@ -8,16 +8,32 @@
},
"labels": {
"in": "In",
"out": "Out"
"out": "Out",
"na": "N/A",
"save": "Save"
}
},
"jobs": {
"labels": {
"no_owner": "No Owner"
"no_owner": "No Owner",
"vehicle_info": "Vehicle"
},
"fields": {
"ro_number": "RO #"
"ro_number": "RO #",
"est_number": "Estimate Number",
"claim_total": "Claim Total",
"deductible": "Deductible"
},
"successes": {
"save": "Record Saved",
"savetitle": "Record saved succesfully."
},
"errors": {
"noaccess": "This job does not exist or you do not have access to it.",
"validationtitle": "Validation Error",
"validation": "Please ensure all fields are entered correctly.",
"saving": "Error encountered while saving record."
}
},

View File

@@ -10296,6 +10296,13 @@ react-i18next@^11.2.7:
"@babel/runtime" "^7.3.1"
html-parse-stringify2 "2.0.1"
react-icons@^3.8.0:
version "3.8.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-3.8.0.tgz#229de5904809696c9f46932bd9b6126b2522866e"
integrity sha512-rA/8GRKjPulft8BSBSMsHkE1AGPqJ7LjNsyk0BE7XjG70Iz62zOled2SJk7LDo8x9z86a3xOstDlKlMZ4pAy7A==
dependencies:
camelcase "^5.0.0"
react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0:
version "16.12.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"