diff --git a/mobile/FIREBASE_SETUP.md b/mobile/FIREBASE_SETUP.md new file mode 100644 index 00000000..951391d8 --- /dev/null +++ b/mobile/FIREBASE_SETUP.md @@ -0,0 +1,28 @@ +# Firebase Setup + +## Initial Setup for New Developers + +1. **Google Services Configuration**: + - Copy `android/app/google-services.json.template` to `android/app/google-services.json` + - Replace all placeholder values with your actual Firebase project configuration + - Get this file from the Firebase Console > Project Settings > General > Your apps + +2. **Required Configuration Files**: + - `android/app/google-services.json` - Firebase configuration for Android + - `ios/Runner/GoogleService-Info.plist` - Firebase configuration for iOS (if applicable) + +3. **Environment Variables** (if using): + - Create `.env` file in project root + - Add your API keys and configuration + +## Security Notes + +- Never commit sensitive files like: + - `google-services.json` + - `GoogleService-Info.plist` + - `.keystore` files + - `key.properties` + - Any files containing API keys or secrets + +- These files are in `.gitignore` for security reasons +- Use template files and environment variables for team development diff --git a/mobile/README.md b/mobile/README.md index 7b012856..2e7d5403 100644 --- a/mobile/README.md +++ b/mobile/README.md @@ -1,16 +1,561 @@ -# mobile +# BottleCRM Mobile -A new Flutter project. +
-## Getting Started +![Flutter](https://img.shields.io/badge/Flutter-3.8.1+-02569B?style=for-the-badge&logo=flutter&logoColor=white) +![Dart](https://img.shields.io/badge/Dart-3.0.0+-0175C2?style=for-the-badge&logo=dart&logoColor=white) +![Android](https://img.shields.io/badge/Android-API%2031+-3DDC84?style=for-the-badge&logo=android&logoColor=white) +![iOS](https://img.shields.io/badge/iOS-11.0+-000000?style=for-the-badge&logo=ios&logoColor=white) +![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge) -This project is a starting point for a Flutter application. +[![Get it on Google Play](https://img.shields.io/badge/Get%20it%20on-Google%20Play-black?style=for-the-badge&logo=google-play&logoColor=white)](https://play.google.com/store/apps/details?id=io.bottlecrm) -A few resources to get you started if this is your first Flutter project: +
-- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) +A modern, feature-rich Flutter CRM application for startups and enterprises. Built with a scalable architecture, BottleCRM Mobile provides comprehensive customer relationship management capabilities with multi-tenant support, real-time synchronization, and intuitive user experience. -For help getting started with Flutter development, view the -[online documentation](https://docs.flutter.dev/), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +## ๐Ÿš€ Overview + +BottleCRM Mobile is designed to streamline your sales and customer management processes with: +- **Multi-tenant Architecture**: Organization-based data isolation and role management +- **Offline-First Design**: Local caching with smart synchronization +- **Modern UI/UX**: Material Design 3 with adaptive layouts +- **Enterprise Security**: OAuth 2.0, JWT tokens, and secure API communication + +## โœจ Features + +### ๐Ÿ” Authentication & Security +- **Google OAuth 2.0**: Seamless single sign-on integration +- **JWT Authentication**: Secure token-based API communication +- **Multi-tenant Support**: Organization-based data isolation +- **Role-based Access**: Granular permissions and user management + +### ๐Ÿ“Š Core CRM Modules +- **Dashboard**: Real-time metrics, KPIs, and activity feeds +- **Contacts**: Complete contact management with search and filtering +- **Leads**: Lead capture, qualification, and conversion tracking +- **Opportunities**: Sales pipeline management with stages +- **Tasks**: Task assignment, tracking, and deadline management +- **Accounts**: Customer account profiles and relationship history +- **Cases**: Customer support ticket management +- **Events**: Calendar integration and meeting scheduling +- **Documents**: File management with cloud storage +- **Teams**: Collaboration tools and team management +- **Invoices**: Billing and invoice generation + +### ๐ŸŽจ User Experience +- **Material Design 3**: Modern, consistent UI patterns +- **Responsive Design**: Optimized for phones, tablets, and foldables +- **Dark/Light Theme**: System-aware theme switching +- **Offline Support**: Local data caching with smart sync +- **Pull-to-Refresh**: Intuitive data refresh patterns +- **Infinite Scrolling**: Smooth pagination for large datasets + +## ๐Ÿ“‹ Requirements + +### System Requirements +- **Flutter SDK**: 3.8.1 or later +- **Dart SDK**: 3.0.0 or later +- **Android Studio/VS Code**: Latest stable version +- **Git**: For version control + +### Platform Support +- **Android**: API level 31+ (Android 12+) +- **iOS**: iOS 11.0+ (for iOS builds) +- **Web**: Modern browsers (Chrome, Firefox, Safari, Edge) +- **Desktop**: Windows, macOS, Linux (experimental) + +### Development Tools +- **Android SDK**: For Android development +- **Xcode**: For iOS development (macOS only) +- **CocoaPods**: iOS dependency management + +## ๐Ÿš€ Getting Started + +### ๐Ÿ“ฑ For End Users + +**Download the app directly from Google Play Store:** + +
+ +[![Get it on Google Play](https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=io.bottlecrm) + +*Package ID: `io.bottlecrm`* + +
+ +### ๐Ÿ‘จโ€๐Ÿ’ป For Developers + +### Quick Start + +1. **Clone the repository**: + ```bash + git clone https://github.com/your-username/bottlecrm_mobile_v2.git + cd bottlecrm_mobile_v2 + ``` + +2. **Install Flutter dependencies**: + ```bash + flutter pub get + ``` + +3. **Set up Firebase & Google Sign-In**: + ```bash + # Copy template and configure + cp android/app/google-services.json.template android/app/google-services.json + # Edit the file with your Firebase project configuration + ``` + +4. **Run the application**: + ```bash + flutter run + ``` + +### ๐Ÿ”ง Detailed Setup + +#### Firebase Configuration +1. Create a new Firebase project at [Firebase Console](https://console.firebase.google.com) +2. Enable Google Sign-In authentication +3. Download `google-services.json` for Android +4. Download `GoogleService-Info.plist` for iOS (if building for iOS) +5. Place files in their respective directories: + - Android: `android/app/google-services.json` + - iOS: `ios/Runner/GoogleService-Info.plist` + +#### Google Cloud Console Setup +1. Navigate to [Google Cloud Console](https://console.cloud.google.com) +2. Create OAuth 2.0 Client ID for Android: + ```bash + # Get your SHA-1 fingerprint + cd android + ./gradlew signingReport + ``` +3. Add the SHA-1 fingerprint to your OAuth client +4. Configure OAuth consent screen + +#### Environment Configuration +The app automatically switches between environments: +- **Debug builds**: Uses development API (ngrok URL) +- **Release builds**: Uses production API (bottlecrm.io) + +You can modify URLs in `lib/config/api_config.dart` + +## ๐Ÿ›  Development + +### Development Commands + +```bash +# Run the app with hot reload +flutter run + +# Run with specific device +flutter run -d + +# Run in debug mode with detailed logging +flutter run --debug --verbose + +# Format code +dart format . + +# Analyze code quality +flutter analyze --no-fatal-infos + +# Run tests +flutter test + +# Generate code coverage +flutter test --coverage +``` + +### Code Quality & Standards + +This project follows strict coding standards: +- **Linting**: Uses `flutter_lints` for consistent code style +- **Architecture**: Singleton services with dependency injection +- **Error Handling**: Comprehensive try-catch with user-friendly messages +- **Naming**: Dart conventions (camelCase, PascalCase, snake_case) +- **Documentation**: Comprehensive inline documentation + +### Debugging + +```bash +# Connect to Android device over WiFi +adb connect :5555 + +# View logs +flutter logs + +# Launch DevTools +flutter pub global activate devtools +flutter pub global run devtools +``` + +## ๐Ÿ“ฆ Build & Deployment + +### Android Builds + +```bash +# Clean and prepare +flutter clean +flutter pub get + +# Debug build (uses development API) +flutter build apk --debug + +# Release build (uses production API) +flutter build apk --release + +# App Bundle for Play Store +flutter build appbundle --release + +# Install APK directly +flutter install build/app/outputs/flutter-apk/app-release.apk +``` + +### iOS Builds (macOS only) + +```bash +# Build for iOS +flutter build ios --release + +# Build for iOS Simulator +flutter build ios --debug --simulator +``` + +### Build Configurations + +The app uses different API endpoints based on build type: +- **Debug builds**: Development server (ngrok tunnel) +- **Release builds**: Production API (`https://api.bottlecrm.io`) + +Build configurations are managed in: +- `lib/config/api_config.dart` - API endpoint configuration +- `android/app/build.gradle.kts` - Android build settings +- `ios/Runner.xcodeproj` - iOS build settings + +## ๐Ÿ— Architecture + +BottleCRM Mobile follows a robust, scalable architecture designed for enterprise applications: + +### Core Architecture Patterns + +- **Singleton Services**: All services use the singleton pattern for consistent state management +- **Service-First Design**: Business logic is encapsulated in service classes +- **Repository Pattern**: Data access abstraction with caching layers +- **Multi-tenant Support**: Organization-based data isolation at the API level + +### Project Structure + +``` +lib/ +โ”œโ”€โ”€ app.dart # Main app configuration & routing +โ”œโ”€โ”€ main.dart # Application entry point +โ”œโ”€โ”€ config/ +โ”‚ โ””โ”€โ”€ api_config.dart # Environment-aware API configuration +โ”œโ”€โ”€ models/ +โ”‚ โ””โ”€โ”€ api_models.dart # Type-safe data models with JSON serialization +โ”œโ”€โ”€ services/ # Business logic & API communication +โ”‚ โ”œโ”€โ”€ api_service.dart # HTTP client with auto-authentication +โ”‚ โ”œโ”€โ”€ auth_service.dart # Google OAuth & organization management +โ”‚ โ”œโ”€โ”€ contacts_service.dart +โ”‚ โ”œโ”€โ”€ dashboard_service.dart +โ”‚ โ”œโ”€โ”€ leads_service.dart +โ”‚ โ””โ”€โ”€ tasks_service.dart +โ””โ”€โ”€ screens/ # UI screens organized by feature + โ”œโ”€โ”€ dashboard_screen.dart + โ”œโ”€โ”€ login_screen.dart + โ”œโ”€โ”€ company_selection_screen.dart + โ””โ”€โ”€ ... +``` + +### Key Architecture Components + +#### 1. Authentication Flow +``` +Login โ†’ Google OAuth โ†’ JWT Token โ†’ Organization Selection โ†’ Dashboard +``` + +#### 2. Service Pattern +```dart +class SomeService { + static final SomeService _instance = SomeService._internal(); + factory SomeService() => _instance; + SomeService._internal(); + + // Service methods... +} +``` + +#### 3. API Communication +- Centralized HTTP client with automatic JWT token injection +- Organization header (`X-Organization-ID`) for multi-tenant requests +- Automatic logout on 401 responses +- Comprehensive error handling with user-friendly messages + +#### 4. State Management +- Service-based state management with singleton pattern +- Local caching using SharedPreferences +- Reactive UI updates with StatefulWidget patterns +- Navigation state preserved with IndexedStack + +### Data Flow + +1. **Authentication**: Google OAuth โ†’ JWT storage โ†’ Organization selection +2. **API Requests**: Service โ†’ ApiService โ†’ HTTP โ†’ Backend API +3. **Data Processing**: JSON โ†’ Model classes โ†’ UI widgets +4. **Local Storage**: Critical data cached in SharedPreferences +5. **Error Handling**: Service level โ†’ UI feedback โ†’ User notification + +For detailed architectural guidelines, see [CLAUDE.md](CLAUDE.md) and [.github/copilot-instructions.md](.github/copilot-instructions.md). + +## โš™๏ธ Configuration + +### API Configuration + +The application uses environment-based API URLs configured in `lib/config/api_config.dart`: + +```dart +// Development (debug builds) +static const String _developmentUrl = 'https://b2ad5166b831.ngrok-free.app'; + +// Production (release builds) +static const String _productionUrl = 'https://api.bottlecrm.io'; +``` + +**Environment Detection**: Automatic switching based on `kDebugMode` flag + +### Authentication Setup + +#### Google Sign-In Configuration + +1. **Firebase Console Setup**: + - Create Firebase project + - Enable Google Sign-In authentication provider + - Configure OAuth consent screen + +2. **Get Android SHA-1 fingerprint**: + ```bash + cd android + ./gradlew signingReport + ``` + +3. **Google Cloud Console**: + - Create OAuth 2.0 Client ID for Android + - Add SHA-1 fingerprint to OAuth client + - Download `google-services.json` + +4. **Firebase Configuration Files**: + ```bash + android/app/google-services.json # Android configuration + ios/Runner/GoogleService-Info.plist # iOS configuration (if applicable) + ``` + +#### Authentication Flow + +``` +1. User clicks "Sign in with Google" +2. Google OAuth flow โ†’ JWT token received +3. Token stored in SharedPreferences +4. User selects organization from available list +5. Organization ID added to all API requests via X-Organization-ID header +6. Dashboard and metadata loaded for selected organization +``` + +### Multi-tenancy Configuration + +- **Organization-based Data Isolation**: All API requests include organization context +- **Automatic Header Injection**: `ApiService` adds `X-Organization-ID` to requests +- **Organization Switching**: Clear cached data when switching organizations +- **Role-based Access**: Different permissions based on user role in organization + +### Storage Configuration + +- **JWT Tokens**: Stored securely in SharedPreferences +- **Organization Data**: Cached locally for offline access +- **Metadata Caching**: Lead statuses, sources, and other metadata cached per organization +- **Auto-cleanup**: Cached data cleared on logout and organization switch + +## ๐Ÿ“š Dependencies + +### Core Dependencies + +| Package | Version | Purpose | +|---------|---------|---------| +| `flutter` | SDK | Flutter framework | +| `cupertino_icons` | ^1.0.8 | iOS-style icons | +| `http` | ^1.1.0 | HTTP client for API requests | +| `google_sign_in` | ^7.1.1 | Google OAuth authentication | +| `shared_preferences` | ^2.2.2 | Local data persistence | +| `jwt_decoder` | ^2.0.1 | JWT token parsing | +| `font_awesome_flutter` | ^10.7.0 | FontAwesome icons | +| `intl` | ^0.19.0 | Internationalization support | +| `package_info_plus` | ^8.0.2 | App version and build info | + +### Development Dependencies + +| Package | Version | Purpose | +|---------|---------|---------| +| `flutter_test` | SDK | Testing framework | +| `flutter_lints` | ^6.0.0 | Dart linting rules | +| `flutter_launcher_icons` | ^0.14.4 | App icon generation | + +### Key Features by Dependency + +- **Authentication**: Google Sign-In with JWT token management +- **HTTP Communication**: Robust API client with error handling +- **Local Storage**: Secure token and metadata caching +- **UI Components**: Material Design with FontAwesome icons +- **Code Quality**: Comprehensive linting and formatting + +## ๐Ÿงช Testing + +### Test Structure +```bash +test/ +โ”œโ”€โ”€ unit/ # Unit tests for services and models +โ”œโ”€โ”€ widget/ # Widget tests for UI components +โ””โ”€โ”€ integration/ # End-to-end integration tests +``` + +### Running Tests +```bash +# Run all tests +flutter test + +# Run with coverage +flutter test --coverage + +# Run specific test file +flutter test test/unit/auth_service_test.dart +``` + +### Testing Guidelines +- **Unit Tests**: All service methods and model classes +- **Widget Tests**: Critical UI components and interactions +- **Integration Tests**: End-to-end user flows +- **Mocking**: Use mockito for external dependencies + +## ๐Ÿš€ Performance Optimization + +### App Performance +- **Lazy Loading**: Screens and data loaded on demand +- **Image Optimization**: Compressed assets and caching +- **Memory Management**: Proper disposal of controllers and streams +- **Network Optimization**: Request batching and intelligent caching + +## ๐Ÿ”ง Troubleshooting + +### Common Issues + +#### Firebase/Google Sign-In Issues +```bash +# Problem: Google Sign-In not working +# Solution: Check SHA-1 fingerprint configuration +cd android && ./gradlew signingReport + +# Problem: google-services.json not found +# Solution: Ensure file is in correct location +ls android/app/google-services.json +``` + +#### Build Issues +```bash +# Problem: Build failures after dependency updates +# Solution: Clean and rebuild +flutter clean +flutter pub get +flutter run + +# Problem: Android build issues +# Solution: Verify Android SDK and NDK versions +flutter doctor -v +``` + +#### API Connection Issues +```bash +# Problem: API requests failing in debug mode +# Solution: Check ngrok tunnel status and update URL in api_config.dart + +# Problem: 401 Unauthorized errors +# Solution: Clear app data and re-authenticate +flutter clean +# Uninstall app from device and reinstall +``` + +### Development Tips + +1. **Hot Reload**: Use `r` in terminal for hot reload during development +2. **Hot Restart**: Use `R` for hot restart when changing app state +3. **DevTools**: Use Flutter DevTools for debugging and performance analysis +4. **Logging**: Check console output for detailed error information + +## ๐Ÿค Contributing + +### Development Workflow + +1. **Fork the repository** +2. **Create a feature branch**: `git checkout -b feature/amazing-feature` +3. **Follow coding standards**: Use `dart format` and `flutter analyze` +4. **Write tests**: Ensure adequate test coverage +5. **Commit changes**: Use conventional commit messages +6. **Create Pull Request**: Provide detailed description + +### Code Style Guidelines + +- Follow Dart naming conventions +- Use meaningful variable and function names +- Add inline documentation for complex logic +- Implement proper error handling +- Write unit tests for new features + +### Commit Message Format +``` +type(scope): description + +feat(auth): add biometric authentication +fix(api): resolve null pointer exception +docs(readme): update installation instructions +``` + +## ๐Ÿ“„ License + +``` +MIT License + +Copyright (c) 2024 BottleCRM + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` + +## ๐ŸŒŸ Support + +- ** Documentation**: [CLAUDE.md](CLAUDE.md) for detailed architecture information +- **๐Ÿ› Issues**: [GitHub Issues](https://github.com/your-username/bottlecrm_mobile_v2/issues) for bug reports +- **๐Ÿ’ฌ Discussions**: [GitHub Discussions](https://github.com/your-username/bottlecrm_mobile_v2/discussions) for questions +- **๐Ÿ”ฅ Firebase Setup**: [FIREBASE_SETUP.md](FIREBASE_SETUP.md) for Firebase configuration + +--- + +
+ +**BottleCRM Mobile** - Free CRM for startups and enterprises + +Made with โค๏ธ using Flutter + +
diff --git a/mobile/android/app/build.gradle.kts b/mobile/android/app/build.gradle.kts index 18a310af..ed7a38f5 100644 --- a/mobile/android/app/build.gradle.kts +++ b/mobile/android/app/build.gradle.kts @@ -1,40 +1,65 @@ +import java.util.Properties +import java.io.FileInputStream + plugins { id("com.android.application") id("kotlin-android") // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id("dev.flutter.flutter-gradle-plugin") + id("com.google.gms.google-services") +} +dependencies { + // ... + implementation("com.google.android.material:material:1.12.0") + // ... +} + +val keystoreProperties = Properties() +val keystorePropertiesFile = rootProject.file("key.properties") +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(FileInputStream(keystorePropertiesFile)) } android { - namespace = "com.example.mobile" + namespace = "io.bottlecrm" compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion + ndkVersion = "27.0.12077973" // Use latest available NDK compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_17.toString() + jvmTarget = JavaVersion.VERSION_11.toString() } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId = "com.example.mobile" + applicationId = "io.bottlecrm" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. - minSdk = flutter.minSdkVersion + minSdk = 28 // Android 9 (API 28) targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode versionName = flutter.versionName } + signingConfigs { + create("release") { + keyAlias = keystoreProperties["keyAlias"] as String + keyPassword = keystoreProperties["keyPassword"] as String + storeFile = keystoreProperties["storeFile"]?.let { file(it) } + storePassword = keystoreProperties["storePassword"] as String + } + } + buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.getByName("debug") + // signingConfig = signingConfigs.getByName("debug") + signingConfig = signingConfigs.getByName("release") } } } diff --git a/mobile/android/app/google-services.json b/mobile/android/app/google-services.json new file mode 100644 index 00000000..2cb23402 --- /dev/null +++ b/mobile/android/app/google-services.json @@ -0,0 +1,63 @@ +{ + "project_info": { + "project_number": "1072513761792", + "project_id": "bottlecrm-io", + "storage_bucket": "bottlecrm-io.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:1072513761792:android:c170ae72445200ecd74ee5", + "android_client_info": { + "package_name": "io.bottlecrm" + } + }, + "oauth_client": [ + { + "client_id": "1072513761792-6cnavnfp5p4me4peah0vgoc477ndkd3h.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.bottlecrm", + "certificate_hash": "5227cfe6b33aceb349e54aaf1ea3cfc191aef324" + } + }, + { + "client_id": "1072513761792-r70ldlpqkbkb654tdpu41sqqrs5b4uf4.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.bottlecrm", + "certificate_hash": "f980d3a3e81564ea45f3634dd706eb5261ec222b" + } + }, + { + "client_id": "1072513761792-vp1nq9690h2v94oge513ejr7d01rh0e8.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.bottlecrm", + "certificate_hash": "67c4be5a9739470b402c1405f181abc7e6cfa7df" + } + }, + { + "client_id": "1072513761792-p59rct7b1c3go7l58e51r3geuqff2tfl.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDsA2wgQIw-bVgwODNMIF482gVRn5xdANU" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1072513761792-dvcv8cj147oj6nav40u7jfjp1r3f0a1d.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/mobile/android/app/src/main/AndroidManifest.xml b/mobile/android/app/src/main/AndroidManifest.xml index ef5beb7e..49ee3232 100644 --- a/mobile/android/app/src/main/AndroidManifest.xml +++ b/mobile/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,9 @@ + + android:icon="@mipmap/launcher_icon"> - diff --git a/mobile/android/app/src/main/res/values/styles.xml b/mobile/android/app/src/main/res/values/styles.xml index cb1ef880..a3fb32f0 100644 --- a/mobile/android/app/src/main/res/values/styles.xml +++ b/mobile/android/app/src/main/res/values/styles.xml @@ -12,7 +12,8 @@ running. This Theme is only used starting with V2 of Flutter's Android embedding. --> - + diff --git a/mobile/android/build.gradle.kts b/mobile/android/build.gradle.kts index dbee657b..a58274b2 100644 --- a/mobile/android/build.gradle.kts +++ b/mobile/android/build.gradle.kts @@ -1,3 +1,13 @@ +buildscript { + repositories { + google() + mavenCentral() + } + dependencies { + classpath("com.google.gms:google-services:4.4.0") + } +} + allprojects { repositories { google() @@ -5,10 +15,7 @@ allprojects { } } -val newBuildDir: Directory = - rootProject.layout.buildDirectory - .dir("../../build") - .get() +val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get() rootProject.layout.buildDirectory.value(newBuildDir) subprojects { diff --git a/mobile/android/gradle.properties b/mobile/android/gradle.properties index fbee1d8c..f018a618 100644 --- a/mobile/android/gradle.properties +++ b/mobile/android/gradle.properties @@ -1,2 +1,3 @@ org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true +android.enableJetifier=true diff --git a/mobile/android/gradle/wrapper/gradle-wrapper.properties b/mobile/android/gradle/wrapper/gradle-wrapper.properties index e4ef43fb..ac3b4792 100644 --- a/mobile/android/gradle/wrapper/gradle-wrapper.properties +++ b/mobile/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/mobile/android/settings.gradle.kts b/mobile/android/settings.gradle.kts index ca7fe065..43394ed5 100644 --- a/mobile/android/settings.gradle.kts +++ b/mobile/android/settings.gradle.kts @@ -1,12 +1,11 @@ pluginManagement { - val flutterSdkPath = - run { - val properties = java.util.Properties() - file("local.properties").inputStream().use { properties.load(it) } - val flutterSdkPath = properties.getProperty("flutter.sdk") - require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } - flutterSdkPath - } + val flutterSdkPath = run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") @@ -19,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.11.1" apply false - id("org.jetbrains.kotlin.android") version "2.2.20" apply false + id("com.android.application") version "8.9.1" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/mobile/assets/icon/icon.png b/mobile/assets/icon/icon.png new file mode 100644 index 00000000..fbac8d9d Binary files /dev/null and b/mobile/assets/icon/icon.png differ diff --git a/mobile/devtools_options.yaml b/mobile/devtools_options.yaml new file mode 100644 index 00000000..fa0b357c --- /dev/null +++ b/mobile/devtools_options.yaml @@ -0,0 +1,3 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: diff --git a/mobile/ios/Flutter/AppFrameworkInfo.plist b/mobile/ios/Flutter/AppFrameworkInfo.plist index 1dc6cf76..7c569640 100644 --- a/mobile/ios/Flutter/AppFrameworkInfo.plist +++ b/mobile/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 13.0 + 12.0 diff --git a/mobile/ios/Runner.xcodeproj/project.pbxproj b/mobile/ios/Runner.xcodeproj/project.pbxproj index 1f1b1aae..019b0d2c 100644 --- a/mobile/ios/Runner.xcodeproj/project.pbxproj +++ b/mobile/ios/Runner.xcodeproj/project.pbxproj @@ -346,7 +346,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -368,7 +368,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.mobile; + PRODUCT_BUNDLE_IDENTIFIER = io.bottlecrm; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -384,7 +384,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.mobile.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = io.bottlecrm.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -401,7 +401,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.mobile.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = io.bottlecrm.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -416,7 +416,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.mobile.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = io.bottlecrm.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -427,7 +427,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -472,7 +472,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -484,7 +484,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -523,7 +523,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -547,7 +547,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.mobile; + PRODUCT_BUNDLE_IDENTIFIER = io.bottlecrm; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -569,7 +569,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.mobile; + PRODUCT_BUNDLE_IDENTIFIER = io.bottlecrm; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index d36b1fab..d0d98aa1 100644 --- a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,122 +1 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} +{"images":[{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@3x.png","scale":"3x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"Icon-App-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"Icon-App-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}} \ No newline at end of file diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index dc9ada47..54f7c8bf 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 7353c41e..515c0312 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png index 797d452e..a2efca6e 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png index 6ed2d933..999e6e4f 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index 4cd7b009..add7e420 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png index fe730945..9db4e88d 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png index 321773cd..0098d6eb 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 797d452e..a2efca6e 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png index 502f463a..ee28bd08 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index 0ec30343..22316918 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 00000000..faccfa86 Binary files /dev/null and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file mode 100644 index 00000000..e8a4b625 Binary files /dev/null and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 00000000..f3aaf104 Binary files /dev/null and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 00000000..1ceac7c6 Binary files /dev/null and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index 0ec30343..22316918 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index e9f5fea2..c0cffe2b 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 00000000..6672cdd2 Binary files /dev/null and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file mode 100644 index 00000000..586a567f Binary files /dev/null and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index 84ac32ae..eaefaf8c 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index 8953cba0..37006b2f 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index 0467bf12..436ed143 100644 Binary files a/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/mobile/ios/Runner/Info.plist b/mobile/ios/Runner/Info.plist index 43427ad3..777b9f40 100644 --- a/mobile/ios/Runner/Info.plist +++ b/mobile/ios/Runner/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Mobile + Bottlecrm CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - mobile + bottle_crm CFBundlePackageType APPL CFBundleShortVersionString diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index f740c76b..08c84b89 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -1,6 +1,22 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + url: "https://pub.dev" + source: hosted + version: "4.0.7" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" async: dependency: transitive description: @@ -25,6 +41,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + url: "https://pub.dev" + source: hosted + version: "2.0.4" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c + url: "https://pub.dev" + source: hosted + version: "0.4.2" clock: dependency: transitive description: @@ -81,6 +113,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" fl_chart: dependency: "direct main" description: @@ -94,6 +134,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_launcher_icons: + dependency: "direct dev" + description: + name: flutter_launcher_icons + sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7" + url: "https://pub.dev" + source: hosted + version: "0.14.4" flutter_lints: dependency: "direct dev" description: @@ -136,8 +184,56 @@ packages: url: "https://pub.dev" source: hosted version: "6.3.3" - http: + google_identity_services_web: dependency: transitive + description: + name: google_identity_services_web + sha256: "5d187c46dc59e02646e10fe82665fc3884a9b71bc1c90c2b8b749316d33ee454" + url: "https://pub.dev" + source: hosted + version: "0.3.3+1" + google_sign_in: + dependency: "direct main" + description: + name: google_sign_in + sha256: "521031b65853b4409b8213c0387d57edaad7e2a949ce6dea0d8b2afc9cb29763" + url: "https://pub.dev" + source: hosted + version: "7.2.0" + google_sign_in_android: + dependency: transitive + description: + name: google_sign_in_android + sha256: "5ec98ab35387c68c0050495bb211bd88375873723a80fae7c2e9266ea0bdd8bb" + url: "https://pub.dev" + source: hosted + version: "7.2.7" + google_sign_in_ios: + dependency: transitive + description: + name: google_sign_in_ios + sha256: aee8bb29484611a37607849175a2009d423de6bd7c129326c69fd7068f0b6ed7 + url: "https://pub.dev" + source: hosted + version: "6.2.4" + google_sign_in_platform_interface: + dependency: transitive + description: + name: google_sign_in_platform_interface + sha256: "7f59208c42b415a3cca203571128d6f84f885fead2d5b53eb65a9e27f2965bb5" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + google_sign_in_web: + dependency: transitive + description: + name: google_sign_in_web + sha256: "2fc1f941e6443b2d6984f4056a727a3eaeab15d8ee99ba7125d79029be75a1da" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + http: + dependency: "direct main" description: name: http sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" @@ -152,6 +248,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: "51555e36056541237b15b57afc31a0f53d4f9aefd9bd00873a6dc0090e54e332" + url: "https://pub.dev" + source: hosted + version: "4.6.0" intl: dependency: "direct main" description: @@ -160,6 +264,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.19.0" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" + jwt_decoder: + dependency: "direct main" + description: + name: jwt_decoder + sha256: "54774aebf83f2923b99e6416b4ea915d47af3bde56884eb622de85feabbc559f" + url: "https://pub.dev" + source: hosted + version: "2.0.1" leak_tracker: dependency: transitive description: @@ -232,6 +352,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.0" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" + url: "https://pub.dev" + source: hosted + version: "8.3.1" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" + url: "https://pub.dev" + source: hosted + version: "3.2.1" path: dependency: transitive description: @@ -288,6 +424,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" + url: "https://pub.dev" + source: hosted + version: "7.0.1" platform: dependency: transitive description: @@ -304,6 +448,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + posix: + dependency: transitive + description: + name: posix + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + url: "https://pub.dev" + source: hosted + version: "6.0.3" riverpod: dependency: transitive description: @@ -312,6 +464,62 @@ packages: url: "https://pub.dev" source: hosted version: "2.6.1" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "83af5c682796c0f7719c2bbf74792d113e40ae97981b8f266fa84574573556bc" + url: "https://pub.dev" + source: hosted + version: "2.4.18" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" simple_gesture_detector: dependency: transitive description: @@ -485,6 +693,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + win32: + dependency: transitive + description: + name: win32 + sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e + url: "https://pub.dev" + source: hosted + version: "5.15.0" xdg_directories: dependency: transitive description: @@ -493,6 +709,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + url: "https://pub.dev" + source: hosted + version: "6.6.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" sdks: - dart: ">=3.10.4 <4.0.0" + dart: ">=3.9.0 <4.0.0" flutter: ">=3.35.0" diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index d8825a42..90702542 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -1,16 +1,23 @@ -name: mobile -description: "SalesPro CRM - A professional sales CRM mobile application" -publish_to: 'none' +name: bottle_crm +description: "CRM for everyone." +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.0.0+1 +version: 1.0.0+9 environment: - sdk: ^3.10.4 + sdk: ^3.8.1 dependencies: flutter: sdk: flutter + http: ^1.1.0 + google_sign_in: ^7.1.1 + shared_preferences: ^2.2.2 + jwt_decoder: ^2.0.1 + package_info_plus: ^8.0.2 # Icons cupertino_icons: ^1.0.8 lucide_icons: ^0.257.0 @@ -37,7 +44,27 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^6.0.0 + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^6.0.0 + flutter_launcher_icons: "^0.14.4" + +flutter_launcher_icons: + android: "launcher_icon" + ios: true + image_path: "assets/icon/icon.png" + min_sdk_android: 31 # android min sdk Android 12 (API 31) + remove_alpha_ios: true # remove alpha channel from iOS icons, default false + +# The following section is specific to Flutter packages. flutter: uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/icon/ + - assets/images/ diff --git a/mobile/test/widget_test.dart b/mobile/test/widget_test.dart deleted file mode 100644 index c4b66f98..00000000 --- a/mobile/test/widget_test.dart +++ /dev/null @@ -1,23 +0,0 @@ -// SalesPro CRM Widget Test - -import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; - -import 'package:mobile/main.dart'; - -void main() { - testWidgets('SalesPro app smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget( - const ProviderScope( - child: SalesProApp(), - ), - ); - - // Wait for splash screen animation - await tester.pump(const Duration(seconds: 1)); - - // Verify that the app starts - expect(find.byType(SalesProApp), findsOneWidget); - }); -}