diff --git a/app/_layout.tsx b/app/_layout.tsx
index 2fceb79..268ecb7 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -7,25 +7,10 @@ export const unstable_settings = {
};
export default function App() {
-
- const [auth, setAuth] = useState(false);
-
useEffect(() => {
- if (auth) {
- router.replace('./landing');
- } else {
- router.replace('/login');
- }
+ router.replace('/login');
}, []);
- useEffect(() => {
- if (auth) {
- router.replace('./landing');
- } else {
- router.replace('/login');
- }
- }, [auth]);
-
return (
+
);
diff --git a/app/generalHelpers.jsx b/app/generalHelpers.jsx
index a0a02ce..be881d3 100644
--- a/app/generalHelpers.jsx
+++ b/app/generalHelpers.jsx
@@ -207,7 +207,17 @@ export const PageHeader = ({
children
}) => {
return (
-
+
+ {children}
+
+ )
+}
+
+export const PageFooter = ({
+ children
+}) => {
+ return (
+
{children}
)
diff --git a/app/incidents.jsx b/app/incidents.jsx
new file mode 100644
index 0000000..c3eb616
--- /dev/null
+++ b/app/incidents.jsx
@@ -0,0 +1,202 @@
+import React, { useState, useRef, useEffect } from 'react';
+import styled from 'styled-components';
+import { useCallFeed } from '../hooks/useCallFeed';
+import { Platform, Linking, View, ScrollView, Text, TouchableOpacity } from 'react-native';
+import {
+ PageHeader,
+ PageFooter,
+} from './generalHelpers.jsx';
+import { Ionicons } from '@expo/vector-icons';
+import ActionSheet from 'react-native-actions-sheet';
+
+const DepartmentActionSheet = styled(ActionSheet)``;
+
+export default function Incidents() {
+ const actionSheetRef = useRef(null);
+ const callFeed = useCallFeed();
+
+ const {
+ departments,
+ callIconMap,
+ callDetails,
+ callColorSelector,
+ } = callFeed;
+
+ const {
+ departmentTypeMap,
+ accountDetails,
+ deptList,
+ setDeptList,
+ selectedDepartment,
+ setSelectedDepartment,
+ updateSelectedDepartment,
+ selectedDepartmentColorPicker,
+ } = departments;
+
+ const { Incident, Address, Person, Response } = callDetails;
+ const { CallThemes, InitList } = 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;
+ const {
+ CriticalCallList,
+ HighCallList,
+ MediumCallList,
+ LowCallList,
+ } = CallThemes;
+
+ return (
+
+
+
+ {
+ actionSheetRef.current?.show();
+ }}
+ >
+
+ {selectedDepartment?.deptAbv}
+
+
+
+
+
+
+
+
+
+
+
+
+ {deptList?.map((item) => {
+ return (
+
+ {
+ actionSheetRef.current?.hide();
+ return updateSelectedDepartment(
+ selectedDepartment?.deptId,
+ item?.deptId
+ )
+ }}
+ >
+
+
+ {item?.dept}
+
+ {item?.primary ? : null}
+
+ {`${item?.deptAbv} - ${departmentTypeMap[item?.type]}`}
+
+
+ );
+ })}
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/app/landing.jsx b/app/landing.jsx
index 1b95a5d..3e31875 100644
--- a/app/landing.jsx
+++ b/app/landing.jsx
@@ -1,145 +1,799 @@
import React, { useState, useRef, useEffect } from 'react';
-import { View, ScrollView, Text, TouchableOpacity } from 'react-native';
+import { useCallFeed } from '../hooks/useCallFeed';
+import { Platform, Linking, View, ScrollView, Text, TouchableOpacity } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
+import { AccidentAndEmergency } from "healthicons-react-native/dist/outline";
+import { Phone } from "healthicons-react-native/dist/filled";
import {
PageHeader,
- StyledContainer,
+ PageFooter,
} from './generalHelpers.jsx';
-import ActionSheet from 'react-native-actions-sheet';
-
-const typeMap = {
- EMS: 'Medical Services',
- Fire: 'Fire Department',
- Rescue: 'Fire & EMS'
-}
-
-const initList = [
- {
- deptId: 0,
- dept: 'Darien EMS',
- deptAbv: 'DEMS',
- rank: 'Assistant Director',
- rankAbv: 'Asst. Director',
- type: 'EMS',
- primary: true,
- selected: true,
- admin: true,
- },
- {
- deptId: 1,
- dept: 'Noroton Fire Department',
- deptAbv: 'NFD',
- rank: 'Lieutenant',
- rankAbv: 'Lt.',
- type: 'Fire',
- primary: false,
- selected: false,
- admin: true,
- },
- {
- deptId: 2,
- dept: 'Stamford Fire Department',
- deptAbv: 'SFD',
- rank: 'Paramedic',
- rankAbv: 'EMT-P',
- type: 'Rescue',
- primary: false,
- selected: false,
- admin: true,
- },
-]
export default function Landing() {
const actionSheetRef = useRef(null);
- const [deptList, setDeptList] = useState(initList);
- const [selectedDepartment, setSelectedDepartment] = useState(deptList?.find((dept) => {
- return dept?.primary;
- }));
+ const callFeed = useCallFeed();
- const updateSelectedDepartment = (currentSelectedId, newSelectedId) => {
- if (currentSelectedId !== newSelectedId) {
- setDeptList(deptList?.map((item) => {
- if (item?.selected) {
- item.selected = false;
- }
- if (item?.deptId === newSelectedId) {
- item.selected = true;
- }
- return item;
- }))
+ const {
+ departments,
+ callIconMap,
+ callDetails,
+ callColorSelector,
+ } = callFeed;
+
+ const {
+ departmentTypeMap,
+ accountDetails,
+ selectedDepartment,
+ setSelectedDepartment,
+ updateSelectedDepartment,
+ selectedDepartmentColorPicker,
+ } = departments;
+
+ const { Incident, Address, Person, Response } = callDetails;
+ 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;
+
+ const SelectedIcon = callIconMap[IncNature] || AccidentAndEmergency;
+
+ const ownDepartmentResponse = Units?.map((unit) => {
+ if (unit?.Department === selectedDepartment?.dept ||
+ selectedDepartment?.addDepts?.includes(unit?.Department)) {
+ return unit;
}
+ return null;
+ })?.filter((filterItem) => {
+ return filterItem;
+ });
+
+ const mutualAidDepartmentResponse = Units?.map((unit) => {
+ if (unit?.Department !== selectedDepartment?.dept &&
+ !selectedDepartment?.addDepts?.includes(unit?.Department)) {
+ return unit;
+ }
+ return null;
+ })?.filter((filterItem) => {
+ return filterItem;
+ });;
+
+ const formatCallTimePast = (callValue) => {
+ const initDate = new Date(callValue);
+ const currentTime = new Date();
+
+ const timeDifference = currentTime - initDate;
+
+ const days = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
+ const hours = Math.floor((timeDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
+ const minutes = Math.floor((timeDifference % (1000 * 60 * 60)) / (1000 * 60));
+ const seconds = Math.floor((timeDifference % (1000 * 60)) / 1000);
+ if (days && days !== 0) {
+ return `${days} day${days === 1 ? '' : 's'} ago`;
+ } else if (hours && hours !== 0) {
+ return `${hours} hour${hours === 1 ? '' : 's'} ago`;
+ } else if (minutes && minutes !== 0) {
+ return `${minutes} minute${minutes === 1 ? '' : 's'} ago`;
+ } else if (seconds && seconds !== 0) {
+ return `${seconds} second${seconds === 1 ? '' : 's'} ago`;
+ }
+ return `Unknown Time Past`;
+ }
+
+ const formatCallDateTime = (callValue) => {
+ const initDate = new Date(callValue);
+ if (initDate) {
+ const formattedDate = `${initDate.toLocaleDateString('en-US', {
+ month: 'short',
+ day: 'numeric',
+ year: 'numeric',
+ })}`;
+ const hours = initDate.getHours().toString().padStart(2, '0');
+ const minutes = initDate.getMinutes().toString().padStart(2, '0');
+ const formattedTime = `${hours}:${minutes}`;
+
+ return `${formattedDate} - ${formattedTime}`;
+ }
+ return 'Date Unavailable';
+ }
+
+ const formatResponseTimes = (time) => {
+ if (time === null) {
+ 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}`;
};
- useEffect(() => {
- if (deptList) {
- setSelectedDepartment(deptList?.find((dept) => {
- return dept?.selected;
- }));
- }
- }, [deptList])
+ const openMaps = (latitude, longitude) => {
+ const daddr = `${latitude},${longitude}`;
+ const company = Platform.OS === "ios" ? "apple" : "google";
+ Linking.openURL(`http://maps.${company}.com/maps?daddr=${daddr}`);
+ };
+
+ const callNumber = (number) => {
+ const formattedNumber = number.replace(/[()\-\s]/g, '');
+ Linking.openURL(`tel:${formattedNumber}`);
+ };
return (
-
- {
- actionSheetRef.current?.show();
- }}>
- {selectedDepartment?.deptAbv}
+
+ {
+ actionSheetRef.current?.show();
+ }}
+ >
+
+ {selectedDepartment?.deptAbv}
+
-
+
-
-
- {deptList?.map((item) => {
- return (
-
- {return updateSelectedDepartment(selectedDepartment?.deptId, item?.deptId)}}
- >
-
- {item?.dept}
- {item?.primary ? : null}
+
+ {formatCallDateTime(IncDate)}
+ {formatCallTimePast(IncDate)}
+
+
+
+
+
+
+
+
+ {`${IncNature}`}
+
+
+
+ {`${IncNatureCodeDesc}`}
+
+
- {`${item?.deptAbv} - ${typeMap[item?.type]}`}
-
+
+
+ {Status === 'CLOSED' ? (
+
+ This Incident is Closed.
+
+ ) : }
+
+ {`Incident #: ${ServiceNumber}`}
+
+
- );
- })}
+
+
+
+
+
+
+
+ {LocationName ? (
+
+ {`${LocationName}`}
+
+ ) : null }
+ {
+ return openMaps(Latitude, Longitude);
+ }}
+ >
+
+ {`${StreetAddress}`}
+
+
+ {`${Town}, ${State}`}
+
+
+ {AddressApartment ? (
+
+
+
+ {`${AddressApartment}`}
+
+
+ ) : null}
+
+
+
+ Map
+
+ {
+ return openMaps(Latitude, Longitude);
+ }}
+ >
+ Nav
+
+
+
+
+
+
+
+
+
+
+ {Intersection1}
+
+
+
+
+
+ {Intersection2}
+
+
+
+
+
+
+ {selectedDepartment?.supervisor ? (
+
+
+
+
+
+ {`${Name}`}
+
+ {
+ return callNumber(CallBackNumber);
+ }}
+ >
+
+ {`${CallBackNumber}`}
+
+
+
+ {
+ return callNumber(CallBackNumber);
+ }}
+ >
+
+
+
+
+
+
+ ) : null }
+
+
+
+ {`${Age} `}
+
+
+ {`${Gender} - `}
+
+
+ {`Concious: ${Conscious} | `}
+
+
+ {`Breathing: ${Breathing}`}
+
+
+
+ {`${Statement}`}
+
+
+
+
+
+
+
+
+
+
+ {Units?.length > 0 ? (
+
+ {ownDepartmentResponse?.length > 0 ? (
+
+
+
+ Units
+ Disp
+ Resp
+ Arr
+ {selectedDepartment?.type === 'EMS' || selectedDepartment?.type === 'Rescue' ? (
+ Trans
+ ) : null}
+ BIS
+
+
+
+ {ownDepartmentResponse?.map((unit) => {
+ return (
+
+
+ {unit?.Unit}
+
+
+ {formatResponseTimes(unit?.Dispatched)}
+
+
+ {formatResponseTimes(unit?.Responding)}
+
+
+ {formatResponseTimes(unit?.OnScene)}
+
+ {selectedDepartment?.type === 'EMS' ||
+ selectedDepartment?.type === 'Rescue' ? (
+
+ {formatResponseTimes(unit?.Transporting)}
+
+ ) : null }
+
+ {formatResponseTimes(unit?.InService)}
+
+
+ )
+ })}
+
+
+
+ ) : (
+
+
+ {`No ${selectedDepartment?.dept} Units Responding`}
+
+
+ ) }
+ {mutualAidDepartmentResponse?.length > 0 ? (
+
+
+
+ M/A
+ Disp
+ Resp
+ Arr
+ {selectedDepartment?.type === 'EMS' || selectedDepartment?.type === 'Rescue' ? (
+ Trans
+ ) : null}
+ BIS
+
+
+ {mutualAidDepartmentResponse?.map((unit) => {
+ return (
+
+
+ {unit?.Unit}
+
+
+ {formatResponseTimes(unit?.Dispatched)}
+
+
+ {formatResponseTimes(unit?.Responding)}
+
+
+ {formatResponseTimes(unit?.OnScene)}
+
+ {selectedDepartment?.type === 'EMS' ||
+ selectedDepartment?.type === 'Rescue' ? (
+
+ {formatResponseTimes(unit?.Transporting)}
+
+ ) : null }
+
+ {formatResponseTimes(unit?.InService)}
+
+
+ )
+ })}
+
+ ) : null }
+
+ ) : (
+
+ No Units Responding
+
+ )}
+
+
+
+
+
+ Incident Notes
+
+
+
+
+ {Notes?.split('\n').map((note, index) => (
+
+ {note}
+ {index < Notes.split('\n').length - 1 && (
+
+ )}
+
+ ))}
+
+
-
+
+
+
+
);
}
\ No newline at end of file
diff --git a/app/login.jsx b/app/login.jsx
index 521d3ba..bf9eec7 100644
--- a/app/login.jsx
+++ b/app/login.jsx
@@ -22,10 +22,10 @@ import {
LoginTextInput
} from './generalHelpers.jsx';
-export default function TabLayout() {
+export default function Login() {
const [hidePassword, setHidePassword] = useState(true);
const [loginButtonDisabled, setLoginButtonDisabled] = useState(true);
- const [auth, setAuth] = useState(true);
+ const [auth, setAuth] = useState(false);
const formik = useFormik({
initialValues: {
@@ -52,8 +52,14 @@ export default function TabLayout() {
}, [formValues])
useEffect(() => {
+ // Temp for Testing
+ // if (!auth) {
+ // setTimeout(() => {
+ // router.navigate('./incidents');
+ // }, 1000);
+ // }
if (auth) {
- router.navigate('./landing');
+ router.navigate('./incidents');
}
}, [auth])
@@ -104,6 +110,12 @@ export default function TabLayout() {
Register
+
+ Incidents
+
+
+ Landing
+
diff --git a/app/register.jsx b/app/register.jsx
index 9e952e1..5dab3f6 100644
--- a/app/register.jsx
+++ b/app/register.jsx
@@ -65,10 +65,12 @@ export default function Register() {
return (
-
-
- Back to Login
-
+
+
+
+ Back to Login
+
+
diff --git a/hooks/index.js b/hooks/index.js
new file mode 100644
index 0000000..efebedc
--- /dev/null
+++ b/hooks/index.js
@@ -0,0 +1,2 @@
+export { useCallFeed } from './useCallFeed';
+export { useDepartments } from './useDepartments';
\ No newline at end of file
diff --git a/hooks/useCallFeed/index.js b/hooks/useCallFeed/index.js
new file mode 100644
index 0000000..5100e13
--- /dev/null
+++ b/hooks/useCallFeed/index.js
@@ -0,0 +1 @@
+export { useCallFeed } from "./useCallFeed";
\ No newline at end of file
diff --git a/hooks/useCallFeed/useCallFeed.js b/hooks/useCallFeed/useCallFeed.js
deleted file mode 100644
index e69de29..0000000
diff --git a/hooks/useCallFeed/useCallFeed.jsx b/hooks/useCallFeed/useCallFeed.jsx
new file mode 100644
index 0000000..be8eeee
--- /dev/null
+++ b/hooks/useCallFeed/useCallFeed.jsx
@@ -0,0 +1,183 @@
+import React, { useState, useEffect } from 'react';
+import { useDepartments } from '../useDepartments';
+import { Cardiology, Cpr, FourByFour } from "healthicons-react-native/dist/outline";
+
+const callIconMap = {
+ "CHEST PAIN|HEART PROBLEMS": Cardiology,
+ "CARDIAC ARREST|DEATH": Cpr,
+ "MOTOR VEHICLE COLLISION (MVC)": FourByFour,
+}
+
+// Squares
+
+// Cariology - Heart
+// BurnUnit - Fire
+// AccidentAndEmergency - Misc.
+// Rheumatology - Bone/Crash
+// Sonography - Baby
+// PainManagement - CPR/Cardiac Arrest
+// Respiratory - Diff Breathing
+
+// Others
+
+// HeartOrgan - Heart
+// Burn - Burns
+// FHIR - Structure Fire
+// Sonogram - Baby
+// SUV - Crash
+// Joints - Bone
+// Pain - CPR/Cardiac Arrest
+// Skull - CPR/Cardiac Arrest
+// CPR - CPR/Cardiac Arrest
+// Pneumonia - Diff Breathing
+// CoughingAlt - Diff Breathing
+// Diabetes - Diabetic Emergency
+// BloodDrop - Bleeding Emergencies
+// Bacteria - Sick
+// RuralClinic - Medical Facility Response
+
+const callDetails = {
+ "Incident": {
+ "IncID": 75,
+ "IncNumber": 6873,
+ "JurisdictionNumber": 3,
+ "ServiceNumber": 42,
+ "ServiceID": 45,
+ "IncDate": "2024-09-25T01:01:01.55",
+ // "IncNature": "CHEST PAIN|HEART PROBLEMS",
+ "IncNature": "MOTOR VEHICLE COLLISION (MVC)",
+ // "IncNature": "CARDIAC ARREST|DEATH",
+ "IncNatureCode": "ALS",
+ "IncNatureCodeDesc": "ALS PRIORITY (ALS)",
+ "Notes": "570, 16:30> 311 Responding\n580, 16:25> Call Dispatched",
+ "Status": "OPEN",
+ "Origin": "911"
+ },
+ "Address": {
+ "StreetAddress": "275 E Main St",
+ "AddressApartment": "IFO",
+ "Town": "Bridgeport",
+ "State": "CT",
+ "ZipCode": "06608",
+ "Latitude": 41.178435683035445,
+ "Longitude": -73.18194442701176,
+ "County": "Fairfield",
+ "Intersection1": "E MAIN ST",
+ "Intersection2": "STRATFORD AVE",
+ "LocationName": "Chipotle Mexican Grill",
+ "WeatherCondition": "Foggy"
+ },
+ "Person": {
+ "Name": "John Doe",
+ "Age": 19,
+ "Gender": "Female",
+ "Statement": "BLOOD PRESSURE 56/41 - IN AND OUT OF CON",
+ "Conscious": "No",
+ "Breathing": "Yes",
+ "CallBackNumber": "(223) 456-7890"
+ },
+ "Response": {
+ "IncID": 75,
+ "ResponseID": 75,
+ "ServiceID": 45,
+ "ServiceName": "DARIEN EMS",
+ "Units": [
+ {
+ "Unit": 311,
+ "Department": 'Darien EMS',
+ "Dispatched": "2024-09-25T01:01:01.55",
+ "Responding": "2024-09-25T01:02:02.55",
+ "OnScene": "2024-09-25T01:10:10.55",
+ "Transporting": "2024-09-25T01:25:01.55",
+ "InService": "2024-09-25T02:00:01.55",
+ },
+ {
+ "Unit": 315,
+ "Department": 'Darien EMS Supv',
+ "Dispatched": "2024-09-25T01:01:01.55",
+ "Responding": "2024-09-25T01:03:03.15",
+ "OnScene": "2024-09-25T01:11:11.55",
+ "Transporting": null,
+ "InService": "2024-09-25T02:10:01.55",
+ },
+ {
+ "Unit": 310,
+ "Department": 'Darien EMS',
+ "Dispatched": "2024-09-25T01:01:01.55",
+ "Responding": "2024-09-25T01:01:01.55",
+ "OnScene": "2024-09-25T01:06:06.55",
+ "Transporting": "2024-09-25T01:25:01.55",
+ "InService": "2024-09-25T02:15:01.55",
+ },
+ {
+ "Unit": 'NHT20',
+ "Department": 'Noroton Heights Fire Department',
+ "Dispatched": "2024-09-25T01:01:01.55",
+ "Responding": "2024-09-25T01:08:08.55",
+ "OnScene": "2024-09-25T01:12:12.55",
+ "Transporting": null,
+ "InService": "2024-09-25T01:01:01.55",
+ },
+ {
+ "Unit": 'NFDE31',
+ "Department": 'Noroton Fire Department',
+ "Dispatched": "2024-09-25T01:01:01.55",
+ "Responding": "2024-09-25T01:07:07.55",
+ "OnScene": "2024-09-25T01:14:14.55",
+ "Transporting": null,
+ "InService": "2024-09-25T01:01:01.55",
+ },
+ {
+ "Unit": 'DFDT43',
+ "Department": 'Darien Fire Department',
+ "Dispatched": "2024-09-25T01:01:01.55",
+ "Responding": "2024-09-25T01:10:10.55",
+ "OnScene": "2024-09-25T01:18:18.55",
+ "Transporting": null,
+ "InService": "2024-09-25T01:01:01.55",
+ },
+ {
+ "Unit": 1514,
+ "Department": 'Greenwich EMS',
+ "Dispatched": "2024-09-25T01:15:15.55",
+ "Responding": "2024-09-25T01:30:30.55",
+ "OnScene": "2024-09-25T01:45:45.55",
+ "Transporting": "2024-09-25T02:05:15.55",
+ "InService": "2024-09-25T02:25:01.55",
+ },
+ ]
+ }
+}
+
+export const useCallFeed = () => {
+ const departments = useDepartments();
+ const { CallThemes } = departments?.accountDetails;
+ const {
+ CriticalCallList,
+ HighCallList,
+ MediumCallList,
+ LowCallList,
+ } = CallThemes;
+
+ const callColorSelector = (callAcuity, cardiacArrestCall, status) => {
+ if (status === 'CLOSED') {
+ return '#0000CD';
+ } else if (CriticalCallList.includes(cardiacArrestCall)) {
+ return '#8B0000';
+ } else if (HighCallList.includes(callAcuity)) {
+ return "#FF0000";
+ } else if (MediumCallList.includes(callAcuity)) {
+ return "#FF8C00";
+ } else if (LowCallList.includes(callAcuity)) {
+ return "#228B22";
+ }
+ return 'grey';
+ };
+
+ return {
+ departments,
+ callIconMap,
+ callDetails,
+ callColorSelector,
+ }
+}
\ No newline at end of file
diff --git a/hooks/useDepartments/index.js b/hooks/useDepartments/index.js
new file mode 100644
index 0000000..dcc4235
--- /dev/null
+++ b/hooks/useDepartments/index.js
@@ -0,0 +1 @@
+export { useDepartments } from './useDepartments';
\ No newline at end of file
diff --git a/hooks/useDepartments/useDepartments.jsx b/hooks/useDepartments/useDepartments.jsx
new file mode 100644
index 0000000..a0ddf69
--- /dev/null
+++ b/hooks/useDepartments/useDepartments.jsx
@@ -0,0 +1,122 @@
+import React, { useState, useEffect } from 'react';
+import { View, Text, TouchableOpacity } from 'react-native';
+
+const departmentTypeMap = {
+ EMS: 'Medical Services',
+ Fire: 'Fire Department',
+ Rescue: 'Fire & EMS'
+}
+
+const accountDetails = {
+ "CallThemes" : {
+ "CriticalCallList": [
+ "CARDIAC ARREST|DEATH",
+ ],
+ "HighCallList": [
+ "ALS"
+ ],
+ "MediumCallList": [
+ "ALS-STANDARD",
+ "BLS-PRIORITY"
+ ],
+ "LowCallList": [
+ "BLS-STANDARD"
+ ]
+ },
+ "InitList": [
+ {
+ deptId: 0,
+ dept: 'Darien EMS',
+ addDepts: [
+ 'Darien EMS Supv'
+ ],
+ deptAbv: 'DEMS',
+ rank: 'Assistant Director',
+ rankAbv: 'Asst. Director',
+ type: 'EMS',
+ primary: true,
+ selected: true,
+ supervisor: true,
+ admin: true,
+ hasVolunteer: true,
+ },
+ {
+ deptId: 1,
+ dept: 'Noroton Fire Department',
+ deptAbv: 'NFD',
+ rank: 'Lieutenant',
+ rankAbv: 'Lt.',
+ type: 'Fire',
+ primary: false,
+ selected: false,
+ supervisor: true,
+ admin: true,
+ hasVolunteer: true,
+ },
+ {
+ deptId: 2,
+ dept: 'Stamford Fire Department',
+ deptAbv: 'SFD',
+ rank: 'Paramedic',
+ rankAbv: 'EMT-P',
+ type: 'Rescue',
+ primary: false,
+ selected: false,
+ supervisor: false,
+ admin: true,
+ hasVolunteer: false,
+ },
+ ]
+}
+
+export const useDepartments = () => {
+ const { InitList } = accountDetails;
+ const [deptList, setDeptList] = useState(InitList);
+ const [selectedDepartment, setSelectedDepartment] = useState(deptList?.find((dept) => {
+ return dept?.primary;
+ }));
+
+ const updateSelectedDepartment = (currentSelectedId, newSelectedId) => {
+ if (currentSelectedId !== newSelectedId) {
+ setDeptList(deptList?.map((item) => {
+ if (item?.selected) {
+ item.selected = false;
+ }
+ if (item?.deptId === newSelectedId) {
+ item.selected = true;
+ }
+ return item;
+ }))
+ }
+ };
+
+ const selectedDepartmentColorPicker = (deptartmentType) => {
+ if (deptartmentType === 'Fire') {
+ return '#FF0000';
+ } else if (deptartmentType === 'EMS') {
+ return '#FF8C00';
+ } else if (deptartmentType === 'Rescue') {
+ return '#0000CD';
+ }
+ return 'grey';
+ };
+
+ useEffect(() => {
+ if (deptList) {
+ setSelectedDepartment(deptList?.find((dept) => {
+ return dept?.selected;
+ }));
+ }
+ }, [deptList]);
+
+ return {
+ departmentTypeMap,
+ accountDetails,
+ deptList,
+ setDeptList,
+ selectedDepartment,
+ setSelectedDepartment,
+ updateSelectedDepartment,
+ selectedDepartmentColorPicker
+ }
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 5da916c..565fe7e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,7 @@
"expo-system-ui": "~3.0.7",
"expo-web-browser": "~13.0.3",
"formik": "^2.4.6",
+ "healthicons-react-native": "^3.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.74.3",
@@ -29,6 +30,7 @@
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.5",
"react-native-screens": "3.31.1",
+ "react-native-svg": "^15.7.1",
"react-native-textinput-effects": "^0.6.3",
"react-native-web": "~0.19.10",
"styled-components": "^6.1.12"
@@ -7724,6 +7726,12 @@
"node": ">= 6"
}
},
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "license": "ISC"
+ },
"node_modules/bplist-creator": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz",
@@ -8558,6 +8566,22 @@
"hyphenate-style-name": "^1.0.3"
}
},
+ "node_modules/css-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
"node_modules/css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
@@ -8568,6 +8592,40 @@
"postcss-value-parser": "^4.0.2"
}
},
+ "node_modules/css-tree": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.0.14",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/css-tree/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
"node_modules/cssom": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
@@ -8907,6 +8965,32 @@
"node": ">=8"
}
},
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
"node_modules/domexception": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
@@ -8920,6 +9004,35 @@
"node": ">=12"
}
},
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
"node_modules/dotenv": {
"version": "16.4.5",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
@@ -8997,7 +9110,6 @@
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "dev": true,
"engines": {
"node": ">=0.12"
},
@@ -10467,6 +10579,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/healthicons-react-native": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/healthicons-react-native/-/healthicons-react-native-3.0.0.tgz",
+ "integrity": "sha512-0M9Tz+72tnQgv+LpneTCEwQgmXOgbdEVILiqdEtOYC/ADmlJeMGWSjJlYiur9+/jLW0uLkUuYDe6ePz5bXxB3g==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.6 || ^17 || ^18",
+ "react-native": ">=0.50.0"
+ }
+ },
"node_modules/hermes-estree": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.19.1.tgz",
@@ -14086,6 +14208,12 @@
"resolved": "https://registry.npmjs.org/md5hex/-/md5hex-1.0.0.tgz",
"integrity": "sha512-c2YOUbp33+6thdCUi34xIyOU/a7bvGKj/3DB1iaPMTuPHf/Q2d5s4sn1FaCOO43XkXggnb08y5W2PU8UNYNLKQ=="
},
+ "node_modules/mdn-data": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+ "license": "CC0-1.0"
+ },
"node_modules/memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
@@ -14935,6 +15063,18 @@
"node": ">=4"
}
},
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
"node_modules/nullthrows": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
@@ -15914,6 +16054,21 @@
"react-native": "*"
}
},
+ "node_modules/react-native-svg": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.7.1.tgz",
+ "integrity": "sha512-Xc11L4t6/DtmUwrQqHR7S45Qy3cIWpcfGlmEatVeZ9c1N8eAK79heJmGRgCOVrXESrrLEHfP/AYGf0BGyrvV6A==",
+ "license": "MIT",
+ "dependencies": {
+ "css-select": "^5.1.0",
+ "css-tree": "^1.1.3",
+ "warn-once": "0.1.1"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/react-native-textinput-effects": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/react-native-textinput-effects/-/react-native-textinput-effects-0.6.3.tgz",
diff --git a/package.json b/package.json
index 2d2a2ae..ff3bb92 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
"expo-system-ui": "~3.0.7",
"expo-web-browser": "~13.0.3",
"formik": "^2.4.6",
+ "healthicons-react-native": "^3.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.74.3",
@@ -36,6 +37,7 @@
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.5",
"react-native-screens": "3.31.1",
+ "react-native-svg": "^15.7.1",
"react-native-textinput-effects": "^0.6.3",
"react-native-web": "~0.19.10",
"styled-components": "^6.1.12"