diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
index 90e4035..730b8a0 100644
--- a/app/(tabs)/_layout.tsx
+++ b/app/(tabs)/_layout.tsx
@@ -4,12 +4,30 @@ import { useTabConfig } from "@/constants/config";
import { useSelector } from "react-redux";
import { RootState } from "@/store";
import { initSocket } from "@/services/socket";
+import { useSnackbar } from "@/contexts/Snackbar";
+import NetInfo from "@react-native-community/netinfo";
export default function TabLayout() {
const { isLoggedIn } = useSelector((state: RootState) => state.auth);
if (!isLoggedIn) return null;
const TAB_CONFIG = useTabConfig();
+ const { showSnackbar } = useSnackbar();
+ useEffect(() => {
+ const unsubscribe = NetInfo.addEventListener((state) => {
+ const isConnected = state.isConnected;
+
+ if (isConnected === false) {
+ console.log("No internet connection");
+ showSnackbar("No internet connection", "error");
+ }
+ });
+
+ return () => {
+ unsubscribe();
+ };
+ }, []);
+
useEffect(() => {
initSocket();
}, [isLoggedIn]);
diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx
index 5748a6d..8001f42 100644
--- a/app/(tabs)/index.tsx
+++ b/app/(tabs)/index.tsx
@@ -29,9 +29,8 @@ export default function HomeScreen() {
const { t } = useTranslation();
const navigation = useNavigation();
const [isSupportModalVisible, setIsSupportModalVisible] = useState(false);
- const { SoC, SoH, chargingState, lat, lon, loading, error } = useSelector(
- (state: RootState) => state.telemetry
- );
+ const { SoC, SoH, chargingState, lat, lon, loading, error, totalDistance } =
+ useSelector((state: RootState) => state.telemetry);
const [prevPosition, setPrevPosition] = useState<{
lat: number;
lon: number;
@@ -139,7 +138,7 @@ export default function HomeScreen() {
@@ -156,7 +155,7 @@ export default function HomeScreen() {
Fetching Location...
- ) : lat && lon ? (
+ ) : lat != null && lon != null ? (
<>
>
) : (
-
-
- Error fetching location
-
+ error && (
+
+
+ Error fetching location
+
+ )
)}
diff --git a/app/_layout.tsx b/app/_layout.tsx
index 923e284..518c268 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -6,6 +6,8 @@ import "react-native-reanimated";
import { I18nextProvider } from "react-i18next";
import { Provider } from "react-redux";
import { store } from "@/store";
+import { PaperProvider } from "react-native-paper";
+import SnackbarProvider from "@/contexts/Snackbar";
export { ErrorBoundary } from "expo-router";
@@ -55,17 +57,21 @@ export default function RootLayout() {
function RootLayoutNav() {
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/app/auth/login.tsx b/app/auth/login.tsx
index b16d8d4..8ea1725 100644
--- a/app/auth/login.tsx
+++ b/app/auth/login.tsx
@@ -8,8 +8,8 @@ import {
TouchableWithoutFeedback,
Keyboard,
KeyboardAvoidingView,
- StatusBar,
Linking,
+ Platform,
} from "react-native";
import { useRouter } from "expo-router";
import { Formik } from "formik";
@@ -22,16 +22,8 @@ import { RootState } from "../../store";
import { AUTH_STATUSES } from "@/constants/types";
import { useTranslation } from "react-i18next";
import { SUPPORT } from "@/constants/config";
-// import { useNavigation } from "expo-router";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
-// type VerifyOTPNavigationProp = StackNavigationProp<
-// RootStackParamList,
-// "VerifyOTP"
-// >;
-
-// import OTPInputView from "@twotalltotems/react-native-otp-input";
-//handleblue => when input field looses focus (mark as touched)
-// handleBlur marks the field as touched, when field looses focus
export default function WelcomeScreen() {
const {
status,
@@ -42,6 +34,8 @@ export default function WelcomeScreen() {
const { t } = useTranslation();
const dispatch = useDispatch();
const router = useRouter();
+ const insets = useSafeAreaInsets();
+
// const navigation = useNavigation();
const phoneValidationSchema = Yup.object().shape({
@@ -63,10 +57,13 @@ export default function WelcomeScreen() {
};
return (
-
-
+
-
+
{t("onboarding.welcome")}
(
-
-
- {t("onboarding.enter-mobile-number")}
-
- {
- handleChange("phone")(text);
- if (sendOTPError) {
- dispatch(clearSendOTPError());
- }
- }}
- onBlur={handleBlur("phone")}
- value={values.phone}
- keyboardType="numeric"
- placeholder={t("onboarding.enter-registered-mobile-number")}
- placeholderTextColor={"#949CAC"}
- />
-
- {touched.phone && errors.phone && (
- {errors.phone}
- )}
- {sendOTPError && (
- {sendOTPError}
- )}
-
-
-
- For any queries,
-
- contact us.
-
+
+
+
+ {t("onboarding.enter-mobile-number")}
+
+ {
+ handleChange("phone")(text);
+ if (sendOTPError) {
+ dispatch(clearSendOTPError());
+ }
+ }}
+ onBlur={handleBlur("phone")}
+ value={values.phone}
+ keyboardType="numeric"
+ placeholder={t("onboarding.enter-registered-mobile-number")}
+ placeholderTextColor={"#949CAC"}
+ />
+
+ {touched.phone && errors.phone && (
+ {errors.phone}
+ )}
+ {sendOTPError && (
+ {sendOTPError}
+ )}
- void}
- style={{
- ...styles.button,
- backgroundColor:
- values.phone.length === 10 &&
- !errors.phone &&
- status !== AUTH_STATUSES.LOADING
- ? "#008761"
- : "#B0B7C5",
- }}
- disabled={
- values.phone.length !== 10 ||
- !!errors.phone ||
- status === AUTH_STATUSES.LOADING
- }
- >
-
- {t("onboarding.send-otp")}
-
-
+
+
+
+
+ For any queries,
+
+ contact us.
+
+
+
+
+ void}
+ style={{
+ ...styles.button,
+ backgroundColor:
+ values.phone.length === 10 &&
+ !errors.phone &&
+ status !== AUTH_STATUSES.LOADING
+ ? "#008761"
+ : "#B0B7C5",
+ }}
+ disabled={
+ values.phone.length !== 10 ||
+ !!errors.phone ||
+ status === AUTH_STATUSES.LOADING
+ }
+ >
+
+ {t("onboarding.send-otp")}
+
+
+
)}
@@ -150,12 +153,29 @@ export default function WelcomeScreen() {
}
const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ padding: 16,
+ backgroundColor: "#F3F5F8",
+ },
+ inner: {
+ flex: 1,
+ },
+ formContainer: {
+ flex: 1,
+ justifyContent: "space-between",
+ },
+ inputContainer: {
+ flex: 1,
+ },
+ bottomSection: {
+ width: "100%",
+ },
contactContainer: {
width: "100%",
alignItems: "center",
justifyContent: "center",
- position: "absolute",
- bottom: 110, // slightly above the "Send OTP" button
+ marginBottom: 16,
},
link: {
fontSize: 14,
@@ -175,24 +195,12 @@ const styles = StyleSheet.create({
fontWeight: "bold",
lineHeight: 20,
},
- inner: {
- flex: 1,
- justifyContent: "flex-start",
- position: "relative",
- },
- form: {
- height: "90%",
- position: "relative",
- },
button: {
height: 48,
borderRadius: 4,
alignItems: "center",
justifyContent: "center",
- marginTop: 20,
width: "100%",
- position: "absolute",
- bottom: 50,
},
buttonText: {
color: "#FCFCFC",
@@ -201,12 +209,6 @@ const styles = StyleSheet.create({
fontWeight: "bold",
lineHeight: 20,
},
- container: {
- flex: 1,
- padding: 16,
- backgroundColor: "#F3F5F8",
- paddingTop: 0,
- },
title: {
fontSize: 28,
fontWeight: "bold",
diff --git a/app/init/language.tsx b/app/init/language.tsx
index 2dd7d87..febc4b0 100644
--- a/app/init/language.tsx
+++ b/app/init/language.tsx
@@ -2,11 +2,14 @@ import React, { useEffect, useState } from "react";
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import { setLanguage } from "../../services/i18n/index";
import { useRouter, useNavigation } from "expo-router";
+import { StatusBar } from "expo-status-bar";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
const LanguageScreen = () => {
const router = useRouter();
const navigation = useNavigation();
const [selectedLang, setSelectedLang] = useState(null);
+ const insets = useSafeAreaInsets();
useEffect(() => {
navigation.setOptions({ headerShown: false });
@@ -24,41 +27,47 @@ const LanguageScreen = () => {
};
return (
-
- Select Language
- Please select your preferred language
+ <>
+
+
+ Select Language
+
+ Please select your preferred language
+
- handleLanguagePress("en")}
- >
- English
-
+ handleLanguagePress("en")}
+ >
+ English
+
- handleLanguagePress("hi")}
- >
- हिन्दी
-
+ handleLanguagePress("hi")}
+ >
+ हिन्दी
+
-
- Select
-
-
+
+ Select
+
+
+ >
);
};
@@ -68,7 +77,6 @@ const styles = StyleSheet.create({
backgroundColor: "#f3f5f8",
paddingTop: 108,
paddingHorizontal: 16,
- paddingBottom: 80,
},
title: {
fontSize: 28,
@@ -91,7 +99,7 @@ const styles = StyleSheet.create({
justifyContent: "center",
},
selectedCard: {
- borderColor: "#008000",
+ borderColor: "#009E71",
},
languageText: {
fontSize: 16,
@@ -99,6 +107,7 @@ const styles = StyleSheet.create({
},
selectButton: {
marginTop: "auto",
+ marginBottom: 16,
padding: 16,
borderRadius: 4,
alignItems: "center",
diff --git a/app/user/profile.tsx b/app/user/profile.tsx
index c197d85..3d0cc37 100644
--- a/app/user/profile.tsx
+++ b/app/user/profile.tsx
@@ -8,56 +8,68 @@ import {
ScrollView,
} from "react-native";
import { MaterialIcons } from "@expo/vector-icons";
+import LanguageModal from "@/components/Profile/LangaugeModal";
export default function ProfileScreen() {
+ const [isLangaugeModalVisible, setLanguageModalVisible] =
+ React.useState(false);
+
+ const toggleLanguageModal = () => {
+ setLanguageModalVisible(!isLangaugeModalVisible);
+ };
return (
-
-
-
-
-
-
-
-
-
-
- Name
- Amar Kesari
-
-
-
+ <>
+
+
+
+
+
-
-
-
- Mobile Number
- 9876543210
+
+
+
+ Name
+ Amar Kesari
+
+
+
+
+
+
+
+
+ Mobile Number
+ 9876543210
+
-
- {/* Other Menu Items */}
-
- {menuItem("My Vehicle")}
-
- {menuItem("Language")}
-
+
+ {menuItem("My Vehicle")}
+
+ {menuItem("Language", () => toggleLanguageModal())}
+
-
- {menuItem("About App")}
-
- {menuItem("Logout")}
-
-
+
+ {menuItem("About App")}
+
+ {menuItem("Logout")}
+
+
+ setLanguageModalVisible(false)}
+ visible={isLangaugeModalVisible}
+ />
+ >
);
}
-const menuItem = (title: string) => (
-
+const menuItem = (title: string, onPress?: () => void) => (
+
{title}
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..73ebf58
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,6 @@
+module.exports = function (api) {
+ api.cache(true);
+ return {
+ presets: ["babel-preset-expo"],
+ };
+};
diff --git a/components/Profile/LangaugeModal.tsx b/components/Profile/LangaugeModal.tsx
new file mode 100644
index 0000000..a064b39
--- /dev/null
+++ b/components/Profile/LangaugeModal.tsx
@@ -0,0 +1,103 @@
+import BottomSheetModal from "@/components/common/BottomSheetModal"; // adjust path
+
+import { StyleSheet, Text, TouchableOpacity } from "react-native";
+import { useEffect, useState } from "react";
+import { getLanguage, setLanguage } from "@/services/i18n";
+
+interface CustomerSupportProps {
+ visible: boolean;
+ onClose: () => void;
+}
+
+export default function LanguageModal({
+ visible,
+ onClose,
+}: CustomerSupportProps) {
+ const [selectedLang, setSelectedLang] = useState<"en" | "hi">("en");
+
+ useEffect(() => {
+ (async () => {
+ const lang = await getLanguage();
+ setSelectedLang(lang === "hi" ? "hi" : "en");
+ })();
+ }, []);
+
+ const handleLanguagePress = (lang: "en" | "hi") => {
+ setSelectedLang(lang);
+ setLanguage(lang);
+ onClose();
+ };
+ return (
+
+ handleLanguagePress("en")}
+ >
+ English
+
+
+ handleLanguagePress("hi")}
+ >
+ हिन्दी
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ languageText: {
+ fontSize: 16,
+ color: "#2f465e",
+ },
+ selectedCard: {
+ borderColor: "#009E71",
+ },
+ languageCard: {
+ width: "100%",
+ borderWidth: 1,
+ borderColor: "#d8dde7",
+ borderRadius: 4,
+ padding: 16,
+ marginBottom: 16,
+ justifyContent: "center",
+ },
+ row: {
+ flexDirection: "row",
+ gap: 16,
+ justifyContent: "space-between",
+ },
+ secondaryButton: {
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "center",
+ paddingVertical: 8,
+ paddingHorizontal: 16,
+ height: 40,
+ borderRadius: 4,
+ backgroundColor: "#F3F5F8",
+ borderWidth: 1,
+ borderColor: "#D8DDE7",
+ width: 156,
+ gap: 8,
+ },
+ fullButton: {
+ width: "100%",
+ },
+ buttonText: {
+ fontSize: 14,
+ fontWeight: "500",
+ color: "#252A34",
+ },
+});
diff --git a/components/common/BottomSheetModal.tsx b/components/common/BottomSheetModal.tsx
new file mode 100644
index 0000000..8559fa9
--- /dev/null
+++ b/components/common/BottomSheetModal.tsx
@@ -0,0 +1,87 @@
+import React from "react";
+import {
+ View,
+ Text,
+ StyleSheet,
+ Modal,
+ Pressable,
+ StyleProp,
+ ViewStyle,
+} from "react-native";
+import { StatusBar } from "expo-status-bar";
+import CloseIcon from "../../assets/icons/close.svg";
+
+type Props = {
+ visible: boolean;
+ onClose: () => void;
+ heading: string;
+ children: React.ReactNode;
+ containerStyle?: StyleProp;
+};
+
+const BottomSheetModal: React.FC = ({
+ visible,
+ onClose,
+ heading,
+ children,
+ containerStyle,
+}) => {
+ return (
+
+
+
+
+
+ {heading}
+
+
+
+
+ {children}
+
+
+
+ );
+};
+
+export default BottomSheetModal;
+
+const styles = StyleSheet.create({
+ overlay: {
+ flex: 1,
+ justifyContent: "flex-end",
+ backgroundColor: "rgba(0,0,0,0.5)",
+ },
+ modalContainer: {
+ backgroundColor: "#fff",
+ borderTopLeftRadius: 12,
+ borderTopRightRadius: 12,
+ paddingHorizontal: 16,
+ paddingVertical: 16,
+ },
+ header: {
+ borderBottomWidth: 1,
+ borderBottomColor: "#E5E9F0",
+ paddingHorizontal: 16,
+ paddingVertical: 8,
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "space-between",
+ },
+ headerText: {
+ fontSize: 14,
+ fontWeight: "600",
+ color: "#252A34",
+ },
+ iconButton: {
+ width: 40,
+ height: 40,
+ padding: 10,
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ content: {
+ paddingVertical: 16,
+ gap: 16,
+ },
+});
diff --git a/components/common/CustomSnackbar.tsx b/components/common/CustomSnackbar.tsx
index b638c87..1dd1532 100644
--- a/components/common/CustomSnackbar.tsx
+++ b/components/common/CustomSnackbar.tsx
@@ -31,7 +31,7 @@ const CustomSnackbar: React.FC = ({
return (
= ({ status, style }) => {
case 1:
return {
text: "Charging",
- backgroundColor: "#006C4D",
+ backgroundColor: "#DAF5ED",
textColor: "#006C4D",
};
case -1:
@@ -28,20 +28,14 @@ const BatteryStatus: React.FC = ({ status, style }) => {
case 0:
return {
text: "Idle",
- backgroundColor: "#565F70",
+ backgroundColor: "#D8DDE7",
textColor: "#565F70",
};
- case null:
- return {
- text: "---",
- backgroundColor: "#e2e3e5",
- textColor: "#6c757d",
- };
default:
return {
- text: "Unknown",
- backgroundColor: "#f8f9fa",
- textColor: "#6c757d",
+ text: "---",
+ backgroundColor: "#D8DDE7",
+ textColor: "#565F70",
};
}
};
diff --git a/components/home/CustomerSupportModal.tsx b/components/home/CustomerSupportModal.tsx
index 106629a..9fa7584 100644
--- a/components/home/CustomerSupportModal.tsx
+++ b/components/home/CustomerSupportModal.tsx
@@ -1,31 +1,23 @@
-import React from "react";
-import {
- View,
- Text,
- StyleSheet,
- Pressable,
- Linking,
- Modal,
-} from "react-native";
+import BottomSheetModal from "@/components/common/BottomSheetModal"; // adjust path
import WhatsappIcon from "../../assets/icons/whatsapp.svg";
import CallIcon from "../../assets/icons/call.svg";
import EmailIcon from "../../assets/icons/mail.svg";
-import CloseIcon from "../../assets/icons/close.svg";
-
+import { Linking, Pressable, StyleSheet, Text, View } from "react-native";
import { SUPPORT } from "@/constants/config";
-import { StatusBar } from "expo-status-bar";
-type Props = {
+interface CustomerSupportProps {
visible: boolean;
onClose: () => void;
-};
+}
-const CustomerSupportModal: React.FC = ({ visible, onClose }) => {
- const openWhatsApp = async () => {
+export default function CustomerSupport({
+ visible,
+ onClose,
+}: CustomerSupportProps) {
+ const openWhatsApp = () => {
const url = `https://wa.me/${
SUPPORT.WHATSAPP_NUMBER
}?text=${encodeURIComponent(SUPPORT.WHATSAPP_PLACEHOLDER)}`;
-
Linking.openURL(url).catch((err) =>
console.log("Failed to open WhatsApp:", err)
);
@@ -43,84 +35,33 @@ const CustomerSupportModal: React.FC = ({ visible, onClose }) => {
};
return (
-
-
-
-
- {/* Header */}
-
- Customer Support
-
-
-
-
-
- {/* Buttons */}
-
-
-
-
- Whatsapp
-
-
-
- Call Us
-
-
-
-
- Email
-
-
-
+
+
+
+
+ Whatsapp
+
+
+
+ Call Us
+
-
+
+
+ Email
+
+
);
-};
-
-export default CustomerSupportModal;
+}
const styles = StyleSheet.create({
- overlay: {
- flex: 1,
- justifyContent: "flex-end",
- backgroundColor: "rgba(0,0,0,0.5)",
- },
- modalContainer: {
- backgroundColor: "#fff",
- borderTopLeftRadius: 12,
- borderTopRightRadius: 12,
- paddingHorizontal: 16,
- paddingVertical: 16,
- },
- header: {
- borderBottomWidth: 1,
- borderBottomColor: "#E5E9F0",
- paddingHorizontal: 16,
- paddingVertical: 8,
- flexDirection: "row",
- alignItems: "center",
- justifyContent: "space-between",
- },
- headerText: {
- fontSize: 14,
- fontWeight: "600",
- color: "#252A34",
- },
- iconButton: {
- width: 40,
- height: 40,
- padding: 10,
- justifyContent: "center",
- alignItems: "center",
- },
- content: {
- paddingVertical: 16,
- gap: 16,
- },
row: {
flexDirection: "row",
gap: 16,
diff --git a/components/home/MetricCard.tsx b/components/home/MetricCard.tsx
index 2861ead..f7efe62 100644
--- a/components/home/MetricCard.tsx
+++ b/components/home/MetricCard.tsx
@@ -13,7 +13,7 @@ const MetricCard: React.FC = ({ heading, value, unit }) => {
{heading}
- {value ?? "---"} {unit}
+ {value?.toFixed(2) ?? "---"} {unit}
diff --git a/eas.json b/eas.json
index 8fd3dd7..a27ec3a 100644
--- a/eas.json
+++ b/eas.json
@@ -3,13 +3,13 @@
"development": {
"env": {
"ENV": "development",
- "BASE_URL": "https://dev-api-service.vecmocon.com/service-buddy"
+ "BASE_URL": "https://dev-driver-saathi-api.vecmocon.com"
}
},
"production": {
"env": {
"ENV": "production",
- "BASE_URL": "https://dev-api-service.vecmocon.com/service-buddy"
+ "BASE_URL": "https://dev-driver-saathi-api.vecmocon.com"
}
}
}
diff --git a/package-lock.json b/package-lock.json
index e203d36..3801f43 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
"dependencies": {
"@expo/vector-icons": "^14.1.0",
"@react-native-async-storage/async-storage": "^2.2.0",
+ "@react-native-community/netinfo": "^11.4.1",
"@react-navigation/native": "^7.1.6",
"@react-navigation/stack": "^7.4.2",
"@reduxjs/toolkit": "^2.8.2",
@@ -30,9 +31,9 @@
"react-dom": "19.0.0",
"react-i18next": "^15.5.3",
"react-native": "0.79.4",
- "react-native-dotenv": "^3.4.11",
"react-native-maps": "^1.24.3",
"react-native-otp-entry": "^1.8.5",
+ "react-native-paper": "^5.14.5",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "^5.4.0",
"react-native-screens": "~4.11.1",
@@ -1537,6 +1538,28 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@callstack/react-theme-provider": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@callstack/react-theme-provider/-/react-theme-provider-3.0.9.tgz",
+ "integrity": "sha512-tTQ0uDSCL0ypeMa8T/E9wAZRGKWj8kXP7+6RYgPTfOPs9N07C9xM8P02GJ3feETap4Ux5S69D9nteq9mEj86NA==",
+ "license": "MIT",
+ "dependencies": {
+ "deepmerge": "^3.2.0",
+ "hoist-non-react-statics": "^3.3.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.3.0"
+ }
+ },
+ "node_modules/@callstack/react-theme-provider/node_modules/deepmerge": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz",
+ "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/@egjs/hammerjs": {
"version": "2.0.17",
"resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
@@ -3324,6 +3347,15 @@
"node": ">=10"
}
},
+ "node_modules/@react-native-community/netinfo": {
+ "version": "11.4.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-11.4.1.tgz",
+ "integrity": "sha512-B0BYAkghz3Q2V09BF88RA601XursIEA111tnc2JOaN7axJWmNefmfjZqw/KdSxKZp7CZUuPpjBmz/WCR9uaHYg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react-native": ">=0.59"
+ }
+ },
"node_modules/@react-native/assets-registry": {
"version": "0.79.4",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.79.4.tgz",
@@ -11816,18 +11848,6 @@
}
}
},
- "node_modules/react-native-dotenv": {
- "version": "3.4.11",
- "resolved": "https://registry.npmjs.org/react-native-dotenv/-/react-native-dotenv-3.4.11.tgz",
- "integrity": "sha512-6vnIE+WHABSeHCaYP6l3O1BOEhWxKH6nHAdV7n/wKn/sciZ64zPPp2NUdEUf1m7g4uuzlLbjgr+6uDt89q2DOg==",
- "license": "MIT",
- "dependencies": {
- "dotenv": "^16.4.5"
- },
- "peerDependencies": {
- "@babel/runtime": "^7.20.6"
- }
- },
"node_modules/react-native-edge-to-edge": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/react-native-edge-to-edge/-/react-native-edge-to-edge-1.6.0.tgz",
@@ -11896,6 +11916,51 @@
"react-native": "*"
}
},
+ "node_modules/react-native-paper": {
+ "version": "5.14.5",
+ "resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-5.14.5.tgz",
+ "integrity": "sha512-eaIH5bUQjJ/mYm4AkI6caaiyc7BcHDwX6CqNDi6RIxfxfWxROsHpll1oBuwn/cFvknvA8uEAkqLk/vzVihI3AQ==",
+ "license": "MIT",
+ "workspaces": [
+ "example",
+ "docs"
+ ],
+ "dependencies": {
+ "@callstack/react-theme-provider": "^3.0.9",
+ "color": "^3.1.2",
+ "use-latest-callback": "^0.2.3"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*",
+ "react-native-safe-area-context": "*"
+ }
+ },
+ "node_modules/react-native-paper/node_modules/color": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
+ "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.3",
+ "color-string": "^1.6.0"
+ }
+ },
+ "node_modules/react-native-paper/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/react-native-paper/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "license": "MIT"
+ },
"node_modules/react-native-reanimated": {
"version": "3.17.5",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.17.5.tgz",
diff --git a/package.json b/package.json
index ef5d1a4..29a92cd 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"dependencies": {
"@expo/vector-icons": "^14.1.0",
"@react-native-async-storage/async-storage": "^2.2.0",
+ "@react-native-community/netinfo": "^11.4.1",
"@react-navigation/native": "^7.1.6",
"@react-navigation/stack": "^7.4.2",
"@reduxjs/toolkit": "^2.8.2",
@@ -35,9 +36,9 @@
"react-dom": "19.0.0",
"react-i18next": "^15.5.3",
"react-native": "0.79.4",
- "react-native-dotenv": "^3.4.11",
"react-native-maps": "^1.24.3",
"react-native-otp-entry": "^1.8.5",
+ "react-native-paper": "^5.14.5",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "^5.4.0",
"react-native-screens": "~4.11.1",