import {Dimensions, Pressable, StyleSheet, ScrollView, BackHandler } from "react-native";
import { Text, View } from "../../../components/Themed";
import React, { useEffect, useRef } from "react";
import Constants from 'expo-constants';
import Webview from "../../../components/Webview";
import { FontAwesome, Foundation, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons";
import Colors from "../../../constants/Colors";
import { getStats } from "../../../components/backend";
import { useFocusEffect } from "expo-router";
export function formatWithCommas(n:any) {
if(n===undefined){return 0}
return n.toString().replace(/\B(?=(\d{3})+\b)/g, ",");
}
export default function Integrations() {
const [showWeb, setShowWeb] = React.useState(false);
const [webUrl, setWebUrl] = React.useState('');
const [stats, setStats] = React.useState<any>({});
const [fetchedDate, setFetchedDate] = React.useState("");
useEffect(()=>{
// fetches data on page load
getStats().then((data)=>{
let res:any={};
for(let i=0;i<data.length;i++){
res[data[i].for] = data[i].count;
}
setStats(res);
setFetchedDate(new Date().toISOString());
}).catch((error)=>{
console.log("INTEGRATIONS: Error fetching stats: ", error);
})
},[])
// When screen is focused
useFocusEffect(
React.useCallback(() => {
let pastFetch = new Date(fetchedDate);
// fetches data every 30 minutes
// Returns if below the 30 minute threshold
if(pastFetch.getTime()+(30*60000) >= Date.now() && !Number.isNaN(pastFetch.getTime())){
// console.log("INTEGRATIONS: Data fetched less than 30 minutes ago, skipping fetch");
return;
}else if(pastFetch.getTime()+(30*60000)<Date.now()){
// Fetches from backend
getStats().then((data)=>{
let res:any={};
for(let i=0;i<data.length;i++){
res[data[i].for] = data[i].count;
}
setStats(res);
setFetchedDate(new Date().toISOString());
}).catch((error)=>{
console.log("INTEGRATIONS: Error fetching stats: ", error);
})
}
}, [fetchedDate])
)
// Handles back button press
useEffect(()=>{
const backHandler = BackHandler.addEventListener('hardwareBackPress', ()=>{
if(showWeb){
setShowWeb(false);
return true;
}
return false;
})
return ()=>backHandler.remove();
}, [showWeb])
return (
<View style={styles.container}>
{/* Webview and back button */}
{showWeb?<View style={styles.web}>
<Pressable style={styles.backIcon}
onPress={()=>setShowWeb(false)}
>
<Ionicons name="close" size={40} color={Colors.dark.redPastel} />
</Pressable>
<Webview url={webUrl} style={styles.web} />
</View>:null}
{/* Link buttons and statistics */}
<ScrollView style={styles.content}>
<View style={styles.iconContainer}>
<Pressable
onPress={()=>{
setWebUrl("https://sheriff.knoxcountytn.gov/index.php");
setShowWeb(true);
}}
style={styles.iconButton}
>
<MaterialCommunityIcons name="hours-24" style={styles.icons}/>
<Text style={styles.iconText}>24 Hour</Text>
</Pressable>
<Pressable
style={styles.iconButton}
onPress={()=>{
setWebUrl("https://sheriff.knoxcountytn.gov/inmate.php");
setShowWeb(true);
}}
>
<MaterialCommunityIcons name="handcuffs" style={styles.icons}/>
<Text style={styles.iconText}>Inmates</Text>
</Pressable>
<Pressable
style={styles.iconButton}
onPress={()=>{
setWebUrl("https://www.tn.gov/tbi/tbis-top-10-most-wanted.html");
setShowWeb(true);
}}
>
<MaterialIcons name="person-search" style={styles.icons}/>
<Text style={styles.iconText}>TBI Wanted</Text>
</Pressable>
<Pressable
style={styles.iconButton}
onPress={()=>{
setWebUrl("https://knoxsheriff.org/safety-man/");
setShowWeb(true);
}}
>
<MaterialCommunityIcons name="safety-goggles" style={styles.icons}/>
<Text style={styles.iconText}>Safety Man</Text>
</Pressable>
<Pressable
style={styles.iconButton}
onPress={()=>{
setWebUrl("https://tnmap.tn.gov/sor/#");
setShowWeb(true);
}}
>
<FontAwesome name="intersex" style={styles.icons}/>
<Text style={styles.iconText}>SOR</Text>
</Pressable>
<Pressable
style={styles.iconButton}
onPress={()=>{
setWebUrl("https://knoxvilletnpolice.gov/");
setShowWeb(true);
}}
>
<MaterialCommunityIcons name="police-badge" style={styles.icons}/>
<Text style={styles.iconText}>KPD</Text>
</Pressable>
<Pressable
style={styles.iconButton}
onPress={()=>{
setWebUrl("https://knoxsheriff.org/");
setShowWeb(true);
}}
>
<MaterialCommunityIcons name="police-station" style={styles.icons}/>
<Text style={styles.iconText}>KCSO</Text>
</Pressable>
<Pressable
style={styles.iconButton}
onPress={()=>{
setWebUrl("https://crimeinsight.tbi.tn.gov/tops");
setShowWeb(true);
}}
>
<Foundation name="graph-pie" style={styles.icons}/>
<Text style={styles.iconText}>TBI Stats *Slow*</Text>
</Pressable>
<Pressable
style={styles.iconButton}
onPress={()=>{
setWebUrl("https://www.tn.gov/tbi/tennessees-missing-children.html");
setShowWeb(true);
}}
>
<MaterialCommunityIcons name="magnify" style={styles.icons}/>
<Text style={styles.iconText}>TN missing people</Text>
</Pressable>
</View>
<View style={styles.separator} darkColor="rgba(255,255,255,0.1)" />
<Text style={styles.title}>Knox stats 📈</Text>
<Text style={styles.lastFetchedText}>Last fetched: {new Date(fetchedDate).toLocaleString()}</Text>
<Text style={styles.monthlyStatsTitle}>Monthly stats</Text>
<View style={styles.statsContainer}>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.highStatNumber}>{formatWithCommas(stats.mClass5)}</Text>
<Text style={styles.classText}> Class 5 reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.highStatNumber}>{formatWithCommas(stats.mClass4)}</Text>
<Text style={styles.classText}> Class 4 reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.statNumber}>{formatWithCommas(stats.mClass3)}</Text>
<Text style={styles.classText}> Class 3 reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.statNumber}>{formatWithCommas(stats.mClass2)}</Text>
<Text style={styles.classText}> Class 2 reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.statNumber}>{formatWithCommas(stats.mClass1)}</Text>
<Text style={styles.classText}> Class 1 reports</Text>
</View>
</View>
<Text style={styles.monthlyStatsTitle}>Sherlock lifelong stats</Text>
<View style={styles.overallStatsContainer}>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.highStatNumber}>{formatWithCommas(stats.class5)}</Text>
<Text style={styles.classText}> Class 5 reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.highStatNumber}>{formatWithCommas(stats.class4)}</Text>
<Text style={styles.classText}> Class 4 reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.statNumber}>{formatWithCommas(stats.class3)}</Text>
<Text style={styles.classText}> Class 3 reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.statNumber}>{formatWithCommas(stats.class2)}</Text>
<Text style={styles.classText}> Class 2 reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.statNumber}>{formatWithCommas(stats.class1)}</Text>
<Text style={styles.classText}> Class 1 reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.statNumber}>{formatWithCommas(stats.kpd_cip)}</Text>
<Text style={styles.classText}>KPD reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.statNumber}>{formatWithCommas(stats.knox_zones)}</Text>
<Text style={styles.classText}>KCSO reports</Text>
</View>
<View style={styles.statRowText}>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.statNumber}>{formatWithCommas(stats.utpd_clery)}</Text>
<Text style={styles.classText}>UTPD reports</Text>
</View>
</View>
</ScrollView>
</View>
);
}
let height = Dimensions.get("window").height;
let width = Dimensions.get("window").width;
const styles = StyleSheet.create({
container: {
flex: 1,
// marginTop: Constants.statusBarHeight,
overflow:"scroll",
backgroundColor: Colors.dark.tabBg,
},
title: {
fontSize: 20,
fontWeight: "bold",
alignSelf: "center",
},
separator: {
marginVertical: 15,
height: 1,
width: "80%",
alignSelf: "center",
},
iconContainer:{
display: "flex",
alignItems: "center",
height:height*.52,
padding: 20,
flexDirection: "row",
flexWrap: "wrap",
columnGap: 20,
alignContent: "flex-start",
backgroundColor: Colors.dark.tabBg,
},
iconButton:{
marginLeft: "auto",
marginRight: "auto",
marginTop: 20,
width:Dimensions.get("window").width*0.2,
height:Dimensions.get("window").width*0.27,
},
icons:{
color: Colors.dark.redPastel,
fontSize: 60,
backgroundColor: Colors.dark.alertBackground,
borderRadius: 10,
padding: 10,
alignSelf: "center",
justifyContent: "center",
width:Dimensions.get("window").width*0.2,
},
iconText:{
textAlign: "center",
marginTop: 2,
},
web:{
position: "absolute",
marginTop: Constants.statusBarHeight,
top: 0,
width: Dimensions.get("window").width,
height: Dimensions.get("window").height-50,
zIndex: 100,
},
content:{
position: "relative",
zIndex: 1,
marginTop: Constants.statusBarHeight,
overflow: "scroll",
},
backIcon:{
position: "absolute",
top: 20,
left: 20,
zIndex: 100,
backgroundColor: Colors.dark.background,
borderRadius: 40,
color: Colors.dark.redPastel,
},
statsContainer:{
flex:1,
flexDirection: "row",
width: width*.9,
flexWrap: "wrap",
alignItems:"flex-start",
backgroundColor: Colors.dark.background,
alignSelf: "center",
borderRadius: 10,
marginBottom:20,
padding:5,
},
highStatNumber:{
color:Colors.dark.redPastel,
fontSize: 50,
marginLeft:20,
flex:1,
flexWrap:"nowrap",
},
statNumber:{
color:Colors.dark.cyan,
fontSize: 50,
marginLeft:20,
flexShrink: 1,
flex:1,
},
statRowText:{
// flex:1,
flexDirection: "row",
alignItems: "center",
alignContent: "flex-start",
columnGap: 10,
backgroundColor: Colors.dark.background,
width:"100%",
maxWidth: "100%",
flexWrap: "nowrap",
},
monthlyStatsTitle:{
fontSize: 16,
fontWeight: "bold",
marginLeft: 20,
marginBottom: 10,
},
overallStatsContainer:{
flex:1,
flexDirection: "row",
// height: height*.5,
width: width*.9,
flexWrap: "wrap",
alignItems:"flex-start",
backgroundColor: Colors.dark.background,
alignSelf: "center",
borderRadius: 10,
marginBottom:80,
overflow: "scroll",
padding:5,
},
classText:{
fontSize:20,
flexWrap:"nowrap",
flex:1,
},
lastFetchedText:{
fontSize: 14,
marginBottom: 10,
alignSelf: "center",
fontWeight:"semibold",
fontStyle: "italic",
}
});