diff --git a/components/job-documents/image-loader.jsx b/components/job-documents/image-loader.jsx
new file mode 100644
index 0000000..fa36f11
--- /dev/null
+++ b/components/job-documents/image-loader.jsx
@@ -0,0 +1,43 @@
+import { useMemo, useState } from "react";
+import { Image } from "react-native";
+import { ActivityIndicator } from "react-native-paper";
+
+const ImageLoader = ({ style, source, ...props }) => {
+ const [loading, setLoading] = useState(true);
+
+ const handleLoadStart = () => {
+ setLoading(true);
+ };
+
+ const handleLoadEnd = () => {
+ setLoading(false);
+ };
+
+ const handleLoad = () => {
+ setLoading(false);
+ };
+
+ const memorizedImage = useMemo(
+ () => (
+
+ ),
+ [source]
+ );
+ if (loading)
+ return (
+ <>
+
+ {memorizedImage}
+ >
+ );
+ return memorizedImage;
+};
+
+export default ImageLoader;
diff --git a/components/job-documents/job-documents.jsx b/components/job-documents/job-documents.jsx
index 2ef7558..9157df6 100644
--- a/components/job-documents/job-documents.jsx
+++ b/components/job-documents/job-documents.jsx
@@ -2,13 +2,7 @@ import cleanAxios from "@/util/CleanAxios";
import axios from "axios";
import { useGlobalSearchParams } from "expo-router";
import React, { useCallback, useEffect, useState } from "react";
-import {
- FlatList,
- Image,
- RefreshControl,
- TouchableOpacity,
- View,
-} from "react-native";
+import { FlatList, RefreshControl, TouchableOpacity, View } from "react-native";
import ImageView from "react-native-image-viewing";
import { ActivityIndicator, Text } from "react-native-paper";
import { connect } from "react-redux";
@@ -17,6 +11,7 @@ import env from "../../env";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { DetermineFileType } from "../../util/document-upload.utility";
import ErrorDisplay from "../error/error-display";
+import ImageLoader from "./image-loader";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -142,7 +137,7 @@ export function JobDocumentsComponent({ bodyshop }) {
setPreviewVisible(true);
}}
>
- ({});
+export default connect(mapStateToProps, mapDispatchToProps)(JobTombstone);
+
+function JobTombstone({ bodyshop }) {
const { jobId } = useLocalSearchParams();
const { loading, error, data, refetch } = useQuery(GET_JOB_BY_PK, {
variables: {
@@ -15,6 +31,10 @@ export default function JobTombstone() {
},
skip: !jobId,
});
+ const [visible, setVisible] = useState(false);
+ const openMenu = () => setVisible(true);
+ const closeMenu = () => setVisible(false);
+ console.log("JobTombstone render", visible);
const theme = useTheme();
@@ -22,6 +42,42 @@ export default function JobTombstone() {
const onRefresh = async () => {
return refetch();
};
+
+ const [availableStatuses, setAvailableStatuses] = useState([]);
+ 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 ;
}
@@ -50,6 +106,15 @@ export default function JobTombstone() {
/>
{job.status}
+
{job.inproduction && (
{t("objects.jobs.labels.inproduction")}
)}
diff --git a/components/jobs-list/jobs-list.jsx b/components/jobs-list/jobs-list.jsx
index f8848a9..82dda10 100644
--- a/components/jobs-list/jobs-list.jsx
+++ b/components/jobs-list/jobs-list.jsx
@@ -31,7 +31,7 @@ export function JobListComponent({ bodyshop }) {
return refetch();
};
- if (loading) return ;
+ if (loading) return ;
if (error) return {error.message};
if (data && data.jobs && data.jobs.length === 0)
return (
diff --git a/graphql/bodyshop.queries.js b/graphql/bodyshop.queries.js
index 114d767..4c2772e 100644
--- a/graphql/bodyshop.queries.js
+++ b/graphql/bodyshop.queries.js
@@ -12,6 +12,7 @@ export const QUERY_BODYSHOP = gql`
features
localmediatoken
imexshopid
+ md_ro_statuses
}
}
`;
diff --git a/package-lock.json b/package-lock.json
index feeaa1b..7a5a884 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"@apollo/client": "^3.14.0",
"@expo/vector-icons": "^15.0.2",
"@react-native-async-storage/async-storage": "2.2.0",
+ "@react-native-picker/picker": "2.11.1",
"@react-native-vector-icons/material-design-icons": "^12.3.0",
"@react-navigation/bottom-tabs": "^7.4.0",
"@react-navigation/elements": "^2.6.5",
@@ -4546,6 +4547,19 @@
"react-native": "^0.0.0-0 || >=0.65 <1.0"
}
},
+ "node_modules/@react-native-picker/picker": {
+ "version": "2.11.1",
+ "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.11.1.tgz",
+ "integrity": "sha512-ThklnkK4fV3yynnIIRBkxxjxR4IFbdMNJVF6tlLdOJ/zEFUEFUEdXY0KmH0iYzMwY8W4/InWsLiA7AkpAbnexA==",
+ "license": "MIT",
+ "workspaces": [
+ "example"
+ ],
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/@react-native-vector-icons/common": {
"version": "12.3.0",
"resolved": "https://registry.npmjs.org/@react-native-vector-icons/common/-/common-12.3.0.tgz",
diff --git a/package.json b/package.json
index 6bc7312..4f2fcb0 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"@apollo/client": "^3.14.0",
"@expo/vector-icons": "^15.0.2",
"@react-native-async-storage/async-storage": "2.2.0",
+ "@react-native-picker/picker": "2.11.1",
"@react-native-vector-icons/material-design-icons": "^12.3.0",
"@react-navigation/bottom-tabs": "^7.4.0",
"@react-navigation/elements": "^2.6.5",
@@ -91,4 +92,4 @@
"eslint-config-expo": "~10.0.0",
"typescript": "~5.9.3"
}
-}
\ No newline at end of file
+}