Compare commits

...

20 Commits

Author SHA1 Message Date
Gitea 6acfde3d52 first commit 2026-04-20 15:13:29 +05:30
CPM 77ab412c66 year filter updated 2026-03-17 18:39:33 +05:30
CPM 4ad584785d Osa Details page icon 2025-11-19 10:24:28 +05:30
CPM d65979518f PSS Trend Added 2025-09-17 11:46:32 +05:30
CPM 85bb27408e Dashboard updated 2025-08-20 11:21:36 +05:30
CPM cd466a2af1 android updated 2025-08-14 17:11:42 +05:30
CPM 6900df4fdf OSA and promotion details page updated 2025-08-14 09:25:09 +05:30
CPM 55fd811683 Updated Store Info... 2025-08-07 16:15:04 +05:30
CPM 2280bd6d19 Store Info Updated 2025-08-07 13:38:34 +05:30
CPM 5a910f62e2 graph and search store updated 2025-08-05 16:49:21 +05:30
anitak 81a82d8124 store info - done 2025-06-26 17:45:20 +05:30
anitak 3096ec0333 resend OTP - done 2025-06-26 12:07:52 +05:30
anitak fb0c62e0dc verify screen - done 2025-06-26 11:15:14 +05:30
anitak 9eb0c3eb2b package add - otp input 2025-06-25 17:40:16 +05:30
anitak 9873a3844d verfify screen start 2025-06-25 17:33:46 +05:30
anitak 2d901a407a login screen done 2025-06-25 16:36:17 +05:30
anitak f0a87b818b lineargradient add 2025-06-25 16:22:02 +05:30
anitak a4f56a2576 splash screen and redux 2025-06-25 13:19:04 +05:30
anitak addd221003 Initial commit 2025-06-25 11:56:07 +05:30
anitak 87af035459 Initial commit
Generated by react-native@0.80.0
2025-06-25 10:47:40 +05:30
70 changed files with 10879 additions and 3230 deletions
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

+6
View File
@@ -110,8 +110,11 @@ android {
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
<<<<<<< HEAD
=======
implementation project(':react-native-vector-icons')
implementation project(':react-native-fs')
>>>>>>> dabur-store-dna
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
@@ -119,6 +122,9 @@ dependencies {
implementation jscFlavor
}
}
<<<<<<< HEAD
=======
apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")
>>>>>>> dabur-store-dna
+3
View File
@@ -1,10 +1,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<<<<<<< HEAD
=======
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
>>>>>>> dabur-store-dna
<application
android:name=".MainApplication"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 15 KiB

