From 0e4072fe8feb883cdecaecf610d890d793319c58 Mon Sep 17 00:00:00 2001 From: Nilanjan Chakrabarti Date: Thu, 25 Sep 2025 12:56:03 +0530 Subject: [PATCH] FAQs link added and Branch and ATM locator updated --- lib/di/injection.dart | 4 +- .../screens/branch_locator_screen.dart | 260 +++++++++++------- .../service/screens/service_screen.dart | 27 +- lib/l10n/app_en.arb | 9 +- lib/l10n/app_hi.arb | 9 +- 5 files changed, 192 insertions(+), 117 deletions(-) diff --git a/lib/di/injection.dart b/lib/di/injection.dart index f0ee81b..197ba14 100644 --- a/lib/di/injection.dart +++ b/lib/di/injection.dart @@ -65,9 +65,9 @@ Dio _createDioClient() { final dio = Dio( BaseOptions( baseUrl: - //'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080', //test + 'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080', //test //'http://lb-kccb-mobile-banking-app-848675342.ap-south-1.elb.amazonaws.com', //prod - 'https://kccbmbnk.net', + //'https://kccbmbnk.net', connectTimeout: const Duration(seconds: 60), receiveTimeout: const Duration(seconds: 60), headers: { diff --git a/lib/features/service/screens/branch_locator_screen.dart b/lib/features/service/screens/branch_locator_screen.dart index 5133863..69ed9a6 100644 --- a/lib/features/service/screens/branch_locator_screen.dart +++ b/lib/features/service/screens/branch_locator_screen.dart @@ -1,17 +1,22 @@ -import '../../../l10n/app_localizations.dart'; import 'package:flutter/material.dart'; +import '../../../l10n/app_localizations.dart'; -class Branch { +// Enum to define the type of location +enum LocationType { branch, atm } + +class Location { final String name; - final String code; - final String ifsc; + final String? code; // Nullable for ATMs + final String? ifsc; // Nullable for ATMs final String address; + final LocationType type; - Branch({ + Location({ required this.name, - required this.code, - required this.ifsc, + this.code, + this.ifsc, required this.address, + required this.type, }); } @@ -22,103 +27,160 @@ class BranchLocatorScreen extends StatefulWidget { State createState() => _BranchLocatorScreenState(); } -class _BranchLocatorScreenState extends State { - final TextEditingController _searchController = TextEditingController(); + class _BranchLocatorScreenState extends State { + final TextEditingController _searchController = TextEditingController(); -// Static list of 2 branches - final List _branches = [ - Branch( - name: "Dharamsala - Head Office", - code: "002", - ifsc: "KACE0000002", - address: "Civil Lines Dharmashala, Kangra, HP - 176215"), - Branch( - name: "Kangra", - code: "033", - ifsc: "KACE0000033", - address: "Rajput Bhawankangrapo, Kangra, HP "), - ]; + final List _allLocations = [ + Location( + name: "Dharamsala - Head Office", + code: "002", + ifsc: "KACE0000002", + address: "Civil Lines Dharmashala, Kangra, HP - 176215", + type: LocationType.branch, + ), + Location( + name: "Kangra", + code: "033", + ifsc: "KACE0000033", + address: "Rajput Bhawankangrapo, Kangra, HP ", + type: LocationType.branch, + ), + Location( + name: "Dharamsala ATM", + address: "Near Main Square, Dharamsala", + type: LocationType.atm, + ), + Location( + name: "Kangra ATM", + address: "Opposite Bus Stand, Kangra", + type: LocationType.atm, + ), + ]; - List _filteredBranches = []; + List _filteredLocations = []; + bool _isLoading = false; - @override - void initState() { - super.initState(); - _filteredBranches = _branches; // Initially show all branches - } +@override +void initState() { + super.initState(); + // _fetchAndSetLocations(); + _filteredLocations = _allLocations; +} - void _filterBranches(String query) { +// Example of a future API fetching function +/* +Future _fetchAndSetLocations() async { + setState(() { + _isLoading = true; + }); + try { + // final locations = await yourApiService.getLocations(); + // setState(() { + // _allLocations = locations; + // _filteredLocations = locations; + // }); + } catch (e) { + // Handle error + } finally { setState(() { - if (query.isEmpty) { - _filteredBranches = _branches; - } else { - _filteredBranches = _branches.where((branch) { - final lowerQuery = query.toLowerCase(); - return branch.name.toLowerCase().contains(lowerQuery) || - branch.code.toLowerCase().contains(lowerQuery) || - branch.ifsc.toLowerCase().contains(lowerQuery) || - branch.address.toLowerCase().contains(lowerQuery); - }).toList(); - } + _isLoading = false; }); } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(AppLocalizations.of(context).branchLocator), - ), - body: Column( - children: [ -// Search bar - Padding( - padding: const EdgeInsets.all(12.0), - child: TextField( - controller: _searchController, - onChanged: _filterBranches, - decoration: InputDecoration( - hintText: AppLocalizations.of(context).searchbranchby, - prefixIcon: const Icon(Icons.search), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - ), - ), - ), - ), - -// List of branches - Expanded( - child: _filteredBranches.isEmpty - ? const Center(child: Text("No matching branches found")) - : ListView.builder( - itemCount: _filteredBranches.length, - itemBuilder: (context, index) { - final branch = _filteredBranches[index]; - return Card( - margin: const EdgeInsets.symmetric( - horizontal: 12, vertical: 6), - child: ListTile( - leading: Icon(Icons.location_city, - color: Theme.of(context).colorScheme.primary), - title: Text(branch.name, - style: - const TextStyle(fontWeight: FontWeight.bold)), - subtitle: Text( - "Code: ${branch.code} | IFSC: ${branch.ifsc} \nBranch Address: ${branch.address}"), - onTap: () { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text("Selected ${branch.name}")), - ); - }, - ), - ); - }, - ), - ), - ], - ), - ); - } } +*/ +void _filterLocations(String query) { + setState(() { + if (query.isEmpty) { + _filteredLocations = _allLocations; + } else { + _filteredLocations = _allLocations.where((location) { + final lowerQuery = query.toLowerCase(); + return location.name.toLowerCase().contains(lowerQuery) || + (location.code?.toLowerCase().contains(lowerQuery) ?? false) || + (location.ifsc?.toLowerCase().contains(lowerQuery) ?? false) || + location.address.toLowerCase().contains(lowerQuery); + }).toList(); + } + }); +} + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context).branchLocator), + ), + body: Column( + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: TextField( + controller: _searchController, + onChanged: _filterLocations, + decoration: InputDecoration( + hintText: AppLocalizations.of(context).searchbranchby, + prefixIcon: const Icon(Icons.search), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + + // Content area +Expanded( + child: _isLoading + ? const Center(child: CircularProgressIndicator()) + : _filteredLocations.isEmpty + ? const Center(child: Text("No matching locations found")) + : ListView.builder( + itemCount: _filteredLocations.length, + itemBuilder: (context, index) { + final location = _filteredLocations[index]; + return _buildLocationItem(location); + }, + ), +), + ], + ), + ); + } + + Widget _buildHeader(String title) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Text( + title, + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + color: Theme.of(context).colorScheme.primary, + ), + ), + ); +} + +// Helper widget to build a single location item +Widget _buildLocationItem(Location location) { + final isBranch = location.type == LocationType.branch; + return Card( + margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + child: ListTile( + leading: CircleAvatar( + child: Icon(isBranch ? Icons.location_city : Icons.currency_rupee), + ), + title: Text(location.name, + style: const TextStyle(fontWeight: FontWeight.bold)), + subtitle: Text( + isBranch + ? "Code: ${location.code} | IFSC: ${location.ifsc}\nAddress: ${location.address}" + : "Address: ${location.address}", + ), + onTap: () { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("Selected ${location.name}")), + ); + }, + ), + ); +} +} \ No newline at end of file diff --git a/lib/features/service/screens/service_screen.dart b/lib/features/service/screens/service_screen.dart index 1a5de3c..6ad3b33 100644 --- a/lib/features/service/screens/service_screen.dart +++ b/lib/features/service/screens/service_screen.dart @@ -29,23 +29,30 @@ Widget build(BuildContext context) { icon: Symbols.add, label: AppLocalizations.of(context).accountOpeningDeposit, onTap: () {}, - disabled: true, // Add this + disabled: true, ), const Divider(height: 1), ServiceManagementTile( icon: Symbols.add, label: AppLocalizations.of(context).accountOpeningLoan, onTap: () {}, - disabled: true, // Add this + disabled: true, ), const Divider(height: 1), ServiceManagementTile( icon: Symbols.captive_portal, label: AppLocalizations.of(context).quickLinks, onTap: () {}, - disabled: true, // Add this + disabled: true, ), const Divider(height: 1), + ServiceManagementTile( + icon: Symbols.question_mark, + label: AppLocalizations.of(context).faq, + onTap: () {}, + disabled: true, + ), + const Divider(height: 1), ServiceManagementTile( icon: Symbols.missing_controller, label: AppLocalizations.of(context).branchLocator, @@ -55,7 +62,7 @@ Widget build(BuildContext context) { MaterialPageRoute( builder: (context) => const BranchLocatorScreen())); }, - disabled: true, // Add this + disabled: false, ), const Divider(height: 1), ], @@ -68,14 +75,14 @@ class ServiceManagementTile extends StatelessWidget { final IconData icon; final String label; final VoidCallback onTap; - final bool disabled; // Add this line + final bool disabled; const ServiceManagementTile({ super.key, required this.icon, required this.label, required this.onTap, - this.disabled = false, // Add this line + this.disabled = false, }); @override @@ -84,20 +91,20 @@ class ServiceManagementTile extends StatelessWidget { return ListTile( leading: Icon( icon, - color: disabled ? theme.disabledColor : null, // Change color when disabled + color: disabled ? theme.disabledColor : null, ), title: Text( label, style: TextStyle( - color: disabled ? theme.disabledColor : null, // Change color when disabled + color: disabled ? theme.disabledColor : null, ), ), trailing: Icon( Symbols.arrow_right, size: 20, - color: disabled ? theme.disabledColor : null, // Change color when disabled + color: disabled ? theme.disabledColor : null, ), - onTap: disabled ? null : onTap, // Disable onTap when disabled + onTap: disabled ? null : onTap, ); } } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index fe6f51a..04a6ec5 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -98,7 +98,7 @@ "accountOpeningDeposit": "Account Opening Request - Deposit", "accountOpeningLoan": "Account Opening Request - Loan", "quickLinks": "Quick Links", -"branchLocator": "Branch Locator", +"branchLocator": "Branch and ATM Locator", "emailLaunchError": "Could not launch email client for", "dialerLaunchError": "Could not launch dialer for", "writeToUs": "Write to us", @@ -248,7 +248,7 @@ "validateBeneficiaryproceeding": "Please validate beneficiary before proceeding", "findnearbybranched": "Find nearby branches", "searchbranch": "Search Branch", - "searchbranchby": "Search by Branch Name / Code / IFSC", + "searchbranchby": "Name / Code / IFSC / Address", "branchsearchsoon": "Branch search coming soon...", "loginFailed": "Login failed", "invalidCredentials": "Invalid credentials", @@ -315,5 +315,8 @@ "themeModeDark": "Dark", "details": "Details", "remarks": "Remarks (Optional)", - "kccbMobile": "KCCB Mobile" + "kccbMobile": "KCCB Mobile", + "faq": "Frequently Asked Questions(FAQs)", + "branches": "Branches", + "atms": "ATMs" } diff --git a/lib/l10n/app_hi.arb b/lib/l10n/app_hi.arb index 39ba8b4..cf36c40 100644 --- a/lib/l10n/app_hi.arb +++ b/lib/l10n/app_hi.arb @@ -98,7 +98,7 @@ "accountOpeningDeposit": "खाता खोलने का अनुरोध - जमा", "accountOpeningLoan": "खाता खोलने का अनुरोध - ऋण", "quickLinks": "त्वरित लिंक", -"branchLocator": "शाखा लोकेटर", +"branchLocator": "शाखा और एटीएम लोकेटर", "emailLaunchError": "ईमेल क्लाइंट खोलने में विफल: ", "dialerLaunchError": "डायलर खोलने में विफल: ", "writeToUs": "हमें लिखें", @@ -249,7 +249,7 @@ "validateBeneficiaryproceeding": "कृपया आगे बढ़ने से पहले लाभार्थी को पट्टे पर मान्य करें", "findnearbybranched": "आस-पास की शाखाएँ खोजें", "searchbranch": "शाखा खोजें", - "searchbranchby": "शाखा खोजें नाम / बैंक कोड / आईएफएससी द्वारा", + "searchbranchby": "शाखा नाम / बैंक कोड / आईएफएससी / पता", "branchsearchsoon": "शाखा खोज सुविधा जल्द ही आ रही है...", "loginFailed": "लॉगिन विफल", "invalidCredentials": "अवैध प्रत्यय पत्र", @@ -316,5 +316,8 @@ "themeModeDark": "डार्क", "details": "विवरण", "remarks": "विचार (अनिवार्य नहीं)", - "kccbMobile": "केसीसीबी मोबाइल" + "kccbMobile": "केसीसीबी मोबाइल", + "faq": "अक्सर पूछे जाने वाले प्रश्न", +"branches": "शाखाओं", + "atms": "एटीएम" }