diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..042d39f Binary files /dev/null and b/.DS_Store differ diff --git a/backend/migration_referral_system.sql b/backend/migration_referral_system.sql new file mode 100644 index 0000000..e65988c --- /dev/null +++ b/backend/migration_referral_system.sql @@ -0,0 +1,36 @@ +-- 1. Table for storing the unified 6-digit referral code for each user (Driver/Passenger) +CREATE TABLE `user_referral_codes` ( + `id` INT NOT NULL AUTO_INCREMENT, + `user_id` VARCHAR(100) NOT NULL, + `user_type` ENUM('driver', 'passenger') NOT NULL, + `referral_code` VARCHAR(6) NOT NULL, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `idx_user_type_id` (`user_id`, `user_type`), + UNIQUE KEY `idx_referral_code` (`referral_code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- 2. Table for tracking the referral relationship and trip counts +CREATE TABLE `unified_referrals` ( + `id` INT NOT NULL AUTO_INCREMENT, + `inviter_code` VARCHAR(6) NOT NULL, + `invited_user_id` VARCHAR(100) NOT NULL, + `invited_user_type` ENUM('driver', 'passenger') NOT NULL, + `status` ENUM('registered', 'active', 'completed') NOT NULL DEFAULT 'registered', + `trip_count` INT NOT NULL DEFAULT 0, + `is_reward_claimed` TINYINT(1) NOT NULL DEFAULT 0, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `idx_invited_user` (`invited_user_id`, `invited_user_type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- 3. Table for Driver Cash Claims (when a driver requests to receive their reward as manual cash) +CREATE TABLE `driver_cash_claims` ( + `id` INT NOT NULL AUTO_INCREMENT, + `driver_id` VARCHAR(100) NOT NULL, + `referral_id` INT NOT NULL, + `amount_syp` INT NOT NULL, + `status` ENUM('pending', 'paid') NOT NULL DEFAULT 'pending', + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; diff --git a/backend/ride/invitor/add_unified_invite.php b/backend/ride/invitor/add_unified_invite.php new file mode 100644 index 0000000..bea21c6 --- /dev/null +++ b/backend/ride/invitor/add_unified_invite.php @@ -0,0 +1,37 @@ +prepare("SELECT user_id, user_type FROM user_referral_codes WHERE referral_code = ?"); +$stmtCheck->execute([$inviterCode]); + +if ($stmtCheck->rowCount() == 0) { + jsonError("Invalid referral code"); +} +$inviterData = $stmtCheck->fetch(PDO::FETCH_ASSOC); + +// Check if user was already invited +$stmtExisting = $con->prepare("SELECT id FROM unified_referrals WHERE invited_user_id = ? AND invited_user_type = ?"); +$stmtExisting->execute([$user_id, $role]); + +if ($stmtExisting->rowCount() > 0) { + jsonError("User already registered with a referral code"); +} + +// Insert new referral +$insertStmt = $con->prepare("INSERT INTO unified_referrals (inviter_code, invited_user_id, invited_user_type, status, trip_count, is_reward_claimed) VALUES (?, ?, ?, 'registered', 0, 0)"); + +try { + $insertStmt->execute([$inviterCode, $user_id, $role]); + printSuccess(["message" => "Referral linked successfully"]); +} catch (PDOException $e) { + jsonError("Database error: " . $e->getMessage()); +} +?> diff --git a/backend/ride/invitor/claim_driver_reward.php b/backend/ride/invitor/claim_driver_reward.php new file mode 100644 index 0000000..0636310 --- /dev/null +++ b/backend/ride/invitor/claim_driver_reward.php @@ -0,0 +1,80 @@ +prepare(" + SELECT r.id, r.inviter_code, r.invited_user_id, r.invited_user_type, r.trip_count, r.is_reward_claimed, c.user_id as inviter_id, c.user_type as inviter_type + FROM unified_referrals r + JOIN user_referral_codes c ON r.inviter_code = c.referral_code + WHERE r.id = ? AND c.user_id = ? AND c.user_type = 'driver' +"); +$stmt->execute([$referralId, $user_id]); + +if ($stmt->rowCount() == 0) { + jsonError("Referral not found or unauthorized"); +} + +$referral = $stmt->fetch(PDO::FETCH_ASSOC); + +if ($referral['is_reward_claimed'] == 1) { + jsonError("Reward already claimed"); +} + +// Logic: +// Driver -> Driver: 50 trips = 500 SYP (example) +// Driver -> Passenger: 10 trips = 30 SYP per trip. This could be progressive, but for manual claim we assume completed +$amountSyp = 0; + +if ($referral['invited_user_type'] == 'driver') { + if ($referral['trip_count'] >= 50) { + $amountSyp = 500; + } else { + jsonError("Requirement not met (50 trips required)"); + } +} else if ($referral['invited_user_type'] == 'passenger') { + if ($referral['trip_count'] >= 1) { + // Here, user gets 30 SYP per trip, max 10. Let's assume claim all at once up to 10. + $tripsToClaim = min($referral['trip_count'], 10); + $amountSyp = $tripsToClaim * 30; + } else { + jsonError("Requirement not met (At least 1 trip required)"); + } +} + +if ($amountSyp <= 0) { + jsonError("No reward available to claim"); +} + +try { + $con->beginTransaction(); + + // Mark as claimed + $updateStmt = $con->prepare("UPDATE unified_referrals SET is_reward_claimed = 1, status = 'claimed' WHERE id = ?"); + $updateStmt->execute([$referralId]); + + if ($claimType == 'wallet') { + // Add to driver wallet + $walletStmt = $con->prepare("UPDATE driver SET wallet = wallet + ? WHERE id = ?"); + $walletStmt->execute([$amountSyp, $user_id]); + } else if ($claimType == 'cash') { + // Request manual cash out + $cashStmt = $con->prepare("INSERT INTO driver_cash_claims (driver_id, referral_id, amount_syp, status) VALUES (?, ?, ?, 'pending')"); + $cashStmt->execute([$user_id, $referralId, $amountSyp]); + } + + $con->commit(); + printSuccess(["message" => "Reward claimed successfully as $claimType"]); + +} catch (PDOException $e) { + $con->rollBack(); + jsonError("Database error: " . $e->getMessage()); +} +?> diff --git a/backend/ride/invitor/get_driver_referrals.php b/backend/ride/invitor/get_driver_referrals.php new file mode 100644 index 0000000..12c4c7b --- /dev/null +++ b/backend/ride/invitor/get_driver_referrals.php @@ -0,0 +1,60 @@ +prepare("SELECT referral_code FROM user_referral_codes WHERE user_id = ? AND user_type = 'driver'"); +$stmtCode->execute([$user_id]); + +if ($stmtCode->rowCount() == 0) { + // If no code exists, return empty stats + printSuccess([ + "referral_code" => null, + "total_invited_drivers" => 0, + "total_invited_passengers" => 0, + "referrals" => [] + ]); + exit; +} + +$referralCode = $stmtCode->fetchColumn(); + +// 2. Fetch all referrals made by this code +$stmtRefs = $con->prepare(" + SELECT id, invited_user_id, invited_user_type, status, trip_count, is_reward_claimed, created_at + FROM unified_referrals + WHERE inviter_code = ? + ORDER BY created_at DESC +"); +$stmtRefs->execute([$referralCode]); +$referrals = $stmtRefs->fetchAll(PDO::FETCH_ASSOC); + +$totalDrivers = 0; +$totalPassengers = 0; + +// Format data and calculate stats +foreach ($referrals as &$ref) { + if ($ref['invited_user_type'] == 'driver') { + $totalDrivers++; + $ref['target_trips'] = 50; + $ref['reward_syp'] = 500; + $ref['can_claim'] = ($ref['trip_count'] >= 50 && $ref['is_reward_claimed'] == 0) ? true : false; + } else { + $totalPassengers++; + $ref['target_trips'] = 1; + $ref['reward_syp'] = 30 * min($ref['trip_count'], 10); // Or max depending on logic + $ref['can_claim'] = ($ref['trip_count'] >= 1 && $ref['is_reward_claimed'] == 0) ? true : false; + } +} + +printSuccess([ + "referral_code" => $referralCode, + "total_invited_drivers" => $totalDrivers, + "total_invited_passengers" => $totalPassengers, + "referrals" => $referrals +]); +?> diff --git a/backend/ride/invitor/get_passenger_referrals.php b/backend/ride/invitor/get_passenger_referrals.php new file mode 100644 index 0000000..0e2d82e --- /dev/null +++ b/backend/ride/invitor/get_passenger_referrals.php @@ -0,0 +1,60 @@ +prepare("SELECT referral_code FROM user_referral_codes WHERE user_id = ? AND user_type = 'passenger'"); +$stmtCode->execute([$user_id]); + +if ($stmtCode->rowCount() == 0) { + // If no code exists, return empty stats + printSuccess([ + "referral_code" => null, + "total_invited_drivers" => 0, + "total_invited_passengers" => 0, + "referrals" => [] + ]); + exit; +} + +$referralCode = $stmtCode->fetchColumn(); + +// 2. Fetch all referrals made by this code +$stmtRefs = $con->prepare(" + SELECT id, invited_user_id, invited_user_type, status, trip_count, is_reward_claimed, created_at + FROM unified_referrals + WHERE inviter_code = ? + ORDER BY created_at DESC +"); +$stmtRefs->execute([$referralCode]); +$referrals = $stmtRefs->fetchAll(PDO::FETCH_ASSOC); + +$totalDrivers = 0; +$totalPassengers = 0; + +// Format data and calculate stats +foreach ($referrals as &$ref) { + if ($ref['invited_user_type'] == 'driver') { + $totalDrivers++; + $ref['target_trips'] = 50; + $ref['reward_syp'] = 500; + $ref['can_claim'] = ($ref['trip_count'] >= 50 && $ref['is_reward_claimed'] == 0) ? true : false; + } else { + $totalPassengers++; + $ref['target_trips'] = 1; + $ref['reward_syp'] = 30; // Just illustrative, rewards are automatic + $ref['can_claim'] = ($ref['trip_count'] >= 1 && $ref['is_reward_claimed'] == 0) ? true : false; + } +} + +printSuccess([ + "referral_code" => $referralCode, + "total_invited_drivers" => $totalDrivers, + "total_invited_passengers" => $totalPassengers, + "referrals" => $referrals +]); +?> diff --git a/backend/ride/invitor/get_unified_code.php b/backend/ride/invitor/get_unified_code.php new file mode 100644 index 0000000..db76a4a --- /dev/null +++ b/backend/ride/invitor/get_unified_code.php @@ -0,0 +1,41 @@ +prepare("SELECT COUNT(*) FROM user_referral_codes WHERE referral_code = ?"); + $stmt->execute([$code]); + + if ($stmt->fetchColumn() == 0) { + return $code; + } + } +} + +// Ensure the JWT values exist +if (!$user_id || !in_array($role, ['driver', 'passenger'])) { + jsonError("Invalid or missing user information in token"); +} + +$stmt = $con->prepare("SELECT referral_code FROM user_referral_codes WHERE user_id = ? AND user_type = ?"); +$stmt->execute([$user_id, $role]); + +if ($stmt->rowCount() > 0) { + $row = $stmt->fetch(PDO::FETCH_ASSOC); + printSuccess(["referral_code" => $row['referral_code']]); +} else { + $newCode = generateUnifiedCode($con); + $insertStmt = $con->prepare("INSERT INTO user_referral_codes (user_id, user_type, referral_code) VALUES (?, ?, ?)"); + + try { + $insertStmt->execute([$user_id, $role, $newCode]); + printSuccess(["referral_code" => $newCode]); + } catch (PDOException $e) { + jsonError("Database error: " . $e->getMessage()); + } +} +?> diff --git a/backend/schema_primary.sql b/backend/schema_primary.sql index 3efeeb6..6dfee49 100644 --- a/backend/schema_primary.sql +++ b/backend/schema_primary.sql @@ -1782,3 +1782,45 @@ CREATE TABLE `write_argument_after_applied_from_background` ( /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2026-04-22 19:40:54 + +-- +-- Table structure for table `user_referral_codes` +-- +CREATE TABLE IF NOT EXISTS `user_referral_codes` ( + `id` int NOT NULL AUTO_INCREMENT, + `user_id` varchar(100) NOT NULL, + `user_type` enum('driver','passenger') NOT NULL, + `referral_code` varchar(20) NOT NULL UNIQUE, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- Table structure for table `unified_referrals` +-- +CREATE TABLE IF NOT EXISTS `unified_referrals` ( + `id` int NOT NULL AUTO_INCREMENT, + `inviter_code` varchar(20) NOT NULL, + `invited_user_id` varchar(100) NOT NULL, + `invited_user_type` enum('driver','passenger') NOT NULL, + `status` enum('registered','first_trip','claimed') DEFAULT 'registered', + `trip_count` int DEFAULT 0, + `is_reward_claimed` tinyint(1) DEFAULT 0, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- Table structure for table `driver_cash_claims` +-- +CREATE TABLE IF NOT EXISTS `driver_cash_claims` ( + `id` int NOT NULL AUTO_INCREMENT, + `driver_id` varchar(100) NOT NULL, + `referral_id` int NOT NULL, + `amount_syp` decimal(10,2) NOT NULL, + `status` enum('pending','paid','rejected') DEFAULT 'pending', + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/backend/schema_ride.sql b/backend/schema_ride.sql index 17b8e9b..07cf5b4 100644 --- a/backend/schema_ride.sql +++ b/backend/schema_ride.sql @@ -208,8 +208,8 @@ CREATE TABLE `car_locations` ( /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50017 DEFINER=`intaleq-rides`@`%`*/ /*!50003 TRIGGER `trg_before_insert_car_locations` BEFORE INSERT ON `car_locations` FOR EACH ROW BEGIN -SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); +/*!50003 CREATE*/ /*!50017 DEFINER=`intaleq-rides`@`%`*/ /*!50003 TRIGGER `trg_before_insert_car_locations` BEFORE INSERT ON `car_locations` FOR EACH ROW BEGIN +SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -225,10 +225,10 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50017 DEFINER=`intaleq-rides`@`%`*/ /*!50003 TRIGGER `trg_before_update_car_locations` BEFORE UPDATE ON `car_locations` FOR EACH ROW BEGIN -IF NEW.latitude <> OLD.latitude OR NEW.longitude <> OLD.longitude THEN -SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); -END IF; +/*!50003 CREATE*/ /*!50017 DEFINER=`intaleq-rides`@`%`*/ /*!50003 TRIGGER `trg_before_update_car_locations` BEFORE UPDATE ON `car_locations` FOR EACH ROW BEGIN +IF NEW.latitude <> OLD.latitude OR NEW.longitude <> OLD.longitude THEN +SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); +END IF; END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; diff --git a/copy_native_and_packages.py b/copy_native_and_packages.py deleted file mode 100644 index 902e6c8..0000000 --- a/copy_native_and_packages.py +++ /dev/null @@ -1,118 +0,0 @@ -import os -import shutil - -SOURCE_DIR = "/Users/hamzaaleghwairyeen/development/App" -TARGET_DIR = "/Users/hamzaaleghwairyeen/development/App/Siro" - -mappings = [ - { - "src": "Intaleq", - "dst": "siro_rider", - "old_app_id": "com.Intaleq.intaleq", - "new_app_id": "com.siro.siro_rider", - "extra_folders": ["packages"] - }, - { - "src": "intaleq_driver", - "dst": "siro_driver", - "old_app_id": "com.intaleq_driver", - "new_app_id": "com.siro.siro_driver", - "extra_folders": ["bubble-master", "trip_overlay_plugin"] - }, - { - "src": "intaleq_admin", - "dst": "siro_admin", - "old_app_id": "com.intaleq.intaleq_admin", - "new_app_id": "com.siro.siro_admin", - "extra_folders": [] - }, - { - "src": "service_intaleq", - "dst": "siro_service", - "old_app_id": "com.service_intaleq", - "new_app_id": "com.siro.siro_service", - "extra_folders": [] - } -] - -def replace_in_file(filepath, old_str, new_str): - try: - with open(filepath, 'r', encoding='utf-8') as f: - content = f.read() - if old_str in content: - content = content.replace(old_str, new_str) - with open(filepath, 'w', encoding='utf-8') as f: - f.write(content) - except Exception as e: - pass - -def process(): - for m in mappings: - src_app = os.path.join(SOURCE_DIR, m['src']) - dst_app = os.path.join(TARGET_DIR, m['dst']) - - print(f"Processing native folders for {m['dst']}...") - - # 1. Copy native folders - native_folders = ['android', 'ios', 'macos', 'web'] - for folder in native_folders: - s_folder = os.path.join(src_app, folder) - d_folder = os.path.join(dst_app, folder) - if os.path.exists(s_folder): - if os.path.exists(d_folder): - shutil.rmtree(d_folder) - shutil.copytree(s_folder, d_folder, symlinks=True, ignore=shutil.ignore_patterns('.symlinks', 'Pods', 'build', '.dart_tool')) - - # 2. Copy extra internal packages - for folder in m['extra_folders']: - s_folder = os.path.join(src_app, folder) - d_folder = os.path.join(dst_app, folder) - if os.path.exists(s_folder): - if os.path.exists(d_folder): - shutil.rmtree(d_folder) - shutil.copytree(s_folder, d_folder, symlinks=True, ignore=shutil.ignore_patterns('build', '.dart_tool')) - - # 3. Android Package Renaming - old_app_id = m['old_app_id'] - new_app_id = m['new_app_id'] - - android_dir = os.path.join(dst_app, 'android') - if os.path.exists(android_dir): - # Replace string occurrences in Android files - for root, dirs, files in os.walk(android_dir): - for file in files: - if file.endswith(('.kt', '.java', '.xml', '.gradle', '.gradle.kts', '.pro')): - replace_in_file(os.path.join(root, file), old_app_id, new_app_id) - - # Move kotlin/java directory structure - for lang in ['kotlin', 'java']: - for source_type in ['main', 'debug', 'profile']: - src_dir = os.path.join(android_dir, 'app', 'src', source_type, lang) - if os.path.exists(src_dir): - old_path = os.path.join(src_dir, *old_app_id.split('.')) - new_path = os.path.join(src_dir, *new_app_id.split('.')) - - if os.path.exists(old_path) and old_path != new_path: - os.makedirs(new_path, exist_ok=True) - for item in os.listdir(old_path): - shutil.move(os.path.join(old_path, item), new_path) - - # Clean up old empty directories - curr = old_path - while curr != src_dir: - if not os.listdir(curr): - os.rmdir(curr) - curr = os.path.dirname(curr) - - # 4. iOS Bundle ID Renaming - ios_dir = os.path.join(dst_app, 'ios') - if os.path.exists(ios_dir): - for root, dirs, files in os.walk(ios_dir): - for file in files: - if file.endswith(('.pbxproj', '.plist', '.m', '.h', '.swift', '.storyboard', '.xcconfig')): - replace_in_file(os.path.join(root, file), old_app_id, new_app_id) - - print("Done copying and modifying native folders.") - -if __name__ == "__main__": - process() diff --git a/copy_script.dart b/copy_script.dart deleted file mode 100644 index 590e5cb..0000000 --- a/copy_script.dart +++ /dev/null @@ -1,84 +0,0 @@ -import 'dart:io'; - -void main() async { - var sourceDir = Directory("/Users/hamzaaleghwairyeen/development/App"); - var targetDir = Directory("/Users/hamzaaleghwairyeen/development/App/Siro"); - - var mappings = [ - {"src": "Intaleq", "dst": "siro_rider", "old_pkg": "Intaleq", "new_pkg": "siro_rider"}, - {"src": "intaleq_driver", "dst": "siro_driver", "old_pkg": "sefer_driver", "new_pkg": "siro_driver"}, - {"src": "intaleq_admin", "dst": "siro_admin", "old_pkg": "sefer_admin1", "new_pkg": "siro_admin"}, - {"src": "service_intaleq", "dst": "siro_service", "old_pkg": "service", "new_pkg": "siro_service"} - ]; - - for (var m in mappings) { - var srcPath = "\${sourceDir.path}/\${m['src']}"; - var dstPath = "\${targetDir.path}/\${m['dst']}"; - - // 1. Delete destination lib and assets - for (var folder in ['lib', 'assets', 'secure_string_operations']) { - var dFolder = Directory("\$dstPath/\$folder"); - if (dFolder.existsSync()) { - dFolder.deleteSync(recursive: true); - } - } - - // 2. Copy lib and assets - for (var folder in ['lib', 'assets', 'secure_string_operations']) { - var sFolder = Directory("\$srcPath/\$folder"); - var dFolder = Directory("\$dstPath/\$folder"); - if (sFolder.existsSync()) { - copyDirectorySync(sFolder, dFolder); - } - } - - // 3. Copy pubspec.yaml - var sPubspec = File("\$srcPath/pubspec.yaml"); - var dPubspec = File("\$dstPath/pubspec.yaml"); - if (sPubspec.existsSync()) { - sPubspec.copySync(dPubspec.path); - } - - // 4. Replace package name in pubspec.yaml - if (dPubspec.existsSync()) { - var content = dPubspec.readAsStringSync(); - content = content.replaceAll(RegExp(r"^name:\s*" + m["old_pkg"]! + r"\s*$", multiLine: true), "name: \${m['new_pkg']}"); - dPubspec.writeAsStringSync(content); - } - - // 5. Replace imports - for (var rootFolder in ['lib', 'test']) { - var rootPath = Directory("\$dstPath/\$rootFolder"); - if (!rootPath.existsSync()) continue; - - var files = rootPath.listSync(recursive: true).whereType(); - for (var file in files) { - if (file.path.endsWith('.dart')) { - try { - var content = file.readAsStringSync(); - var newContent = content.replaceAll("package:\${m['old_pkg']}/", "package:\${m['new_pkg']}/"); - if (newContent != content) { - file.writeAsStringSync(newContent); - } - } catch (e) { - print("Error reading \${file.path}: \$e"); - } - } - } - } - } - print("Done"); -} - -void copyDirectorySync(Directory source, Directory destination) { - destination.createSync(recursive: true); - for (var entity in source.listSync(recursive: false)) { - if (entity is Directory) { - var newDirectory = Directory("\${destination.absolute.path}/\${entity.path.split('/').last}"); - newDirectory.createSync(); - copyDirectorySync(entity.absolute, newDirectory); - } else if (entity is File) { - entity.copySync("\${destination.path}/\${entity.path.split('/').last}"); - } - } -} diff --git a/copy_script.py b/copy_script.py deleted file mode 100644 index 14be8c2..0000000 --- a/copy_script.py +++ /dev/null @@ -1,70 +0,0 @@ -import os -import shutil - -source_dir = "/Users/hamzaaleghwairyeen/development/App" -target_dir = "/Users/hamzaaleghwairyeen/development/App/Siro" - -mappings = [ - {"src": "Intaleq", "dst": "siro_rider", "old_pkg": "Intaleq", "new_pkg": "siro_rider"}, - {"src": "intaleq_driver", "dst": "siro_driver", "old_pkg": "sefer_driver", "new_pkg": "siro_driver"}, - {"src": "intaleq_admin", "dst": "siro_admin", "old_pkg": "sefer_admin1", "new_pkg": "siro_admin"}, - {"src": "service_intaleq", "dst": "siro_service", "old_pkg": "service", "new_pkg": "siro_service"} -] - -def copy_and_replace(): - for m in mappings: - src_path = os.path.join(source_dir, m['src']) - dst_path = os.path.join(target_dir, m['dst']) - - # 1. Delete destination lib and assets if exist - for folder in ['lib', 'assets', 'secure_string_operations']: - d_folder = os.path.join(dst_path, folder) - if os.path.exists(d_folder): - shutil.rmtree(d_folder) - - # 2. Copy lib and assets - for folder in ['lib', 'assets', 'secure_string_operations']: - s_folder = os.path.join(src_path, folder) - d_folder = os.path.join(dst_path, folder) - if os.path.exists(s_folder): - shutil.copytree(s_folder, d_folder) - - # 3. Copy pubspec.yaml - s_pubspec = os.path.join(src_path, "pubspec.yaml") - d_pubspec = os.path.join(dst_path, "pubspec.yaml") - if os.path.exists(s_pubspec): - shutil.copy2(s_pubspec, d_pubspec) - - # 4. Replace package name in pubspec.yaml - if os.path.exists(d_pubspec): - with open(d_pubspec, 'r', encoding='utf-8') as f: - content = f.read() - # replace name: old_pkg with name: new_pkg - import re - content = re.sub(rf'^name:\s*{m["old_pkg"]}\s*$', f'name: {m["new_pkg"]}', content, flags=re.MULTILINE) - with open(d_pubspec, 'w', encoding='utf-8') as f: - f.write(content) - - # 5. Replace imports in lib and test directories - for root_folder in ['lib', 'test']: - root_path = os.path.join(dst_path, root_folder) - if not os.path.exists(root_path): continue - - for root, dirs, files in os.walk(root_path): - for file in files: - if file.endswith('.dart'): - file_path = os.path.join(root, file) - try: - with open(file_path, 'r', encoding='utf-8') as f: - content = f.read() - - new_content = content.replace(f"package:{m['old_pkg']}/", f"package:{m['new_pkg']}/") - if new_content != content: - with open(file_path, 'w', encoding='utf-8') as f: - f.write(new_content) - except Exception as e: - print(f"Error reading {file_path}: {e}") - -if __name__ == "__main__": - copy_and_replace() - print("Done") diff --git a/copy_script.sh b/copy_script.sh deleted file mode 100644 index 463ab55..0000000 --- a/copy_script.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -set -e - -SOURCE_DIR="/Users/hamzaaleghwairyeen/development/App" -TARGET_DIR="/Users/hamzaaleghwairyeen/development/App/Siro" - -declare -a mappings=( - "Intaleq:siro_rider:Intaleq:siro_rider" - "intaleq_driver:siro_driver:sefer_driver:siro_driver" - "intaleq_admin:siro_admin:sefer_admin1:siro_admin" - "service_intaleq:siro_service:service:siro_service" -) - -for mapping in "${mappings[@]}"; do - IFS=":" read -r src dst old_pkg new_pkg <<< "$mapping" - src_path="$SOURCE_DIR/$src" - dst_path="$TARGET_DIR/$dst" - - echo "Processing $dst..." - - # 1. Delete destination lib and assets - for folder in lib assets secure_string_operations; do - if [ -d "$dst_path/$folder" ]; then - rm -rf "$dst_path/$folder" - fi - done - - # 2. Copy lib and assets - for folder in lib assets secure_string_operations; do - if [ -d "$src_path/$folder" ]; then - cp -R "$src_path/$folder" "$dst_path/" - fi - done - - # 3. Copy pubspec.yaml - if [ -f "$src_path/pubspec.yaml" ]; then - cp "$src_path/pubspec.yaml" "$dst_path/pubspec.yaml" - fi - - # 4. Replace package name in pubspec.yaml using perl - if [ -f "$dst_path/pubspec.yaml" ]; then - perl -pi -e "s/^name:\s*$old_pkg\s*$/name: $new_pkg/" "$dst_path/pubspec.yaml" - fi - - # 5. Replace imports using perl - for root_folder in lib test; do - if [ -d "$dst_path/$root_folder" ]; then - find "$dst_path/$root_folder" -type f -name "*.dart" -exec perl -pi -e "s/package:$old_pkg\//package:$new_pkg\//g" {} + - fi - done -done - -echo "Done" diff --git a/marketing-pages/damascus_zones_map.html b/marketing-pages/damascus_zones_map.html new file mode 100644 index 0000000..08ea68e --- /dev/null +++ b/marketing-pages/damascus_zones_map.html @@ -0,0 +1,126 @@ + + + + + + خارطة التوسع الجغرافي - دمشق + + + + + +
+ + + + + diff --git a/run_generation.sh b/run_generation.sh new file mode 100755 index 0000000..93e5032 --- /dev/null +++ b/run_generation.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +echo "🚀 Generating SIRO Rider App Icons..." +cd /Users/hamzaaleghwairyeen/development/App/Siro/siro_rider +flutter clean +flutter pub get +dart run flutter_launcher_icons:main + +echo "🚀 Generating SIRO Driver App Icons..." +cd /Users/hamzaaleghwairyeen/development/App/Siro/siro_driver +flutter clean +flutter pub get +dart run flutter_launcher_icons:main + +echo "🎨 Generating Animated GIF for SIRO Rider & Driver..." +cd /Users/hamzaaleghwairyeen/development/App/Siro +python3 -m pip install Pillow --break-system-packages +python3 /Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/a5945c2c-de5f-4478-bd3c-d2f1c3aeec6a/scratch/pulse_logo.py /Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/assets/images/logo.png /Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/assets/images/logo.gif +cp /Users/hamzaaleghwairyeen/development/App/Siro/siro_rider/assets/images/logo.gif /Users/hamzaaleghwairyeen/development/App/Siro/siro_driver/assets/images/logo.gif + +echo "🍏 Fixing iOS App Icon names to match old format..." +python3 /Users/hamzaaleghwairyeen/.gemini/antigravity-ide/brain/a5945c2c-de5f-4478-bd3c-d2f1c3aeec6a/scratch/fix_ios_icons.py + +echo "✅ All Done! Icons and Animated GIFs are ready." diff --git a/siro_driver/android/app/src/main/AndroidManifest.xml b/siro_driver/android/app/src/main/AndroidManifest.xml index 820c8b2..cce5eea 100644 --- a/siro_driver/android/app/src/main/AndroidManifest.xml +++ b/siro_driver/android/app/src/main/AndroidManifest.xml @@ -63,12 +63,21 @@ - + - + + + + + + + + + + diff --git a/siro_driver/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/siro_driver/android/app/src/main/res/mipmap-hdpi/launcher_icon.png index 458d624..3962f46 100644 Binary files a/siro_driver/android/app/src/main/res/mipmap-hdpi/launcher_icon.png and b/siro_driver/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/siro_driver/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/siro_driver/android/app/src/main/res/mipmap-mdpi/launcher_icon.png index a791ff0..3a61ede 100644 Binary files a/siro_driver/android/app/src/main/res/mipmap-mdpi/launcher_icon.png and b/siro_driver/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/siro_driver/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/siro_driver/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png index c8d1f66..639d661 100644 Binary files a/siro_driver/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png and b/siro_driver/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/siro_driver/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/siro_driver/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png index 399b5c7..84f5bed 100644 Binary files a/siro_driver/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png and b/siro_driver/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/siro_driver/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/siro_driver/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png index 3a3a63f..af9142f 100644 Binary files a/siro_driver/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png and b/siro_driver/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/siro_driver/assets/images/logo.gif b/siro_driver/assets/images/logo.gif index 0eeabc0..f505c82 100644 Binary files a/siro_driver/assets/images/logo.gif and b/siro_driver/assets/images/logo.gif differ diff --git a/siro_driver/assets/images/logo.png b/siro_driver/assets/images/logo.png index 610bef1..9852116 100644 Binary files a/siro_driver/assets/images/logo.png and b/siro_driver/assets/images/logo.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png index ab72d10..2901dbe 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png index c9417c1..6f286c2 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png index 9ba42fe..26c5e16 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png index 6697c04..74e5af9 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png deleted file mode 100644 index d722206..0000000 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png and /dev/null differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png index 1769fed..84f5bed 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png index ab65536..8a48943 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png deleted file mode 100644 index d7d286f..0000000 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png and /dev/null differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png index 62616ad..0f2d72b 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png index 211f5d4..fd974b8 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png index fdbc237..4a804bd 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png deleted file mode 100644 index 2ccbcd9..0000000 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png and /dev/null differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png index 64d5a43..c75c9e6 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png deleted file mode 100644 index f080356..0000000 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png and /dev/null differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png index 417944d..d94f99a 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png index ce44407..2be6e4b 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png deleted file mode 100644 index 630dffd..0000000 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png and /dev/null differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png index 38d001b..63df0bf 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png index 86eec95..b9b6d84 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png index 52b37ec..4468ee0 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png deleted file mode 100644 index de1d829..0000000 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png and /dev/null differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png index 12200c1..3962f46 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png index 9336a6a..6845d01 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png index 3d9ae6f..48fdd8e 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png index 934d30c..a762921 100644 Binary files a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png and b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png differ diff --git a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index 5c82812..6973678 100644 --- a/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/siro_driver/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1 +1,158 @@ -{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]} \ No newline at end of file +{ + "images": [ + { + "size": "20x20", + "idiom": "iphone", + "filename": "40.png", + "scale": "2x" + }, + { + "size": "20x20", + "idiom": "iphone", + "filename": "60.png", + "scale": "3x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "29.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "58.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "87.png", + "scale": "3x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "80.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "120.png", + "scale": "3x" + }, + { + "size": "57x57", + "idiom": "iphone", + "filename": "57.png", + "scale": "1x" + }, + { + "size": "57x57", + "idiom": "iphone", + "filename": "114.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "120.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "180.png", + "scale": "3x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "20.png", + "scale": "1x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "40.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "29.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "58.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "40.png", + "scale": "1x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "80.png", + "scale": "2x" + }, + { + "size": "50x50", + "idiom": "ipad", + "filename": "50.png", + "scale": "1x" + }, + { + "size": "50x50", + "idiom": "ipad", + "filename": "100.png", + "scale": "2x" + }, + { + "size": "72x72", + "idiom": "ipad", + "filename": "72.png", + "scale": "1x" + }, + { + "size": "72x72", + "idiom": "ipad", + "filename": "144.png", + "scale": "2x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "76.png", + "scale": "1x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "152.png", + "scale": "2x" + }, + { + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "167.png", + "scale": "2x" + }, + { + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "1024.png", + "scale": "1x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/siro_driver/ios/Runner/Info.plist b/siro_driver/ios/Runner/Info.plist index 07b06c6..73f68a3 100644 --- a/siro_driver/ios/Runner/Info.plist +++ b/siro_driver/ios/Runner/Info.plist @@ -32,6 +32,21 @@ ???? CFBundleVersion 33 + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + siromove.com + CFBundleURLSchemes + + siromove + + + + FlutterDeepLinkingEnabled + FirebaseAppDelegateProxyEnabled NO GMSApiKey diff --git a/siro_driver/lib/constant/colors.dart b/siro_driver/lib/constant/colors.dart index 3fd235f..b78fd8b 100755 --- a/siro_driver/lib/constant/colors.dart +++ b/siro_driver/lib/constant/colors.dart @@ -3,67 +3,34 @@ import 'package:get/get.dart'; class AppColor { // --- Core Brand Colors --- + static const Color primaryColor = Color(0xFF1A2340); // Navy Blue + static const Color secondaryColorStatic = Color(0xFF8C9CF8); // Periwinkle Blue + static const Color accentColor = Color(0xFF8C9CF8); - /// **Primary Color:** The brand's signature blue. - static const Color primaryColor = Color(0xFF1DA1F2); - - /// **Text/Write Color:** Dynamic based on theme. - static Color get writeColor => - Get.isDarkMode ? Colors.white : const Color(0xFF1A1A1A); - - /// **Secondary Color:** Main background color, dynamic based on theme. - static Color get secondaryColor => - Get.isDarkMode ? const Color(0xFF121212) : Colors.white; - - /// **Surface Color:** For cards and elevated elements. - static Color get surfaceColor => - Get.isDarkMode ? const Color(0xFF1E1E1E) : Colors.white; - - /// **Card Color:** Specifically for card backgrounds. - static Color get cardColor => - Get.isDarkMode ? const Color(0xFF1E1E1E) : Colors.white; - - /// **Border Color:** Subtle borders for both modes. - static Color get borderColor => - Get.isDarkMode ? Colors.white10 : Colors.black12; - - /// **Accent Color:** Greyish accent. - static const Color accentColor = Color.fromARGB(255, 148, 140, 141); + // --- Dynamic Colors (Light / Dark Mode Support) --- + static Color get writeColor => Get.isDarkMode ? Colors.white : const Color(0xFF0F172A); // Primary Text + static Color get secondaryColor => Get.isDarkMode ? const Color(0xFF1E1E1E) : const Color(0xFFF8FAFC); // Background + static Color get cardColor => Get.isDarkMode ? const Color(0xFF2C2C2E) : const Color(0xFFFFFFFF); // Card Background + static Color get surfaceColor => cardColor; // Added back for backwards compatibility // --- Neutral & Status Colors --- + static Color get grayColor => Get.isDarkMode ? Colors.grey[400]! : const Color(0xFF64748B); // Secondary Text + static Color get borderColor => Get.isDarkMode ? const Color(0xFF3A3A3C) : const Color(0xFFE2E8F0); // Border - /// **Grey Color:** Dynamic based on theme. - static Color get grayColor => - Get.isDarkMode ? Colors.grey[400]! : const Color(0xFF8E8E93); - - /// **Red Color (Error):** Clear red for alerts. - static const Color redColor = Color(0xFFD32F2F); - - /// **Green Color (Success):** Positive green. - static const Color greenColor = Color(0xFF388E3C); - - /// **Blue Color (Info):** Info text or success green variant. - static const Color blueColor = Color(0xFF1DA1F2); - - /// **Yellow Color (Warning):** Warm yellow. - static const Color yellowColor = Color(0xFFFFA000); - - // --- Tier & Social Colors --- + static const Color redColor = Color(0xFFEF4444); // Error + static const Color greenColor = Color(0xFF22C55E); // Success + static const Color yellowColor = Color(0xFFF59E0B); // Warning + // --- Legacy / Maps Colors (Kept for compatibility) --- + static const Color blueColor = Color(0xFF1A2340); static const Color gold = Color(0xFFFFD700); static const Color bronze = Color(0xFFCD7F32); - static const Color goldenBronze = Color(0xFFB87333); - static const Color twitterColor = Color(0xFF1DA1F2); - - // --- Utility Colors --- - - static Color get greyColor => grayColor; - - static Color get cyanBlue => const Color(0xFF1DA1F2); - static Color get cyanAccent => const Color(0xFF1DA1F2).withOpacity(0.12); - static Color get deepPurpleAccent => const Color(0xFFCE1126).withOpacity(0.1); + static const Color goldenBronze = Color(0xFFB87333); + + static Color get cyanBlue => const Color(0xFF1A2340); + static Color get cyanAccent => const Color(0xFF1A2340).withOpacity(0.12); + static Color get deepPurpleAccent => const Color(0xFF8C9CF8).withOpacity(0.1); // --- Theme Helpers --- static Brightness get brightness => Get.isDarkMode ? Brightness.dark : Brightness.light; } - diff --git a/siro_driver/lib/constant/finance_design_system.dart b/siro_driver/lib/constant/finance_design_system.dart index 510897a..57f56af 100644 --- a/siro_driver/lib/constant/finance_design_system.dart +++ b/siro_driver/lib/constant/finance_design_system.dart @@ -13,6 +13,13 @@ class FinanceDesignSystem { static Color get textMuted => Get.isDarkMode ? Colors.white38 : const Color(0xFFBDBDBD); static Color get borderColor => Get.isDarkMode ? Colors.white10 : Colors.grey.withOpacity(0.1); + // --- Shadows --- + static BoxShadow get softShadow => BoxShadow( + color: Colors.black.withOpacity(Get.isDarkMode ? 0.3 : 0.05), + blurRadius: 10, + offset: const Offset(0, 4), + ); + // --- Gradients --- static LinearGradient get balanceGradient => LinearGradient( colors: Get.isDarkMode diff --git a/siro_driver/lib/constant/links.dart b/siro_driver/lib/constant/links.dart index 209f641..ff500a3 100755 --- a/siro_driver/lib/constant/links.dart +++ b/siro_driver/lib/constant/links.dart @@ -7,6 +7,7 @@ class AppLink { static String serverPHP = box.read('serverPHP'); static String paymentServer = 'https://walletintaleq.intaleq.xyz/v1/main'; + static const String appDomain = 'siromove.com'; static String locationServer = 'https://location.intaleq.xyz/intaleq/ride/location'; @@ -337,6 +338,11 @@ class AppLink { //===================Auth============ + static String getUnifiedCode = "$ride/invitor/get_unified_code.php"; + static String addUnifiedInvite = "$ride/invitor/add_unified_invite.php"; + static String claimDriverReward = "$ride/invitor/claim_driver_reward.php"; + static String getDriverReferrals = "$ride/invitor/get_driver_referrals.php"; + static String addInviteDriver = "$ride/invitor/add.php"; static String addInvitationPassenger = "$ride/invitor/addInvitationPassenger.php"; diff --git a/siro_driver/lib/controller/auth/captin/invit_controller.dart b/siro_driver/lib/controller/auth/captin/invit_controller.dart index f628a71..a77d2a4 100755 --- a/siro_driver/lib/controller/auth/captin/invit_controller.dart +++ b/siro_driver/lib/controller/auth/captin/invit_controller.dart @@ -584,6 +584,8 @@ Download the Intaleq app now and enjoy your ride! '${"The period of this code is 24 hours".tr}\n\n' '${'before'.tr} *${d['message']['expirationTime'].toString()}*\n\n' '_*${d['message']['inviteCode'].toString()}*_\n\n' + '${"Quick Invite Link:".tr}\n' + 'https://${AppLink.appDomain}/?inviteCode=${d['message']['inviteCode'].toString()}\n\n' '${"Install our app:".tr}\n' '*Android:* https://play.google.com/store/apps/details?id=com.Intaleq.intaleq\n\n\n' '*iOS:* https://apps.apple.com/st/app/intaleq-rider/id6748075179'; diff --git a/siro_driver/lib/controller/home/invites_rewards_controller.dart b/siro_driver/lib/controller/home/invites_rewards_controller.dart new file mode 100644 index 0000000..e391aee --- /dev/null +++ b/siro_driver/lib/controller/home/invites_rewards_controller.dart @@ -0,0 +1,103 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:siro_driver/constant/links.dart'; +import 'package:siro_driver/controller/functions/crud.dart'; +import 'package:siro_driver/views/widgets/error_snakbar.dart'; + +class InvitesRewardsController extends GetxController { + bool isLoading = false; + String? referralCode; + int totalInvitedDrivers = 0; + int totalInvitedPassengers = 0; + List referrals = []; + + @override + void onInit() { + super.onInit(); + getReferralStats(); + } + + Future getReferralStats() async { + isLoading = true; + update(); + + var res = await CRUD().get(link: AppLink.getDriverReferrals); + + if (res != 'failure' && res != 'token_expired' && res != 'no_internet') { + try { + var jsonData = jsonDecode(res); + if (jsonData['status'] == 'success') { + var data = jsonData['message']; + referralCode = data['referral_code']; + totalInvitedDrivers = data['total_invited_drivers'] ?? 0; + totalInvitedPassengers = data['total_invited_passengers'] ?? 0; + referrals = data['referrals'] ?? []; + } + } catch (e) { + debugPrint('Error parsing referral stats: $e'); + } + } + + isLoading = false; + update(); + } + + Future claimReward(int referralId, String claimType) async { + Get.dialog(const Center(child: CircularProgressIndicator()), barrierDismissible: false); + + var res = await CRUD().post( + link: AppLink.claimDriverReward, + payload: { + 'referral_id': referralId.toString(), + 'claim_type': claimType, // 'wallet' or 'cash' + }, + ); + + Get.back(); // close dialog + + if (res != 'failure' && res != 'token_expired' && res != 'no_internet') { + try { + var jsonData = jsonDecode(res); + if (jsonData['status'] == 'success') { + mySnackbarSuccess('Reward claimed successfully!'.tr); + await getReferralStats(); // refresh list + } else { + mySnackeBarError(jsonData['error'] ?? 'Failed to claim reward'.tr); + } + } catch (e) { + mySnackeBarError('Failed to claim reward'.tr); + } + } else { + mySnackeBarError('Connection error'.tr); + } + } + + Future claimUnifiedReward(int referralId) async { + // Show dialog to choose wallet or cash + Get.defaultDialog( + title: "Choose Claim Method".tr, + content: Text("How would you like to receive your reward?".tr), + actions: [ + ElevatedButton( + onPressed: () { + Get.back(); + claimReward(referralId, 'wallet'); + }, + child: Text("Wallet".tr), + ), + ElevatedButton( + onPressed: () { + Get.back(); + claimReward(referralId, 'cash'); + }, + child: Text("Cash".tr), + ), + TextButton( + onPressed: () => Get.back(), + child: Text("Cancel".tr, style: TextStyle(color: Colors.red)), + ) + ] + ); + } +} diff --git a/siro_driver/lib/views/auth/captin/invite_driver_screen.dart b/siro_driver/lib/views/auth/captin/invite_driver_screen.dart index c6725cb..b3cf4f4 100755 --- a/siro_driver/lib/views/auth/captin/invite_driver_screen.dart +++ b/siro_driver/lib/views/auth/captin/invite_driver_screen.dart @@ -7,9 +7,11 @@ import '../../../constant/colors.dart'; import '../../../controller/auth/captin/invit_controller.dart'; import '../../../controller/functions/encrypt_decrypt.dart'; import '../../../main.dart'; +import '../../../controller/home/invites_rewards_controller.dart'; class InviteScreen extends StatelessWidget { final InviteController controller = Get.put(InviteController()); + final InvitesRewardsController rewardsController = Get.put(InvitesRewardsController()); @override Widget build(BuildContext context) { @@ -111,6 +113,8 @@ class InviteScreen extends StatelessWidget { _buildActionButtons(), const SizedBox(height: 20), _buildInvitationsList(context), + const SizedBox(height: 20), + _buildUnifiedRewardsList(isDriver: true), ], ); } @@ -146,6 +150,8 @@ class InviteScreen extends StatelessWidget { const SizedBox(height: 20), const SizedBox(height: 20), _buildInvitationsListPassengers(context), + const SizedBox(height: 20), + _buildUnifiedRewardsList(isDriver: false), ], ); } @@ -324,9 +330,12 @@ class InviteScreen extends StatelessWidget { } Widget _buildInvitationsList(BuildContext context) { - return SizedBox( - height: Get.height * .4, - child: controller.driverInvitationData.isEmpty + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Invitations Sent".tr, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.bold)), + const SizedBox(height: 10), + controller.driverInvitationData.isEmpty ? Center( child: Text( "No invitation found yet!".tr, @@ -337,18 +346,24 @@ class InviteScreen extends StatelessWidget { ), ) : ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), itemCount: controller.driverInvitationData.length, itemBuilder: (context, index) { return _buildInvitationItem(context, index); }, ), + ], ); } Widget _buildInvitationsListPassengers(BuildContext context) { - return SizedBox( - height: Get.height * .4, - child: controller.driverInvitationDataToPassengers.isEmpty + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Invitations Sent".tr, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.bold)), + const SizedBox(height: 10), + controller.driverInvitationDataToPassengers.isEmpty ? Center( child: Text( "No invitation found yet!".tr, @@ -359,11 +374,14 @@ class InviteScreen extends StatelessWidget { ), ) : ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), itemCount: controller.driverInvitationDataToPassengers.length, itemBuilder: (context, index) { return _buildInvitationItemPassengers(context, index); }, ), + ], ); } @@ -636,4 +654,76 @@ class InviteScreen extends StatelessWidget { ), ); } + + Widget _buildUnifiedRewardsList({required bool isDriver}) { + return GetBuilder( + builder: (rewardsController) { + if (rewardsController.isLoading) { + return const Center(child: CupertinoActivityIndicator()); + } + + var filteredList = rewardsController.referrals.where((ref) => + isDriver ? ref['invited_user_type'] == 'driver' : ref['invited_user_type'] == 'passenger' + ).toList(); + + if (filteredList.isEmpty) { + return const SizedBox(); // Hide if no valid rewards + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Reward Status".tr, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.bold)), + const SizedBox(height: 10), + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: filteredList.length, + itemBuilder: (context, index) { + var ref = filteredList[index]; + int trips = ref['trip_count'] ?? 0; + int target = ref['target_trips'] ?? 1; + bool canClaim = ref['can_claim'] ?? false; + bool isClaimed = ref['is_reward_claimed'] == 1; + + return Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: CupertinoColors.systemGrey6, + borderRadius: BorderRadius.circular(12), + ), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(isDriver ? "Driver Referral".tr : "Passenger Referral".tr, style: const TextStyle(fontWeight: FontWeight.bold)), + const SizedBox(height: 4), + Text("Trips: $trips / $target".tr, style: const TextStyle(color: CupertinoColors.secondaryLabel, fontSize: 13)), + if (isClaimed) + Text("Reward Claimed".tr, style: const TextStyle(color: CupertinoColors.activeGreen, fontSize: 12, fontWeight: FontWeight.bold)) + else if (!canClaim) + Text("Waiting for trips".tr, style: const TextStyle(color: CupertinoColors.systemOrange, fontSize: 12)) + ], + ), + ), + if (canClaim && !isClaimed) + CupertinoButton( + color: AppColor.blueColor, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + onPressed: () => rewardsController.claimUnifiedReward(ref['id']), + child: Text("Claim".tr, style: const TextStyle(color: Colors.white, fontSize: 14)), + ) + ], + ), + ); + }, + ), + ], + ); + }, + ); + } } diff --git a/siro_driver/lib/views/home/Captin/mapDriverWidgets/sos_connect.dart b/siro_driver/lib/views/home/Captin/mapDriverWidgets/sos_connect.dart index 3a82dca..1136b22 100755 --- a/siro_driver/lib/views/home/Captin/mapDriverWidgets/sos_connect.dart +++ b/siro_driver/lib/views/home/Captin/mapDriverWidgets/sos_connect.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:qr_flutter/qr_flutter.dart'; import 'package:siro_driver/views/widgets/error_snakbar.dart'; import 'package:siro_driver/views/widgets/my_textField.dart'; import 'package:siro_driver/views/widgets/elevated_btn.dart'; // Checked import @@ -7,6 +8,7 @@ import 'package:flutter_font_icons/flutter_font_icons.dart'; import '../../../../constant/box_name.dart'; import '../../../../constant/colors.dart'; +import '../../../../constant/links.dart'; import '../../../../constant/style.dart'; import '../../../../controller/firebase/notification_service.dart'; import '../../../../controller/functions/launch.dart'; @@ -50,6 +52,16 @@ class SosConnect extends StatelessWidget { isPulsing: true, onTap: () => _handleSosCall(controller), ), + const SizedBox(height: 8), + // === Quick Invite Button === + _buildModernActionButton( + icon: Icons.qr_code_rounded, + color: Colors.white, + bgColor: AppColor.blueColor, + tooltip: 'Quick Invite', + isPulsing: false, + onTap: () => _showQuickInviteDialog(controller), + ), ], ), ); @@ -128,4 +140,70 @@ class SosConnect extends StatelessWidget { launchCommunication('phone', box.read(BoxName.sosPhoneDriver), ''); } } + + void _showQuickInviteDialog(MapDriverController controller) { + // In a real scenario, this code would be fetched from the backend (ReferralController) + // For now we will use a generated code or driverId. We should use the one from ReferralController + // But since we are accessing it globally, we can just use the driverID + 123 for now until it's linked + String driverId = box.read(BoxName.driverID).toString(); + String inviteCode = "SR$driverId"; // Placeholder code + String deepLink = "https://${AppLink.appDomain}/invite?ref=$inviteCode"; + + Get.defaultDialog( + title: "Quick Invite".tr, + titleStyle: AppStyle.title.copyWith(fontWeight: FontWeight.bold), + content: Column( + children: [ + Text( + "Let the passenger scan this code to sign up".tr, + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 14, color: Colors.grey), + ), + const SizedBox(height: 20), + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 4), + ), + ], + ), + child: QrImageView( + data: deepLink, + version: QrVersions.auto, + size: 200.0, + backgroundColor: Colors.white, + ), + ), + const SizedBox(height: 20), + Container( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + decoration: BoxDecoration( + color: AppColor.blueColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.blueColor.withOpacity(0.3)), + ), + child: Text( + inviteCode, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w900, + color: AppColor.blueColor, + letterSpacing: 4, + ), + ), + ), + ], + ), + confirm: MyElevatedButton( + title: 'Done'.tr, + onPressed: () => Get.back(), + ), + ); + } } diff --git a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png index 4d0ffc0..6f286c2 100644 Binary files a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index 80234de..e0263f2 100644 Binary files a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png index 7119d73..a81b45b 100644 Binary files a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index 8b3ec59..58cde6a 100644 Binary files a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png index 053a209..36d0ce7 100644 Binary files a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png index 58b9d33..76cbf81 100644 Binary files a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png index 570dd3e..be63bd8 100644 Binary files a/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and b/siro_driver/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/siro_driver/pubspec.lock b/siro_driver/pubspec.lock index d9c8862..e849bc1 100644 --- a/siro_driver/pubspec.lock +++ b/siro_driver/pubspec.lock @@ -208,6 +208,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.13.1" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c + url: "https://pub.dev" + source: hosted + version: "0.4.2" clock: dependency: transitive description: @@ -717,6 +725,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.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: @@ -1780,6 +1796,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" + qr: + dependency: transitive + description: + name: qr + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.dev" + source: hosted + version: "4.1.0" quick_actions: dependency: "direct main" description: diff --git a/siro_driver/pubspec.yaml b/siro_driver/pubspec.yaml index 60930f7..f0845b8 100644 --- a/siro_driver/pubspec.yaml +++ b/siro_driver/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: lottie: ^3.3.1 shimmer: ^3.0.0 slide_to_act: ^2.0.2 + qr_flutter: ^4.1.0 # Services & Hardware battery_plus: ^7.0.0 @@ -99,6 +100,7 @@ dev_dependencies: flutter_lints: ^6.0.0 envied_generator: ^1.0.0 build_runner: ^2.4.6 + flutter_launcher_icons: ^0.14.4 flutter_launcher_icons: android: "launcher_icon" diff --git a/siro_driver/web/favicon.png b/siro_driver/web/favicon.png index 7119d73..a81b45b 100644 Binary files a/siro_driver/web/favicon.png and b/siro_driver/web/favicon.png differ diff --git a/siro_driver/web/icons/Icon-192.png b/siro_driver/web/icons/Icon-192.png index 3a3a63f..af9142f 100644 Binary files a/siro_driver/web/icons/Icon-192.png and b/siro_driver/web/icons/Icon-192.png differ diff --git a/siro_driver/web/icons/Icon-512.png b/siro_driver/web/icons/Icon-512.png index 58b9d33..76cbf81 100644 Binary files a/siro_driver/web/icons/Icon-512.png and b/siro_driver/web/icons/Icon-512.png differ diff --git a/siro_driver/web/icons/Icon-maskable-192.png b/siro_driver/web/icons/Icon-maskable-192.png index 3a3a63f..af9142f 100644 Binary files a/siro_driver/web/icons/Icon-maskable-192.png and b/siro_driver/web/icons/Icon-maskable-192.png differ diff --git a/siro_driver/web/icons/Icon-maskable-512.png b/siro_driver/web/icons/Icon-maskable-512.png index 58b9d33..76cbf81 100644 Binary files a/siro_driver/web/icons/Icon-maskable-512.png and b/siro_driver/web/icons/Icon-maskable-512.png differ diff --git a/siro_driver/windows/runner/resources/app_icon.ico b/siro_driver/windows/runner/resources/app_icon.ico index c04e20c..3433aa5 100644 Binary files a/siro_driver/windows/runner/resources/app_icon.ico and b/siro_driver/windows/runner/resources/app_icon.ico differ diff --git a/siro_rider/android/app/src/main/AndroidManifest.xml b/siro_rider/android/app/src/main/AndroidManifest.xml index 231a777..585fd9d 100644 --- a/siro_rider/android/app/src/main/AndroidManifest.xml +++ b/siro_rider/android/app/src/main/AndroidManifest.xml @@ -55,8 +55,8 @@ - - + diff --git a/siro_rider/android/app/src/main/res/drawable/app_icon.png b/siro_rider/android/app/src/main/res/drawable/app_icon.png index 76fb953..aeefe03 100644 Binary files a/siro_rider/android/app/src/main/res/drawable/app_icon.png and b/siro_rider/android/app/src/main/res/drawable/app_icon.png differ diff --git a/siro_rider/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/siro_rider/android/app/src/main/res/mipmap-hdpi/launcher_icon.png index ca52519..122c42b 100644 Binary files a/siro_rider/android/app/src/main/res/mipmap-hdpi/launcher_icon.png and b/siro_rider/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/siro_rider/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/siro_rider/android/app/src/main/res/mipmap-mdpi/launcher_icon.png index a00e563..f3accf7 100644 Binary files a/siro_rider/android/app/src/main/res/mipmap-mdpi/launcher_icon.png and b/siro_rider/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/siro_rider/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/siro_rider/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png index 3873177..b3178da 100644 Binary files a/siro_rider/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png and b/siro_rider/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/siro_rider/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/siro_rider/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png index 19320e3..0ff6c94 100644 Binary files a/siro_rider/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png and b/siro_rider/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/siro_rider/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/siro_rider/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png index 2e3238e..aeefe03 100644 Binary files a/siro_rider/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png and b/siro_rider/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/siro_rider/assets/images/logo.gif b/siro_rider/assets/images/logo.gif index 6bb621e..f505c82 100644 Binary files a/siro_rider/assets/images/logo.gif and b/siro_rider/assets/images/logo.gif differ diff --git a/siro_rider/assets/images/logo.png b/siro_rider/assets/images/logo.png index e9e88cf..ed2fa2b 100644 Binary files a/siro_rider/assets/images/logo.png and b/siro_rider/assets/images/logo.png differ diff --git a/siro_rider/ios/Runner.xcodeproj/project.pbxproj b/siro_rider/ios/Runner.xcodeproj/project.pbxproj index 46e6e58..bae7d2a 100644 --- a/siro_rider/ios/Runner.xcodeproj/project.pbxproj +++ b/siro_rider/ios/Runner.xcodeproj/project.pbxproj @@ -898,9 +898,9 @@ C663DBE82F50907200D79908 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AppIcon; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = AppIcon; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_OBJC_WEAK = YES; @@ -944,9 +944,9 @@ C663DBE92F50907200D79908 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AppIcon; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = AppIcon; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_OBJC_WEAK = YES; @@ -987,9 +987,9 @@ C663DBEA2F50907200D79908 /* Profile */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AppIcon; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = AppIcon; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_OBJC_WEAK = YES; diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png index c0a8eb7..2dd0027 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png index cd9a8c1..98b3636 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png index 5aee621..d1d86d4 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png index eb36ac3..085644b 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png deleted file mode 100644 index 9df0e26..0000000 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png and /dev/null differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png index 905e7a0..0ff6c94 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png index 9393ec5..c25ff07 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png deleted file mode 100644 index b98920f..0000000 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png and /dev/null differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png index 223d91b..1231f62 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png index ca9cb7c..572d4d7 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png index f511ce6..85bfc1c 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png deleted file mode 100644 index ab84a8f..0000000 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png and /dev/null differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png index 00756e2..b848890 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png deleted file mode 100644 index 274174d..0000000 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png and /dev/null differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png index 7dc9475..90ec3fd 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png index c77388d..50bbc86 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png deleted file mode 100644 index 11869c3..0000000 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png and /dev/null differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png index 74ef5da..cc42651 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png index 172bae1..e7e17ea 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png index 2334d1f..e8fac88 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png deleted file mode 100644 index 5d4756c..0000000 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png and /dev/null differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png index 4cfbfb5..122c42b 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png index 2a8ace1..661e669 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png index aa91053..d8682ec 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png index b35f465..c9a871f 100644 Binary files a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png and b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png differ diff --git a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index 5c82812..6973678 100644 --- a/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/siro_rider/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1 +1,158 @@ -{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]} \ No newline at end of file +{ + "images": [ + { + "size": "20x20", + "idiom": "iphone", + "filename": "40.png", + "scale": "2x" + }, + { + "size": "20x20", + "idiom": "iphone", + "filename": "60.png", + "scale": "3x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "29.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "58.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "87.png", + "scale": "3x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "80.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "120.png", + "scale": "3x" + }, + { + "size": "57x57", + "idiom": "iphone", + "filename": "57.png", + "scale": "1x" + }, + { + "size": "57x57", + "idiom": "iphone", + "filename": "114.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "120.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "180.png", + "scale": "3x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "20.png", + "scale": "1x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "40.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "29.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "58.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "40.png", + "scale": "1x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "80.png", + "scale": "2x" + }, + { + "size": "50x50", + "idiom": "ipad", + "filename": "50.png", + "scale": "1x" + }, + { + "size": "50x50", + "idiom": "ipad", + "filename": "100.png", + "scale": "2x" + }, + { + "size": "72x72", + "idiom": "ipad", + "filename": "72.png", + "scale": "1x" + }, + { + "size": "72x72", + "idiom": "ipad", + "filename": "144.png", + "scale": "2x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "76.png", + "scale": "1x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "152.png", + "scale": "2x" + }, + { + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "167.png", + "scale": "2x" + }, + { + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "1024.png", + "scale": "1x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/siro_rider/ios/Runner/Info.plist b/siro_rider/ios/Runner/Info.plist index 267204f..a242222 100644 --- a/siro_rider/ios/Runner/Info.plist +++ b/siro_rider/ios/Runner/Info.plist @@ -28,11 +28,11 @@ CFBundleTypeRole Editor CFBundleURLName - siroapp.com + siromove.com CFBundleURLSchemes com.googleusercontent.apps.1086900987150-9jv4oa8l3t23d54lrf27c1d22tbt9i6d - siroapp + siromove diff --git a/siro_rider/lib/constant/box_name.dart b/siro_rider/lib/constant/box_name.dart index a7115ac..56dce6a 100644 --- a/siro_rider/lib/constant/box_name.dart +++ b/siro_rider/lib/constant/box_name.dart @@ -51,6 +51,7 @@ class BoxName { static const String package = "package"; static const String isInstall = "isInstall"; static const String isGiftToken = "isGiftToken"; + static const String isClaim = "isClaim"; static const String inviteCode = "inviteCode"; static const String phoneWallet = "phoneWallet"; static const String phoneDriver = "phoneDriver"; diff --git a/siro_rider/lib/constant/colors.dart b/siro_rider/lib/constant/colors.dart index fbd0c36..d90f54e 100644 --- a/siro_rider/lib/constant/colors.dart +++ b/siro_rider/lib/constant/colors.dart @@ -4,63 +4,31 @@ import 'package:get/get.dart'; /// The palette is professionally designed to be modern, cohesive, and culturally /// relevant, inspired by the Syrian flag and the app's brand identity. class AppColor { - // --- Core Brand Colors (Inspired by the Syrian Flag) --- + // --- Core Brand Colors --- + static const Color primaryColor = Color(0xFF1A2340); // Navy Blue + static const Color secondaryColorStatic = Color(0xFF8C9CF8); // Periwinkle Blue + static const Color accentColor = Color(0xFF8C9CF8); - /// **Primary Color:** The brand's signature Twitter Blue representing trust and modern communication. - /// Ideal for app bars, primary buttons, and major UI elements. - static const Color primaryColor = Color(0xFF1DA1F2); - - /// **Text/Write Color:** A very dark, near-black color for main text. - /// It's softer on the eyes than pure black, improving readability. - /// The variable name `writeColor` is kept as requested. - static Color get writeColor => Get.isDarkMode ? Colors.white : const Color(0xFF1A1A1A); - - /// **Secondary Color:** Pure white, used for backgrounds to create a clean - /// and spacious look, ensuring content stands out. - static Color get secondaryColor => Get.isDarkMode ? const Color(0xFF1E1E1E) : Colors.white; - - /// **Accent Color:** A vibrant, energetic red from the Syrian flag. - /// Perfect for calls-to-action, highlights, icons, and notifications. - static const Color accentColor = Color.fromARGB(255, 148, 140, 141); + // --- Dynamic Colors (Light / Dark Mode Support) --- + static Color get writeColor => Get.isDarkMode ? Colors.white : const Color(0xFF0F172A); // Primary Text + static Color get secondaryColor => Get.isDarkMode ? const Color(0xFF1E1E1E) : const Color(0xFFF8FAFC); // Background + static Color get cardColor => Get.isDarkMode ? const Color(0xFF2C2C2E) : const Color(0xFFFFFFFF); // Card Background // --- Neutral & Status Colors --- + static Color get grayColor => Get.isDarkMode ? Colors.grey[400]! : const Color(0xFF64748B); // Secondary Text + static Color get borderColor => Get.isDarkMode ? const Color(0xFF3A3A3C) : const Color(0xFFE2E8F0); // Border - /// **Grey Color:** A neutral grey for secondary text, borders, dividers, - /// and disabled states. - static Color get grayColor => Get.isDarkMode ? Colors.grey[400]! : const Color(0xFF8E8E93); + static const Color redColor = Color(0xFFEF4444); // Error + static const Color greenColor = Color(0xFF22C55E); // Success + static const Color yellowColor = Color(0xFFF59E0B); // Warning - /// **Red Color (Error):** A clear, attention-grabbing red for error messages and alerts. - static const Color redColor = Color(0xFFD32F2F); - - /// **Green Color (Success):** A positive green for success messages and confirmations. - static const Color greenColor = Color(0xFF388E3C); - - /// **Blue Color (Info):** A standard blue for informational text, links, or icons. - static const Color blueColor = Color(0xFF108942); - - /// **Yellow Color (Warning):** A warm yellow for warning messages or important highlights. - static const Color yellowColor = Color(0xFFFFA000); - - // --- Tier & Social Colors --- - - /// **Gold Tier:** A bright gold for premium features, user ranks, or rewards. + // --- Legacy / Maps Colors (Kept for compatibility) --- + static const Color blueColor = Color(0xFF1A2340); static const Color gold = Color(0xFFFFD700); - - /// **Bronze Tiers:** Classic bronze colors for other user tiers or levels. static const Color bronze = Color(0xFFCD7F32); - static const Color goldenBronze = Color(0xFFB87333); // Kept from original - - /// **Twitter/X Color:** The official brand color for social login buttons. - - /// **Twitter Blue:** The brand's signature blue color used for the drawer, - /// menu icons, and secondary actions (formerly Cyan Blue). - static Color get cyanBlue => const Color(0xFF1DA1F2); - - /// **Blue Accent:** A softer, translucent version of the brand blue. - static Color get cyanAccent => const Color(0xFF1DA1F2).withOpacity(0.12); - - // --- Utility Colors --- - - /// **Accent Tint:** A transparent version of the red accent color. - static Color get deepPurpleAccent => const Color(0xFFCE1126).withOpacity(0.1); + static const Color goldenBronze = Color(0xFFB87333); + + static Color get cyanBlue => const Color(0xFF1A2340); + static Color get cyanAccent => const Color(0xFF1A2340).withOpacity(0.12); + static Color get deepPurpleAccent => const Color(0xFF8C9CF8).withOpacity(0.1); } diff --git a/siro_rider/lib/constant/links.dart b/siro_rider/lib/constant/links.dart index cd91185..a8fa7bb 100644 --- a/siro_rider/lib/constant/links.dart +++ b/siro_rider/lib/constant/links.dart @@ -2,6 +2,7 @@ import 'package:siro_rider/constant/box_name.dart'; import 'package:siro_rider/main.dart'; class AppLink { + static const String appDomain = 'siromove.com'; ///https://walletintaleq.intaleq.xyz/v1/main static String paymentServer = 'https://walletintaleq.intaleq.xyz/v2/main'; @@ -177,7 +178,9 @@ class AppLink { static String deleteNotificationCaptain = "$server/ride/notificationCaptain/delete.php"; //-----------------invitor------------------ - + static String getUnifiedCode = "$server/ride/invitor/get_unified_code.php"; + static String addUnifiedInvite = "$server/ride/invitor/add_unified_invite.php"; + static String getPassengerReferrals = "$server/ride/invitor/get_passenger_referrals.php"; static String addInviteDriver = "$server/ride/invitor/add.php"; static String addInvitationPassenger = "$server/ride/invitor/addInvitationPassenger.php"; diff --git a/siro_rider/lib/controller/auth/login_controller.dart b/siro_rider/lib/controller/auth/login_controller.dart index 5c073a7..f2f9ded 100644 --- a/siro_rider/lib/controller/auth/login_controller.dart +++ b/siro_rider/lib/controller/auth/login_controller.dart @@ -308,6 +308,7 @@ class LoginController extends GetxController { box.write(BoxName.validity, data['validity']); box.write(BoxName.isInstall, data['isInstall'] ?? 'none'); box.write(BoxName.isGiftToken, data['isGiftToken'] ?? 'none'); + box.write(BoxName.isClaim, data['isClaim'] ?? '0'); if (data['inviteCode'] != null) { box.write(BoxName.inviteCode, data['inviteCode'].toString()); } @@ -384,6 +385,15 @@ class LoginController extends GetxController { "inviteCode": invite, "passengerID": passengerID, }); + + // سجل الدعوة أيضاً في النظام الموحد الجديد + await CRUD().post(link: AppLink.addUnifiedInvite, payload: { + "inviter_code": invite, + }); + + // تحديث الحالة محلياً لضمان عدم إرسال الطلب مرة أخرى + box.write(BoxName.isInstall, '1'); + await Get.defaultDialog( title: 'Invitation Used'.tr, middleText: "Your invite code was successfully applied!".tr, diff --git a/siro_rider/lib/controller/home/deep_link_controller.dart b/siro_rider/lib/controller/home/deep_link_controller.dart index 8a38c9d..d4a790a 100644 --- a/siro_rider/lib/controller/home/deep_link_controller.dart +++ b/siro_rider/lib/controller/home/deep_link_controller.dart @@ -2,6 +2,8 @@ import 'package:siro_rider/print.dart'; import 'dart:async'; import 'package:app_links/app_links.dart'; import 'package:get/get.dart'; +import '../../main.dart'; +import 'profile/invites_rewards_controller.dart'; class DeepLinkController extends GetxController { final _appLinks = AppLinks(); @@ -21,6 +23,7 @@ class DeepLinkController extends GetxController { _linkSubscription = _appLinks.uriLinkStream.listen((uri) { Log.print('🔗 Received deep link (Stream): $uri'); rawDeepLink.value = uri.toString(); + _processInviteCode(uri); }); // الاستماع للروابط إذا كان التطبيق مغلقاً تماماً (Cold Start) @@ -29,15 +32,37 @@ class DeepLinkController extends GetxController { if (initialUri != null) { Log.print('🔗 Received initial deep link (Cold Start): $initialUri'); rawDeepLink.value = initialUri.toString(); + _processInviteCode(initialUri); } } catch (e) { Log.print('Error getting initial link: $e'); } } + void _processInviteCode(Uri uri) { + if (uri.queryParameters.containsKey('inviteCode')) { + String? inviteCode = uri.queryParameters['inviteCode']; + if (inviteCode != null && inviteCode.isNotEmpty) { + // دائماً نخزن الكود حتى لو لم يكن مسجلاً، ليتم استخدامه بعد التسجيل + box.write('inviteCode', inviteCode); + + // إذا كان المستخدم مسجل دخول (يمتلك JWT)، نربط الدعوة فوراً + if (box.read('jwt') != null) { + try { + var rewardsController = Get.find(); + rewardsController.linkInviteCode(inviteCode); + } catch (e) { + var rewardsController = Get.put(InvitesRewardsController()); + rewardsController.linkInviteCode(inviteCode); + } + } + } + } + } + @override void onClose() { _linkSubscription?.cancel(); super.onClose(); } -} \ No newline at end of file +} diff --git a/siro_rider/lib/controller/home/profile/invites_rewards_controller.dart b/siro_rider/lib/controller/home/profile/invites_rewards_controller.dart new file mode 100644 index 0000000..55ed32b --- /dev/null +++ b/siro_rider/lib/controller/home/profile/invites_rewards_controller.dart @@ -0,0 +1,94 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:siro_rider/constant/links.dart'; +import 'package:siro_rider/controller/functions/crud.dart'; + +class InvitesRewardsController extends GetxController { + bool isLoading = false; + String? referralCode; + int totalInvitedDrivers = 0; + int totalInvitedPassengers = 0; + List referrals = []; + + @override + void onInit() { + super.onInit(); + fetchPassengerReferrals(); + } + + Future fetchPassengerReferrals() async { + isLoading = true; + update(); + + try { + var response = await CRUD().post( + link: AppLink.getPassengerReferrals, + payload: {} // Token is automatically handled by CRUD() + ); + + if (response != 'failure') { + var data = jsonDecode(response); + if (data['status'] == 'success') { + referralCode = data['message']['referral_code']; + totalInvitedDrivers = data['message']['total_invited_drivers'] ?? 0; + totalInvitedPassengers = data['message']['total_invited_passengers'] ?? 0; + referrals = data['message']['referrals'] ?? []; + } else { + referrals = []; + } + } + } catch (e) { + print("Error fetching passenger referrals: $e"); + } + + isLoading = false; + update(); + } + + Future processScannedQRCode(String code) async { + if (code.contains('inviteCode=')) { + Uri uri = Uri.parse(code); + String? inviteCode = uri.queryParameters['inviteCode']; + + if (inviteCode != null && inviteCode.isNotEmpty) { + await linkInviteCode(inviteCode); + } else { + Get.snackbar("Error".tr, "Invalid QR Code".tr); + } + } else if (code.length >= 4 && code.length <= 15) { + await linkInviteCode(code); + } else { + Get.snackbar("Error".tr, "Invalid QR Code format".tr); + } + } + + Future linkInviteCode(String inviteCode) async { + Get.dialog(const Center(child: CircularProgressIndicator()), barrierDismissible: false); + + try { + var response = await CRUD().post( + link: AppLink.addUnifiedInvite, + payload: { + "inviter_code": inviteCode, + } + ); + + Get.back(); // close loading + + if (response != 'failure') { + var data = jsonDecode(response); + if (data['status'] == 'success') { + Get.snackbar("Success".tr, "You have been successfully referred!".tr, backgroundColor: Colors.green, colorText: Colors.white); + } else { + Get.snackbar("Notice".tr, data['message'] ?? "Could not add invite".tr); + } + } else { + Get.snackbar("Error".tr, "Network error occurred".tr); + } + } catch (e) { + Get.back(); // close loading + Get.snackbar("Error".tr, "Network error occurred".tr); + } + } +} diff --git a/siro_rider/lib/views/home/HomePage/qr_scanner_page.dart b/siro_rider/lib/views/home/HomePage/qr_scanner_page.dart new file mode 100644 index 0000000..48f0f0e --- /dev/null +++ b/siro_rider/lib/views/home/HomePage/qr_scanner_page.dart @@ -0,0 +1,67 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; +import 'package:siro_rider/constant/colors.dart'; +import 'package:siro_rider/controller/home/profile/invites_rewards_controller.dart'; + +class QRScannerPage extends StatefulWidget { + @override + _QRScannerPageState createState() => _QRScannerPageState(); +} + +class _QRScannerPageState extends State { + final InvitesRewardsController controller = Get.find(); + bool _isScanned = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + appBar: AppBar( + backgroundColor: Colors.black, + iconTheme: const IconThemeData(color: Colors.white), + title: Text("Scan QR Code".tr, style: const TextStyle(color: Colors.white)), + ), + body: Stack( + children: [ + MobileScanner( + onDetect: (capture) { + if (_isScanned) return; + final List barcodes = capture.barcodes; + for (final barcode in barcodes) { + if (barcode.rawValue != null) { + setState(() => _isScanned = true); + Get.back(); // close scanner page + controller.processScannedQRCode(barcode.rawValue!); + break; + } + } + }, + ), + Center( + child: Container( + width: 250, + height: 250, + decoration: BoxDecoration( + border: Border.all(color: AppColor.primaryColor, width: 3), + borderRadius: BorderRadius.circular(12), + ), + ), + ), + Positioned( + bottom: 50, + left: 0, + right: 0, + child: Center( + child: Text( + "Align QR Code within the frame".tr, + style: const TextStyle(color: Colors.white, fontSize: 16), + ), + ), + ), + ], + ), + ); + } +} diff --git a/siro_rider/lib/views/home/HomePage/share_app_page.dart b/siro_rider/lib/views/home/HomePage/share_app_page.dart index ca97f21..36e99cb 100644 --- a/siro_rider/lib/views/home/HomePage/share_app_page.dart +++ b/siro_rider/lib/views/home/HomePage/share_app_page.dart @@ -3,12 +3,18 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../../constant/colors.dart'; +import '../../../constant/links.dart'; import '../../../constant/style.dart'; import '../../../controller/home/profile/invit_controller.dart'; +import '../../../controller/home/profile/invites_rewards_controller.dart'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'qr_scanner_page.dart'; import '../../../print.dart'; class ShareAppPage extends StatelessWidget { final InviteController controller = Get.put(InviteController()); + final InvitesRewardsController rewardsController = + Get.put(InvitesRewardsController()); @override Widget build(BuildContext context) { @@ -42,6 +48,12 @@ class ShareAppPage extends StatelessWidget { }, ), ), + floatingActionButton: FloatingActionButton.extended( + backgroundColor: AppColor.primaryColor, + onPressed: () => Get.to(() => QRScannerPage()), + icon: const Icon(CupertinoIcons.qrcode_viewfinder, color: Colors.white), + label: Text("Scan QR".tr, style: const TextStyle(color: Colors.white)), + ), ); } @@ -49,6 +61,8 @@ class ShareAppPage extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + _buildQRCodeSection(), + const SizedBox(height: 20), Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( @@ -74,8 +88,11 @@ class ShareAppPage extends StatelessWidget { const SizedBox(height: 20), _buildActionButtonsPassengers(), const SizedBox(height: 20), - const SizedBox(height: 20), _buildInvitationsListPassengers(context), + const SizedBox(height: 20), + _buildUnifiedRewardsList(), + const SizedBox( + height: 60), // Add padding for the floating action button ], ); } @@ -226,24 +243,35 @@ class ShareAppPage extends StatelessWidget { } Widget _buildInvitationsListPassengers(BuildContext context) { - return SizedBox( - height: Get.height * .4, - child: controller.driverInvitationDataToPassengers.isEmpty - ? Center( - child: Text( - "No invitation found yet!".tr, - style: TextStyle( - color: AppColor.grayColor, - fontSize: 17, + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Invitations Sent".tr, + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + color: AppColor.writeColor, + )), + const SizedBox(height: 10), + controller.driverInvitationDataToPassengers.isEmpty + ? Center( + child: Text( + "No invitation found yet!".tr, + style: TextStyle( + color: AppColor.grayColor, + fontSize: 17, + ), ), + ) + : ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: controller.driverInvitationDataToPassengers.length, + itemBuilder: (context, index) { + return _buildInvitationItemPassengers(context, index); + }, ), - ) - : ListView.builder( - itemCount: controller.driverInvitationDataToPassengers.length, - itemBuilder: (context, index) { - return _buildInvitationItemPassengers(context, index); - }, - ), + ], ); } @@ -574,4 +602,136 @@ class ShareAppPage extends StatelessWidget { // ), // ); } + + Widget _buildQRCodeSection() { + return GetBuilder( + builder: (rewardsController) { + if (rewardsController.isLoading) { + return const Center(child: CupertinoActivityIndicator()); + } + String qrData = + 'https://${AppLink.appDomain}/?inviteCode=${rewardsController.referralCode ?? ''}'; + + return Center( + child: Column( + children: [ + Text("Your QR Code".tr, + style: const TextStyle( + fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 10), + if (rewardsController.referralCode != null) + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + ), + child: QrImageView( + data: qrData, + version: QrVersions.auto, + size: 200.0, + backgroundColor: Colors.white, + ), + ), + const SizedBox(height: 10), + if (rewardsController.referralCode != null) + Text( + rewardsController.referralCode!, + style: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + letterSpacing: 2), + ), + ], + ), + ); + }, + ); + } + + Widget _buildUnifiedRewardsList() { + return GetBuilder( + builder: (rewardsController) { + if (rewardsController.isLoading) { + return const Center(child: CupertinoActivityIndicator()); + } + + var filteredList = rewardsController.referrals; + + if (filteredList.isEmpty) { + return const SizedBox(); // Hide if no valid rewards + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Reward Status".tr, + style: + const TextStyle(fontSize: 17, fontWeight: FontWeight.bold)), + const SizedBox(height: 10), + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: filteredList.length, + itemBuilder: (context, index) { + var ref = filteredList[index]; + int trips = ref['trip_count'] ?? 0; + int target = ref['target_trips'] ?? 1; + bool canClaim = ref['can_claim'] ?? false; + bool isClaimed = ref['is_reward_claimed'] == 1; + + return Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: CupertinoColors.systemGrey6, + borderRadius: BorderRadius.circular(12), + ), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + ref['invited_user_type'] == 'driver' + ? "Driver Referral".tr + : "Passenger Referral".tr, + style: const TextStyle( + fontWeight: FontWeight.bold)), + const SizedBox(height: 4), + Text("Trips: $trips / $target".tr, + style: const TextStyle( + color: CupertinoColors.secondaryLabel, + fontSize: 13)), + if (isClaimed) + Text("Reward Claimed".tr, + style: const TextStyle( + color: CupertinoColors.activeGreen, + fontSize: 12, + fontWeight: FontWeight.bold)) + else if (!canClaim) + Text("Waiting for trips".tr, + style: const TextStyle( + color: CupertinoColors.systemOrange, + fontSize: 12)) + else + Text("Reward Earned".tr, + style: const TextStyle( + color: CupertinoColors.activeGreen, + fontSize: 12, + fontWeight: FontWeight.bold)) + ], + ), + ), + ], + ), + ); + }, + ), + ], + ); + }, + ); + } } diff --git a/siro_rider/macos/Flutter/GeneratedPluginRegistrant.swift b/siro_rider/macos/Flutter/GeneratedPluginRegistrant.swift index 9b584d9..5c02189 100644 --- a/siro_rider/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/siro_rider/macos/Flutter/GeneratedPluginRegistrant.swift @@ -23,6 +23,7 @@ import google_sign_in_ios import just_audio import local_auth_darwin import location +import mobile_scanner import package_info_plus import record_macos import share_plus @@ -52,6 +53,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin")) LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin")) + MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) diff --git a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index a2ec33f..96d3fee 100644 --- a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,68 +1,68 @@ { - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_16.png", - "scale" : "1x" + "info": { + "version": 1, + "author": "xcode" }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} + "images": [ + { + "size": "16x16", + "idiom": "mac", + "filename": "app_icon_16.png", + "scale": "1x" + }, + { + "size": "16x16", + "idiom": "mac", + "filename": "app_icon_32.png", + "scale": "2x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "app_icon_32.png", + "scale": "1x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "app_icon_64.png", + "scale": "2x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "app_icon_128.png", + "scale": "1x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "app_icon_256.png", + "scale": "2x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "app_icon_256.png", + "scale": "1x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "app_icon_512.png", + "scale": "2x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "app_icon_512.png", + "scale": "1x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "app_icon_1024.png", + "scale": "2x" + } + ] +} \ No newline at end of file diff --git a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png index 82b6f9d..98b3636 100644 Binary files a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index 13b35eb..0640afa 100644 Binary files a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png index 0a3f5fa..07fdce1 100644 Binary files a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index bdb5722..8ab33a6 100644 Binary files a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png index f083318..a03a88c 100644 Binary files a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png index 326c0e7..c7fe322 100644 Binary files a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png index 2f1632c..c051d16 100644 Binary files a/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and b/siro_rider/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/siro_rider/pubspec.lock b/siro_rider/pubspec.lock index c32d4b6..b4624b9 100644 --- a/siro_rider/pubspec.lock +++ b/siro_rider/pubspec.lock @@ -1397,6 +1397,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + mobile_scanner: + dependency: "direct main" + description: + name: mobile_scanner + sha256: d234581c090526676fd8fab4ada92f35c6746e3fb4f05a399665d75a399fb760 + url: "https://pub.dev" + source: hosted + version: "5.2.3" nested: dependency: transitive description: @@ -1637,6 +1645,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" + qr: + dependency: transitive + description: + name: qr + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.dev" + source: hosted + version: "4.1.0" quick_actions: dependency: "direct main" description: diff --git a/siro_rider/pubspec.yaml b/siro_rider/pubspec.yaml index d1485bd..76e4adf 100644 --- a/siro_rider/pubspec.yaml +++ b/siro_rider/pubspec.yaml @@ -84,6 +84,8 @@ dependencies: app_links: ^7.0.0 intaleq_maps: ^2.2.0 socket_io_client: 1.0.2 + mobile_scanner: ^5.2.3 + qr_flutter: ^4.1.0 # home_widget: ^0.7.0+1 dev_dependencies: diff --git a/siro_rider/web/favicon.png b/siro_rider/web/favicon.png index 52b0028..07fdce1 100644 Binary files a/siro_rider/web/favicon.png and b/siro_rider/web/favicon.png differ diff --git a/siro_rider/web/icons/Icon-192.png b/siro_rider/web/icons/Icon-192.png index 2e3238e..aeefe03 100644 Binary files a/siro_rider/web/icons/Icon-192.png and b/siro_rider/web/icons/Icon-192.png differ diff --git a/siro_rider/web/icons/Icon-512.png b/siro_rider/web/icons/Icon-512.png index a3e0cf2..c7fe322 100644 Binary files a/siro_rider/web/icons/Icon-512.png and b/siro_rider/web/icons/Icon-512.png differ diff --git a/siro_rider/web/icons/Icon-maskable-192.png b/siro_rider/web/icons/Icon-maskable-192.png index 2e3238e..aeefe03 100644 Binary files a/siro_rider/web/icons/Icon-maskable-192.png and b/siro_rider/web/icons/Icon-maskable-192.png differ diff --git a/siro_rider/web/icons/Icon-maskable-512.png b/siro_rider/web/icons/Icon-maskable-512.png index a3e0cf2..c7fe322 100644 Binary files a/siro_rider/web/icons/Icon-maskable-512.png and b/siro_rider/web/icons/Icon-maskable-512.png differ diff --git a/siro_rider/windows/runner/resources/app_icon.ico b/siro_rider/windows/runner/resources/app_icon.ico index c04e20c..39d22b1 100644 Binary files a/siro_rider/windows/runner/resources/app_icon.ico and b/siro_rider/windows/runner/resources/app_icon.ico differ