@@ -1,3 +1,7 @@
<resources>
<<<<<<< HEAD
<string name="app_name">PerformicsStoreDNA</string>
=======
<string name="app_name">Performics Store DNA</string>
>>>>>>> dabur-store-dna
</resources>
Binary file not shown.
+5
View File
@@ -32,7 +32,12 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
<<<<<<< HEAD
newArchEnabled=true
=======
newArchEnabled=false
org.gradle.java.home=/opt/homebrew/opt/openjdk@17
>>>>>>> dabur-store-dna
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
Vendored Executable → Regular
View File
Vendored Executable → Regular
+201 -99
View File
@@ -1,99 +1,201 @@
@REM Copyright (c) Meta Platforms, Inc. and affiliates.
@REM
@REM This source code is licensed under the MIT license found in the
@REM LICENSE file in the root directory of this source tree.
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
<<<<<<< HEAD
@REM Copyright (c) Meta Platforms, Inc. and affiliates.
@REM
@REM This source code is licensed under the MIT license found in the
@REM LICENSE file in the root directory of this source tree.
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
=======
@REM Copyright (c) Meta Platforms, Inc. and affiliates.
@REM
@REM This source code is licensed under the MIT license found in the
@REM LICENSE file in the root directory of this source tree.
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
>>>>>>> dabur-store-dna
+3
View File
@@ -4,6 +4,9 @@ extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autoli
rootProject.name = 'PerformicsStoreDNA'
include ':app'
includeBuild('../node_modules/@react-native/gradle-plugin')
<<<<<<< HEAD
=======
include ':react-native-fs'
project(':react-native-fs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fs/android')
>>>>>>> dabur-store-dna
+3
View File
@@ -1,7 +1,10 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
<<<<<<< HEAD
=======
plugins: [
// other plugins here...
'react-native-reanimated/plugin', // 👈 must be last
],
>>>>>>> dabur-store-dna
};
@@ -11,11 +11,28 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
<<<<<<< HEAD
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
remoteInfo = PerformicsStoreDNA;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
=======
D36C74772E212F7200955E13 /* white.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C74762E212F7200955E13 /* white.png */; };
DB45BE4A6E0F03A0CC859A6F /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
>>>>>>> dabur-store-dna
13B07F961A680F5B00A75B9A /* PerformicsStoreDNA.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PerformicsStoreDNA.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = PerformicsStoreDNA/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = PerformicsStoreDNA/Info.plist; sourceTree = "<group>"; };
@@ -25,7 +42,10 @@
5DCACB8F33CDC322A6C60F78 /* libPods-PerformicsStoreDNA.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PerformicsStoreDNA.a"; sourceTree = BUILT_PRODUCTS_DIR; };
761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = PerformicsStoreDNA/AppDelegate.swift; sourceTree = "<group>"; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = PerformicsStoreDNA/LaunchScreen.storyboard; sourceTree = "<group>"; };
<<<<<<< HEAD
=======
D36C74762E212F7200955E13 /* white.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = white.png; sourceTree = "<group>"; };
>>>>>>> dabur-store-dna
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
@@ -41,6 +61,17 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
<<<<<<< HEAD
00E356F01AD99517003FC87E /* Supporting Files */ = {
isa = PBXGroup;
children = (
00E356F11AD99517003FC87E /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
=======
>>>>>>> dabur-store-dna
13B07FAE1A68108700A75B9A /* PerformicsStoreDNA */ = {
isa = PBXGroup;
children = (
@@ -72,7 +103,10 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
<<<<<<< HEAD
=======
D36C74762E212F7200955E13 /* white.png */,
>>>>>>> dabur-store-dna
13B07FAE1A68108700A75B9A /* PerformicsStoreDNA */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
83CBBA001A601CBA00E9B192 /* Products */,
@@ -157,14 +191,28 @@
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
<<<<<<< HEAD
00E356EC1AD99517003FC87E /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
=======
>>>>>>> dabur-store-dna
13B07F8E1A680F5B00A75B9A /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
<<<<<<< HEAD
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
=======
D36C74772E212F7200955E13 /* white.png in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
DB45BE4A6E0F03A0CC859A6F /* PrivacyInfo.xcprivacy in Resources */,
>>>>>>> dabur-store-dna
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -195,10 +243,20 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PerformicsStoreDNA/Pods-PerformicsStoreDNA-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
<<<<<<< HEAD
=======
inputPaths = (
);
>>>>>>> dabur-store-dna
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PerformicsStoreDNA/Pods-PerformicsStoreDNA-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
<<<<<<< HEAD
=======
outputPaths = (
);
>>>>>>> dabur-store-dna
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PerformicsStoreDNA/Pods-PerformicsStoreDNA-frameworks.sh\"\n";
@@ -234,10 +292,20 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PerformicsStoreDNA/Pods-PerformicsStoreDNA-resources-${CONFIGURATION}-input-files.xcfilelist",
);
<<<<<<< HEAD
=======
inputPaths = (
);
>>>>>>> dabur-store-dna
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PerformicsStoreDNA/Pods-PerformicsStoreDNA-resources-${CONFIGURATION}-output-files.xcfilelist",
);
<<<<<<< HEAD
=======
outputPaths = (
);
>>>>>>> dabur-store-dna
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PerformicsStoreDNA/Pods-PerformicsStoreDNA-resources.sh\"\n";
@@ -256,6 +324,17 @@
};
/* End PBXSourcesBuildPhase section */
<<<<<<< HEAD
/* Begin PBXTargetDependency section */
00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 13B07F861A680F5B00A75B9A /* PerformicsStoreDNA */;
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
=======
>>>>>>> dabur-store-dna
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
@@ -263,8 +342,12 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3;
<<<<<<< HEAD
CURRENT_PROJECT_VERSION = 1;
=======
CURRENT_PROJECT_VERSION = 9;
DEVELOPMENT_TEAM = JGDHGNH9XY;
>>>>>>> dabur-store-dna
ENABLE_BITCODE = NO;
INFOPLIST_FILE = PerformicsStoreDNA/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
@@ -272,13 +355,21 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.3;
<<<<<<< HEAD
MARKETING_VERSION = 1.0;
=======
MARKETING_VERSION = 1.9;
>>>>>>> dabur-store-dna
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
<<<<<<< HEAD
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
=======
PRODUCT_BUNDLE_IDENTIFIER = com.performicsstoredna;
>>>>>>> dabur-store-dna
PRODUCT_NAME = PerformicsStoreDNA;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -292,21 +383,33 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3;
<<<<<<< HEAD
CURRENT_PROJECT_VERSION = 1;
=======
CURRENT_PROJECT_VERSION = 9;
DEVELOPMENT_TEAM = JGDHGNH9XY;
>>>>>>> dabur-store-dna
INFOPLIST_FILE = PerformicsStoreDNA/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.3;
<<<<<<< HEAD
MARKETING_VERSION = 1.0;
=======
MARKETING_VERSION = 1.9;
>>>>>>> dabur-store-dna
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
<<<<<<< HEAD
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
=======
PRODUCT_BUNDLE_IDENTIFIER = com.performicsstoredna;
>>>>>>> dabur-store-dna
PRODUCT_NAME = PerformicsStoreDNA;
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -382,11 +485,15 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
<<<<<<< HEAD
SDKROOT = iphoneos;
=======
OTHER_LDFLAGS = "$(inherited) ";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
USE_HERMES = true;
>>>>>>> dabur-store-dna
};
name = Debug;
};
@@ -451,10 +558,14 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
<<<<<<< HEAD
SDKROOT = iphoneos;
=======
OTHER_LDFLAGS = "$(inherited) ";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
>>>>>>> dabur-store-dna
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -1,55 +1,82 @@
{
"images" : [
{
<<<<<<< HEAD
=======
"filename" : "40.png",
>>>>>>> dabur-store-dna
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
<<<<<<< HEAD
=======
"filename" : "60.png",
>>>>>>> dabur-store-dna
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
<<<<<<< HEAD
=======
"filename" : "58.png",
>>>>>>> dabur-store-dna
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
<<<<<<< HEAD
=======
"filename" : "87.png",
>>>>>>> dabur-store-dna
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
<<<<<<< HEAD
=======
"filename" : "80.png",
>>>>>>> dabur-store-dna
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
<<<<<<< HEAD
=======
"filename" : "120.png",
>>>>>>> dabur-store-dna
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
<<<<<<< HEAD
=======
"filename" : "120 1.png",
>>>>>>> dabur-store-dna
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
<<<<<<< HEAD
=======
"filename" : "180.png",
>>>>>>> dabur-store-dna
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
<<<<<<< HEAD
=======
"filename" : "1024.png",
>>>>>>> dabur-store-dna
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
+10
View File
@@ -26,12 +26,21 @@
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<<<<<<< HEAD
<!-- Do not change NSAllowsArbitraryLoads to true, or you will risk app rejection! -->
=======
>>>>>>> dabur-store-dna
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<<<<<<< HEAD
<string></string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
=======
<string>This app uses your location to enhance reporting and store-related services.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need access to your location for [your reason, e.g., providing location-based services].</string>
@@ -62,6 +71,7 @@
<string>Octicons.ttf</string>
<string>Zocial.ttf</string>
</array>
>>>>>>> dabur-store-dna
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
+36 -36
View File
@@ -1771,7 +1771,7 @@ PODS:
- SocketRocket
- WCPhotoManipulator (~> 2.6.0)
- Yoga
- react-native-safe-area-context (5.5.1):
- react-native-safe-area-context (5.5.2):
- boost
- DoubleConversion
- fast_float
@@ -1790,8 +1790,8 @@ PODS:
- React-hermes
- React-ImageManager
- React-jsi
- react-native-safe-area-context/common (= 5.5.1)
- react-native-safe-area-context/fabric (= 5.5.1)
- react-native-safe-area-context/common (= 5.5.2)
- react-native-safe-area-context/fabric (= 5.5.2)
- React-NativeModulesApple
- React-RCTFabric
- React-renderercss
@@ -1802,7 +1802,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- react-native-safe-area-context/common (5.5.1):
- react-native-safe-area-context/common (5.5.2):
- boost
- DoubleConversion
- fast_float
@@ -1831,7 +1831,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- react-native-safe-area-context/fabric (5.5.1):
- react-native-safe-area-context/fabric (5.5.2):
- boost
- DoubleConversion
- fast_float
@@ -2368,7 +2368,7 @@ PODS:
- Yoga
- RNFS (2.20.0):
- React-Core
- RNGestureHandler (2.27.1):
- RNGestureHandler (2.27.2):
- boost
- DoubleConversion
- fast_float
@@ -2397,7 +2397,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- RNPermissions (5.4.1):
- RNPermissions (5.4.2):
- boost
- DoubleConversion
- fast_float
@@ -2426,7 +2426,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- RNReanimated (3.18.0):
- RNReanimated (3.19.0):
- boost
- DoubleConversion
- fast_float
@@ -2453,11 +2453,11 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNReanimated/reanimated (= 3.18.0)
- RNReanimated/worklets (= 3.18.0)
- RNReanimated/reanimated (= 3.19.0)
- RNReanimated/worklets (= 3.19.0)
- SocketRocket
- Yoga
- RNReanimated/reanimated (3.18.0):
- RNReanimated/reanimated (3.19.0):
- boost
- DoubleConversion
- fast_float
@@ -2484,10 +2484,10 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNReanimated/reanimated/apple (= 3.18.0)
- RNReanimated/reanimated/apple (= 3.19.0)
- SocketRocket
- Yoga
- RNReanimated/reanimated/apple (3.18.0):
- RNReanimated/reanimated/apple (3.19.0):
- boost
- DoubleConversion
- fast_float
@@ -2516,7 +2516,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- RNReanimated/worklets (3.18.0):
- RNReanimated/worklets (3.19.0):
- boost
- DoubleConversion
- fast_float
@@ -2543,10 +2543,10 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNReanimated/worklets/apple (= 3.18.0)
- RNReanimated/worklets/apple (= 3.19.0)
- SocketRocket
- Yoga
- RNReanimated/worklets/apple (3.18.0):
- RNReanimated/worklets/apple (3.19.0):
- boost
- DoubleConversion
- fast_float
@@ -2575,7 +2575,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- RNScreens (4.11.1):
- RNScreens (4.13.1):
- boost
- DoubleConversion
- fast_float
@@ -2603,10 +2603,10 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNScreens/common (= 4.11.1)
- RNScreens/common (= 4.13.1)
- SocketRocket
- Yoga
- RNScreens/common (4.11.1):
- RNScreens/common (4.13.1):
- boost
- DoubleConversion
- fast_float
@@ -2636,7 +2636,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- RNSVG (15.12.0):
- RNSVG (15.12.1):
- boost
- DoubleConversion
- fast_float
@@ -2663,10 +2663,10 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNSVG/common (= 15.12.0)
- RNSVG/common (= 15.12.1)
- SocketRocket
- Yoga
- RNSVG/common (15.12.0):
- RNSVG/common (15.12.1):
- boost
- DoubleConversion
- fast_float
@@ -2695,7 +2695,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- RNVectorIcons (10.2.0):
- RNVectorIcons (10.3.0):
- boost
- DoubleConversion
- fast_float
@@ -2725,11 +2725,11 @@ PODS:
- SocketRocket
- Yoga
- SocketRocket (0.7.1)
- VisionCamera (4.7.0):
- VisionCamera/Core (= 4.7.0)
- VisionCamera/React (= 4.7.0)
- VisionCamera/Core (4.7.0)
- VisionCamera/React (4.7.0):
- VisionCamera (4.7.1):
- VisionCamera/Core (= 4.7.1)
- VisionCamera/React (= 4.7.1)
- VisionCamera/Core (4.7.1)
- VisionCamera/React (4.7.1):
- React-Core
- WCPhotoManipulator (2.6.0)
- Yoga (0.0.0)
@@ -3060,7 +3060,7 @@ SPEC CHECKSUMS:
react-native-geolocation: f01ad4718ad1d015d0c0dd12a6f707354022530e
react-native-image-resizer: 8537d9fdbd14b9d5f301a2d319c469bf56f6e9a0
react-native-photo-manipulator: 5ac803352e07b7f61f5905e78952006f0c4efd54
react-native-safe-area-context: d3738f0c3b1fcefaed874a45891b0d44306c47c1
react-native-safe-area-context: 68d1363b8354472a961aa6861ba8451beaf9a810
react-native-sqlite-storage: 0c84826214baaa498796c7e46a5ccc9a82e114ed
React-NativeModulesApple: e16d5c133019987285f001fbf1461a861e40426f
React-oscompat: 7c0a341cc31e350da71ddf2e46de0a845d1d1626
@@ -3095,14 +3095,14 @@ SPEC CHECKSUMS:
ReactCommon: b028d09a66e60ebd83ca59d8cc9a1216360db147
RNCAsyncStorage: 1f04c8d56558e533277beda29187f571cf7eecb2
RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8
RNGestureHandler: 5e1a1605659c22098719fc2e8aee453fe728f52e
RNPermissions: ebf576a01cc2cb73db0006e0b3c9b4760e0aa569
RNReanimated: bc1ddb7a5352648bcf0d592256069833bf935a46
RNScreens: ee2abe7e0c548eed14e92742e81ed991165c56aa
RNSVG: 341f555dbcd83a34d1f058e88df387de7bbc3347
RNVectorIcons: ef9b4b0b786053ebdd63ee2972f48de9633ba166
RNGestureHandler: a0c83d8e4422f2ac04d1acb1741866a5184c7b73
RNPermissions: b15c9d7ba7aacff916439d445f385abbb2a36a4f
RNReanimated: 5ee070eb08e681be2a9ee7e797019d97d4706131
RNScreens: c63849403489bd068ea160f276fbc8416f19f2f7
RNSVG: d407e5f2ede12bbcd92e4d23a405ad5a5f7294a3
RNVectorIcons: be4d047a76ad307ffe54732208fb0498fcb8477f
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
VisionCamera: c5c07db74721d37f4c9f8331ad1f8da7b2539995
VisionCamera: 9a8f98ae344fe5d148f84bb45829f9e4caab9d2f
WCPhotoManipulator: 804988e16a6fe941cddff942b2acf887110de5d6
Yoga: 0c4b7d2aacc910a1f702694fa86be830386f4ceb
+141 -80
View File
@@ -1,80 +1,141 @@
{
"name": "PerformicsStoreDNA",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest",
"postinstall": "patch-package"
},
"dependencies": {
"@bam.tech/react-native-image-resizer": "^3.0.11",
"@gluestack-ui/nativewind-utils": "^1.0.26",
"@gluestack-ui/overlay": "^0.1.22",
"@gluestack-ui/toast": "^1.0.9",
"@likashefqet/react-native-image-zoom": "^4.3.0",
"@react-native-async-storage/async-storage": "^2.2.0",
"@react-native-community/geolocation": "^3.4.0",
"@react-native/new-app-screen": "0.80.0",
"@react-navigation/elements": "^2.5.2",
"@react-navigation/native": "^7.1.14",
"@react-navigation/native-stack": "^7.3.21",
"@reduxjs/toolkit": "^2.8.2",
"axios": "^1.10.0",
"deprecated-react-native-prop-types": "^5.0.0",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"patch-package": "^8.0.0",
"react": "19.1.0",
"react-native": "0.80.0",
"react-native-chart-kit": "^6.12.0",
"react-native-element-dropdown": "^2.12.4",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "^2.27.1",
"react-native-gifted-charts": "^1.4.63",
"react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-linear-gradient": "^2.8.3",
"react-native-loader-kit": "^3.0.0",
"react-native-modal-selector": "^2.1.2",
"react-native-multiple-select": "^0.5.12",
"react-native-otp-entry": "^1.8.5",
"react-native-permissions": "^5.4.1",
"react-native-photo-manipulator": "^1.9.2",
"react-native-raw-bottom-sheet": "^3.0.0",
"react-native-reanimated": "^3.18.0",
"react-native-safe-area-context": "^5.5.0",
"react-native-screens": "^4.11.1",
"react-native-sqlite-storage": "^6.0.1",
"react-native-svg": "^15.12.0",
"react-native-toast-message": "^2.3.1",
"react-native-vector-icons": "^10.2.0",
"react-native-vision-camera": "^4.7.0",
"react-redux": "^9.2.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "19.0.0",
"@react-native-community/cli-platform-android": "19.0.0",
"@react-native-community/cli-platform-ios": "19.0.0",
"@react-native/babel-preset": "0.80.0",
"@react-native/eslint-config": "0.80.0",
"@react-native/metro-config": "0.80.0",
"@react-native/typescript-config": "0.80.0",
"@types/jest": "^29.5.13",
"@types/react": "^19.1.0",
"@types/react-test-renderer": "^19.1.0",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-test-renderer": "19.1.0",
"typescript": "5.0.4"
},
"engines": {
"node": ">=18"
}
}
<<<<<<< HEAD
{
"name": "PerformicsStoreDNA",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"@react-native-async-storage/async-storage": "^2.2.0",
"@react-native/new-app-screen": "0.80.0",
"@react-navigation/elements": "^2.5.2",
"@react-navigation/native": "^7.1.14",
"@react-navigation/native-stack": "^7.3.21",
"@reduxjs/toolkit": "^2.8.2",
"axios": "^1.10.0",
"react": "19.1.0",
"react-native": "0.80.0",
"react-native-chart-kit": "^6.12.0",
"react-native-element-dropdown": "^2.12.4",
"react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-linear-gradient": "^2.8.3",
"react-native-otp-entry": "^1.8.5",
"react-native-safe-area-context": "^5.5.0",
"react-native-screens": "^4.11.1",
"react-native-sqlite-storage": "^6.0.1",
"react-native-svg": "^15.12.0",
"react-native-toast-message": "^2.3.1",
"react-native-vector-icons": "^10.2.0",
"react-redux": "^9.2.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "19.0.0",
"@react-native-community/cli-platform-android": "19.0.0",
"@react-native-community/cli-platform-ios": "19.0.0",
"@react-native/babel-preset": "0.80.0",
"@react-native/eslint-config": "0.80.0",
"@react-native/metro-config": "0.80.0",
"@react-native/typescript-config": "0.80.0",
"@types/jest": "^29.5.13",
"@types/react": "^19.1.0",
"@types/react-test-renderer": "^19.1.0",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-test-renderer": "19.1.0",
"typescript": "5.0.4"
},
"engines": {
"node": ">=18"
}
}
=======
{
"name": "PerformicsStoreDNA",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest",
"postinstall": "patch-package"
},
"dependencies": {
"@bam.tech/react-native-image-resizer": "^3.0.11",
"@gluestack-ui/nativewind-utils": "^1.0.26",
"@gluestack-ui/overlay": "^0.1.22",
"@gluestack-ui/toast": "^1.0.9",
"@likashefqet/react-native-image-zoom": "^4.3.0",
"@react-native-async-storage/async-storage": "^2.2.0",
"@react-native-community/geolocation": "^3.4.0",
"@react-native/new-app-screen": "0.80.0",
"@react-navigation/elements": "^2.5.2",
"@react-navigation/native": "^7.1.14",
"@react-navigation/native-stack": "^7.3.21",
"@reduxjs/toolkit": "^2.8.2",
"axios": "^1.10.0",
"deprecated-react-native-prop-types": "^5.0.0",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"patch-package": "^8.0.0",
"react": "19.1.0",
"react-native": "0.80.0",
"react-native-chart-kit": "^6.12.0",
"react-native-element-dropdown": "^2.12.4",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "^2.27.1",
"react-native-gifted-charts": "^1.4.63",
"react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-linear-gradient": "^2.8.3",
"react-native-loader-kit": "^3.0.0",
"react-native-modal-selector": "^2.1.2",
"react-native-multiple-select": "^0.5.12",
"react-native-otp-entry": "^1.8.5",
"react-native-permissions": "^5.4.1",
"react-native-photo-manipulator": "^1.9.2",
"react-native-raw-bottom-sheet": "^3.0.0",
"react-native-reanimated": "^3.18.0",
"react-native-safe-area-context": "^5.5.0",
"react-native-screens": "^4.11.1",
"react-native-sqlite-storage": "^6.0.1",
"react-native-svg": "^15.12.0",
"react-native-toast-message": "^2.3.1",
"react-native-vector-icons": "^10.2.0",
"react-native-vision-camera": "^4.7.1",
"react-redux": "^9.2.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "19.0.0",
"@react-native-community/cli-platform-android": "19.0.0",
"@react-native-community/cli-platform-ios": "19.0.0",
"@react-native/babel-preset": "0.80.0",
"@react-native/eslint-config": "0.80.0",
"@react-native/metro-config": "0.80.0",
"@react-native/typescript-config": "0.80.0",
"@types/jest": "^29.5.13",
"@types/react": "^19.1.0",
"@types/react-test-renderer": "^19.1.0",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-test-renderer": "19.1.0",
"typescript": "5.0.4"
},
"engines": {
"node": ">=18"
}
}
>>>>>>> dabur-store-dna
BIN
View File
Binary file not shown.
+43 -25
View File
@@ -1,25 +1,43 @@
import * as React from 'react';
import { useEffect } from 'react';
import { Provider } from 'react-redux';
import Routes from './navigation/Routes';
import { store } from './redux/store';
import { initTables } from './constants/database';
import { CreateImageFolders } from './constants/function';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
function App() {
useEffect(() => {
initTables(); // Ensure DB tables are created
CreateImageFolders();
}, []);
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<Provider store={store}>
<Routes />
</Provider>
</GestureHandlerRootView>
);
}
export default App;
<<<<<<< HEAD
// In App.js in a new project
import * as React from 'react';
import {Provider} from 'react-redux';
import Routes from './navigation/Routes';
import { store } from './redux/store';
function App() {
return (
<Provider store={store}>
<Routes />
</Provider>
);
}
export default App;
=======
import * as React from 'react';
import { useEffect } from 'react';
import { Provider } from 'react-redux';
import Routes from './navigation/Routes';
import { store } from './redux/store';
import { initTables } from './constants/database';
import { CreateImageFolders } from './constants/function';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
function App() {
useEffect(() => {
initTables(); // Ensure DB tables are created
CreateImageFolders();
}, []);
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<Provider store={store}>
<Routes />
</Provider>
</GestureHandlerRootView>
);
}
export default App;
>>>>>>> dabur-store-dna
+1 -2
View File
@@ -2,11 +2,10 @@ export const BASE_URL = 'https://dax.parinaam.in/execute/dabur';
export const ApiURL = {
// login: `${BASE_URL}/api/v1/auth/login`,
pssscoreApi: `${BASE_URL}/mtd/pssscore`,
getotpApi: `https://api1.parinaam.in/api/dabur/SendOTP`,
verifyotpApi: `https://api1.parinaam.in/api/dabur/AuthenticateOTP`,
storeDNAfilter:`https://api1.parinaam.in/api/dabur/StoreDNAfilter`,
storeSearch :`https://api1.parinaam.in/api/dabur/StoreDNAstoreSearch`,
storeInfo :`https://api1.parinaam.in/api/dabur/StoreDNAstoreInfo`,
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

+1 -1
View File
@@ -31,7 +31,7 @@ export function ConfirmSaveAlert({
onYesCallBack = () => { },
msg = 'Do you really want to save data?',
yesText = 'Yes',
cancelText = 'NO',
cancelText = 'No',
}) {
return (
<CustomModal
+66 -33
View File
@@ -1,33 +1,66 @@
// src/components/Background.js
import React from 'react';
import { StyleSheet, StatusBar, useColorScheme } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import { SafeAreaView } from 'react-native-safe-area-context';
import { GlobalTheme } from '../theme';
const Background = ({ children, barcolor = 'light-content'}) => {
const isDarkMode = useColorScheme() === 'dark';
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle={'light-content'} />
<LinearGradient colors={['#E3EBF8', '#ffffff']} start={{ x: 0.5, y: 0 }} end={{ x: 0.5, y: 1 }} style={styles.gradient}>
{children}
</LinearGradient>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: GlobalTheme.colors.primary,
},
gradient: {
flex: 1,
// paddingHorizontal: 20,
},
});
export default Background;
<<<<<<< HEAD
// src/components/Background.js
import React from 'react';
import { StyleSheet, SafeAreaView, StatusBar, useColorScheme } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
const Background = ({ children, barcolor = 'light-content'}) => {
const isDarkMode = useColorScheme() === 'dark';
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<LinearGradient colors={['#E3EBF8', '#ffffff']} start={{ x: 0.5, y: 0 }} end={{ x: 0.5, y: 1 }} style={styles.gradient}>
{children}
</LinearGradient>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
gradient: {
flex: 1,
paddingHorizontal: 20,
},
});
export default Background;
=======
// src/components/Background.js
import React from 'react';
import { StyleSheet, StatusBar, useColorScheme } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import { SafeAreaView } from 'react-native-safe-area-context';
import { GlobalTheme } from '../theme';
const Background = ({ children, barcolor = 'light-content'}) => {
const isDarkMode = useColorScheme() === 'dark';
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle={'light-content'} />
<LinearGradient colors={['#E3EBF8', '#ffffff']} start={{ x: 0.5, y: 0 }} end={{ x: 0.5, y: 1 }} style={styles.gradient}>
{children}
</LinearGradient>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: GlobalTheme.colors.primary,
},
gradient: {
flex: 1,
// paddingHorizontal: 20,
},
});
export default Background;
>>>>>>> dabur-store-dna
+29 -13
View File
@@ -1,13 +1,29 @@
import { View, Text, TouchableOpacity } from 'react-native';
const CustomButton = ({ title, style, textstyle, onPress , disabled}) => {
return (
<TouchableOpacity disabled={disabled} onPress={onPress}>
<View style={{ marginHorizontal: 0, paddingVertical: 10, ...style }}>
<Text style={{ textAlign: 'center', ...textstyle }}>{title}</Text>
</View>
</TouchableOpacity>
);
};
export default CustomButton;
<<<<<<< HEAD
import { View, Text, TouchableOpacity } from 'react-native';
const CustomButton = ({ title, style, textstyle, onPress }) => {
return (
<TouchableOpacity onPress={onPress}>
<View style={{ marginHorizontal: 0, paddingVertical: 10, ...style }}>
<Text style={{ textAlign: 'center', ...textstyle }}>{title}</Text>
</View>
</TouchableOpacity>
);
};
export default CustomButton;
=======
import { View, Text, TouchableOpacity } from 'react-native';
const CustomButton = ({ title, style, textstyle, onPress , disabled}) => {
return (
<TouchableOpacity disabled={disabled} onPress={onPress}>
<View style={{ marginHorizontal: 0, paddingVertical: 10, ...style }}>
<Text style={{ textAlign: 'center', ...textstyle }}>{title}</Text>
</View>
</TouchableOpacity>
);
};
export default CustomButton;
>>>>>>> dabur-store-dna
+20 -14
View File
@@ -1,5 +1,5 @@
import React from 'react';
import { View, Text, Modal, StyleSheet, TouchableOpacity, Image} from 'react-native';
import { View, Text, Modal, StyleSheet, TouchableOpacity, Image } from 'react-native';
import IMAGES from '../constants/Images';
const CustomModal = ({
@@ -18,17 +18,21 @@ const CustomModal = ({
<Modal visible={showModal} transparent animationType="fade">
<View style={styles.overlay}>
<View style={[styles.modalContainer, style]}>
{onClose && (
{/* {onClose && (
<TouchableOpacity onPress={onClose} style={styles.closeButton}>
<Image source={IMAGES.crossIcon} style={styles.iconStyle} />
<Image source={IMAGES.crossIcon} style={styles.iconStyle} />
</TouchableOpacity>
)}
)} */}
{title && <Text style={[styles.title, titleStyle]}>{title}</Text>}
{message && <Text style={[styles.message, messageStyle]}>{message}</Text>}
{/* <TouchableOpacity onPress={onClose} style={styles.closeButton}>
<Image source={IMAGES.alert} style={styles.iconStyle} />
</TouchableOpacity> */}
<View style={{ marginTop: 10 }}>
{title && <Text style={[styles.title, titleStyle]}>{title}</Text>}
{message && <Text style={[styles.message, messageStyle]}>{message}</Text>}
</View>
<View style={{ marginVertical: 10 }}>{children}</View>
</View>
</View>
</Modal>
@@ -50,12 +54,14 @@ const styles = StyleSheet.create({
borderRadius: 12,
padding: 15,
alignItems: 'center',
minHeight:200
minHeight: 180,
justifyContent: 'center'
},
title: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 6,
color: "#000"
},
message: {
fontSize: 14,
@@ -63,17 +69,17 @@ const styles = StyleSheet.create({
textAlign: 'center',
},
closeButton: {
alignSelf:'flex-end',
marginBottom:15
alignSelf: 'center',
marginBottom: 15
},
closeText: {
color: '#fff',
fontWeight: 'bold',
},
iconStyle:{
height:35,
width:35,
resizeMode:'contain',
iconStyle: {
height: 50,
width: 50,
resizeMode: 'contain',
// tintColor:'red'
}
});
+173 -85
View File
@@ -1,85 +1,173 @@
import { View, Text, TextInput, StyleSheet, } from 'react-native';
import React, { useState } from 'react';
import { GlobalTheme, Screen } from '../theme';
const CustomTextInput = ({
label,
value,
onChangeText,
keyboardType,
secureTextEntry,
right,
textstyle,
viewstyle,
maxLength
}) => {
const [isFocused, setFocused] = useState(false);
const [hidepassword, setHidePassword] = useState(false);
const handleFocus = () => {
setFocused(true);
};
const handleBlur = () => {
setFocused(false);
};
const inputStyle = {
borderColor: isFocused ? '#2680EB' : '#DFDFDF',
borderWidth: isFocused ? 2 : 1,
backgroundColor: isFocused ? '#FFF' : '#Fff',
borderRadius: GlobalTheme.borderRadius.md,
};
return (
<View style={styles.inputContainer}>
<Text
style={{
color: GlobalTheme.colors.black,
fontSize: GlobalTheme.typography.fontSize.small,
fontWeight: GlobalTheme.typography.fontWeight.regular,
marginTop: 10,
marginHorizontal: 0,
...textstyle,
}}>
{label}
</Text>
<View
style={{
borderRadius: GlobalTheme.borderRadius.lgg,
// borderWidth: 6,
borderColor: isFocused ? '#DFECFF' : 'transparent',
marginTop: 8,
...viewstyle,
}}>
<TextInput
maxLength={maxLength}
style={[styles.input, inputStyle]}
value={value}
onChangeText={onChangeText}
keyboardType={keyboardType}
autoCapitalize="none"
onFocus={handleFocus}
onBlur={handleBlur}
placeholder={`Enter your ${label.toLowerCase()}`}
placeholderTextColor={'#555555'}
/>
</View>
</View>
);
};
export default CustomTextInput;
const styles = StyleSheet.create({
input: {
height: 50,
borderWidth: 1,
padding: 10,
color: GlobalTheme.colors.black,
},
inputContainer: {
marginBottom: 16,
},
});
<<<<<<< HEAD
import { View, Text, TextInput, StyleSheet, } from 'react-native';
import React, { useState } from 'react';
import { GlobalTheme, Screen } from '../theme';
const CustomTextInput = ({
label,
value,
onChangeText,
keyboardType,
secureTextEntry,
right,
textstyle,
viewstyle,
maxLength
}) => {
const [isFocused, setFocused] = useState(false);
const [hidepassword, setHidePassword] = useState(false);
const handleFocus = () => {
setFocused(true);
};
const handleBlur = () => {
setFocused(false);
};
const inputStyle = {
borderColor: isFocused ? '#2680EB' : '#DFDFDF',
borderWidth: isFocused ? 2 : 1,
backgroundColor: isFocused ? '#FFF' : '#Fff',
borderRadius: GlobalTheme.borderRadius.md,
};
return (
<View style={styles.inputContainer}>
<Text
style={{
color: GlobalTheme.colors.black,
fontSize: GlobalTheme.typography.fontSize.medium,
fontWeight: GlobalTheme.typography.fontWeight.medium,
marginTop: 10,
marginHorizontal: 0,
...textstyle,
}}>
{label}
</Text>
<View
style={{
borderRadius: GlobalTheme.borderRadius.lgg,
// borderWidth: 6,
borderColor: isFocused ? '#DFECFF' : 'transparent',
marginTop: 8,
...viewstyle,
}}>
<TextInput
maxLength={maxLength}
style={[styles.input, inputStyle]}
value={value}
onChangeText={onChangeText}
keyboardType={keyboardType}
autoCapitalize="none"
onFocus={handleFocus}
onBlur={handleBlur}
placeholder={`Enter your ${label.toLowerCase()}`}
placeholderTextColor={'#555555'}
/>
</View>
</View>
);
};
export default CustomTextInput;
const styles = StyleSheet.create({
input: {
height: 50,
borderWidth: 1,
padding: 10,
color: GlobalTheme.colors.black,
},
inputContainer: {
marginBottom: 16,
},
});
=======
import { View, Text, TextInput, StyleSheet, } from 'react-native';
import React, { useState } from 'react';
import { GlobalTheme, Screen } from '../theme';
const CustomTextInput = ({
label,
value,
onChangeText,
keyboardType,
secureTextEntry,
right,
textstyle,
viewstyle,
maxLength
}) => {
const [isFocused, setFocused] = useState(false);
const [hidepassword, setHidePassword] = useState(false);
const handleFocus = () => {
setFocused(true);
};
const handleBlur = () => {
setFocused(false);
};
const inputStyle = {
borderColor: isFocused ? '#2680EB' : '#DFDFDF',
borderWidth: isFocused ? 2 : 1,
backgroundColor: isFocused ? '#FFF' : '#Fff',
borderRadius: GlobalTheme.borderRadius.md,
};
return (
<View style={styles.inputContainer}>
<Text
style={{
color: GlobalTheme.colors.black,
fontSize: GlobalTheme.typography.fontSize.small,
fontWeight: GlobalTheme.typography.fontWeight.regular,
marginTop: 10,
marginHorizontal: 0,
...textstyle,
}}>
{label}
</Text>
<View
style={{
borderRadius: GlobalTheme.borderRadius.lgg,
// borderWidth: 6,
borderColor: isFocused ? '#DFECFF' : 'transparent',
marginTop: 8,
...viewstyle,
}}>
<TextInput
maxLength={maxLength}
style={[styles.input, inputStyle]}
value={value}
onChangeText={onChangeText}
keyboardType={keyboardType}
autoCapitalize="none"
onFocus={handleFocus}
onBlur={handleBlur}
placeholder={`Enter your ${label.toLowerCase()}`}
placeholderTextColor={'#555555'}
/>
</View>
</View>
);
};
export default CustomTextInput;
const styles = StyleSheet.create({
input: {
height: 50,
borderWidth: 1,
padding: 10,
color: GlobalTheme.colors.black,
},
inputContainer: {
marginBottom: 16,
},
});
>>>>>>> dabur-store-dna
+19 -8
View File
@@ -1,8 +1,19 @@
// colors.js
export const colors = [
{ bgColor: '#eddeb8', textColor: '#0c8fa5' },
{ bgColor: '#dcf2ee', textColor: '#f39a19' },
{ bgColor: '#eebdc3', textColor: '#ff5f5f' },
{ bgColor: '#d1c4e9', textColor: '#6A1B9A' },
{ bgColor: '#ffe0b2', textColor: '#EF6C00' },
];
<<<<<<< HEAD
// colors.js
export const colors = [
{ bgColor: '#eddeb8', textColor: '#0c8fa5' },
{ bgColor: '#dcf2ee', textColor: '#f39a19' },
{ bgColor: '#eebdc3', textColor: '#ff5f5f' },
{ bgColor: '#d1c4e9', textColor: '#6A1B9A' },
{ bgColor: '#ffe0b2', textColor: '#EF6C00' },
];
=======
// colors.js
export const colors = [
{ bgColor: '#eddeb8', textColor: '#0c8fa5' },
{ bgColor: '#dcf2ee', textColor: '#f39a19' },
{ bgColor: '#eebdc3', textColor: '#ff5f5f' },
{ bgColor: '#d1c4e9', textColor: '#6A1B9A' },
{ bgColor: '#ffe0b2', textColor: '#EF6C00' },
];
>>>>>>> dabur-store-dna
+152 -75
View File
@@ -1,75 +1,152 @@
import React from 'react';
import AntDesign from 'react-native-vector-icons/AntDesign';
import Entypo from 'react-native-vector-icons/Entypo';
import EvilIcons from 'react-native-vector-icons/EvilIcons';
import Feather from 'react-native-vector-icons/Feather';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import Fontisto from 'react-native-vector-icons/Fontisto';
import Foundation from 'react-native-vector-icons/Foundation';
import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Octicons from 'react-native-vector-icons/Octicons';
import Zocial from 'react-native-vector-icons/Zocial';
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons';
import { GlobalTheme } from '../theme';
function CustomIcon({
iconLibrary,
icon,
size = 22,
color = GlobalTheme.colors.primary,
style = {},
...rest
}) {
let Icon = AntDesign;
switch (iconLibrary) {
case 'AntDesign':
Icon = AntDesign;
break;
case 'Entypo':
Icon = Entypo;
break;
case 'EvilIcons':
Icon = EvilIcons;
break;
case 'Feather':
Icon = Feather;
break;
case 'FontAwesome':
Icon = FontAwesome;
break;
case 'Fontisto':
Icon = Fontisto;
break;
case 'Foundation':
Icon = Foundation;
break;
case 'Ionicons':
Icon = Ionicons;
break;
case 'MaterialIcons':
Icon = MaterialIcons;
break;
case 'MaterialCommunityIcons':
Icon = MaterialCommunityIcons;
break;
case 'Octicons':
Icon = Octicons;
break;
case 'Zocial':
Icon = Zocial;
break;
case 'SimpleLineIcons':
Icon = SimpleLineIcons;
break;
default:
Icon = AntDesign;
}
return <Icon name={icon} size={size} style={style} color={color} {...rest} />;
}
export default CustomIcon;
<<<<<<< HEAD
import React from 'react';
import AntDesign from 'react-native-vector-icons/AntDesign';
import Entypo from 'react-native-vector-icons/Entypo';
import EvilIcons from 'react-native-vector-icons/EvilIcons';
import Feather from 'react-native-vector-icons/Feather';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import Fontisto from 'react-native-vector-icons/Fontisto';
import Foundation from 'react-native-vector-icons/Foundation';
import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Octicons from 'react-native-vector-icons/Octicons';
import Zocial from 'react-native-vector-icons/Zocial';
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons';
import { GlobalTheme } from 'src/theme';
function CustomIcon({
iconLibrary,
icon,
size = 22,
color = GlobalTheme.colors.primary,
style = {},
...rest
}) {
let Icon = AntDesign;
switch (iconLibrary) {
case 'AntDesign':
Icon = AntDesign;
break;
case 'Entypo':
Icon = Entypo;
break;
case 'EvilIcons':
Icon = EvilIcons;
break;
case 'Feather':
Icon = Feather;
break;
case 'FontAwesome':
Icon = FontAwesome;
break;
case 'Fontisto':
Icon = Fontisto;
break;
case 'Foundation':
Icon = Foundation;
break;
case 'Ionicons':
Icon = Ionicons;
break;
case 'MaterialIcons':
Icon = MaterialIcons;
break;
case 'MaterialCommunityIcons':
Icon = MaterialCommunityIcons;
break;
case 'Octicons':
Icon = Octicons;
break;
case 'Zocial':
Icon = Zocial;
break;
case 'SimpleLineIcons':
Icon = SimpleLineIcons;
break;
default:
Icon = AntDesign;
}
return <Icon name={icon} size={size} style={style} color={color} {...rest} />;
}
export default CustomIcon;
=======
import React from 'react';
import AntDesign from 'react-native-vector-icons/AntDesign';
import Entypo from 'react-native-vector-icons/Entypo';
import EvilIcons from 'react-native-vector-icons/EvilIcons';
import Feather from 'react-native-vector-icons/Feather';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import Fontisto from 'react-native-vector-icons/Fontisto';
import Foundation from 'react-native-vector-icons/Foundation';
import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Octicons from 'react-native-vector-icons/Octicons';
import Zocial from 'react-native-vector-icons/Zocial';
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons';
import { GlobalTheme } from '../theme';
function CustomIcon({
iconLibrary,
icon,
size = 22,
color = GlobalTheme.colors.primary,
style = {},
...rest
}) {
let Icon = AntDesign;
switch (iconLibrary) {
case 'AntDesign':
Icon = AntDesign;
break;
case 'Entypo':
Icon = Entypo;
break;
case 'EvilIcons':
Icon = EvilIcons;
break;
case 'Feather':
Icon = Feather;
break;
case 'FontAwesome':
Icon = FontAwesome;
break;
case 'Fontisto':
Icon = Fontisto;
break;
case 'Foundation':
Icon = Foundation;
break;
case 'Ionicons':
Icon = Ionicons;
break;
case 'MaterialIcons':
Icon = MaterialIcons;
break;
case 'MaterialCommunityIcons':
Icon = MaterialCommunityIcons;
break;
case 'Octicons':
Icon = Octicons;
break;
case 'Zocial':
Icon = Zocial;
break;
case 'SimpleLineIcons':
Icon = SimpleLineIcons;
break;
default:
Icon = AntDesign;
}
return <Icon name={icon} size={size} style={style} color={color} {...rest} />;
}
export default CustomIcon;
>>>>>>> dabur-store-dna
+51 -32
View File
@@ -1,32 +1,51 @@
const IMAGES = {
// AppLogo: require('../assets/Images/logo.png'),
AppLogo: require('../assets/Images/logo.png'),
filterIcon: require('../assets/Icons/filter.png'),
menuIcon: require('../assets/Icons/menu.png'),
pluscircleIcon: require('../assets/Icons/pluscircle.png'),
rightArrowIcon: require('../assets/Icons/rightarrow.png'),
leftArrowIcon: require('../assets/Icons/leftarrow.png'),
crossIcon: require('../assets/Icons/cross.png'),
searchIcon: require('../assets/Icons/search.png'),
greenCameraIcon: require('../assets/Icons/green_camera.png'),
redCameraIcon: require('../assets/Icons/red_camera.png'),
normalCameraIcon: require('../assets/Icons/camera.png'),
WhiteBGIMG: require('../assets/Images/white.png'),
backIcon:require('../assets/Icons/backIcon.png'),
greenTick:require('../assets/Icons/greenTick.png'),
storeIcon:require('../assets/Icons/store.png'),
reportIcon:require('../assets/Icons/report.png'),
downIcon:require('../assets/Icons/down.png'),
upArrow:require('../assets/Icons/uparrow.png'),
footerImage : require('../assets/Images/footerImage.png'),
Logo: require('../assets/Images/applogo.png'),
WelcomeBackground: require('../assets/Images/welcomebackground.png'),
Welcomelogo: require('../assets/Images/welcomelogo.png'),
AuthTopBG: require('../assets/Images/logintopBG.png'),
AuthTopBGNew: require('../assets/Images/appLogoNew.png'),
AuthBottomBG: require('../assets/Images/loginbottomBG.png'),
dotsIcon: require('../assets/Icons/dots.png'),
};
export default IMAGES;
<<<<<<< HEAD
const IMAGES = {
// AppLogo: require('../assets/Images/logo.png'),
AppLogo: require('../assets/Images/logo.png'),
filterIcon: require('../assets/Icons/filter.png'),
menuIcon: require('../assets/Icons/menu.png'),
pluscircleIcon: require('../assets/Icons/pluscircle.png'),
rightArrowIcon: require('../assets/Icons/rightarrow.png'),
crossIcon: require('../assets/Icons/cross.png'),
};
export default IMAGES;
=======
const IMAGES = {
// AppLogo: require('../assets/Images/logo.png'),
AppLogo: require('../assets/Images/logo.png'),
filterIcon: require('../assets/Icons/filter.png'),
menuIcon: require('../assets/Icons/menu.png'),
pluscircleIcon: require('../assets/Icons/pluscircle.png'),
rightArrowIcon: require('../assets/Icons/rightarrow.png'),
leftArrowIcon: require('../assets/Icons/leftarrow.png'),
crossIcon: require('../assets/Icons/cross.png'),
searchIcon: require('../assets/Icons/search.png'),
greenCameraIcon: require('../assets/Icons/green_camera.png'),
redCameraIcon: require('../assets/Icons/red_camera.png'),
normalCameraIcon: require('../assets/Icons/camera.png'),
WhiteBGIMG: require('../assets/Images/white.png'),
backIcon:require('../assets/Icons/backIcon.png'),
greenTick:require('../assets/Icons/greenTick.png'),
storeIcon:require('../assets/Icons/store.png'),
reportIcon:require('../assets/Icons/report.png'),
downIcon:require('../assets/Icons/down.png'),
upArrow:require('../assets/Icons/uparrow.png'),
footerImage : require('../assets/Images/footerImage.png'),
Logo: require('../assets/Images/applogo.png'),
WelcomeBackground: require('../assets/Images/welcomebackground.png'),
Welcomelogo: require('../assets/Images/welcomelogo.png'),
AuthTopBG: require('../assets/Images/logintopBG.png'),
AuthTopBGNew: require('../assets/Images/appLogoNew.png'),
AuthBottomBG: require('../assets/Images/loginbottomBG.png'),
projectIdImg: require('../assets/Images/projectId.png'),
PerformicsLogo: require('../assets/Images/PerformicsLogo.png'),
dotsIcon: require('../assets/Icons/dots.png'),
pending: require('../assets/Icons/wall-clock.png'),
alert: require('../assets/Icons/question-mark.png'),
};
export default IMAGES;
>>>>>>> dabur-store-dna
+73 -35
View File
@@ -1,36 +1,74 @@
// Toast.js
import Toast from 'react-native-toast-message';
const showToast = (type, text1, text2) => {
Toast.show({
type: type,
text1: text1,
text2: text2,
position: 'top',
visibilityTime: 3000,
autoHide: true,
topOffset: 30,
bottomOffset: 40,
text1Style: {
fontSize: 15, // Custom font size for the main text
fontWeight: 'bold',
},
text2Style: {
fontSize: 14, // Custom font size for the secondary text
color:'gray'
},
});
};
const ToastComponent = () => {
return <Toast innerRef={(ref) => Toast.setRef(ref)} />;
};
const toastSuccess = (text1, text2) => {
showToast('success', text1, text2);
};
const toastError = (text1, text2) => {
showToast('error', text1, text2);
};
<<<<<<< HEAD
// Toast.js
import Toast from 'react-native-toast-message';
const showToast = (type, text1, text2) => {
Toast.show({
type: type,
text1: text1,
text2: text2,
position: 'top',
visibilityTime: 3000,
autoHide: true,
topOffset: 30,
bottomOffset: 40,
text1Style: {
fontSize: 15, // Custom font size for the main text
fontWeight: 'bold',
},
text2Style: {
fontSize: 14, // Custom font size for the secondary text
color:'gray'
},
});
};
const ToastComponent = () => {
return <Toast innerRef={(ref) => Toast.setRef(ref)} />;
};
const toastSuccess = (text1, text2) => {
showToast('success', text1, text2);
};
const toastError = (text1, text2) => {
showToast('error', text1, text2);
};
=======
// Toast.js
import Toast from 'react-native-toast-message';
const showToast = (type, text1, text2) => {
Toast.show({
type: type,
text1: text1,
text2: text2,
position: 'top',
visibilityTime: 3000,
autoHide: true,
topOffset: 30,
bottomOffset: 40,
text1Style: {
fontSize: 15, // Custom font size for the main text
fontWeight: 'bold',
},
text2Style: {
fontSize: 14, // Custom font size for the secondary text
color:'gray'
},
});
};
const ToastComponent = () => {
return <Toast innerRef={(ref) => Toast.setRef(ref)} />;
};
const toastSuccess = (text1, text2) => {
showToast('success', text1, text2);
};
const toastError = (text1, text2) => {
showToast('error', text1, text2);
};
>>>>>>> dabur-store-dna
export { ToastComponent, toastSuccess, toastError };
+83 -46
View File
@@ -1,47 +1,84 @@
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Splash from '../screens/AuthScreen/Splash';
import Login from '../screens/AuthScreen/Login';
import VerifyOTP from '../screens/AuthScreen/VerifyOTP';
import { ToastComponent } from '../constants/Toast';
import StoreInfo from '../screens/MainScreen/StoreInfo';
import Feedback from '../screens/MainScreen/Feedback';
import Dashboard from '../screens/MainScreen/Dashboard';
import FeedbackCategories from '../screens/MainScreen/Feedback/FeedbackCategories';
import { Platform, StatusBar, View } from 'react-native';
import Welcome from '../screens/MainScreen/WelcomePage';
const Stack = createNativeStackNavigator();
const Routes = () => {
const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? 50 : StatusBar.currentHeight;
return (
<NavigationContainer>
{Platform.OS === 'ios' && (
<View style={{
height: STATUSBAR_HEIGHT,
bbarStyle:'light-content',
backgroundColor: '#113F8C',
}} />
)}
<StatusBar barStyle={'light-content'} backgroundColor={'#113F8C'} />
<Stack.Navigator
screenOptions={{ headerShown: false }}
initialRouteName="Splash">
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="VerifyOTP" component={VerifyOTP} />
<Stack.Screen name="Welcome" component={Welcome} />
<Stack.Screen name="StoreInfo" component={StoreInfo} />
<Stack.Screen name="Dashboard" component={Dashboard} />
<Stack.Screen name="Feedback" component={Feedback} />
<Stack.Screen name="FeedbackCategories" component={FeedbackCategories} />
</Stack.Navigator>
<ToastComponent />
</NavigationContainer>
);
};
<<<<<<< HEAD
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Splash from '../screens/AuthScreen/Splash';
import Login from '../screens/AuthScreen/Login';
import VerifyOTP from '../screens/AuthScreen/VerifyOTP';
import { ToastComponent } from '../constants/Toast';
import StoreInfo from '../screens/MainScreen/StoreInfo';
const Stack = createNativeStackNavigator();
const Routes = () => {
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{ headerShown: false }}
initialRouteName="Splash">
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="VerifyOTP" component={VerifyOTP} />
<Stack.Screen name="StoreInfo" component={StoreInfo} />
</Stack.Navigator>
<ToastComponent />
</NavigationContainer>
);
};
=======
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Splash from '../screens/AuthScreen/Splash';
import Login from '../screens/AuthScreen/Login/Login';
import VerifyOTP from '../screens/AuthScreen/VerifyOTP';
import { ToastComponent } from '../constants/Toast';
import StoreInfo from '../screens/MainScreen/StoreInfo';
import Feedback from '../screens/MainScreen/Feedback';
import Dashboard from '../screens/MainScreen/Dashboard';
import FeedbackCategories from '../screens/MainScreen/Feedback/FeedbackCategories';
import { Platform, StatusBar, View } from 'react-native';
import Welcome from '../screens/MainScreen/WelcomePage';
import Details from '../screens/MainScreen/Dashboard/Details';
import Project from '../screens/AuthScreen/Project/Project';
const Stack = createNativeStackNavigator();
const Routes = () => {
const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? 50 : StatusBar.currentHeight;
return (
<NavigationContainer>
{Platform.OS === 'ios' && (
<View style={{
height: STATUSBAR_HEIGHT,
bbarStyle:'light-content',
backgroundColor: '#113F8C',
}} />
)}
<StatusBar barStyle={'light-content'} backgroundColor={'#113F8C'} />
<Stack.Navigator
screenOptions={{ headerShown: false }}
initialRouteName="Splash">
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="VerifyOTP" component={VerifyOTP} />
<Stack.Screen name="Welcome" component={Welcome} />
<Stack.Screen name="StoreInfo" component={StoreInfo} />
<Stack.Screen name="Dashboard" component={Dashboard} />
<Stack.Screen name="Feedback" component={Feedback} />
<Stack.Screen name="FeedbackCategories" component={FeedbackCategories} />
<Stack.Screen name="Details" component={Details} />
<Stack.Screen name="Project" component={Project} />
</Stack.Navigator>
<ToastComponent />
</NavigationContainer>
);
};
>>>>>>> dabur-store-dna
export default Routes;
+13 -5
View File
@@ -1,5 +1,13 @@
import userSlice from '../slices/userSlice';
export default {
user: userSlice,
};
<<<<<<< HEAD
import userSlice from '../slices/userSlice';
export default {
user: userSlice,
};
=======
import userSlice from '../slices/userSlice';
export default {
user: userSlice,
};
>>>>>>> dabur-store-dna
+67 -32
View File
@@ -1,33 +1,68 @@
// // src/redux/slices/authSlice.js
// import { createSlice } from '@reduxjs/toolkit';
// const initialState = {
// token: null,
// loading: false,
// error: null,
// };
// const authSlice = createSlice({
// name: 'auth',
// initialState,
// reducers: {
// loginStart: (state) => {
// state.loading = true;
// state.error = null;
// },
// loginSuccess: (state, action) => {
// state.loading = false;
// state.token = action.payload;
// },
// loginFailure: (state, action) => {
// state.loading = false;
// state.error = action.payload;
// },
// logout: (state) => {
// state.token = null;
// },
// },
// });
// export const { loginStart, loginSuccess, loginFailure, logout } = authSlice.actions;
<<<<<<< HEAD
// // src/redux/slices/authSlice.js
// import { createSlice } from '@reduxjs/toolkit';
// const initialState = {
// token: null,
// loading: false,
// error: null,
// };
// const authSlice = createSlice({
// name: 'auth',
// initialState,
// reducers: {
// loginStart: (state) => {
// state.loading = true;
// state.error = null;
// },
// loginSuccess: (state, action) => {
// state.loading = false;
// state.token = action.payload;
// },
// loginFailure: (state, action) => {
// state.loading = false;
// state.error = action.payload;
// },
// logout: (state) => {
// state.token = null;
// },
// },
// });
// export const { loginStart, loginSuccess, loginFailure, logout } = authSlice.actions;
=======
// // src/redux/slices/authSlice.js
// import { createSlice } from '@reduxjs/toolkit';
// const initialState = {
// token: null,
// loading: false,
// error: null,
// };
// const authSlice = createSlice({
// name: 'auth',
// initialState,
// reducers: {
// loginStart: (state) => {
// state.loading = true;
// state.error = null;
// },
// loginSuccess: (state, action) => {
// state.loading = false;
// state.token = action.payload;
// },
// loginFailure: (state, action) => {
// state.loading = false;
// state.error = action.payload;
// },
// logout: (state) => {
// state.token = null;
// },
// },
// });
// export const { loginStart, loginSuccess, loginFailure, logout } = authSlice.actions;
>>>>>>> dabur-store-dna
// export default authSlice.reducer;
+53 -25
View File
@@ -1,25 +1,53 @@
import {createSlice} from '@reduxjs/toolkit';
const initialState = {
token: '',
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
setUser(state, action) {
return {
...state,
...action.payload,
token: action?.payload?.usertoken,
};
},
resetUserState() {
return initialState;
},
},
});
export const {setUser, resetUserState} = userSlice.actions;
export default userSlice.reducer;
<<<<<<< HEAD
import {createSlice} from '@reduxjs/toolkit';
const initialState = {
token: '',
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
setUser(state, action) {
return {
...state,
...action.payload,
token: action?.payload?.usertoken,
};
},
resetUserState() {
return initialState;
},
},
});
export const {setUser, resetUserState} = userSlice.actions;
export default userSlice.reducer;
=======
import {createSlice} from '@reduxjs/toolkit';
const initialState = {
token: '',
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
setUser(state, action) {
return {
...state,
...action.payload,
token: action?.payload?.usertoken,
};
},
resetUserState() {
return initialState;
},
},
});
export const {setUser, resetUserState} = userSlice.actions;
export default userSlice.reducer;
>>>>>>> dabur-store-dna
+11 -4
View File
@@ -1,5 +1,12 @@
import { configureStore } from '@reduxjs/toolkit'
import reducer from './reducer'
<<<<<<< HEAD
import { configureStore } from '@reduxjs/toolkit'
import reducer from './reducer'
=======
import { configureStore } from '@reduxjs/toolkit'
import reducer from './reducer'
>>>>>>> dabur-store-dna
export const store = configureStore({ reducer: reducer })
+97
View File
@@ -0,0 +1,97 @@
import React, { useEffect, useState } from 'react';
import { View, Text, Image, Platform, ImageBackground } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import IMAGES from '../../../constants/Images';
import { styles } from './style';
import { useDispatch } from 'react-redux';
import CustomTextInput from '../../../components/CustomTextInput';
import CustomButton from '../../../components/CustomButton';
import Loader from '../../../constants/Loader';
import { ApiURL } from '../../../api/ApiConstant';
import { toastError, toastSuccess } from '../../../constants/Toast';
import axios from 'axios';
import { SafeAreaView } from 'react-native-safe-area-context';
import { GlobalTheme } from '../../../theme';
import Geolocation from '@react-native-community/geolocation';
const Login = ({ navigation }) => {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const [username, setUsername] = useState('');
// geo loc
useEffect(() => {
Geolocation.getCurrentPosition(info => console.log("Location infoooo====>", JSON.stringify(info)));
}, [])
// end geo loc
const onSubmit = () => {
setLoading(true);
getOTP();
};
const getOTP = async () => {
try {
const params = {
"UserId": username
};
const config = {
method: 'post',
url: ApiURL.getotpApi,
headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json'
},
data: params
};
const response = await axios.request(config);
const res = response.data || [];
console.log('OTP is ===> ', res?.SendOTP);
if (res?.SendOTP[0].OTP === '0' || res?.SendOTP[0].OTP === 0) {
setLoading(false);
toastError("Alert", "Invalid User");
} else {
toastSuccess("Alert", res?.SendOTP[0]?.Messages);
navigation.navigate('VerifyOTP', { username: username });
setLoading(false);
}
// console.log('getotpApi res==>', JSON.stringify(res?.SendOTP[0]));
} catch (error) {
console.log("❌ OTP API error:", error);
setLoading(false);
}
};
return (
<SafeAreaView style={styles.container}>
<KeyboardAwareScrollView keyboardShouldPersistTaps="handled" enableOnAndroid={true} contentContainerStyle={{ justifyContent: 'center', flexGrow: 1, marginTop: 0 }} style={styles.container}>
<View style={{ backgroundColor: GlobalTheme.colors.primary, height: 40 }} />
<Image style={styles.appLogo} source={IMAGES.AuthTopBGNew} resizeMode='contain' />
<View style={styles.card}>
<Text style={styles.loginTitle}>Login</Text>
<CustomTextInput
label="Username"
placeholder="Enter username"
value={username}
onChangeText={setUsername}
containerStyle={styles.inputWrapper}
/>
<CustomButton onPress={() => onSubmit()} title={'Continue'} style={styles.btnbg} textstyle={styles.btntext} />
<ImageBackground source={IMAGES.AuthBottomBG} style={styles.AuthBottomBG} >
<Text style={{ position: 'absolute', textAlign: 'center', alignContent: 'center', alignSelf: 'center', bottom: 0, color: GlobalTheme.colors.gray }}> Copyright CPM India - 2025</Text>
{/* <Image source={IMAGES.Logo} style={styles.footerImage} resizeMode="contain"/> */}
</ImageBackground>
</View>
</KeyboardAwareScrollView>
<Loader visible={loading} loadingtext={'Loading ...'} />
</SafeAreaView>
);
};
export default Login;
+38 -97
View File
@@ -1,97 +1,38 @@
import React, { useEffect, useState } from 'react';
import { View, Text, Image, Platform, ImageBackground } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import IMAGES from '../../../constants/Images';
import { styles } from './style';
import { useDispatch } from 'react-redux';
import CustomTextInput from '../../../components/CustomTextInput';
import CustomButton from '../../../components/CustomButton';
import Loader from '../../../constants/Loader';
import { ApiURL } from '../../../api/ApiConstant';
import { toastError, toastSuccess } from '../../../constants/Toast';
import axios from 'axios';
import { SafeAreaView } from 'react-native-safe-area-context';
import { GlobalTheme } from '../../../theme';
import Geolocation from '@react-native-community/geolocation';
const Login = ({ navigation }) => {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const [username, setUsername] = useState('');
// geo loc
useEffect(() => {
Geolocation.getCurrentPosition(info => console.log("Location infoooo====>", JSON.stringify(info)));
}, [])
// end geo loc
const onSubmit = () => {
setLoading(true);
getOTP();
};
const getOTP = async () => {
try {
const params = {
"UserId": username
};
const config = {
method: 'post',
url: ApiURL.getotpApi,
headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json'
},
data: params
};
const response = await axios.request(config);
const res = response.data || [];
console.log('OTP is ===> ', res?.SendOTP);
if (res?.SendOTP[0].OTP === '0' || res?.SendOTP[0].OTP === 0) {
setLoading(false);
toastError("Alert", "Invalid User");
} else {
toastSuccess("Alert", res?.SendOTP[0]?.Messages);
navigation.navigate('VerifyOTP', { username: username });
setLoading(false);
}
// console.log('getotpApi res==>', JSON.stringify(res?.SendOTP[0]));
} catch (error) {
console.log("❌ OTP API error:", error);
setLoading(false);
}
};
return (
<SafeAreaView style={styles.container}>
<KeyboardAwareScrollView keyboardShouldPersistTaps="handled" enableOnAndroid={true} contentContainerStyle={{ justifyContent: 'center', flexGrow: 1, marginTop: 0 }} style={styles.container}>
<View style={{ backgroundColor: GlobalTheme.colors.primary, height: 40 }} />
<Image style={styles.appLogo} source={IMAGES.AuthTopBGNew} resizeMode='contain' />
<View style={styles.card}>
<Text style={styles.loginTitle}>Login</Text>
<CustomTextInput
label="Username"
placeholder="Enter username"
value={username}
onChangeText={setUsername}
containerStyle={styles.inputWrapper}
/>
<CustomButton onPress={() => onSubmit()} title={'Continue'} style={styles.btnbg} textstyle={styles.btntext} />
<ImageBackground source={IMAGES.AuthBottomBG} style={styles.AuthBottomBG} >
<Text style={{ position: 'absolute', textAlign: 'center', alignContent: 'center', alignSelf: 'center', bottom: 0, color: GlobalTheme.colors.gray }}> Copyright CPM India - 2025</Text>
{/* <Image source={IMAGES.Logo} style={styles.footerImage} resizeMode="contain"/> */}
</ImageBackground>
</View>
</KeyboardAwareScrollView>
<Loader visible={loading} loadingtext={'Loading ...'} />
</SafeAreaView>
);
};
export default Login;
import React, { useState } from 'react';
import { View, Text, Image, Alert } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import IMAGES from '../../../constants/Images';
import { styles } from './style';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useDispatch } from 'react-redux';
import CustomTextInput from '../../../components/CustomTextInput';
import CustomButton from '../../../components/CustomButton';
import Background from '../../../components/Background';
const Login = ({ navigation }) => {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const [username, setUsername] = useState('');
return (
<Background barcolor="light-content">
<KeyboardAwareScrollView style={styles.container} contentContainerStyle={{ justifyContent: 'center', flex: 1 }}>
<View style={styles.logoContainer}>
<Image style={styles.appLogo} source={IMAGES.AppLogo} />
</View>
<View style={styles.titleContainer}>
<Text style={styles.titleText}>Log In</Text>
</View>
<View style={{ marginTop: 50 }}>
<CustomTextInput label="Username" value={username} onChangeText={setUsername}
/>
</View>
<View style={{ marginTop: 100 }}>
<CustomButton onPress={() => navigation.navigate('VerifyOTP')} title={'Login'} style={styles.btnbg} textstyle={styles.btntext} />
</View>
</KeyboardAwareScrollView>
</Background>
);
};
export default Login;
+120 -82
View File
@@ -1,82 +1,120 @@
import { StyleSheet, Dimensions } from 'react-native';
import { GlobalTheme } from '../../../theme';
import { normalize } from '../../../utilis/responsive';
const { width, height } = Dimensions.get('window');
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: GlobalTheme.colors.primary,
},
logoContainer: {
width: '100%',
},
appLogo: {
height: normalize(170),
width: '100%',
resizeMode: 'contain',
},
titleContainer: {
alignSelf: 'center',
marginBottom: normalize(10),
},
titleText: {
fontSize: normalize(20),
fontWeight: 'bold',
color: GlobalTheme.colors.black,
},
card: {
backgroundColor: GlobalTheme.colors.white,
borderTopLeftRadius: GlobalTheme.borderRadius.xxlg || normalize(20),
borderTopRightRadius: GlobalTheme.borderRadius.xxlg || normalize(20),
padding: normalize(20),
width: width,
alignSelf: 'center',
// marginTop: normalize(30),
shadowColor: '#000',
shadowOpacity: 0.05,
shadowOffset: { width: 0, height: 4 },
shadowRadius: 8,
elevation: 4,
flex: 1,
},
btnbg: {
backgroundColor: GlobalTheme.colors.secondary,
borderRadius: GlobalTheme.borderRadius.md,
marginTop: normalize(30),
paddingVertical: normalize(12),
alignItems: 'center',
},
btntext: {
color: GlobalTheme.colors.white,
fontSize: normalize(GlobalTheme.typography.fontSize.small),
fontWeight: GlobalTheme.typography.fontWeight.regular,
},
footer: {
marginTop: normalize(60),
alignItems: 'center',
},
footerImage: {
width: '100%',
height: normalize(80),
resizeMode: 'contain',
marginTop : normalize(160),
},
AuthBottomBG: {
width: '100%',
resizeMode: 'contain',
height: normalize(300),
justifyContent: 'center',
},
loginTitle: {
color: GlobalTheme.colors.black,
fontSize: normalize(GlobalTheme.typography.fontSize.large),
fontWeight: GlobalTheme.typography.fontWeight.medium,
textAlign: 'center',
marginBottom: normalize(20),
},
mainContainer: {
flex: 1,
backgroundColor: '#EAF0FF',
},
});
<<<<<<< HEAD
import { StyleSheet } from 'react-native';
import { GlobalTheme, Screen } from '../../../theme';
export const styles = StyleSheet.create({
container: {
flex: 1,
// backgroundColor: GlobalTheme.colors.white,
},
logoContainer: {
alignItems: 'center',
},
appLogo: {
height: 200,
width: 200,
resizeMode: 'contain',
},
titleContainer: {
alignSelf: 'center',
// marginTop: 15,
},
titleText: {
fontSize: 25,
fontWeight: 'bold',
color: GlobalTheme.colors.black,
},
btnbg: {
backgroundColor: GlobalTheme.colors.secondary, borderRadius: GlobalTheme.borderRadius.md
},
btntext: {
color: GlobalTheme.colors.white,
fontSize: GlobalTheme.typography.fontSize.medium
}
});
=======
import { StyleSheet, Dimensions } from 'react-native';
import { GlobalTheme } from '../../../theme';
import { normalize } from '../../../utilis/responsive';
const { width, height } = Dimensions.get('window');
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: GlobalTheme.colors.primary,
},
logoContainer: {
width: '100%',
},
appLogo: {
height: normalize(170),
width: '100%',
resizeMode: 'contain',
},
titleContainer: {
alignSelf: 'center',
marginBottom: normalize(10),
},
titleText: {
fontSize: normalize(20),
fontWeight: 'bold',
color: GlobalTheme.colors.black,
},
card: {
backgroundColor: GlobalTheme.colors.white,
borderTopLeftRadius: GlobalTheme.borderRadius.xxlg || normalize(20),
borderTopRightRadius: GlobalTheme.borderRadius.xxlg || normalize(20),
padding: normalize(20),
width: width,
alignSelf: 'center',
// marginTop: normalize(30),
shadowColor: '#000',
shadowOpacity: 0.05,
shadowOffset: { width: 0, height: 4 },
shadowRadius: 8,
elevation: 4,
flex: 1,
},
btnbg: {
backgroundColor: GlobalTheme.colors.secondary,
borderRadius: GlobalTheme.borderRadius.md,
marginTop: normalize(30),
paddingVertical: normalize(12),
alignItems: 'center',
},
btntext: {
color: GlobalTheme.colors.white,
fontSize: normalize(GlobalTheme.typography.fontSize.small),
fontWeight: GlobalTheme.typography.fontWeight.regular,
},
footer: {
marginTop: normalize(60),
alignItems: 'center',
},
footerImage: {
width: '100%',
height: normalize(80),
resizeMode: 'contain',
marginTop : normalize(160),
},
AuthBottomBG: {
width: '100%',
resizeMode: 'contain',
height: normalize(300),
justifyContent: 'center',
},
loginTitle: {
color: GlobalTheme.colors.black,
fontSize: normalize(GlobalTheme.typography.fontSize.large),
fontWeight: GlobalTheme.typography.fontWeight.medium,
textAlign: 'center',
marginBottom: normalize(20),
},
mainContainer: {
flex: 1,
backgroundColor: '#EAF0FF',
},
});
>>>>>>> dabur-store-dna
+103
View File
@@ -0,0 +1,103 @@
import React, { useEffect, useState } from 'react';
import { View, Text, Image, Platform, ImageBackground, TextInput } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import IMAGES from '../../../constants/Images';
import { styles } from './style';
import { useDispatch } from 'react-redux';
import CustomButton from '../../../components/CustomButton';
import Loader from '../../../constants/Loader';
import { ApiURL } from '../../../api/ApiConstant';
import { toastError, toastSuccess } from '../../../constants/Toast';
import axios from 'axios';
import { SafeAreaView } from 'react-native-safe-area-context';
import { GlobalTheme } from '../../../theme';
import Geolocation from '@react-native-community/geolocation';
const Project = ({ navigation }) => {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const [username, setUsername] = useState('');
// geo loc
useEffect(() => {
Geolocation.getCurrentPosition(info => console.log("Location infoooo====>", JSON.stringify(info)));
}, [])
// end geo loc
const onSubmit = () => {
// setLoading(true);
// getOTP();
navigation.navigate("Login")
};
const getOTP = async () => {
try {
const params = {
"UserId": username
};
const config = {
method: 'post',
url: ApiURL.getotpApi,
headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json'
},
data: params
};
const response = await axios.request(config);
const res = response.data || [];
console.log('OTP is ===> ', res?.SendOTP);
if (res?.SendOTP[0].OTP === '0' || res?.SendOTP[0].OTP === 0) {
setLoading(false);
toastError("Alert", "Invalid User");
} else {
toastSuccess("Alert", res?.SendOTP[0]?.Messages);
navigation.navigate('VerifyOTP', { username: username });
setLoading(false);
}
// console.log('getotpApi res==>', JSON.stringify(res?.SendOTP[0]));
} catch (error) {
console.log("❌ OTP API error:", error);
setLoading(false);
}
};
return (
<SafeAreaView style={styles.container}>
<KeyboardAwareScrollView keyboardShouldPersistTaps="handled" enableOnAndroid={true} contentContainerStyle={{ justifyContent: 'center', flexGrow: 1, marginTop: 0 }} style={styles.container}>
{/* <View style={{ backgroundColor: GlobalTheme.colors.primary, height: 40 }} /> */}
<Image style={styles.performicsLogo} source={IMAGES.PerformicsLogo} resizeMode='contain' />
<Image style={styles.appLogo} source={IMAGES.projectIdImg} resizeMode='contain' />
<View style={styles.card}>
<View style={{marginTop:25}}>
<Text style={[styles.loginTitle, { fontSize: 15, color: '#555555', marginBottom: 10 }]}>Hey There</Text>
<Text style={styles.loginTitle}>Enter Your Project Id</Text>
</View>
<View style={{ marginTop: 20, height: 50, backgroundColor: '#eee', borderRadius: 10 }}>
<TextInput
style={{ height: 50, paddingHorizontal: 15 }}
placeholder='Enter Project Id'
placeholderTextColor={'gray'}
keyboardType='numeric'
/>
</View>
<CustomButton onPress={() => onSubmit()} title={'Next'} style={styles.btnbg} textstyle={styles.btntext} />
<ImageBackground source={IMAGES.AuthBottomBG} style={styles.AuthBottomBG} >
<Text style={{ position: 'absolute', textAlign: 'center', alignContent: 'center', alignSelf: 'center', bottom: 20, color: GlobalTheme.colors.gray }}> Copyright CPM India - 2025</Text>
</ImageBackground>
</View>
</KeyboardAwareScrollView>
<Loader visible={loading} loadingtext={'Loading ...'} />
</SafeAreaView>
);
};
export default Project;
+87
View File
@@ -0,0 +1,87 @@
import { StyleSheet, Dimensions } from 'react-native';
import { GlobalTheme } from '../../../theme';
import { normalize } from '../../../utilis/responsive';
const { width, height } = Dimensions.get('window');
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
},
logoContainer: {
width: '100%',
},
appLogo: {
height: normalize(180),
width: '100%',
resizeMode: 'contain',
marginTop: 30,
},
performicsLogo: {
height: normalize(50),
width: '55%',
resizeMode: 'contain',
alignSelf: 'center',
marginTop:10,
},
titleContainer: {
alignSelf: 'center',
marginBottom: normalize(10),
},
titleText: {
fontSize: normalize(20),
fontWeight: 'bold',
color: GlobalTheme.colors.black,
},
card: {
padding: normalize(25),
width: width,
alignSelf: 'center',
// marginTop: normalize(30),
shadowColor: '#000',
shadowOpacity: 0.05,
shadowOffset: { width: 0, height: 4 },
shadowRadius: 8,
// elevation: 4,
flex: 1,
},
btnbg: {
backgroundColor: GlobalTheme.colors.secondary,
borderRadius: GlobalTheme.borderRadius.md,
marginTop: normalize(30),
paddingVertical: normalize(12),
alignItems: 'center',
},
btntext: {
color: GlobalTheme.colors.white,
fontSize: normalize(GlobalTheme.typography.fontSize.small),
fontWeight: GlobalTheme.typography.fontWeight.regular,
},
footer: {
marginTop: normalize(60),
alignItems: 'center',
},
footerImage: {
width: '100%',
height: normalize(80),
resizeMode: 'contain',
marginTop: normalize(160),
},
AuthBottomBG: {
width: '100%',
resizeMode: 'contain',
height: normalize(210),
justifyContent: 'center',
},
loginTitle: {
color: GlobalTheme.colors.black,
fontSize: normalize(GlobalTheme.typography.fontSize.small),
fontWeight: GlobalTheme.typography.fontWeight.medium,
textAlign: 'center',
marginBottom: normalize(20),
},
mainContainer: {
flex: 1,
backgroundColor: '#EAF0FF',
},
});
+201 -95
View File
@@ -1,95 +1,201 @@
import { View, Text, Image, Dimensions, StyleSheet } from 'react-native';
import React, { useEffect } from 'react';
import IMAGES from '../../../constants/Images';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useDispatch } from 'react-redux';
import { setUser } from '../../../redux/slices/userSlice';
const SplashScreen = ({ navigation }) => {
const dispatch = useDispatch();
useEffect(() => {
const checkLoginStatus = async () => {
try {
const isuserlogin = await AsyncStorage.getItem('@Dabur_DNA_User');
console.log("isuserlogin", isuserlogin)
const parsedUser = JSON.parse(isuserlogin);
if (isuserlogin) {
dispatch(setUser(parsedUser));
navigation.reset({
index: 0,
routes: [{ name: 'Welcome' }],
});
} else {
navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
});
}
} catch (error) {
console.error('Error checking login status:', error);
}
};
checkLoginStatus();
}, []);
return (
<View style={styles.container}>
<View style={styles.backgroundContainer}>
<Image
source={IMAGES.splashFullImg}
resizeMode="stretch"
style={styles.backdrop}
/>
</View>
<View style={styles.overlay}>
<Image style={styles.logo} source={IMAGES.AppLogo} />
</View>
</View>
);
};
export default SplashScreen;
const styles = StyleSheet.create({
backgroundContainer: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
overlay: {
opacity: 1,
alignItems: 'center',
justifyContent: 'center',
},
logo: {
backgroundColor: 'rgba(0,0,0,0)',
height: 200,
width: 200,
overflow: 'hidden',
resizeMode: 'contain',
marginTop: 5,
justifyContent: 'center',
},
backdrop: {
flex: 1,
width: '100%',
height: '100%',
},
headline: {
fontSize: 18,
textAlign: 'center',
backgroundColor: 'black',
color: 'white',
//borderWidth:1
},
});
<<<<<<< HEAD
import {View, Text, Image, Dimensions, StyleSheet} from 'react-native';
import React, {useEffect} from 'react';
import IMAGES from '../../../constants/Images';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {useDispatch} from 'react-redux';
const SplashScreen = ({navigation}) => {
const dispatch = useDispatch();
// const get_token = async () => {
// let token = await AsyncStorage.getItem('@Collector_User');
// console.log(token);
// token = JSON.parse(token);
// if (token) {
// dispatch(setUser(token));
// navigation.reset({
// index: 0,
// routes: [{name: 'mainStack', params: {screen: 'dashboard'}}],
// });
// } else {
// setTimeout(() => {
// navigation.reset({
// index: 0,
// routes: [{name: 'Login'}],
// });
// }, 2000);
// }
// };
useEffect(() => {
// get_token();
setTimeout(() => {
navigation.reset({
index: 0,
routes: [{name: 'Login'}],
});
}, 4000);
}, []);
return (
<View style={styles.container}>
<View style={styles.backgroundContainer}>
<Image
source={IMAGES.splashFullImg}
resizeMode="stretch"
style={styles.backdrop}
/>
</View>
<View style={styles.overlay}>
<Image style={styles.logo} source={IMAGES.AppLogo} />
</View>
</View>
);
};
export default SplashScreen;
const styles = StyleSheet.create({
backgroundContainer: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
overlay: {
opacity: 1,
alignItems: 'center',
justifyContent: 'center',
},
logo: {
backgroundColor: 'rgba(0,0,0,0)',
height: 200,
width: 200,
overflow: 'hidden',
resizeMode: 'contain',
marginTop: 5,
justifyContent: 'center',
},
backdrop: {
flex: 1,
width: '100%',
height: '100%',
},
headline: {
fontSize: 18,
textAlign: 'center',
backgroundColor: 'black',
color: 'white',
//borderWidth:1
},
});
=======
import { View, Text, Image, Dimensions, StyleSheet } from 'react-native';
import React, { useEffect } from 'react';
import IMAGES from '../../../constants/Images';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useDispatch } from 'react-redux';
import { setUser } from '../../../redux/slices/userSlice';
const SplashScreen = ({ navigation }) => {
const dispatch = useDispatch();
useEffect(() => {
checkLoginStatus();
}, []);
const checkLoginStatus = async () => {
try {
const isuserlogin = await AsyncStorage.getItem('@Dabur_DNA_User');
console.log("isuserlogin", isuserlogin)
const parsedUser = JSON.parse(isuserlogin);
if (isuserlogin) {
dispatch(setUser(parsedUser));
setTimeout(() => {
navigation.reset({
index: 0,
routes: [{ name: 'Welcome' }],
});
}, 1000);
} else {
setTimeout(() => {
navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
});
}, 1000);
}
} catch (error) {
console.error('Error checking login status:', error);
}
};
return (
<View style={styles.container}>
<View style={styles.backgroundContainer}>
<Image
source={IMAGES.splashFullImg}
resizeMode="stretch"
style={styles.backdrop}
/>
</View>
<View style={styles.overlay}>
<Image style={styles.logo} source={IMAGES.AppLogo} />
</View>
</View>
);
};
export default SplashScreen;
const styles = StyleSheet.create({
backgroundContainer: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
overlay: {
opacity: 1,
alignItems: 'center',
justifyContent: 'center',
},
logo: {
backgroundColor: 'rgba(0,0,0,0)',
height: 200,
width: 200,
overflow: 'hidden',
resizeMode: 'contain',
marginTop: 5,
justifyContent: 'center',
},
backdrop: {
flex: 1,
width: '100%',
height: '100%',
},
headline: {
fontSize: 18,
textAlign: 'center',
backgroundColor: 'black',
color: 'white',
//borderWidth:1
},
});
>>>>>>> dabur-store-dna
+346 -219
View File
@@ -1,219 +1,346 @@
import React, { useEffect, useState } from 'react';
import { View, Text, Image, TouchableOpacity, ImageBackground } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { useDispatch } from 'react-redux';
import { OtpInput } from "react-native-otp-entry";
import CustomButton from '../../../components/CustomButton';
import Background from '../../../components/Background';
import IMAGES from '../../../constants/Images';
import { GlobalTheme } from '../../../theme';
import { styles } from './style';
import { toastError, toastSuccess } from '../../../constants/Toast';
import Loader from '../../../constants/Loader';
import { ApiURL } from '../../../api/ApiConstant';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { setUser } from '../../../redux/slices/userSlice';
import axios from 'axios';
import { SafeAreaView } from 'react-native-safe-area-context';
const VerifyOTP = ({ navigation, route }) => {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const [otp, setOTP] = useState('');
const [timer, setTimer] = useState(300); // 5 minutes = 300 seconds
const [showResend, setShowResend] = useState(false);
const username = route.params.username;
useEffect(() => {
if (timer === 0) {
setShowResend(true);
return;
}
const interval = setInterval(() => {
setTimer(prev => prev - 1);
}, 1000);
return () => clearInterval(interval);
}, [timer]);
const formatTime = (secs) => {
const minutes = Math.floor(secs / 60);
const seconds = secs % 60;
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
};
const handle_validate = () => {
if (otp.length < 6) {
toastError('Alert', "Please enter 6 digit PIN");
} else {
onSubmit();
}
}
const resendOTP = async () => {
try {
const params = {
"UserId": username
}
const config = {
method: 'post',
url: ApiURL.getotpApi,
headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json'
},
data: params
};
const response = await axios.request(config);
const res = response.data || [];
// console.log('storeSearchApi====>', res);
if (res?.SendOTP[0].OTP === '0' || res?.SendOTP[0].OTP === 0) {
toastError("Alert", res?.SendOTP[0]?.Messages)
} else {
toastSuccess("Alert", res?.SendOTP[0]?.Messages)
navigation.navigate('VerifyOTP', { username: username });
}
// console.log('getotpApi res==>', JSON.stringify(res?.SendOTP[0]));
// setLoading(false)
} catch (error) {
// setLoading(false)
console.log("❌ Filter API error:", error);
}
};
const resend_OTP = () => {
setTimer(300);
setShowResend(false);
toastSuccess('Resend OTP Successfully.')
resendOTP();
}
const onSubmit = () => {
setLoading(true)
VerifyOTP();
setTimeout(() => {
setLoading(false)
}, 100);
}
const VerifyOTP = async () => {
try {
const params = {
"UserId": username,
"OTP": otp
}
const config = {
method: 'post',
url: ApiURL.verifyotpApi,
headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json'
},
data: params
};
const response = await axios.request(config);
const res = response.data || [];
if (res?.AuthenticateOTP[0].Message == 'OTP is matched') {
toastSuccess("Alert", res?.AuthenticateOTP[0]?.Message || "Alert", "Login Successfully.")
await AsyncStorage.setItem('@Dabur_DNA_User', JSON.stringify(res?.AuthenticateOTP[0]));
dispatch(setUser(res?.AuthenticateOTP[0]));
navigation.reset({ index: 0, routes: [{ name: 'Welcome' }] })
} else {
toastError("Alert", res?.AuthenticateOTP[0]?.Message);
}
} catch (error) {
// setLoading(false)
console.log("❌ Filter API error:", error);
}
}
return (
<SafeAreaView style={styles.container}>
<TouchableOpacity onPress={() => navigation.goBack()}>
<View style={styles.backTextView}>
<Image source={IMAGES.leftArrowIcon} style={styles.iconStyle} />
<Text style={styles.backIconText}>Back</Text>
</View>
</TouchableOpacity>
<KeyboardAwareScrollView keyboardShouldPersistTaps="handled" enableOnAndroid={true} style={styles.container} contentContainerStyle={{ justifyContent: 'center', flex: 1 }}>
<View style={{ backgroundColor: GlobalTheme.colors.primary, height: 40 }} />
<Image style={styles.appLogo} source={IMAGES.AuthTopBGNew} resizeMode='contain' />
<View style={styles.card}>
<View style={styles.titleContainer}>
<Text style={styles.titleText}>Enter the OTP sent to your {"\n"} registered contact</Text>
</View>
<View style={{ marginTop: 50 }}>
<OtpInput
numberOfDigits={6}
focusColor={GlobalTheme.colors.primary}
autoFocus={false}
hideStick={true}
placeholder=""
blurOnFilled={true}
disabled={false}
type="numeric"
secureTextEntry={false}
focusStickBlinkingDuration={500}
// onFocus={() => console.log("Focused")}
// onBlur={() => console.log("Blurred")}
onTextChange={(text) => setOTP(text)}
onFilled={(text) => {
setOTP(text);
console.log(`OTP is ${text}`);
}}
textInputProps={{
accessibilityLabel: "One-Time Password",
}}
textProps={{
accessibilityRole: "text",
accessibilityLabel: "OTP digit",
allowFontScaling: false,
}}
theme={{
containerStyle: styles.container,
pinCodeContainerStyle: styles.pinCodeContainer,
pinCodeTextStyle: styles.pinCodeText,
focusStickStyle: styles.focusStick,
focusedPinCodeContainerStyle: styles.activePinCodeContainer,
placeholderTextStyle: styles.placeholderText,
filledPinCodeContainerStyle: styles.filledPinCodeContainer,
disabledPinCodeContainerStyle: styles.disabledPinCodeContainer,
}}
/>
</View>
<View style={{ marginTop: 100}}>
<CustomButton onPress={handle_validate} title={'Verify'} style={styles.btnbg} textstyle={styles.btntext} />
</View>
<View style={{ alignItems: 'center', marginTop: 20 }}>
{!showResend ? (
<Text style={{ color: GlobalTheme.colors.darkGray }}>Resend OTP in {formatTime(timer)}</Text>
) : (
<TouchableOpacity onPress={resend_OTP}>
<Text style={styles.resendOTP} >
Resend OTP
</Text>
</TouchableOpacity>
)}
</View>
<ImageBackground source={IMAGES.AuthBottomBG} style={styles.AuthBottomBG} >
{/* <Image source={IMAGES.Logo} style={styles.footerImage} resizeMode="contain"/> */}
<Text style={{ position : 'absolute', textAlign:'center', alignContent:'center',alignSelf:'center', bottom:0 , color : GlobalTheme.colors.gray}}> Copyright CPM India - 2025</Text>
</ImageBackground>
</View>
</KeyboardAwareScrollView>
<Loader visible={loading} />
</SafeAreaView>
);
};
export default VerifyOTP;
<<<<<<< HEAD
import React, { useEffect, useRef, useState } from 'react';
import { View, Text, Image, Alert, TouchableOpacity } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { useDispatch } from 'react-redux';
import { OtpInput } from "react-native-otp-entry";
import CustomButton from '../../../components/CustomButton';
import Background from '../../../components/Background';
import IMAGES from '../../../constants/Images';
import { GlobalTheme } from '../../../theme';
import { styles } from './style';
import { toastError, toastSuccess } from '../../../constants/Toast';
const VerifyOTP = ({ navigation }) => {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const [otp, setOTP] = useState('');
const [timer, setTimer] = useState(300); // 5 minutes = 300 seconds
const [showResend, setShowResend] = useState(false);
// Countdown effect
useEffect(() => {
if (timer === 0) {
setShowResend(true);
return;
}
const interval = setInterval(() => {
setTimer(prev => prev - 1);
}, 1000);
return () => clearInterval(interval);
}, [timer]);
const formatTime = (secs) => {
const minutes = Math.floor(secs / 60);
const seconds = secs % 60;
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
};
const handle_validate = () => {
if (otp.length < 6) {
toastError('Alert', "Please enter 6 digit PIN");
} else {
navigation.navigate('StoreInfo');
}
}
const resend_OTP = () => {
setTimer(300);
setShowResend(false);
toastSuccess('Resend OTP Successfully.')
}
return (
<Background barcolor="light-content">
<KeyboardAwareScrollView style={styles.container} contentContainerStyle={{ justifyContent: 'center', flex: 1 }}>
<View style={styles.logoContainer}>
<Image style={styles.appLogo} source={IMAGES.AppLogo} />
</View>
<View style={styles.titleContainer}>
<Text style={styles.titleText}>Verify OTP</Text>
</View>
<View style={{ marginTop: 50 }}>
<OtpInput
numberOfDigits={6}
focusColor={GlobalTheme.colors.primary}
autoFocus={false}
hideStick={true}
placeholder=""
blurOnFilled={true}
disabled={false}
type="numeric"
secureTextEntry={false}
focusStickBlinkingDuration={500}
onFocus={() => console.log("Focused")}
onBlur={() => console.log("Blurred")}
onTextChange={(text) => setOTP(text)}
onFilled={(text) => {
setOTP(text);
console.log(`OTP is ${text}`);
}}
textInputProps={{
accessibilityLabel: "One-Time Password",
}}
textProps={{
accessibilityRole: "text",
accessibilityLabel: "OTP digit",
allowFontScaling: false,
}}
theme={{
containerStyle: styles.container,
pinCodeContainerStyle: styles.pinCodeContainer,
pinCodeTextStyle: styles.pinCodeText,
focusStickStyle: styles.focusStick,
focusedPinCodeContainerStyle: styles.activePinCodeContainer,
placeholderTextStyle: styles.placeholderText,
filledPinCodeContainerStyle: styles.filledPinCodeContainer,
disabledPinCodeContainerStyle: styles.disabledPinCodeContainer,
}}
/>
</View>
<View style={{ marginTop: 100 }}>
<CustomButton onPress={handle_validate} title={'Verify'} style={styles.btnbg} textstyle={styles.btntext} />
</View>
<View style={{ alignItems: 'center', marginTop: 20 }}>
{!showResend ? (
<Text style={{ color: GlobalTheme.colors.darkGray }}>Resend OTP in {formatTime(timer)}</Text>
) : (
<TouchableOpacity onPress={resend_OTP}>
<Text style={styles.resendOTP} >
Resend OTP
</Text>
</TouchableOpacity>
)}
</View>
</KeyboardAwareScrollView>
</Background>
);
};
export default VerifyOTP;
=======
import React, { useEffect, useState } from 'react';
import { View, Text, Image, TouchableOpacity, ImageBackground } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { useDispatch } from 'react-redux';
import { OtpInput } from "react-native-otp-entry";
import CustomButton from '../../../components/CustomButton';
import Background from '../../../components/Background';
import IMAGES from '../../../constants/Images';
import { GlobalTheme } from '../../../theme';
import { styles } from './style';
import { toastError, toastSuccess } from '../../../constants/Toast';
import Loader from '../../../constants/Loader';
import { ApiURL } from '../../../api/ApiConstant';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { setUser } from '../../../redux/slices/userSlice';
import axios from 'axios';
import { SafeAreaView } from 'react-native-safe-area-context';
const VerifyOTP = ({ navigation, route }) => {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const [otp, setOTP] = useState('');
const [timer, setTimer] = useState(300); // 5 minutes = 300 seconds
const [showResend, setShowResend] = useState(false);
const username = route.params.username;
useEffect(() => {
if (timer === 0) {
setShowResend(true);
return;
}
const interval = setInterval(() => {
setTimer(prev => prev - 1);
}, 1000);
return () => clearInterval(interval);
}, [timer]);
const formatTime = (secs) => {
const minutes = Math.floor(secs / 60);
const seconds = secs % 60;
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
};
const handle_validate = () => {
if (otp.length < 6) {
toastError('Alert', "Please enter 6 digit PIN");
} else {
onSubmit();
}
}
const resendOTP = async () => {
try {
const params = {
"UserId": username
}
const config = {
method: 'post',
url: ApiURL.getotpApi,
headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json'
},
data: params
};
const response = await axios.request(config);
const res = response.data || [];
// console.log('storeSearchApi====>', res);
if (res?.SendOTP[0].OTP === '0' || res?.SendOTP[0].OTP === 0) {
toastError("Alert", res?.SendOTP[0]?.Messages)
} else {
toastSuccess("Alert", res?.SendOTP[0]?.Messages)
navigation.navigate('VerifyOTP', { username: username });
}
// console.log('getotpApi res==>', JSON.stringify(res?.SendOTP[0]));
// setLoading(false)
} catch (error) {
// setLoading(false)
console.log("❌ Filter API error:", error);
}
};
const resend_OTP = () => {
setTimer(300);
setShowResend(false);
toastSuccess('Resend OTP Successfully.')
resendOTP();
}
const onSubmit = () => {
setLoading(true)
VerifyOTP();
setTimeout(() => {
setLoading(false)
}, 100);
}
const VerifyOTP = async () => {
try {
const params = {
"UserId": username,
"OTP": otp
}
const config = {
method: 'post',
url: ApiURL.verifyotpApi,
headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json'
},
data: params
};
const response = await axios.request(config);
const res = response.data || [];
if (res?.AuthenticateOTP[0].Message == 'OTP is matched') {
toastSuccess("Alert", res?.AuthenticateOTP[0]?.Message || "Alert", "Login Successfully.")
await AsyncStorage.setItem('@Dabur_DNA_User', JSON.stringify(res?.AuthenticateOTP[0]));
dispatch(setUser(res?.AuthenticateOTP[0]));
navigation.reset({ index: 0, routes: [{ name: 'Welcome' }] })
} else {
toastError("Alert", res?.AuthenticateOTP[0]?.Message);
}
} catch (error) {
// setLoading(false)
console.log("❌ Filter API error:", error);
}
}
return (
<SafeAreaView style={styles.container}>
<TouchableOpacity onPress={() => navigation.goBack()}>
<View style={styles.backTextView}>
<Image source={IMAGES.leftArrowIcon} style={styles.iconStyle} />
<Text style={styles.backIconText}>Back</Text>
</View>
</TouchableOpacity>
<KeyboardAwareScrollView keyboardShouldPersistTaps="handled" enableOnAndroid={true} style={styles.container} contentContainerStyle={{ justifyContent: 'center', flex: 1 }}>
<View style={{ backgroundColor: GlobalTheme.colors.primary, height: 40 }} />
<Image style={styles.appLogo} source={IMAGES.AuthTopBGNew} resizeMode='contain' />
<View style={styles.card}>
<View style={styles.titleContainer}>
<Text style={styles.titleText}>Enter the OTP sent to your {"\n"} registered contact</Text>
</View>
<View style={{ marginTop: 50 }}>
<OtpInput
numberOfDigits={6}
focusColor={GlobalTheme.colors.primary}
autoFocus={false}
hideStick={true}
placeholder=""
blurOnFilled={true}
disabled={false}
type="numeric"
secureTextEntry={false}
focusStickBlinkingDuration={500}
// onFocus={() => console.log("Focused")}
// onBlur={() => console.log("Blurred")}
onTextChange={(text) => setOTP(text)}
onFilled={(text) => {
setOTP(text);
console.log(`OTP is ${text}`);
}}
textInputProps={{
accessibilityLabel: "One-Time Password",
}}
textProps={{
accessibilityRole: "text",
accessibilityLabel: "OTP digit",
allowFontScaling: false,
}}
theme={{
containerStyle: styles.container,
pinCodeContainerStyle: styles.pinCodeContainer,
pinCodeTextStyle: styles.pinCodeText,
focusStickStyle: styles.focusStick,
focusedPinCodeContainerStyle: styles.activePinCodeContainer,
placeholderTextStyle: styles.placeholderText,
filledPinCodeContainerStyle: styles.filledPinCodeContainer,
disabledPinCodeContainerStyle: styles.disabledPinCodeContainer,
}}
/>
</View>
<View style={{ marginTop: 100}}>
<CustomButton onPress={handle_validate} title={'Verify'} style={styles.btnbg} textstyle={styles.btntext} />
</View>
<View style={{ alignItems: 'center', marginTop: 20 }}>
{!showResend ? (
<Text style={{ color: GlobalTheme.colors.darkGray }}>Resend OTP in {formatTime(timer)}</Text>
) : (
<TouchableOpacity onPress={resend_OTP}>
<Text style={styles.resendOTP} >
Resend OTP
</Text>
</TouchableOpacity>
)}
</View>
<ImageBackground source={IMAGES.AuthBottomBG} style={styles.AuthBottomBG} >
{/* <Image source={IMAGES.Logo} style={styles.footerImage} resizeMode="contain"/> */}
<Text style={{ position : 'absolute', textAlign:'center', alignContent:'center',alignSelf:'center', bottom:0 , color : GlobalTheme.colors.gray}}> Copyright CPM India - 2025</Text>
</ImageBackground>
</View>
</KeyboardAwareScrollView>
<Loader visible={loading} />
</SafeAreaView>
);
};
export default VerifyOTP;
>>>>>>> dabur-store-dna
+253 -149
View File
@@ -1,149 +1,253 @@
import { Dimensions, StyleSheet } from 'react-native';
import { GlobalTheme, Screen } from '../../../theme';
import { normalize } from '../../../utilis/responsive';
const { width, height } = Dimensions.get('window');
export const styles = StyleSheet.create({
container: {
// flex: 1,
// paddingHorizontal: 5
flex: 1,
backgroundColor: GlobalTheme.colors.primary,
},
logoContainer: {
alignItems: 'center',
},
appLogo: {
height: normalize(170),
width: '100%',
resizeMode: 'contain',
marginTop: 40
},
titleContainer: {
alignSelf: 'center',
},
titleText: {
fontSize: 18,
fontWeight: '500',
color: GlobalTheme.colors.black,
textAlign: 'center'
},
btnbg: {
backgroundColor: GlobalTheme.colors.secondary, borderRadius: GlobalTheme.borderRadius.md
},
btntext: {
color: GlobalTheme.colors.white,
fontSize: GlobalTheme.typography.fontSize.medium
},
otp_inputStyle: {
textAlign: 'center',
backgroundColor: 'red',
width: 100,
borderRadius: 4,
paddingVertical: 10,
paddingHorizontal: 15,
height: 50,
color: 'red',
marginBottom: 10,
marginRight: 10,
fontSize: 25,
},
// OTP
pinCodeContainer: {
width: 45,
height: 55,
borderWidth: 1,
borderColor: '#D8E3F1',
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
activePinCodeContainer: {
borderColor: GlobalTheme.colors.primary,
borderWidth: 2,
},
filledPinCodeContainer: {
backgroundColor: '#D8E3F1',
},
disabledPinCodeContainer: {
backgroundColor: '#f0f0f0',
borderColor: '#ddd',
},
pinCodeText: {
fontSize: 20,
fontWeight: 'bold',
color: '#333',
},
focusStick: {
height: 2,
width: 20,
backgroundColor: GlobalTheme.colors.primary,
marginTop: 4,
},
placeholderText: {
color: '#aaa',
fontSize: 18,
},
resendText: {
color: GlobalTheme.colors.primary,
fontWeight: 'bold',
fontSize: 14,
marginTop: 20,
textAlign: 'center',
},
timerText: {
color: 'gray',
fontSize: 14,
marginTop: 20,
textAlign: 'center',
},
resendOTP: {
color: GlobalTheme.colors.secondary, fontWeight: GlobalTheme.typography.fontWeight.medium, fontSize: GlobalTheme.typography.fontSize.small
},
iconStyle: {
height: 20,
width: 20,
resizeMode: 'contain',
tintColor: GlobalTheme.colors.white
},
backIconText: { fontSize: GlobalTheme.typography.fontSize.small, color: GlobalTheme.colors.white, fontWeight: GlobalTheme.typography.fontWeight.medium, marginLeft: 8 },
backTextView: {
flexDirection: 'row', alignItems: 'center', paddingTop: 20, paddingHorizontal: 10
},
card: {
backgroundColor: GlobalTheme.colors.white,
borderTopLeftRadius: GlobalTheme.borderRadius.xxlg || normalize(20),
borderTopRightRadius: GlobalTheme.borderRadius.xxlg || normalize(20),
padding: normalize(20),
width: width,
alignSelf: 'center',
// marginTop: normalize(30),
shadowColor: '#000',
shadowOpacity: 0.05,
shadowOffset: { width: 0, height: 4 },
shadowRadius: 8,
elevation: 4,
flex: 1,
minHeight : height * 0.7
},
footer: {
marginTop: 60,
alignItems: 'center',
},
footerImage: {
width: '100%',
height: normalize(80),
resizeMode: 'contain',
marginTop: normalize(160),
},
AuthBottomBG: {
width: '100%',
resizeMode: 'contain',
height: normalize(270),
justifyContent: 'center',
marginTop: normalize(-40),
},
});
<<<<<<< HEAD
import { StyleSheet } from 'react-native';
import { GlobalTheme, Screen } from '../../../theme';
export const styles = StyleSheet.create({
container: {
flex: 1,
},
logoContainer: {
alignItems: 'center',
},
appLogo: {
height: 200,
width: 200,
resizeMode: 'contain',
},
titleContainer: {
alignSelf: 'center',
// marginTop: 15,
},
titleText: {
fontSize: 25,
fontWeight: 'bold',
color: GlobalTheme.colors.black,
},
btnbg: {
backgroundColor: GlobalTheme.colors.secondary, borderRadius: GlobalTheme.borderRadius.md
},
btntext: {
color: GlobalTheme.colors.white,
fontSize: GlobalTheme.typography.fontSize.medium
},
otp_inputStyle: {
textAlign: 'center',
backgroundColor: 'red',
width: 100,
borderRadius: 4,
paddingVertical: 10,
paddingHorizontal: 15,
height: 50,
color: 'red',
marginBottom: 10,
marginRight: 10,
fontSize: 25,
},
// OTP
pinCodeContainer: {
width: 45,
height: 55,
borderWidth: 1,
borderColor: '#D8E3F1',
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
activePinCodeContainer: {
borderColor: GlobalTheme.colors.primary,
borderWidth: 2,
},
filledPinCodeContainer: {
backgroundColor: '#D8E3F1',
},
disabledPinCodeContainer: {
backgroundColor: '#f0f0f0',
borderColor: '#ddd',
},
pinCodeText: {
fontSize: 20,
fontWeight: 'bold',
color: '#333',
},
focusStick: {
height: 2,
width: 20,
backgroundColor: GlobalTheme.colors.primary,
marginTop: 4,
},
placeholderText: {
color: '#aaa',
fontSize: 18,
},
resendText: {
color: GlobalTheme.colors.primary,
fontWeight: 'bold',
fontSize: 14,
marginTop: 20,
textAlign: 'center',
},
timerText: {
color: 'gray',
fontSize: 14,
marginTop: 20,
textAlign: 'center',
},
resendOTP:{
color: GlobalTheme.colors.secondary, fontWeight: GlobalTheme.typography.fontWeight.medium , fontSize : GlobalTheme.typography.fontSize.small
}
});
=======
import { Dimensions, StyleSheet } from 'react-native';
import { GlobalTheme, Screen } from '../../../theme';
import { normalize } from '../../../utilis/responsive';
const { width, height } = Dimensions.get('window');
export const styles = StyleSheet.create({
container: {
// flex: 1,
// paddingHorizontal: 5
flex: 1,
backgroundColor: GlobalTheme.colors.primary,
},
logoContainer: {
alignItems: 'center',
},
appLogo: {
height: normalize(170),
width: '100%',
resizeMode: 'contain',
marginTop: 40
},
titleContainer: {
alignSelf: 'center',
},
titleText: {
fontSize: 18,
fontWeight: '500',
color: GlobalTheme.colors.black,
textAlign: 'center'
},
btnbg: {
backgroundColor: GlobalTheme.colors.secondary, borderRadius: GlobalTheme.borderRadius.md
},
btntext: {
color: GlobalTheme.colors.white,
fontSize: GlobalTheme.typography.fontSize.medium
},
otp_inputStyle: {
textAlign: 'center',
backgroundColor: 'red',
width: 100,
borderRadius: 4,
paddingVertical: 10,
paddingHorizontal: 15,
height: 50,
color: 'red',
marginBottom: 10,
marginRight: 10,
fontSize: 25,
},
// OTP
pinCodeContainer: {
width: 45,
height: 55,
borderWidth: 1,
borderColor: '#D8E3F1',
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
activePinCodeContainer: {
borderColor: GlobalTheme.colors.primary,
borderWidth: 2,
},
filledPinCodeContainer: {
backgroundColor: '#D8E3F1',
},
disabledPinCodeContainer: {
backgroundColor: '#f0f0f0',
borderColor: '#ddd',
},
pinCodeText: {
fontSize: 20,
fontWeight: 'bold',
color: '#333',
},
focusStick: {
height: 2,
width: 20,
backgroundColor: GlobalTheme.colors.primary,
marginTop: 4,
},
placeholderText: {
color: '#aaa',
fontSize: 18,
},
resendText: {
color: GlobalTheme.colors.primary,
fontWeight: 'bold',
fontSize: 14,
marginTop: 20,
textAlign: 'center',
},
timerText: {
color: 'gray',
fontSize: 14,
marginTop: 20,
textAlign: 'center',
},
resendOTP: {
color: GlobalTheme.colors.secondary, fontWeight: GlobalTheme.typography.fontWeight.medium, fontSize: GlobalTheme.typography.fontSize.small
},
iconStyle: {
height: 20,
width: 20,
resizeMode: 'contain',
tintColor: GlobalTheme.colors.white
},
backIconText: { fontSize: GlobalTheme.typography.fontSize.small, color: GlobalTheme.colors.white, fontWeight: GlobalTheme.typography.fontWeight.medium, marginLeft: 8 },
backTextView: {
flexDirection: 'row', alignItems: 'center', paddingTop: 20, paddingHorizontal: 10
},
card: {
backgroundColor: GlobalTheme.colors.white,
borderTopLeftRadius: GlobalTheme.borderRadius.xxlg || normalize(20),
borderTopRightRadius: GlobalTheme.borderRadius.xxlg || normalize(20),
padding: normalize(20),
width: width,
alignSelf: 'center',
// marginTop: normalize(30),
shadowColor: '#000',
shadowOpacity: 0.05,
shadowOffset: { width: 0, height: 4 },
shadowRadius: 8,
elevation: 4,
flex: 1,
minHeight : height * 0.7
},
footer: {
marginTop: 60,
alignItems: 'center',
},
footerImage: {
width: '100%',
height: normalize(80),
resizeMode: 'contain',
marginTop: normalize(160),
},
AuthBottomBG: {
width: '100%',
resizeMode: 'contain',
height: normalize(270),
justifyContent: 'center',
marginTop: normalize(-40),
},
});
>>>>>>> dabur-store-dna
@@ -0,0 +1,406 @@
import React, { useEffect, useState } from 'react';
import { View, Text, TouchableOpacity, ScrollView, Image, Modal, Platform, StyleSheet, Alert } from 'react-native';
import { useRoute, useNavigation } from '@react-navigation/native';
import { post } from '../../../api/ApiService';
import IMAGES from '../../../constants/Images';
import { GlobalTheme } from '../../../theme';
import Loader from '../../../constants/Loader';
import { SafeAreaView } from 'react-native-safe-area-context';
import { toastError } from '../../../constants/Toast';
const Details = () => {
const route = useRoute();
const navigation = useNavigation();
const { selectedDetails = [], storeData, year, month, mainTabIndex } = route.params || {};
const [modalGraphData, setModalGraphData] = useState({});
const [activePromoTab, setActivePromoTab] = useState('Executed');
const [allCatData, setAllCatData] = useState([])
const [selectedCategoryData, setSelectedCategoryData] = useState([]);
const [categoryModalVisible, setCategoryModalVisible] = useState(false);
useEffect(() => {
if (selectedDetails.length > 0) {
fetchDetailGraphs(selectedDetails);
}
}, [selectedDetails]);
useEffect(() => {
getAllCatData();
}, [])
const getAllCatData = () => {
let data = {
parameters: {
projectid: 41654,
year: year,
monthno: month,
storeid: storeData?.StoreId
},
}
const apiUrl = mainTabIndex === 0
? 'https://dax.parinaam.in/execute/dabur/detmtd/oos_sku_list_for_all_visits_mtd'
: 'https://dax.parinaam.in/execute/dabur/detlsv/oos_sku_list_on_lsv';
post(apiUrl, data)
.then(res => {
setAllCatData(res?.data);
})
.catch(err => {
console.log('Error =>', err);
});
}
const fetchDetailGraphs = async (detailPages) => {
try {
const resultMap = {};
for (let item of detailPages) {
const response = await post(item.GraphUrl, {
parameters: {
projectid: 41654,
year: year,
monthno: month,
storeid: storeData?.StoreId
},
});
resultMap[item.GraphUrl] = response?.data || [];
}
setModalGraphData(resultMap);
} catch (error) {
console.log("❌ Error fetching detail graphs:", error);
}
};
const showCategoryDetails = (data) => {
setCategoryModalVisible(!categoryModalVisible)
// Filter SKUs from allCatData where the category name matches
const filteredCategory = allCatData.filter(item =>
item.Product_CategoryCategory_Name === data.Product_CategoryCategory_Name
);
// Save for display
setSelectedCategoryData(filteredCategory);
}
const isOSATab = selectedDetails.some(item => item.GraphTitle === "OSA - Category");
return (
<SafeAreaView style={{ flex: 1, backgroundColor: '#113F8C' }}>
<View style={{ flex: 1, backgroundColor: '#fff' }}>
{/* Header */}
<View style={styled.header}>
<TouchableOpacity onPress={() => navigation.goBack()} style={{ padding: 5 }}>
<Image source={IMAGES.backIcon} style={{ height: 20, width: 20, tintColor: '#fff' }} />
</TouchableOpacity>
<Text style={{ color: '#fff', fontSize: 20, fontWeight: 'bold' }}>Details</Text>
<View style={{ width: 25 }} /> {/* spacer */}
</View>
<ScrollView style={{ padding: 20 }}>
{selectedDetails.map((detail, index) => {
const values = modalGraphData[detail.GraphUrl] || [];
if (!modalGraphData[detail.GraphUrl]) {
return (
<View key={index} style={{ flex: 1, marginBottom: 20 }}>
<Loader visible={true} />
</View>
);
}
switch (detail.GraphType) {
case 'Table':
// Check if it's the Promotion table
const isPromotionTable =
values.length > 0 &&
values[0].hasOwnProperty('Product_CategoryCategory_Name') &&
values[0].hasOwnProperty('Promotion_MasterPromotion_Definition');
if (isPromotionTable) {
// Filter data based on active tab
const filteredValues = values.filter(row =>
activePromoTab === 'Executed'
? row.Executed?.toLowerCase() === 'yes'
: row.Executed?.toLowerCase() === 'no'
);
// Group data by Product_CategoryCategory_Name
const groupedData = filteredValues.reduce((acc, curr) => {
const category = curr.Product_CategoryCategory_Name || 'Unknown';
if (!acc[category]) acc[category] = [];
acc[category].push(curr);
return acc;
}, {});
return (
<View key={index} style={{ marginBottom: 10 }}>
{/* Horizontal Tabs - show once at top */}
{index === 0 && ( // ensures only first promotion table renders the toggle
<View style={{ flexDirection: 'row', marginBottom: 20 }}>
{['Executed', 'Not Executed'].map(tab => {
const isSelected = activePromoTab === tab;
return (
<TouchableOpacity
key={tab}
onPress={() => setActivePromoTab(tab)}
style={{
flex: 1,
paddingVertical: 10,
backgroundColor: isSelected ? '#113F8C' : '#E3EBF8',
borderRadius: 8,
marginHorizontal: 5,
alignItems: 'center',
}}
>
<Text style={{ color: isSelected ? '#fff' : '#000', fontWeight: '600' }}>
{tab}
</Text>
</TouchableOpacity>
);
})}
</View>
)}
{/* No data message */}
<View style={{}}>
{filteredValues.length === 0 ? (
<View style={{ marginTop: 0, backgroundColor: 'red' }} />
) : (
Object.keys(groupedData).map((categoryName, catIdx) => (
<View key={catIdx} style={{ marginBottom: 20, }}>
{/* Category Header */}
<View style={{ backgroundColor: '#E8F0FF', padding: 8, borderRadius: 6 }}>
<Text style={{ fontSize: 15, fontWeight: '700', color: '#113F8C' }}>
{String(categoryName)}
</Text>
</View>
{/* Table Header */}
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: '#f5f5f5',
paddingVertical: 8,
paddingHorizontal: 9,
borderTopLeftRadius: 8,
borderTopRightRadius: 8,
marginTop: 5
}}
>
<Text style={{ color: '#000', fontWeight: 'bold', width: '80%' }}>
Definition
</Text>
<Text style={{ color: '#000', fontWeight: 'bold', width: '20%', textAlign: 'center' }}>
Executed
</Text>
</View>
{/* Table Rows */}
<View
style={{
backgroundColor: '#fff',
paddingHorizontal: 10,
borderBottomLeftRadius: 8,
borderBottomRightRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
elevation: 2
}}
>
{groupedData[categoryName].map((row, rowIdx) => (
<View
key={rowIdx}
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 8,
borderBottomWidth: rowIdx === groupedData[categoryName].length - 1 ? 0 : 1,
borderColor: '#eee'
}}
>
<Text style={{ color: '#000', width: '80%' }}>
{String(row.Promotion_MasterPromotion_Definition) || '-'}
</Text>
<Text style={{ color: '#000', width: '20%', textAlign: 'center' }}>
{row.Executed || '-'}
</Text>
</View>
))}
</View>
</View>
))
)}
</View>
</View>
);
}
let displayKey = null;
let presentKey = null;
if (values.length > 0) {
const presentKeys = Object.keys(values[0]).filter(k =>
(typeof values[0][k] === 'string' && ['Yes', 'No'].includes(values[0][k])) ||
typeof values[0][k] === 'boolean' ||
typeof values[0][k] === 'number'
);
presentKey = presentKeys.length > 0 ? presentKeys[0] : null;
const displayKeys = Object.keys(values[0]).filter(k => k !== presentKey && typeof values[0][k] === 'string');
displayKey = displayKeys.length > 0 ? displayKeys[0] : null;
}
return (
<View key={index} style={{ marginBottom: 30 }}>
<Text style={{ color: '#000', fontSize: 16, fontWeight: '600', marginBottom: 10 }}>
{detail.GraphTitle}
</Text>
<View style={styled.categoryHeader}>
<Text style={{ color: '#000', fontWeight: 'bold', width: '80%' }}>
{displayKey ? displayKey.replace(/_/g, ' ').replace(/([a-z])([A-Z])/g, '$1 $2') : ''}
</Text>
<Text style={{ color: '#000', fontWeight: 'bold', width: '20%', textAlign: 'center' }}>
{presentKey ? presentKey.replace(/_/g, ' ').replace(/([a-z])([A-Z])/g, '$1 $2') : ''}
</Text>
</View>
<View style={styled.itemContainer}>
{values.map((row, idx) => {
const presentKeys = Object.keys(row).filter(k =>
(typeof row[k] === 'string' && ['Yes', 'No'].includes(row[k])) ||
typeof row[k] === 'boolean' ||
typeof row[k] === 'number'
);
const presentKey = presentKeys.length > 0 ? presentKeys[0] : null;
const displayKeys = Object.keys(row).filter(k => k !== presentKey && typeof row[k] === 'string');
const displayKey = displayKeys.length > 0 ? displayKeys[0] : null;
return (
<View
key={idx}
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 8,
borderBottomWidth: idx === values.length - 1 ? 0 : 1,
borderColor: '#eee',
}}>
<Text style={{ color: '#000', width: '80%' }}>{row[displayKey] || '--'}</Text>
<TouchableOpacity disabled={isOSATab ? false : true}
onPress={() => {
if (row[presentKey] == 100 || row[presentKey] == '100') {
toastError('Alert', 'No Data Available')
} else {
showCategoryDetails(row)
}
}}
style={{ width: '20%', }}>
<Text style={{ color: '#113F8C', textAlign: 'center', fontWeight: '500' }}>
{presentKey ? (
typeof row[presentKey] === 'string' && ['Yes', 'No'].includes(row[presentKey]) ? row[presentKey] :
typeof row[presentKey] === 'boolean' ? (row[presentKey] ? 'Yes' : 'No') :
typeof row[presentKey] === 'number' ? row[presentKey].toFixed(2) : row[presentKey] || '-'
) : '-'}
</Text>
</TouchableOpacity>
</View>
);
})}
</View>
</View>
);
default:
return (
<View key={index} style={{ marginBottom: 20 }}>
<Text>Unsupported GraphType: {detail.GraphType}</Text>
</View>
);
}
})}
</ScrollView>
<Modal
visible={categoryModalVisible}
animationType="slide"
onRequestClose={() => setCategoryModalVisible(false)}
>
<View style={{ flex: 1, }}>
{/* Header */}
<View style={{ height: Platform.OS === 'ios' ? 55 : 0, backgroundColor: '#113F8C' }} />
<View style={{ width: '100%', backgroundColor: '#113F8C', borderBottomWidth: 1, borderColor: 'gray', padding: 5, paddingHorizontal: 20, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
<View style={{ width: '93%', alignItems: 'center' }}>
<Text style={{ color: '#fff', fontSize: 20, fontWeight: 'bold', marginBottom: 10, alignSelf: 'center' }}>{selectedCategoryData[0]?.Product_CategoryCategory_Name || 'Category'}</Text>
</View>
<TouchableOpacity onPress={() => setCategoryModalVisible(false)} style={{ width: '7%', alignItems: 'center' }}>
<Image source={IMAGES.crossIcon} style={{ height: 25, width: 25, resizeMode: 'contain' }} />
</TouchableOpacity>
</View>
{/* SKU List */}
<ScrollView contentContainerStyle={{ padding: 15 }}>
{/* <Text style={{ color: '#000', fontSize: 16, fontWeight: 'bold', marginBottom: 5 }}>OOS SKU details</Text> */}
{selectedCategoryData.map((item, idx) => (
<View
key={idx}
style={{
marginTop: 2,
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 8,
borderBottomWidth: idx === selectedCategoryData.length - 1 ? 0 : 1,
borderColor: '#eee',
}}
>
<Text style={{ color: '#000', width: '80%' }}>
{item.Product_MasterProduct_Name}
</Text>
{/* <Text style={{ color: '#000', width: '20%', textAlign: 'center' }}>
{item['#_of_OOS_SKU_for_all_visits']}
</Text> */}
</View>
))}
</ScrollView>
</View>
</Modal>
</View>
</SafeAreaView>
);
};
const styled = StyleSheet.create({
header: {
width: '100%',
backgroundColor: '#113F8C',
padding: 10,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
},
categoryHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: '#EDEDED',
paddingVertical: 8,
paddingHorizontal: 10,
borderTopLeftRadius: 8,
borderTopRightRadius: 8,
},
itemContainer: {
backgroundColor: '#fff',
paddingHorizontal: 10,
borderBottomLeftRadius: 8,
borderBottomRightRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
elevation: 2
}
})
export default Details;
+431
View File
@@ -0,0 +1,431 @@
import React, { useEffect, useState } from 'react';
import { View, Text, TouchableOpacity, ScrollView, Image, Modal, Platform, StyleSheet, Alert } from 'react-native';
import { useRoute, useNavigation } from '@react-navigation/native';
import { post } from '../../../api/ApiService';
import IMAGES from '../../../constants/Images';
import { GlobalTheme } from '../../../theme';
import Loader from '../../../constants/Loader';
import { SafeAreaView } from 'react-native-safe-area-context';
import { toastError } from '../../../constants/Toast';
const Details = () => {
const route = useRoute();
const navigation = useNavigation();
const { selectedDetails = [], storeData, year, month, mainTabIndex } = route.params || {};
const [modalGraphData, setModalGraphData] = useState({});
const [activePromoTab, setActivePromoTab] = useState('Executed');
const [allCatData, setAllCatData] = useState([])
const [selectedCategoryData, setSelectedCategoryData] = useState([]);
const [categoryModalVisible, setCategoryModalVisible] = useState(false);
useEffect(() => {
if (selectedDetails.length > 0) {
fetchDetailGraphs(selectedDetails);
}
}, [selectedDetails]);
useEffect(() => {
getAllCatData();
}, [])
const getAllCatData = () => {
let data = {
parameters: {
projectid: 41654,
year: year,
monthno: month,
storeid: storeData?.StoreId
},
}
const apiUrl = mainTabIndex === 0
? 'https://dax.parinaam.in/execute/dabur/detmtd/oos_sku_list_for_all_visits_mtd'
: 'https://dax.parinaam.in/execute/dabur/detlsv/oos_sku_list_on_lsv';
post(apiUrl, data)
.then(res => {
setAllCatData(res?.data);
})
.catch(err => {
console.log('Error =>', err);
});
}
const fetchDetailGraphs = async (detailPages) => {
try {
const resultMap = {};
for (let item of detailPages) {
const response = await post(item.GraphUrl, {
parameters: {
projectid: 41654,
year: year,
monthno: month,
storeid: storeData?.StoreId
},
});
resultMap[item.GraphUrl] = response?.data || [];
}
setModalGraphData(resultMap);
} catch (error) {
console.log("❌ Error fetching detail graphs:", error);
}
};
const showCategoryDetails = (data) => {
setCategoryModalVisible(!categoryModalVisible)
// Filter SKUs from allCatData where the category name matches
const filteredCategory = allCatData.filter(item =>
item.Product_CategoryCategory_Name === data.Product_CategoryCategory_Name
);
// Save for display
setSelectedCategoryData(filteredCategory);
}
const isOSATab = selectedDetails.some(item => item.GraphTitle === "OSA - Category");
console.log('isOSATab----',isOSATab);
return (
<SafeAreaView style={{ flex: 1, backgroundColor: '#113F8C' }}>
<View style={{ flex: 1, backgroundColor: '#fff' }}>
{/* Header */}
<View style={styled.header}>
<TouchableOpacity onPress={() => navigation.goBack()} style={{ padding: 5 }}>
<Image source={IMAGES.backIcon} style={{ height: 20, width: 20, tintColor: '#fff' }} />
</TouchableOpacity>
<Text style={{ color: '#fff', fontSize: 20, fontWeight: 'bold' }}>Details</Text>
<View style={{ width: 25 }} />
</View>
<ScrollView style={{ padding: 20 }}>
{selectedDetails && selectedDetails.length > 0 ? selectedDetails.map((detail, index) => {
const values = modalGraphData[detail.GraphUrl] || [];
if (!modalGraphData[detail.GraphUrl]) {
return (
<View key={index} style={{ flex: 1, marginBottom: 20 }}>
<Loader visible={true} />
</View>
);
}
switch (detail.GraphType) {
case 'Table':
// Check if it's the Promotion table
const isPromotionTable =
values.length > 0 &&
values[0].hasOwnProperty('Product_CategoryCategory_Name') &&
values[0].hasOwnProperty('Promotion_MasterPromotion_Definition');
if (isPromotionTable) {
// Filter data based on active tab
const filteredValues = values.filter(row =>
activePromoTab === 'Executed'
? row.Executed?.toLowerCase() === 'yes'
: row.Executed?.toLowerCase() === 'no'
);
// Group data by Product_CategoryCategory_Name
const groupedData = filteredValues.reduce((acc, curr) => {
const category = curr.Product_CategoryCategory_Name || 'Unknown';
if (!acc[category]) acc[category] = [];
acc[category].push(curr);
return acc;
}, {});
return (
<View key={index} style={{ marginBottom: 10 }}>
{/* Horizontal Tabs - show once at top */}
{index === 0 && ( // ensures only first promotion table renders the toggle
<View style={{ flexDirection: 'row', marginBottom: 20 }}>
{['Executed', 'Not Executed'].map(tab => {
const isSelected = activePromoTab === tab;
return (
<TouchableOpacity
key={tab}
onPress={() => setActivePromoTab(tab)}
style={{
flex: 1,
paddingVertical: 10,
backgroundColor: isSelected ? '#113F8C' : '#E3EBF8',
borderRadius: 8,
marginHorizontal: 5,
alignItems: 'center',
}}
>
<Text style={{ color: isSelected ? '#fff' : '#000', fontWeight: '600' }}>
{tab}
</Text>
</TouchableOpacity>
);
})}
</View>
)}
{/* No data message */}
<View style={{}}>
{filteredValues.length === 0 ? (
<View style={{ marginTop: 0, backgroundColor: 'red' }} />
) : (
Object.keys(groupedData).map((categoryName, catIdx) => (
<View key={catIdx} style={{ marginBottom: 20 }}>
{/* Category Header */}
<View style={{ backgroundColor: '#E8F0FF', padding: 8, borderRadius: 6 }}>
<Text style={{ fontSize: 15, fontWeight: '700', color: '#113F8C' }}>
{String(categoryName)}
</Text>
</View>
{/* Table Header */}
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: '#f5f5f5',
paddingVertical: 8,
paddingHorizontal: 9,
borderTopLeftRadius: 8,
borderTopRightRadius: 8,
marginTop: 5
}}
>
<Text style={{ color: '#000', fontWeight: 'bold', width: '80%' }}>
Definition
</Text>
<Text style={{ color: '#000', fontWeight: 'bold', width: '20%', textAlign: 'center' }}>
Executed
</Text>
</View>
{/* Table Rows */}
<View
style={{
backgroundColor: '#fff',
paddingHorizontal: 10,
borderBottomLeftRadius: 8,
borderBottomRightRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
elevation: 2
}}
>
{groupedData[categoryName].map((row, rowIdx) => (
<View
key={rowIdx}
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 8,
borderBottomWidth: rowIdx === groupedData[categoryName].length - 1 ? 0 : 1,
borderColor: '#eee'
}}
>
<Text style={{ color: '#000', width: '80%' }}>
{String(row.Promotion_MasterPromotion_Definition) || '-'}
</Text>
<Text style={{ color: '#000', width: '20%', textAlign: 'center' }}>
{row.Executed || '-'}
</Text>
</View>
))}
</View>
</View>
))
)}
</View>
</View>
);
}
let displayKey = null;
let presentKey = null;
if (values.length > 0) {
const presentKeys = Object.keys(values[0]).filter(k =>
(typeof values[0][k] === 'string' && ['Yes', 'No'].includes(values[0][k])) ||
typeof values[0][k] === 'boolean' ||
typeof values[0][k] === 'number'
);
presentKey = presentKeys.length > 0 ? presentKeys[0] : null;
const displayKeys = Object.keys(values[0]).filter(k => k !== presentKey && typeof values[0][k] === 'string');
displayKey = displayKeys.length > 0 ? displayKeys[0] : null;
}
return (
<View key={index} style={{ marginBottom: 30 }}>
<Text style={{ marginTop: 10, color: '#000', fontSize: 16, fontWeight: '600', marginBottom: 10 }}>
{detail.GraphTitle}
</Text>
<View style={styled.categoryHeader}>
<Text style={{ color: '#000', fontWeight: 'bold', width: '80%' }}>
{displayKey ? displayKey.replace(/_/g, ' ').replace(/([a-z])([A-Z])/g, '$1 $2') : ''}
</Text>
<Text style={{ color: '#000', fontWeight: 'bold', width: '20%', textAlign: 'center' }}>
{presentKey ? presentKey.replace(/_/g, ' ').replace(/([a-z])([A-Z])/g, '$1 $2') : ''}
</Text>
</View>
<View style={styled.itemContainer}>
{values.map((row, idx) => {
const presentKeys = Object.keys(row).filter(k =>
(typeof row[k] === 'string' && ['Yes', 'No'].includes(row[k])) ||
typeof row[k] === 'boolean' ||
typeof row[k] === 'number'
);
const presentKey = presentKeys.length > 0 ? presentKeys[0] : null;
const displayKeys = Object.keys(row).filter(k => k !== presentKey && typeof row[k] === 'string');
const displayKey = displayKeys.length > 0 ? displayKeys[0] : null;
return (
<View
key={idx}
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 8,
borderBottomWidth: idx === values.length - 1 ? 0 : 1,
borderColor: '#eee',
}}>
<Text style={{ color: '#000', width: '80%' }}>{row[displayKey] || '--'}</Text>
<TouchableOpacity disabled={isOSATab ? false : true}
onPress={() => {
if (row[presentKey] == 100 || row[presentKey] == '100') {
toastError('Alert', 'No Data Available')
} else {
showCategoryDetails(row)
}
}}
style={{ width: '20%', }}>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<Text style={{ color: '#113F8C', textAlign: 'center', fontWeight: '500' }}>
{presentKey ? (
typeof row[presentKey] === 'string' && ['Yes', 'No'].includes(row[presentKey]) ? row[presentKey] :
typeof row[presentKey] === 'boolean' ? (row[presentKey] ? 'Yes' : 'No') :
typeof row[presentKey] === 'number' ? row[presentKey].toFixed(2) : row[presentKey] || '-'
) : '-'}
</Text>
{ isOSATab && row[presentKey] != 100 || isOSATab && row[presentKey] != '100'? <Image source={IMAGES.rightArrowIcon} style={{marginLeft:6, height: 12, width: 12, resizeMode: 'contain' }} /> :null}
</View>
</TouchableOpacity>
</View>
);
})}
</View>
</View>
);
default:
return (
<View key={index} style={{ marginBottom: 20 }}>
<Text>Unsupported GraphType: {detail.GraphType}</Text>
</View>
);
}
}) :
<Loader visible={true} />
}
</ScrollView>
<Modal
visible={categoryModalVisible}
animationType="slide"
onRequestClose={() => setCategoryModalVisible(false)}
>
<View style={{ flex: 1, }}>
{/* Header */}
<View style={{ height: Platform.OS === 'ios' ? 55 : 0, backgroundColor: '#113F8C' }} />
<View style={{ width: '100%', backgroundColor: '#113F8C', borderBottomWidth: 1, borderColor: 'gray', padding: 5, paddingHorizontal: 20, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
<View style={{ width: '93%', alignItems: 'center' }}>
<Text style={{ color: '#fff', fontSize: 20, fontWeight: 'bold', marginBottom: 10, alignSelf: 'center' }}>{selectedCategoryData[0]?.Product_CategoryCategory_Name || 'Category'}</Text>
</View>
<TouchableOpacity onPress={() => setCategoryModalVisible(false)} style={{ width: '7%', alignItems: 'center' }}>
<Image source={IMAGES.crossIcon} style={{ height: 25, width: 25, resizeMode: 'contain' }} />
</TouchableOpacity>
</View>
<View style={{ borderTopLeftRadius: 10, borderTopRightRadius: 10, marginTop: 15, marginHorizontal: 15, backgroundColor: '#eee', padding: 10, borderWidth: 1, borderColor: 'gray' }}>
<Text style={{ color: '#000', fontSize: 16, fontWeight: '500' }}>{'Out of Stock SKUs:'}</Text>
</View>
{/* SKU List */}
<ScrollView contentContainerStyle={{
marginHorizontal: 15,
borderBottomWidth: 0.5,
borderLeftWidth: 0.5,
borderRightWidth: 0.5,
borderColor: 'gray',
borderBottomEndRadius: 10,
borderBottomLeftRadius: 10,
}}>
{/* <Text style={{ color: '#000', fontSize: 16, fontWeight: 'bold', marginBottom: 5 }}>OOS SKU details</Text> */}
{selectedCategoryData.map((item, idx) => (
<View
key={idx}
style={{
marginTop: 2,
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 8,
borderBottomWidth: idx === selectedCategoryData.length - 1 ? 0 : 1,
borderColor: '#eee',
}}
>
<View style={{ flexDirection: 'row' }}>
<Text style={{ color: '#000', marginLeft: 10 }}>{idx + 1}. </Text>
<Text style={{ color: '#000', }}>
{item.Product_MasterProduct_Name}
</Text>
</View>
{/* <Text style={{ color: '#000', width: '20%', textAlign: 'center' }}>
{item['#_of_OOS_SKU_for_all_visits']}
</Text> */}
</View>
))}
</ScrollView>
</View>
</Modal>
</View>
</SafeAreaView>
);
};
const styled = StyleSheet.create({
header: {
width: '100%',
backgroundColor: '#113F8C',
padding: 10,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
},
categoryHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: '#EDEDED',
paddingVertical: 8,
paddingHorizontal: 10,
borderTopLeftRadius: 8,
borderTopRightRadius: 8,
},
itemContainer: {
backgroundColor: '#fff',
paddingHorizontal: 10,
borderBottomLeftRadius: 8,
borderBottomRightRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
elevation: 2
}
})
export default Details;
+110 -1
View File
@@ -206,4 +206,113 @@
"GraphOptions": {}
}
]
}
},
{
"TabId": 3,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Compliance",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Compliance_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 3,
"GraphId": 3,
"GraphType": "Table",
"GraphTitle": "SOS Compliance - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/sos_sompliance_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 3,
"GraphId": 4,
"GraphType": "BarGraph",
"GraphTitle": "SOS Compliance Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/sos_compliance_trend_perc_mtd",
"GraphBackground": "#fff",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 1,
"gridLinesV": 1
}
},
{
"TabId": 3,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Compliance",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/sos_compliance_lsv_perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 3,
"GraphId": 3,
"GraphType": "Table",
"GraphTitle": "SOS Actual - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detlsv/sos_compliance_lsv_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 3,
"GraphId": 4,
"GraphType": "BarGraph",
"GraphTitle": "SOS Compliance Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/sos_compliance_trend_lsv_perc",
"GraphBackground": "#fff",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 1,
"gridLinesV": 1
}
},
+318 -346
View File
@@ -1,5 +1,5 @@
import { View, Text, StyleSheet, Image, TouchableOpacity, Dimensions, TextInput, ScrollView, FlatList, Button, Alert, Modal, TouchableWithoutFeedback, StatusBar, ActivityIndicator, Platform } from 'react-native'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { View, Text, Image, TouchableOpacity, Dimensions, TextInput, ScrollView, FlatList, Alert, Modal, ActivityIndicator, Platform } from 'react-native'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import RBSheet from 'react-native-raw-bottom-sheet';
import { styles } from './style';
import LinearGradient from 'react-native-linear-gradient';
@@ -10,12 +10,8 @@ import CustomDropdown from '../../../components/CustomDropdown';
import { GlobalTheme } from '../../../theme';
import { SafeAreaView } from 'react-native-safe-area-context';
import { BarChart } from 'react-native-gifted-charts';
import displayData from './display.json'
import { LineChart, PieChart, StackedBarChart } from 'react-native-chart-kit';
import { getDownloadJson } from '../../../constants/function';
import db, { getAllFromTable } from '../../../constants/database';
import { post } from '../../../api/ApiService';
import { PieChart } from 'react-native-chart-kit';
import db from '../../../constants/database';
import { ApiURL } from '../../../api/ApiConstant';
import mainDisplayData from './mainDisplay.json'
import axios from 'axios';
@@ -26,127 +22,114 @@ import moment from 'moment';
import _ from 'lodash';
import AsyncStorage from '@react-native-async-storage/async-storage';
// Latest code pushed
// const visitedStoreData = [
// {
// id: 1,
// name: "Chawla Store",
// address: "G-8, Mahakavi Goswami Tulsidas Marg, Paraag Vihar, Press Colony, Hari Nagar, New Delhi, 110027",
// status: "pending"
// },
// {
// id: 2,
// name: "Mohan Mahalaxmi store",
// address: "G-8, Mahakavi Goswami Tulsidas Marg, Paraag Vihar, Press Colony, Hari Nagar, New Delhi, 110027",
// status: "completed"
// },
// {
// id: 3,
// name: "Bansal General store",
// address: "G-8, Mahakavi Goswami Tulsidas Marg, Paraag Vihar, Press Colony, Hari Nagar, New Delhi, 110027",
// status: "completed"
// }
const visitedStoreData = [
{
id: 1,
name: "Chawla Store",
address: "G-8, Mahakavi Goswami Tulsidas Marg, Paraag Vihar, Press Colony, Hari Nagar, New Delhi, 110027",
status: "pending"
},
{
id: 2,
name: "Mohan Mahalaxmi store",
address: "G-8, Mahakavi Goswami Tulsidas Marg, Paraag Vihar, Press Colony, Hari Nagar, New Delhi, 110027",
status: "completed"
},
{
id: 3,
name: "Bansal General store",
address: "G-8, Mahakavi Goswami Tulsidas Marg, Paraag Vihar, Press Colony, Hari Nagar, New Delhi, 110027",
status: "completed"
}
// ];
];
const monthData = [
{ label: 'January', value: '1' },
{ label: 'February', value: '2' },
{ label: 'March', value: '3' },
{ label: 'April', value: '4' },
{ label: 'May', value: '5' },
{ label: 'June', value: '6' },
{ label: 'July', value: '7' },
{ label: 'August', value: '8' },
{ label: 'September', value: '9' },
{ label: 'October', value: '10' },
{ label: 'November', value: '11' },
{ label: 'December', value: '12' },
];
const yearData = [
{ label: '2025', value: '2025' },
{ label: '2024', value: '2024' },
{ label: '2023', value: '2023' },
{ label: '2022', value: '2022' },
{ label: '2021', value: '2021' },
{ label: '2020', value: '2020' },
{ label: '2019', value: '2019' },
{ label: '2018', value: '2018' },
{ label: '2017', value: '2017' },
{ label: '2016', value: '2016' },
{ label: '2015', value: '2015' },
];
const assetData = [
{
"section": "Asset%",
"data": [
{ "display": "Real Endcap", "present": "No" },
{ "display": "Honey Parasite", "present": "Yes" },
{ "display": "Odonil Floor Stack", "present": "YHes" }
]
},
{
"section": "Additional Visibility",
"data": [
{ "display": "Active 1 Ltr Endcap", "present": "Yes" },
{ "display": "Chyawanprash Stack", "present": "Yes" }
]
},
{
"section": "Promotion",
"data": [
{ "display": "Activ 100% Juice", "present": "Yes" },
{ "display": "Airfresher", "present": "No" },
{ "display": "BABY CARE", "present": "No" },
{ "display": "Chyawanprash", "present": "No" },
{ "display": "Hair Oil", "present": "No" },
]
}
]
const PieData = [
{
name: "Seoul",
population: 21500000,
color: "rgba(131, 167, 234, 1)",
legendFontColor: "#7F7F7F",
legendFontSize: 15
},
{
name: "Toronto",
population: 2800000,
color: "#F00",
legendFontColor: "#7F7F7F",
legendFontSize: 15
},
{
name: "Beijing",
population: 527612,
color: "red",
legendFontColor: "#7F7F7F",
legendFontSize: 15
},
{
name: "New York",
population: 8538000,
color: "#ffffff",
legendFontColor: "#7F7F7F",
legendFontSize: 15
},
{
name: "Moscow",
population: 11920000,
color: "rgb(0, 0, 255)",
legendFontColor: "#7F7F7F",
legendFontSize: 15
}
];
const barData = {
labels: ["Jan", "Feb", "March", "April",],
datasets: [
{
data: [20, 45, 28, 80]
}
]
};
// const yearData = [
// { label: '2025', value: '2025' },
// { label: '2024', value: '2024' },
// { label: '2023', value: '2023' },
// { label: '2022', value: '2022' },
// { label: '2021', value: '2021' },
// { label: '2020', value: '2020' },
// { label: '2019', value: '2019' },
// { label: '2018', value: '2018' },
// { label: '2017', value: '2017' },
// { label: '2016', value: '2016' },
// { label: '2015', value: '2015' },
// ];
// const assetData = [
// {
// "section": "Asset%",
// "data": [
// { "display": "Real Endcap", "present": "No" },
// { "display": "Honey Parasite", "present": "Yes" },
// { "display": "Odonil Floor Stack", "present": "YHes" }
// ]
// },
// {
// "section": "Additional Visibility",
// "data": [
// { "display": "Active 1 Ltr Endcap", "present": "Yes" },
// { "display": "Chyawanprash Stack", "present": "Yes" }
// ]
// },
// {
// "section": "Promotion",
// "data": [
// { "display": "Activ 100% Juice", "present": "Yes" },
// { "display": "Airfresher", "present": "No" },
// { "display": "BABY CARE", "present": "No" },
// { "display": "Chyawanprash", "present": "No" },
// { "display": "Hair Oil", "present": "No" },
// ]
// }
// ]
// const PieData = [
// {
// name: "Seoul",
// population: 21500000,
// color: "rgba(131, 167, 234, 1)",
// legendFontColor: "#7F7F7F",
// legendFontSize: 15
// },
// {
// name: "Toronto",
// population: 2800000,
// color: "#F00",
// legendFontColor: "#7F7F7F",
// legendFontSize: 15
// },
// {
// name: "Beijing",
// population: 527612,
// color: "red",
// legendFontColor: "#7F7F7F",
// legendFontSize: 15
// },
// {
// name: "New York",
// population: 8538000,
// color: "#ffffff",
// legendFontColor: "#7F7F7F",
// legendFontSize: 15
// },
// {
// name: "Moscow",
// population: 11920000,
// color: "rgb(0, 0, 255)",
// legendFontColor: "#7F7F7F",
// legendFontSize: 15
// }
// ];
// const barData = {
// labels: ["Jan", "Feb", "March", "April",],
// datasets: [
// {
// data: [20, 45, 28, 80]
// }
// ]
// };
const Dashboard = (props) => {
@@ -200,6 +183,7 @@ const Dashboard = (props) => {
let user_exist_data = useSelector(state => state?.user);
const userId = user_exist_data.UserId || '';
const onClickLogout = () => {
setLogoutModal(false);
Alert.alert(
@@ -231,12 +215,6 @@ const Dashboard = (props) => {
setTabCache({}); // reset cache when filters change
}, [month, year]);
// useEffect(() => {
// if (mainDisplayJson && storeData?.StoreId) {
// getTabData(mainDisplayJson);
// }
// }, [mainTabIndex, storeData]);
useEffect(() => {
if (mainDisplayJson && storeData?.StoreId) {
setTimeout(() => getTabData(mainDisplayJson), 0);
@@ -257,14 +235,9 @@ const Dashboard = (props) => {
return;
}
const escape = str => (str || '').toString().replace(/'/g, "''");
db.transaction(tx => {
data_arr.forEach(item => {
const { StoreId, StoreName, ChainName, Address, Pincode, StateName, StoreType, CityName } = item;
// First, check if the StoreId exists
tx.executeSql(
`SELECT * FROM StoreInfoDNALocal WHERE StoreId = ?`,
[StoreId],
@@ -275,8 +248,6 @@ const Dashboard = (props) => {
INSERT INTO StoreInfoDNALocal
(VISIT_DATE, StoreId, StoreName, ChainName, Address, Pincode, CityName, StateName, StoreType, UPLOAD_STATUS)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
tx.executeSql(sql, [
d2,
StoreId,
@@ -316,7 +287,7 @@ const Dashboard = (props) => {
[d2],
(tx, results) => {
console.log("results===", results);
// console.log("results===", results);
const rows = [];
for (let i = 0; i < results.rows.length; i++) {
rows.push(results.rows.item(i));
@@ -335,47 +306,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) => {
if (!storeData?.StoreId) return;
@@ -400,23 +330,8 @@ const Dashboard = (props) => {
console.log("🔁 API Params:", params);
const graphDetails = tabData?.graphDetails || [];
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 config = {
method: 'post',
@@ -430,15 +345,10 @@ const Dashboard = (props) => {
return await fetchWithRetry(config);
});
const results = await Promise.all(apiCalls);
console.log("📊 API Results:", results.map(r => r?.data));
const dataMap = {};
// uniqueUrls.forEach((url, idx) => {
// dataMap[url] = results[idx].data;
// });
uniqueUrls.forEach((url, idx) => {
const responseData = results[idx]?.data;
if (!responseData || !responseData.data || responseData.data.length === 0) {
@@ -447,7 +357,6 @@ const Dashboard = (props) => {
}
dataMap[url] = responseData;
});
console.log('uniqueUrls-dataMap---------->', dataMap);
setGraphApiData(dataMap);
setTabCache(prev => ({ ...prev, [tabKey]: dataMap }));
@@ -459,7 +368,6 @@ const Dashboard = (props) => {
}
};
const fetchWithRetry = async (config, retries = 2, delay = 1000) => {
for (let i = 0; i <= retries; i++) {
try {
@@ -477,31 +385,6 @@ const Dashboard = (props) => {
return null; // all attempts failed
};
const fetchDetailGraphs = async (detailPages) => {
try {
const resultMap = {};
for (let item of detailPages) {
const response = await post(item.GraphUrl, {
parameters: {
projectid: 41654,
year: year,
monthno: month,
storeid: storeData?.StoreId
},
});
console.log(`Data for ${item.GraphTitle}:`, response?.data); // Add this
resultMap[item.GraphUrl] = response?.data || [];
}
setModalGraphData(resultMap);
} catch (error) {
console.log("❌ Error fetching detail graphs:", error);
}
};
const handleScroll = (event) => {
const offsetY = event.nativeEvent.contentOffset.y;
setShowButton(offsetY > 0); // Show button only if not at the top
@@ -509,7 +392,7 @@ const Dashboard = (props) => {
const openBottomSheet = () => {
refRBSheet.current.open()
}
};
const onSelectStore = async (item) => {
await insertStoreInfoDNALocal([item]);
@@ -522,11 +405,11 @@ const Dashboard = (props) => {
getTabData(currentTab?.MainTabData);
refRBSheet.current.close()
}
};
const onSelectSubTab = (item) => {
setActiveTab(item?.TabId)
}
};
const getFilterStateCity = async () => {
try {
@@ -567,7 +450,7 @@ const Dashboard = (props) => {
console.log('state--', state, city);
console.log('searchText--', searchText);
setSearchResult(!searchResult)
// setSearchResult(!searchResult)
setLoading(true)
try {
const params = JSON.stringify({
@@ -577,6 +460,9 @@ const Dashboard = (props) => {
"StoreSearchText": searchText ? searchText : "",
"UserId": userId || 0,
});
console.log('params---->', params);
const config = {
method: 'post',
@@ -593,7 +479,7 @@ const Dashboard = (props) => {
setStoreList(resData)
setLoading(false)
console.log('storeSearchApi====>', JSON.stringify(resData));
// console.log('storeSearchApi====>', JSON.stringify(resData));
} catch (error) {
setLoading(false)
@@ -601,21 +487,47 @@ const Dashboard = (props) => {
}
};
const renderItem = ({ item }) => {
const apiData = graphApiData[item.GraphUrl];
// const values = apiData?.data || [];
const generateYears = (startYear = 2015) => {
const currentYear = new Date().getFullYear();
const totalYears = Math.max(currentYear - startYear + 1, 1);
return Array.from({ length: totalYears }, (_, i) => {
const year = currentYear - i;
return { label: `${year}`, value: `${year}` };
});
};
const monthData = [
{ label: 'January', value: '1' },
{ label: 'February', value: '2' },
{ label: 'March', value: '3' },
{ label: 'April', value: '4' },
{ label: 'May', value: '5' },
{ label: 'June', value: '6' },
{ label: 'July', value: '7' },
{ label: 'August', value: '8' },
{ label: 'September', value: '9' },
{ label: 'October', value: '10' },
{ label: 'November', value: '11' },
{ label: 'December', value: '12' },
];
const yearData = useMemo(() => generateYears(), []);
// console.log('yearData------>', yearData);
const renderItem = ({ item }) => {
// console.log('graphApiData--->', JSON.stringify(graphApiData));
const apiData = graphApiData[item.GraphUrl];
// console.log('apiData--->', JSON.stringify(apiData));
const values = apiData?.data?.length ? apiData.data : [];
// console.log('values--->', JSON.stringify(values));
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>
console.log('apiData --->', apiData);
if (apiData?.status === 'error') {
return (
<View style={styles.percentBox}>
@@ -625,15 +537,6 @@ const Dashboard = (props) => {
);
}
// if (!apiData) {
// return (
// <View style={[styles.percentBox, { justifyContent: 'center', alignItems: 'center' }]}>
// <ActivityIndicator size="small" color="#113F8C" />
// </View>
// );
// }
switch (item.GraphType) {
case "ScoreCard":
const firstDataObj = values[0] || {};
@@ -649,19 +552,109 @@ const Dashboard = (props) => {
);
//GIFTED CHART LIBRARY -----
// case "BarGraph":
// const chartWidth = screenWidth * 0.80;
// const barWidth = 40;
// const barColors = ['#1BF2E0', '#1B7BF2', '#1BC0F2'];
// console.log('BarGraph-valuesvalues=> ', values);
// const barData = values.map((v, idx) => {
// const value = parseFloat(Object.values(v).find(val => typeof val === 'number').toFixed(1));
// return {
// value,
// label: v.CalendarYear_Month,
// frontColor: barColors[idx % barColors.length],
// topLabelComponent: () => (
// <Text style={{ color: '#000', fontSize: 12, fontWeight: '500', marginBottom: 5 }}>{value}%</Text>
// )
// };
// });
// const visibleBars = barData.length;
// const totalSpacing = chartWidth - visibleBars * barWidth;
// const spacing = totalSpacing / (visibleBars + 1);
// if (!values || values == '' || values == undefined || values == null) {
// return null;
// }
// return (
// <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 }}> */}
// <Text style={{ color: '#000', fontSize: 16, fontWeight: '600', marginBottom: 10 }}>
// {item.GraphTitle}
// </Text>
// <BarChart
// data={barData}
// barWidth={barWidth}
// spacing={spacing}
// noOfSections={6}
// maxValue={105}
// roundedTop={false}
// disableScroll={true}
// yAxisLabelTexts={['0%', '20%', '40%', '60%', '80%', '100%']}
// // yAxisLabelTexts={['0%', '👉', '👉', '👉', '👉', '100%']} // 👈 only 0% and 100%
// yAxisTextStyle={{ color: '#000', fontSize: 12 }}
// xAxisLabelTextStyle={{ color: '#000', fontSize: 12, fontWeight: '500', marginTop: 5 }}
// isAnimated
// width={chartWidth}
// hideYAxisText={true} //to hide y axis text
// // hideRules={true}
// hideYAxisLine={true}
// yAxisThickness={0}
// xAxisThickness={0}
// rulesLength={chartWidth}
// // xAxisLength={chartWidth}
// hideAxesAndRules={false}
// // xAxisLabelTextStyle={{ color: '#000', fontSize: 10, marginTop: 4 }}
// />
// {/* </View> */}
// <View style={{ height: 10, }} />
// </View>
// );
case "BarGraph":
const chartWidth = screenWidth * 0.75;
const chartWidth = screenWidth * 0.80;
const barWidth = 40;
const barColors = ['#1BF2E0', '#1B7BF2', '#1BC0F2'];
// Sample API response (youll replace this with real API data)
let values2 = [
{ "Month_Id": 91, "CalendarYear_Month": "Jul-25", "Share_of_Shelf_Perc": 40.44959 },
{ "Month_Id": 92, "CalendarYear_Month": "Aug-25", "Share_of_Shelf_Perc": 44.60024 },
{ "Month_Id": 90, "CalendarYear_Month": "Jun-25", "Share_of_Shelf_Perc": 47.94166 },
];
// console.log('BarGraph-values2values2=> ', JSON.stringify(values2));
console.log('BarGraph-values=> ', JSON.stringify(values));
if (!values2 || values2 == '' || values2 == undefined || values2 == null) {
return null;
}
// ✅ Step 1: Sort by Month_Id
const sortedValues = values2.sort((a, b) => a.CalendarMonth_ID - b.Month_Id);
// console.log('sortedValues====>',JSON.stringify(sortedValues));
// ✅ Step 2: Prepare chart data
const barData = values.map((v, idx) => {
const value = parseFloat(Object.values(v).find(val => typeof val === 'number').toFixed(1));
// Find the first numeric field dynamically (excluding Month_Id)
const numericKey = Object.keys(v).find(
key => key !== "CalendarMonth_ID" && key !== "CalendarYear_Month" && typeof v[key] === "number"
);
const value = numericKey ? parseFloat(v[numericKey].toFixed(1)) : 0;
return {
value,
label: v.CalendarYear_Month,
frontColor: barColors[idx % barColors.length],
topLabelComponent: () => (
<Text style={{ color: '#000', fontSize: 12, fontWeight: '500', marginBottom: 5 }}>{value}%</Text>
<Text style={{ color: '#000', fontSize: 12, fontWeight: '500', marginBottom: 5 }}>
{value}%
</Text>
)
};
});
@@ -670,59 +663,38 @@ const Dashboard = (props) => {
const totalSpacing = chartWidth - visibleBars * barWidth;
const spacing = totalSpacing / (visibleBars + 1);
if (!values || values == '' || values == undefined || values == null) {
return null;
}
return (
<View style={{ alignItems: 'center', justifyContent: 'center', padding: 10, borderWidth: 0.5, borderRadius: 10, }}>
{/* <View style={{ alignSelf: 'center', borderWidth: 0.5,borderRadius:20, paddingBottom: 10 }}> */}
<Text style={{ fontSize: 16, fontWeight: '600', marginBottom: 10 }}>
{item.GraphTitle}
</Text>
<View style={styles.barGraphView}>
<Text style={styles.trendTitle}>{item.GraphTitle}</Text>
<BarChart
data={barData}
barWidth={barWidth}
spacing={spacing}
noOfSections={5}
noOfSections={6}
maxValue={105}
roundedTop={false}
disableScroll={true}
yAxisLabelTexts={['0%', '20%', '40%', '60%', '80%', '100%']}
// yAxisLabelTexts={['0%', '👉', '👉', '👉', '👉', '100%']} // 👈 only 0% and 100%
yAxisTextStyle={{ color: '#000', fontSize: 12 }}
xAxisLabelTextStyle={{ color: '#000', fontSize: 12, fontWeight: '500', marginTop: 5 }}
xAxisLabelTextStyle={{ color: '#000', fontSize: 12, fontWeight: '500', }}
isAnimated
width={chartWidth}
hideYAxisText={true} //to hide y axis text
// hideRules={true}
hideYAxisText={true}
hideYAxisLine={true}
yAxisThickness={0}
xAxisThickness={0}
rulesLength={chartWidth}
// xAxisLength={chartWidth}
hideAxesAndRules={false}
// backgroundColor={'red'}
// backgroundColor={'yellow'}
// xAxisLabelTextStyle={{ color: '#000', fontSize: 10, marginTop: 4 }}
/>
{/* </View> */}
<View style={{ height: 10 }} />
</View>
);
case "Table":
return (
<View style={{ flex: 1 }}>
<ScrollView>
<Text style={{ fontSize: 16, fontWeight: '600', marginBottom: 10 }}>{item.GraphTitle}</Text>
<Text style={{ color: '#000', fontSize: 16, fontWeight: '600', marginBottom: 10 }}>{item.GraphTitle}</Text>
{values.map((row, index) => {
const keys = Object.keys(row);
return (
@@ -743,7 +715,7 @@ const Dashboard = (props) => {
</View>
);
// case "PieChart":
case "PieChart":
const pieChartData = values.map((item, idx) => {
const [labelKey, valueKey] = Object.keys(item);
return {
@@ -800,7 +772,6 @@ const Dashboard = (props) => {
}, 300), []);
const feedbackCount = visitedStoreData1?.filter(item => item?.UPLOAD_STATUS == 'U')?.length;
const filteredStores = storeList.filter((store) => {
const query = searchQuery.toLowerCase();
return (
@@ -868,16 +839,19 @@ const Dashboard = (props) => {
disabled={store?.UPLOAD_STATUS == 'U' ? true : false}
onPress={() => onSelectStore(store)}
key={store.StoreId} style={styles.storeCard}>
<View style={[styles.row, { margin: 0 }]}>
<Text style={styles.cardTextBold}>{store.StoreName}</Text>
<View style={[styles.row, { margin: 0, width: "100%" }]}>
<View style={{ width: "70%" }}>
<Text style={styles.cardTextBold}>{store.StoreName}</Text>
</View>
{store?.UPLOAD_STATUS === 'U' ?
<Image source={IMAGES.greenTick} style={{ height: 20, width: 20 }} />
:
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<View style={{ backgroundColor: '#FFF8CD', padding: 5, paddingHorizontal: 7, borderRadius: 15 }}>
<Text style={{ color: 'orange', fontSize: 13, fontWeight: '500' }}>Pending</Text>
<View style={{ width: "30%", flexDirection: 'row', alignItems: 'center' }}>
<View style={{ flexDirection: 'row', backgroundColor: '#ffefd5', padding: 5, paddingHorizontal: 10, borderRadius: 15 }}>
<Text style={{ color: 'orange', fontSize: 12, fontWeight: '500' }}>Feedback Pending</Text>
{/* <Image source={IMAGES.pending} style={{ marginLeft: 5, height: 18, width: 18, tintColor: 'orange' }} /> */}
</View>
<Image source={IMAGES.rightArrowIcon} style={{ marginLeft: 10, height: 20, width: 20, resizeMode: 'contain', tintColor: '#97ADD6' }} />
<Image source={IMAGES.rightArrowIcon} style={{ marginLeft: -2, height: 20, width: 20, resizeMode: 'contain', tintColor: '#97ADD6' }} />
</View>
}
</View>
@@ -904,14 +878,13 @@ const Dashboard = (props) => {
onRightPress={() => setFeedBackModal(true)}
/>
{/* Store Name Card */}
<View style={styles.row}>
<View style={styles.selectedStoreText}>
{/* <Text style={[styles.storeNameText, { width: '90%' }]}> {`${storeData?.StoreName} \n(Store Id :${storeData?.StoreId})`}</Text> */}
<View style={{ width: '90%' }}>
<View style={{ width: '88%' }}>
<Text style={[styles.storeNameText, {}]}>{storeData?.StoreName}</Text>
<Text style={{ color: GlobalTheme.colors.gray, fontSize: 13 }}>Store Id : {storeData?.StoreId}</Text>
</View>
<Text style={{}}></Text>
<TouchableOpacity onPress={() => openBottomSheet()} style={styles.filterIcon}>
<Image source={IMAGES.filterIcon} style={{ height: 18, width: 18 }} />
</TouchableOpacity>
@@ -960,7 +933,6 @@ const Dashboard = (props) => {
<View style={styles.seperator} />
{/* Main Tab */}
<View style={{ flexDirection: 'row' }}>
{mainTabs.map((tab, index) => {
const isSelected = index === mainTabIndex;
@@ -1014,29 +986,31 @@ const Dashboard = (props) => {
{/* Score Card */}
<View style={{ margin: 5 }}>
<View style={{ marginHorizontal: 5 }}>
<View style={{ marginHorizontal: 5, marginTop: 5 }}>
{firstItem && (
<TouchableOpacity
activeOpacity={0.8}
// onPress={() => {
// if (firstItem.clickable === 1 && firstItem.DetailsPage?.length > 0) {
// setSelectedDetails(firstItem.DetailsPage);
// setShowDetailsModal(true);
// fetchDetailGraphs(firstItem.DetailsPage);
// }
// }}
onPress={() => {
if (firstItem.clickable === 1 && firstItem.DetailsPage?.length > 0) {
setSelectedDetails(firstItem.DetailsPage);
setShowDetailsModal(true);
fetchDetailGraphs(firstItem.DetailsPage);
navigation.navigate('Details', {
selectedDetails: firstItem.DetailsPage,
storeData,
year,
month,
mainTabIndex
});
}
}}
>
<View
style={[
styles.percentBox,
{
backgroundColor: "#C3D7FF",
width: '100%',
elevation: 0,
},
]}
>
<View style={{ width: '48%', height: 100, minHeight: 100, borderRadius: 20, justifyContent: 'center', alignItems: 'center', backgroundColor: "#C3D7FF", width: '100%', elevation: 0, }} >
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<View style={{ width: '80%', alignItems: 'center' }}>
<Text style={styles.boxText}>{firstItem.GraphTitle}</Text>
@@ -1286,7 +1260,7 @@ const Dashboard = (props) => {
<View style={[styles.row, {}]}>
<Text style={styles.dropHeaderText}>State</Text>
<Text style={styles.dropHeaderText}> City</Text>
<Text style={styles.dropHeaderText}> ASM Area</Text>
{/* <Text style={styles.dropHeaderText}> ASM Area</Text> */}
</View>
{/* Dropdown */}
@@ -1340,9 +1314,9 @@ const Dashboard = (props) => {
const uniqueAsms = Array.from(new Map(asms.map(a => [a.value, a])).values());
setCityOptions(uniqueCities);
setAsmOptions(uniqueAsms);
// setAsmOptions(uniqueAsms);
setCity(null); // reset
setAsmArea(null); // reset
// setAsmArea(null); // reset
}}
containerStyle={{ flex: 1 }}
/>
@@ -1356,12 +1330,12 @@ const Dashboard = (props) => {
/>
{/* ASM Area Dropdown */}
<CustomDropdown
{/* <CustomDropdown
data={asmOptions}
value={asmArea}
onChange={(item) => setAsmArea(item.value)}
containerStyle={{ flex: 1 }}
/>
/> */}
</View>
@@ -1382,38 +1356,38 @@ const Dashboard = (props) => {
textstyle={{ color: GlobalTheme.colors.white, fontSize: GlobalTheme.typography.fontSize.medium }}
/>
</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>
: 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>
@@ -1436,5 +1410,3 @@ const Dashboard = (props) => {
}
export default Dashboard
@@ -0,0 +1,631 @@
{
"Tabs": [
{
"MainTabId": 1,
"MainTabName": "MTD",
"MainTabData": {
"subTabs": [
{
"TabId": 1,
"TabName": "PSS Score",
"TabRow": 1,
"TabCol": 1
},
{
"TabId": 2,
"TabName": "PSS Trend",
"TabRow": 1,
"TabCol": 2
},
{
"TabId": 3,
"TabName": "SOS Actual",
"TabRow": 1,
"TabCol": 2
},
{
"TabId": 4,
"TabName": "OSA",
"TabRow": 1,
"TabCol": 4
},
{
"TabId": 5,
"TabName": "Asset",
"TabRow": 1,
"TabCol": 5
},
{
"TabId": 6,
"TabName": "Promotion",
"TabRow": 1,
"TabCol": 6
}
],
"graphDetails": [
{
"TabId": 1,
"GraphId": 1,
"GraphType": "ScoreCard",
"GraphTitle": "PSS Score",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/pssscore",
"GraphBackground": "#C3D7FF",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 2,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Actual",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Actual_Perc",
"GraphBackground": "#E2C8FE",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 4,
"GraphType": "ScoreCard",
"GraphTitle": "OSA",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/OSA_Perc",
"GraphBackground": "#FFF9A1",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 5,
"GraphType": "ScoreCard",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/Asset_Perc",
"GraphBackground": "#A2F3DE",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 6,
"GraphType": "ScoreCard",
"GraphTitle": "Promotion",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/Promotion_Perc",
"GraphBackground": "#BFC2FF",
"GraphOptions": {}
},
{
"TabId": 2,
"GraphId": 1,
"GraphType": "ScoreCard",
"GraphTitle": "PSS Score",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Actual_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 0,
"DetailsPage": [
{
"TabId": 2,
"GraphId": 1,
"GraphType": "Table",
"GraphTitle": "PSS - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/sos_actual_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 2,
"GraphId": 2,
"GraphType": "BarGraph",
"GraphTitle": "PSS Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/sos_actual_trend_perc_mtd",
"GraphBackground": "#F4EAFF",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 0,
"gridLinesV": 0
}
},
{
"TabId": 3,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Actual",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Actual_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 2,
"GraphId": 1,
"GraphType": "Table",
"GraphTitle": "SOS - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/sos_actual_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 3,
"GraphId": 4,
"GraphType": "BarGraph",
"GraphTitle": "SOS Actual Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/sos_actual_trend_perc_mtd",
"GraphBackground": "#F4EAFF",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 0,
"gridLinesV": 0
}
},
{
"TabId": 4,
"GraphId": 5,
"GraphType": "ScoreCard",
"GraphTitle": "OSA",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/OSA_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 3,
"GraphId": 3,
"GraphType": "Table",
"GraphTitle": "OSA - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/osa_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 4,
"GraphId": 6,
"GraphType": "BarGraph",
"GraphTitle": "OSA",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/osa_trend_perc_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 7,
"GraphType": "ScoreCard",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/Asset_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/asset_availability_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Additional Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/additional_visibility_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 5,
"GraphId": 8,
"GraphType": "BarGraph",
"GraphTitle": "Asset Details",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/asset_trend_perc_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 6,
"GraphId": 9,
"GraphType": "ScoreCard",
"GraphTitle": "Promotion",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/Promotion_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 6,
"GraphId": 9,
"GraphType": "Table",
"GraphTitle": "Promotion Not Executed",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/promotion_not_executed_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 6,
"GraphId": 10,
"GraphType": "Table",
"GraphTitle": "Promotion executed",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/promotion_executed_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 6,
"GraphId": 11,
"GraphType": "BarGraph",
"GraphTitle": "Promotion",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/promotion_trend_perc_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
}
},
{
"MainTabId": 2,
"MainTabName": "Last Visit",
"MainTabData": {
"subTabs": [
{
"TabId": 1,
"TabName": "PSS Score",
"TabRow": 1,
"TabCol": 1
},
{
"TabId": 2,
"TabName": "SOS Actual",
"TabRow": 1,
"TabCol": 2
},
{
"TabId": 4,
"TabName": "OSA",
"TabRow": 1,
"TabCol": 4
},
{
"TabId": 5,
"TabName": "Asset",
"TabRow": 1,
"TabCol": 5
},
{
"TabId": 6,
"TabName": "Promotion",
"TabRow": 1,
"TabCol": 6
}
],
"graphDetails": [
{
"TabId": 1,
"GraphId": 1,
"GraphType": "ScoreCard",
"GraphTitle": "PSS Score",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/PSS_Score_LSV_Perc",
"GraphBackground": "#E2C8FE",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 2,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Actual",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/sos_actual_lsv_perc",
"GraphBackground": "#E2C8FE",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 4,
"GraphType": "ScoreCard",
"GraphTitle": "OSA",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/osa_lsv_perc",
"GraphBackground": "#FFF9A1",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 5,
"GraphType": "ScoreCard",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/asset_lsv_perc",
"GraphBackground": "#A2F3DE",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 6,
"GraphType": "ScoreCard",
"GraphTitle": "Promotion",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/promotion_lsv_perc",
"GraphBackground": "#BFC2FF",
"GraphOptions": {}
},
{
"TabId": 2,
"GraphId": 1,
"GraphType": "ScoreCard",
"GraphTitle": "PSS Score",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Actual_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 0,
"DetailsPage": [
{
"TabId": 2,
"GraphId": 1,
"GraphType": "Table",
"GraphTitle": "PSS - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/sos_actual_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 2,
"GraphId": 2,
"GraphType": "BarGraph",
"GraphTitle": "PSS Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/sos_actual_trend_perc_mtd",
"GraphBackground": "#F4EAFF",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 0,
"gridLinesV": 0
}
},
{
"TabId": 3,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Actual",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/sos_actual_lsv_perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 2,
"GraphId": 1,
"GraphType": "Table",
"GraphTitle": "SOS Actual - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detlsv/sos_actual_lsv_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 3,
"GraphId": 4,
"GraphType": "BarGraph",
"GraphTitle": "SOS Actual Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/sos_actual_trend_lsv_perc",
"GraphBackground": "#F4EAFF",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 1,
"gridLinesV": 1
}
},
{
"TabId": 4,
"GraphId": 5,
"GraphType": "ScoreCard",
"GraphTitle": "OSA",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/osa_lsv_perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 4,
"GraphId": 7,
"GraphType": "Table",
"GraphTitle": "OSA - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detlsv/osa_lsv_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 4,
"GraphId": 6,
"GraphType": "BarGraph",
"GraphTitle": "OSA Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/osa_trend_lsv_perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 7,
"GraphType": "ScoreCard",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/asset_lsv_perc",
"GraphBa ckground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/asset_availability_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Additional Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/additional_visibility_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 5,
"GraphId": 8,
"GraphType": "BarGraph",
"GraphTitle": "Asset Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/asset_trend_lsv_perc",
"GraphBackground": "#fff",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 1,
"gridLinesV": 1
}
},
{
"TabId": 6,
"GraphId": 9,
"GraphType": "ScoreCard",
"GraphTitle": "Promotion",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/promotion_lsv_perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 6,
"GraphId": 9,
"GraphType": "Table",
"GraphTitle": "Promotion Not Executed",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detlsv/promotion_not_executed_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 6,
"GraphId": 10,
"GraphType": "Table",
"GraphTitle": "Promotion executed",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detlsv/promotion_executed_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 6,
"GraphId": 11,
"GraphType": "BarGraph",
"GraphTitle": "Promotion",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/promotion_trend_lsv_perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
}
}
]
}
+282 -221
View File
@@ -13,15 +13,15 @@
},
{
"TabId": 2,
"TabName": "SOS Actual",
"TabName": "PSS Trend",
"TabRow": 1,
"TabCol": 2
},
{
"TabId": 3,
"TabName": "SOS Compliance",
"TabName": "SOS Actual",
"TabRow": 1,
"TabCol": 3
"TabCol": 2
},
{
"TabId": 4,
@@ -42,6 +42,9 @@
"TabCol": 6
}
],
"graphDetails": [
{
"TabId": 1,
@@ -61,15 +64,6 @@
"GraphBackground": "#E2C8FE",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Compliance",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Compliance_Perc",
"GraphBackground": "#FFD7C3",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 4,
@@ -97,10 +91,62 @@
"GraphBackground": "#BFC2FF",
"GraphOptions": {}
},
{
"TabId": 2,
"GraphId": 1,
"GraphType": "ScoreCard",
"GraphTitle": "PSS Score",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/pssscore",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 0,
"DetailsPage": [
{
"TabId": 2,
"GraphId": 1,
"GraphType": "Table",
"GraphTitle": "PSS - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/sos_actual_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 2,
"GraphId": 2,
"GraphType": "BarGraph",
"GraphTitle": "PSS Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/pss_trend_perc_mtd_O",
"GraphBackground": "#F4EAFF",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 0,
"gridLinesV": 0
}
},
{
"TabId": 3,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Actual",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Actual_Perc",
"GraphBackground": "#ECFFFA",
@@ -119,11 +165,11 @@
]
},
{
"TabId": 2,
"GraphId": 2,
"TabId": 3,
"GraphId": 4,
"GraphType": "BarGraph",
"GraphTitle": "SOS Actual Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/sos_actual_trend_perc_mtd",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/sos_actual_trend_perc_mtd_O",
"GraphBackground": "#F4EAFF",
"GraphOptions": {
"axisX": "month",
@@ -138,89 +184,14 @@
"gridLinesV": 0
}
},
{
"TabId": 3,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Compliance",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/SOS_Compliance_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 3,
"GraphId": 3,
"GraphType": "Table",
"GraphTitle": "SOS Compliance - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/sos_sompliance_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 3,
"GraphId": 4,
"GraphType": "BarGraph",
"GraphTitle": "SOS Compliance Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/sos_compliance_trend_perc_mtd",
"GraphBackground": "#fff",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 1,
"gridLinesV": 1
}
},
{
"TabId": 5,
"GraphId": 5,
"GraphType": "ScoreCard",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/Asset_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Asset Availability",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/asset_availability_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/additional_visibility_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 5,
"GraphId": 6,
"GraphType": "BarGraph",
"GraphTitle": "Asset Details",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/asset_trend_perc_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
{
"TabId": 4,
"GraphId": 7,
"GraphId": 5,
"GraphType": "ScoreCard",
"GraphTitle": "OSA",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/OSA_Perc",
@@ -232,7 +203,7 @@
"TabId": 3,
"GraphId": 3,
"GraphType": "Table",
"GraphTitle": "SOS Compliance - Category",
"GraphTitle": "OSA - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/osa_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
@@ -241,13 +212,57 @@
},
{
"TabId": 4,
"GraphId": 8,
"GraphId": 6,
"GraphType": "BarGraph",
"GraphTitle": "OSA",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/osa_trend_perc_mtd",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/osa_trend_perc_mtd_O",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 7,
"GraphType": "ScoreCard",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/mtd/Asset_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/asset_availability_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Additional Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/additional_visibility_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 5,
"GraphId": 8,
"GraphType": "BarGraph",
"GraphTitle": "Asset Details",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/asset_trend_perc_mtd_O",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 6,
"GraphId": 9,
@@ -262,25 +277,51 @@
"TabId": 6,
"GraphId": 9,
"GraphType": "Table",
"GraphTitle": "Promotion Availability",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/promotion_availability_mtd",
"GraphTitle": "Promotion Not Executed",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/promotion_not_executed_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 6,
"GraphId": 10,
"GraphType": "Table",
"GraphTitle": "Promotion executed",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/promotion_executed_mtd",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 6,
"GraphId": 10,
"GraphId": 11,
"GraphType": "BarGraph",
"GraphTitle": "Promotion",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/promotion_trend_perc_mtd",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpimtd/promotion_trend_perc_mtd_O",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
}
},
{
"MainTabId": 2,
"MainTabName": "Last Visit",
@@ -292,17 +333,18 @@
"TabRow": 1,
"TabCol": 1
},
{
{
"TabId": 2,
"TabName": "SOS Actual",
"TabName": "PSS Trend",
"TabRow": 1,
"TabCol": 2
},
{
"TabId": 3,
"TabName": "SOS Compliance",
"TabName": "SOS Actual",
"TabRow": 1,
"TabCol": 3
"TabCol": 2
},
{
"TabId": 4,
@@ -342,15 +384,6 @@
"GraphBackground": "#E2C8FE",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Compliance",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/sos_compliance_lsv_perc",
"GraphBackground": "#FFD7C3",
"GraphOptions": {}
},
{
"TabId": 1,
"GraphId": 4,
@@ -378,10 +411,63 @@
"GraphBackground": "#BFC2FF",
"GraphOptions": {}
},
{
{
"TabId": 2,
"GraphId": 1,
"GraphType": "ScoreCard",
"GraphTitle": "PSS Score",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/PSS_Score_LSV_Perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 0,
"DetailsPage": [
{
"TabId": 2,
"GraphId": 1,
"GraphType": "Table",
"GraphTitle": "PSS - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detmtd/sos_actual_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 2,
"GraphId": 2,
"GraphType": "BarGraph",
"GraphTitle": "PSS Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/pss_trend_perc_lsv_O",
"GraphBackground": "#F4EAFF",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 0,
"gridLinesV": 0
}
},
{
"TabId": 3,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Actual",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/sos_actual_lsv_perc",
"GraphBackground": "#ECFFFA",
@@ -400,11 +486,11 @@
]
},
{
"TabId": 2,
"GraphId": 2,
"TabId": 3,
"GraphId": 4,
"GraphType": "BarGraph",
"GraphTitle": "SOS Actual Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/sos_actual_trend_lsv_perc",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/sos_actual_trend_lsv_perc_O",
"GraphBackground": "#F4EAFF",
"GraphOptions": {
"axisX": "month",
@@ -419,100 +505,14 @@
"gridLinesV": 1
}
},
{
"TabId": 3,
"GraphId": 3,
"GraphType": "ScoreCard",
"GraphTitle": "SOS Compliance",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/sos_compliance_lsv_perc",
"GraphBackground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 3,
"GraphId": 3,
"GraphType": "Table",
"GraphTitle": "SOS Actual - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detlsv/sos_compliance_lsv_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 3,
"GraphId": 4,
"GraphType": "BarGraph",
"GraphTitle": "SOS Compliance Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/sos_compliance_trend_lsv_perc",
"GraphBackground": "#fff",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 1,
"gridLinesV": 1
}
},
{
"TabId": 5,
"GraphId": 5,
"GraphType": "ScoreCard",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/asset_lsv_perc",
"GraphBa ckground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Asset Availability",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/asset_availability_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/additional_visibility_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 5,
"GraphId": 6,
"GraphType": "BarGraph",
"GraphTitle": "Asset Details",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/asset_trend_lsv_perc",
"GraphBackground": "#fff",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 1,
"gridLinesV": 1
}
},
{
"TabId": 4,
"GraphId": 7,
"GraphId": 5,
"GraphType": "ScoreCard",
"GraphTitle": "OSA",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/osa_lsv_perc",
@@ -524,7 +524,7 @@
"TabId": 4,
"GraphId": 7,
"GraphType": "Table",
"GraphTitle": "SOS Actual - Category",
"GraphTitle": "OSA - Category",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detlsv/osa_lsv_perc_on_category",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
@@ -533,13 +533,65 @@
},
{
"TabId": 4,
"GraphId": 8,
"GraphId": 6,
"GraphType": "BarGraph",
"GraphTitle": "OSA",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/osa_trend_lsv_perc",
"GraphTitle": "OSA Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/osa_trend_lsv_perc_O",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 7,
"GraphType": "ScoreCard",
"GraphTitle": "Asset",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/lsv/asset_lsv_perc",
"GraphBa ckground": "#ECFFFA",
"GraphOptions": {},
"clickable": 1,
"DetailsPage": [
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/asset_availability_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 5,
"GraphId": 5,
"GraphType": "Table",
"GraphTitle": "Additional Visibility",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/additional_visibility_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
]
},
{
"TabId": 5,
"GraphId": 8,
"GraphType": "BarGraph",
"GraphTitle": "Asset Trend",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/asset_trend_lsv_perc_O",
"GraphBackground": "#fff",
"GraphOptions": {
"axisX": "month",
"axisY": "score",
"labelShow": 1,
"barColors": [
"#11a4ff",
"#0ea3e3",
"#0b9ddb"
],
"gridLinesH": 1,
"gridLinesV": 1
}
},
{
"TabId": 6,
"GraphId": 9,
@@ -554,8 +606,17 @@
"TabId": 6,
"GraphId": 9,
"GraphType": "Table",
"GraphTitle": "Promotion Availability",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/promotion_availability_lsv",
"GraphTitle": "Promotion Not Executed",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detlsv/promotion_not_executed_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
},
{
"TabId": 6,
"GraphId": 10,
"GraphType": "Table",
"GraphTitle": "Promotion executed",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/detlsv/promotion_executed_lsv",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
@@ -563,10 +624,10 @@
},
{
"TabId": 6,
"GraphId": 10,
"GraphId": 11,
"GraphType": "BarGraph",
"GraphTitle": "Promotion",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/promotion_trend_lsv_perc",
"GraphUrl": "https://dax.parinaam.in/execute/dabur/kpilsv/promotion_trend_lsv_perc_O",
"GraphBackground": "#ECFFFA",
"GraphOptions": {}
}
+29 -4
View File
@@ -146,7 +146,7 @@ export const styles = StyleSheet.create({
fontWeight: '400'
},
dropHeaderText: {
width: '33%',
width: '50%',
color: '#000',
fontWeight: '400',
fontSize: 14
@@ -202,7 +202,7 @@ export const styles = StyleSheet.create({
},
filterIcon: {
backgroundColor: '#D8E3F1',
padding: 3,
padding: 5,
borderRadius: 5
},
storeInfoText: {
@@ -217,9 +217,20 @@ export const styles = StyleSheet.create({
minHeight: 100,
backgroundColor: '#EAF1FF',
borderRadius: 20,
elevation: 2,
justifyContent: '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: {
color: '#000',
@@ -352,5 +363,19 @@ export const styles = StyleSheet.create({
marginTop: 10,
marginBottom: 10,
}
},
barGraphView: {
width: '100%',
alignItems: 'center',
justifyContent: 'center',
padding: 10,
borderWidth: 0.5,
borderRadius: 25,
},
trendTitle: {
color: '#000',
fontSize: 16,
fontWeight: '600',
marginBottom: 10
},
});
File diff suppressed because it is too large Load Diff
+567 -319
View File
@@ -1,319 +1,567 @@
import React, { useState, useRef, useEffect } from 'react';
import { View, Text, TouchableOpacity, ScrollView, FlatList } from 'react-native';
import { styles } from './style';
import GlobalTheme, { horizonalLine, Screen } from '../../../theme/theme';
import CustomHeader from '../../../components/CustomHeader';
import IMAGES from '../../../constants/Images';
import axios from 'axios';
import Loader from '../../../constants/Loader';
import { SafeAreaView } from 'react-native-safe-area-context';
const storeinfodata = [
{
tabId: 0,
section: 'Store details',
items: [
{ brand: 'Store Name', name: 'Reliance Smart' },
{ brand: 'Store ID', name: '#98440' },
{ brand: 'Address', name: 'Rabindra Nagar, Delhi 110003' },
{ brand: 'City', name: 'Okhla' },
{ brand: 'Store Size', name: '15002000 sq ft' },
{ brand: 'Average Footfall', name: '10000' },
{ brand: 'Store age', name: '8' },
{ brand: 'Store Ranking', name: '24' },
],
},
{
tabId: 0,
section: 'Dabur Employees',
items: [
{ brand: 'RKAM', name: 'Rajesh Paal Singh' },
{ brand: 'SO', name: 'Soniya Singhal' },
],
},
{
tabId: 0,
section: '3P employees',
items: [
{ brand: 'Promoter Name', name: 'Payal Singh' },
{ brand: 'AM Name', name: 'Soniya Singhal' },
{ brand: 'Supervisor Name', name: 'Soniya Dhankar' },
{ brand: 'City', name: 'Okhla' },
{ brand: 'Promoter duration', name: '2 Year 7 months' },
{ brand: 'Average incentive', name: '5000' },
],
},
// Last Visit Details (tabId: 1)
{
tabId: 1,
section: 'Dabur employee',
items: [
{ brand: 'SO', name: 'Rajesh Paal Singh', date: '23/05/2025', test: 'gxsjhxbas' },
{ brand: 'AH', name: 'Umesh Singh', date: '18/04/2025' },
{ brand: 'KAM', name: 'Rahul Tawde', date: '15/05/2025' },
{ brand: 'Others', name: 'Singhal Singh', date: '06/05/2025' },
],
},
{
tabId: 1,
section: '3P team',
items: [
{ brand: 'Supervisor', name: 'Ashish Talwar', date: '27/05/2025' },
{ brand: 'AM', name: 'Soniya Singhal', date: '23/05/2025' },
],
},
// Competition (tabId: 2)
{
tabId: 2,
section: 'Competition assets',
items: [
{ brand: 'Marico', value: 5 },
{ brand: 'Colgate', value: 1 },
{ brand: 'Godrej', value: 2 },
{ brand: 'HUL', value: 1 },
{ brand: 'XX', value: 2 },
],
},
{
tabId: 2,
section: 'Promoter details',
items: [
{ brand: 'Marico', value: 1 },
{ brand: 'Colgate', value: 1 },
{ brand: 'Godrej', value: 1 },
{ brand: 'HUL', value: 1 },
{ brand: 'XX', value: 0 },
],
},
];
const tabs = [
{ id: 0, title: 'Store Info' },
{ id: 1, title: 'Last visit details' },
{ id: 2, title: 'Competition' },
];
const RenderHeader = ({ columns }) => {
const colWidth = Screen.screenWidth * 0.95 / columns?.length;
return (
null
// <View style={{ flexDirection: 'row', paddingVertical: 6 }}>
// {columns.map((col, index) => (
// <View key={index} style={{ width: colWidth }}>
// <Text style={styles.subheaderText}>{col.toUpperCase()}</Text>
// </View>
// ))}
// </View>
);
};
const RenderItem = ({ item, columns }) => {
const colWidth = Screen.screenWidth * 0.95 / columns?.length;
return (
<View>
<View style={styles.row}>
{columns.map((key, index) => (
<View key={index} style={{ width: colWidth }}>
<Text style={styles.name}>{String(item[key] ?? '')}</Text>
</View>
))}
</View>
<View style={[horizonalLine, { marginVertical: 4 }]} />
</View>
);
};
const SectionListView = ({ listData }) => {
const scrollRef = useRef(null); // shared horizontal scroll ref
console.log("/-", listData)
return (
<FlatList
data={listData}
keyExtractor={(item, index) => item.section + index}
contentContainerStyle={{ paddingBottom: 20 }}
ItemSeparatorComponent={() => <View style={{ paddingVertical: 5 }} />}
renderItem={({ item }) => {
const columns = Object.keys(item.items[0] || {}).filter(
key => item.items.some(obj => obj[key] !== undefined && obj[key] !== null)
);
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>{item.section}</Text>
<View style={[horizonalLine, { marginVertical: 10 }]} />
{/* Shared horizontal scroll view for header + rows */}
<ScrollView
horizontal
ref={scrollRef}
showsHorizontalScrollIndicator={false}
scrollEventThrottle={16}
>
<View>
<RenderHeader columns={columns} />
{item.items.map((subItem, index) => (
<RenderItem key={index} item={subItem} columns={columns} />
))}
</View>
</ScrollView>
</View>
);
}}
/>
);
};
const StoreInfo = ({ navigation, route }) => {
const { storeData } = route.params || {};
const [loading, setLoading] = useState(false)
const [selectedTab, setSelectedTab] = useState(0);
const [storeInfoData, setStoreInfoData] = useState([])
useEffect(() => {
getStoreInfo()
}, [])
const getStoreInfo = async () => {
setLoading(true);
try {
const params = { StoreId: storeData?.StoreId || "723" };
const config = {
method: 'post',
url: 'https://api1.parinaam.in/api/dabur/StoreDNAstoreInfo',
headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json'
},
data: params
};
const response = await axios.request(config);
const res = response.data?.StoreDNAstoreInfo || {};
// Step 1: Flatten API data
const tempData = [];
Object.entries(res).forEach(([sectionTitle, dataArray]) => {
if (dataArray?.length > 0) {
const tabId = dataArray[0]?.TabId ?? 0;
dataArray.forEach(item => {
const cleanItem = { ...item };
delete cleanItem.TabId;
delete cleanItem.TabName;
console.log("tempData---", item)
const formattedItems = Object.entries(cleanItem).map(([key, value]) => ({
brand: key,
name: String(value)
}));
tempData.push({
tabId,
section: sectionTitle.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
items: formattedItems
});
});
}
});
// Step 2: Group items by tabId and section
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);
});
// let objTemp={}
// groupedData['0-Dabur Employee']?.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)
? Array.from(new Set(storeInfoData.map(item => item.tabId))).map(id => ({
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 (
<SafeAreaView style={{ flex: 1, backgroundColor: GlobalTheme.colors.primary }}>
<View style={[styles.container, { paddingHorizontal: 0 }]}>
<CustomHeader
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%' }}>{renderTabContent()}</View>
</ScrollView>
</View>
<Loader visible={loading} />
</View>
</SafeAreaView>
);
};
export default StoreInfo;
<<<<<<< HEAD
import React, { useState , useRef} from 'react';
import {View,Text,TouchableOpacity,ScrollView,FlatList} from 'react-native';
import { styles } from './style';
import { horizonalLine, Screen } from '../../../theme/theme';
const storeinfodata = [
{
tabId: 0,
section: 'Store details',
items: [
{ brand: 'Store Name', name: 'Reliance Smart' },
{ brand: 'Store ID', name: '#98440' },
{ brand: 'Address', name: 'Rabindra Nagar, Delhi 110003' },
{ brand: 'City', name: 'Okhla' },
{ brand: 'Store Size', name: '15002000 sq ft' },
{ brand: 'Average Footfall', name: '10000' },
{ brand: 'Store age', name: '8' },
{ brand: 'Store Ranking', name: '24' },
],
},
{
tabId: 0,
section: 'Dabur Employees',
items: [
{ brand: 'RKAM', name: 'Rajesh Paal Singh' },
{ brand: 'SO', name: 'Soniya Singhal' },
],
},
{
tabId: 0,
section: '3P employees',
items: [
{ brand: 'Promoter Name', name: 'Payal Singh' },
{ brand: 'AM Name', name: 'Soniya Singhal' },
{ brand: 'Supervisor Name', name: 'Soniya Dhankar' },
{ brand: 'City', name: 'Okhla' },
{ brand: 'Promoter duration', name: '2 Year 7 months' },
{ brand: 'Average incentive', name: '5000' },
],
},
// Last Visit Details (tabId: 1)
{
tabId: 1,
section: 'Dabur employee',
items: [
{ brand: 'SO', name: 'Rajesh Paal Singh', date: '23/05/2025' , test : 'gxsjhxbas' },
{ brand: 'AH', name: 'Umesh Singh', date: '18/04/2025' },
{ brand: 'KAM', name: 'Rahul Tawde', date: '15/05/2025' },
{ brand: 'Others', name: 'Singhal Singh', date: '06/05/2025' },
],
},
{
tabId: 1,
section: '3P team',
items: [
{ brand: 'Supervisor', name: 'Ashish Talwar', date: '27/05/2025' },
{ brand: 'AM', name: 'Soniya Singhal', date: '23/05/2025' },
],
},
// Competition (tabId: 2)
{
tabId: 2,
section: 'Competition assets',
items: [
{ brand: 'Marico', value: 5 },
{ brand: 'Colgate', value: 1 },
{ brand: 'Godrej', value: 2 },
{ brand: 'HUL', value: 1 },
{ brand: 'XX', value: 2 },
],
},
{
tabId: 2,
section: 'Promoter details',
items: [
{ brand: 'Marico', value: 1 },
{ brand: 'Colgate', value: 1 },
{ brand: 'Godrej', value: 1 },
{ brand: 'HUL', value: 1 },
{ brand: 'XX', value: 0 },
],
},
];
const tabs = [
{ id: 0, title: 'Store Info' },
{ id: 1, title: 'Last visit details' },
{ id: 2, title: 'Competition' },
];
const RenderHeader = ({ columns }) => {
const colWidth = Screen.screenWidth * 0.95 / columns?.length;
return (
<View style={{ flexDirection: 'row', paddingVertical: 6 }}>
{columns.map((col, index) => (
<View key={index} style={{ width: colWidth }}>
<Text style={styles.subheaderText}>{col.toUpperCase()}</Text>
</View>
))}
</View>
);
};
const RenderItem = ({ item, columns }) => {
const colWidth = Screen.screenWidth * 0.95 / columns?.length;
return (
<View>
<View style={styles.row}>
{columns.map((key, index) => (
<View key={index} style={{ width: colWidth }}>
<Text style={styles.name}>{String(item[key] ?? '')}</Text>
</View>
))}
</View>
<View style={[horizonalLine, { marginVertical: 4 }]} />
</View>
);
};
const SectionListView = ({ listData }) => {
const scrollRef = useRef(null); // shared horizontal scroll ref
return (
<FlatList
data={listData}
keyExtractor={(item, index) => item.section + index}
contentContainerStyle={{ paddingBottom: 20 }}
ItemSeparatorComponent={() => <View style={{ paddingVertical: 5 }} />}
renderItem={({ item }) => {
const columns = Object.keys(item.items[0] || {}).filter(
key => item.items.some(obj => obj[key] !== undefined && obj[key] !== null)
);
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>{item.section}</Text>
<View style={[horizonalLine, { marginVertical: 10 }]} />
{/* Shared horizontal scroll view for header + rows */}
<ScrollView
horizontal
ref={scrollRef}
showsHorizontalScrollIndicator={false}
scrollEventThrottle={16}
>
<View>
<RenderHeader columns={columns} />
{item.items.map((subItem, index) => (
<RenderItem key={index} item={subItem} columns={columns} />
))}
</View>
</ScrollView>
</View>
);
}}
/>
);
};
const StoreInfo = () => {
const [selectedTab, setSelectedTab] = useState(0);
const filteredData = storeinfodata?.filter(item => item.tabId === selectedTab);
const selectedTabTitle = tabs?.find(tab => tab.id === selectedTab)?.title ?? 'NA';
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 (
<View style={styles.container}>
<View style={styles.tabstyle}>
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
<View style={{ flexDirection: 'row' }}>
{tabs?.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%' }}>{renderTabContent()}</View>
</ScrollView>
</View>
);
};
export default StoreInfo;
=======
import React, { useState, useRef, useEffect } from 'react';
import { View, Text, TouchableOpacity, ScrollView, FlatList } from 'react-native';
import { styles } from './style';
import GlobalTheme, { horizonalLine, Screen } from '../../../theme/theme';
import CustomHeader from '../../../components/CustomHeader';
import IMAGES from '../../../constants/Images';
import axios from 'axios';
import Loader from '../../../constants/Loader';
import { SafeAreaView } from 'react-native-safe-area-context';
import { ApiURL } from '../../../api/ApiConstant';
const storeinfodata = [
{
tabId: 0,
section: 'Store details',
items: [
{ brand: 'Store Name', name: 'Reliance Smart' },
{ brand: 'Store ID', name: '#98440' },
{ brand: 'Address', name: 'Rabindra Nagar, Delhi 110003' },
{ brand: 'City', name: 'Okhla' },
{ brand: 'Store Size', name: '15002000 sq ft' },
{ brand: 'Average Footfall', name: '10000' },
{ brand: 'Store age', name: '8' },
{ brand: 'Store Ranking', name: '24' },
],
},
{
tabId: 0,
section: 'Dabur Employees',
items: [
{ brand: 'RKAM', name: 'Rajesh Paal Singh' },
{ brand: 'SO', name: 'Soniya Singhal' },
],
},
{
tabId: 0,
section: '3P employees',
items: [
{ brand: 'Promoter Name', name: 'Payal Singh' },
{ brand: 'AM Name', name: 'Soniya Singhal' },
{ brand: 'Supervisor Name', name: 'Soniya Dhankar' },
{ brand: 'City', name: 'Okhla' },
{ brand: 'Promoter duration', name: '2 Year 7 months' },
{ brand: 'Average incentive', name: '5000' },
],
},
// Last Visit Details (tabId: 1)
{
tabId: 1,
section: 'Dabur employee',
items: [
{ brand: 'SO', name: 'Rajesh Paal Singh', date: '23/05/2025', test: 'gxsjhxbas' },
{ brand: 'AH', name: 'Umesh Singh', date: '18/04/2025' },
{ brand: 'KAM', name: 'Rahul Tawde', date: '15/05/2025' },
{ brand: 'Others', name: 'Singhal Singh', date: '06/05/2025' },
],
},
{
tabId: 1,
section: '3P team',
items: [
{ brand: 'Supervisor', name: 'Ashish Talwar', date: '27/05/2025' },
{ brand: 'AM', name: 'Soniya Singhal', date: '23/05/2025' },
],
},
// Competition (tabId: 2)
{
tabId: 2,
section: 'Competition assets',
items: [
{ brand: 'Marico', value: 5 },
{ brand: 'Colgate', value: 1 },
{ brand: 'Godrej', value: 2 },
{ brand: 'HUL', value: 1 },
{ brand: 'XX', value: 2 },
],
},
{
tabId: 2,
section: 'Promoter details',
items: [
{ brand: 'Marico', value: 1 },
{ brand: 'Colgate', value: 1 },
{ brand: 'Godrej', value: 1 },
{ brand: 'HUL', value: 1 },
{ brand: 'XX', value: 0 },
],
},
];
const tabs = [
{ id: 0, title: 'Store Info' },
{ id: 1, title: 'Last visit details' },
{ id: 2, title: 'Competition' },
];
const RenderHeader = ({ columns }) => {
const colWidth = Screen.screenWidth * 0.95 / columns?.length;
return (
null
// <View style={{ flexDirection: 'row', paddingVertical: 6 }}>
// {columns.map((col, index) => (
// <View key={index} style={{ width: colWidth }}>
// <Text style={styles.subheaderText}>{col.toUpperCase()}</Text>
// </View>
// ))}
// </View>
);
};
const RenderItem = ({ item, columns }) => {
const colWidth = Screen.screenWidth * 0.95 / columns?.length;
return (
<View>
<View style={styles.row}>
{columns.map((key, index) => (
<View key={index} style={{ width: colWidth }}>
<Text style={styles.name}>{String(item[key] ?? '')}</Text>
</View>
))}
</View>
<View style={[horizonalLine, { marginVertical: 4 }]} />
</View>
);
};
const SectionListView = ({ listData }) => {
const scrollRef = useRef(null); // shared horizontal scroll ref
console.log("/-", listData)
return (
<FlatList
data={listData}
keyExtractor={(item, index) => item.section + index}
contentContainerStyle={{ paddingBottom: 20 }}
ItemSeparatorComponent={() => <View style={{ paddingVertical: 5 }} />}
renderItem={({ item }) => {
const columns = Object.keys(item.items[0] || {}).filter(
key => item.items.some(obj => obj[key] !== undefined && obj[key] !== null)
);
return (
<>
{!item.hideSectionTitle && (
<>
<Text style={styles.sectionTitle}>{item.section}</Text>
{/* <View style={[horizonalLine, { marginVertical: 10 }]} /> */}
</>
)}
<View style={styles.section}>
<ScrollView
horizontal
ref={scrollRef}
showsHorizontalScrollIndicator={false}
scrollEventThrottle={16}
>
<View>
<RenderHeader columns={columns} />
{item.items.map((subItem, index) => (
<RenderItem key={index} item={subItem} columns={columns} />
))}
</View>
</ScrollView>
</View>
</>
);
}}
/>
);
};
const StoreInfo = ({ navigation, route }) => {
const { storeData } = route.params || {};
const [loading, setLoading] = useState(false)
const [selectedTab, setSelectedTab] = useState(0);
const [storeInfoData, setStoreInfoData] = useState([])
useEffect(() => {
getStoreInfo()
}, [])
const getStoreInfo = async () => {
setLoading(true);
try {
const params = { StoreId: storeData?.StoreId || "723" };
const config = {
method: 'post',
url: ApiURL.storeInfo,
headers: {
'api_key': '9a1f056fecb84eaf8eb4152dda22ab0501955c4f9bbe7daa8780740459fdde7a',
'Content-Type': 'application/json'
},
data: params
};
const response = await axios.request(config);
const res = response.data?.StoreDNAstoreInfo || {};
// Step 1: Flatten API data
const tempData = [];
Object.entries(res).forEach(([sectionTitle, dataArray]) => {
if (dataArray?.length > 0) {
const tabId = dataArray[0]?.TabId ?? 0;
dataArray.forEach(item => {
const cleanItem = { ...item };
delete cleanItem.TabId;
delete cleanItem.TabName;
console.log("tempData---", item)
const formattedItems = Object.entries(cleanItem).map(([key, value]) => ({
brand: key,
name: String(value)
}));
tempData.push({
tabId,
section: sectionTitle.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
items: formattedItems
});
});
}
});
// Step 2: Group items by tabId and section
// 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);
// });
// 👇 Replace Step 2 with this
const groupedData = {};
let threePEmployeeCount = 0;
tempData.forEach(entry => {
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);
}
});
// let objTemp={}
// groupedData['0-Dabur Employee']?.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)
? Array.from(new Set(storeInfoData.map(item => item.tabId))).map(id => ({
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 (
<SafeAreaView style={{ flex: 1, backgroundColor: GlobalTheme.colors.primary }}>
<View style={[styles.container, { paddingHorizontal: 0 }]}>
<CustomHeader
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;
>>>>>>> dabur-store-dna
+232 -115
View File
@@ -1,115 +1,232 @@
import { StyleSheet } from 'react-native';
import { GlobalTheme, Screen, shadow } from '../../../theme';
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: GlobalTheme.colors.white,
paddingHorizontal: 10
},
// tabs
tabview: {
alignItems: 'center',
justifyContent: 'space-between',
marginVertical: 10,
flexDirection: 'row',
},
tabstyle: {
flexDirection: 'row',
justifyContent: 'space-between',
borderColor: GlobalTheme.colors.lightblue,
borderWidth: 1.5,
borderRadius: GlobalTheme.borderRadius.xxlg,
marginTop: 10,
paddingHorizontal: 10,
},
tabtext: {
overflow: 'hidden',
color:'#000'
},
selecttabView: {
backgroundColor: GlobalTheme.colors.primary,
paddingVertical: 8,
paddingHorizontal: 15,
borderRadius: GlobalTheme.borderRadius.lgg
},
selecttabText: {
color: GlobalTheme.colors.white,
fontSize: GlobalTheme.typography.fontSize.small,
fontWeight: GlobalTheme.typography.fontWeight.regular,
textAlign: 'center'
},
unselecttabView: {
paddingVertical: 8,
paddingHorizontal: 15,
borderRadius: GlobalTheme.borderRadius.md
},
unselecttabText: {
color: GlobalTheme.colors.lightbluetext,
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
textAlign: 'center'
},
// comp
section: {
backgroundColor: GlobalTheme.colors.white,
padding: 12,
marginHorizontal: 5,
borderRadius: 8,
elevation: 2,
width: Screen.screenWidth * 0.92,
marginVertical: 5,
borderWidth: 1,
borderColor: GlobalTheme.colors.lightblueborder,
// ...shadow,
},
sectionTitle: {
color:'#000',
fontWeight: GlobalTheme.typography.fontWeight.bold,
fontSize: GlobalTheme.typography.fontSize.small,
},
row: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 4
},
brand: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
color: GlobalTheme.colors.black,
fontWeight: GlobalTheme.typography.fontWeight.medium,
},
value: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.medium,
},
name: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
flexWrap:'wrap',
color:'#000'
},
date: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
flexWrap:'wrap'
},
subheaderText:{
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
flexWrap:'wrap',
color : GlobalTheme.colors.gray,
textTransform: 'capitalize',
},
headerText:{
fontSize: GlobalTheme.typography.fontSize.medium,
fontWeight: GlobalTheme.typography.fontWeight.medium,
flexWrap:'wrap',
color : GlobalTheme.colors.black,
paddingVertical:10,
paddingHorizontal:10
}
});
<<<<<<< HEAD
import { StyleSheet } from 'react-native';
import { GlobalTheme, Screen, shadow } from '../../../theme';
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: GlobalTheme.colors.white,
paddingHorizontal: 10
},
// tabs
tabview: {
alignItems: 'center',
justifyContent: 'space-between',
marginVertical: 10,
flexDirection: 'row',
},
tabstyle: {
flexDirection: 'row',
justifyContent: 'space-between',
borderColor: GlobalTheme.colors.lightblue,
borderWidth: 1.5,
borderRadius: GlobalTheme.borderRadius.xxlg,
marginTop: 10,
paddingHorizontal: 10,
},
tabtext: {
overflow: 'hidden',
},
selecttabView: {
backgroundColor: GlobalTheme.colors.primary,
paddingVertical: 8,
paddingHorizontal: 15,
borderRadius: GlobalTheme.borderRadius.lgg
},
selecttabText: {
color: GlobalTheme.colors.white,
fontSize: GlobalTheme.typography.fontSize.small,
fontWeight: GlobalTheme.typography.fontWeight.regular,
textAlign: 'center'
},
unselecttabView: {
paddingVertical: 8,
paddingHorizontal: 15,
borderRadius: GlobalTheme.borderRadius.md
},
unselecttabText: {
color: GlobalTheme.colors.lightbluetext,
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
textAlign: 'center'
},
// comp
section: {
backgroundColor: GlobalTheme.colors.white,
padding: 12,
marginHorizontal: 5,
borderRadius: 8,
elevation: 2,
width: Screen.screenWidth * 0.92,
marginVertical: 5,
borderWidth: 1,
borderColor: GlobalTheme.colors.lightblueborder,
// ...shadow,
},
sectionTitle: {
fontWeight: GlobalTheme.typography.fontWeight.bold,
fontSize: GlobalTheme.typography.fontSize.small,
},
row: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 4
},
brand: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
color: GlobalTheme.colors.black,
fontWeight: GlobalTheme.typography.fontWeight.medium,
},
value: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.medium,
},
name: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
flexWrap:'wrap'
},
date: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
flexWrap:'wrap'
},
subheaderText:{
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
flexWrap:'wrap',
color : GlobalTheme.colors.gray,
textTransform: 'capitalize',
},
headerText:{
fontSize: GlobalTheme.typography.fontSize.medium,
fontWeight: GlobalTheme.typography.fontWeight.medium,
flexWrap:'wrap',
color : GlobalTheme.colors.black,
paddingVertical:10,
paddingHorizontal:10
}
});
=======
import { StyleSheet } from 'react-native';
import { GlobalTheme, Screen, shadow } from '../../../theme';
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: GlobalTheme.colors.white,
paddingHorizontal: 10
},
// tabs
tabview: {
alignItems: 'center',
justifyContent: 'space-between',
marginVertical: 10,
flexDirection: 'row',
},
tabstyle: {
flexDirection: 'row',
justifyContent: 'space-between',
borderColor: GlobalTheme.colors.lightblue,
borderWidth: 1.5,
borderRadius: GlobalTheme.borderRadius.xxlg,
marginTop: 10,
paddingHorizontal: 10,
},
tabtext: {
overflow: 'hidden',
color:'#000'
},
selecttabView: {
backgroundColor: GlobalTheme.colors.primary,
paddingVertical: 8,
paddingHorizontal: 15,
borderRadius: GlobalTheme.borderRadius.lgg
},
selecttabText: {
color: GlobalTheme.colors.white,
fontSize: GlobalTheme.typography.fontSize.small,
fontWeight: GlobalTheme.typography.fontWeight.regular,
textAlign: 'center'
},
unselecttabView: {
paddingVertical: 8,
paddingHorizontal: 15,
borderRadius: GlobalTheme.borderRadius.md
},
unselecttabText: {
color: GlobalTheme.colors.lightbluetext,
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
textAlign: 'center'
},
// comp
section: {
backgroundColor: GlobalTheme.colors.white,
padding: 12,
marginHorizontal: 5,
borderRadius: 8,
elevation: 2,
width: Screen.screenWidth * 0.92,
marginVertical: 5,
borderWidth: 0.5,
borderColor: 'gray',
marginBottom:15,
marginTop:10,
// ...shadow,
},
sectionTitle: {
color:'#000',
fontWeight: GlobalTheme.typography.fontWeight.bold,
fontSize: GlobalTheme.typography.fontSize.small,
marginHorizontal:10
},
row: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 4
},
brand: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
color: GlobalTheme.colors.black,
fontWeight: GlobalTheme.typography.fontWeight.medium,
},
value: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.medium,
},
name: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
flexWrap:'wrap',
color:'#000'
},
date: {
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
flexWrap:'wrap'
},
subheaderText:{
fontSize: GlobalTheme.typography.fontSize.xsmall,
fontWeight: GlobalTheme.typography.fontWeight.regular,
flexWrap:'wrap',
color : GlobalTheme.colors.gray,
textTransform: 'capitalize',
},
headerText:{
fontSize: GlobalTheme.typography.fontSize.medium,
fontWeight: GlobalTheme.typography.fontWeight.medium,
flexWrap:'wrap',
color : GlobalTheme.colors.black,
paddingVertical:10,
paddingHorizontal:10
}
});
>>>>>>> dabur-store-dna
+1 -1
View File
@@ -12,7 +12,7 @@ const Welcome = ({ navigation }) => {
return (
<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}>
<Image source={IMAGES.Welcomelogo} style={styles.illustration} />
<Text style={styles.title}>Welcome to {"\n"} Performics Store DNA</Text>
+11 -4
View File
@@ -1,4 +1,11 @@
import GlobalTheme from './theme';
import { shadow , Screen , horizonalLine } from './theme';
export {GlobalTheme, Screen , shadow, horizonalLine};
<<<<<<< HEAD
import GlobalTheme from './theme';
import { shadow , Screen , horizonalLine } from './theme';
export {GlobalTheme, Screen , shadow, horizonalLine};
=======
import GlobalTheme from './theme';
import { shadow , Screen , horizonalLine } from './theme';
export {GlobalTheme, Screen , shadow, horizonalLine};
>>>>>>> dabur-store-dna
+176 -87
View File
@@ -1,87 +1,176 @@
import { Dimensions, Platform } from 'react-native';
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
export const Screen = {
screenWidth,
screenHeight,
isAndroid: Platform.OS === 'android',
isIOS: Platform.OS === 'ios',
};
const GlobalTheme = {
colors: {
// Primary Colors
primary: '#113F8C', // Main color for buttons, headers
secondary: '#2357C6',
lightbluetext:'#7F83AB',
text: '#333333', // Text color for most content
lightblue:'#E2E7F2',
lightblueborder:'#ECECEC',
bluebgcolor :'#EAF0F4',
// Additional Colors
success: '#4caf50', // Success or positive action color
yellow: '#FFD661', // Warning or alert color
error: '#ff5252', // Error or negative action color
info: '#2196f3', // Information color
// Grayscale
white: '#ffffff',
lightGray: '#F1F1F1',
gray: '#676767',
darkGray: '#555555',
black: '#000000',
},
typography: {
// Define typography styles here (e.g., font family, sizes, line heights, etc.)
fontFamily: 'Regular',
fontSize: {
xxsmall: 12,
xsmall :14,
small: 16,
medium: 18,
large: 20,
},
fontWeight: {
regular: '400',
medium: '500',
bold: '700',
},
},
spacing: {
// Define spacing units (e.g., margin and padding) for consistent layout
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32,
},
borderRadius: {
// Define border radius values for consistent UI elements
sm: 5,
md: 10,
lg: 15,
lgg: 20,
xlg: 25,
xxlg: 35,
},
// Add other global theme properties as needed
};
export default GlobalTheme;
export const shadow = {
shadowColor: '#00000029',
shadowOffset: {width: 5, height: 5},
shadowOpacity: 0.8,
shadowRadius: 10,
elevation: 20,
};
export const horizonalLine = {
backgroundColor :'#E2E7F2',
height:1.5,
width: '100%',
};
<<<<<<< HEAD
import { Dimensions, Platform } from 'react-native';
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
export const Screen = {
screenWidth,
screenHeight,
isAndroid: Platform.OS === 'android',
isIOS: Platform.OS === 'ios',
};
const GlobalTheme = {
colors: {
// Primary Colors
primary: '#113F8C', // Main color for buttons, headers
secondary: '#2357C6',
lightbluetext:'#7F83AB',
text: '#333333', // Text color for most content
lightblue:'#E2E7F2',
lightblueborder:'#ECECEC',
// Additional Colors
success: '#4caf50', // Success or positive action color
yellow: '#FFD661', // Warning or alert color
error: '#ff5252', // Error or negative action color
info: '#2196f3', // Information color
// Grayscale
white: '#ffffff',
lightGray: '#F1F1F1',
gray: '#676767',
darkGray: '#555555',
black: '#000000',
},
typography: {
// Define typography styles here (e.g., font family, sizes, line heights, etc.)
fontFamily: 'Regular',
fontSize: {
xxsmall: 12,
xsmall :14,
small: 16,
medium: 18,
large: 20,
},
fontWeight: {
regular: '400',
medium: '500',
bold: '700',
},
},
spacing: {
// Define spacing units (e.g., margin and padding) for consistent layout
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32,
},
borderRadius: {
// Define border radius values for consistent UI elements
sm: 5,
md: 10,
lg: 15,
lgg: 20,
xlg: 25,
xxlg: 35,
},
// Add other global theme properties as needed
};
export default GlobalTheme;
export const shadow = {
shadowColor: '#00000029',
shadowOffset: {width: 5, height: 5},
shadowOpacity: 0.8,
shadowRadius: 10,
elevation: 20,
};
export const horizonalLine = {
backgroundColor :'#E2E7F2',
height:1.5,
width: '100%',
};
=======
import { Dimensions, Platform } from 'react-native';
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
export const Screen = {
screenWidth,
screenHeight,
isAndroid: Platform.OS === 'android',
isIOS: Platform.OS === 'ios',
};
const GlobalTheme = {
colors: {
// Primary Colors
primary: '#113F8C', // Main color for buttons, headers
secondary: '#2357C6',
lightbluetext:'#7F83AB',
text: '#333333', // Text color for most content
lightblue:'#E2E7F2',
lightblueborder:'#ECECEC',
bluebgcolor :'#EAF0F4',
// Additional Colors
success: '#4caf50', // Success or positive action color
yellow: '#FFD661', // Warning or alert color
error: '#ff5252', // Error or negative action color
info: '#2196f3', // Information color
// Grayscale
white: '#ffffff',
lightGray: '#F1F1F1',
gray: '#676767',
darkGray: '#555555',
black: '#000000',
},
typography: {
// Define typography styles here (e.g., font family, sizes, line heights, etc.)
fontFamily: 'Regular',
fontSize: {
xxsmall: 12,
xsmall :14,
small: 16,
medium: 18,
large: 20,
},
fontWeight: {
regular: '400',
medium: '500',
bold: '700',
},
},
spacing: {
// Define spacing units (e.g., margin and padding) for consistent layout
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32,
},
borderRadius: {
// Define border radius values for consistent UI elements
sm: 5,
md: 10,
lg: 15,
lgg: 20,
xlg: 25,
xxlg: 35,
},
// Add other global theme properties as needed
};
export default GlobalTheme;
export const shadow = {
shadowColor: '#00000029',
shadowOffset: {width: 5, height: 5},
shadowOpacity: 0.8,
shadowRadius: 10,
elevation: 20,
};
export const horizonalLine = {
backgroundColor :'#E2E7F2',
height:1.5,
width: '100%',
};
>>>>>>> dabur-store-dna
+44 -21
View File
@@ -1,21 +1,44 @@
import { StatusBar} from 'react-native';
import React from 'react';
import {GlobalTheme} from '../theme';
import { SafeAreaView } from 'react-native-safe-area-context';
const MyStatusBar = () => {
return (
<SafeAreaView
style={{
backgroundColor: GlobalTheme.colors.primary,
}}>
<StatusBar
translucent={false}
backgroundColor={GlobalTheme.colors.black}
barStyle={'light-content'}
/>
</SafeAreaView>
);
};
export default MyStatusBar;
<<<<<<< HEAD
import {SafeAreaView, StatusBar} from 'react-native';
import React from 'react';
import {GlobalTheme} from '../theme';
const MyStatusBar = () => {
return (
<SafeAreaView
style={{
backgroundColor: GlobalTheme.colors.black,
}}>
<StatusBar
translucent={false}
backgroundColor={GlobalTheme.colors.black}
barStyle={'light-content'}
/>
</SafeAreaView>
);
};
export default MyStatusBar;
=======
import { StatusBar} from 'react-native';
import React from 'react';
import {GlobalTheme} from '../theme';
import { SafeAreaView } from 'react-native-safe-area-context';
const MyStatusBar = () => {
return (
<SafeAreaView
style={{
backgroundColor: GlobalTheme.colors.primary,
}}>
<StatusBar
translucent={false}
backgroundColor={GlobalTheme.colors.black}
barStyle={'light-content'}
/>
</SafeAreaView>
);
};
export default MyStatusBar;
>>>>>>> dabur-store-dna
+4343 -378
View File
File diff suppressed because it is too large Load Diff