Store Info Updated

This commit is contained in:
CPM
2025-08-07 13:38:34 +05:30
parent 5a910f62e2
commit 2280bd6d19
16 changed files with 1642 additions and 1689 deletions
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.
+1
View File
@@ -33,6 +33,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# to write custom TurboModules/Fabric components OR use libraries that # to write custom TurboModules/Fabric components OR use libraries that
# are providing them. # are providing them.
newArchEnabled=false newArchEnabled=false
org.gradle.java.home=/opt/homebrew/opt/openjdk@17
# Use this property to enable or disable the Hermes JS engine. # Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead. # If set to false, you will be using JSC instead.
@@ -263,7 +263,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = JGDHGNH9XY; DEVELOPMENT_TEAM = JGDHGNH9XY;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = PerformicsStoreDNA/Info.plist; INFOPLIST_FILE = PerformicsStoreDNA/Info.plist;
@@ -272,7 +272,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.3; MARKETING_VERSION = 1.4;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"$(inherited)", "$(inherited)",
"-ObjC", "-ObjC",
@@ -292,7 +292,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = JGDHGNH9XY; DEVELOPMENT_TEAM = JGDHGNH9XY;
INFOPLIST_FILE = PerformicsStoreDNA/Info.plist; INFOPLIST_FILE = PerformicsStoreDNA/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.1; IPHONEOS_DEPLOYMENT_TARGET = 15.1;
@@ -300,7 +300,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.3; MARKETING_VERSION = 1.4;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"$(inherited)", "$(inherited)",
"-ObjC", "-ObjC",
@@ -382,7 +382,10 @@
"-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1",
); );
OTHER_LDFLAGS = "$(inherited) "; OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
@@ -451,7 +454,10 @@
"-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1",
); );
OTHER_LDFLAGS = "$(inherited) "; OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos; SDKROOT = iphoneos;
USE_HERMES = true; USE_HERMES = true;
+36 -36
View File
@@ -1771,7 +1771,7 @@ PODS:
- SocketRocket - SocketRocket
- WCPhotoManipulator (~> 2.6.0) - WCPhotoManipulator (~> 2.6.0)
- Yoga - Yoga
- react-native-safe-area-context (5.5.1): - react-native-safe-area-context (5.5.2):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -1790,8 +1790,8 @@ PODS:
- React-hermes - React-hermes
- React-ImageManager - React-ImageManager
- React-jsi - React-jsi
- react-native-safe-area-context/common (= 5.5.1) - react-native-safe-area-context/common (= 5.5.2)
- react-native-safe-area-context/fabric (= 5.5.1) - react-native-safe-area-context/fabric (= 5.5.2)
- React-NativeModulesApple - React-NativeModulesApple
- React-RCTFabric - React-RCTFabric
- React-renderercss - React-renderercss
@@ -1802,7 +1802,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- Yoga - Yoga
- react-native-safe-area-context/common (5.5.1): - react-native-safe-area-context/common (5.5.2):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -1831,7 +1831,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- Yoga - Yoga
- react-native-safe-area-context/fabric (5.5.1): - react-native-safe-area-context/fabric (5.5.2):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2368,7 +2368,7 @@ PODS:
- Yoga - Yoga
- RNFS (2.20.0): - RNFS (2.20.0):
- React-Core - React-Core
- RNGestureHandler (2.27.1): - RNGestureHandler (2.27.2):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2397,7 +2397,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNPermissions (5.4.1): - RNPermissions (5.4.2):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2426,7 +2426,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNReanimated (3.18.0): - RNReanimated (3.19.0):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2453,11 +2453,11 @@ PODS:
- ReactCodegen - ReactCodegen
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- RNReanimated/reanimated (= 3.18.0) - RNReanimated/reanimated (= 3.19.0)
- RNReanimated/worklets (= 3.18.0) - RNReanimated/worklets (= 3.19.0)
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNReanimated/reanimated (3.18.0): - RNReanimated/reanimated (3.19.0):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2484,10 +2484,10 @@ PODS:
- ReactCodegen - ReactCodegen
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- RNReanimated/reanimated/apple (= 3.18.0) - RNReanimated/reanimated/apple (= 3.19.0)
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNReanimated/reanimated/apple (3.18.0): - RNReanimated/reanimated/apple (3.19.0):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2516,7 +2516,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNReanimated/worklets (3.18.0): - RNReanimated/worklets (3.19.0):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2543,10 +2543,10 @@ PODS:
- ReactCodegen - ReactCodegen
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- RNReanimated/worklets/apple (= 3.18.0) - RNReanimated/worklets/apple (= 3.19.0)
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNReanimated/worklets/apple (3.18.0): - RNReanimated/worklets/apple (3.19.0):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2575,7 +2575,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNScreens (4.11.1): - RNScreens (4.13.1):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2603,10 +2603,10 @@ PODS:
- ReactCodegen - ReactCodegen
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- RNScreens/common (= 4.11.1) - RNScreens/common (= 4.13.1)
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNScreens/common (4.11.1): - RNScreens/common (4.13.1):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2636,7 +2636,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNSVG (15.12.0): - RNSVG (15.12.1):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2663,10 +2663,10 @@ PODS:
- ReactCodegen - ReactCodegen
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- RNSVG/common (= 15.12.0) - RNSVG/common (= 15.12.1)
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNSVG/common (15.12.0): - RNSVG/common (15.12.1):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2695,7 +2695,7 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- Yoga - Yoga
- RNVectorIcons (10.2.0): - RNVectorIcons (10.3.0):
- boost - boost
- DoubleConversion - DoubleConversion
- fast_float - fast_float
@@ -2725,11 +2725,11 @@ PODS:
- SocketRocket - SocketRocket
- Yoga - Yoga
- SocketRocket (0.7.1) - SocketRocket (0.7.1)
- VisionCamera (4.7.0): - VisionCamera (4.7.1):
- VisionCamera/Core (= 4.7.0) - VisionCamera/Core (= 4.7.1)
- VisionCamera/React (= 4.7.0) - VisionCamera/React (= 4.7.1)
- VisionCamera/Core (4.7.0) - VisionCamera/Core (4.7.1)
- VisionCamera/React (4.7.0): - VisionCamera/React (4.7.1):
- React-Core - React-Core
- WCPhotoManipulator (2.6.0) - WCPhotoManipulator (2.6.0)
- Yoga (0.0.0) - Yoga (0.0.0)
@@ -3060,7 +3060,7 @@ SPEC CHECKSUMS:
react-native-geolocation: f01ad4718ad1d015d0c0dd12a6f707354022530e react-native-geolocation: f01ad4718ad1d015d0c0dd12a6f707354022530e
react-native-image-resizer: 8537d9fdbd14b9d5f301a2d319c469bf56f6e9a0 react-native-image-resizer: 8537d9fdbd14b9d5f301a2d319c469bf56f6e9a0
react-native-photo-manipulator: 5ac803352e07b7f61f5905e78952006f0c4efd54 react-native-photo-manipulator: 5ac803352e07b7f61f5905e78952006f0c4efd54
react-native-safe-area-context: d3738f0c3b1fcefaed874a45891b0d44306c47c1 react-native-safe-area-context: 68d1363b8354472a961aa6861ba8451beaf9a810
react-native-sqlite-storage: 0c84826214baaa498796c7e46a5ccc9a82e114ed react-native-sqlite-storage: 0c84826214baaa498796c7e46a5ccc9a82e114ed
React-NativeModulesApple: e16d5c133019987285f001fbf1461a861e40426f React-NativeModulesApple: e16d5c133019987285f001fbf1461a861e40426f
React-oscompat: 7c0a341cc31e350da71ddf2e46de0a845d1d1626 React-oscompat: 7c0a341cc31e350da71ddf2e46de0a845d1d1626
@@ -3095,14 +3095,14 @@ SPEC CHECKSUMS:
ReactCommon: b028d09a66e60ebd83ca59d8cc9a1216360db147 ReactCommon: b028d09a66e60ebd83ca59d8cc9a1216360db147
RNCAsyncStorage: 1f04c8d56558e533277beda29187f571cf7eecb2 RNCAsyncStorage: 1f04c8d56558e533277beda29187f571cf7eecb2
RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8 RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8
RNGestureHandler: 5e1a1605659c22098719fc2e8aee453fe728f52e RNGestureHandler: a0c83d8e4422f2ac04d1acb1741866a5184c7b73
RNPermissions: ebf576a01cc2cb73db0006e0b3c9b4760e0aa569 RNPermissions: b15c9d7ba7aacff916439d445f385abbb2a36a4f
RNReanimated: bc1ddb7a5352648bcf0d592256069833bf935a46 RNReanimated: 5ee070eb08e681be2a9ee7e797019d97d4706131
RNScreens: ee2abe7e0c548eed14e92742e81ed991165c56aa RNScreens: c63849403489bd068ea160f276fbc8416f19f2f7
RNSVG: 341f555dbcd83a34d1f058e88df387de7bbc3347 RNSVG: d407e5f2ede12bbcd92e4d23a405ad5a5f7294a3
RNVectorIcons: ef9b4b0b786053ebdd63ee2972f48de9633ba166 RNVectorIcons: be4d047a76ad307ffe54732208fb0498fcb8477f
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
VisionCamera: c5c07db74721d37f4c9f8331ad1f8da7b2539995 VisionCamera: 9a8f98ae344fe5d148f84bb45829f9e4caab9d2f
WCPhotoManipulator: 804988e16a6fe941cddff942b2acf887110de5d6 WCPhotoManipulator: 804988e16a6fe941cddff942b2acf887110de5d6
Yoga: 0c4b7d2aacc910a1f702694fa86be830386f4ceb Yoga: 0c4b7d2aacc910a1f702694fa86be830386f4ceb
+1 -1
View File
@@ -51,7 +51,7 @@
"react-native-svg": "^15.12.0", "react-native-svg": "^15.12.0",
"react-native-toast-message": "^2.3.1", "react-native-toast-message": "^2.3.1",
"react-native-vector-icons": "^10.2.0", "react-native-vector-icons": "^10.2.0",
"react-native-vision-camera": "^4.7.0", "react-native-vision-camera": "^4.7.1",
"react-redux": "^9.2.0" "react-redux": "^9.2.0"
}, },
"devDependencies": { "devDependencies": {
BIN
View File
Binary file not shown.
+79 -75
View File
@@ -6,90 +6,94 @@ import { useDispatch } from 'react-redux';
import { setUser } from '../../../redux/slices/userSlice'; import { setUser } from '../../../redux/slices/userSlice';
const SplashScreen = ({ navigation }) => { const SplashScreen = ({ navigation }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
useEffect(() => {
checkLoginStatus();
}, []);
useEffect(() => {
const checkLoginStatus = async () => { const checkLoginStatus = async () => {
try { try {
const isuserlogin = await AsyncStorage.getItem('@Dabur_DNA_User'); const isuserlogin = await AsyncStorage.getItem('@Dabur_DNA_User');
console.log("isuserlogin", isuserlogin) console.log("isuserlogin", isuserlogin)
const parsedUser = JSON.parse(isuserlogin); const parsedUser = JSON.parse(isuserlogin);
if (isuserlogin) { if (isuserlogin) {
dispatch(setUser(parsedUser)); dispatch(setUser(parsedUser));
navigation.reset({ setTimeout(() => {
index: 0, navigation.reset({
routes: [{ name: 'Welcome' }], index: 0,
}); routes: [{ name: 'Welcome' }],
} else { });
navigation.reset({ }, 1000);
index: 0, } else {
routes: [{ name: 'Login' }], setTimeout(() => {
}); navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
});
}, 1000);
}
} catch (error) {
console.error('Error checking login status:', error);
} }
} catch (error) {
console.error('Error checking login status:', error);
}
}; };
checkLoginStatus();
}, []);
return (
return ( <View style={styles.container}>
<View style={styles.container}> <View style={styles.backgroundContainer}>
<View style={styles.backgroundContainer}> <Image
<Image source={IMAGES.splashFullImg}
source={IMAGES.splashFullImg} resizeMode="stretch"
resizeMode="stretch" style={styles.backdrop}
style={styles.backdrop} />
/> </View>
</View> <View style={styles.overlay}>
<View style={styles.overlay}> <Image style={styles.logo} source={IMAGES.AppLogo} />
<Image style={styles.logo} source={IMAGES.AppLogo} /> </View>
</View> </View>
</View> );
);
}; };
export default SplashScreen; export default SplashScreen;
const styles = StyleSheet.create({ const styles = StyleSheet.create({
backgroundContainer: { backgroundContainer: {
position: 'absolute', position: 'absolute',
top: 0, top: 0,
bottom: 0, bottom: 0,
left: 0, left: 0,
right: 0, right: 0,
}, },
container: { container: {
flex: 1, flex: 1,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
}, },
overlay: { overlay: {
opacity: 1, opacity: 1,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
}, },
logo: { logo: {
backgroundColor: 'rgba(0,0,0,0)', backgroundColor: 'rgba(0,0,0,0)',
height: 200, height: 200,
width: 200, width: 200,
overflow: 'hidden', overflow: 'hidden',
resizeMode: 'contain', resizeMode: 'contain',
marginTop: 5, marginTop: 5,
justifyContent: 'center', justifyContent: 'center',
}, },
backdrop: { backdrop: {
flex: 1, flex: 1,
width: '100%', width: '100%',
height: '100%', height: '100%',
}, },
headline: { headline: {
fontSize: 18, fontSize: 18,
textAlign: 'center', textAlign: 'center',
backgroundColor: 'black', backgroundColor: 'black',
color: 'white', color: 'white',
//borderWidth:1 //borderWidth:1
}, },
}); });
+45 -153
View File
@@ -231,12 +231,6 @@ const Dashboard = (props) => {
setTabCache({}); // reset cache when filters change setTabCache({}); // reset cache when filters change
}, [month, year]); }, [month, year]);
// useEffect(() => {
// if (mainDisplayJson && storeData?.StoreId) {
// getTabData(mainDisplayJson);
// }
// }, [mainTabIndex, storeData]);
useEffect(() => { useEffect(() => {
if (mainDisplayJson && storeData?.StoreId) { if (mainDisplayJson && storeData?.StoreId) {
setTimeout(() => getTabData(mainDisplayJson), 0); setTimeout(() => getTabData(mainDisplayJson), 0);
@@ -257,14 +251,9 @@ const Dashboard = (props) => {
return; return;
} }
const escape = str => (str || '').toString().replace(/'/g, "''"); const escape = str => (str || '').toString().replace(/'/g, "''");
db.transaction(tx => { db.transaction(tx => {
data_arr.forEach(item => { data_arr.forEach(item => {
const { StoreId, StoreName, ChainName, Address, Pincode, StateName, StoreType, CityName } = item; const { StoreId, StoreName, ChainName, Address, Pincode, StateName, StoreType, CityName } = item;
// First, check if the StoreId exists
tx.executeSql( tx.executeSql(
`SELECT * FROM StoreInfoDNALocal WHERE StoreId = ?`, `SELECT * FROM StoreInfoDNALocal WHERE StoreId = ?`,
[StoreId], [StoreId],
@@ -275,8 +264,6 @@ const Dashboard = (props) => {
INSERT INTO StoreInfoDNALocal INSERT INTO StoreInfoDNALocal
(VISIT_DATE, StoreId, StoreName, ChainName, Address, Pincode, CityName, StateName, StoreType, UPLOAD_STATUS) (VISIT_DATE, StoreId, StoreName, ChainName, Address, Pincode, CityName, StateName, StoreType, UPLOAD_STATUS)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`; VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
tx.executeSql(sql, [ tx.executeSql(sql, [
d2, d2,
StoreId, StoreId,
@@ -335,47 +322,6 @@ const Dashboard = (props) => {
}); });
}; };
// const getTabData = async (tabData) => {
// setLoading(true)
// try {
// const params = {
// parameters: {
// projectid: 41654,
// year: year,
// monthno: month,
// storeid: storeData?.StoreId
// }
// };
// const graphDetails = tabData?.graphDetails || [];
// const uniqueUrls = [...new Set(graphDetails.map(graph => graph.GraphUrl))];
// const apiCalls = uniqueUrls.map(url => {
// const config = {
// method: 'post',
// url: url, // each URL from the list
// headers: {
// 'X-API-Key': 'f7fa9b09-ced8-4862-8cb7-5e7599d90fa2',
// 'Content-Type': 'application/json'
// },
// data: params
// };
// return axios.request(config);
// });
// const results = await Promise.all(apiCalls);
// const dataMap = {};
// uniqueUrls.forEach((url, idx) => {
// dataMap[url] = results[idx].data; // collect raw API response
// });
// setGraphApiData(dataMap);
// setLoading(false)
// } catch (err) {
// console.log("❌ Error fetching tab data:", err);
// }
// };
// 🔧 Optimized getTabData with caching logic added
const getTabData = async (tabData) => { const getTabData = async (tabData) => {
if (!storeData?.StoreId) return; if (!storeData?.StoreId) return;
@@ -400,23 +346,8 @@ const Dashboard = (props) => {
console.log("🔁 API Params:", params); console.log("🔁 API Params:", params);
const graphDetails = tabData?.graphDetails || []; const graphDetails = tabData?.graphDetails || [];
const uniqueUrls = [...new Set(graphDetails.map(graph => graph.GraphUrl))]; const uniqueUrls = [...new Set(graphDetails.map(graph => graph.GraphUrl))];
// const apiCalls = uniqueUrls.map(url => {
// const config = {
// method: 'post',
// url: url,
// headers: {
// 'X-API-Key': 'f7fa9b09-ced8-4862-8cb7-5e7599d90fa2',
// 'Content-Type': 'application/json'
// },
// data: params
// };
// return axios.request(config);
// });
const apiCalls = uniqueUrls.map(async url => { const apiCalls = uniqueUrls.map(async url => {
const config = { const config = {
method: 'post', method: 'post',
@@ -430,15 +361,10 @@ const Dashboard = (props) => {
return await fetchWithRetry(config); return await fetchWithRetry(config);
}); });
const results = await Promise.all(apiCalls); const results = await Promise.all(apiCalls);
console.log("📊 API Results:", results.map(r => r?.data)); console.log("📊 API Results:", results.map(r => r?.data));
const dataMap = {}; const dataMap = {};
// uniqueUrls.forEach((url, idx) => {
// dataMap[url] = results[idx].data;
// });
uniqueUrls.forEach((url, idx) => { uniqueUrls.forEach((url, idx) => {
const responseData = results[idx]?.data; const responseData = results[idx]?.data;
if (!responseData || !responseData.data || responseData.data.length === 0) { if (!responseData || !responseData.data || responseData.data.length === 0) {
@@ -447,8 +373,6 @@ const Dashboard = (props) => {
} }
dataMap[url] = responseData; dataMap[url] = responseData;
}); });
console.log('uniqueUrls-dataMap---------->', dataMap);
setGraphApiData(dataMap); setGraphApiData(dataMap);
setTabCache(prev => ({ ...prev, [tabKey]: dataMap })); setTabCache(prev => ({ ...prev, [tabKey]: dataMap }));
@@ -459,7 +383,6 @@ const Dashboard = (props) => {
} }
}; };
const fetchWithRetry = async (config, retries = 2, delay = 1000) => { const fetchWithRetry = async (config, retries = 2, delay = 1000) => {
for (let i = 0; i <= retries; i++) { for (let i = 0; i <= retries; i++) {
try { try {
@@ -477,8 +400,6 @@ const Dashboard = (props) => {
return null; // all attempts failed return null; // all attempts failed
}; };
const fetchDetailGraphs = async (detailPages) => { const fetchDetailGraphs = async (detailPages) => {
try { try {
const resultMap = {}; const resultMap = {};
@@ -501,7 +422,6 @@ const Dashboard = (props) => {
} }
}; };
const handleScroll = (event) => { const handleScroll = (event) => {
const offsetY = event.nativeEvent.contentOffset.y; const offsetY = event.nativeEvent.contentOffset.y;
setShowButton(offsetY > 0); // Show button only if not at the top setShowButton(offsetY > 0); // Show button only if not at the top
@@ -567,7 +487,7 @@ const Dashboard = (props) => {
console.log('state--', state, city); console.log('state--', state, city);
console.log('searchText--', searchText); console.log('searchText--', searchText);
setSearchResult(!searchResult) // setSearchResult(!searchResult)
setLoading(true) setLoading(true)
try { try {
const params = JSON.stringify({ const params = JSON.stringify({
@@ -577,6 +497,9 @@ const Dashboard = (props) => {
"StoreSearchText": searchText ? searchText : "", "StoreSearchText": searchText ? searchText : "",
"UserId": userId || 0, "UserId": userId || 0,
}); });
console.log('params---->', params);
const config = { const config = {
method: 'post', method: 'post',
@@ -604,18 +527,11 @@ const Dashboard = (props) => {
const renderItem = ({ item }) => { const renderItem = ({ item }) => {
const apiData = graphApiData[item.GraphUrl]; const apiData = graphApiData[item.GraphUrl];
// const values = apiData?.data || []; // const values = apiData?.data || [];
const values = apiData?.data?.length ? apiData.data : []; const values = apiData?.data?.length ? apiData.data : [];
const scoreValue = values.length > 0 ? Object.values(values[0])[0] : null; const scoreValue = values.length > 0 ? Object.values(values[0])[0] : null;
// <Text>{scoreValue !== undefined ? `${scoreValue.toFixed(1)}%` : "No Data"}</Text> // <Text>{scoreValue !== undefined ? `${scoreValue.toFixed(1)}%` : "No Data"}</Text>
console.log('apiData --->', apiData);
if (apiData?.status === 'error') { if (apiData?.status === 'error') {
return ( return (
<View style={styles.percentBox}> <View style={styles.percentBox}>
@@ -625,15 +541,6 @@ const Dashboard = (props) => {
); );
} }
// if (!apiData) {
// return (
// <View style={[styles.percentBox, { justifyContent: 'center', alignItems: 'center' }]}>
// <ActivityIndicator size="small" color="#113F8C" />
// </View>
// );
// }
switch (item.GraphType) { switch (item.GraphType) {
case "ScoreCard": case "ScoreCard":
const firstDataObj = values[0] || {}; const firstDataObj = values[0] || {};
@@ -650,7 +557,7 @@ const Dashboard = (props) => {
//GIFTED CHART LIBRARY ----- //GIFTED CHART LIBRARY -----
case "BarGraph": case "BarGraph":
const chartWidth = screenWidth * 0.75; const chartWidth = screenWidth * 0.80;
const barWidth = 40; const barWidth = 40;
const barColors = ['#1BF2E0', '#1B7BF2', '#1BC0F2']; const barColors = ['#1BF2E0', '#1B7BF2', '#1BC0F2'];
@@ -675,7 +582,7 @@ const Dashboard = (props) => {
} }
return ( return (
<View style={{ alignItems: 'center', justifyContent: 'center', padding: 10, borderWidth: 0.5, borderRadius: 10, }}> <View style={{ width: '100%', alignItems: 'center', justifyContent: 'center', padding: 10, borderWidth: 0.5, borderRadius: 25, }}>
{/* <View style={{ alignSelf: 'center', borderWidth: 0.5,borderRadius:20, paddingBottom: 10 }}> */} {/* <View style={{ alignSelf: 'center', borderWidth: 0.5,borderRadius:20, paddingBottom: 10 }}> */}
<Text style={{ fontSize: 16, fontWeight: '600', marginBottom: 10 }}> <Text style={{ fontSize: 16, fontWeight: '600', marginBottom: 10 }}>
@@ -800,7 +707,6 @@ const Dashboard = (props) => {
}, 300), []); }, 300), []);
const feedbackCount = visitedStoreData1?.filter(item => item?.UPLOAD_STATUS == 'U')?.length; const feedbackCount = visitedStoreData1?.filter(item => item?.UPLOAD_STATUS == 'U')?.length;
const filteredStores = storeList.filter((store) => { const filteredStores = storeList.filter((store) => {
const query = searchQuery.toLowerCase(); const query = searchQuery.toLowerCase();
return ( return (
@@ -904,14 +810,13 @@ const Dashboard = (props) => {
onRightPress={() => setFeedBackModal(true)} onRightPress={() => setFeedBackModal(true)}
/> />
{/* Store Name Card */}
<View style={styles.row}> <View style={styles.row}>
<View style={styles.selectedStoreText}> <View style={styles.selectedStoreText}>
{/* <Text style={[styles.storeNameText, { width: '90%' }]}> {`${storeData?.StoreName} \n(Store Id :${storeData?.StoreId})`}</Text> */} <View style={{ width: '88%' }}>
<View style={{ width: '90%' }}>
<Text style={[styles.storeNameText, {}]}>{storeData?.StoreName}</Text> <Text style={[styles.storeNameText, {}]}>{storeData?.StoreName}</Text>
<Text style={{ color: GlobalTheme.colors.gray, fontSize: 13 }}>Store Id : {storeData?.StoreId}</Text> <Text style={{ color: GlobalTheme.colors.gray, fontSize: 13 }}>Store Id : {storeData?.StoreId}</Text>
</View> </View>
<Text style={{}}></Text>
<TouchableOpacity onPress={() => openBottomSheet()} style={styles.filterIcon}> <TouchableOpacity onPress={() => openBottomSheet()} style={styles.filterIcon}>
<Image source={IMAGES.filterIcon} style={{ height: 18, width: 18 }} /> <Image source={IMAGES.filterIcon} style={{ height: 18, width: 18 }} />
</TouchableOpacity> </TouchableOpacity>
@@ -960,7 +865,6 @@ const Dashboard = (props) => {
<View style={styles.seperator} /> <View style={styles.seperator} />
{/* Main Tab */} {/* Main Tab */}
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
{mainTabs.map((tab, index) => { {mainTabs.map((tab, index) => {
const isSelected = index === mainTabIndex; const isSelected = index === mainTabIndex;
@@ -1014,8 +918,7 @@ const Dashboard = (props) => {
{/* Score Card */} {/* Score Card */}
<View style={{ margin: 5 }}> <View style={{ margin: 5 }}>
<View style={{ marginHorizontal: 5, marginTop: 5 }}>
<View style={{ marginHorizontal: 5 }}>
{firstItem && ( {firstItem && (
<TouchableOpacity <TouchableOpacity
activeOpacity={0.8} activeOpacity={0.8}
@@ -1027,16 +930,7 @@ const Dashboard = (props) => {
} }
}} }}
> >
<View <View style={{ width: '48%', height: 100, minHeight: 100, borderRadius: 20, justifyContent: 'center', alignItems: 'center', backgroundColor: "#C3D7FF", width: '100%', elevation: 0, }} >
style={[
styles.percentBox,
{
backgroundColor: "#C3D7FF",
width: '100%',
elevation: 0,
},
]}
>
<View style={{ flexDirection: 'row', alignItems: 'center' }}> <View style={{ flexDirection: 'row', alignItems: 'center' }}>
<View style={{ width: '80%', alignItems: 'center' }}> <View style={{ width: '80%', alignItems: 'center' }}>
<Text style={styles.boxText}>{firstItem.GraphTitle}</Text> <Text style={styles.boxText}>{firstItem.GraphTitle}</Text>
@@ -1286,7 +1180,7 @@ const Dashboard = (props) => {
<View style={[styles.row, {}]}> <View style={[styles.row, {}]}>
<Text style={styles.dropHeaderText}>State</Text> <Text style={styles.dropHeaderText}>State</Text>
<Text style={styles.dropHeaderText}> City</Text> <Text style={styles.dropHeaderText}> City</Text>
<Text style={styles.dropHeaderText}> ASM Area</Text> {/* <Text style={styles.dropHeaderText}> ASM Area</Text> */}
</View> </View>
{/* Dropdown */} {/* Dropdown */}
@@ -1340,9 +1234,9 @@ const Dashboard = (props) => {
const uniqueAsms = Array.from(new Map(asms.map(a => [a.value, a])).values()); const uniqueAsms = Array.from(new Map(asms.map(a => [a.value, a])).values());
setCityOptions(uniqueCities); setCityOptions(uniqueCities);
setAsmOptions(uniqueAsms); // setAsmOptions(uniqueAsms);
setCity(null); // reset setCity(null); // reset
setAsmArea(null); // reset // setAsmArea(null); // reset
}} }}
containerStyle={{ flex: 1 }} containerStyle={{ flex: 1 }}
/> />
@@ -1356,12 +1250,12 @@ const Dashboard = (props) => {
/> />
{/* ASM Area Dropdown */} {/* ASM Area Dropdown */}
<CustomDropdown {/* <CustomDropdown
data={asmOptions} data={asmOptions}
value={asmArea} value={asmArea}
onChange={(item) => setAsmArea(item.value)} onChange={(item) => setAsmArea(item.value)}
containerStyle={{ flex: 1 }} containerStyle={{ flex: 1 }}
/> /> */}
</View> </View>
@@ -1382,38 +1276,38 @@ const Dashboard = (props) => {
textstyle={{ color: GlobalTheme.colors.white, fontSize: GlobalTheme.typography.fontSize.medium }} textstyle={{ color: GlobalTheme.colors.white, fontSize: GlobalTheme.typography.fontSize.medium }}
/> />
</View> </View>
{searchResult ?
<View style={{ marginBottom: 70 }}>
<View style={{ marginTop: 20 }}>
{/* <Text style={{ color: '#000', fontSize: 14 }}>{storeList ? storeList.length : 0} Store</Text> */}
<Text style={{ color: '#000', fontSize: 14 }}>{filteredStores.length} Store{filteredStores.length !== 1 ? 's' : ''}</Text>
</View>
<View style={styles.searchByID}>
<Image source={IMAGES.searchIcon} style={{ height: 15, width: 15 }} />
<TextInput
placeholder="Search by Store Name or Store ID"
placeholderTextColor={'gray'}
value={searchQuery}
onChangeText={setSearchQuery}
style={{ color: '#000', marginLeft: 5, height: 38, width: '95%' }}
/>
</View>
{filteredStores && filteredStores.length > 0 ? filteredStores.map((store) => (
<TouchableOpacity onPress={() => onSelectStore(store)}
key={store.StoreId} style={styles.storeCard}>
<Text style={styles.cardTextBold}>{store.StoreName}</Text>
<Text style={styles.cardText}>{store.Address}</Text>
<Text style={styles.cardText}>{'Store Id:'} {store.StoreId}</Text>
</TouchableOpacity>
)) : null
}
<View style={{ marginBottom: 70 }}>
<View style={{ marginTop: 20 }}>
{/* <Text style={{ color: '#000', fontSize: 14 }}>{storeList ? storeList.length : 0} Store</Text> */}
<Text style={{ color: '#000', fontSize: 14 }}>{filteredStores.length} Store{filteredStores.length !== 1 ? 's' : ''}</Text>
</View> </View>
: null
} <View style={styles.searchByID}>
<Image source={IMAGES.searchIcon} style={{ height: 15, width: 15 }} />
<TextInput
placeholder="Search by Store Name or Store ID"
placeholderTextColor={'gray'}
value={searchQuery}
onChangeText={setSearchQuery}
style={{ color: '#000', marginLeft: 5, height: 38, width: '95%' }}
/>
</View>
{filteredStores && filteredStores.length > 0 ? filteredStores.map((store) => (
<TouchableOpacity onPress={() => onSelectStore(store)}
key={store.StoreId} style={styles.storeCard}>
<Text style={styles.cardTextBold}>{store.StoreName}</Text>
<Text style={styles.cardText}>{store.Address}</Text>
<Text style={styles.cardText}>{'Store Id:'} {store.StoreId}</Text>
</TouchableOpacity>
))
: null
}
</View>
</View> </View>
@@ -1436,5 +1330,3 @@ const Dashboard = (props) => {
} }
export default Dashboard export default Dashboard
@@ -17,12 +17,12 @@
"TabRow": 1, "TabRow": 1,
"TabCol": 2 "TabCol": 2
}, },
{ // {
"TabId": 3, // "TabId": 3,
"TabName": "SOS Compliance", // "TabName": "SOS Compliance",
"TabRow": 1, // "TabRow": 1,
"TabCol": 3 // "TabCol": 3
}, // },
{ {
"TabId": 4, "TabId": 4,
"TabName": "OSA", "TabName": "OSA",
@@ -61,15 +61,15 @@
"GraphBackground": "#E2C8FE", "GraphBackground": "#E2C8FE",
"GraphOptions": {} "GraphOptions": {}
}, },
{ // {
"TabId": 1, // "TabId": 1,
"GraphId": 3, // "GraphId": 3,
"GraphType": "ScoreCard", // "GraphType": "ScoreCard",
"GraphTitle": "SOS Compliance", // "GraphTitle": "SOS Compliance",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Compliance_Perc", // "GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Compliance_Perc",
"GraphBackground": "#FFD7C3", // "GraphBackground": "#FFD7C3",
"GraphOptions": {} // "GraphOptions": {}
}, // },
{ {
"TabId": 1, "TabId": 1,
"GraphId": 4, "GraphId": 4,
@@ -193,7 +193,7 @@
"TabId": 5, "TabId": 5,
"GraphId": 5, "GraphId": 5,
"GraphType": "Table", "GraphType": "Table",
"GraphTitle": "Asset Availability", "GraphTitle": "Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/asset_availability_mtd", "GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/asset_availability_mtd",
"GraphBackground": "#ECFFFA", "GraphBackground": "#ECFFFA",
"GraphOptions": {} "GraphOptions": {}
@@ -202,7 +202,7 @@
"TabId": 5, "TabId": 5,
"GraphId": 5, "GraphId": 5,
"GraphType": "Table", "GraphType": "Table",
"GraphTitle": "Asset", "GraphTitle": "Additional Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/additional_visibility_mtd", "GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/additional_visibility_mtd",
"GraphBackground": "#ECFFFA", "GraphBackground": "#ECFFFA",
"GraphOptions": {} "GraphOptions": {}
@@ -232,7 +232,7 @@
"TabId": 3, "TabId": 3,
"GraphId": 3, "GraphId": 3,
"GraphType": "Table", "GraphType": "Table",
"GraphTitle": "SOS Compliance - Category", "GraphTitle": "OSA - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/osa_perc_on_category", "GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/osa_perc_on_category",
"GraphBackground": "#ECFFFA", "GraphBackground": "#ECFFFA",
"GraphOptions": {} "GraphOptions": {}
@@ -298,12 +298,12 @@
"TabRow": 1, "TabRow": 1,
"TabCol": 2 "TabCol": 2
}, },
{ // {
"TabId": 3, // "TabId": 3,
"TabName": "SOS Compliance", // "TabName": "SOS Compliance",
"TabRow": 1, // "TabRow": 1,
"TabCol": 3 // "TabCol": 3
}, // },
{ {
"TabId": 4, "TabId": 4,
"TabName": "OSA", "TabName": "OSA",
@@ -342,15 +342,15 @@
"GraphBackground": "#E2C8FE", "GraphBackground": "#E2C8FE",
"GraphOptions": {} "GraphOptions": {}
}, },
{ // {
"TabId": 1, // "TabId": 1,
"GraphId": 3, // "GraphId": 3,
"GraphType": "ScoreCard", // "GraphType": "ScoreCard",
"GraphTitle": "SOS Compliance", // "GraphTitle": "SOS Compliance",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/sos_compliance_lsv_perc", // "GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/sos_compliance_lsv_perc",
"GraphBackground": "#FFD7C3", // "GraphBackground": "#FFD7C3",
"GraphOptions": {} // "GraphOptions": {}
}, // },
{ {
"TabId": 1, "TabId": 1,
"GraphId": 4, "GraphId": 4,
+14 -3
View File
@@ -146,7 +146,7 @@ export const styles = StyleSheet.create({
fontWeight: '400' fontWeight: '400'
}, },
dropHeaderText: { dropHeaderText: {
width: '33%', width: '50%',
color: '#000', color: '#000',
fontWeight: '400', fontWeight: '400',
fontSize: 14 fontSize: 14
@@ -202,7 +202,7 @@ export const styles = StyleSheet.create({
}, },
filterIcon: { filterIcon: {
backgroundColor: '#D8E3F1', backgroundColor: '#D8E3F1',
padding: 3, padding: 5,
borderRadius: 5 borderRadius: 5
}, },
storeInfoText: { storeInfoText: {
@@ -217,9 +217,20 @@ export const styles = StyleSheet.create({
minHeight: 100, minHeight: 100,
backgroundColor: '#EAF1FF', backgroundColor: '#EAF1FF',
borderRadius: 20, borderRadius: 20,
elevation: 2,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
// Cross-platform shadow styles
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
shadowRadius: 2,
},
android: {
elevation: 2,
},
}),
}, },
boxText: { boxText: {
color: '#000', color: '#000',
+300 -259
View File
@@ -9,311 +9,352 @@ import Loader from '../../../constants/Loader';
import { SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaView } from 'react-native-safe-area-context';
const storeinfodata = [ const storeinfodata = [
{ {
tabId: 0, tabId: 0,
section: 'Store details', section: 'Store details',
items: [ items: [
{ brand: 'Store Name', name: 'Reliance Smart' }, { brand: 'Store Name', name: 'Reliance Smart' },
{ brand: 'Store ID', name: '#98440' }, { brand: 'Store ID', name: '#98440' },
{ brand: 'Address', name: 'Rabindra Nagar, Delhi 110003' }, { brand: 'Address', name: 'Rabindra Nagar, Delhi 110003' },
{ brand: 'City', name: 'Okhla' }, { brand: 'City', name: 'Okhla' },
{ brand: 'Store Size', name: '15002000 sq ft' }, { brand: 'Store Size', name: '15002000 sq ft' },
{ brand: 'Average Footfall', name: '10000' }, { brand: 'Average Footfall', name: '10000' },
{ brand: 'Store age', name: '8' }, { brand: 'Store age', name: '8' },
{ brand: 'Store Ranking', name: '24' }, { brand: 'Store Ranking', name: '24' },
], ],
}, },
{ {
tabId: 0, tabId: 0,
section: 'Dabur Employees', section: 'Dabur Employees',
items: [ items: [
{ brand: 'RKAM', name: 'Rajesh Paal Singh' }, { brand: 'RKAM', name: 'Rajesh Paal Singh' },
{ brand: 'SO', name: 'Soniya Singhal' }, { brand: 'SO', name: 'Soniya Singhal' },
], ],
}, },
{ {
tabId: 0, tabId: 0,
section: '3P employees', section: '3P employees',
items: [ items: [
{ brand: 'Promoter Name', name: 'Payal Singh' }, { brand: 'Promoter Name', name: 'Payal Singh' },
{ brand: 'AM Name', name: 'Soniya Singhal' }, { brand: 'AM Name', name: 'Soniya Singhal' },
{ brand: 'Supervisor Name', name: 'Soniya Dhankar' }, { brand: 'Supervisor Name', name: 'Soniya Dhankar' },
{ brand: 'City', name: 'Okhla' }, { brand: 'City', name: 'Okhla' },
{ brand: 'Promoter duration', name: '2 Year 7 months' }, { brand: 'Promoter duration', name: '2 Year 7 months' },
{ brand: 'Average incentive', name: '5000' }, { brand: 'Average incentive', name: '5000' },
], ],
}, },
// Last Visit Details (tabId: 1) // Last Visit Details (tabId: 1)
{ {
tabId: 1, tabId: 1,
section: 'Dabur employee', section: 'Dabur employee',
items: [ items: [
{ brand: 'SO', name: 'Rajesh Paal Singh', date: '23/05/2025', test: 'gxsjhxbas' }, { brand: 'SO', name: 'Rajesh Paal Singh', date: '23/05/2025', test: 'gxsjhxbas' },
{ brand: 'AH', name: 'Umesh Singh', date: '18/04/2025' }, { brand: 'AH', name: 'Umesh Singh', date: '18/04/2025' },
{ brand: 'KAM', name: 'Rahul Tawde', date: '15/05/2025' }, { brand: 'KAM', name: 'Rahul Tawde', date: '15/05/2025' },
{ brand: 'Others', name: 'Singhal Singh', date: '06/05/2025' }, { brand: 'Others', name: 'Singhal Singh', date: '06/05/2025' },
], ],
}, },
{ {
tabId: 1, tabId: 1,
section: '3P team', section: '3P team',
items: [ items: [
{ brand: 'Supervisor', name: 'Ashish Talwar', date: '27/05/2025' }, { brand: 'Supervisor', name: 'Ashish Talwar', date: '27/05/2025' },
{ brand: 'AM', name: 'Soniya Singhal', date: '23/05/2025' }, { brand: 'AM', name: 'Soniya Singhal', date: '23/05/2025' },
], ],
}, },
// Competition (tabId: 2) // Competition (tabId: 2)
{ {
tabId: 2, tabId: 2,
section: 'Competition assets', section: 'Competition assets',
items: [ items: [
{ brand: 'Marico', value: 5 }, { brand: 'Marico', value: 5 },
{ brand: 'Colgate', value: 1 }, { brand: 'Colgate', value: 1 },
{ brand: 'Godrej', value: 2 }, { brand: 'Godrej', value: 2 },
{ brand: 'HUL', value: 1 }, { brand: 'HUL', value: 1 },
{ brand: 'XX', value: 2 }, { brand: 'XX', value: 2 },
], ],
}, },
{ {
tabId: 2, tabId: 2,
section: 'Promoter details', section: 'Promoter details',
items: [ items: [
{ brand: 'Marico', value: 1 }, { brand: 'Marico', value: 1 },
{ brand: 'Colgate', value: 1 }, { brand: 'Colgate', value: 1 },
{ brand: 'Godrej', value: 1 }, { brand: 'Godrej', value: 1 },
{ brand: 'HUL', value: 1 }, { brand: 'HUL', value: 1 },
{ brand: 'XX', value: 0 }, { brand: 'XX', value: 0 },
], ],
}, },
]; ];
const tabs = [ const tabs = [
{ id: 0, title: 'Store Info' }, { id: 0, title: 'Store Info' },
{ id: 1, title: 'Last visit details' }, { id: 1, title: 'Last visit details' },
{ id: 2, title: 'Competition' }, { id: 2, title: 'Competition' },
]; ];
const RenderHeader = ({ columns }) => { const RenderHeader = ({ columns }) => {
const colWidth = Screen.screenWidth * 0.95 / columns?.length; const colWidth = Screen.screenWidth * 0.95 / columns?.length;
return ( return (
null null
// <View style={{ flexDirection: 'row', paddingVertical: 6 }}> // <View style={{ flexDirection: 'row', paddingVertical: 6 }}>
// {columns.map((col, index) => ( // {columns.map((col, index) => (
// <View key={index} style={{ width: colWidth }}> // <View key={index} style={{ width: colWidth }}>
// <Text style={styles.subheaderText}>{col.toUpperCase()}</Text> // <Text style={styles.subheaderText}>{col.toUpperCase()}</Text>
// </View> // </View>
// ))} // ))}
// </View> // </View>
); );
}; };
const RenderItem = ({ item, columns }) => { const RenderItem = ({ item, columns }) => {
const colWidth = Screen.screenWidth * 0.95 / columns?.length; const colWidth = Screen.screenWidth * 0.95 / columns?.length;
return ( return (
<View> <View>
<View style={styles.row}> <View style={styles.row}>
{columns.map((key, index) => ( {columns.map((key, index) => (
<View key={index} style={{ width: colWidth }}> <View key={index} style={{ width: colWidth }}>
<Text style={styles.name}>{String(item[key] ?? '')}</Text> <Text style={styles.name}>{String(item[key] ?? '')}</Text>
</View> </View>
))} ))}
</View>
<View style={[horizonalLine, { marginVertical: 4 }]} />
</View> </View>
<View style={[horizonalLine, { marginVertical: 4 }]} /> );
</View>
);
}; };
const SectionListView = ({ listData }) => { const SectionListView = ({ listData }) => {
const scrollRef = useRef(null); // shared horizontal scroll ref const scrollRef = useRef(null); // shared horizontal scroll ref
console.log("/-", listData) console.log("/-", listData)
return ( return (
<FlatList <FlatList
data={listData} data={listData}
keyExtractor={(item, index) => item.section + index} keyExtractor={(item, index) => item.section + index}
contentContainerStyle={{ paddingBottom: 20 }} contentContainerStyle={{ paddingBottom: 20 }}
ItemSeparatorComponent={() => <View style={{ paddingVertical: 5 }} />} ItemSeparatorComponent={() => <View style={{ paddingVertical: 5 }} />}
renderItem={({ item }) => { renderItem={({ item }) => {
const columns = Object.keys(item.items[0] || {}).filter( const columns = Object.keys(item.items[0] || {}).filter(
key => item.items.some(obj => obj[key] !== undefined && obj[key] !== null) key => item.items.some(obj => obj[key] !== undefined && obj[key] !== null)
); );
return ( return (
<View style={styles.section}> <>
<Text style={styles.sectionTitle}>{item.section}</Text> {!item.hideSectionTitle && (
<View style={[horizonalLine, { marginVertical: 10 }]} /> <>
<Text style={styles.sectionTitle}>{item.section}</Text>
{/* <View style={[horizonalLine, { marginVertical: 10 }]} /> */}
</>
)}
<View style={styles.section}>
{/* ✅ Only show title if not hidden */}
{/* Shared horizontal scroll view for header + rows */}
<ScrollView {/* <Text style={styles.sectionTitle}>{item.section}</Text>
horizontal <View style={[horizonalLine, { marginVertical: 10 }]} /> */}
ref={scrollRef}
showsHorizontalScrollIndicator={false} {/* Shared horizontal scroll view for header + rows */}
scrollEventThrottle={16} <ScrollView
> horizontal
<View> ref={scrollRef}
<RenderHeader columns={columns} /> showsHorizontalScrollIndicator={false}
{item.items.map((subItem, index) => ( scrollEventThrottle={16}
<RenderItem key={index} item={subItem} columns={columns} /> >
))} <View>
</View> <RenderHeader columns={columns} />
</ScrollView> {item.items.map((subItem, index) => (
</View> <RenderItem key={index} item={subItem} columns={columns} />
); ))}
}} </View>
/> </ScrollView>
); </View>
</>
);
}}
/>
);
}; };
const StoreInfo = ({ navigation, route }) => { const StoreInfo = ({ navigation, route }) => {
const { storeData } = route.params || {}; const { storeData } = route.params || {};
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [selectedTab, setSelectedTab] = useState(0); const [selectedTab, setSelectedTab] = useState(0);
const [storeInfoData, setStoreInfoData] = useState([]) const [storeInfoData, setStoreInfoData] = useState([])
useEffect(() => { useEffect(() => {
getStoreInfo() getStoreInfo()
}, []) }, [])
const getStoreInfo = async () => { const getStoreInfo = async () => {
setLoading(true); setLoading(true);
try { try {
const params = { StoreId: storeData?.StoreId || "723" }; const params = { StoreId: storeData?.StoreId || "723" };
const config = { const config = {
method: 'post', method: 'post',
url: 'https://api1.parinaam.in/api/dabur/StoreDNAstoreInfo', url: 'https://api1.parinaam.in/api/dabur/StoreDNAstoreInfo',
headers: { headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a', 'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
data: params data: params
}; };
const response = await axios.request(config); const response = await axios.request(config);
const res = response.data?.StoreDNAstoreInfo || {}; const res = response.data?.StoreDNAstoreInfo || {};
// Step 1: Flatten API data // Step 1: Flatten API data
const tempData = []; const tempData = [];
Object.entries(res).forEach(([sectionTitle, dataArray]) => { Object.entries(res).forEach(([sectionTitle, dataArray]) => {
if (dataArray?.length > 0) { if (dataArray?.length > 0) {
const tabId = dataArray[0]?.TabId ?? 0; const tabId = dataArray[0]?.TabId ?? 0;
dataArray.forEach(item => { dataArray.forEach(item => {
const cleanItem = { ...item }; const cleanItem = { ...item };
delete cleanItem.TabId; delete cleanItem.TabId;
delete cleanItem.TabName; delete cleanItem.TabName;
console.log("tempData---", item) console.log("tempData---", item)
const formattedItems = Object.entries(cleanItem).map(([key, value]) => ({ const formattedItems = Object.entries(cleanItem).map(([key, value]) => ({
brand: key, brand: key,
name: String(value) name: String(value)
})); }));
tempData.push({ tempData.push({
tabId, tabId,
section: sectionTitle.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()), section: sectionTitle.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
items: formattedItems items: formattedItems
}); });
}); });
} }
}); });
// Step 2: Group items by tabId and section // Step 2: Group items by tabId and section
const groupedData = {}; // const groupedData = {};
// tempData.forEach(entry => {
// const key = `${entry.tabId}-${entry.section}`;
// if (!groupedData[key]) {
// groupedData[key] = {
// tabId: entry.tabId,
// section: entry.section,
// items: []
// };
// }
// groupedData[key].items.push(...entry.items);
// });
tempData.forEach(entry => { // 👇 Replace Step 2 with this
const key = `${entry.tabId}-${entry.section}`; const groupedData = {};
if (!groupedData[key]) { let threePEmployeeCount = 0;
groupedData[key] = {
tabId: entry.tabId,
section: entry.section,
items: []
};
}
groupedData[key].items.push(...entry.items);
});
// let objTemp={} tempData.forEach(entry => {
// groupedData['0-Dabur Employee']?.items if (entry.section === "3P Employee") {
// increment counter
threePEmployeeCount += 1;
const uniqueKey = `${entry.tabId}-${entry.section}-${Math.random()}`;
groupedData[uniqueKey] = {
tabId: entry.tabId,
section: entry.section,
items: entry.items,
hideSectionTitle: threePEmployeeCount > 1 // 👈 hide title after first card
};
} else {
const key = `${entry.tabId}-${entry.section}`;
if (!groupedData[key]) {
groupedData[key] = {
tabId: entry.tabId,
section: entry.section,
items: []
};
}
groupedData[key].items.push(...entry.items);
}
});
// Step 3: Set to state
setStoreInfoData(Object.values(groupedData));
setLoading(false);
} catch (error) {
console.log("❌ store info api error:", error);
setLoading(false);
}
};
const filteredData = Array.isArray(storeInfoData)
? storeInfoData.filter(item => item.tabId === selectedTab)
: [];
const selectedTabTitle = tabs?.find(tab => tab.id === selectedTab)?.title ?? 'NA';
const dynamicTabs = Array.isArray(storeInfoData) // let objTemp={}
? Array.from(new Set(storeInfoData.map(item => item.tabId))).map(id => ({ // groupedData['0-Dabur Employee']?.items
id,
title: tabs.find(tab => tab.id === id)?.title || `Tab ${id}`
}))
: [];
const renderTabContent = () => {
switch (selectedTab) {
case 0:
return <SectionListView listData={filteredData} />
case 1:
return <SectionListView listData={filteredData} />
case 2:
return <SectionListView listData={filteredData} />;
default:
return null;
}
};
return ( // Step 3: Set to state
setStoreInfoData(Object.values(groupedData));
setLoading(false);
} catch (error) {
console.log("❌ store info api error:", error);
setLoading(false);
}
};
<SafeAreaView style={{ flex: 1, backgroundColor: GlobalTheme.colors.primary }}> const filteredData = Array.isArray(storeInfoData)
<View style={[styles.container, { paddingHorizontal: 0 }]}> ? storeInfoData.filter(item => item.tabId === selectedTab)
<CustomHeader : [];
title={'Store Info'} const selectedTabTitle = tabs?.find(tab => tab.id === selectedTab)?.title ?? 'NA';
leftIcon={IMAGES.leftArrowIcon}
onLeftPress={() => navigation.goBack()} /> const dynamicTabs = Array.isArray(storeInfoData)
<View style={styles.container}> ? Array.from(new Set(storeInfoData.map(item => item.tabId))).map(id => ({
<View style={styles.tabstyle}> id,
<ScrollView horizontal showsHorizontalScrollIndicator={false}> title: tabs.find(tab => tab.id === id)?.title || `Tab ${id}`
<View style={{ flexDirection: 'row' }}> }))
{/* {tabs?.map((tab) => ( */} : [];
{dynamicTabs?.map((tab) => (
<TouchableOpacity key={tab.id} style={styles.tabview} activeOpacity={1} onPress={() => setSelectedTab(tab.id)}> const renderTabContent = () => {
<View style={selectedTab === tab.id ? styles.selecttabView : styles.unselecttabView}> switch (selectedTab) {
<Text style={[styles.tabtext, selectedTab === tab.id ? styles.selecttabText : styles.unselecttabText]}> case 0:
{tab.title} return <SectionListView listData={filteredData} />
</Text> case 1:
</View> return <SectionListView listData={filteredData} />
</TouchableOpacity> case 2:
))} return <SectionListView listData={filteredData} />;
</View> default:
</ScrollView> return null;
</View> }
<ScrollView horizontal={false} style={{ flex: 1 }}> };
<Text style={styles.headerText}>{selectedTabTitle} </Text>
<View style={{ width: '100%' }}>{renderTabContent()}</View> return (
</ScrollView>
</View> <SafeAreaView style={{ flex: 1, backgroundColor: GlobalTheme.colors.primary }}>
<Loader visible={loading} /> <View style={[styles.container, { paddingHorizontal: 0 }]}>
</View> <CustomHeader
</SafeAreaView> title={'Store Info'}
); leftIcon={IMAGES.leftArrowIcon}
onLeftPress={() => navigation.goBack()} />
<View style={styles.container}>
<View style={styles.tabstyle}>
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
<View style={{ flexDirection: 'row' }}>
{/* {tabs?.map((tab) => ( */}
{dynamicTabs?.map((tab) => (
<TouchableOpacity key={tab.id} style={styles.tabview} activeOpacity={1} onPress={() => setSelectedTab(tab.id)}>
<View style={selectedTab === tab.id ? styles.selecttabView : styles.unselecttabView}>
<Text style={[styles.tabtext, selectedTab === tab.id ? styles.selecttabText : styles.unselecttabText]}>
{tab.title}
</Text>
</View>
</TouchableOpacity>
))}
</View>
</ScrollView>
</View>
<ScrollView horizontal={false} style={{ flex: 1 }}>
{/* <Text style={styles.headerText}>{selectedTabTitle} </Text> */}
<View style={{ width: '100%', marginTop: 20, }}>{renderTabContent()}</View>
</ScrollView>
</View>
<Loader visible={loading} />
</View>
</SafeAreaView>
);
}; };
export default StoreInfo; export default StoreInfo;
+4 -1
View File
@@ -61,7 +61,9 @@ export const styles = StyleSheet.create({
width: Screen.screenWidth * 0.92, width: Screen.screenWidth * 0.92,
marginVertical: 5, marginVertical: 5,
borderWidth: 1, borderWidth: 1,
borderColor: GlobalTheme.colors.lightblueborder, borderColor: '#113F8C',
marginBottom:15,
marginTop:10,
// ...shadow, // ...shadow,
}, },
@@ -69,6 +71,7 @@ export const styles = StyleSheet.create({
color:'#000', color:'#000',
fontWeight: GlobalTheme.typography.fontWeight.bold, fontWeight: GlobalTheme.typography.fontWeight.bold,
fontSize: GlobalTheme.typography.fontSize.small, fontSize: GlobalTheme.typography.fontSize.small,
marginHorizontal:10
}, },
row: { row: {
flexDirection: 'row', flexDirection: 'row',
+1 -1
View File
@@ -12,7 +12,7 @@ const Welcome = ({ navigation }) => {
return ( return (
<View style={styles.container}> <View style={styles.container}>
<ImageBackground source={IMAGES.WelcomeBackground} style={styles.background} resizeMode='cover'> <ImageBackground source={IMAGES.WelcomeBackground} style={styles.background} resizeMode='contain'>
<View style={styles.content}> <View style={styles.content}>
<Image source={IMAGES.Welcomelogo} style={styles.illustration} /> <Image source={IMAGES.Welcomelogo} style={styles.illustration} />
<Text style={styles.title}>Welcome to {"\n"} Performics Store DNA</Text> <Text style={styles.title}>Welcome to {"\n"} Performics Store DNA</Text>
+1116 -1121
View File
File diff suppressed because it is too large Load Diff