diff --git a/.gitignore b/.gitignore index e801a6f..8a77fef 100644 --- a/.gitignore +++ b/.gitignore @@ -41,5 +41,20 @@ Thumbs.db coverage/ TestResults/ +# React Native / Mobile +mobile/ios/Pods/ +mobile/ios/build/ +mobile/android/.gradle/ +mobile/android/app/build/ +mobile/android/build/ +*.xcworkspace +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +xcuserdata/ +*.hmap +*.ipa + # Build artifacts *.zip diff --git a/mobile/.env.example b/mobile/.env.example new file mode 100644 index 0000000..ae5f177 --- /dev/null +++ b/mobile/.env.example @@ -0,0 +1,8 @@ +# API +API_URL=https://api.proposals.seahaven.com/api + +# Cognito (set after CDK deployment) +COGNITO_DOMAIN=proposal-system.auth.us-east-1.amazoncognito.com +COGNITO_CLIENT_ID= +COGNITO_USER_POOL_ID= +COGNITO_REDIRECT_URI=com.seahavenind.proposals://auth/callback diff --git a/mobile/app.json b/mobile/app.json new file mode 100644 index 0000000..f738613 --- /dev/null +++ b/mobile/app.json @@ -0,0 +1,4 @@ +{ + "name": "ProposalSystem", + "displayName": "Sea Haven Proposals" +} diff --git a/mobile/babel.config.js b/mobile/babel.config.js new file mode 100644 index 0000000..f7b3da3 --- /dev/null +++ b/mobile/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ['module:@react-native/babel-preset'], +}; diff --git a/mobile/index.js b/mobile/index.js new file mode 100644 index 0000000..117ddca --- /dev/null +++ b/mobile/index.js @@ -0,0 +1,5 @@ +import { AppRegistry } from 'react-native'; +import App from './src/App'; +import { name as appName } from './app.json'; + +AppRegistry.registerComponent(appName, () => App); diff --git a/mobile/metro.config.js b/mobile/metro.config.js new file mode 100644 index 0000000..fee5f8a --- /dev/null +++ b/mobile/metro.config.js @@ -0,0 +1,17 @@ +const path = require('path'); +const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); + +const projectRoot = __dirname; +const monorepoRoot = path.resolve(projectRoot, '..'); + +const config = { + watchFolders: [path.resolve(monorepoRoot, 'shared')], + resolver: { + nodeModulesPaths: [ + path.resolve(projectRoot, 'node_modules'), + path.resolve(monorepoRoot, 'node_modules'), + ], + }, +}; + +module.exports = mergeConfig(getDefaultConfig(projectRoot), config); diff --git a/mobile/package.json b/mobile/package.json index 2ba72eb..a18e805 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -4,13 +4,37 @@ "private": true, "scripts": { "start": "react-native start", - "ios": "react-native run-ios" + "ios": "react-native run-ios", + "android": "react-native run-android", + "typecheck": "tsc --noEmit" }, "dependencies": { + "@proposal-system/api-contracts": "file:../shared/api-contracts", + "@react-native-async-storage/async-storage": "^2.1.0", + "@react-native-community/netinfo": "^11.4.0", + "@react-navigation/bottom-tabs": "^7.2.0", + "@react-navigation/native": "^7.0.0", + "@react-navigation/native-stack": "^7.2.0", + "@reduxjs/toolkit": "^2.11.2", + "@tanstack/react-query": "^5.100.10", + "axios": "^1.16.0", "react": "^19.0.0", - "react-native": "^0.76.0" + "react-native": "^0.79.0", + "react-native-app-auth": "^8.0.0", + "react-native-document-picker": "^9.3.0", + "react-native-haptic-feedback": "^2.3.0", + "react-native-image-picker": "^7.2.0", + "react-native-keychain": "^9.2.0", + "react-native-paper": "^5.13.0", + "react-native-safe-area-context": "^5.0.0", + "react-native-screens": "^4.5.0", + "react-native-share": "^11.0.0", + "react-native-vector-icons": "^10.2.0", + "react-redux": "^9.2.0" }, "devDependencies": { + "@react-native/babel-preset": "^0.79.0", + "@react-native/metro-config": "^0.79.0", "@types/react": "^19.0.0", "typescript": "~5.7.0" } diff --git a/mobile/tsconfig.json b/mobile/tsconfig.json new file mode 100644 index 0000000..e766c19 --- /dev/null +++ b/mobile/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "jsx": "react-jsx", + "esModuleInterop": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "allowJs": true, + "outDir": "./dist", + "rootDir": ".", + "baseUrl": ".", + "paths": { + "@proposal-system/api-contracts": ["../shared/api-contracts/src"] + } + }, + "include": ["src"], + "exclude": ["node_modules", "dist"] +}