diff --git a/app.config.js b/app.config.js
index 43a6812..01ba285 100644
--- a/app.config.js
+++ b/app.config.js
@@ -15,7 +15,7 @@ export default ({ config }) => {
projectId: IS_ROME ? "df105e21-a07f-4425-af10-2200a7704a48" : "ffe01f3a-d507-4698-82cd-da1f1cad450b"
}
},
- icon: IS_ROME ? "./assets/RomeIcon.png" : "./assets/logo192noa.png",
+ icon: IS_ROME ? "./assets/RomeIcon.png" : "./assets/ImEXlogo192noa.png",
ios: {
...config.ios,
bundleIdentifier: IS_ROME ? "com.rome.mobile" : "com.imex.imexmobile"
@@ -55,7 +55,5 @@ export default ({ config }) => {
}
})
-
- console.log("New Expo Config:", JSON.stringify(newConfig, null, 2));
return newConfig;
};
\ No newline at end of file
diff --git a/app/_layout.tsx b/app/_layout.tsx
index 121fd00..414e42c 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -1,6 +1,7 @@
import { checkUserSession } from "@/redux/user/user.actions";
import { selectBodyshop, selectCurrentUser } from "@/redux/user/user.selectors";
import { ApolloProvider } from "@apollo/client";
+import { loadDevMessages, loadErrorMessages } from "@apollo/client/dev";
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
import {
DarkTheme,
@@ -28,6 +29,9 @@ import { persistor, store } from "../redux/store";
import "../translations/i18n";
import { registerForPushNotificationsAsync } from "../util/notificationHandler";
+loadDevMessages();
+loadErrorMessages();
+
function AuthenticatedLayout() {
const { t } = useTranslation();
const paperTheme = usePaperTheme();
diff --git a/components-old/camera-controls/camera-controls.component.jsx b/components-old/camera-controls/camera-controls.component.jsx
deleted file mode 100644
index e015c58..0000000
--- a/components-old/camera-controls/camera-controls.component.jsx
+++ /dev/null
@@ -1,103 +0,0 @@
-// // src/toolbar.component.js file
-// import { Ionicons } from "@expo/vector-icons";
-// import { Camera } from "expo-camera";
-// import React from "react";
-// import {
-// StyleSheet,
-// TouchableOpacity,
-// TouchableWithoutFeedback,
-// View,
-// } from "react-native";
-
-// const styles = StyleSheet.create({
-// alignCenter: {
-// flex: 1,
-// alignItems: "center",
-// justifyContent: "center",
-// },
-// bottomToolbar: {
-// marginTop: "auto",
-// height: 100,
-// display: "flex",
-// justifyContent: "space-evenly",
-// alignItems: "center",
-// flexDirection: "row",
-// },
-// captureBtn: {
-// width: 60,
-// height: 60,
-// borderWidth: 2,
-// borderRadius: 60,
-// borderColor: "#FFFFFF",
-// },
-// captureBtnActive: {
-// width: 80,
-// height: 80,
-// },
-// captureBtnInternal: {
-// width: 76,
-// height: 76,
-// borderWidth: 2,
-// borderRadius: 76,
-// backgroundColor: "red",
-// borderColor: "transparent",
-// },
-// });
-
-// const { FlashMode: CameraFlashModes, Type: CameraTypes } = Camera.Constants;
-
-// export default function CameraControls({
-// capturing = false,
-// cameraType = CameraTypes.back,
-// flashMode = CameraFlashModes.off,
-// setFlashMode,
-// setCameraType,
-// onCaptureIn,
-// onCaptureOut,
-// onLongCapture,
-// onShortCapture,
-// }) {
-// return (
-//
-//
-// setFlashMode(
-// flashMode === CameraFlashModes.on
-// ? CameraFlashModes.off
-// : CameraFlashModes.on
-// )
-// }
-// >
-//
-//
-
-//
-//
-// {capturing && }
-//
-//
-
-//
-// setCameraType(
-// cameraType === CameraTypes.back
-// ? CameraTypes.front
-// : CameraTypes.back
-// )
-// }
-// >
-//
-//
-//
-// );
-// }
diff --git a/components-old/camera-select-job/camera-select-job.component.jsx b/components-old/camera-select-job/camera-select-job.component.jsx
deleted file mode 100644
index fccbd55..0000000
--- a/components-old/camera-select-job/camera-select-job.component.jsx
+++ /dev/null
@@ -1,184 +0,0 @@
-import { useQuery } from "@apollo/client";
-import { Ionicons } from "@expo/vector-icons";
-import React from "react";
-import { useTranslation } from "react-i18next";
-import { FlatList, RefreshControl, View } from "react-native";
-import { Button, List, Modal, Portal, Searchbar } from "react-native-paper";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { QUERY_ALL_ACTIVE_JOBS } from "../../graphql/jobs.queries";
-import { setCameraJob, setCameraJobId } from "../../redux/app/app.actions";
-import {
- selectCurrentCameraJob,
- selectCurrentCameraJobId,
-} from "../../redux/app/app.selectors";
-import { selectBodyshop } from "../../redux/user/user.selectors";
-import ErrorDisplay from "../error-display/error-display.component";
-import LoadingDisplay from "../loading-display/loading-display.component";
-
-const mapStateToProps = createStructuredSelector({
- bodyshop: selectBodyshop,
- cameraJobId: selectCurrentCameraJobId,
- cameraJob: selectCurrentCameraJob,
-});
-
-const mapDispatchToProps = (dispatch) => ({
- setCameraJobId: (id) => dispatch(setCameraJobId(id)),
- setCameraJob: (job) => dispatch(setCameraJob(job)),
-});
-
-export function CameraSelectJob({
- bodyshop,
- cameraJobId,
- setCameraJobId,
- cameraJob,
- setCameraJob,
-}) {
- const { loading, error, data, refetch } = useQuery(QUERY_ALL_ACTIVE_JOBS, {
- variables: {
- statuses: bodyshop.md_ro_statuses.active_statuses || ["Open", "Open*"],
- },
- skip: !bodyshop,
- });
- const { t } = useTranslation();
- const [visible, setVisible] = React.useState(false);
- const [searchQuery, setSearchQuery] = React.useState("");
- if (loading) return ;
- if (error) return ;
-
- const showModal = () => setVisible(true);
- const hideModal = () => setVisible(false);
-
- const onRefresh = async () => {
- return refetch();
- };
-
- const onChangeSearch = (query) => setSearchQuery(query);
-
- const jobs = data
- ? searchQuery === ""
- ? data.jobs
- : data.jobs.filter(
- (j) =>
- (j.ro_number || "")
- .toString()
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.ownr_co_nm || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.ownr_fn || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.ownr_ln || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.plate_no || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.v_model_desc || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.v_make_desc || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase())
- )
- : [];
-
- return (
- <>
-
-
-
-
-
-
-
- }
- data={[{ id: "temp", ro_number: "Temporary Storage" }, ...jobs]}
- keyExtractor={(item) => item.id}
- renderItem={(object) => (
- {
- setCameraJobId(object.item.id);
- setCameraJob(object.item);
- hideModal();
- setSearchQuery("");
- }}
- left={() => {
- if (object.item.id !== cameraJobId) return null;
- return (
-
- );
- }}
- titleStyle={{
- ...(object.item.id === cameraJobId
- ? { color: "dodgerblue" }
- : {}),
- }}
- title={`${
- object.item.ro_number ? `${object.item.ro_number} ` : ``
- }${object.item.ownr_fn || ""} ${object.item.ownr_ln || ""} ${
- object.item.ownr_co_nm || ""
- } ${
- object.item.v_model_yr ? `- ${object.item.v_model_yr}` : ""
- } ${
- object.item.v_make_desc ? `- ${object.item.v_make_desc}` : ""
- } ${
- object.item.v_model_desc
- ? `- ${object.item.v_model_desc}`
- : ""
- }`}
- key={object.item.id}
- />
- )}
- />
-
-
-
- >
- );
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(CameraSelectJob);
diff --git a/components-old/error-display/error-display.component.jsx b/components-old/error-display/error-display.component.jsx
deleted file mode 100644
index 84f41b6..0000000
--- a/components-old/error-display/error-display.component.jsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from "react";
-import { View, Text } from "react-native";
-
-export default function ErrorDisplay({ errorMessage }) {
- return (
-
- {errorMessage}
-
- );
-}
diff --git a/components-old/flat-list-item-separator/flat-list-item-separator.component.jsx b/components-old/flat-list-item-separator/flat-list-item-separator.component.jsx
deleted file mode 100644
index 511a779..0000000
--- a/components-old/flat-list-item-separator/flat-list-item-separator.component.jsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from "react";
-import { View, Text } from "react-native";
-
-export default function FlatListItemSeparator() {
- return (
-
- );
-}
diff --git a/components-old/job-documents/job-documents-local.component.jsx b/components-old/job-documents/job-documents-local.component.jsx
deleted file mode 100644
index 181d31b..0000000
--- a/components-old/job-documents/job-documents-local.component.jsx
+++ /dev/null
@@ -1,112 +0,0 @@
-import React, { useEffect, useState } from "react";
-import {
- FlatList,
- Image,
- RefreshControl,
- Text,
- TouchableOpacity,
- View,
-} from "react-native";
-import MediaCacheOverlay from "../media-cache-overlay/media-cache-overlay.component";
-import * as Sentry from "@sentry/react-native";
-import Toast from "react-native-toast-message";
-
-import cleanAxios from "../../util/CleanAxios";
-
-export default function JobDocumentsLocalComponent({ bodyshop, job }) {
- const [previewVisible, setPreviewVisible] = useState(false);
- const [images, setImages] = useState([]);
- const [imgIndex, setImgIndex] = useState(0);
- useEffect(() => {
- if (job.id) {
- getPhotos({ bodyshop, jobid: job.id, setImages });
- }
- }, [job.id, bodyshop]);
-
- const onRefresh = async () => {
- return getPhotos({ bodyshop, jobid: job.id, setImages });
- };
-
- return (
-
-
- }
- data={images}
- numColumns={4}
- style={{ flex: 1 }}
- keyExtractor={(item) => item.id}
- renderItem={(object) => (
- {
- setImgIndex(object.index);
- setPreviewVisible(true);
- }}
- >
-
-
- )}
- />
-
- {images?.filter((d) => d.type?.mime?.startsWith("image")).length}
-
-
-
-
- );
-}
-
-async function getPhotos({ bodyshop, jobid, setImages }) {
- let localmediaserverhttp = bodyshop.localmediaserverhttp.trim();
- if (localmediaserverhttp.endsWith("/")) {
- localmediaserverhttp = localmediaserverhttp.slice(0, -1);
- }
-
- try {
- const imagesFetch = await cleanAxios.post(
- `${localmediaserverhttp}/jobs/list`,
- {
- jobid,
- },
- { headers: { ims_token: bodyshop.localmediatoken } }
- );
-
- const normalizedImages = imagesFetch.data
- .filter((d) => d.type?.mime?.startsWith("image"))
- .map((d, idx) => {
- return {
- ...d,
- // src: `${localmediaserverhttp}/${d.src}`,
-
- uri: `${localmediaserverhttp}${d.src}`,
- thumbUrl: `${localmediaserverhttp}${d.thumbnail}`,
- id: idx,
- };
- });
-
- setImages(normalizedImages);
- } catch (error) {
- Sentry.captureException(error);
- Toast.show({
- type: "error",
- text1: `Error fetching photos.`,
-
- text2: JSON.stringify(error),
- });
- }
-}
diff --git a/components-old/job-documents/job-documents.component.jsx b/components-old/job-documents/job-documents.component.jsx
deleted file mode 100644
index 899d05d..0000000
--- a/components-old/job-documents/job-documents.component.jsx
+++ /dev/null
@@ -1,175 +0,0 @@
-import axios from "axios";
-import React, { useEffect, useState } from "react";
-import {
- FlatList,
- Image,
- RefreshControl,
- Text,
- TouchableOpacity,
- View,
-} from "react-native";
-import env from "../../env";
-import { DetermineFileType } from "../../util/document-upload.utility";
-import MediaCacheOverlay from "../media-cache-overlay/media-cache-overlay.component";
-
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { selectBodyshop } from "../../redux/user/user.selectors";
-//import { splitClient } from "../screen-main/screen-main.component";
-
-const mapStateToProps = createStructuredSelector({
- //currentUser: selectCurrentUser
- bodyshop: selectBodyshop,
-});
-const mapDispatchToProps = (dispatch) => ({
- //setUserLanguage: language => dispatch(setUserLanguage(language))
-});
-export default connect(
- mapStateToProps,
- mapDispatchToProps
-)(JobDocumentsComponent);
-
-export function JobDocumentsComponent({ bodyshop, job, loading, refetch }) {
- const [previewVisible, setPreviewVisible] = useState(false);
- const [fullphotos, setFullPhotos] = useState([]);
- const [imgIndex, setImgIndex] = useState(0);
-
- const useImgproxy = splitClient?.getTreatment("Imgproxy");
-
- const onRefresh = async () => {
- return refetch();
- };
-
- useEffect(() => {
- async function getPhotos() {
- if (useImgproxy) {
- const result = await axios.post(
- `${env.API_URL}/media/imgproxy/thumbnails`,
- {
- jobid: job.id,
- }
- );
-
- setFullPhotos(
- result.data.map((doc, idx) => {
- return {
- id: idx,
- videoUrl:
- DetermineFileType(doc.type) === "video" &&
- doc.originalUrlViaProxyPath,
- source:
- DetermineFileType(doc.type) === "video"
- ? { uri: doc.thumbnailUrl }
- : { uri: doc.originalUrl },
- url:
- DetermineFileType(doc.type) === "video"
- ? doc.thumbnailUrl
- : doc.originalUrl,
- uri:
- DetermineFileType(doc.type) === "video"
- ? doc.originalUrlViaProxyPath
- : doc.originalUrl,
- thumbUrl: doc.thumbnailUrl,
- };
- })
- );
- } else {
- setFullPhotos(
- job.documents.map((doc, idx) => {
- return {
- id: idx,
- videoUrl:
- DetermineFileType(doc.type) === "video" && GenerateSrcUrl(doc),
- source:
- DetermineFileType(doc.type) === "video"
- ? { uri: GenerateThumbUrl(doc) }
- : { uri: GenerateSrcUrl(doc) },
- url:
- DetermineFileType(doc.type) === "video"
- ? GenerateThumbUrl(doc)
- : GenerateSrcUrl(doc),
- uri:
- DetermineFileType(doc.type) === "video"
- ? GenerateThumbUrl(doc)
- : GenerateSrcUrl(doc),
- thumbUrl: GenerateThumbUrl(doc),
- };
- })
- );
- }
- }
-
- getPhotos();
- }, [job.documents]);
-
- return (
-
-
- }
- data={fullphotos}
- numColumns={4}
- style={{ flex: 1 }}
- keyExtractor={(item) => item.id}
- renderItem={(object) => (
- {
- setImgIndex(object.index);
- setPreviewVisible(true);
- }}
- >
-
-
- )}
- />
-
-
- {fullphotos.length}
-
-
-
-
- );
-}
-
-export const GenerateSrcUrl = (value) => {
- let extension = value.extension;
- if (extension && extension.toLowerCase().includes("heic")) extension = "jpg";
-
- return `${env.REACT_APP_CLOUDINARY_ENDPOINT}/${DetermineFileType(
- value.type
- )}/upload/${value.key}${extension ? `.${extension}` : ""}`;
-};
-
-export const GenerateThumbUrl = (value) => {
- let extension = value.extension;
- if (extension && extension.includes("heic")) extension = "jpg";
- else if (
- DetermineFileType(value.type) !== "image" ||
- (value.type && value.type.includes("application"))
- )
- extension = "jpg";
-
- return `${env.REACT_APP_CLOUDINARY_ENDPOINT}/${DetermineFileType(
- value.type
- )}/upload/${env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS}/${value.key}${
- extension ? `.${extension}` : ""
- }`;
-};
diff --git a/components-old/job-lines/job-lines.component.jsx b/components-old/job-lines/job-lines.component.jsx
deleted file mode 100644
index 05240b4..0000000
--- a/components-old/job-lines/job-lines.component.jsx
+++ /dev/null
@@ -1,72 +0,0 @@
-import React from "react";
-import { useTranslation } from "react-i18next";
-import { FlatList, RefreshControl, StyleSheet, Text, View } from "react-native";
-import { Card, DataTable } from "react-native-paper";
-
-export default function JobLines({ job, loading, refetch }) {
- const { t } = useTranslation();
-
- if (!job) {
-
- Job is not defined.
- ;
- }
- const onRefresh = async () => {
- return refetch();
- };
-
- return (
-
-
-
-
- {t("jobdetail.labels.lines_desc")}
-
-
- {t("jobdetail.labels.lines_lbr_ty")}
-
-
- {t("jobdetail.labels.lines_lb_hrs")}
-
-
- {t("jobdetail.labels.lines_part_type")}
-
-
- {t("jobdetail.labels.lines_qty")}
-
-
-
-
-
- }
- keyExtractor={(item) => item.id}
- renderItem={(object) => (
-
-
- {object.item.line_desc}
-
-
- {object.item.mod_lbr_ty &&
- t(`jobdetail.lbr_types.${object.item.mod_lbr_ty}`)}
-
-
- {object.item.mod_lb_hrs}
-
-
- {object.item.part_type &&
- t(`jobdetail.part_types.${object.item.part_type}`)}
-
-
- {object.item.part_qty}
-
-
- )}
- />
-
- );
-}
-
-const localStyles = StyleSheet.create({});
diff --git a/components-old/job-list-item/job-list-item.component.jsx b/components-old/job-list-item/job-list-item.component.jsx
deleted file mode 100644
index 5d7a516..0000000
--- a/components-old/job-list-item/job-list-item.component.jsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import { Ionicons } from "@expo/vector-icons";
-import { useNavigation } from "@react-navigation/native";
-import React from "react";
-import { useTranslation } from "react-i18next";
-import { Button, List, Title } from "react-native-paper";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { logImEXEvent } from "../../firebase/firebase.analytics";
-import { setCameraJob, setCameraJobId } from "../../redux/app/app.actions";
-
-const mapStateToProps = createStructuredSelector({});
-const mapDispatchToProps = (dispatch) => ({
- setCameraJobId: (id) => dispatch(setCameraJobId(id)),
- setCameraJob: (job) => dispatch(setCameraJob(job)),
-});
-
-export function JobListItem({ setCameraJob, setCameraJobId, item }) {
- const { t } = useTranslation();
- const navigation = useNavigation();
- // const _swipeableRow = useRef(null);
-
- // const RenderRightAction = (progress, dragX) => {
- // const scale = dragX.interpolate({
- // inputRange: [-100, 0],
- // outputRange: [0.7, 0],
- // });
-
- // return (
- // {
- // logImEXEvent("imexmobile_setcamerajobid_swipe");
- // setCameraJobId(item.id);
- // setCameraJob(item);
- // navigation.navigate("MediaBrowserTab");
- // _swipeableRow.current.close();
- // }}
- // >
- //
- //
- //
- //
- // );
- // };
-
- const onPress = () => {
- logImEXEvent("imexmobile_view_job_detail");
- navigation.push("JobDetail", {
- jobId: item.id,
- title: item.ro_number || t("general.labels.na"),
- job: item,
- });
- };
-
- return (
- {item.ro_number || t("general.labels.na")}}
- description={`${item.ownr_fn || ""} ${item.ownr_ln || ""} ${
- item.ownr_co_nm || ""
- } - ${item.v_model_yr || ""} ${item.v_make_desc || ""} ${
- item.v_model_desc || ""
- }`}
- right={({ style }) => (
-
- )}
- />
- );
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(JobListItem);
diff --git a/components-old/job-list/job-list.component.jsx b/components-old/job-list/job-list.component.jsx
deleted file mode 100644
index 56db494..0000000
--- a/components-old/job-list/job-list.component.jsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import { useQuery } from "@apollo/client";
-import React from "react";
-import { useTranslation } from "react-i18next";
-import { FlatList, RefreshControl, Text, View } from "react-native";
-import { Button, Searchbar, Title } from "react-native-paper";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { QUERY_ALL_ACTIVE_JOBS } from "../../graphql/jobs.queries";
-import { selectBodyshop } from "../../redux/user/user.selectors";
-import ErrorDisplay from "../error-display/error-display.component";
-import JobListItem from "../job-list-item/job-list-item.component";
-import LoadingDisplay from "../loading-display/loading-display.component";
-
-const mapStateToProps = createStructuredSelector({
- bodyshop: selectBodyshop,
-});
-
-export function JobListComponent({ bodyshop }) {
- const { t } = useTranslation();
- const [searchQuery, setSearchQuery] = React.useState("");
- const { loading, error, data, refetch } = useQuery(QUERY_ALL_ACTIVE_JOBS, {
- variables: {
- statuses: bodyshop.md_ro_statuses.active_statuses || ["Open", "Open*"],
- },
- skip: !bodyshop,
- notifyOnNetworkStatusChange: true,
- });
-
- const onRefresh = async () => {
- return refetch();
- };
- const onChangeSearch = (query) => setSearchQuery(query);
-
- if (loading) return ;
- if (error) return ;
- if (data && data.jobs && data.jobs.length === 0)
- return (
-
-
- {t("joblist.labels.nojobs")}
-
-
-
- );
-
- const jobs = data
- ? searchQuery === ""
- ? data.jobs
- : data.jobs.filter(
- (j) =>
- (j.ro_number || "")
- .toString()
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.ownr_co_nm || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.ownr_fn || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.ownr_ln || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.v_model_desc || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase()) ||
- (j.v_make_desc || "")
- .toLowerCase()
- .includes(searchQuery.toLowerCase())
- )
- : [];
-
- return (
-
-
-
- }
- style={{ flex: 1 }}
- data={jobs}
- renderItem={(object) => }
- />
-
- );
-}
-
-export default connect(mapStateToProps, null)(JobListComponent);
diff --git a/components-old/job-notes-item/job-notes-item.component.jsx b/components-old/job-notes-item/job-notes-item.component.jsx
deleted file mode 100644
index 78b1914..0000000
--- a/components-old/job-notes-item/job-notes-item.component.jsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { AntDesign } from "@expo/vector-icons";
-import { DateTime } from "luxon";
-import React from "react";
-import { Text, View } from "react-native";
-import { Card } from "react-native-paper";
-export default function NoteListItem({ item }) {
- return (
-
-
-
- {item.text}
-
- {item.private && (
-
- )}
- {item.critical && (
-
- )}
- {item.created_by}
-
- {DateTime.fromISO(item.created_at).toLocaleString(
- DateTime.DATETIME_SHORT
- )}
-
-
-
-
-
- );
-}
diff --git a/components-old/job-notes/job-notes.component.jsx b/components-old/job-notes/job-notes.component.jsx
deleted file mode 100644
index 01b9695..0000000
--- a/components-old/job-notes/job-notes.component.jsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import React from "react";
-import { useTranslation } from "react-i18next";
-import { FlatList, RefreshControl, Text } from "react-native";
-import { Card } from "react-native-paper";
-import JobNotesItem from "../job-notes-item/job-notes-item.component";
-export default function JobNotes({ job, loading, refetch }) {
- const { t } = useTranslation();
- if (!job) {
-
- Job is not defined.
- ;
- }
-
- const onRefresh = async () => {
- return refetch();
- };
-
- if (job.notes.length === 0)
- return (
-
-
- {t("jobdetail.labels.nojobnotes")}
-
-
- );
-
- return (
-
- }
- style={{ flex: 1 }}
- data={job.notes}
- renderItem={(object) => }
- />
- );
-}
diff --git a/components-old/job-space-available/job-space-available.component.jsx b/components-old/job-space-available/job-space-available.component.jsx
deleted file mode 100644
index c3d7d76..0000000
--- a/components-old/job-space-available/job-space-available.component.jsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { useQuery } from "@apollo/client";
-import React from "react";
-import { ProgressBar } from "react-native-paper";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { GET_DOC_SIZE_TOTALS } from "../../graphql/documents.queries";
-import { selectBodyshop } from "../../redux/user/user.selectors";
-import { View, Text } from "react-native";
-import { useTranslation } from "react-i18next";
-import { formatBytes } from "../../util/document-upload.utility";
-const mapStateToProps = createStructuredSelector({
- bodyshop: selectBodyshop,
-});
-const mapDispatchToProps = (dispatch) => ({
- //setUserLanguage: language => dispatch(setUserLanguage(language))
-});
-export default connect(mapStateToProps, mapDispatchToProps)(JobSpaceAvailable);
-
-export function JobSpaceAvailable({ bodyshop, style, jobid }) {
- const { t } = useTranslation();
- const { data } = useQuery(GET_DOC_SIZE_TOTALS, {
- variables: { jobId: jobid },
- skip: !jobid || jobid === "temp",
- });
-
- if (!jobid || !data) return <>>;
-
- const progress =
- data.documents_aggregate.aggregate.sum.size /
- ((bodyshop && bodyshop.jobsizelimit) || 1);
-
- return (
-
-
- {t("mediabrowser.labels.storageused", {
- used: formatBytes(data.documents_aggregate.aggregate.sum.size),
- total: formatBytes((bodyshop && bodyshop.jobsizelimit) || 1),
- percent: Math.round(progress * 100),
- })}
-
-
-
- );
-}
diff --git a/components-old/job-tombstone/job-tombstone.component.jsx b/components-old/job-tombstone/job-tombstone.component.jsx
deleted file mode 100644
index 30f0c37..0000000
--- a/components-old/job-tombstone/job-tombstone.component.jsx
+++ /dev/null
@@ -1,172 +0,0 @@
-import { useTranslation } from "react-i18next";
-import {
- RefreshControl,
- ScrollView,
- StyleSheet,
- Text,
- View,
-} from "react-native";
-import { Card, Headline, Subheading } from "react-native-paper";
-import DataLabelComponent from "../../components/data-label/data-label";
-import StyleRepeater from "../style-repeater/style-repeater";
-import styles from "../styles";
-
-export default function JobTombstone({ job, loading, refetch }) {
- const { t } = useTranslation();
- if (!job) {
-
- Job is not defined.
- ;
- }
- const onRefresh = async () => {
- return refetch();
- };
-
- return (
-
- }
- >
-
-
-
-
- {job.status}
- {job.inproduction && (
- {t("objects.jobs.labels.inproduction")}
- )}
- {job.inproduction &&
- job.production_vars &&
- !!job.production_vars.note && (
- {job.production_vars.note}
- )}
-
-
-
-
-
-
-
-
-
- {`${job.v_model_yr || ""} ${job.v_make_desc || ""} ${
- job.v_model_desc || ""
- }`}
- {job.v_vin}
-
- }
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-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",
- },
-});
diff --git a/components-old/loading-display/loading-display.component.jsx b/components-old/loading-display/loading-display.component.jsx
deleted file mode 100644
index 16a92b0..0000000
--- a/components-old/loading-display/loading-display.component.jsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from "react";
-import { View } from "react-native";
-import { BarIndicator } from "react-native-indicators";
-
-export default function LoadingDisplay({ count = 5 }) {
- //TODO: This is throwing an error per expo, but it appears to be happening inside the component itself.
- return (
-
-
-
- );
-}
diff --git a/components-old/media-cache-overlay/media-cache-overlay.component.jsx b/components-old/media-cache-overlay/media-cache-overlay.component.jsx
deleted file mode 100644
index 99fb6fa..0000000
--- a/components-old/media-cache-overlay/media-cache-overlay.component.jsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { SafeAreaView } from "react-native";
-import React from "react";
-
-import ImageView from "react-native-image-viewing";
-
-export default function MediaCacheOverlay({
- photos,
- previewVisible,
- setPreviewVisible,
- imgIndex,
- setImgIndex,
-}) {
- //const videoRef = React.useRef(null);
-
- return (
-
- setPreviewVisible(false)}
- visible={previewVisible}
- images={photos}
- imageIndex={imgIndex}
- // onImageIndexChange={(...props) => {
- // // console.log(props);
- // }}
- />
-
- );
diff --git a/components-old/screen-camera/screen-camera.jsx b/components-old/screen-camera/screen-camera.jsx
deleted file mode 100644
index b32b40f..0000000
--- a/components-old/screen-camera/screen-camera.jsx
+++ /dev/null
@@ -1,157 +0,0 @@
-// import { useFocusEffect } from "@react-navigation/native";
-// import { Camera } from "expo-camera";
-// import * as FileSystem from "expo-file-system";
-// import React, { useEffect, useRef, useState } from "react";
-// import { Text, View } from "react-native";
-// import { connect } from "react-redux";
-// import { createStructuredSelector } from "reselect";
-// import {
-// selectCurrentCameraJob,
-// selectCurrentCameraJobId,
-// } from "../../redux/app/app.selectors";
-// import { addPhoto } from "../../redux/photos/photos.actions";
-// import CameraControls from "../camera-controls/camera-controls.component";
-// import CameraSelectJob from "../camera-select-job/camera-select-job.component";
-
-// const mapStateToProps = createStructuredSelector({
-// cameraJobId: selectCurrentCameraJobId,
-// cameraJob: selectCurrentCameraJob,
-// });
-// const mapDispatchToProps = (dispatch) => ({
-// addPhoto: (photo) => dispatch(addPhoto(photo)),
-// });
-
-// export function ScreenCamera({ cameraJobId, addPhoto }) {
-// const [hasPermission, setHasPermission] = useState(null);
-// const [state, setState] = useState({
-// flashMode: Camera.Constants.FlashMode.off,
-// capturing: null,
-// cameraType: Camera.Constants.Type.back,
-// tabHasFocus: null,
-// });
-// const cameraRef = useRef(null);
-
-// useFocusEffect(
-// React.useCallback(() => {
-// // Do something when the screen is focused
-// setState({ ...state, tabHasFocus: true });
-// return () => {
-// // Do something when the screen is unfocused
-// // Useful for cleanup functions
-// setState({ ...state, tabHasFocus: false });
-// };
-// }, [])
-// );
-
-// useEffect(() => {
-// (async () => {
-// const { status } = await Camera.requestPermissionsAsync();
-// setHasPermission(status === "granted");
-// })();
-// }, []);
-
-// const setFlashMode = (flashMode) => setState({ ...state, flashMode });
-// const setCameraType = (cameraType) => setState({ ...state, cameraType });
-// const handleCaptureIn = () => setState({ ...state, capturing: true });
-
-// const handleCaptureOut = () => {
-// if (state.capturing) cameraRef.current.stopRecording();
-// };
-
-// const handleShortCapture = async () => {
-// if (cameraRef.current) {
-// const options = {
-// quality: 0.8,
-// //base64: true,
-// skipProcessing: true,
-// };
-
-// let photo = await cameraRef.current.takePictureAsync(options);
-// const filename = photo.uri.substring(photo.uri.lastIndexOf("/") + 1);
-// const newUri = FileSystem.documentDirectory + "photos/" + filename;
-
-// await FileSystem.moveAsync({
-// from: photo.uri,
-// to: newUri,
-// });
-// setState({ ...state, capturing: false });
-// addPhoto({
-// ...photo,
-// id: filename,
-// uri: newUri,
-// jobId: cameraJobId,
-// video: false,
-// });
-// }
-// };
-
-// const handleLongCapture = async () => {
-// console.log("Taking a video!");
-// if (cameraRef.current) {
-// let video = await cameraRef.current.recordAsync();
-
-// const filename = video.uri.substring(video.uri.lastIndexOf("/") + 1);
-// const newUri = FileSystem.documentDirectory + "photos/" + filename;
-
-// await FileSystem.moveAsync({
-// from: video.uri,
-// to: newUri,
-// });
-// setState({ ...state, capturing: false });
-// console.log("Adding Photo", {
-// ...video,
-// id: filename,
-// uri: newUri,
-// jobId: cameraJobId,
-// video: true,
-// });
-// addPhoto({
-// ...video,
-// id: filename,
-// uri: newUri,
-// jobId: cameraJobId,
-// video: true,
-// });
-// }
-// };
-
-// if (hasPermission === null || !state.tabHasFocus) {
-// return ;
-// }
-
-// if (hasPermission === false) {
-// return No access to camera. Please ensure that you allow it.;
-// }
-
-// const { flashMode, cameraType, capturing } = state;
-
-// return (
-//
-//
-//
-
-//
-//
-//
-// );
-// }
-// export default connect(mapStateToProps, mapDispatchToProps)(ScreenCamera);
diff --git a/components-old/screen-job-detail/screen-job-detail.component.jsx b/components-old/screen-job-detail/screen-job-detail.component.jsx
deleted file mode 100644
index 0bde256..0000000
--- a/components-old/screen-job-detail/screen-job-detail.component.jsx
+++ /dev/null
@@ -1,101 +0,0 @@
-import { useQuery } from "@apollo/client";
-import React from "react";
-import { useTranslation } from "react-i18next";
-import { useWindowDimensions } from "react-native";
-import { SceneMap, TabView, TabBar } from "react-native-tab-view";
-import { GET_JOB_BY_PK } from "../../graphql/jobs.queries";
-import ErrorDisplay from "../error-display/error-display.component";
-import JobDocuments from "../job-documents/job-documents.component";
-import JobLines from "../job-lines/job-lines.component";
-import JobNotes from "../job-notes/job-notes.component";
-import JobTombstone from "../job-tombstone/job-tombstone.component";
-import LoadingDisplay from "../loading-display/loading-display.component";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { selectBodyshop } from "../../redux/user/user.selectors";
-import JobDocumentsLocalComponent from "../job-documents/job-documents-local.component";
-const mapStateToProps = createStructuredSelector({
- bodyshop: selectBodyshop,
-});
-const mapDispatchToProps = (dispatch) => ({
- //setUserLanguage: language => dispatch(setUserLanguage(language))
-});
-export default connect(mapStateToProps, mapDispatchToProps)(ScreenJobDetail);
-
-export function ScreenJobDetail({ bodyshop, route }) {
- const {
- params: { jobId },
- } = route;
- const { t } = useTranslation();
- const layout = useWindowDimensions();
- const { loading, error, data, refetch } = useQuery(GET_JOB_BY_PK, {
- variables: {
- id: jobId,
- },
- skip: !jobId,
- });
-
- const renderTabBar = (props) => (
-
- );
-
- const renderScene = SceneMap({
- job: () =>
- JobTombstone({
- job: data.jobs_by_pk,
- loading: loading,
- refetch: refetch,
- }),
- lines: () =>
- JobLines({
- job: data.jobs_by_pk,
- loading: loading,
- refetch: refetch,
- }),
-
- documents: () => {
- return bodyshop.uselocalmediaserver ? (
-
- ) : (
-
- );
- },
-
- notes: () =>
- JobNotes({
- job: data.jobs_by_pk,
- loading: loading,
- refetch: refetch,
- }),
- });
-
- const [index, setIndex] = React.useState(0);
- const [routes] = React.useState([
- { key: "job", title: t("jobdetail.labels.job") },
- { key: "lines", title: t("jobdetail.labels.lines") },
- { key: "documents", title: t("jobdetail.labels.documents") },
- { key: "notes", title: t("jobdetail.labels.notes") },
- ]);
-
- if (loading) return ;
- if (error) return ;
-
- return (
-
- );
-}
diff --git a/components-old/screen-job-list/screen-job-list.component.jsx b/components-old/screen-job-list/screen-job-list.component.jsx
deleted file mode 100644
index ca2fd90..0000000
--- a/components-old/screen-job-list/screen-job-list.component.jsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import React from "react";
-import JobListComponent from "../job-list/job-list.component.jsx";
-
-export default function ScreenJobList({ navigation }) {
- return ;
-}
diff --git a/components-old/screen-main/screen-main.component.jsx b/components-old/screen-main/screen-main.component.jsx
deleted file mode 100644
index eea93f8..0000000
--- a/components-old/screen-main/screen-main.component.jsx
+++ /dev/null
@@ -1,197 +0,0 @@
-import { Ionicons } from "@expo/vector-icons";
-import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
-import { NavigationContainer } from "@react-navigation/native";
-import { createNativeStackNavigator } from "@react-navigation/native-stack";
-import i18n from "i18next";
-import moment from "moment";
-import { useEffect } from "react";
-import { Button } from "react-native-paper";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { logImEXEvent } from "../../firebase/firebase.analytics";
-import { setCameraJob, setCameraJobId } from "../../redux/app/app.actions";
-import {
- checkUserSession,
- emailSignInStart,
- signOutStart,
-} from "../../redux/user/user.actions";
-import {
- selectBodyshop,
- selectCurrentUser,
-} from "../../redux/user/user.selectors";
-import ScreenJobDetail from "../screen-job-detail/screen-job-detail.component";
-import ScreenJobList from "../screen-job-list/screen-job-list.component";
-import ScreenMediaBrowser from "../screen-media-browser/screen-media-browser.component";
-import ScreenSettingsComponent from "../screen-settings/screen-settings.component";
-import ScreenSignIn from "../screen-sign-in/screen-sign-in.component";
-import ScreenSplash from "../screen-splash/screen-splash.component";
-
-const ActiveJobStack = createNativeStackNavigator();
-const MoreStack = createNativeStackNavigator();
-const BottomTabs = createBottomTabNavigator();
-const MediaBrowserStack = createNativeStackNavigator();
-
-const mapStateToProps = createStructuredSelector({
- bodyshop: selectBodyshop,
- currentUser: selectCurrentUser,
-});
-
-const mapDispatchToProps = (dispatch) => ({
- checkUserSession: () => dispatch(checkUserSession()),
- emailSignInStart: (email, password) =>
- dispatch(emailSignInStart({ email, password })),
- signOutStart: () => dispatch(signOutStart()),
- setCameraJobId: (id) => dispatch(setCameraJobId(id)),
- setCameraJob: (job) => dispatch(setCameraJob(job)),
-});
-
-const JobsTabNavigator = connect(
- mapStateToProps,
- mapDispatchToProps
-)(({ setCameraJobId, setCameraJob }) => (
-
- ({
- title: i18n.t("joblist.labels.activejobs"),
- })}
- component={ScreenJobList}
- />
- ({
- title:
- (route.params && route.params.title) ||
- i18n.t("joblist.labels.detail"),
- // eslint-disable-next-line react/display-name
- headerRight: () => (
-
- ),
- })}
- />
-
-));
-
-const MediaBrowserStackNavigator = () => (
-
-
-
-);
-
-const MoreStackNavigator = () => (
-
-
-
-);
-
-const BottomTabsNavigator = () => (
- ({
- // eslint-disable-next-line react/display-name
- tabBarIcon: ({ color, size }) => {
- let iconName;
- if (route.name === "JobTab") {
- iconName = "list";
- } else if (route.name === "MoreTab") {
- iconName = "settings";
- } else if (route.name === "MediaBrowserTab") {
- iconName = "camera";
- } else {
- //iconName = "customerservice";
- }
-
- return ;
- },
- })}
- >
-
-
-
-
-);
-
-export function ScreenMainComponent({
- checkUserSession,
- currentUser,
- bodyshop,
-}) {
- useEffect(() => {
- checkUserSession();
- }, [checkUserSession]);
-
- // useEffect(() => {
- // // LogRocket.init("idt6oy/imex-mobile", {
- // // updateId: Updates.isEmbeddedLaunch ? null : Updates.updateId,
- // // expoChannel: Updates.channel,
- // // });
- // }, []);
-
- return (
-
- {currentUser.authorized === null ? (
-
- ) : currentUser.authorized ? (
- bodyshop ? (
- HasAccess(bodyshop) ? (
-
- ) : (
-
- )
- ) : (
-
- )
- ) : (
-
- )}
-
- );
-}
-export default connect(
- mapStateToProps,
- mapDispatchToProps
-)(ScreenMainComponent);
-
-function HasAccess({ features }) {
- if (features.mobile === undefined || features.mobile === true) return true;
- if (features.mobile === false) return false;
- const d = moment(moment(features.mobile));
- if (d.isValid()) return d.isAfter(moment());
-}
diff --git a/components-old/screen-media-browser/screen-media-browser.component.jsx b/components-old/screen-media-browser/screen-media-browser.component.jsx
deleted file mode 100644
index 4692774..0000000
--- a/components-old/screen-media-browser/screen-media-browser.component.jsx
+++ /dev/null
@@ -1,162 +0,0 @@
-import Constants from "expo-constants";
-import * as ImagePicker from "expo-image-picker";
-import { useCallback, useEffect, useState } from "react";
-import { useTranslation } from "react-i18next";
-import { StyleSheet, Text, View } from "react-native";
-import { Button } from "react-native-paper";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { toggleDeleteAfterUpload } from "../../redux/app/app.actions";
-import {
- selectCurrentCameraJobId,
- selectDeleteAfterUpload,
-} from "../../redux/app/app.selectors";
-import { selectBodyshop } from "../../redux/user/user.selectors";
-import CameraSelectJob from "../camera-select-job/camera-select-job.component";
-import JobSpaceAvailable from "../job-space-available/job-space-available.component";
-import UploadDeleteSwitch from "../upload-delete-switch/upload-delete-switch.component";
-import UploadProgressLocal from "../upload-progress-local/upload-progress-local.component";
-import UploadProgress from "../upload-progress/upload-progress.component";
-
-const mapStateToProps = createStructuredSelector({
- selectedCameraJobId: selectCurrentCameraJobId,
- bodyshop: selectBodyshop,
- deleteAfterUpload: selectDeleteAfterUpload,
-});
-
-const mapDispatchToProps = (dispatch) => ({
- toggleDeleteAfterUpload: () => dispatch(toggleDeleteAfterUpload()),
-});
-
-export function ImageBrowserScreen({
- bodyshop,
- selectedCameraJobId,
- //toggleDeleteAfterUpload,
- // deleteAfterUpload,
-}) {
- const { t } = useTranslation();
- const [uploads, setUploads] = useState(null);
- const [density, setDensity] = useState(3);
- const [tick, setTick] = useState(0);
-
- const forceRerender = useCallback(() => {
- setTick((tick) => tick + 1);
- }, []);
-
- useEffect(() => {
- (async () => {
- if (Constants.platform.ios) {
- const cameraRollStatus =
- await ImagePicker.requestMediaLibraryPermissionsAsync();
- const cameraStatus = await ImagePicker.requestCameraPermissionsAsync();
- if (
- cameraRollStatus.status !== "granted" ||
- cameraStatus.status !== "granted"
- ) {
- alert(
- "Photo and Camera permissions have not been granted. Please open the settings app and allow these permissions to upload photos."
- );
- }
- }
- })();
- }, []);
-
- const pickImage = async () => {
- let result = await ImagePicker.launchImageLibraryAsync({
- mediaTypes: ["images", "videos"],
- aspect: [4, 3],
- quality: 1,
- allowsMultipleSelection: true,
- });
- setUploads(result.assets);
- };
-
- return (
-
-
- {bodyshop.uselocalmediaserver ? (
-
- {t("mediabrowser.labels.localserver", {
- url: bodyshop.localmediaserverhttp,
- })}
-
- ) : (
-
- )}
-
-
- {!selectedCameraJobId && (
-
- {t("mediabrowser.labels.selectjobassetselector")}
-
- )}
-
- {bodyshop.uselocalmediaserver ? (
-
- ) : (
-
- )}
-
- );
-}
-
-const styles = StyleSheet.create({
- flex: {
- flex: 1,
- },
- container: {
- display: "flex",
- // position: "relative",
- },
- buttonStyle: {
- //backgroundColor: "tomato",
- },
- textStyle: {
- color: "dodgerblue",
- },
-});
-
-export default connect(mapStateToProps, mapDispatchToProps)(ImageBrowserScreen);
-
-// // Utility to get asset ID from URI if missing
-// async function getAssetIdFromUri(uri, filename = null, maxPages = 10) {
-// let after = null;
-// let found = null;
-// let pageCount = 0;
-
-// while (!found && pageCount < maxPages) {
-// const page = await MediaLibrary.getAssetsAsync({
-// first: 100,
-// mediaType: [MediaLibrary.MediaType.photo, MediaLibrary.MediaType.video],
-// after,
-// });
-
-// // Try to match by URI
-// found = page.assets.find((asset) => asset.uri === uri);
-
-// // Fallback: try to match by filename if not found and filename is available
-// if (!found && filename) {
-// found = page.assets.find((asset) => asset.filename === filename);
-// }
-
-// after = page.endCursor;
-// pageCount++;
-// if (!after) break;
-// }
-
-// return found ? found.id : null;
-// }
diff --git a/components-old/screen-media-cache/screen-media-cache.component.jsx b/components-old/screen-media-cache/screen-media-cache.component.jsx
deleted file mode 100644
index b4f5f17..0000000
--- a/components-old/screen-media-cache/screen-media-cache.component.jsx
+++ /dev/null
@@ -1,140 +0,0 @@
-import _ from "lodash";
-import React, { useState } from "react";
-import { useTranslation } from "react-i18next";
-import {
- ActivityIndicator,
- FlatList,
- Image,
- SafeAreaView,
- StyleSheet,
- Text,
- TouchableOpacity,
- View,
-} from "react-native";
-import { Button } from "react-native-paper";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import {
- removeAllPhotos,
- uploadAllPhotos,
-} from "../../redux/photos/photos.actions";
-import {
- selectPhotos,
- selectUploadInProgress,
-} from "../../redux/photos/photos.selectors";
-import MediaCacheOverlay from "../media-cache-overlay/media-cache-overlay.component";
-
-const mapStateToProps = createStructuredSelector({
- photos: selectPhotos,
- uploadInProgress: selectUploadInProgress,
-});
-const mapDispatchToProps = (dispatch) => ({
- removeAllPhotos: () => dispatch(removeAllPhotos()),
- uploadAllphotos: () => dispatch(uploadAllPhotos()),
-});
-
-export function ScreenMediaCache({
- photos,
- removeAllPhotos,
- uploadAllphotos,
- uploadInProgress,
-}) {
- const { t } = useTranslation();
- const [previewVisible, setPreviewVisible] = useState(false);
- const [imgIndex, setImgIndex] = useState(0);
-
- const groupedPhotos = _.groupBy(photos, "jobId");
-
- const RenderJobPictures = ({ jobId, jobPhotos }) => (
-
- {jobId}
- item.id}
- numColumns={4}
- renderItem={(object) =>
- object.item.video ? (
- Video
- ) : (
- {
- setImgIndex(object.index);
- setPreviewVisible(true);
- }}
- >
-
-
- )
- }
- />
-
- );
-
- return (
-
-
-
-
-
- item}
- renderItem={(object) => (
-
- )}
- />
-
- {`${photos.length} Photos`}
-
- );
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- actions: {
- display: "flex",
- flexDirection: "row",
- justifyContent: "space-evenly",
- },
- listContentContainer: {
- //flex: 1,
- justifyContent: "flex-start",
- //flexDirection: "row",
- },
-});
-
-export default connect(mapStateToProps, mapDispatchToProps)(ScreenMediaCache);
-
-// item.id}
-// renderItem={(object) => {object.item}}
-// />;
diff --git a/components-old/screen-messaging-conversation/screen-messaging-conversation.component.jsx b/components-old/screen-messaging-conversation/screen-messaging-conversation.component.jsx
deleted file mode 100644
index c881b5d..0000000
--- a/components-old/screen-messaging-conversation/screen-messaging-conversation.component.jsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from "react";
-import { View, Text } from "react-native";
-
-export default function ScreenMessagingConversation({ navigation }) {
- return (
-
-
-
- );
-}
diff --git a/components-old/screen-messaging-list/screen-messaging-list.component.jsx b/components-old/screen-messaging-list/screen-messaging-list.component.jsx
deleted file mode 100644
index 069ff23..0000000
--- a/components-old/screen-messaging-list/screen-messaging-list.component.jsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from "react";
-import { View, Text } from "react-native";
-
-export default function ScreenMessagingList() {
- return (
-
- A list of conversations.
-
- );
-}
diff --git a/components-old/screen-production/screen-production.jsx b/components-old/screen-production/screen-production.jsx
deleted file mode 100644
index e546389..0000000
--- a/components-old/screen-production/screen-production.jsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import React, { useState } from "react";
-import { Text, View, StyleSheet, TouchableOpacity } from "react-native";
-import DraggableFlatList, {
- ScaleDecorator,
- NestableScrollContainer,
- NestableDraggableFlatList,
-} from "react-native-draggable-flatlist";
-
-const NUM_ITEMS = 10;
-function getColor(i) {
- const multiplier = 255 / (NUM_ITEMS - 1);
- const colorVal = i * multiplier;
- return `rgb(${colorVal}, ${Math.abs(128 - colorVal)}, ${255 - colorVal})`;
-}
-
-const initialData = [...Array(NUM_ITEMS)].map((d, index) => {
- const backgroundColor = getColor(index);
- return {
- key: `item-${index}`,
- label: String(index) + "",
- height: 100,
- width: 60 + Math.random() * 40,
- backgroundColor,
- };
-});
-
-const initialData2 = [...Array(NUM_ITEMS)].map((d, index) => {
- const backgroundColor = getColor(index);
- return {
- key: `item-${index}`,
- label: String(index) + "",
- height: 100,
- width: 60 + Math.random() * 40,
- backgroundColor,
- };
-});
-
-export default function App() {
- const [data, setData] = useState(initialData);
- const [data2, setData2] = useState(initialData2);
-
- const renderItem = ({ item, drag, isActive }) => {
- return (
-
-
- {item.label}
-
-
- );
- };
-
- return (
-
- setData(data)}
- keyExtractor={(item) => item.key}
- renderItem={renderItem}
- />
- setData2(data)}
- keyExtractor={(item) => item.key}
- renderItem={renderItem}
- />
-
- );
-}
-
-const styles = StyleSheet.create({
- rowItem: {
- height: 100,
- width: 100,
- alignItems: "center",
- justifyContent: "center",
- },
- text: {
- color: "white",
- fontSize: 24,
- fontWeight: "bold",
- textAlign: "center",
- },
-});
diff --git a/components-old/screen-settings/screen-settings.component.jsx b/components-old/screen-settings/screen-settings.component.jsx
deleted file mode 100644
index 5dc0c84..0000000
--- a/components-old/screen-settings/screen-settings.component.jsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import Constants from "expo-constants";
-import React from "react";
-import { useTranslation } from "react-i18next";
-import { View, Text } from "react-native";
-import { Title, Button } from "react-native-paper";
-import { purgeStoredState } from "redux-persist";
-import SignOutButton from "../sign-out-button/sign-out-button.component";
-import * as Updates from "expo-updates";
-import * as Application from "expo-application";
-
-export default function ScreenSettingsComponent() {
- const { t } = useTranslation();
- return (
-
-
- {t("settings.labels.version", {
- number: `${Constants.expoConfig.version}(${Application.nativeBuildVersion} - ${Constants.expoConfig.extra.expover})`,
- })}
-
-
- Release Channel {Updates.channel}
-
- {/*
- );
-}
diff --git a/components-old/screen-sign-in/screen-sign-in.component.jsx b/components-old/screen-sign-in/screen-sign-in.component.jsx
deleted file mode 100644
index f70bf62..0000000
--- a/components-old/screen-sign-in/screen-sign-in.component.jsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import { Formik } from "formik";
-import React from "react";
-import { useTranslation } from "react-i18next";
-import { Image, StyleSheet, Text, View } from "react-native";
-import { Button, TextInput, Title } from "react-native-paper";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import Logo from "../../assets/logo192.png";
-import { emailSignInStart } from "../../redux/user/user.actions";
-import {
- selectCurrentUser,
- selectSigningIn,
-} from "../../redux/user/user.selectors";
-import SignInErrorAlertComponent from "../sign-in-error-alert/sign-in-error-alert.component";
-import Constants from "expo-constants";
-import * as Updates from "expo-updates";
-
-const mapStateToProps = createStructuredSelector({
- currentUser: selectCurrentUser,
- signingIn: selectSigningIn,
-});
-
-const mapDispatchToProps = (dispatch) => ({
- emailSignInStart: (email, password) =>
- dispatch(emailSignInStart({ email, password })),
-});
-
-export function SignIn({ emailSignInStart, signingIn }) {
- const { t } = useTranslation();
-
- const formSubmit = (values) => {
- const { email, password } = values;
- emailSignInStart(email, password);
- };
-
- return (
-
-
-
- {t("app.title")}
-
-
-
-
- {({ handleChange, handleBlur, handleSubmit, values }) => (
-
-
-
-
-
-
-
-
- )}
-
-
-
- {t("settings.labels.version", {
- number: Constants.expoConfig.version,
- })}
-
-
- );
-}
-
-const localStyles = StyleSheet.create({
- content: {
- display: "flex",
- flex: 1,
- },
- logo: { width: 100, height: 100 },
- input: {
- margin: 12,
- },
-});
-
-export default connect(mapStateToProps, mapDispatchToProps)(SignIn);
diff --git a/components-old/screen-splash/screen-splash.component.jsx b/components-old/screen-splash/screen-splash.component.jsx
deleted file mode 100644
index 0f138d0..0000000
--- a/components-old/screen-splash/screen-splash.component.jsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import React from "react";
-import { useTranslation } from "react-i18next";
-import { ActivityIndicator, Image, StyleSheet, View } from "react-native";
-import { Title, Subheading, Divider } from "react-native-paper";
-import Logo from "../../assets/logo192.png";
-import SignOutButton from "../sign-out-button/sign-out-button.component";
-
-export default function ScreenSplash({ noAccess }) {
- const { t } = useTranslation();
- return (
-
-
-
- {t("app.title")}
-
-
- {noAccess ? (
-
-
- {t("app.nomobileaccess")}
-
-
-
-
- ) : (
-
- )}
-
- );
-}
-const localStyles = StyleSheet.create({
- container: {
- display: "flex",
- flex: 1,
- flexDirection: "column",
- alignContent: "center",
- justifyContent: "center",
- },
- logoContainer: {
- display: "flex",
- flexDirection: "column",
- margin: 10,
- alignItems: "center",
- },
- logo: { width: 175, height: 175, margin: 20 },
-});
diff --git a/components-old/sign-in-error-alert/sign-in-error-alert.component.jsx b/components-old/sign-in-error-alert/sign-in-error-alert.component.jsx
deleted file mode 100644
index ba3fce8..0000000
--- a/components-old/sign-in-error-alert/sign-in-error-alert.component.jsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Title } from "react-native-paper";
-import React, { useEffect, useState } from "react";
-import { useTranslation } from "react-i18next";
-import { StyleSheet, View } from "react-native";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { selectSignInError } from "../../redux/user/user.selectors";
-
-const mapStateToProps = createStructuredSelector({
- signInError: selectSignInError,
-});
-
-export function SignInErrorAlertComponent({ signInError }) {
- const [errorText, setErrorText] = useState("");
- const { t } = useTranslation();
-
- useEffect(() => {
- let text;
- if (signInError && signInError.code)
- switch (signInError.code) {
- case "auth/user-not-found":
- text = t("signin.errors.usernotfound");
- break;
- case "auth/invalid-email":
- text = t("signin.errors.emailformat");
- break;
- case "auth/wrong-password":
- text = t("signin.errors.wrongpassword");
- break;
- default:
- text = signInError.code + " " + signInError.message;
- break;
- }
-
- setErrorText(text);
- }, [signInError, setErrorText]);
- return (
-
- {errorText ? {errorText} : null}
-
- );
-}
-
-export default connect(mapStateToProps, null)(SignInErrorAlertComponent);
-
-const localStyles = StyleSheet.create({
- alert: {
- color: "red",
- textAlign: "center",
- margin: 15,
- padding: 15,
- },
-});
diff --git a/components-old/style-repeater/style-repeater.jsx b/components-old/style-repeater/style-repeater.jsx
deleted file mode 100644
index 0f18ee0..0000000
--- a/components-old/style-repeater/style-repeater.jsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import React from "react";
-
-export default function StyleRepeater({ childStyle, children }) {
- return (
- <>
- {React.Children.map(children, (child) =>
- React.cloneElement(child, {
- style: [child.props.style, childStyle],
- })
- )}
- >
- );
-}
diff --git a/components-old/styles.js b/components-old/styles.js
deleted file mode 100644
index 3ca0bee..0000000
--- a/components-old/styles.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { StyleSheet } from "react-native";
-
-const cardBackgroundColor = "gainsboro";
-
-export default StyleSheet.create({
- cardBackground: {
- padding: 5,
- backgroundColor: cardBackgroundColor,
- display: "flex",
- flex: 1,
- },
-});
diff --git a/components-old/upload-delete-switch/upload-delete-switch.component.jsx b/components-old/upload-delete-switch/upload-delete-switch.component.jsx
deleted file mode 100644
index eb89d22..0000000
--- a/components-old/upload-delete-switch/upload-delete-switch.component.jsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { useTranslation } from "react-i18next";
-import { StyleSheet, Text, View } from "react-native";
-import { Switch } from "react-native-paper";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { toggleDeleteAfterUpload } from "../../redux/app/app.actions";
-import { selectDeleteAfterUpload } from "../../redux/app/app.selectors";
-
-const mapStateToProps = createStructuredSelector({
- deleteAfterUpload: selectDeleteAfterUpload,
-});
-
-const mapDispatchToProps = (dispatch) => ({
- toggleDeleteAfterUpload: () => dispatch(toggleDeleteAfterUpload()),
-});
-
-export function UploadDeleteSwitch({
- deleteAfterUpload,
- toggleDeleteAfterUpload,
-}) {
-
- const { t } = useTranslation();
- return (
-
-
- {t("mediabrowser.labels.deleteafterupload")}
-
- {
- toggleDeleteAfterUpload();
- }}
- value={deleteAfterUpload}
- />
-
- );
-}
-const styles = StyleSheet.create({
- container: {
- display: "flex",
- flexDirection: "row",
- alignItems: "center",
- margin: 10,
- },
-
- text: {
- flex: 1,
- },
-});
-export default connect(mapStateToProps, mapDispatchToProps)(UploadDeleteSwitch);
diff --git a/components-old/upload-progress-local/upload-progress-local.component.jsx b/components-old/upload-progress-local/upload-progress-local.component.jsx
deleted file mode 100644
index f8a959c..0000000
--- a/components-old/upload-progress-local/upload-progress-local.component.jsx
+++ /dev/null
@@ -1,218 +0,0 @@
-import * as MediaLibrary from "expo-media-library";
-import React, { useEffect, useState } from "react";
-
-import {
- ActivityIndicator,
- Alert,
- Modal,
- Platform,
- StyleSheet,
- Text,
- View,
-} from "react-native";
-import { ProgressBar } from "react-native-paper";
-import Toast from "react-native-toast-message";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { logImEXEvent } from "../../firebase/firebase.analytics";
-import {
- selectCurrentCameraJobId,
- selectDeleteAfterUpload,
-} from "../../redux/app/app.selectors";
-import * as Sentry from "@sentry/react-native";
-
-import { formatBytes } from "../../util/document-upload.utility";
-import { handleLocalUpload } from "../../util/local-document-upload.utility";
-
-const mapStateToProps = createStructuredSelector({
- selectedCameraJobId: selectCurrentCameraJobId,
- deleteAfterUpload: selectDeleteAfterUpload,
-});
-
-export default connect(mapStateToProps, null)(UploadProgress);
-
-export function UploadProgress({
- selectedCameraJobId,
- deleteAfterUpload,
- uploads,
- setUploads,
- forceRerender,
-}) {
- const [progress, setProgress] = useState({
- loading: false,
- uploadInProgress: false,
- speed: 0,
- });
-
- useEffect(() => {
- //Set the state of uploads to do.
- if (uploads) {
- beginUploads(uploads);
- setUploads(null);
- }
- }, [uploads]);
-
- async function handleOnSuccess({ duration, data }) {
- //If it's not in production, show a toast with the time.
- Toast.show({
- type: "success",
- text1: ` Upload completed in ${duration}.`,
- //
- // text2: duration,
- });
- if (deleteAfterUpload) {
- try {
- if (Platform.OS === "android") {
- //Create a new asset with the first file to delete.
- // console.log('Trying new delete.');
- await MediaLibrary.getPermissionsAsync(false);
-
- const album = await MediaLibrary.createAlbumAsync(
- "ImEX Mobile Deleted",
- data.pop(),
- false
- );
- //Move the rest.
- if (data.length > 0) {
- const moveResult = await MediaLibrary.addAssetsToAlbumAsync(
- data,
- album,
- false
- );
- }
- const deleteResult = await MediaLibrary.deleteAlbumsAsync(album);
-
- //Delete the album.
-
- //This defaults to delete all assets in the album.
- } else {
- await MediaLibrary.deleteAssetsAsync(data.map((f) => f.id));
- }
- } catch (error) {
- console.log("Unable to delete picture.", error);
- Sentry.captureException(error);
- }
- }
-
- logImEXEvent("imexmobile_successful_upload");
- forceRerender();
- setProgress({ ...progress, speed: 0, percent: 1, uploadInProgress: false });
- }
-
- function handleOnProgress({ percent, loaded }) {
- setProgress((progress) => ({
- ...progress,
- speed: loaded - progress.loaded,
- loaded: loaded,
- percent,
- }));
- }
-
- function handleOnError({ assetid, error }) {
- logImEXEvent("imexmobile_upload_documents_error");
- Toast.show({
- type: "error",
- text1: "Unable to upload documents.",
- text2: error,
- autoHide: false,
- });
- setProgress({
- speed: 0,
- percent: 1,
- uploadInProgress: false,
- });
- }
-
- const beginUploads = async (data) => {
- //Validate to make sure the totals for the file sizes do not exceed the total on the job.
- setProgress({
- percent: 0,
- loaded: 0,
- uploadInProgress: true,
- start: new Date(),
- average: 0,
- });
-
- await handleLocalUpload({
- files: data,
- onError: ({ assetid, error }) => handleOnError({ assetid, error }),
- onProgress: ({ percent, loaded }) =>
- handleOnProgress({ percent, loaded }),
- onSuccess: ({ duration }) => handleOnSuccess({ duration, data }),
- context: {
- jobid:
- selectedCameraJobId !== "temp" ? selectedCameraJobId : "temporary",
- },
- });
- };
-
- return (
- {
- Alert.alert("Cancel?", "Do you want to abort the upload?", [
- {
- text: "Yes",
- onPress: () => {
- setUploads(null);
- setProgress(null);
- },
- },
- { text: "No" },
- ]);
- }}
- >
-
-
-
-
- {`${formatBytes(
- progress.speed
- )}/sec`}
- {`Avg. ${formatBytes(
- progress.loaded / ((new Date() - progress.start) / 1000)
- )}/sec`}
- {`Total Uploaded ${formatBytes(progress.loaded)}`}
- {`Duration ${(
- (new Date() - progress.start) /
- 1000
- ).toFixed(1)} sec`}
-
-
-
- );
-}
-const styles = StyleSheet.create({
- modalContainer: {
- display: "flex",
- flex: 1,
- justifyContent: "center",
- },
- modal: {
- // flex: 1,
- display: "flex",
- marginLeft: 20,
- marginRight: 20,
- backgroundColor: "white",
- borderRadius: 20,
- padding: 18,
- shadowColor: "#000",
- shadowOffset: {
- width: 0,
- height: 2,
- },
- shadowOpacity: 0.25,
- shadowRadius: 4,
- elevation: 5,
- },
-});
diff --git a/components-old/upload-progress/upload-progress.component.jsx b/components-old/upload-progress/upload-progress.component.jsx
deleted file mode 100644
index d0388ae..0000000
--- a/components-old/upload-progress/upload-progress.component.jsx
+++ /dev/null
@@ -1,426 +0,0 @@
-import { useApolloClient } from "@apollo/client";
-import { File } from "expo-file-system";
-import * as MediaLibrary from "expo-media-library";
-import React, { useEffect, useState } from "react";
-import { useTranslation } from "react-i18next";
-import {
- ActivityIndicator,
- Alert,
- Modal,
- Platform,
- StyleSheet,
- Text,
- View,
-} from "react-native";
-import { Divider, ProgressBar } from "react-native-paper";
-import Toast from "react-native-toast-message";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import * as Sentry from "@sentry/react-native";
-import { logImEXEvent } from "../../firebase/firebase.analytics";
-import { GET_DOC_SIZE_TOTALS } from "../../graphql/documents.queries";
-import {
- selectCurrentCameraJobId,
- selectDeleteAfterUpload,
-} from "../../redux/app/app.selectors";
-import {
- selectBodyshop,
- selectCurrentUser,
-} from "../../redux/user/user.selectors";
-import { formatBytes, handleUpload } from "../../util/document-upload.utility";
-
-const mapStateToProps = createStructuredSelector({
- currentUser: selectCurrentUser,
- bodyshop: selectBodyshop,
- selectedCameraJobId: selectCurrentCameraJobId,
- deleteAfterUpload: selectDeleteAfterUpload,
-});
-
-export default connect(mapStateToProps, null)(UploadProgress);
-
-export function UploadProgress({
- currentUser,
- bodyshop,
- selectedCameraJobId,
- deleteAfterUpload,
- uploads,
- setUploads,
- forceRerender,
-}) {
- const [progress, setProgress] = useState({
- uploadInProgress: false,
- totalToUpload: 0,
- totalUploaded: 0,
- startTime: null,
- totalFiles: 0,
- totalFilesCompleted: 0,
- currentFile: null,
- files: {}, //uri is the key, value is progress
- });
-
- let filesToDelete = [];
- const client = useApolloClient();
-
- const { t } = useTranslation();
-
- useEffect(() => {
- if (uploads) {
- onDone(uploads);
- setUploads(null);
- }
- }, [uploads]);
-
- function handleOnSuccess(asset) {
- //NEEDS REDO.
- filesToDelete.push(asset);
- setProgress((progress) => ({
- ...progress,
- // totalUploaded: progress.totalToUpload + asset.size,
- totalFilesCompleted: progress.totalFilesCompleted + 1,
- files: {
- ...progress.files,
- [asset.uri]: {
- ...progress.files[asset.uri],
- uploadEnd: new Date(),
- },
- },
- }));
- }
-
- function handleOnProgress({ uri, filename }, percent, loaded) {
- //NEED REDO
- setProgress((progress) => {
- return {
- ...progress,
- totalUploaded:
- progress.totalUploaded +
- (loaded - (progress.files[uri]?.loaded || 0)),
- files: {
- ...progress.files,
- [uri]: {
- ...progress.files[uri],
- percent,
- filename,
- speed: loaded - (progress.files[uri]?.loaded || 0),
- loaded: loaded,
- uploadStart: progress.files[uri]?.uploadStart || new Date(),
- },
- },
- };
- });
- }
- function handleOnError(error) {
- logImEXEvent("imexmobile_upload_documents_error", { error });
- Toast.show({
- type: "error",
- text1: "Unable to upload document.",
- text2: error,
- autoHide: false,
- });
- }
-
- const onDone = async (selectedFiles) => {
- setProgress((progress) => {
- return {
- ...progress,
- uploadInProgress: true,
- statusText: "Preparing upload...",
- };
- });
- try {
- //Validate to make sure the totals for the file sizes do not exceed the total on the job.
- const data = [];
- const totalOfUploads = await selectedFiles.reduce(async (acc, val) => {
- //Get the size of the file based on URI.
- if (acc.fileSize) {
- return acc + acc.fileSize;
- } else {
- const info = new File(val.uri).size;
- data.push({ ...info, ...val }); //Add in the size.
- val.albumId && MediaLibrary.migrateAlbumIfNeededAsync(val.albumId);
- return (await acc) + info.size;
- }
- }, 0);
-
- if (selectedCameraJobId !== "temp") {
- const queryData = await client.query({
- query: GET_DOC_SIZE_TOTALS,
- fetchPolicy: "network-only",
- variables: {
- jobId: selectedCameraJobId,
- },
- });
-
- if (
- bodyshop.jobsizelimit -
- queryData.data.documents_aggregate.aggregate.sum.size <=
- totalOfUploads
- ) {
- //No more room... abandon ship.
- setProgress((progress) => ({
- ...progress,
- speed: 0,
- action: null,
- statusText: null,
- uploadInProgress: false,
- }));
- Alert.alert(
- t("mediabrowser.labels.storageexceeded_title"),
- t("mediabrowser.labels.storageexceeded")
- );
- return;
- }
- //We made it this far. We have enough space, so let's start uploading.
- setProgress((progress) => ({
- ...progress,
- totalToUpload: totalOfUploads,
- totalUploaded: 0,
- totalFilesCompleted: 0,
- startTime: new Date(),
- totalFiles: data.length,
- currentFile: null,
- statusText: null,
- files: {}, //uri is the key, value is progress
- }));
- }
-
- for (var i = 0; i < data.length + 4; i = i + 4) {
- //Reset the files.
- setProgress((progress) => ({ ...progress, files: {} }));
- let proms = [];
- if (data[i]) {
- proms.push(CreateUploadProm(data[i]));
- }
- if (data[i + 1]) {
- proms.push(CreateUploadProm(data[i + 1]));
- }
- if (data[i + 2]) {
- proms.push(CreateUploadProm(data[i + 2]));
- }
- if (data[i + 3]) {
- proms.push(CreateUploadProm(data[i + 3]));
- }
-
- await Promise.all(proms);
- }
- } catch (error) {
- console.log("Error during upload.", error, error.stack);
- Sentry.captureException(error);
- setProgress((progress) => ({
- ...progress,
- speed: 0,
- action: null,
- statusText: null,
- uploadInProgress: false,
- }));
- Alert.alert(
- t("mediabrowser.labels.uploaderror_title"),
- t("mediabrowser.labels.uploaderror")
- );
- return;
- }
-
- //Everything is uploaded, delete the succesful ones.
- if (deleteAfterUpload) {
- try {
- if (Platform.OS === "android") {
- //Create a new asset with the first file to delete.
- // console.log('Trying new delete.');
- await MediaLibrary.getPermissionsAsync(false);
-
- const album = await MediaLibrary.createAlbumAsync(
- "ImEX Mobile Deleted",
- filesToDelete.pop(),
- false
- );
- //Move the rest.
- if (filesToDelete.length > 0) {
- const moveResult = await MediaLibrary.addAssetsToAlbumAsync(
- filesToDelete,
- album,
- false
- );
- }
- const deleteResult = await MediaLibrary.deleteAlbumsAsync(album);
-
- //Delete the album.
-
- //This defaults to delete all assets in the album.
- } else {
- await MediaLibrary.deleteAssetsAsync(filesToDelete.map((f) => f.id));
- }
- } catch (error) {
- console.log("Unable to delete picture.", error);
- Sentry.captureException(error);
- }
- }
- filesToDelete = [];
- Toast.show({
- type: "success",
- text1: ` Upload completed.`,
- //
- // text2: duration,
- });
- //Reset state.
-
- setProgress({
- uploadInProgress: false,
- totalToUpload: 0,
- totalUploaded: 0,
- totalFilesCompleted: 0,
- startTime: null,
- totalFiles: 0,
- currentFile: null,
- files: {},
- });
-
- forceRerender();
- };
-
- const CreateUploadProm = async (p) => {
- return handleUpload(
- {
- mediaId: p.id,
- onError: handleOnError,
- onProgress: ({ percent, loaded }) =>
- handleOnProgress(p, percent, loaded),
- onSuccess: () => handleOnSuccess(p),
- },
- {
- bodyshop: bodyshop,
- jobId: selectedCameraJobId !== "temp" ? selectedCameraJobId : null,
- uploaded_by: currentUser.email,
- photo: p,
- }
- );
- };
-
- return (
- {
- Alert.alert("Cancel?", "Do you want to abort the upload?", [
- {
- text: "Yes",
- onPress: () => {
- setUploads(null);
- setProgress({
- uploadInProgress: false,
- totalToUpload: 0,
- totalUploaded: 0,
- totalFilesCompleted: 0,
- startTime: null,
- totalFiles: 0,
- currentFile: null,
- files: {},
- });
- },
- },
- { text: "No" },
- ]);
- }}
- >
-
-
- {Object.keys(progress.files).map((key) => (
-
-
- {progress.files[key].filename}
-
-
-
-
- {`${formatBytes(
- progress.files[key].loaded /
- (((progress.files[key].uploadEnd || new Date()) -
- progress.files[key].uploadStart) /
- 1000)
- )}/sec`}
- {progress.files[key].percent === 1 && (
- <>
-
- Processing...
- >
- )}
-
-
-
- ))}
-
- {progress.statusText ? (
- <>
-
- {progress.statusText}
-
- >
- ) : (
- <>
- {`${progress.totalFilesCompleted} of ${progress.totalFiles} uploaded.`}
- {`${formatBytes(progress.totalUploaded)} of ${formatBytes(
- progress.totalToUpload
- )} uploaded.`}
- >
- )}
-
-
-
-
- );
-}
-const styles = StyleSheet.create({
- modalContainer: {
- display: "flex",
- flex: 1,
- justifyContent: "center",
- },
- modal: {
- //flex: 1,
- display: "flex",
- marginLeft: 20,
- marginRight: 20,
- backgroundColor: "white",
- borderRadius: 20,
- padding: 18,
- shadowColor: "#000",
- shadowOffset: {
- width: 0,
- height: 2,
- },
- shadowOpacity: 0.25,
- shadowRadius: 4,
- elevation: 5,
- },
- centeredView: {
- justifyContent: "center",
- alignItems: "center",
- marginTop: 22,
- },
- progressItem: {
- display: "flex",
- flexDirection: "row",
- alignItems: "center",
- marginBottom: 12,
- marginLeft: 12,
- marginRight: 12,
- },
- progressText: {
- flex: 1,
- },
- progressBarContainer: {
- flex: 3,
- marginLeft: 12,
- marginRight: 12,
- },
-});
diff --git a/components/global-search/global-search.jsx b/components/global-search/global-search.jsx
index 192bee3..645d520 100644
--- a/components/global-search/global-search.jsx
+++ b/components/global-search/global-search.jsx
@@ -47,8 +47,6 @@ export default function GlobalSearch() {
if (!q) return;
setLoading(true);
setError(null);
- // TODO: Integrate real search endpoint
- console.log(`[GlobalSearch] (debounced placeholder) searching for: "${q}"`);
try {
const searchData = await axios.post(`${env.API_URL}/search`, {
search: q,
diff --git a/components/job-documents/job-documents.jsx b/components/job-documents/job-documents.jsx
index ced9544..2ef7558 100644
--- a/components/job-documents/job-documents.jsx
+++ b/components/job-documents/job-documents.jsx
@@ -105,11 +105,6 @@ export function JobDocumentsComponent({ bodyshop }) {
setFullPhotos(normalizedImages);
}
} catch (error) {
- console.log(
- "Error fetching photos:",
- error.message,
- JSON.stringify(error, null, 2)
- );
setError(error.message || "Unknown error fetching photos.");
}
setLoading(false);
diff --git a/components/settings/settings.jsx b/components/settings/settings.jsx
index c37553c..0c0d3ce 100644
--- a/components/settings/settings.jsx
+++ b/components/settings/settings.jsx
@@ -144,7 +144,11 @@ function Tab({ bodyshop, currentUser, signOutStart }) {
"Error",
`Unable to register for notifications: ${error.message}`
);
- console.log("Notification registration error:", error);
+ console.log(
+ "Notification registration error:",
+ error,
+ error.stack
+ );
}
}}
>
@@ -161,7 +165,9 @@ function Tab({ bodyshop, currentUser, signOutStart }) {
}`}
- {`${t("settings.labels.signedinuser")} ${currentUser?.email || "Unknown"}`}
+ {`${t("settings.labels.signedinuser")} ${
+ currentUser?.email || "Unknown"
+ }`}
diff --git a/constants/theme.ts b/constants/theme.ts
deleted file mode 100644
index f06facd..0000000
--- a/constants/theme.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Below are the colors that are used in the app. The colors are defined in the light and dark mode.
- * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
- */
-
-import { Platform } from 'react-native';
-
-const tintColorLight = '#0a7ea4';
-const tintColorDark = '#fff';
-
-export const Colors = {
- light: {
- text: '#11181C',
- background: '#fff',
- tint: tintColorLight,
- icon: '#687076',
- tabIconDefault: '#687076',
- tabIconSelected: tintColorLight,
- },
- dark: {
- text: '#ECEDEE',
- background: '#151718',
- tint: tintColorDark,
- icon: '#9BA1A6',
- tabIconDefault: '#9BA1A6',
- tabIconSelected: tintColorDark,
- },
-};
-
-export const Fonts = Platform.select({
- ios: {
- /** iOS `UIFontDescriptorSystemDesignDefault` */
- sans: 'system-ui',
- /** iOS `UIFontDescriptorSystemDesignSerif` */
- serif: 'ui-serif',
- /** iOS `UIFontDescriptorSystemDesignRounded` */
- rounded: 'ui-rounded',
- /** iOS `UIFontDescriptorSystemDesignMonospaced` */
- mono: 'ui-monospace',
- },
- default: {
- sans: 'normal',
- serif: 'serif',
- rounded: 'normal',
- mono: 'monospace',
- },
- web: {
- sans: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
- serif: "Georgia, 'Times New Roman', serif",
- rounded: "'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Meiryo, 'MS PGothic', sans-serif",
- mono: "SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
- },
-});
diff --git a/env.js b/env.js
index 782c392..5abd1e0 100644
--- a/env.js
+++ b/env.js
@@ -64,11 +64,9 @@ const ENV = {
}
};
const IS_ROME = Constants?.expoConfig?.extra?.appVariant === 'ROME';
-//console.log("*** ~ Constants?.expoConfig?.extra:", Constants?.expoConfig);
function getEnvVars() {
if (Updates.channel !== "production") return IS_ROME ? ENV.rometest : ENV.test;
else return IS_ROME ? ENV.romeprod : ENV.prod;
}
-console.log('APP_VARIANT:', Constants?.expoConfig?.extra?.appVariant, 'IS_ROME:', IS_ROME, "ENV: ", getEnvVars());
export default getEnvVars();
diff --git a/graphql/client.js b/graphql/client.js
index 1c31d3c..dc547b6 100644
--- a/graphql/client.js
+++ b/graphql/client.js
@@ -25,34 +25,14 @@ const errorLink = onError(
}
);
-const subscriptionMiddleware = {
- applyMiddleware: async (options, next) => {
- options.authToken =
- auth.currentUser && (await auth.currentUser.getIdToken(true));
- next();
- },
-};
-//wsLink.subscriptionClient.use([subscriptionMiddleware]);
-
-// const link = split(
-// // split based on operation type
-// ({ query }) => {
-// const definition = getMainDefinition(query);
-// // console.log(
-// // "##Intercepted GQL Transaction : " +
-// // definition.operation +
-// // "|" +
-// // // definition.name.value +
-// // "##"
-// // );
-// return (
-// definition.kind === "OperationDefinition" &&
-// definition.operation === "subscription"
-// );
+// const subscriptionMiddleware = {
+// applyMiddleware: async (options, next) => {
+// options.authToken =
+// auth.currentUser && (await auth.currentUser.getIdToken(true));
+// next();
// },
-// wsLink,
-// httpLink
-// );
+// };
+
const authLink = setContext((_, { headers }) => {
return (
@@ -84,7 +64,7 @@ const retryLink = new RetryLink({
},
});
-const cache = new InMemoryCache({});
+const cache = new InMemoryCache();
export const client = new ApolloClient({
//link: ApolloLink.from(middlewares),
diff --git a/package-lock.json b/package-lock.json
index 2ade863..34ac00f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,7 +8,7 @@
"name": "imexmobile",
"version": "1.0.0",
"dependencies": {
- "@apollo/client": "^3.12.11",
+ "@apollo/client": "^3.14.0",
"@expo/vector-icons": "^15.0.2",
"@react-native-async-storage/async-storage": "2.2.0",
"@react-native-vector-icons/material-design-icons": "^12.3.0",
@@ -57,6 +57,7 @@
"react-native-image-viewing": "^0.2.2",
"react-native-paper": "^5.14.5",
"react-native-reanimated": "~4.1.3",
+ "react-native-reanimated-dnd": "^1.1.0",
"react-native-safe-area-context": "~5.6.1",
"react-native-screens": "~4.17.1",
"react-native-tab-view": "4.1.3",
@@ -2792,9 +2793,9 @@
"license": "MIT"
},
"node_modules/@expo/vector-icons": {
- "version": "15.0.2",
- "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.2.tgz",
- "integrity": "sha512-IiBjg7ZikueuHNf40wSGCf0zS73a3guJLdZzKnDUxsauB8VWPLMeWnRIupc+7cFhLUkqyvyo0jLNlcxG5xPOuQ==",
+ "version": "15.0.3",
+ "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.3.tgz",
+ "integrity": "sha512-SBUyYKphmlfUBqxSfDdJ3jAdEVSALS2VUPOUyqn48oZmb2TL/O7t7/PQm5v4NQujYEPLPMTLn9KVw6H7twwbTA==",
"license": "MIT",
"peerDependencies": {
"expo-font": ">=14.0.4",
@@ -13285,6 +13286,18 @@
"react-native-worklets": ">=0.5.0"
}
},
+ "node_modules/react-native-reanimated-dnd": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/react-native-reanimated-dnd/-/react-native-reanimated-dnd-1.1.0.tgz",
+ "integrity": "sha512-9ZgdAFsw2rjB/0VE3wsR9+PnBOWIoO+1s6lEiyV51ptBcoz0NaUnUb8aqGocEztnXSbySSznpOh5vy6Ijo9A3Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-native": ">=0.60.0",
+ "react-native-gesture-handler": ">=2.0.0",
+ "react-native-reanimated": ">=3.0.0"
+ }
+ },
"node_modules/react-native-reanimated/node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
diff --git a/package.json b/package.json
index 559d0a6..a2a5045 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"lint": "expo lint"
},
"dependencies": {
- "@apollo/client": "^3.12.11",
+ "@apollo/client": "^3.14.0",
"@expo/vector-icons": "^15.0.2",
"@react-native-async-storage/async-storage": "2.2.0",
"@react-native-vector-icons/material-design-icons": "^12.3.0",
@@ -72,6 +72,7 @@
"react-native-image-viewing": "^0.2.2",
"react-native-paper": "^5.14.5",
"react-native-reanimated": "~4.1.3",
+ "react-native-reanimated-dnd": "^1.1.0",
"react-native-safe-area-context": "~5.6.1",
"react-native-screens": "~4.17.1",
"react-native-tab-view": "4.1.3",
diff --git a/redux/photos/photos.sagas.js b/redux/photos/photos.sagas.js
index c199db5..b90e9ea 100644
--- a/redux/photos/photos.sagas.js
+++ b/redux/photos/photos.sagas.js
@@ -83,7 +83,7 @@ export function* openImagePickerAction({ payload: jobid }) {
yield put(mediaUploadStart({ photos: result.assets, jobid }));
}
} catch (error) {
- console.log("Saga Error: open Picker", error);
+ // console.log("Saga Error: open Picker", error);
}
}
@@ -93,8 +93,6 @@ export function* onMediaUploadStart() {
export function* mediaUploadStartAction({ payload: { photos, jobid } }) {
try {
- console.log("Starting upload for", photos.length, "photos");
-
const bodyshop = yield select(selectBodyshop);
if (bodyshop.uselocalmediaserver) {
@@ -130,7 +128,7 @@ export function* mediaUploadStartAction({ payload: { photos, jobid } }) {
yield delay(100);
}
}
- console.log("All uploads completed. This shouldn't fire before the uploads are done.");
+
yield put(mediaUploadCompleted(photos));
} catch (error) {