189 lines
5.7 KiB
Dart
189 lines
5.7 KiB
Dart
// lib/screens/settings/air_clients_settings.dart
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:environment_monitoring_app/auth_provider.dart';
|
|
|
|
class AirClientsSettingsScreen extends StatefulWidget {
|
|
const AirClientsSettingsScreen({super.key});
|
|
|
|
@override
|
|
State<AirClientsSettingsScreen> createState() =>
|
|
_AirClientsSettingsScreenState();
|
|
}
|
|
|
|
class _AirClientsSettingsScreenState extends State<AirClientsSettingsScreen> {
|
|
final TextEditingController _airClientSearchController =
|
|
TextEditingController();
|
|
String _airClientSearchQuery = '';
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_airClientSearchController.addListener(_onAirClientSearchChanged);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_airClientSearchController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
void _onAirClientSearchChanged() {
|
|
setState(() {
|
|
_airClientSearchQuery = _airClientSearchController.text;
|
|
});
|
|
}
|
|
|
|
Widget _buildSectionHeader(BuildContext context, String title) {
|
|
return Padding(
|
|
padding: const EdgeInsets.fromLTRB(8.0, 24.0, 8.0, 16.0),
|
|
child: Text(
|
|
title,
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.headlineSmall
|
|
?.copyWith(fontWeight: FontWeight.bold),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildExpansionTile({
|
|
required String title,
|
|
required IconData leadingIcon,
|
|
required Widget child,
|
|
}) {
|
|
return ExpansionTile(
|
|
leading: Icon(leadingIcon),
|
|
title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
|
|
initiallyExpanded: true,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
|
child: child,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildSearchBar({
|
|
required TextEditingController controller,
|
|
required String labelText,
|
|
required String hintText,
|
|
}) {
|
|
return Padding(
|
|
padding: const EdgeInsets.only(bottom: 8.0, top: 8.0),
|
|
child: TextField(
|
|
controller: controller,
|
|
decoration: InputDecoration(
|
|
labelText: labelText,
|
|
hintText: hintText,
|
|
prefixIcon: const Icon(Icons.search),
|
|
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8.0)),
|
|
suffixIcon: controller.text.isNotEmpty
|
|
? IconButton(
|
|
icon: const Icon(Icons.clear),
|
|
onPressed: () => controller.clear())
|
|
: null,
|
|
),
|
|
style: const TextStyle(fontSize: 14),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildClientList(
|
|
List<Map<String, dynamic>>? clients,
|
|
String noMatchText,
|
|
String noDataText,
|
|
Widget Function(Map<String, dynamic>) itemBuilder,
|
|
{double height = 250}) {
|
|
if (clients == null || clients.isEmpty) {
|
|
return Center(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Text(
|
|
clients == null ? noDataText : noMatchText,
|
|
textAlign: TextAlign.center,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
return SizedBox(
|
|
height: height,
|
|
child: ListView.builder(
|
|
itemCount: clients.length,
|
|
itemBuilder: (context, index) {
|
|
final client = clients[index];
|
|
return itemBuilder(client);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildClientTile({required String title, required String subtitle}) {
|
|
return ListTile(
|
|
title: Text(title, style: const TextStyle(fontSize: 14)),
|
|
subtitle: Text(subtitle, style: const TextStyle(fontSize: 12)),
|
|
dense: true,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text("Air Clients"),
|
|
),
|
|
body: Consumer<AuthProvider>(
|
|
builder: (context, auth, child) {
|
|
final filteredAirClients = (auth.airClients?.where((client) {
|
|
final clientName = client['client_name']?.toLowerCase() ?? '';
|
|
final clientId = client['client_id']?.toString().toLowerCase() ?? '';
|
|
final query = _airClientSearchQuery.toLowerCase();
|
|
return clientName.contains(query) || clientId.contains(query);
|
|
}).toList())
|
|
?.cast<Map<String, dynamic>>();
|
|
|
|
return ListView(
|
|
padding: const EdgeInsets.all(16.0),
|
|
children: [
|
|
_buildSectionHeader(context, "Air Clients"),
|
|
Card(
|
|
margin: EdgeInsets.zero,
|
|
child: Column(
|
|
children: [
|
|
_buildExpansionTile(
|
|
title: 'Air Clients',
|
|
leadingIcon: Icons.air,
|
|
child: Column(
|
|
children: [
|
|
_buildSearchBar(
|
|
controller: _airClientSearchController,
|
|
labelText: 'Search Air Clients',
|
|
hintText: 'Search by name or ID',
|
|
),
|
|
const SizedBox(height: 16),
|
|
_buildClientList(
|
|
filteredAirClients,
|
|
'No matching air clients found.',
|
|
'No air clients available. Sync to download.',
|
|
(client) => _buildClientTile(
|
|
title: client['client_name'] ?? 'N/A',
|
|
subtitle: 'ID: ${client['client_id'] ?? 'N/A'}',
|
|
),
|
|
height: 400, // Increased height
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
} |