diff --git a/App.tsx b/App.tsx index 85d9178..579b91f 100644 --- a/App.tsx +++ b/App.tsx @@ -22,6 +22,28 @@ import { StatusBar } from 'react-native'; function AppContent(): React.JSX.Element { const isAuthenticated = useSelector((s: RootState) => Boolean(s.auth.token)); const selectedService = useSelector((s: RootState) => s.integrations.selectedService); + const linking = { + prefixes: ['centralizedreportingsystem://', 'https://centralizedreportingsystem.com'], + config: { + screens: { + // App tabs (see src/navigation/AppNavigator.tsx) + Dashboard: { + path: 'dashboard', + }, + Profile: { + path: 'profile', + screens: { + Profile: { + path: ':userId?', + parse: { + userId: (userId: string) => (userId ? parseInt(userId, 10) : undefined), + }, + }, + }, + }, + }, + }, + }; return ( } persistor={persistor}> @@ -32,11 +54,13 @@ function AppContent(): React.JSX.Element { ) : ( !selectedService ? ( - + ) : ( + + ) )} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e189252..5a82dba 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -21,6 +21,27 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/package-lock.json b/package-lock.json index 7ceb62e..96ba073 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "react-native-svg": "^15.12.1", "react-native-toast-message": "^2.2.1", "react-native-vector-icons": "^10.3.0", + "react-native-webview": "^13.16.0", "react-redux": "^9.2.0", "redux-persist": "^6.0.0" }, @@ -11544,6 +11545,20 @@ "node": ">=10" } }, + "node_modules/react-native-webview": { + "version": "13.16.0", + "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.16.0.tgz", + "integrity": "sha512-Nh13xKZWW35C0dbOskD7OX01nQQavOzHbCw9XoZmar4eXCo7AvrYJ0jlUfRVVIJzqINxHlpECYLdmAdFsl9xDA==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "invariant": "2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native/node_modules/@react-native/virtualized-lists": { "version": "0.79.0", "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.79.0.tgz", diff --git a/package.json b/package.json index e7fff90..674f12a 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "react-native-svg": "^15.12.1", "react-native-toast-message": "^2.2.1", "react-native-vector-icons": "^10.3.0", + "react-native-webview": "^13.16.0", "react-redux": "^9.2.0", "redux-persist": "^6.0.0" }, diff --git a/src/modules/integrations/screens/IntegrationCategoryScreen.tsx b/src/modules/integrations/screens/IntegrationCategoryScreen.tsx index 23a9a68..c47d7b7 100644 --- a/src/modules/integrations/screens/IntegrationCategoryScreen.tsx +++ b/src/modules/integrations/screens/IntegrationCategoryScreen.tsx @@ -7,6 +7,8 @@ import type { IntegrationsStackParamList } from '@/modules/integrations/navigati import { useDispatch } from 'react-redux'; import { setSelectedService } from '@/modules/integrations/store/integrationsSlice'; import type { AppDispatch } from '@/store/store'; +import ZohoAuth from './ZohoAuth'; +import { Modal } from 'react-native'; type Route = RouteProp; @@ -55,6 +57,8 @@ interface Props { const IntegrationCategoryScreen: React.FC = ({ route }) => { const { colors, fonts } = useTheme(); const dispatch = useDispatch(); + const [showZohoAuth, setShowZohoAuth] = React.useState(false); + const [pendingService, setPendingService] = React.useState(null); const services = servicesMap[route.params.categoryKey] ?? []; return ( @@ -68,7 +72,17 @@ const IntegrationCategoryScreen: React.FC = ({ route }) => { dispatch(setSelectedService(item.key))} + onPress={() => { + // Here we decide whether to require Zoho authentication first + const requiresZohoAuth = item.key === 'zohoProjects' || item.key === 'zohoPeople' || item.key === 'zohoBooks' || item.key === 'zohoCRM'; + console.log('key pressed',item.key) + if (requiresZohoAuth) { + setPendingService(item.key); + setShowZohoAuth(true); + } else { + dispatch(setSelectedService(item.key)); + } + }} > @@ -77,6 +91,34 @@ const IntegrationCategoryScreen: React.FC = ({ route }) => { )} /> + + {/* Zoho Auth Modal */} + setShowZohoAuth(false)} + > + { + console.log('auth data i got',authData) + setShowZohoAuth(false); + if (pendingService) { + dispatch(setSelectedService(pendingService)); + setPendingService(null); + } + }} + onAuthError={() => { + setShowZohoAuth(false); + setPendingService(null); + }} + onClose={() => { + setShowZohoAuth(false); + setPendingService(null); + }} + /> + ); }; diff --git a/src/modules/integrations/screens/README.md b/src/modules/integrations/screens/README.md new file mode 100644 index 0000000..48d4659 --- /dev/null +++ b/src/modules/integrations/screens/README.md @@ -0,0 +1,159 @@ +# Zoho Authentication WebView + +This directory contains the Zoho authentication implementation using React Native WebView. + +## Files + +- `ZohoAuth.tsx` - Main WebView component for Zoho OAuth authentication +- `ZohoAuthExample.tsx` - Example implementation showing how to use the ZohoAuth component +- `LoginScreen.tsx` - Existing login screen (can be extended to include Zoho auth) + +## ZohoAuth Component + +The `ZohoAuth` component provides a WebView-based authentication flow for Zoho services. + +### Features + +- ✅ WebView-based OAuth flow +- ✅ Error handling and retry functionality +- ✅ Loading states and user feedback +- ✅ Theme integration with the app's design system +- ✅ TypeScript support with proper type definitions +- ✅ Responsive design with proper styling + +### Usage + +```tsx +import React, { useState } from 'react'; +import { Modal } from 'react-native'; +import ZohoAuth from './ZohoAuth'; + +const MyComponent = () => { + const [showZohoAuth, setShowZohoAuth] = useState(false); + + const handleAuthSuccess = (authData) => { + console.log('Auth successful:', authData); + // Handle successful authentication + setShowZohoAuth(false); + }; + + const handleAuthError = (error) => { + console.error('Auth failed:', error); + // Handle authentication error + setShowZohoAuth(false); + }; + + return ( + <> +