Files
imexmobile/components/job-tombstone/job-tombstone.jsx
2025-10-29 15:26:20 -07:00

267 lines
8.3 KiB
JavaScript

import { GET_JOB_BY_PK } from "@/graphql/jobs.queries";
import { selectBodyshop } from "@/redux/user/user.selectors";
import { useQuery } from "@apollo/client";
import { useLocalSearchParams } from "expo-router";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { RefreshControl, ScrollView, StyleSheet, View } from "react-native";
import { ActivityIndicator, Card, Chip, Text } from "react-native-paper";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import DataLabelComponent from "../data-label/data-label";
import ErrorDisplay from "../error/error-display";
import { JobStatusSelector } from "../job-status-selector/job-status-selector";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({});
export default connect(mapStateToProps, mapDispatchToProps)(JobTombstone);
function JobTombstone({ bodyshop }) {
const { jobId } = useLocalSearchParams();
const { loading, error, data, refetch } = useQuery(GET_JOB_BY_PK, {
variables: {
id: jobId,
},
skip: !jobId,
});
const { t } = useTranslation();
const onRefresh = async () => {
return refetch();
};
const [availableStatuses, setAvailableStatuses] = useState([]);
const job = data?.jobs_by_pk;
useEffect(() => {
if (!job || !bodyshop) return;
const { md_ro_statuses } = bodyshop;
const {
pre_production_statuses,
production_statuses,
post_production_statuses,
statuses,
default_invoiced,
default_exported,
} = md_ro_statuses;
// Handle non-parts entry scenarios based on job status
if (pre_production_statuses.includes(job.status)) {
setAvailableStatuses(pre_production_statuses);
} else if (production_statuses.includes(job.status)) {
setAvailableStatuses(production_statuses);
} else if (post_production_statuses.includes(job.status)) {
// Filter out invoiced and exported statuses for post-production
setAvailableStatuses(
post_production_statuses.filter(
(status) => status !== default_invoiced && status !== default_exported
)
);
} else {
// Default to all statuses if no specific restrictions apply
console.log(
"Status didn't match any restrictions. Allowing all status changes."
);
setAvailableStatuses(statuses);
}
}, [job, bodyshop, setAvailableStatuses]);
if (loading) {
return <ActivityIndicator size="large" style={{ flex: 1 }} />;
}
if (error) {
return <ErrorDisplay message={JSON.stringify(error)} />;
}
if (!data.jobs_by_pk) {
return (
<Card>
<Text>Job is not defined.</Text>
</Card>
);
}
return (
<ScrollView
contentContainerStyle={{
rowGap: 16,
padding: 10,
}}
refreshControl={
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
}
>
<Card>
<Card.Title
title={t("jobdetail.labels.jobinfo")}
titleVariant="titleLarge"
/>
<Card.Content>
<DataLabelComponent
label={t("objects.jobs.fields.status")}
content={
<JobStatusSelector
statuses={availableStatuses}
currentStatus={job.status}
label={t("jobdetail.labels.status")}
/>
}
/>
{job.inproduction && (
<DataLabelComponent
label={t("objects.jobs.fields.inproduction")}
content={
<Chip mode="outlined">
{t("objects.jobs.labels.inproduction")}
</Chip>
}
/>
)}
{job.inproduction &&
job.production_vars &&
!!job.production_vars.note && (
<DataLabelComponent
label={t("objects.jobs.fields.production_note")}
content={<Text>{job.production_vars.note}</Text>}
/>
)}
</Card.Content>
</Card>
<Card>
<Card.Title
title={t("jobdetail.labels.claiminformation")}
titleVariant="titleLarge"
/>
<Card.Content style={localStyles.twoColumnCard}>
<View style={localStyles.twoColumnCardColumn}>
<DataLabelComponent
label={t("objects.jobs.fields.owner")}
content={`${job.ownr_fn || ""} ${job.ownr_ln || ""} ${
job.ownr_co_nm || ""
}`}
/>
<DataLabelComponent
label={t("objects.jobs.fields.vehicle")}
content={`${job.v_model_yr || ""} ${job.v_make_desc || ""} ${
job.v_model_desc || ""
} - ${job.v_vin}`}
/>
</View>
<View style={localStyles.twoColumnCardColumn}>
<DataLabelComponent
label={t("objects.jobs.fields.ins_co_nm")}
content={job.ins_co_nm}
/>
<DataLabelComponent
label={t("objects.jobs.fields.clm_no")}
content={job.clm_no}
/>
</View>
</Card.Content>
</Card>
<Card>
<Card.Title
title={t("jobdetail.labels.employeeassignments")}
titleVariant="titleLarge"
/>
<Card.Content>
<DataLabelComponent
label={t("objects.jobs.fields.employee_body")}
content={`${
(job.employee_body_rel && job.employee_body_rel.first_name) ||
t("general.labels.na")
} ${
(job.employee_body_rel && job.employee_body_rel.last_name) || ""
}`}
/>
<DataLabelComponent
label={t("objects.jobs.fields.employee_prep")}
content={`${
(job.employee_prep_rel && job.employee_prep_rel.first_name) ||
t("general.labels.na")
} ${
(job.employee_prep_rel && job.employee_prep_rel.last_name) || ""
}`}
/>
<DataLabelComponent
label={t("objects.jobs.fields.employee_refinish")}
content={`${
(job.employee_refinish_rel &&
job.employee_refinish_rel.first_name) ||
t("general.labels.na")
} ${
(job.employee_refinish_rel &&
job.employee_refinish_rel.last_name) ||
""
}`}
/>
<DataLabelComponent
label={t("objects.jobs.fields.employee_csr")}
content={`${
(job.employee_csr_rel && job.employee_csr_rel.first_name) ||
t("general.labels.na")
} ${
(job.employee_csr_rel && job.employee_csr_rel.last_name) || ""
}`}
/>
</Card.Content>
</Card>
<Card>
<Card.Title
title={t("jobdetail.labels.dates")}
titleVariant="titleLarge"
/>
<Card.Content style={localStyles.twoColumnCard}>
<View style={localStyles.twoColumnCardColumn}>
<DataLabelComponent
label={t("objects.jobs.fields.scheduled_in")}
content={job.scheduled_in}
dateTime
/>
<DataLabelComponent
label={t("objects.jobs.fields.actual_in")}
content={job.actual_in}
dateTime
/>
</View>
<View style={localStyles.twoColumnCardColumn}>
<DataLabelComponent
label={t("objects.jobs.fields.scheduled_completion")}
content={job.scheduled_completion}
dateTime
/>
<DataLabelComponent
label={t("objects.jobs.fields.scheduled_delivery")}
content={job.scheduled_delivery}
dateTime
/>
</View>
</Card.Content>
</Card>
<View
style={{ height: 64 }} //Spacer
/>
</ScrollView>
);
}
const localStyles = StyleSheet.create({
twoColumnCard: { display: "flex", flexDirection: "row" },
twoColumnCardColumn: { flex: 1 },
status: {
textAlign: "center",
flexDirection: "row",
justifyContent: "center",
},
inproduction: {
textAlign: "center",
flexDirection: "row",
justifyContent: "center",
},
});