Refactor to using RNP & UI Updates.
This commit is contained in:
16
App.js
16
App.js
@@ -26,29 +26,17 @@ const theme = {
|
|||||||
...DefaultTheme,
|
...DefaultTheme,
|
||||||
colors: {
|
colors: {
|
||||||
...DefaultTheme.colors,
|
...DefaultTheme.colors,
|
||||||
primary: "tomato",
|
primary: "dodgerblue",
|
||||||
accent: "yellow",
|
accent: "tomato",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class App extends React.Component {
|
export default class App extends React.Component {
|
||||||
// constructor(props) {
|
|
||||||
// super(props);
|
|
||||||
// this.state = {
|
|
||||||
// isReady: false,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
logImEXEvent("imexmobile_app_start");
|
logImEXEvent("imexmobile_app_start");
|
||||||
//this.setState({ isReady: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// if (!this.state.isReady) {
|
|
||||||
// return <AppLoading />;
|
|
||||||
// }
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<PersistGate persistor={persistor}>
|
<PersistGate persistor={persistor}>
|
||||||
|
|||||||
@@ -162,6 +162,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>dates</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>documents</name>
|
<name>documents</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -225,6 +246,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>jobinfo</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>lines</name>
|
<name>lines</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -246,6 +288,132 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>lines_desc</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>lines_lb_hrs</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>lines_lbr_ty</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>lines_part_type</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>lines_price</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>lines_qty</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>nojobnotes</name>
|
<name>nojobnotes</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { useQuery } from "@apollo/client";
|
import { useQuery } from "@apollo/client";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FlatList, RefreshControl } from "react-native";
|
import { FlatList, RefreshControl, View } from "react-native";
|
||||||
import { Button, List, Modal, Portal, Provider } from "react-native-paper";
|
import { Button, List, Modal, Portal, Searchbar } from "react-native-paper";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { QUERY_ALL_ACTIVE_JOBS } from "../../graphql/jobs.queries";
|
import { QUERY_ALL_ACTIVE_JOBS } from "../../graphql/jobs.queries";
|
||||||
@@ -47,23 +48,80 @@ export function CameraSelectJob({
|
|||||||
|
|
||||||
const showModal = () => setVisible(true);
|
const showModal = () => setVisible(true);
|
||||||
const hideModal = () => setVisible(false);
|
const hideModal = () => setVisible(false);
|
||||||
const containerStyle = { backgroundColor: "white", padding: 20 };
|
|
||||||
const onRefresh = async () => {
|
const onRefresh = async () => {
|
||||||
return refetch();
|
return refetch();
|
||||||
};
|
};
|
||||||
|
const [searchQuery, setSearchQuery] = React.useState("");
|
||||||
|
|
||||||
|
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 (
|
return (
|
||||||
<Provider>
|
<>
|
||||||
<Portal>
|
<Portal>
|
||||||
<Modal
|
<Modal
|
||||||
visible={visible}
|
visible={visible}
|
||||||
onDismiss={hideModal}
|
onDismiss={hideModal}
|
||||||
contentContainerStyle={containerStyle}
|
// eslint-disable-next-line react-native/no-color-literals
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: 20,
|
||||||
|
paddingBottom: 20,
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "white",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
margin: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button onPress={() => hideModal()}>
|
||||||
|
<Ionicons name="ios-arrow-back" size={32} color="dodgerblue" />
|
||||||
|
</Button>
|
||||||
|
<Searchbar
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
onChangeText={onChangeSearch}
|
||||||
|
value={searchQuery}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
<FlatList
|
<FlatList
|
||||||
refreshControl={
|
refreshControl={
|
||||||
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
||||||
}
|
}
|
||||||
data={data.jobs}
|
data={[{ id: "temp", ro_number: "Temporary Storage" }, ...jobs]}
|
||||||
keyExtractor={(item) => item.id}
|
keyExtractor={(item) => item.id}
|
||||||
renderItem={(object) => (
|
renderItem={(object) => (
|
||||||
<List.Item
|
<List.Item
|
||||||
@@ -71,8 +129,25 @@ export function CameraSelectJob({
|
|||||||
setCameraJobId(object.item.id);
|
setCameraJobId(object.item.id);
|
||||||
setCameraJob(object.item);
|
setCameraJob(object.item);
|
||||||
hideModal();
|
hideModal();
|
||||||
|
setSearchQuery("");
|
||||||
}}
|
}}
|
||||||
description={`${
|
left={() => {
|
||||||
|
if (object.item.id !== cameraJobId) return null;
|
||||||
|
return (
|
||||||
|
<Ionicons
|
||||||
|
name="ios-checkmark-circle"
|
||||||
|
size={24}
|
||||||
|
color="dodgerblue"
|
||||||
|
style={{ alignSelf: "center" }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
titleStyle={{
|
||||||
|
...(object.item.id === cameraJobId
|
||||||
|
? { color: "dodgerblue" }
|
||||||
|
: {}),
|
||||||
|
}}
|
||||||
|
title={`${
|
||||||
object.item.ro_number ? `${object.item.ro_number} - ` : ``
|
object.item.ro_number ? `${object.item.ro_number} - ` : ``
|
||||||
}${object.item.ownr_fn || ""} ${object.item.ownr_ln || ""} ${
|
}${object.item.ownr_fn || ""} ${object.item.ownr_ln || ""} ${
|
||||||
object.item.ownr_co_nm || ""
|
object.item.ownr_co_nm || ""
|
||||||
@@ -85,41 +160,19 @@ export function CameraSelectJob({
|
|||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
</Portal>
|
</Portal>
|
||||||
<Button style={{ marginTop: 30 }} onPress={showModal}>
|
<Button mode="outlined" style={{ margin: 8 }} onPress={showModal}>
|
||||||
{cameraJobId
|
{cameraJobId
|
||||||
? `${cameraJob.ro_number ? `${cameraJob.ro_number} - ` : ``}${
|
? cameraJobId === "temp"
|
||||||
cameraJob.ownr_fn || ""
|
? t("mediabrowser.labels.temporarystorage")
|
||||||
} ${cameraJob.ownr_ln || ""} ${cameraJob.ownr_co_nm || ""} - ${
|
: `${cameraJob.ro_number ? `${cameraJob.ro_number} - ` : ``}${
|
||||||
cameraJob.v_model_yr || ""
|
cameraJob.ownr_fn || ""
|
||||||
} ${cameraJob.v_make_desc || ""} ${cameraJob.v_model_desc || ""}`
|
} ${cameraJob.ownr_ln || ""} ${cameraJob.ownr_co_nm || ""} - ${
|
||||||
|
cameraJob.v_model_yr || ""
|
||||||
|
} ${cameraJob.v_make_desc || ""} ${cameraJob.v_model_desc || ""}`
|
||||||
: t("mediabrowser.labels.selectjob")}
|
: t("mediabrowser.labels.selectjob")}
|
||||||
</Button>
|
</Button>
|
||||||
</Provider>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
// return (
|
|
||||||
// <View
|
|
||||||
// style={{
|
|
||||||
// marginHorizontal: 10,
|
|
||||||
// }}
|
|
||||||
// >
|
|
||||||
// <Picker
|
|
||||||
// selectedValue={cameraJobId}
|
|
||||||
// onValueChange={(value, idx) => {
|
|
||||||
// logImEXEvent("imexmobile_setcamerajobid");
|
|
||||||
// setCameraJobId(value);
|
|
||||||
// setCameraJob(data.jobs[idx]);
|
|
||||||
// }}
|
|
||||||
// >
|
|
||||||
// <Picker.Item
|
|
||||||
// label={t("mediabrowser.labels.selectjob")}
|
|
||||||
// value={null}
|
|
||||||
// key="null"
|
|
||||||
// />
|
|
||||||
|
|
||||||
// </Picker>
|
|
||||||
// </View>
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(CameraSelectJob);
|
export default connect(mapStateToProps, mapDispatchToProps)(CameraSelectJob);
|
||||||
|
|||||||
@@ -1,55 +1,78 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState, useMemo } from "react";
|
||||||
import {
|
import {
|
||||||
FlatList,
|
FlatList,
|
||||||
Image,
|
Image,
|
||||||
RefreshControl,
|
RefreshControl,
|
||||||
StyleSheet,
|
|
||||||
Text,
|
Text,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
View,
|
View,
|
||||||
} from "react-native";
|
} 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 MediaCacheOverlay from "../media-cache-overlay/media-cache-overlay.component";
|
||||||
|
|
||||||
const REACT_APP_CLOUDINARY_IMAGE_ENDPOINT =
|
|
||||||
"https://res.cloudinary.com/bodyshop/image/upload";
|
|
||||||
const REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS = "c_fill,f_auto,h_250,w_250";
|
|
||||||
|
|
||||||
export default function JobDocumentsComponent({ job, loading, refetch }) {
|
export default function JobDocumentsComponent({ job, loading, refetch }) {
|
||||||
const [previewVisible, setPreviewVisible] = useState(false);
|
const [previewVisible, setPreviewVisible] = useState(false);
|
||||||
const [imgIndex, setImgIndex] = useState(0);
|
const [imgIndex, setImgIndex] = useState(0);
|
||||||
const onRefresh = async () => {
|
const onRefresh = async () => {
|
||||||
return refetch();
|
return refetch();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fullphotos = useMemo(
|
||||||
|
() =>
|
||||||
|
job.documents.map((doc) => {
|
||||||
|
return {
|
||||||
|
source: {
|
||||||
|
uri: `${env.REACT_APP_CLOUDINARY_ENDPOINT}/${DetermineFileType(
|
||||||
|
doc.type
|
||||||
|
)}/upload/${doc.key}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
[job.documents]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View style={{ flex: 1 }}>
|
||||||
<FlatList
|
<FlatList
|
||||||
refreshControl={
|
refreshControl={
|
||||||
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
||||||
}
|
}
|
||||||
data={job.documents}
|
data={job.documents}
|
||||||
contentContainerStyle={styles.listContentContainer}
|
|
||||||
keyExtractor={(item) => item.id}
|
|
||||||
numColumns={4}
|
numColumns={4}
|
||||||
|
keyExtractor={(item) => item.id}
|
||||||
renderItem={(object) => (
|
renderItem={(object) => (
|
||||||
<TouchableOpacity
|
<View
|
||||||
onPress={() => {
|
style={{
|
||||||
setImgIndex(object.index);
|
flex: 1,
|
||||||
setPreviewVisible(true);
|
flexDirection: "column",
|
||||||
|
margin: 5,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<TouchableOpacity
|
||||||
style={{ margin: 5 }}
|
onPress={() => {
|
||||||
source={{
|
setImgIndex(object.index);
|
||||||
width: 100,
|
setPreviewVisible(true);
|
||||||
height: 100,
|
|
||||||
uri: `${REACT_APP_CLOUDINARY_IMAGE_ENDPOINT}/${REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS}/${object.item.key}`,
|
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
</TouchableOpacity>
|
<Image
|
||||||
|
source={{
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
uri: `${
|
||||||
|
env.REACT_APP_CLOUDINARY_ENDPOINT
|
||||||
|
}/${DetermineFileType(object.item.type)}/upload/${
|
||||||
|
env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS
|
||||||
|
}/${object.item.key}`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Text>{job.documents.length}</Text>
|
<Text>{job.documents.length}</Text>
|
||||||
<MediaCacheOverlay
|
<MediaCacheOverlay
|
||||||
|
photos={fullphotos}
|
||||||
imgIndex={imgIndex}
|
imgIndex={imgIndex}
|
||||||
setImgIndex={setImgIndex}
|
setImgIndex={setImgIndex}
|
||||||
previewVisible={previewVisible}
|
previewVisible={previewVisible}
|
||||||
@@ -58,22 +81,3 @@ export default function JobDocumentsComponent({ job, loading, refetch }) {
|
|||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-evenly",
|
|
||||||
},
|
|
||||||
listContentContainer: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
thumbnail: {
|
|
||||||
width: 10,
|
|
||||||
height: 10,
|
|
||||||
backgroundColor: "tomato",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import Dinero from "dinero.js";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FlatList, RefreshControl, StyleSheet, Text, View } from "react-native";
|
import { FlatList, RefreshControl, StyleSheet, Text, View } from "react-native";
|
||||||
import { Card } from "react-native-paper";
|
import { Card, DataTable } from "react-native-paper";
|
||||||
|
|
||||||
export default function JobLines({ job, loading, refetch }) {
|
export default function JobLines({ job, loading, refetch }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -18,60 +18,64 @@ export default function JobLines({ job, loading, refetch }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
|
<DataTable>
|
||||||
|
<DataTable.Header>
|
||||||
|
<DataTable.Title style={{ flex: 4 }}>
|
||||||
|
{t("jobdetail.labels.lines_desc")}
|
||||||
|
</DataTable.Title>
|
||||||
|
<DataTable.Title style={{ flex: 2 }}>
|
||||||
|
{t("jobdetail.labels.lines_lbr_ty")}
|
||||||
|
</DataTable.Title>
|
||||||
|
<DataTable.Title style={{ flex: 1 }}>
|
||||||
|
{t("jobdetail.labels.lines_lb_hrs")}
|
||||||
|
</DataTable.Title>
|
||||||
|
<DataTable.Title style={{ flex: 2 }}>
|
||||||
|
{t("jobdetail.labels.lines_part_type")}
|
||||||
|
</DataTable.Title>
|
||||||
|
<DataTable.Title style={{ flex: 1 }}>
|
||||||
|
{t("jobdetail.labels.lines_qty")}
|
||||||
|
</DataTable.Title>
|
||||||
|
<DataTable.Title style={{ flex: 1 }}>
|
||||||
|
{t("jobdetail.labels.lines_price")}
|
||||||
|
</DataTable.Title>
|
||||||
|
</DataTable.Header>
|
||||||
|
</DataTable>
|
||||||
|
|
||||||
<FlatList
|
<FlatList
|
||||||
data={job.joblines}
|
data={job.joblines}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
||||||
}
|
}
|
||||||
contentContainerStyle={localStyles.listContentContainer}
|
|
||||||
keyExtractor={(item) => item.id}
|
keyExtractor={(item) => item.id}
|
||||||
renderItem={(object) => (
|
renderItem={(object) => (
|
||||||
<Card>
|
<DataTable.Row>
|
||||||
<Card.Content style={localStyles.flexRow}>
|
<DataTable.Cell style={{ flex: 4 }}>
|
||||||
<Text style={localStyles.growWithEllipsis}>{`${
|
{object.item.line_desc}
|
||||||
object.item.line_desc
|
</DataTable.Cell>
|
||||||
}${
|
<DataTable.Cell style={{ flex: 2 }}>
|
||||||
object.item.part_qty > 1 ? ` x ${object.item.part_qty}` : ""
|
{object.item.mod_lbr_ty &&
|
||||||
}`}</Text>
|
t(`jobdetail.lbr_types.${object.item.mod_lbr_ty}`)}
|
||||||
{object.item.part_type && (
|
</DataTable.Cell>
|
||||||
<Text style={localStyles.sideMargins}>
|
<DataTable.Cell style={{ flex: 1 }}>
|
||||||
{t(`jobdetail.part_types.${object.item.part_type}`)}
|
{object.item.mod_lb_hrs}
|
||||||
</Text>
|
</DataTable.Cell>
|
||||||
)}
|
<DataTable.Cell style={{ flex: 2 }}>
|
||||||
<Text style={localStyles.sideMargins}>
|
{object.item.part_type &&
|
||||||
{Dinero({
|
t(`jobdetail.part_types.${object.item.part_type}`)}
|
||||||
amount: Math.round((object.item.act_price || 0) * 100),
|
</DataTable.Cell>
|
||||||
}).toFormat()}
|
<DataTable.Cell style={{ flex: 1 }}>
|
||||||
</Text>
|
{object.item.part_qty}
|
||||||
</Card.Content>
|
</DataTable.Cell>
|
||||||
<Card.Content style={localStyles.flexRow}>
|
<DataTable.Cell style={{ flex: 1 }}>
|
||||||
{object.item.mod_lbr_ty && (
|
{Dinero({
|
||||||
<Text>
|
amount: Math.round((object.item.act_price || 0) * 100),
|
||||||
{t(`jobdetail.lbr_types.${object.item.mod_lbr_ty}`)}
|
}).toFormat()}
|
||||||
</Text>
|
</DataTable.Cell>
|
||||||
)}
|
</DataTable.Row>
|
||||||
</Card.Content>
|
|
||||||
</Card>
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const localStyles = StyleSheet.create({
|
const localStyles = StyleSheet.create({});
|
||||||
listContentContainer: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
flexRow: {
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
},
|
|
||||||
sideMargins: {
|
|
||||||
marginLeft: 5,
|
|
||||||
marginRight: 5,
|
|
||||||
},
|
|
||||||
growWithEllipsis: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import React, { useRef } from "react";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Animated } from "react-native";
|
import { Animated } from "react-native";
|
||||||
import { TouchableOpacity } from "react-native-gesture-handler";
|
import { TouchableOpacity } from "react-native-gesture-handler";
|
||||||
import Swipeable from "react-native-gesture-handler/Swipeable";
|
import { Button, List, Title } from "react-native-paper";
|
||||||
import { List } from "react-native-paper";
|
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||||
@@ -60,21 +59,35 @@ export function JobListItem({ setCameraJob, setCameraJobId, item }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Swipeable
|
<TouchableOpacity onPress={onPress}>
|
||||||
ref={_swipeableRow}
|
|
||||||
renderRightActions={RenderRightAction}
|
|
||||||
shouldCancelWhenOutside
|
|
||||||
>
|
|
||||||
<List.Item
|
<List.Item
|
||||||
onPress={onPress}
|
title={<Title>{item.ro_number || t("general.labels.na")}</Title>}
|
||||||
title={item.ro_number || t("general.labels.na")}
|
|
||||||
description={`${item.ownr_fn || ""} ${item.ownr_ln || ""} ${
|
description={`${item.ownr_fn || ""} ${item.ownr_ln || ""} ${
|
||||||
item.ownr_co_nm || ""
|
item.ownr_co_nm || ""
|
||||||
} - ${item.v_model_yr || ""} ${item.v_make_desc || ""} ${
|
} - ${item.v_model_yr || ""} ${item.v_make_desc || ""} ${
|
||||||
item.v_model_desc || ""
|
item.v_model_desc || ""
|
||||||
}`}
|
}`}
|
||||||
|
right={({ style }) => (
|
||||||
|
<Button
|
||||||
|
style={style}
|
||||||
|
onPress={() => {
|
||||||
|
logImEXEvent("imexmobile_setcamerajobid_swipe");
|
||||||
|
setCameraJobId(item.id);
|
||||||
|
setCameraJob(item);
|
||||||
|
navigation.navigate("MediaBrowserTab");
|
||||||
|
_swipeableRow.current.close();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
style={style}
|
||||||
|
name="ios-add"
|
||||||
|
size={32}
|
||||||
|
color="dodgerblue"
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</Swipeable>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Text, View } from "react-native";
|
|||||||
import { Card } from "react-native-paper";
|
import { Card } from "react-native-paper";
|
||||||
export default function NoteListItem({ item }) {
|
export default function NoteListItem({ item }) {
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card style={{ margin: 8 }}>
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<View style={{ display: "flex", flex: 1 }}>
|
<View style={{ display: "flex", flex: 1 }}>
|
||||||
<Text>{item.text}</Text>
|
<Text>{item.text}</Text>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FlatList, RefreshControl, Text } from "react-native";
|
import { FlatList, RefreshControl, Text } from "react-native";
|
||||||
import JobNotesItem from "../job-notes-item/job-notes-item.component";
|
|
||||||
import { Card } from "react-native-paper";
|
import { Card } from "react-native-paper";
|
||||||
|
import JobNotesItem from "../job-notes-item/job-notes-item.component";
|
||||||
export default function JobNotes({ job, loading, refetch }) {
|
export default function JobNotes({ job, loading, refetch }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
if (!job) {
|
if (!job) {
|
||||||
@@ -14,6 +14,7 @@ export default function JobNotes({ job, loading, refetch }) {
|
|||||||
const onRefresh = async () => {
|
const onRefresh = async () => {
|
||||||
return refetch();
|
return refetch();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (job.notes.length === 0)
|
if (job.notes.length === 0)
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
@@ -31,7 +32,6 @@ export default function JobNotes({ job, loading, refetch }) {
|
|||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
data={job.notes}
|
data={job.notes}
|
||||||
renderItem={(object) => <JobNotesItem item={object.item} />}
|
renderItem={(object) => <JobNotesItem item={object.item} />}
|
||||||
//ItemSeparatorComponent={FlatListItemSeparator}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import { Card } from "react-native-paper";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
RefreshControl,
|
RefreshControl,
|
||||||
StyleSheet,
|
|
||||||
ScrollView,
|
ScrollView,
|
||||||
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
|
import { Card, Headline, Subheading } from "react-native-paper";
|
||||||
import DataLabelComponent from "../data-label/data-label.component";
|
import DataLabelComponent from "../data-label/data-label.component";
|
||||||
|
import StyleRepeater from "../style-repeater/style-repeater";
|
||||||
|
import styles from "../styles";
|
||||||
|
|
||||||
export default function JobTombstone({ job, loading, refetch }) {
|
export default function JobTombstone({ job, loading, refetch }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -23,114 +25,121 @@ export default function JobTombstone({ job, loading, refetch }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView
|
<ScrollView
|
||||||
padder
|
style={styles.cardBackground}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Card>
|
<StyleRepeater childStyle={{ margin: 4 }}>
|
||||||
<Card.Content bordered style={localStyles.status}>
|
<Card>
|
||||||
<Text>{job.status}</Text>
|
<Card.Title title={t("jobdetail.labels.jobinfo")} />
|
||||||
</Card.Content>
|
<Card.Content>
|
||||||
{job.inproduction && (
|
<Headline>{job.status}</Headline>
|
||||||
<Card.Content bordered style={localStyles.inproduction}>
|
{job.inproduction && (
|
||||||
<Text>{t("objects.jobs.labels.inproduction")}</Text>
|
<Subheading>{t("objects.jobs.labels.inproduction")}</Subheading>
|
||||||
|
)}
|
||||||
|
{job.inproduction &&
|
||||||
|
job.production_vars &&
|
||||||
|
!!job.production_vars.note && (
|
||||||
|
<Subheading>{job.production_vars.note}</Subheading>
|
||||||
|
)}
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
)}
|
</Card>
|
||||||
{job.inproduction && job.production_vars && !!job.production_vars.note && (
|
|
||||||
<Card.Content bordered style={localStyles.inproduction}>
|
<Card>
|
||||||
<Text>{job.production_vars.note}</Text>
|
<Card.Title title={t("jobdetail.labels.claiminformation")} />
|
||||||
|
<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 || ""
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
</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.Content>
|
||||||
)}
|
</Card>
|
||||||
</Card>
|
<Card>
|
||||||
<Card>
|
<Card.Title title={t("jobdetail.labels.employeeassignments")} />
|
||||||
<Card.Content bordered style={localStyles.status}>
|
<Card.Content>
|
||||||
<Text>{t("jobdetail.labels.claiminformation")}</Text>
|
<DataLabelComponent
|
||||||
</Card.Content>
|
label={t("objects.jobs.fields.employee_body")}
|
||||||
<View>
|
content={`${
|
||||||
<DataLabelComponent
|
(job.employee_body_rel && job.employee_body_rel.first_name) ||
|
||||||
label={t("objects.jobs.fields.owner")}
|
""
|
||||||
content={`${job.ownr_fn || ""} ${job.ownr_ln || ""} ${
|
} ${
|
||||||
job.ownr_co_nm || ""
|
(job.employee_body_rel && job.employee_body_rel.last_name) || ""
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
<DataLabelComponent
|
<DataLabelComponent
|
||||||
label={t("objects.jobs.fields.vehicle")}
|
label={t("objects.jobs.fields.employee_prep")}
|
||||||
content={`${job.v_model_yr || ""} ${job.v_make_desc || ""} ${
|
content={`${
|
||||||
job.v_model_desc || ""
|
(job.employee_prep_rel && job.employee_prep_rel.first_name) ||
|
||||||
}`}
|
""
|
||||||
/>
|
} ${
|
||||||
<DataLabelComponent
|
(job.employee_prep_rel && job.employee_prep_rel.last_name) || ""
|
||||||
label={t("objects.jobs.fields.ins_co_nm")}
|
}`}
|
||||||
content={job.ins_co_nm}
|
/>
|
||||||
/>
|
<DataLabelComponent
|
||||||
<DataLabelComponent
|
label={t("objects.jobs.fields.employee_refinish")}
|
||||||
label={t("objects.jobs.fields.clm_no")}
|
content={`${
|
||||||
content={job.clm_no}
|
(job.employee_refinish_rel &&
|
||||||
/>
|
job.employee_refinish_rel.first_name) ||
|
||||||
</View>
|
""
|
||||||
</Card>
|
} ${
|
||||||
<Card>
|
(job.employee_refinish_rel &&
|
||||||
<Card.Content bordered style={localStyles.status}>
|
job.employee_refinish_rel.last_name) ||
|
||||||
<Text>{t("jobdetail.labels.employeeassignments")}</Text>
|
""
|
||||||
</Card.Content>
|
}`}
|
||||||
<View>
|
/>
|
||||||
<DataLabelComponent
|
</Card.Content>
|
||||||
label={t("objects.jobs.fields.employee_body")}
|
</Card>
|
||||||
content={`${
|
<Card>
|
||||||
(job.employee_body_rel && job.employee_body_rel.first_name) || ""
|
<Card.Title title={t("jobdetail.labels.dates")} />
|
||||||
} ${
|
<Card.Content style={localStyles.twoColumnCard}>
|
||||||
(job.employee_body_rel && job.employee_body_rel.last_name) || ""
|
<View style={localStyles.twoColumnCardColumn}>
|
||||||
}`}
|
<DataLabelComponent
|
||||||
/>
|
label={t("objects.jobs.fields.scheduled_in")}
|
||||||
<DataLabelComponent
|
content={job.scheduled_in}
|
||||||
label={t("objects.jobs.fields.employee_prep")}
|
dateTime
|
||||||
content={`${
|
/>
|
||||||
(job.employee_prep_rel && job.employee_prep_rel.first_name) || ""
|
<DataLabelComponent
|
||||||
} ${
|
label={t("objects.jobs.fields.actual_in")}
|
||||||
(job.employee_prep_rel && job.employee_prep_rel.last_name) || ""
|
content={job.actual_in}
|
||||||
}`}
|
dateTime
|
||||||
/>
|
/>
|
||||||
<DataLabelComponent
|
</View>
|
||||||
label={t("objects.jobs.fields.employee_refinish")}
|
<View style={localStyles.twoColumnCardColumn}>
|
||||||
content={`${
|
<DataLabelComponent
|
||||||
(job.employee_refinish_rel &&
|
label={t("objects.jobs.fields.scheduled_completion")}
|
||||||
job.employee_refinish_rel.first_name) ||
|
content={job.scheduled_completion}
|
||||||
""
|
dateTime
|
||||||
} ${
|
/>
|
||||||
(job.employee_refinish_rel &&
|
<DataLabelComponent
|
||||||
job.employee_refinish_rel.last_name) ||
|
label={t("objects.jobs.fields.scheduled_delivery")}
|
||||||
""
|
content={job.scheduled_delivery}
|
||||||
}`}
|
dateTime
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</Card>
|
</Card.Content>
|
||||||
<Card style={localStyles.twoColumnCard}>
|
</Card>
|
||||||
<View style={localStyles.twoColumnCardColumn}>
|
</StyleRepeater>
|
||||||
<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>
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -144,7 +153,6 @@ const localStyles = StyleSheet.create({
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
},
|
},
|
||||||
inproduction: {
|
inproduction: {
|
||||||
backgroundColor: "tomato",
|
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
|
|||||||
@@ -1,84 +1,23 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Alert, Modal, StyleSheet, Text, Button, View } from "react-native";
|
import { Modal } from "react-native";
|
||||||
import ImageViewer from "react-native-image-zoom-viewer";
|
import Gallery from "react-native-image-gallery";
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { createStructuredSelector } from "reselect";
|
|
||||||
import { removePhotos } from "../../redux/photos/photos.actions";
|
|
||||||
import { selectPhotos } from "../../redux/photos/photos.selectors";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
export default function MediaCacheOverlay({
|
||||||
photos: selectPhotos,
|
|
||||||
});
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
|
||||||
removePhotos: (ids) => dispatch(removePhotos(ids)),
|
|
||||||
});
|
|
||||||
|
|
||||||
export function MediaCacheOverlay({
|
|
||||||
photos,
|
photos,
|
||||||
removePhotos,
|
|
||||||
previewVisible,
|
previewVisible,
|
||||||
setPreviewVisible,
|
setPreviewVisible,
|
||||||
imgIndex,
|
imgIndex,
|
||||||
setImgIndex,
|
setImgIndex,
|
||||||
}) {
|
}) {
|
||||||
|
console.log("photos :>> ", photos);
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
animationType="slide"
|
onDismiss={() => setPreviewVisible(false)}
|
||||||
onRequestClose={() => {
|
onRequestClose={() => setPreviewVisible(false)}
|
||||||
Alert.alert("Modal has been closed.");
|
|
||||||
}}
|
|
||||||
visible={previewVisible}
|
visible={previewVisible}
|
||||||
transparent={true}
|
transparent={false}
|
||||||
>
|
>
|
||||||
<ImageViewer
|
<Gallery initialPage={imgIndex} style={{ flex: 1 }} images={photos} />
|
||||||
onCancel={() => setPreviewVisible(false)}
|
|
||||||
index={imgIndex}
|
|
||||||
onChange={(index) => setImgIndex(index)}
|
|
||||||
style={{ display: "flex" }}
|
|
||||||
renderFooter={(index) => (
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
marginleft: "auto",
|
|
||||||
backgroundColor: "tomato",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text>{index} This is the thing.</Text>
|
|
||||||
<Button
|
|
||||||
onPress={() => {
|
|
||||||
removePhotos([photos[index].id]);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text>Delete</Text>
|
|
||||||
</Button>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
enableSwipeDown
|
|
||||||
enablePreload
|
|
||||||
imageUrls={photos.map((p) => {
|
|
||||||
return { url: p.uri };
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-evenly",
|
|
||||||
},
|
|
||||||
listContentContainer: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
thumbnail: {
|
|
||||||
width: 10,
|
|
||||||
height: 10,
|
|
||||||
backgroundColor: "tomato",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(MediaCacheOverlay);
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useQuery } from "@apollo/client";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useWindowDimensions } from "react-native";
|
import { useWindowDimensions } from "react-native";
|
||||||
import { SceneMap, TabView } from "react-native-tab-view";
|
import { SceneMap, TabView, TabBar } from "react-native-tab-view";
|
||||||
import { GET_JOB_BY_PK } from "../../graphql/jobs.queries";
|
import { GET_JOB_BY_PK } from "../../graphql/jobs.queries";
|
||||||
import ErrorDisplay from "../error-display/error-display.component";
|
import ErrorDisplay from "../error-display/error-display.component";
|
||||||
import JobDocuments from "../job-documents/job-documents.component";
|
import JobDocuments from "../job-documents/job-documents.component";
|
||||||
@@ -24,6 +24,14 @@ export default function ScreenJobDetail({ route }) {
|
|||||||
skip: !jobId,
|
skip: !jobId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const renderTabBar = (props) => (
|
||||||
|
<TabBar
|
||||||
|
{...props}
|
||||||
|
indicatorStyle={{ backgroundColor: "white" }}
|
||||||
|
style={{ backgroundColor: "dodgerblue" }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
const renderScene = SceneMap({
|
const renderScene = SceneMap({
|
||||||
job: () =>
|
job: () =>
|
||||||
JobTombstone({
|
JobTombstone({
|
||||||
@@ -68,6 +76,7 @@ export default function ScreenJobDetail({ route }) {
|
|||||||
renderScene={renderScene}
|
renderScene={renderScene}
|
||||||
onIndexChange={setIndex}
|
onIndexChange={setIndex}
|
||||||
initialLayout={{ width: layout.width }}
|
initialLayout={{ width: layout.width }}
|
||||||
|
renderTabBar={renderTabBar}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ export function ImageBrowserScreen({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onDone = async (data) => {
|
const onDone = async (data) => {
|
||||||
console.log("Assets :>> ", data);
|
|
||||||
logImEXEvent("imexmobile_upload_documents", { count: data.length });
|
logImEXEvent("imexmobile_upload_documents", { count: data.length });
|
||||||
const actions = [];
|
const actions = [];
|
||||||
data.forEach(function (p) {
|
data.forEach(function (p) {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { Formik } from "formik";
|
import { Formik } from "formik";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { ActivityIndicator, Image, StyleSheet, View, Text } from "react-native";
|
import { Image, StyleSheet, Text, View } from "react-native";
|
||||||
|
import { Button, TextInput, Title } from "react-native-paper";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import Logo from "../../assets/logo192.png";
|
import Logo from "../../assets/logo192.png";
|
||||||
@@ -11,8 +12,6 @@ import {
|
|||||||
selectSigningIn,
|
selectSigningIn,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
import SignInErrorAlertComponent from "../sign-in-error-alert/sign-in-error-alert.component";
|
import SignInErrorAlertComponent from "../sign-in-error-alert/sign-in-error-alert.component";
|
||||||
import styles from "../styles";
|
|
||||||
import { TextInput, Button, Subheading } from "react-native-paper";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
@@ -33,41 +32,46 @@ export function SignIn({ emailSignInStart, signingIn }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View style={localStyles.content}>
|
||||||
scrollEnabled={false}
|
<View
|
||||||
contentContainerStyle={styles.contentContainer__centered}
|
style={{
|
||||||
style={localStyles.content}
|
display: "flex",
|
||||||
>
|
|
||||||
<View style={styles.evenlySpacedRow}>
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-evenly",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Image style={localStyles.logo} source={Logo} />
|
<Image style={localStyles.logo} source={Logo} />
|
||||||
<Text>{t("app.title")}</Text>
|
<Title>{t("app.title")}</Title>
|
||||||
</View>
|
</View>
|
||||||
<Formik initialValues={{ email: "", password: "" }} onSubmit={formSubmit}>
|
<Formik initialValues={{ email: "", password: "" }} onSubmit={formSubmit}>
|
||||||
{({ handleChange, handleBlur, handleSubmit, values }) => (
|
{({ handleChange, handleBlur, handleSubmit, values }) => (
|
||||||
<View>
|
<View>
|
||||||
<View>
|
<TextInput
|
||||||
<Subheading>{t("signin.fields.email")}</Subheading>
|
label={t("signin.fields.email")}
|
||||||
<TextInput
|
mode="outlined"
|
||||||
autoCapitalize="none"
|
autoCapitalize="none"
|
||||||
keyboardType="email-address"
|
keyboardType="email-address"
|
||||||
onChangeText={handleChange("email")}
|
onChangeText={handleChange("email")}
|
||||||
onBlur={handleBlur("email")}
|
onBlur={handleBlur("email")}
|
||||||
value={values.email}
|
value={values.email}
|
||||||
/>
|
style={[localStyles.input]}
|
||||||
</View>
|
/>
|
||||||
<View>
|
|
||||||
<Subheading>{t("signin.fields.password")}</Subheading>
|
<TextInput
|
||||||
<TextInput
|
label={t("signin.fields.password")}
|
||||||
secureTextEntry={true}
|
mode="outlined"
|
||||||
onChangeText={handleChange("password")}
|
secureTextEntry={true}
|
||||||
onBlur={handleBlur("password")}
|
onChangeText={handleChange("password")}
|
||||||
value={values.password}
|
onBlur={handleBlur("password")}
|
||||||
/>
|
value={values.password}
|
||||||
</View>
|
style={[localStyles.input]}
|
||||||
|
/>
|
||||||
|
|
||||||
<SignInErrorAlertComponent />
|
<SignInErrorAlertComponent />
|
||||||
<Button full onPress={handleSubmit}>
|
<Button mode="outlined" loading={signingIn} onPress={handleSubmit}>
|
||||||
<Text>{t("signin.actions.signin")}</Text>
|
<Text>{t("signin.actions.signin")}</Text>
|
||||||
{signingIn ? <ActivityIndicator size="large" /> : null}
|
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
@@ -78,9 +82,13 @@ export function SignIn({ emailSignInStart, signingIn }) {
|
|||||||
|
|
||||||
const localStyles = StyleSheet.create({
|
const localStyles = StyleSheet.create({
|
||||||
content: {
|
content: {
|
||||||
paddingBottom: 200,
|
display: "flex",
|
||||||
|
flex: 1,
|
||||||
},
|
},
|
||||||
logo: { width: 100, height: 100 },
|
logo: { width: 100, height: 100 },
|
||||||
|
input: {
|
||||||
|
margin: 12,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(SignIn);
|
export default connect(mapStateToProps, mapDispatchToProps)(SignIn);
|
||||||
|
|||||||
@@ -1,29 +1,35 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Image, StyleSheet, View } from "react-native";
|
import { ActivityIndicator, Image, StyleSheet, View } from "react-native";
|
||||||
import { BarIndicator } from "react-native-indicators";
|
|
||||||
import { Title } from "react-native-paper";
|
import { Title } from "react-native-paper";
|
||||||
import Logo from "../../assets/logo192.png";
|
import Logo from "../../assets/logo192.png";
|
||||||
import styles from "../styles";
|
|
||||||
|
|
||||||
export default function ScreenSplash() {
|
export default function ScreenSplash() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<View
|
<View style={[localStyles.container]}>
|
||||||
contentContainerStyle={[
|
<View style={[localStyles.logoContainer]}>
|
||||||
styles.contentContainer__centered,
|
<Image style={localStyles.logo} source={Logo} />
|
||||||
localStyles.middleAlign,
|
<Title>{t("app.title")}</Title>
|
||||||
]}
|
</View>
|
||||||
>
|
|
||||||
<Image style={localStyles.logo} source={Logo} />
|
<ActivityIndicator color="dodgerblue" size="large" />
|
||||||
<Title>{t("app.title")}</Title>
|
|
||||||
<BarIndicator count={5} color="dodgerblue" />
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const localStyles = StyleSheet.create({
|
const localStyles = StyleSheet.create({
|
||||||
middleAlign: {
|
container: {
|
||||||
|
display: "flex",
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: "column",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
logoContainer: {
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
},
|
},
|
||||||
logo: { width: 100, height: 100, margin: 20 },
|
logo: { width: 175, height: 175, margin: 20 },
|
||||||
});
|
});
|
||||||
|
|||||||
13
components/style-repeater/style-repeater.jsx
Normal file
13
components/style-repeater/style-repeater.jsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function StyleRepeater({ childStyle, children }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{React.Children.map(children, (child) =>
|
||||||
|
React.cloneElement(child, {
|
||||||
|
style: [child.props.style, childStyle],
|
||||||
|
})
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,30 +1,12 @@
|
|||||||
import { StyleSheet } from "react-native";
|
import { StyleSheet } from "react-native";
|
||||||
|
|
||||||
|
const cardBackgroundColor = "gainsboro";
|
||||||
|
|
||||||
export default StyleSheet.create({
|
export default StyleSheet.create({
|
||||||
contentContainer__centered: {
|
cardBackground: {
|
||||||
justifyContent: "center",
|
padding: 5,
|
||||||
|
backgroundColor: cardBackgroundColor,
|
||||||
|
display: "flex",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
evenlySpacedRow: {
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-evenly",
|
|
||||||
alignItems: "center",
|
|
||||||
},
|
|
||||||
|
|
||||||
swipe_view: {
|
|
||||||
flex: 1,
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: 100,
|
|
||||||
// marginTop: 5,
|
|
||||||
//marginBottom: 5,
|
|
||||||
},
|
|
||||||
swipe_view_blue: {
|
|
||||||
backgroundColor: "dodgerblue",
|
|
||||||
},
|
|
||||||
swipe_text: {
|
|
||||||
textAlign: "center",
|
|
||||||
color: "white",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import React from "react";
|
import React, { useMemo } from "react";
|
||||||
import {
|
import {
|
||||||
ScrollView,
|
ScrollView,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
@@ -10,10 +10,15 @@ import {
|
|||||||
import * as Progress from "react-native-progress";
|
import * as Progress from "react-native-progress";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
export default function UploadProgress({ uploads, setUploads }) {
|
export default function UploadProgress({ uploads, setUploads }) {
|
||||||
|
const uploadKeys = useMemo(() => {
|
||||||
|
if (uploads) return Object.keys(uploads);
|
||||||
|
return [];
|
||||||
|
}, [uploads]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
{Object.keys(uploads).map((key) => (
|
{uploadKeys.map((key) => (
|
||||||
<View key={key} style={styles.progressItem}>
|
<View key={key} style={styles.progressItem}>
|
||||||
<Text style={styles.progressText}>{key}</Text>
|
<Text style={styles.progressText}>{key}</Text>
|
||||||
<View style={styles.progressBarContainer}>
|
<View style={styles.progressBarContainer}>
|
||||||
|
|||||||
1
env.js
1
env.js
@@ -5,6 +5,7 @@ export const prodUrl = "https://someapp.herokuapp.com";
|
|||||||
const ENV = {
|
const ENV = {
|
||||||
dev: {
|
dev: {
|
||||||
API_URL: "https://api.imex.online",
|
API_URL: "https://api.imex.online",
|
||||||
|
|
||||||
REACT_APP_CLOUDINARY_ENDPOINT_API:
|
REACT_APP_CLOUDINARY_ENDPOINT_API:
|
||||||
"https://api.cloudinary.com/v1_1/bodyshop",
|
"https://api.cloudinary.com/v1_1/bodyshop",
|
||||||
REACT_APP_CLOUDINARY_ENDPOINT: "https://res.cloudinary.com/bodyshop",
|
REACT_APP_CLOUDINARY_ENDPOINT: "https://res.cloudinary.com/bodyshop",
|
||||||
|
|||||||
@@ -274,6 +274,7 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
name
|
name
|
||||||
key
|
key
|
||||||
created_at
|
created_at
|
||||||
|
type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
71
package-lock.json
generated
71
package-lock.json
generated
@@ -42,7 +42,7 @@
|
|||||||
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.0.tar.gz",
|
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.0.tar.gz",
|
||||||
"react-native-easy-grid": "^0.2.2",
|
"react-native-easy-grid": "^0.2.2",
|
||||||
"react-native-gesture-handler": "~1.8.0",
|
"react-native-gesture-handler": "~1.8.0",
|
||||||
"react-native-image-zoom-viewer": "^3.0.1",
|
"react-native-image-gallery": "^2.1.5",
|
||||||
"react-native-indicators": "^0.17.0",
|
"react-native-indicators": "^0.17.0",
|
||||||
"react-native-pager-view": "^5.1.0",
|
"react-native-pager-view": "^5.1.0",
|
||||||
"react-native-paper": "^4.7.2",
|
"react-native-paper": "^4.7.2",
|
||||||
@@ -13001,6 +13001,15 @@
|
|||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/react-mixin": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-mixin/-/react-mixin-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-z9fZ0aCRDjlgxLdMeWkJ9TwhmVLhQ09r8RFpin/cEPA2T6jsb7YHNWcIe0Oii+hhJNyMymdy91CSya5mRkuCkg==",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4.0.1",
|
||||||
|
"smart-mixin": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-native": {
|
"node_modules/react-native": {
|
||||||
"version": "0.63.2",
|
"version": "0.63.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -13063,23 +13072,14 @@
|
|||||||
"prop-types": "^15.7.2"
|
"prop-types": "^15.7.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-native-image-pan-zoom": {
|
"node_modules/react-native-image-gallery": {
|
||||||
"version": "2.1.12",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-image-pan-zoom/-/react-native-image-pan-zoom-2.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-image-gallery/-/react-native-image-gallery-2.1.5.tgz",
|
||||||
"integrity": "sha512-BF66XeP6dzuANsPmmFsJshM2Jyh/Mo1t8FsGc1L9Q9/sVP8MJULDabB1hms+eAoqgtyhMr5BuXV3E1hJ5U5H6Q==",
|
"integrity": "sha512-xC7nuPu4GUH0da6byofQ10LjtqlKj+VaLc0NHBJmeMHVvdvmRvFEO6UOq0Q0m/ePx3OQiPTNwGbf5BSPJEKa0w==",
|
||||||
"license": "ISC",
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "*",
|
|
||||||
"react-native": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-native-image-zoom-viewer": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-native-image-zoom-viewer/-/react-native-image-zoom-viewer-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-la6s5DNSuq4GCRLsi5CZ29FPjgTpdCuGIRdO5T9rUrAtxrlpBPhhSnHrbmPVxsdtOUvxHacTh2Gfa9+RraMZQA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react-native-image-pan-zoom": "^2.1.12"
|
"prop-types": "^15.6.0",
|
||||||
|
"react-mixin": "^3.0.5",
|
||||||
|
"react-timer-mixin": "^0.13.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*",
|
"react": "*",
|
||||||
@@ -14223,6 +14223,11 @@
|
|||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/smart-mixin": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/smart-mixin/-/smart-mixin-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-o0oQVeMqdbMNK048oyPcmctT9Dc="
|
||||||
|
},
|
||||||
"node_modules/snapdragon": {
|
"node_modules/snapdragon": {
|
||||||
"version": "0.8.2",
|
"version": "0.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||||
@@ -25256,6 +25261,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
|
"react-mixin": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-mixin/-/react-mixin-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-z9fZ0aCRDjlgxLdMeWkJ9TwhmVLhQ09r8RFpin/cEPA2T6jsb7YHNWcIe0Oii+hhJNyMymdy91CSya5mRkuCkg==",
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4.0.1",
|
||||||
|
"smart-mixin": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-native": {
|
"react-native": {
|
||||||
"version": "0.63.2",
|
"version": "0.63.2",
|
||||||
"requires": {
|
"requires": {
|
||||||
@@ -25317,18 +25331,14 @@
|
|||||||
"prop-types": "^15.7.2"
|
"prop-types": "^15.7.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-native-image-pan-zoom": {
|
"react-native-image-gallery": {
|
||||||
"version": "2.1.12",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-image-pan-zoom/-/react-native-image-pan-zoom-2.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-image-gallery/-/react-native-image-gallery-2.1.5.tgz",
|
||||||
"integrity": "sha512-BF66XeP6dzuANsPmmFsJshM2Jyh/Mo1t8FsGc1L9Q9/sVP8MJULDabB1hms+eAoqgtyhMr5BuXV3E1hJ5U5H6Q==",
|
"integrity": "sha512-xC7nuPu4GUH0da6byofQ10LjtqlKj+VaLc0NHBJmeMHVvdvmRvFEO6UOq0Q0m/ePx3OQiPTNwGbf5BSPJEKa0w==",
|
||||||
"requires": {}
|
|
||||||
},
|
|
||||||
"react-native-image-zoom-viewer": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-native-image-zoom-viewer/-/react-native-image-zoom-viewer-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-la6s5DNSuq4GCRLsi5CZ29FPjgTpdCuGIRdO5T9rUrAtxrlpBPhhSnHrbmPVxsdtOUvxHacTh2Gfa9+RraMZQA==",
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"react-native-image-pan-zoom": "^2.1.12"
|
"prop-types": "^15.6.0",
|
||||||
|
"react-mixin": "^3.0.5",
|
||||||
|
"react-timer-mixin": "^0.13.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-native-indicators": {
|
"react-native-indicators": {
|
||||||
@@ -26146,6 +26156,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz",
|
||||||
"integrity": "sha512-tf+h5W1IrjNm/9rKKj0JU2MDMruiopx0jjVA5zCdBtcGjfp0+c5rHw/zADLC3IeKlGHtVbHtpfzvYA0OYT+HKg=="
|
"integrity": "sha512-tf+h5W1IrjNm/9rKKj0JU2MDMruiopx0jjVA5zCdBtcGjfp0+c5rHw/zADLC3IeKlGHtVbHtpfzvYA0OYT+HKg=="
|
||||||
},
|
},
|
||||||
|
"smart-mixin": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/smart-mixin/-/smart-mixin-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-o0oQVeMqdbMNK048oyPcmctT9Dc="
|
||||||
|
},
|
||||||
"snapdragon": {
|
"snapdragon": {
|
||||||
"version": "0.8.2",
|
"version": "0.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.0.tar.gz",
|
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.0.tar.gz",
|
||||||
"react-native-easy-grid": "^0.2.2",
|
"react-native-easy-grid": "^0.2.2",
|
||||||
"react-native-gesture-handler": "~1.8.0",
|
"react-native-gesture-handler": "~1.8.0",
|
||||||
"react-native-image-zoom-viewer": "^3.0.1",
|
"react-native-image-gallery": "^2.1.5",
|
||||||
"react-native-indicators": "^0.17.0",
|
"react-native-indicators": "^0.17.0",
|
||||||
"react-native-pager-view": "^5.1.0",
|
"react-native-pager-view": "^5.1.0",
|
||||||
"react-native-paper": "^4.7.2",
|
"react-native-paper": "^4.7.2",
|
||||||
|
|||||||
@@ -19,10 +19,18 @@
|
|||||||
"jobdetail": {
|
"jobdetail": {
|
||||||
"labels": {
|
"labels": {
|
||||||
"claiminformation": "Claim Information",
|
"claiminformation": "Claim Information",
|
||||||
"documents": "Documents",
|
"dates": "Dates",
|
||||||
|
"documents": "Docs",
|
||||||
"employeeassignments": "Employee Assignments",
|
"employeeassignments": "Employee Assignments",
|
||||||
"job": "Job",
|
"job": "Job",
|
||||||
|
"jobinfo": "Job Information",
|
||||||
"lines": "Lines",
|
"lines": "Lines",
|
||||||
|
"lines_desc": "Desc.",
|
||||||
|
"lines_lb_hrs": "Hrs",
|
||||||
|
"lines_lbr_ty": "Lbr. Ty.",
|
||||||
|
"lines_part_type": "Part Ty.",
|
||||||
|
"lines_price": "$",
|
||||||
|
"lines_qty": "Qty.",
|
||||||
"nojobnotes": "There are no notes.",
|
"nojobnotes": "There are no notes.",
|
||||||
"notes": "Notes"
|
"notes": "Notes"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,10 +19,18 @@
|
|||||||
"jobdetail": {
|
"jobdetail": {
|
||||||
"labels": {
|
"labels": {
|
||||||
"claiminformation": "",
|
"claiminformation": "",
|
||||||
|
"dates": "",
|
||||||
"documents": "",
|
"documents": "",
|
||||||
"employeeassignments": "",
|
"employeeassignments": "",
|
||||||
"job": "",
|
"job": "",
|
||||||
|
"jobinfo": "",
|
||||||
"lines": "",
|
"lines": "",
|
||||||
|
"lines_desc": "",
|
||||||
|
"lines_lb_hrs": "",
|
||||||
|
"lines_lbr_ty": "",
|
||||||
|
"lines_part_type": "",
|
||||||
|
"lines_price": "",
|
||||||
|
"lines_qty": "",
|
||||||
"nojobnotes": "",
|
"nojobnotes": "",
|
||||||
"notes": ""
|
"notes": ""
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,10 +19,18 @@
|
|||||||
"jobdetail": {
|
"jobdetail": {
|
||||||
"labels": {
|
"labels": {
|
||||||
"claiminformation": "",
|
"claiminformation": "",
|
||||||
|
"dates": "",
|
||||||
"documents": "",
|
"documents": "",
|
||||||
"employeeassignments": "",
|
"employeeassignments": "",
|
||||||
"job": "",
|
"job": "",
|
||||||
|
"jobinfo": "",
|
||||||
"lines": "",
|
"lines": "",
|
||||||
|
"lines_desc": "",
|
||||||
|
"lines_lb_hrs": "",
|
||||||
|
"lines_lbr_ty": "",
|
||||||
|
"lines_part_type": "",
|
||||||
|
"lines_price": "",
|
||||||
|
"lines_qty": "",
|
||||||
"nojobnotes": "",
|
"nojobnotes": "",
|
||||||
"notes": ""
|
"notes": ""
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -181,7 +181,6 @@ export const uploadToCloudinary = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function DetermineFileType(filetype) {
|
export function DetermineFileType(filetype) {
|
||||||
console.log("Checking Type", filetype, filetype.startsWith("video"));
|
|
||||||
if (!filetype) return "auto";
|
if (!filetype) return "auto";
|
||||||
else if (filetype.startsWith("image")) return "image";
|
else if (filetype.startsWith("image")) return "image";
|
||||||
else if (filetype.startsWith("video")) return "video";
|
else if (filetype.startsWith("video")) return "video";
|
||||||
|
|||||||
32
yarn.lock
32
yarn.lock
@@ -7338,6 +7338,14 @@
|
|||||||
"resolved" "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz"
|
"resolved" "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz"
|
||||||
"version" "17.0.1"
|
"version" "17.0.1"
|
||||||
|
|
||||||
|
"react-mixin@^3.0.5":
|
||||||
|
"integrity" "sha512-z9fZ0aCRDjlgxLdMeWkJ9TwhmVLhQ09r8RFpin/cEPA2T6jsb7YHNWcIe0Oii+hhJNyMymdy91CSya5mRkuCkg=="
|
||||||
|
"resolved" "https://registry.npmjs.org/react-mixin/-/react-mixin-3.1.1.tgz"
|
||||||
|
"version" "3.1.1"
|
||||||
|
dependencies:
|
||||||
|
"object-assign" "^4.0.1"
|
||||||
|
"smart-mixin" "^2.0.0"
|
||||||
|
|
||||||
"react-native-easy-grid@^0.2.2":
|
"react-native-easy-grid@^0.2.2":
|
||||||
"integrity" "sha512-MlYrNIldnEMKn6TVatQN1P64GoVlwGIuz+8ncdfJ0Wq/xtzUkQwlil8Uksyp7MhKfENE09MQnGNcba6Mx3oSAA=="
|
"integrity" "sha512-MlYrNIldnEMKn6TVatQN1P64GoVlwGIuz+8ncdfJ0Wq/xtzUkQwlil8Uksyp7MhKfENE09MQnGNcba6Mx3oSAA=="
|
||||||
"resolved" "https://registry.npmjs.org/react-native-easy-grid/-/react-native-easy-grid-0.2.2.tgz"
|
"resolved" "https://registry.npmjs.org/react-native-easy-grid/-/react-native-easy-grid-0.2.2.tgz"
|
||||||
@@ -7355,17 +7363,14 @@
|
|||||||
"invariant" "^2.2.4"
|
"invariant" "^2.2.4"
|
||||||
"prop-types" "^15.7.2"
|
"prop-types" "^15.7.2"
|
||||||
|
|
||||||
"react-native-image-pan-zoom@^2.1.12":
|
"react-native-image-gallery@^2.1.5":
|
||||||
"integrity" "sha512-BF66XeP6dzuANsPmmFsJshM2Jyh/Mo1t8FsGc1L9Q9/sVP8MJULDabB1hms+eAoqgtyhMr5BuXV3E1hJ5U5H6Q=="
|
"integrity" "sha512-xC7nuPu4GUH0da6byofQ10LjtqlKj+VaLc0NHBJmeMHVvdvmRvFEO6UOq0Q0m/ePx3OQiPTNwGbf5BSPJEKa0w=="
|
||||||
"resolved" "https://registry.npmjs.org/react-native-image-pan-zoom/-/react-native-image-pan-zoom-2.1.12.tgz"
|
"resolved" "https://registry.npmjs.org/react-native-image-gallery/-/react-native-image-gallery-2.1.5.tgz"
|
||||||
"version" "2.1.12"
|
"version" "2.1.5"
|
||||||
|
|
||||||
"react-native-image-zoom-viewer@^3.0.1":
|
|
||||||
"integrity" "sha512-la6s5DNSuq4GCRLsi5CZ29FPjgTpdCuGIRdO5T9rUrAtxrlpBPhhSnHrbmPVxsdtOUvxHacTh2Gfa9+RraMZQA=="
|
|
||||||
"resolved" "https://registry.npmjs.org/react-native-image-zoom-viewer/-/react-native-image-zoom-viewer-3.0.1.tgz"
|
|
||||||
"version" "3.0.1"
|
|
||||||
dependencies:
|
dependencies:
|
||||||
"react-native-image-pan-zoom" "^2.1.12"
|
"prop-types" "^15.6.0"
|
||||||
|
"react-mixin" "^3.0.5"
|
||||||
|
"react-timer-mixin" "^0.13.3"
|
||||||
|
|
||||||
"react-native-indicators@^0.17.0":
|
"react-native-indicators@^0.17.0":
|
||||||
"integrity" "sha512-s23em477GHGxWeGczWrixScAZD6tQU4mx1fttlrwhEGKOxhBgp55Kh3RoD9Wj4yna4e5W35xQNoPqoJAT6QW5A=="
|
"integrity" "sha512-s23em477GHGxWeGczWrixScAZD6tQU4mx1fttlrwhEGKOxhBgp55Kh3RoD9Wj4yna4e5W35xQNoPqoJAT6QW5A=="
|
||||||
@@ -7499,7 +7504,7 @@
|
|||||||
"resolved" "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz"
|
"resolved" "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz"
|
||||||
"version" "0.4.3"
|
"version" "0.4.3"
|
||||||
|
|
||||||
"react-timer-mixin@^0.13.4":
|
"react-timer-mixin@^0.13.3", "react-timer-mixin@^0.13.4":
|
||||||
"integrity" "sha512-4+ow23tp/Tv7hBM5Az5/Be/eKKF7DIvJ09voz5LyHGQaqqz9WV8YMs31eFvcYQs7d451LSg7kDJV70XYN/Ug/Q=="
|
"integrity" "sha512-4+ow23tp/Tv7hBM5Az5/Be/eKKF7DIvJ09voz5LyHGQaqqz9WV8YMs31eFvcYQs7d451LSg7kDJV70XYN/Ug/Q=="
|
||||||
"resolved" "https://registry.npmjs.org/react-timer-mixin/-/react-timer-mixin-0.13.4.tgz"
|
"resolved" "https://registry.npmjs.org/react-timer-mixin/-/react-timer-mixin-0.13.4.tgz"
|
||||||
"version" "0.13.4"
|
"version" "0.13.4"
|
||||||
@@ -8069,6 +8074,11 @@
|
|||||||
"resolved" "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz"
|
"resolved" "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz"
|
||||||
"version" "1.4.7"
|
"version" "1.4.7"
|
||||||
|
|
||||||
|
"smart-mixin@^2.0.0":
|
||||||
|
"integrity" "sha1-o0oQVeMqdbMNK048oyPcmctT9Dc="
|
||||||
|
"resolved" "https://registry.npmjs.org/smart-mixin/-/smart-mixin-2.0.0.tgz"
|
||||||
|
"version" "2.0.0"
|
||||||
|
|
||||||
"snapdragon-node@^2.0.1":
|
"snapdragon-node@^2.0.1":
|
||||||
"integrity" "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw=="
|
"integrity" "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw=="
|
||||||
"resolved" "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz"
|
"resolved" "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user