@@ -1,15 +1,15 @@
|
||||
import { PrinterFilled } from "@ant-design/icons";
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { Button, Card, Col, Divider, Drawer, Grid, Row, Space } from "antd";
|
||||
import {PrinterFilled} from "@ant-design/icons";
|
||||
import {useQuery} from "@apollo/client";
|
||||
import {Button, Card, Col, Divider, Drawer, Grid, Row, Space} from "antd";
|
||||
import queryString from "query-string";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { Link, useNavigate, useLocation } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { QUERY_JOB_CARD_DETAILS } from "../../graphql/jobs.queries";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {connect} from "react-redux";
|
||||
import {Link, useLocation, useNavigate} from "react-router-dom";
|
||||
import {createStructuredSelector} from "reselect";
|
||||
import {QUERY_JOB_CARD_DETAILS} from "../../graphql/jobs.queries";
|
||||
import {setModalContext} from "../../redux/modals/modals.actions";
|
||||
import {selectBodyshop} from "../../redux/user/user.selectors";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import JobSyncButton from "../job-sync-button/job-sync-button.component";
|
||||
import JobsDetailHeader from "../jobs-detail-header/jobs-detail-header.component";
|
||||
@@ -23,150 +23,151 @@ import JobDetailCardsPartsComponent from "./job-detail-cards.parts.component";
|
||||
import JobDetailCardsTotalsComponent from "./job-detail-cards.totals.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setPrintCenterContext: (context) =>
|
||||
dispatch(setModalContext({ context: context, modal: "printCenter" })),
|
||||
setPrintCenterContext: (context) =>
|
||||
dispatch(setModalContext({context: context, modal: "printCenter"})),
|
||||
});
|
||||
|
||||
const span = {
|
||||
sm: { span: 24 },
|
||||
md: { span: 12 },
|
||||
lg: { span: 8 },
|
||||
sm: {span: 24},
|
||||
md: {span: 12},
|
||||
lg: {span: 8},
|
||||
};
|
||||
|
||||
export function JobDetailCards({ bodyshop, setPrintCenterContext }) {
|
||||
const selectedBreakpoint = Object.entries(Grid.useBreakpoint())
|
||||
.filter((screen) => !!screen[1])
|
||||
.slice(-1)[0];
|
||||
export function JobDetailCards({bodyshop, setPrintCenterContext}) {
|
||||
const selectedBreakpoint = Object.entries(Grid.useBreakpoint())
|
||||
.filter((screen) => !!screen[1])
|
||||
.slice(-1)[0];
|
||||
|
||||
const bpoints = {
|
||||
xs: "100%",
|
||||
sm: "100%",
|
||||
md: "100%",
|
||||
lg: "75%",
|
||||
xl: "75%",
|
||||
xxl: "60%",
|
||||
};
|
||||
const drawerPercentage = selectedBreakpoint
|
||||
? bpoints[selectedBreakpoint[0]]
|
||||
: "100%";
|
||||
const bpoints = {
|
||||
xs: "100%",
|
||||
sm: "100%",
|
||||
md: "100%",
|
||||
lg: "75%",
|
||||
xl: "75%",
|
||||
xxl: "60%",
|
||||
};
|
||||
const drawerPercentage = selectedBreakpoint
|
||||
? bpoints[selectedBreakpoint[0]]
|
||||
: "100%";
|
||||
|
||||
const searchParams = queryString.parse(useLocation().search);
|
||||
const { selected } = searchParams;
|
||||
const history = useNavigate();
|
||||
const { loading, error, data, refetch } = useQuery(QUERY_JOB_CARD_DETAILS, {
|
||||
variables: { id: selected },
|
||||
skip: !selected,
|
||||
fetchPolicy: "network-only",
|
||||
nextFetchPolicy: "network-only",
|
||||
});
|
||||
|
||||
const { t } = useTranslation();
|
||||
const handleDrawerClose = () => {
|
||||
delete searchParams.selected;
|
||||
history({
|
||||
search: queryString.stringify({
|
||||
...searchParams,
|
||||
}),
|
||||
const searchParams = queryString.parse(useLocation().search);
|
||||
const {selected} = searchParams;
|
||||
const history = useNavigate();
|
||||
const {loading, error, data, refetch} = useQuery(QUERY_JOB_CARD_DETAILS, {
|
||||
variables: {id: selected},
|
||||
skip: !selected,
|
||||
fetchPolicy: "network-only",
|
||||
nextFetchPolicy: "network-only",
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
open={!!selected}
|
||||
destroyOnClose
|
||||
width={drawerPercentage}
|
||||
placement="right"
|
||||
onClose={handleDrawerClose}
|
||||
>
|
||||
{loading ? <LoadingSpinner /> : null}
|
||||
{error ? <AlertComponent message={error.message} type="error" /> : null}
|
||||
{data ? (
|
||||
<Card
|
||||
title={
|
||||
<Link to={`/manage/jobs/${data.jobs_by_pk.id}`}>
|
||||
{data.jobs_by_pk.ro_number || t("general.labels.na")}
|
||||
</Link>
|
||||
}
|
||||
extra={
|
||||
<Space wrap>
|
||||
<JobSyncButton job={data.jobs_by_pk} />
|
||||
const {t} = useTranslation();
|
||||
const handleDrawerClose = () => {
|
||||
delete searchParams.selected;
|
||||
history({
|
||||
search: queryString.stringify({
|
||||
...searchParams,
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
<Button
|
||||
onClick={() => {
|
||||
setPrintCenterContext({
|
||||
actions: { refetch: refetch },
|
||||
context: {
|
||||
id: data.jobs_by_pk.id,
|
||||
job: data.jobs_by_pk,
|
||||
type: "job",
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<PrinterFilled />
|
||||
{t("jobs.actions.printCenter")}
|
||||
</Button>
|
||||
<Link to={`/manage/jobs/${data.jobs_by_pk.id}?tab=repairdata`}>
|
||||
<Button>{t("parts.actions.order")}</Button>
|
||||
</Link>
|
||||
</Space>
|
||||
}
|
||||
return (
|
||||
<Drawer
|
||||
open={!!selected}
|
||||
destroyOnClose
|
||||
width={drawerPercentage}
|
||||
placement="right"
|
||||
onClose={handleDrawerClose}
|
||||
>
|
||||
<JobsDetailHeader job={data ? data.jobs_by_pk : null} />
|
||||
<Divider type="horizontal" />
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsInsuranceComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsTotalsComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsDatesComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsPartsComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsNotesComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
{!bodyshop.uselocalmediaserver && (
|
||||
<Col {...span}>
|
||||
<JobDetailCardsDocumentsComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
)}
|
||||
<Col {...span}>
|
||||
<JobDetailCardsDamageComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
) : null}
|
||||
</Drawer>
|
||||
);
|
||||
{loading ? <LoadingSpinner/> : null}
|
||||
{error ? <AlertComponent message={error.message} type="error"/> : null}
|
||||
{data ? (
|
||||
<Card
|
||||
title={
|
||||
<Link to={`/manage/jobs/${data.jobs_by_pk.id}`}>
|
||||
{data.jobs_by_pk.ro_number || t("general.labels.na")}
|
||||
</Link>
|
||||
}
|
||||
extra={
|
||||
<Space wrap>
|
||||
<JobSyncButton job={data.jobs_by_pk}/>
|
||||
|
||||
<Button
|
||||
onClick={() => {
|
||||
setPrintCenterContext({
|
||||
actions: {refetch: refetch},
|
||||
context: {
|
||||
id: data.jobs_by_pk.id,
|
||||
job: data.jobs_by_pk,
|
||||
type: "job",
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<PrinterFilled/>
|
||||
{t("jobs.actions.printCenter")}
|
||||
</Button>
|
||||
<Link to={`/manage/jobs/${data.jobs_by_pk.id}?tab=repairdata`}>
|
||||
<Button>{t("parts.actions.order")}</Button>
|
||||
</Link>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<JobsDetailHeader job={data ? data.jobs_by_pk : null}/>
|
||||
<Divider type="horizontal"/>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsInsuranceComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsTotalsComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsDatesComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsPartsComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...span}>
|
||||
<JobDetailCardsNotesComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
{!bodyshop.uselocalmediaserver && (
|
||||
<Col {...span}>
|
||||
<JobDetailCardsDocumentsComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
)}
|
||||
<Col {...span}>
|
||||
<JobDetailCardsDamageComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
) : null}
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JobDetailCards);
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import CardTemplate from "./job-detail-cards.template.component";
|
||||
import Car from "../job-damage-visual/job-damage-visual.component";
|
||||
|
||||
export default function JobDetailCardsDamageComponent({ loading, data }) {
|
||||
const { t } = useTranslation();
|
||||
const { area_of_damage } = data;
|
||||
return (
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.damage")}>
|
||||
{area_of_damage ? (
|
||||
<Car dmg1={area_of_damage.impact1} dmg2={area_of_damage.impact2} />
|
||||
) : (
|
||||
t("jobs.errors.nodamage")
|
||||
)}
|
||||
</CardTemplate>
|
||||
);
|
||||
export default function JobDetailCardsDamageComponent({loading, data}) {
|
||||
const {t} = useTranslation();
|
||||
const {area_of_damage} = data;
|
||||
return (
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.damage")}>
|
||||
{area_of_damage ? (
|
||||
<Car dmg1={area_of_damage.impact1} dmg2={area_of_damage.impact2}/>
|
||||
) : (
|
||||
t("jobs.errors.nodamage")
|
||||
)}
|
||||
</CardTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
import { Carousel } from "antd";
|
||||
import {Carousel} from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { GenerateThumbUrl } from "../jobs-documents-gallery/job-documents.utility";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {GenerateThumbUrl} from "../jobs-documents-gallery/job-documents.utility";
|
||||
import CardTemplate from "./job-detail-cards.template.component";
|
||||
export default function JobDetailCardsDocumentsComponent({ loading, data }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!data)
|
||||
export default function JobDetailCardsDocumentsComponent({loading, data}) {
|
||||
const {t} = useTranslation();
|
||||
|
||||
if (!data)
|
||||
return (
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.documents")}>
|
||||
null
|
||||
</CardTemplate>
|
||||
);
|
||||
|
||||
return (
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.documents")}>
|
||||
null
|
||||
</CardTemplate>
|
||||
<CardTemplate
|
||||
loading={loading}
|
||||
title={t("jobs.labels.cards.documents")}
|
||||
extraLink={`/manage/jobs/${data.id}?tab=documents`}
|
||||
>
|
||||
{data.documents.length > 0 ? (
|
||||
<Carousel autoplay>
|
||||
{data.documents.map((item) => (
|
||||
<img key={item.id} src={GenerateThumbUrl(item)} alt={item.name}/>
|
||||
))}
|
||||
</Carousel>
|
||||
) : (
|
||||
<div>{t("documents.errors.nodocuments")}</div>
|
||||
)}
|
||||
</CardTemplate>
|
||||
);
|
||||
|
||||
return (
|
||||
<CardTemplate
|
||||
loading={loading}
|
||||
title={t("jobs.labels.cards.documents")}
|
||||
extraLink={`/manage/jobs/${data.id}?tab=documents`}
|
||||
>
|
||||
{data.documents.length > 0 ? (
|
||||
<Carousel autoplay>
|
||||
{data.documents.map((item) => (
|
||||
<img key={item.id} src={GenerateThumbUrl(item)} alt={item.name} />
|
||||
))}
|
||||
</Carousel>
|
||||
) : (
|
||||
<div>{t("documents.errors.nodocuments")}</div>
|
||||
)}
|
||||
</CardTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import DataLabel from "../data-label/data-label.component";
|
||||
import CardTemplate from "./job-detail-cards.template.component";
|
||||
export default function JobDetailCardsInsuranceComponent({ loading, data }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.insurance")}>
|
||||
{data ? (
|
||||
<span>
|
||||
export default function JobDetailCardsInsuranceComponent({loading, data}) {
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.insurance")}>
|
||||
{data ? (
|
||||
<span>
|
||||
<DataLabel label={t("jobs.fields.ins_co_nm")} hideIfNull>
|
||||
{data.ins_co_nm}
|
||||
</DataLabel>
|
||||
@@ -16,29 +17,29 @@ export default function JobDetailCardsInsuranceComponent({ loading, data }) {
|
||||
{data.clm_no}
|
||||
</DataLabel>
|
||||
<DataLabel
|
||||
label={t("jobs.labels.cards.filehandler")}
|
||||
open={data.ins_ct_fn && data.ins_ct_ln}>
|
||||
label={t("jobs.labels.cards.filehandler")}
|
||||
open={data.ins_ct_fn && data.ins_ct_ln}>
|
||||
{data.ins_ea ? (
|
||||
<a href={`mailto:${data.ins_ea}`}>
|
||||
<div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div>
|
||||
</a>
|
||||
<a href={`mailto:${data.ins_ea}`}>
|
||||
<div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div>
|
||||
</a>
|
||||
) : (
|
||||
<div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div>
|
||||
<div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div>
|
||||
)}
|
||||
</DataLabel>
|
||||
<DataLabel
|
||||
label={t("jobs.labels.cards.estimator")}
|
||||
open={data.est_ct_fn && data.est_ct_ln}>
|
||||
label={t("jobs.labels.cards.estimator")}
|
||||
open={data.est_ct_fn && data.est_ct_ln}>
|
||||
{data.ins_ea ? (
|
||||
<a href={`mailto:${data.est_ea}`}>
|
||||
<div>{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}</div>
|
||||
</a>
|
||||
<a href={`mailto:${data.est_ea}`}>
|
||||
<div>{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}</div>
|
||||
</a>
|
||||
) : (
|
||||
<div>{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}</div>
|
||||
<div>{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}</div>
|
||||
)}
|
||||
</DataLabel>
|
||||
</span>
|
||||
) : null}
|
||||
</CardTemplate>
|
||||
);
|
||||
) : null}
|
||||
</CardTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { List } from "antd";
|
||||
import {
|
||||
WarningFilled,
|
||||
EyeInvisibleFilled,
|
||||
AuditOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import {List} from "antd";
|
||||
import {AuditOutlined, EyeInvisibleFilled, WarningFilled,} from "@ant-design/icons";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import CardTemplate from "./job-detail-cards.template.component";
|
||||
import styled from "styled-components";
|
||||
|
||||
@@ -14,33 +10,33 @@ const Container = styled.div`
|
||||
overflow-y: auto;
|
||||
`;
|
||||
|
||||
export default function JobDetailCardsNotesComponent({ loading, data }) {
|
||||
const { t } = useTranslation();
|
||||
export default function JobDetailCardsNotesComponent({loading, data}) {
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<CardTemplate
|
||||
loading={loading}
|
||||
title={t("jobs.labels.cards.notes")}
|
||||
extraLink={`/manage/jobs/${data.id}?tab=notes`}
|
||||
>
|
||||
{data ? (
|
||||
<Container>
|
||||
<List
|
||||
bordered
|
||||
dataSource={data.notes}
|
||||
renderItem={(item) => (
|
||||
<List.Item style={{ whiteSpace: "pre-line" }}>
|
||||
{item.critical ? (
|
||||
<EyeInvisibleFilled style={{ margin: 4, color: "red" }} />
|
||||
) : null}
|
||||
{item.private ? <WarningFilled style={{ margin: 4 }} /> : null}
|
||||
{item.audit ? <AuditOutlined style={{ margin: 4 }} /> : null}
|
||||
{item.text}
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</Container>
|
||||
) : null}
|
||||
</CardTemplate>
|
||||
);
|
||||
return (
|
||||
<CardTemplate
|
||||
loading={loading}
|
||||
title={t("jobs.labels.cards.notes")}
|
||||
extraLink={`/manage/jobs/${data.id}?tab=notes`}
|
||||
>
|
||||
{data ? (
|
||||
<Container>
|
||||
<List
|
||||
bordered
|
||||
dataSource={data.notes}
|
||||
renderItem={(item) => (
|
||||
<List.Item style={{whiteSpace: "pre-line"}}>
|
||||
{item.critical ? (
|
||||
<EyeInvisibleFilled style={{margin: 4, color: "red"}}/>
|
||||
) : null}
|
||||
{item.private ? <WarningFilled style={{margin: 4}}/> : null}
|
||||
{item.audit ? <AuditOutlined style={{margin: 4}}/> : null}
|
||||
{item.text}
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</Container>
|
||||
) : null}
|
||||
</CardTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import PartsStatusPie from "../parts-status-pie/parts-status-pie.component";
|
||||
import CardTemplate from "./job-detail-cards.template.component";
|
||||
|
||||
export default function JobDetailCardsPartsComponent({ loading, data }) {
|
||||
const { t } = useTranslation();
|
||||
const { joblines_status } = data;
|
||||
export default function JobDetailCardsPartsComponent({loading, data}) {
|
||||
const {t} = useTranslation();
|
||||
const {joblines_status} = data;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.parts")}>
|
||||
<PartsStatusPie joblines_status={joblines_status} />
|
||||
</CardTemplate>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.parts")}>
|
||||
<PartsStatusPie joblines_status={joblines_status}/>
|
||||
</CardTemplate>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
import { Card } from "antd";
|
||||
import {Card} from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {connect} from "react-redux";
|
||||
import {Link} from "react-router-dom";
|
||||
import {createStructuredSelector} from "reselect";
|
||||
import {selectTechnician} from "../../redux/tech/tech.selectors";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
technician: selectTechnician,
|
||||
technician: selectTechnician,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(JobDetailCardTemplate);
|
||||
|
||||
export function JobDetailCardTemplate({
|
||||
loading,
|
||||
title,
|
||||
extraLink,
|
||||
technician,
|
||||
...otherProps
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
loading,
|
||||
title,
|
||||
extraLink,
|
||||
technician,
|
||||
...otherProps
|
||||
}) {
|
||||
const {t} = useTranslation();
|
||||
|
||||
let extra;
|
||||
if (extraLink && !technician)
|
||||
extra = {
|
||||
extra: <Link to={extraLink}>{t("jobs.labels.cards.more")}</Link>,
|
||||
};
|
||||
return (
|
||||
<Card
|
||||
size="small"
|
||||
className="job-card"
|
||||
title={title}
|
||||
loading={loading}
|
||||
style={{ height: "100%" }}
|
||||
{...extra}
|
||||
>
|
||||
{otherProps.children}
|
||||
</Card>
|
||||
);
|
||||
let extra;
|
||||
if (extraLink && !technician)
|
||||
extra = {
|
||||
extra: <Link to={extraLink}>{t("jobs.labels.cards.more")}</Link>,
|
||||
};
|
||||
return (
|
||||
<Card
|
||||
size="small"
|
||||
className="job-card"
|
||||
title={title}
|
||||
loading={loading}
|
||||
style={{height: "100%"}}
|
||||
{...extra}
|
||||
>
|
||||
{otherProps.children}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
import { Statistic } from "antd";
|
||||
import {Statistic} from "antd";
|
||||
import Dinero from "dinero.js";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import CardTemplate from "./job-detail-cards.template.component";
|
||||
|
||||
export default function JobDetailCardsTotalsComponent({ loading, data }) {
|
||||
const { t } = useTranslation();
|
||||
export default function JobDetailCardsTotalsComponent({loading, data}) {
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.totals")}>
|
||||
{data.job_totals ? (
|
||||
<div className="imex-flex-row imex-flex-row__flex-space-around">
|
||||
<Statistic
|
||||
className="imex-flex-row__margin-large"
|
||||
title={t("jobs.labels.total_repairs")}
|
||||
value={Dinero(data.job_totals.totals.total_repairs).toFormat()}
|
||||
/>
|
||||
<Statistic
|
||||
className="imex-flex-row__margin-large"
|
||||
title={t("jobs.fields.ded_amt")}
|
||||
value={Dinero({
|
||||
amount: Math.round((data.ded_amt || 0) * 100),
|
||||
}).toFormat()}
|
||||
/>
|
||||
<Statistic
|
||||
className="imex-flex-row__margin-large"
|
||||
title={t("jobs.labels.net_repairs")}
|
||||
value={Dinero(data.job_totals.totals.net_repairs).toFormat()}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
t("jobs.errors.nofinancial")
|
||||
)}
|
||||
</CardTemplate>
|
||||
);
|
||||
return (
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.totals")}>
|
||||
{data.job_totals ? (
|
||||
<div className="imex-flex-row imex-flex-row__flex-space-around">
|
||||
<Statistic
|
||||
className="imex-flex-row__margin-large"
|
||||
title={t("jobs.labels.total_repairs")}
|
||||
value={Dinero(data.job_totals.totals.total_repairs).toFormat()}
|
||||
/>
|
||||
<Statistic
|
||||
className="imex-flex-row__margin-large"
|
||||
title={t("jobs.fields.ded_amt")}
|
||||
value={Dinero({
|
||||
amount: Math.round((data.ded_amt || 0) * 100),
|
||||
}).toFormat()}
|
||||
/>
|
||||
<Statistic
|
||||
className="imex-flex-row__margin-large"
|
||||
title={t("jobs.labels.net_repairs")}
|
||||
value={Dinero(data.job_totals.totals.net_repairs).toFormat()}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
t("jobs.errors.nofinancial")
|
||||
)}
|
||||
</CardTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import CardTemplate from "./job-detail-cards.template.component";
|
||||
|
||||
export default function JobDetailCardsVehicleComponent({ loading, data }) {
|
||||
const { t } = useTranslation();
|
||||
export default function JobDetailCardsVehicleComponent({loading, data}) {
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<CardTemplate
|
||||
loading={loading}
|
||||
title={t("jobs.labels.cards.vehicle")}
|
||||
extraLink={data.vehicle ? `/manage/vehicles/${data.vehicle.id}` : null}
|
||||
>
|
||||
{data ? (
|
||||
<span>
|
||||
return (
|
||||
<CardTemplate
|
||||
loading={loading}
|
||||
title={t("jobs.labels.cards.vehicle")}
|
||||
extraLink={data.vehicle ? `/manage/vehicles/${data.vehicle.id}` : null}
|
||||
>
|
||||
{data ? (
|
||||
<span>
|
||||
{` ${data.vehicle?.v_model_yr || t("general.labels.na")} ${
|
||||
data.vehicle?.v_make_desc || t("general.labels.na")
|
||||
data.vehicle?.v_make_desc || t("general.labels.na")
|
||||
} ${data.vehicle?.v_model_desc || t("general.labels.na")}`}
|
||||
</span>
|
||||
) : null}
|
||||
</CardTemplate>
|
||||
);
|
||||
) : null}
|
||||
</CardTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user