2025-08-11 19:34:16 +00:00
|
|
|
import React, { useRef } from 'react';
|
2025-04-19 02:50:53 +00:00
|
|
|
import styled from 'styled-components';
|
2025-08-12 20:36:26 +00:00
|
|
|
import { router } from 'expo-router';
|
2024-10-05 23:10:41 +00:00
|
|
|
import { useCallFeed } from '../hooks/useCallFeed';
|
|
|
|
|
import { Platform, Linking, View, ScrollView, Text, TouchableOpacity } from 'react-native';
|
2025-08-11 19:34:16 +00:00
|
|
|
import { useLocalSearchParams } from 'expo-router';
|
2024-10-02 04:16:04 +00:00
|
|
|
import { StatusBar } from 'expo-status-bar';
|
|
|
|
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
|
|
|
import { Ionicons } from '@expo/vector-icons';
|
2024-10-05 23:10:41 +00:00
|
|
|
import { AccidentAndEmergency } from "healthicons-react-native/dist/outline";
|
|
|
|
|
import { Phone } from "healthicons-react-native/dist/filled";
|
2024-10-02 04:16:04 +00:00
|
|
|
import {
|
|
|
|
|
PageHeader,
|
2024-10-05 23:10:41 +00:00
|
|
|
PageFooter,
|
2025-08-11 19:34:16 +00:00
|
|
|
} from '@/components/generalHelpers.jsx';
|
2025-04-19 02:50:53 +00:00
|
|
|
import ActionSheet from 'react-native-actions-sheet';
|
|
|
|
|
|
|
|
|
|
const DepartmentActionSheet = styled(ActionSheet)``;
|
2024-10-02 04:16:04 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
function fromBase64Unicode(str) {
|
|
|
|
|
return new TextDecoder().decode(Uint8Array.from(atob(str), c => c.charCodeAt(0)));
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-19 16:40:07 +00:00
|
|
|
export default function Call() {
|
2025-08-12 20:36:26 +00:00
|
|
|
const { callDetails } = useLocalSearchParams();
|
|
|
|
|
const actionSheetRef = useRef(null);
|
|
|
|
|
const callFeed = useCallFeed(true);
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
departments,
|
|
|
|
|
callIconMap,
|
|
|
|
|
callColorSelector,
|
|
|
|
|
formatCallTimePast,
|
|
|
|
|
formatCallDateTime
|
|
|
|
|
} = callFeed;
|
2024-10-05 23:10:41 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
const {
|
|
|
|
|
departmentTypeMap,
|
|
|
|
|
accountDetails,
|
|
|
|
|
selectedDepartment,
|
|
|
|
|
setSelectedDepartment,
|
|
|
|
|
updateSelectedDepartment,
|
|
|
|
|
selectedDepartmentColorPicker,
|
|
|
|
|
deptList,
|
|
|
|
|
} = departments;
|
2024-10-05 23:10:41 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
const decoded = fromBase64Unicode(callDetails);
|
2024-10-02 04:16:04 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
const { incident, address, person, response } = JSON.parse(decoded);
|
|
|
|
|
const { CallThemes } = accountDetails;
|
|
|
|
|
const {
|
|
|
|
|
incID,
|
|
|
|
|
incNumber,
|
|
|
|
|
jurisdictionNumber,
|
|
|
|
|
serviceNumber,
|
|
|
|
|
serviceID,
|
|
|
|
|
incDate,
|
|
|
|
|
incNature,
|
|
|
|
|
incNatureCode,
|
|
|
|
|
incNatureCodeDesc,
|
|
|
|
|
notes,
|
|
|
|
|
status,
|
|
|
|
|
origin,
|
|
|
|
|
} = incident;
|
|
|
|
|
const {
|
|
|
|
|
streetAddress,
|
|
|
|
|
addressApartment,
|
|
|
|
|
town,
|
|
|
|
|
state,
|
|
|
|
|
zipCode,
|
|
|
|
|
latitude,
|
|
|
|
|
longitude,
|
|
|
|
|
county,
|
|
|
|
|
intersection1,
|
|
|
|
|
intersection2,
|
|
|
|
|
locationName,
|
|
|
|
|
weatherCondition,
|
|
|
|
|
} = address;
|
|
|
|
|
const {
|
|
|
|
|
name,
|
|
|
|
|
age,
|
|
|
|
|
gender,
|
|
|
|
|
statement,
|
|
|
|
|
conscious,
|
|
|
|
|
breathing,
|
|
|
|
|
callBackNumber,
|
|
|
|
|
} = person;
|
|
|
|
|
const {
|
|
|
|
|
units
|
|
|
|
|
} = response;
|
2025-04-19 06:36:25 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
const SelectedIcon = callIconMap[incNature] || AccidentAndEmergency;
|
2024-10-05 23:10:41 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
const ownDepartmentResponse = units?.map((unit) => {
|
|
|
|
|
if (unit?.department === selectedDepartment?.dept ||
|
|
|
|
|
selectedDepartment?.addDepts?.includes(unit?.department)) {
|
|
|
|
|
return unit;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
})?.filter((filterItem) => {
|
|
|
|
|
return filterItem;
|
|
|
|
|
});
|
2024-10-05 23:10:41 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
const mutualAidDepartmentResponse = units?.map((unit) => {
|
|
|
|
|
if (unit?.department !== selectedDepartment?.dept &&
|
|
|
|
|
!selectedDepartment?.addDepts?.includes(unit?.department)) {
|
|
|
|
|
return unit;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
})?.filter((filterItem) => {
|
|
|
|
|
return filterItem;
|
|
|
|
|
});;
|
2024-10-05 23:10:41 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
const formatResponseTimes = (time) => {
|
|
|
|
|
if (time === null || time === undefined || time === '') {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
const initTime = new Date(time);
|
|
|
|
|
const hours = initTime.getHours().toString().padStart(2, '0');
|
|
|
|
|
const minutes = initTime.getMinutes().toString().padStart(2, '0');
|
|
|
|
|
return `${hours}:${minutes}`;
|
|
|
|
|
};
|
2024-10-05 23:10:41 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
const openMaps = (latitude, longitude) => {
|
|
|
|
|
const daddr = `${latitude},${longitude}`;
|
|
|
|
|
const company = Platform.OS === "ios" ? "apple" : "google";
|
|
|
|
|
Linking.openURL(`http://maps.${company}.com/maps?daddr=${daddr}`);
|
|
|
|
|
};
|
2024-10-05 23:10:41 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
const callNumber = (number) => {
|
|
|
|
|
const formattedNumber = number.replace(/[()\-\s]/g, '');
|
|
|
|
|
Linking.openURL(`tel:${formattedNumber}`);
|
|
|
|
|
};
|
2024-10-05 23:10:41 +00:00
|
|
|
|
2025-08-12 20:36:26 +00:00
|
|
|
return (
|
|
|
|
|
<React.Fragment>
|
|
|
|
|
<PageHeader
|
|
|
|
|
leftHeader={ <View style={{ flex: 1, alignItems: 'flex-start' }}>
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
onPress={router.back}
|
|
|
|
|
style={{ flexDirection: 'row', alignItems: 'center' }}
|
|
|
|
|
>
|
|
|
|
|
<Ionicons name="chevron-back-outline" size={22} color="red" style={{ paddingLeft: 10 }} />
|
|
|
|
|
<Text style={{ color: 'red', fontWeight: 600 }}>Back to Incidents</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
</View>}
|
|
|
|
|
centerHeader={<View style={{ flex: 1, alignItems: 'center' }}>
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 6,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: '#333',
|
|
|
|
|
shadowOpacity: .8,
|
|
|
|
|
shadowRadius: 2,
|
|
|
|
|
paddingHorizontal: 10,
|
|
|
|
|
paddingVertical: 2,
|
2024-10-05 23:10:41 +00:00
|
|
|
}}
|
2025-08-12 20:36:26 +00:00
|
|
|
onPress={() => {
|
|
|
|
|
actionSheetRef.current?.show();
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
color: selectedDepartmentColorPicker(selectedDepartment?.type),
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
fontSize: 14
|
|
|
|
|
}}
|
2024-10-05 23:10:41 +00:00
|
|
|
>
|
2025-08-12 20:36:26 +00:00
|
|
|
{selectedDepartment?.deptAbv}
|
|
|
|
|
</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
</View>}
|
|
|
|
|
/>
|
|
|
|
|
<ScrollView showsVerticalScrollIndicator={false}>
|
|
|
|
|
<StatusBar style="dark" />
|
|
|
|
|
<SafeAreaView />
|
|
|
|
|
<View style={{ flexDirection: 'column', padding: 20 }}>
|
|
|
|
|
<View key="callDateAndTime"
|
|
|
|
|
style={{
|
|
|
|
|
paddingBottom: 6,
|
|
|
|
|
paddingLeft: 10,
|
|
|
|
|
paddingRight: 10,
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
justifyContent: 'space-between'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text style={{ fontSize: 12 }}>{formatCallDateTime(incDate)}</Text>
|
|
|
|
|
<Text style={{ fontSize: 12 }}>{formatCallTimePast(incDate)}</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<View key="callDetails" style={{ padding: 2 }}>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: callColorSelector(
|
|
|
|
|
incNatureCode,
|
|
|
|
|
incNature,
|
|
|
|
|
status
|
|
|
|
|
),
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 5,
|
|
|
|
|
padding: 10,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<View style={{ flexDirection: 'column' }}>
|
|
|
|
|
<View style={{ flexDirection: 'row', alignItems: 'center', maxWidth: '90%' }}>
|
|
|
|
|
<SelectedIcon
|
|
|
|
|
color={callColorSelector(
|
|
|
|
|
incNatureCode,
|
|
|
|
|
incNature,
|
|
|
|
|
status
|
|
|
|
|
)}
|
|
|
|
|
opacity={0.3}
|
|
|
|
|
width={56}
|
|
|
|
|
height={56}
|
|
|
|
|
/>
|
|
|
|
|
<View style={{ flexDirection: 'column', maxWidth: '90%' }}>
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
color: 'black',
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
fontSize: 16
|
|
|
|
|
}}
|
2024-10-05 23:10:41 +00:00
|
|
|
>
|
2025-08-12 20:36:26 +00:00
|
|
|
{`${incNature}`}
|
2024-10-05 23:10:41 +00:00
|
|
|
</Text>
|
2025-08-12 20:36:26 +00:00
|
|
|
<View style={{ flexDirection: 'row', justifyContent: 'space-between', maxWidth: '90%' }}>
|
|
|
|
|
<Text
|
2024-10-05 23:10:41 +00:00
|
|
|
style={{
|
2025-08-12 20:36:26 +00:00
|
|
|
color: 'black',
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
textShadowColor: callColorSelector(
|
|
|
|
|
incNatureCode,
|
|
|
|
|
incNature,
|
|
|
|
|
status
|
|
|
|
|
),
|
|
|
|
|
textShadowRadius: 1
|
2024-10-05 23:10:41 +00:00
|
|
|
}}
|
2025-08-12 20:36:26 +00:00
|
|
|
>
|
|
|
|
|
{`${incNatureCodeDesc}`}
|
|
|
|
|
</Text>
|
2024-10-05 23:10:41 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
</View>
|
2024-10-05 23:10:41 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
|
|
|
{status.toLowerCase() === 'closed' ? (
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
color: '#'
|
|
|
|
|
}}
|
2024-10-05 23:10:41 +00:00
|
|
|
>
|
2025-08-12 20:36:26 +00:00
|
|
|
This Incident is Closed.
|
|
|
|
|
</Text>
|
|
|
|
|
) : <Text></Text>}
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
textAlign: 'right'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{`Incident #: ${serviceNumber}`}
|
|
|
|
|
</Text>
|
2024-10-05 23:10:41 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
<View style={{ margin: 6 }} />
|
|
|
|
|
<View key="callLocation" style={{ padding: 2 }}>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: 'grey',
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 1,
|
|
|
|
|
padding: 10,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
alignItems: 'top',
|
|
|
|
|
justifyContent: 'space-between'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<View style={{ flexDirection: 'column', maxWidth: '70%' }}>
|
|
|
|
|
{locationName ? (
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
color: 'black',
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
fontSize: 16
|
|
|
|
|
}}
|
2024-10-05 23:10:41 +00:00
|
|
|
>
|
2025-08-12 20:36:26 +00:00
|
|
|
{`${locationName}`}
|
|
|
|
|
</Text>
|
|
|
|
|
) : null}
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
onLongPress={() => {
|
|
|
|
|
return openMaps(latitude, longitude);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text
|
|
|
|
|
style={[{
|
|
|
|
|
color: 'black',
|
|
|
|
|
}, locationName ? {} : { fontSize: 12, fontWeight: 600 }]}
|
2024-10-05 23:10:41 +00:00
|
|
|
>
|
2025-08-12 20:36:26 +00:00
|
|
|
{`${streetAddress}`}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text
|
|
|
|
|
style={[{
|
|
|
|
|
color: 'black',
|
|
|
|
|
}, locationName ? {} : { fontSize: 12, fontWeight: 600 }]}
|
2024-10-05 23:10:41 +00:00
|
|
|
>
|
2025-08-12 20:36:26 +00:00
|
|
|
{`${town}, ${state}`}
|
|
|
|
|
</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
{addressApartment ? (
|
|
|
|
|
<View>
|
|
|
|
|
<View style={{ margin: 10 }} />
|
|
|
|
|
<Text
|
|
|
|
|
style={[{
|
|
|
|
|
color: 'black',
|
|
|
|
|
}, locationName ? {} : { fontSize: 12, fontWeight: 600 }]}
|
|
|
|
|
>
|
|
|
|
|
{`${addressApartment}`}
|
|
|
|
|
</Text>
|
2024-10-05 23:10:41 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
) : null}
|
2024-10-05 23:10:41 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
<View style={{ flexDirection: 'column' }}>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: 'grey',
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 1,
|
|
|
|
|
padding: 25,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text style={{ fontSize: 12 }}>Map</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#ECEDEE',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: 'grey',
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 1,
|
|
|
|
|
marginTop: 6,
|
|
|
|
|
paddingLeft: 6,
|
|
|
|
|
paddingVertical: 6,
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
justifyContent: 'center'
|
|
|
|
|
}}
|
|
|
|
|
onPress={() => {
|
|
|
|
|
return openMaps(latitude, longitude);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text style={{ fontSize: 10 }}>Nav</Text>
|
|
|
|
|
<Ionicons name="chevron-forward-outline" />
|
|
|
|
|
</TouchableOpacity>
|
2024-10-05 23:10:41 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
<View style={{ margin: 6 }} />
|
|
|
|
|
<View key="callCrossStreets"
|
|
|
|
|
style={{
|
|
|
|
|
padding: 2,
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
justifyContent: 'space-evenly',
|
|
|
|
|
marginHorizontal: 2,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: 'grey',
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 1,
|
|
|
|
|
paddingVertical: 14,
|
|
|
|
|
width: "48%"
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
textAlign: 'center'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{intersection1}
|
|
|
|
|
</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<View style={{ paddingHorizontal: "2%" }} />
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: 'grey',
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 1,
|
|
|
|
|
paddingVertical: 14,
|
|
|
|
|
width: "48%"
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
textAlign: 'center'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{intersection2}
|
|
|
|
|
</Text>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
<View style={{ margin: 6 }} />
|
|
|
|
|
<View key="callerInformation" style={{ padding: 2 }}>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: 'grey',
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 1,
|
|
|
|
|
padding: 10,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{selectedDepartment?.supervisor ? (
|
|
|
|
|
<View>
|
|
|
|
|
<View>
|
2024-10-05 23:10:41 +00:00
|
|
|
<View
|
2025-08-12 20:36:26 +00:00
|
|
|
style={{
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
marginHorizontal: 10
|
|
|
|
|
}}
|
2024-10-05 23:10:41 +00:00
|
|
|
>
|
2025-08-12 20:36:26 +00:00
|
|
|
<View style={{ flexDirection: 'column' }}>
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
color: 'black',
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
fontSize: 16
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{`${name}`}
|
|
|
|
|
</Text>
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
onLongPress={() => {
|
|
|
|
|
return callNumber(callBackNumber);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text
|
|
|
|
|
style={{ color: 'black', fontSize: 12 }}
|
|
|
|
|
>
|
|
|
|
|
{`${callBackNumber}`}
|
|
|
|
|
</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
</View>
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
onLongPress={() => {
|
|
|
|
|
return callNumber(callBackNumber);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Phone
|
|
|
|
|
color='blue'
|
|
|
|
|
opacity={0.3}
|
|
|
|
|
width={32}
|
|
|
|
|
height={32}
|
|
|
|
|
/>
|
|
|
|
|
</TouchableOpacity>
|
2024-10-05 23:10:41 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
</View>
|
|
|
|
|
<View
|
2024-10-05 23:10:41 +00:00
|
|
|
style={{
|
2025-08-12 20:36:26 +00:00
|
|
|
marginVertical: 5,
|
|
|
|
|
height: 1,
|
|
|
|
|
width: '100%',
|
|
|
|
|
backgroundColor: 'grey'
|
2024-10-05 23:10:41 +00:00
|
|
|
}}
|
2025-08-12 20:36:26 +00:00
|
|
|
/>
|
|
|
|
|
</View>
|
|
|
|
|
) : null}
|
|
|
|
|
<View style={{ alignItems: 'center' }}>
|
|
|
|
|
<View style={{ flexDirection: 'row' }}>
|
|
|
|
|
<Text style={{ fontSize: 14 }}>
|
|
|
|
|
{`${age} `}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={{ fontSize: 14 }}>
|
|
|
|
|
{`${gender} - `}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={{ fontSize: 14 }}>
|
|
|
|
|
{`Conscious: ${conscious} | `}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={{ fontSize: 14 }}>
|
|
|
|
|
{`Breathing: ${breathing}`}
|
|
|
|
|
</Text>
|
2024-10-05 23:10:41 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
<Text style={{ fontSize: 12 }}>
|
|
|
|
|
{`${statement}`}
|
|
|
|
|
</Text>
|
|
|
|
|
</View>
|
2024-10-02 04:16:04 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
</View>
|
|
|
|
|
<View style={{ alignItems: 'center' }}>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
marginVertical: 10,
|
|
|
|
|
height: 2,
|
|
|
|
|
width: '95%',
|
|
|
|
|
backgroundColor: 'grey'
|
|
|
|
|
}}
|
2024-10-05 23:10:41 +00:00
|
|
|
/>
|
2025-08-12 20:36:26 +00:00
|
|
|
</View>
|
|
|
|
|
<View key="respondingUnitInformation" style={{ padding: 2 }}>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: 'grey',
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 1,
|
|
|
|
|
padding: 10,
|
|
|
|
|
}}
|
2024-10-06 21:55:18 +00:00
|
|
|
>
|
2025-08-12 20:36:26 +00:00
|
|
|
<View style={{ flexDirection: 'column' }}>
|
|
|
|
|
{units?.length > 0 ? (
|
|
|
|
|
<View>
|
|
|
|
|
{ownDepartmentResponse?.length > 0 ? (
|
|
|
|
|
<View>
|
|
|
|
|
<View>
|
|
|
|
|
<View style={{ flexDirection: 'row', justifyContent: 'space-evenly', alignItems: 'center' }}>
|
|
|
|
|
<Text style={{ fontWeight: '600', textAlign: 'center', flex: 1 }}>Units</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>Disp</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>Resp</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>Arr</Text>
|
|
|
|
|
{selectedDepartment?.type === 'EMS' || selectedDepartment?.type === 'Rescue' ? (
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>Trans</Text>
|
|
|
|
|
) : null}
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>BIS</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
marginVertical: 5,
|
|
|
|
|
height: 1,
|
|
|
|
|
width: '95%',
|
|
|
|
|
backgroundColor: 'grey',
|
|
|
|
|
alignSelf: 'center'
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
flex: 1,
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'center'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{ownDepartmentResponse?.map((unit) => {
|
|
|
|
|
return (
|
|
|
|
|
<View key={unit?.unit}
|
|
|
|
|
style={{
|
|
|
|
|
flex: 1,
|
|
|
|
|
alignSelf: 'stretch',
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
justifyContent: 'space-evenly',
|
|
|
|
|
alignItems: 'center'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text
|
2024-10-06 21:55:18 +00:00
|
|
|
style={{
|
2025-08-12 20:36:26 +00:00
|
|
|
fontSize: 12,
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
flex: 1
|
2024-10-06 21:55:18 +00:00
|
|
|
}}
|
2025-08-12 20:36:26 +00:00
|
|
|
>
|
|
|
|
|
{unit?.unit}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.dispatched)}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.responding)}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.onScene)}
|
|
|
|
|
</Text>
|
|
|
|
|
{selectedDepartment?.type === 'EMS' ||
|
|
|
|
|
selectedDepartment?.type === 'Rescue' ? (
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.transporting)}
|
|
|
|
|
</Text>
|
|
|
|
|
) : null}
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.inService)}
|
|
|
|
|
</Text>
|
|
|
|
|
</View>
|
|
|
|
|
)
|
|
|
|
|
})}
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
) : (
|
|
|
|
|
<View style={{ alignItems: 'center' }}>
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
textAlign: 'center'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{`No ${selectedDepartment?.dept} Units Responding`}
|
|
|
|
|
</Text>
|
|
|
|
|
</View>
|
|
|
|
|
)}
|
|
|
|
|
{mutualAidDepartmentResponse?.length > 0 ? (
|
|
|
|
|
<View>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
marginVertical: 5,
|
|
|
|
|
height: 2,
|
|
|
|
|
width: '100%',
|
|
|
|
|
backgroundColor: 'grey',
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<View style={{ flexDirection: 'row', justifyContent: 'space-evenly', alignItems: 'center' }}>
|
|
|
|
|
<Text style={{ fontWeight: '600', textAlign: 'center', flex: 1 }}>M/A</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>Disp</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>Resp</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>Arr</Text>
|
|
|
|
|
{selectedDepartment?.type === 'EMS' || selectedDepartment?.type === 'Rescue' ? (
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>Trans</Text>
|
|
|
|
|
) : null}
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>BIS</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
marginVertical: 5,
|
|
|
|
|
height: 1,
|
|
|
|
|
width: '95%',
|
|
|
|
|
backgroundColor: 'grey',
|
|
|
|
|
alignSelf: 'center'
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
{mutualAidDepartmentResponse?.map((unit) => {
|
|
|
|
|
return (
|
|
|
|
|
<View key={unit?.unit}
|
|
|
|
|
style={{
|
|
|
|
|
flex: 1,
|
|
|
|
|
alignSelf: 'stretch',
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
justifyContent: 'space-evenly',
|
|
|
|
|
alignItems: 'center'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
flex: 1
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{unit?.unit}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.dispatched)}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.responding)}
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.onScene)}
|
|
|
|
|
</Text>
|
|
|
|
|
{selectedDepartment?.type === 'EMS' ||
|
|
|
|
|
selectedDepartment?.type === 'Rescue' ? (
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.transporting)}
|
|
|
|
|
</Text>
|
|
|
|
|
) : null}
|
|
|
|
|
<Text style={{ textAlign: 'center', flex: 1 }}>
|
|
|
|
|
{formatResponseTimes(unit?.inService)}
|
|
|
|
|
</Text>
|
2024-10-06 21:55:18 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
)
|
|
|
|
|
})}
|
|
|
|
|
</View>
|
|
|
|
|
) : null}
|
|
|
|
|
</View>
|
|
|
|
|
) : (
|
|
|
|
|
<View style={{ alignItems: 'center' }}>
|
|
|
|
|
<Text>No Units Responding</Text>
|
|
|
|
|
</View>
|
|
|
|
|
)}
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
<View style={{ margin: 6 }} />
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
color: 'grey',
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
paddingLeft: 10
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Incident Notes
|
|
|
|
|
</Text>
|
|
|
|
|
<View style={{ margin: 2 }} />
|
|
|
|
|
<View key="incidentNotes" style={{ padding: 2 }}>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
shadowOffset: { width: 0, height: 0 },
|
|
|
|
|
shadowColor: 'grey',
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 1,
|
|
|
|
|
padding: 10,
|
|
|
|
|
minHeight: 200
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{notes?.split('\n').map((note, index) => (
|
|
|
|
|
<View key={`notes-${index}`}>
|
|
|
|
|
<Text>{note}</Text>
|
|
|
|
|
{index < notes.split('\n').length - 1 && (
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
height: 1,
|
|
|
|
|
backgroundColor: 'grey',
|
|
|
|
|
marginVertical: 10
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2024-10-06 21:55:18 +00:00
|
|
|
</View>
|
2025-08-12 20:36:26 +00:00
|
|
|
))}
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
</ScrollView>
|
|
|
|
|
<PageFooter>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
height: 100,
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'flex-start',
|
|
|
|
|
paddingTop: 7
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</PageFooter>
|
|
|
|
|
<DepartmentActionSheet
|
|
|
|
|
ref={actionSheetRef}
|
|
|
|
|
gestureEnabled
|
|
|
|
|
containerStyle={{
|
|
|
|
|
height: "50%",
|
|
|
|
|
width: "100%",
|
|
|
|
|
backgroundColor: '#ECEDEE',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<View style={{ flexDirection: 'column', padding: 20 }}>
|
|
|
|
|
{deptList?.map((item) => {
|
|
|
|
|
return (
|
|
|
|
|
<View style={{ padding: 2 }} key={item?.deptId}>
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 6,
|
|
|
|
|
elevation: 3,
|
|
|
|
|
backgroundColor: item?.selected ? 'grey' : '#fff',
|
|
|
|
|
shadowOffset: { width: 1, height: 1 },
|
|
|
|
|
shadowColor: '#333',
|
|
|
|
|
shadowOpacity: 0.3,
|
|
|
|
|
shadowRadius: 2,
|
|
|
|
|
marginHorizontal: 20,
|
|
|
|
|
marginVertical: 6,
|
|
|
|
|
padding: 10
|
|
|
|
|
}}
|
|
|
|
|
onPress={() => {
|
|
|
|
|
actionSheetRef.current?.hide();
|
|
|
|
|
return updateSelectedDepartment(
|
|
|
|
|
selectedDepartment?.deptId,
|
|
|
|
|
item?.deptId
|
|
|
|
|
)
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
color: selectedDepartmentColorPicker(
|
|
|
|
|
item?.type
|
|
|
|
|
),
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
fontSize: '16'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{item?.dept}
|
|
|
|
|
</Text>
|
|
|
|
|
{item?.primary ? <Ionicons name="star" size={16} color="yellow" style={{
|
|
|
|
|
paddingLeft: 20,
|
|
|
|
|
shadowColor: '#333',
|
|
|
|
|
shadowOffset: 1,
|
|
|
|
|
shadowOpacity: 1,
|
|
|
|
|
shadowRadius: 6
|
|
|
|
|
}} /> : null}
|
|
|
|
|
</View>
|
|
|
|
|
<Text>{`${item?.deptAbv} - ${departmentTypeMap[item?.type]}`}</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
</View>
|
|
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
</View>
|
|
|
|
|
</DepartmentActionSheet>
|
|
|
|
|
</React.Fragment>
|
|
|
|
|
);
|
|
|
|
|
}
|