Feature/notification system #26
4 changed files with 86 additions and 63 deletions
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { useCallFeed } from '../hooks/useCallFeed';
|
||||
import { Platform, Linking, View, ScrollView, Text, TouchableOpacity } from 'react-native';
|
||||
import { useLocalSearchParams, router } from 'expo-router';
|
||||
import { useLocalSearchParams } from 'expo-router';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
|
|
@ -11,7 +11,7 @@ import { Phone } from "healthicons-react-native/dist/filled";
|
|||
import {
|
||||
PageHeader,
|
||||
PageFooter,
|
||||
} from '../components/generalHelpers.jsx';
|
||||
} from '@/components/generalHelpers.jsx';
|
||||
import ActionSheet from 'react-native-actions-sheet';
|
||||
|
||||
const DepartmentActionSheet = styled(ActionSheet)``;
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ export default function Incidents() {
|
|||
formatCallDateTime
|
||||
} = callFeed;
|
||||
|
||||
const sortedAndFilteredCalls = callDetails
|
||||
.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
|
||||
const sortedAndFilteredCalls = callDetails.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
|
||||
.filter((item, index, self) => {
|
||||
return index === self.findIndex(i => {
|
||||
return `${i?.data?.Incident?.IncID}${i?.data?.Response?.ServiceName}` === `${item?.data?.Incident?.IncID}${item?.data?.Response?.ServiceName}`
|
||||
return `${i?.incident?.incID}${i?.response?.serviceName}` === `${item?.incident?.incID}${item?.response?.serviceName}`
|
||||
});
|
||||
});
|
||||
})?.map(item => { return {...item, timestamp: item?.incident?.incDate} })
|
||||
|| [];
|
||||
|
||||
const {
|
||||
departmentTypeMap,
|
||||
|
|
@ -93,31 +93,30 @@ export default function Incidents() {
|
|||
<View style={{ flexDirection: 'column', padding: 20 }}>
|
||||
{sortedAndFilteredCalls?.length ? (
|
||||
sortedAndFilteredCalls?.map((callItem, index) => {
|
||||
const { data: call, timestamp } = callItem;
|
||||
const { Incident, Address, Response } = call;
|
||||
const { incident, address, response, timestamp } = callItem;
|
||||
const {
|
||||
ServiceNumber,
|
||||
IncDate,
|
||||
IncNature,
|
||||
IncNatureCode,
|
||||
IncNatureCodeDesc,
|
||||
Status,
|
||||
} = Incident;
|
||||
serviceNumber,
|
||||
incDate,
|
||||
incNature,
|
||||
incNatureCode,
|
||||
incNatureCodeDesc,
|
||||
status,
|
||||
} = incident;
|
||||
const {
|
||||
StreetAddress,
|
||||
AddressApartment,
|
||||
Town,
|
||||
State,
|
||||
LocationName,
|
||||
} = Address;
|
||||
streetAddress,
|
||||
addressApartment,
|
||||
town,
|
||||
state,
|
||||
locationName,
|
||||
} = address;
|
||||
const {
|
||||
ServiceName
|
||||
} = Response;
|
||||
const SelectedIcon = callIconMap[IncNature] || AccidentAndEmergency;
|
||||
serviceName
|
||||
} = response;
|
||||
const SelectedIcon = callIconMap[incNature] || AccidentAndEmergency;
|
||||
return (
|
||||
<TouchableOpacity
|
||||
key={`callDetails - ${timestamp}`}
|
||||
style={{ padding: 2 }}
|
||||
style={{ paddingBottom: 15 }}
|
||||
onPress={() => {
|
||||
router.push({
|
||||
pathname: '/call',
|
||||
|
|
@ -134,9 +133,9 @@ export default function Incidents() {
|
|||
backgroundColor: '#fff',
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowColor: callColorSelector(
|
||||
IncNatureCode,
|
||||
IncNature,
|
||||
Status
|
||||
incNatureCodeDesc,
|
||||
incNature,
|
||||
status
|
||||
),
|
||||
shadowOpacity: 1,
|
||||
shadowRadius: 5,
|
||||
|
|
@ -151,10 +150,10 @@ export default function Incidents() {
|
|||
justifyContent: 'space-between'
|
||||
}}
|
||||
>
|
||||
<Text style={{ fontSize: 12 }}>{formatCallDateTime(IncDate)}</Text>
|
||||
<Text style={{ fontSize: 12 }}>{formatCallDateTime(incDate)}</Text>
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
<Text style={{ fontSize: 12 }}>{formatCallTimePast(IncDate)}</Text>
|
||||
{Status === 'CLOSED' ? (
|
||||
<Text style={{ fontSize: 12 }}>{formatCallTimePast(incDate)}</Text>
|
||||
{status === 'CLOSED' ? (
|
||||
<Ionicons
|
||||
name="lock-closed-outline"
|
||||
color='red'
|
||||
|
|
@ -171,16 +170,16 @@ export default function Incidents() {
|
|||
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<SelectedIcon
|
||||
color={callColorSelector(
|
||||
IncNatureCode,
|
||||
IncNature,
|
||||
Status
|
||||
incNatureCodeDesc,
|
||||
incNature,
|
||||
status
|
||||
)}
|
||||
opacity={0.3}
|
||||
width={56}
|
||||
height={56}
|
||||
/>
|
||||
<View style={{ flexDirection: 'column' }}>
|
||||
{LocationName ? (
|
||||
{locationName ? (
|
||||
<Text
|
||||
style={{
|
||||
color: 'black',
|
||||
|
|
@ -188,7 +187,7 @@ export default function Incidents() {
|
|||
fontSize: 16
|
||||
}}
|
||||
>
|
||||
{`${LocationName}`}
|
||||
{`${locationName}`}
|
||||
</Text>
|
||||
) : (
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
|
|
@ -199,9 +198,9 @@ export default function Incidents() {
|
|||
fontWeight: 600
|
||||
}]}
|
||||
>
|
||||
{`${StreetAddress}`}
|
||||
{`${streetAddress?.split(',')[0]}`}
|
||||
</Text>
|
||||
{AddressApartment ? (
|
||||
{addressApartment ? (
|
||||
<Text
|
||||
style={[{
|
||||
color: 'black',
|
||||
|
|
@ -209,7 +208,7 @@ export default function Incidents() {
|
|||
fontWeight: 600
|
||||
}]}
|
||||
>
|
||||
{` - ${AddressApartment}`}
|
||||
{` - ${addressApartment}`}
|
||||
</Text>
|
||||
) : null}
|
||||
<Text
|
||||
|
|
@ -219,7 +218,7 @@ export default function Incidents() {
|
|||
fontWeight: 600
|
||||
}]}
|
||||
>
|
||||
{` ${Town}, ${State}`}
|
||||
{` ${town}, ${state}`}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
|
@ -230,7 +229,7 @@ export default function Incidents() {
|
|||
fontSize: 16
|
||||
}}
|
||||
>
|
||||
{`${IncNature}`}
|
||||
{`${incNature}`}
|
||||
</Text>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||
<Text
|
||||
|
|
@ -238,14 +237,14 @@ export default function Incidents() {
|
|||
color: 'black',
|
||||
fontSize: 12,
|
||||
textShadowColor: callColorSelector(
|
||||
IncNatureCode,
|
||||
IncNature,
|
||||
Status
|
||||
incNatureCode,
|
||||
incNature,
|
||||
status
|
||||
),
|
||||
textShadowRadius: 1
|
||||
}}
|
||||
>
|
||||
{`${IncNatureCodeDesc}`}
|
||||
{`${incNatureCodeDesc}`}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
|
@ -261,7 +260,7 @@ export default function Incidents() {
|
|||
fontSize: 12,
|
||||
}}
|
||||
>
|
||||
Service: {ServiceName}
|
||||
Service: {serviceName}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
|
|
@ -269,7 +268,7 @@ export default function Incidents() {
|
|||
textAlign: 'right'
|
||||
}}
|
||||
>
|
||||
{`Incident #: ${ServiceNumber}`}
|
||||
{`Incident #: ${serviceNumber}`}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -86,16 +86,16 @@ const formatCallDateTime = (callValue) => {
|
|||
const getIncidents = async (departments, incidentStatus) => {
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(`${process.env.EXPO_PUBLIC_DATABASE_URL}/api/getRecentCalls`, {
|
||||
response = await fetch(`${process.env.EXPO_PUBLIC_DATABASE_URL}/getRecentCalls/${5}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
apiKey: process.env.EXPO_PUBLIC_DATABASE_API_KEY
|
||||
},
|
||||
body: JSON.stringify({
|
||||
departments,
|
||||
status: incidentStatus,
|
||||
}),
|
||||
// body: JSON.stringify({
|
||||
// callCount: 25,
|
||||
// departments,
|
||||
// status: incidentStatus,
|
||||
// }),
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Failed to fetch initial calls:", e);
|
||||
|
|
@ -114,9 +114,12 @@ export const useCallFeed = () => {
|
|||
const [selectedStatus, setSelectedStatus] = useState({id: 'all', value: 'All Incidents'});
|
||||
|
||||
useEffect(() => {
|
||||
const incidents = getIncidents(InitList?.map((dept) => { return dept?.id }), selectedStatus?.id);
|
||||
setAllCalls(incidents);
|
||||
setInit(false);
|
||||
async function fetchData() {
|
||||
const incidents = await getIncidents(InitList?.map((dept) => { return dept?.id }), selectedStatus?.id);
|
||||
setAllCalls(incidents);
|
||||
setInit(false);
|
||||
}
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -129,14 +132,17 @@ export const useCallFeed = () => {
|
|||
}, [lastMessage]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!init) {
|
||||
const incidents = getIncidents(InitList?.map((dept) => { return dept?.id }), selectedStatus?.id);
|
||||
async function fetchData() {
|
||||
const incidents = await getIncidents(InitList?.map((dept) => { return dept?.id }), selectedStatus?.id);
|
||||
setAllCalls(incidents);
|
||||
}
|
||||
if (!init) {
|
||||
fetchData();
|
||||
}
|
||||
}, [selectedStatus]);
|
||||
|
||||
const callColorSelector = (callAcuity, cardiacArrestCall, status) => {
|
||||
if (status === "CLOSED") {
|
||||
if (status?.toLowerCase() === "closed") {
|
||||
return "#0000CD";
|
||||
} else if (CriticalCallList.includes(cardiacArrestCall)) {
|
||||
return "#8B0000";
|
||||
|
|
|
|||
|
|
@ -12,14 +12,32 @@ const accountDetails = {
|
|||
"CARDIAC ARREST|DEATH",
|
||||
],
|
||||
"HighCallList": [
|
||||
"ALS"
|
||||
"EMS ALS PRIORITY (ALS)",
|
||||
"EMS Advanced Life Support life threatening response (ALS)",
|
||||
"EMS ALS Intercept Required",
|
||||
"EMS ALS Response – Cardiac Related",
|
||||
"EMS ALS Response – Respiratory Distress",
|
||||
"EMS ALS Response – Stroke Alert",
|
||||
"EMS Basic Life Support with Paramedic Assist (BLS)",
|
||||
"EMS ALS Tiered Response with Fire",
|
||||
"EMS Response – Behavioral Emergency (ALS)",
|
||||
"EMS Response – Obstetric Emergency (ALS)",
|
||||
"EMS ALS Response – Overdose / Poisoning",
|
||||
"EMS ALS Priority Interfacility Transfer",
|
||||
"EMS Response – Unresponsive / Unconscious Patient (ALS)"
|
||||
],
|
||||
"MediumCallList": [
|
||||
"ALS-STANDARD",
|
||||
"BLS-PRIORITY"
|
||||
"BLS-PRIORITY",
|
||||
"EMS BLS Priority Response",
|
||||
"EMS BLS Response – Fall Injury"
|
||||
],
|
||||
"LowCallList": [
|
||||
"BLS-STANDARD"
|
||||
"EMS Standard Basic Life Support Response (BLS)",
|
||||
"EMS BLS Non-Emergency Transport",
|
||||
"EMS BLS Standby – Event Coverage",
|
||||
"EMS Public Assist – Lift Only (BLS)",
|
||||
"EMS BLS Scheduled Interfacility Transport"
|
||||
]
|
||||
},
|
||||
"InitList": [
|
||||
|
|
|
|||
Loading…
Reference in a new issue