Add job tabs.
This commit is contained in:
59
app/jobs/[jobId]/_layout.tsx
Normal file
59
app/jobs/[jobId]/_layout.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import FontAwesome from "@expo/vector-icons/FontAwesome";
|
||||||
|
import { Tabs } from "expo-router";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
function JobTabLayout() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tabs
|
||||||
|
screenOptions={{
|
||||||
|
tabBarActiveTintColor: "blue",
|
||||||
|
tabBarPosition: "top",
|
||||||
|
headerShown: false,
|
||||||
|
tabBarStyle: {
|
||||||
|
marginTop: -50,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="index"
|
||||||
|
options={{
|
||||||
|
title: t("jobdetail.labels.job"),
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<FontAwesome size={28} name="home" color={color} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="lines"
|
||||||
|
options={{
|
||||||
|
title: t("jobdetail.labels.lines"),
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<FontAwesome size={28} name="cog" color={color} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="documents"
|
||||||
|
options={{
|
||||||
|
title: t("jobdetail.labels.documents"),
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<FontAwesome size={28} name="cog" color={color} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="notes"
|
||||||
|
options={{
|
||||||
|
title: t("jobdetail.labels.notes"),
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<FontAwesome size={28} name="cog" color={color} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tabs>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JobTabLayout;
|
||||||
10
app/jobs/[jobId]/documents.tsx
Normal file
10
app/jobs/[jobId]/documents.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
|
function Documents() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>Documents</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Documents;
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
import { useLocalSearchParams } from "expo-router";
|
import { useLocalSearchParams } from "expo-router";
|
||||||
import { StyleSheet, Text, View } from "react-native";
|
import { StyleSheet, Text, View } from "react-native";
|
||||||
|
import JobDetail from "../../../components/job-detail/job-detail";
|
||||||
|
|
||||||
export default function JobDetail() {
|
export default function JobDetailScreen() {
|
||||||
const params = useLocalSearchParams();
|
const params = useLocalSearchParams();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text>Job Details for Job ID: {JSON.stringify(params)}</Text>
|
<Text>Job Details for Job ID: {JSON.stringify(params)}</Text>
|
||||||
|
<JobDetail />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
10
app/jobs/[jobId]/lines.tsx
Normal file
10
app/jobs/[jobId]/lines.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
|
function JobLines() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>Job Lines</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default JobLines;
|
||||||
10
app/jobs/[jobId]/notes.tsx
Normal file
10
app/jobs/[jobId]/notes.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
|
function Notes() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>Notes</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Notes;
|
||||||
@@ -31,6 +31,7 @@ function JobsStack() {
|
|||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="[jobId]"
|
name="[jobId]"
|
||||||
options={({ route }) => ({
|
options={({ route }) => ({
|
||||||
|
//headerShown: false,
|
||||||
title: (route.params as any)?.title || "Job Details",
|
title: (route.params as any)?.title || "Job Details",
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
|||||||
9
components/error/error-display.jsx
Normal file
9
components/error/error-display.jsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
|
export default function ErrorDisplay({ errorMessage }) {
|
||||||
|
return (
|
||||||
|
<View style={{ backgroundColor: "red" }}>
|
||||||
|
<Text>{errorMessage}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
173
components/job-detail/job-detail.jsx
Normal file
173
components/job-detail/job-detail.jsx
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
import React from "react";
|
||||||
|
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 "../data-label/data-label.component";
|
||||||
|
import StyleRepeater from "../style-repeater/style-repeater";
|
||||||
|
import styles from "../styles";
|
||||||
|
|
||||||
|
export default function JobTombstone({ job, loading, refetch }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
if (!job) {
|
||||||
|
<Card>
|
||||||
|
<Text>Job is not defined.</Text>
|
||||||
|
</Card>;
|
||||||
|
}
|
||||||
|
const onRefresh = async () => {
|
||||||
|
return refetch();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView
|
||||||
|
style={styles.cardBackground}
|
||||||
|
refreshControl={
|
||||||
|
<RefreshControl refreshing={loading} onRefresh={onRefresh} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<StyleRepeater childStyle={{ margin: 4 }}>
|
||||||
|
<Card>
|
||||||
|
<Card.Title title={t("jobdetail.labels.jobinfo")} />
|
||||||
|
<Card.Content>
|
||||||
|
<Headline>{job.status}</Headline>
|
||||||
|
{job.inproduction && (
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<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={
|
||||||
|
<View>
|
||||||
|
<Text>{`${job.v_model_yr || ""} ${job.v_make_desc || ""} ${
|
||||||
|
job.v_model_desc || ""
|
||||||
|
}`}</Text>
|
||||||
|
<Text>{job.v_vin}</Text>
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={localStyles.twoColumnCardColumn}>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.ins_co_nm")}
|
||||||
|
content={job.ins_co_nm}
|
||||||
|
/>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.clm_no")}
|
||||||
|
content={job.clm_no}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<Card.Title title={t("jobdetail.labels.employeeassignments")} />
|
||||||
|
<Card.Content>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.employee_body")}
|
||||||
|
content={`${
|
||||||
|
(job.employee_body_rel && job.employee_body_rel.first_name) ||
|
||||||
|
""
|
||||||
|
} ${
|
||||||
|
(job.employee_body_rel && job.employee_body_rel.last_name) || ""
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.employee_prep")}
|
||||||
|
content={`${
|
||||||
|
(job.employee_prep_rel && job.employee_prep_rel.first_name) ||
|
||||||
|
""
|
||||||
|
} ${
|
||||||
|
(job.employee_prep_rel && job.employee_prep_rel.last_name) || ""
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.employee_refinish")}
|
||||||
|
content={`${
|
||||||
|
(job.employee_refinish_rel &&
|
||||||
|
job.employee_refinish_rel.first_name) ||
|
||||||
|
""
|
||||||
|
} ${
|
||||||
|
(job.employee_refinish_rel &&
|
||||||
|
job.employee_refinish_rel.last_name) ||
|
||||||
|
""
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.employee_csr")}
|
||||||
|
content={`${
|
||||||
|
(job.employee_csr_rel && job.employee_csr_rel.first_name) || ""
|
||||||
|
} ${
|
||||||
|
(job.employee_csr_rel && job.employee_csr_rel.last_name) || ""
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<Card.Title title={t("jobdetail.labels.dates")} />
|
||||||
|
<Card.Content style={localStyles.twoColumnCard}>
|
||||||
|
<View style={localStyles.twoColumnCardColumn}>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.scheduled_in")}
|
||||||
|
content={job.scheduled_in}
|
||||||
|
dateTime
|
||||||
|
/>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.actual_in")}
|
||||||
|
content={job.actual_in}
|
||||||
|
dateTime
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={localStyles.twoColumnCardColumn}>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.scheduled_completion")}
|
||||||
|
content={job.scheduled_completion}
|
||||||
|
dateTime
|
||||||
|
/>
|
||||||
|
<DataLabelComponent
|
||||||
|
label={t("objects.jobs.fields.scheduled_delivery")}
|
||||||
|
content={job.scheduled_delivery}
|
||||||
|
dateTime
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
|
</StyleRepeater>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const localStyles = StyleSheet.create({
|
||||||
|
twoColumnCard: { display: "flex", flexDirection: "row" },
|
||||||
|
twoColumnCardColumn: { flex: 1 },
|
||||||
|
status: {
|
||||||
|
textAlign: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
inproduction: {
|
||||||
|
textAlign: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user