Branch and ATM Locator added

This commit is contained in:
2025-11-14 14:36:06 +05:30
parent 39165d631e
commit 3135116f26
5 changed files with 347 additions and 175 deletions

View File

@@ -1,19 +1,10 @@
// ignore_for_file: unused_element
import 'package:flutter/material.dart';
import '../../../l10n/app_localizations.dart';
import 'package:kmobile/api/services/branch_service.dart'; // Added: Import BranchService for Atm model and API calls
import 'package:kmobile/di/injection.dart'; // Added: Import for dependency injection (getIt)
import 'package:shimmer/shimmer.dart'; // Added: Import for shimmer loading effect
// Enum to define the type of location
class Location {
final String name;
final String address;
Location({
required this.name,
required this.address,
});
}
// Removed: The local 'Location' class is no longer needed as we use the 'Atm' model from branch_service.dart
class ATMLocatorScreen extends StatefulWidget {
const ATMLocatorScreen({super.key});
@@ -24,58 +15,36 @@ class ATMLocatorScreen extends StatefulWidget {
class _ATMLocatorScreenState extends State<ATMLocatorScreen> {
final TextEditingController _searchController = TextEditingController();
final List<Location> _allLocations = [
Location(
name: "Dharamsala ATM",
address: "Near Main Square, Dharamsala",
),
Location(
name: "Kangra ATM",
address: "Opposite Bus Stand, Kangra",
),
];
List<Location> _filteredLocations = [];
bool _isLoading = false;
var service = getIt<BranchService>(); // Added: Instance of BranchService for API calls
bool _isLoading = true; // State variable to manage loading status
List<Atm> _allAtms = []; // Changed: List to hold all fetched Atm objects
List<Atm> _filteredAtms = []; // Changed: List to hold filtered Atm objects for display
@override
void initState() {
super.initState();
// _fetchAndSetLocations();
_filteredLocations = _allLocations;
_loadAtms(); // Changed: Call _loadAtms to fetch data on initialization
}
// Example of a future API fetching function
/*
Future<void> _fetchAndSetLocations() async {
setState(() {
_isLoading = true;
});
try {
// final locations = await yourApiService.getLocations();
// setState(() {
// _allLocations = locations;
// _filteredLocations = locations;
// });
} catch (e) {
// Handle error
} finally {
/// Fetches the list of ATMs from the API using BranchService.
Future<void> _loadAtms() async {
final data = await service.fetchAtmList(); // Call the new fetchAtmList method
setState(() {
_isLoading = false;
_allAtms = data; // Update the list of all ATMs
_filteredAtms = data; // Initialize filtered list with all ATMs
_isLoading = false; // Set loading to false once data is fetched
});
}
}
*/
void _filterLocations(String query) {
/// Filters the list of ATMs based on the search query.
void _filterAtms(String query) { // Changed: Renamed from _filterLocations
setState(() {
if (query.isEmpty) {
_filteredLocations = _allLocations;
_filteredAtms = _allAtms; // If query is empty, show all ATMs
} else {
_filteredLocations = _allLocations.where((location) {
_filteredAtms = _allAtms.where((atm) { // Changed: Filter based on Atm object
final lowerQuery = query.toLowerCase();
return location.name.toLowerCase().contains(lowerQuery) ||
location.address.toLowerCase().contains(lowerQuery);
return atm.name.toLowerCase().contains(lowerQuery); // Filter by atm.name
}).toList();
}
});
@@ -85,7 +54,7 @@ Future<void> _fetchAndSetLocations() async {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("ATM Locator"),
title: const Text("ATM Locator"), // Title for the app bar
),
body: Stack(
children: [
@@ -95,10 +64,10 @@ Future<void> _fetchAndSetLocations() async {
padding: const EdgeInsets.all(12.0),
child: TextField(
controller: _searchController,
onChanged: _filterLocations,
onChanged: _filterAtms, // Updated: Call _filterAtms on text change
decoration: InputDecoration(
hintText: "Name/Address",
prefixIcon: const Icon(Icons.search),
hintText: "Name/Address", // Hint text for the search bar
prefixIcon: const Icon(Icons.search), // Search icon
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
@@ -106,18 +75,18 @@ Future<void> _fetchAndSetLocations() async {
),
),
// Content area
// Content area: Displays loading shimmer, "no ATMs found", or the list of ATMs
Expanded(
child: _isLoading
? const Center(child: CircularProgressIndicator())
: _filteredLocations.isEmpty
? _buildShimmerList() // Display shimmer while loading
: _filteredAtms.isEmpty
? const Center(
child: Text("No matching locations found"))
child: Text("No matching ATMs found")) // Message if no ATMs found
: ListView.builder(
itemCount: _filteredLocations.length,
itemCount: _filteredAtms.length, // Number of items in the filtered list
itemBuilder: (context, index) {
final location = _filteredLocations[index];
return _buildLocationItem(location);
final atm = _filteredAtms[index]; // Get the current Atm object
return _buildAtmItem(atm); // Build the ATM list item
},
),
),
@@ -126,9 +95,9 @@ Future<void> _fetchAndSetLocations() async {
IgnorePointer(
child: Center(
child: Opacity(
opacity: 0.1, // Low opacity
opacity: 0.1, // Low opacity for background logo
child: Image.asset(
'assets/images/logo.png',
'assets/images/logo.png', // Background logo image
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
),
@@ -140,36 +109,43 @@ Future<void> _fetchAndSetLocations() async {
);
}
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) {
/// Helper widget to build a single ATM list item.
Widget _buildAtmItem(Atm atm) { // Changed: Takes an Atm object
return Card(
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
child: ListTile(
leading: const Icon(Icons.currency_rupee),
title: Text(location.name,
leading: const Icon(Icons.currency_rupee), // Icon for ATM
title: Text(atm.name, // Display the ATM's name
style: const TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text(
"Address: ${location.address}",
),
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Selected ${location.name}")),
SnackBar(content: Text("Selected ${atm.name}")), // Show snackbar on tap
);
},
),
);
}
/// Helper widget to display a shimmer loading effect.
Widget _buildShimmerList() {
return ListView.builder(
itemCount: 10, // Number of shimmer items to display
itemBuilder: (context, index) => Shimmer.fromColors(
baseColor: Colors.grey.shade300,
highlightColor: Colors.grey.shade100,
child: ListTile(
leading: const CircleAvatar(
radius: 24,
backgroundColor: Colors.white,
),
title: Container(
height: 16,
color: Colors.white,
margin: const EdgeInsets.symmetric(vertical: 4),
),
),
),
);
}
}