diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies
index 7a84eb0..b1ea07b 100644
--- a/.flutter-plugins-dependencies
+++ b/.flutter-plugins-dependencies
@@ -1 +1 @@
-{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_local_notifications","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications-21.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_foundation-2.6.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"workmanager_apple","path":"/home/suherdy/.pub-cache/hosted/pub.dev/workmanager_apple-0.9.1+2/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"flutter_local_notifications","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications-21.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.21/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"workmanager_android","path":"/home/suherdy/.pub-cache/hosted/pub.dev/workmanager_android-0.9.0+2/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"flutter_local_notifications","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications-21.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_foundation-2.6.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"flutter_local_notifications_linux","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications_linux-8.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false}],"windows":[{"name":"flutter_local_notifications_windows","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications_windows-3.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false}],"web":[{"name":"shared_preferences_web","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"flutter_local_notifications","dependencies":["flutter_local_notifications_linux","flutter_local_notifications_windows"]},{"name":"flutter_local_notifications_linux","dependencies":[]},{"name":"flutter_local_notifications_windows","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"workmanager","dependencies":["workmanager_android","workmanager_apple"]},{"name":"workmanager_android","dependencies":[]},{"name":"workmanager_apple","dependencies":[]}],"date_created":"2026-03-21 16:17:41.924512","version":"3.41.5","swift_package_manager_enabled":{"ios":false,"macos":false}}
\ No newline at end of file
+{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_local_notifications","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications-21.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_foundation-2.6.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_ios","path":"/home/suherdy/.pub-cache/hosted/pub.dev/url_launcher_ios-6.4.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"workmanager_apple","path":"/home/suherdy/.pub-cache/hosted/pub.dev/workmanager_apple-0.9.1+2/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"flutter_local_notifications","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications-21.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.21/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_android","path":"/home/suherdy/.pub-cache/hosted/pub.dev/url_launcher_android-6.3.29/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"workmanager_android","path":"/home/suherdy/.pub-cache/hosted/pub.dev/workmanager_android-0.9.0+2/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"flutter_local_notifications","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications-21.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_foundation-2.6.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_macos","path":"/home/suherdy/.pub-cache/hosted/pub.dev/url_launcher_macos-3.2.5/","native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"flutter_local_notifications_linux","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications_linux-8.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false},{"name":"url_launcher_linux","path":"/home/suherdy/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.2/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"flutter_local_notifications_windows","path":"/home/suherdy/.pub-cache/hosted/pub.dev/flutter_local_notifications_windows-3.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/home/suherdy/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false},{"name":"url_launcher_windows","path":"/home/suherdy/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.5/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"shared_preferences_web","path":"/home/suherdy/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false},{"name":"url_launcher_web","path":"/home/suherdy/.pub-cache/hosted/pub.dev/url_launcher_web-2.4.2/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"flutter_local_notifications","dependencies":["flutter_local_notifications_linux","flutter_local_notifications_windows"]},{"name":"flutter_local_notifications_linux","dependencies":[]},{"name":"flutter_local_notifications_windows","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]},{"name":"workmanager","dependencies":["workmanager_android","workmanager_apple"]},{"name":"workmanager_android","dependencies":[]},{"name":"workmanager_apple","dependencies":[]}],"date_created":"2026-03-27 08:55:53.380396","version":"3.41.5","swift_package_manager_enabled":{"ios":false,"macos":false}}
\ No newline at end of file
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 40babd1..9886387 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -3,7 +3,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/screens/branches_screen.dart b/lib/screens/branches_screen.dart
index 63b175f..4106010 100644
--- a/lib/screens/branches_screen.dart
+++ b/lib/screens/branches_screen.dart
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
+import 'package:url_launcher/url_launcher.dart';
import '../services/odoo_service.dart';
import '../theme/app_theme.dart';
@@ -36,6 +37,30 @@ class _BranchesScreenState extends State {
}
}
+ Future _launchMaps(String queryTerm) async {
+ final query = Uri.encodeComponent(queryTerm);
+ final url = Uri.parse('https://www.google.com/maps/search/?api=1&query=$query');
+ if (await canLaunchUrl(url)) {
+ await launchUrl(url, mode: LaunchMode.externalApplication);
+ } else {
+ if (mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Could not open map.')));
+ }
+ }
+
+ Future _launchWhatsApp(String phone) async {
+ final cleanPhone = phone.replaceAll(RegExp(r'\D'), '');
+ String waPhone = cleanPhone;
+ if (waPhone.startsWith('0')) {
+ waPhone = '62${waPhone.substring(1)}';
+ }
+ final url = Uri.parse('https://wa.me/$waPhone');
+ if (await canLaunchUrl(url)) {
+ await launchUrl(url, mode: LaunchMode.externalApplication);
+ } else {
+ if (mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Could not open WhatsApp.')));
+ }
+ }
+
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -69,44 +94,51 @@ class _BranchesScreenState extends State {
)
]
),
- child: ListTile(
- contentPadding: const EdgeInsets.all(16),
- leading: Container(
- padding: const EdgeInsets.all(12),
- decoration: BoxDecoration(
- color: AppTheme.secondaryContainer.withOpacity(0.2),
- shape: BoxShape.circle,
+ child: ListTile(
+ contentPadding: const EdgeInsets.all(16),
+ onTap: () => _launchMaps('${branch['name']} ${addressParts}'),
+ leading: Container(
+ padding: const EdgeInsets.all(12),
+ decoration: BoxDecoration(
+ color: AppTheme.secondaryContainer.withOpacity(0.2),
+ shape: BoxShape.circle,
+ ),
+ child: const Icon(Icons.storefront, color: AppTheme.secondary),
),
- child: const Icon(Icons.storefront, color: AppTheme.secondary),
- ),
- title: Text(
- branch['name'] ?? 'Mapan Branch',
- style: Theme.of(context).textTheme.titleMedium,
- ),
- subtitle: Padding(
- padding: const EdgeInsets.only(top: 8.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- addressParts.isEmpty ? 'No address specified' : addressParts,
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- if (phone.isNotEmpty) ...[
- const SizedBox(height: 4),
- Row(
- children: [
- const Icon(Icons.phone, size: 14, color: AppTheme.primary),
- const SizedBox(width: 4),
- Text(phone, style: Theme.of(context).textTheme.bodySmall?.copyWith(color: AppTheme.primary)),
- ],
+ title: Text(
+ branch['name'] ?? 'Mapan Branch',
+ style: Theme.of(context).textTheme.titleMedium,
+ ),
+ subtitle: Padding(
+ padding: const EdgeInsets.only(top: 8.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ addressParts.isEmpty ? 'No address specified' : addressParts,
+ style: Theme.of(context).textTheme.bodyMedium,
),
- ]
- ],
+ if (phone.isNotEmpty) ...[
+ const SizedBox(height: 4),
+ Row(
+ children: [
+ const Icon(Icons.phone, size: 14, color: AppTheme.primary),
+ const SizedBox(width: 4),
+ Text(phone, style: Theme.of(context).textTheme.bodySmall?.copyWith(color: AppTheme.primary)),
+ ],
+ ),
+ ]
+ ],
+ ),
),
+ trailing: phone.isNotEmpty
+ ? IconButton(
+ icon: const Icon(Icons.chat_bubble_outline, color: Colors.green),
+ onPressed: () => _launchWhatsApp(phone),
+ tooltip: 'Chat on WhatsApp',
+ )
+ : const Icon(Icons.chevron_right, color: AppTheme.onSurfaceVariant),
),
- trailing: const Icon(Icons.chevron_right, color: AppTheme.onSurfaceVariant),
- ),
);
},
),
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 731c75a..6f01d65 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -7,8 +7,10 @@ import Foundation
import flutter_local_notifications
import shared_preferences_foundation
+import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
+ UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
}
diff --git a/pubspec.lock b/pubspec.lock
index 4a8f843..93c0883 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -565,6 +565,70 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.0"
+ url_launcher:
+ dependency: "direct main"
+ description:
+ name: url_launcher
+ sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.3.2"
+ url_launcher_android:
+ dependency: transitive
+ description:
+ name: url_launcher_android
+ sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.3.29"
+ url_launcher_ios:
+ dependency: transitive
+ description:
+ name: url_launcher_ios
+ sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.4.1"
+ url_launcher_linux:
+ dependency: transitive
+ description:
+ name: url_launcher_linux
+ sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.2.2"
+ url_launcher_macos:
+ dependency: transitive
+ description:
+ name: url_launcher_macos
+ sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.2.5"
+ url_launcher_platform_interface:
+ dependency: transitive
+ description:
+ name: url_launcher_platform_interface
+ sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.2"
+ url_launcher_web:
+ dependency: transitive
+ description:
+ name: url_launcher_web
+ sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.2"
+ url_launcher_windows:
+ dependency: transitive
+ description:
+ name: url_launcher_windows
+ sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.5"
vector_math:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index f76ca03..d8eb043 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -39,6 +39,7 @@ dependencies:
flutter_local_notifications: ^21.0.0
shared_preferences: ^2.5.4
google_fonts: ^6.2.1
+ url_launcher: ^6.3.2
dev_dependencies:
flutter_test:
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index 8b6d468..4f78848 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h"
+#include
void RegisterPlugins(flutter::PluginRegistry* registry) {
+ UrlLauncherWindowsRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index 93f25e1..83dbdeb 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
+ url_launcher_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST