| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- import 'package:flutter/material.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:ristoris/core/credit_score_color.dart';
- import 'package:ristoris/database/database.dart';
- import 'package:ristoris/providers/database_provider.dart';
- import '../../widgets/search_bar.dart' as sw;
- import '../../widgets/empty_state.dart';
- class SelezioneClientePage extends ConsumerStatefulWidget {
- final int idAgente;
- const SelezioneClientePage({super.key, required this.idAgente});
- @override
- ConsumerState<SelezioneClientePage> createState() =>
- _SelezioneClientePageState();
- }
- class _SelezioneClientePageState extends ConsumerState<SelezioneClientePage> {
- String _filter = '';
- final _searchCtrl = TextEditingController();
- @override
- void dispose() {
- _searchCtrl.dispose();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- final clientiAsync = ref.watch(
- _filter.isEmpty
- ? customerListForAgentProvider(widget.idAgente)
- : customerSearchForAgentProvider((
- idAgente: widget.idAgente,
- filter: _filter,
- )),
- );
- return Scaffold(
- appBar: AppBar(title: const Text('Seleziona Cliente')),
- body: SafeArea(
- child: Column(
- children: [
- sw.SearchBarWidget(
- controller: _searchCtrl,
- hint: 'Cerca per codice, ragione sociale o partita IVA...',
- onChanged: (v) => setState(() => _filter = v),
- onClear: () {
- _searchCtrl.clear();
- setState(() => _filter = '');
- },
- ),
- Expanded(
- child: clientiAsync.when(
- data: (clienti) {
- if (clienti.isEmpty) {
- return const EmptyState(
- icon: Icons.people_outline,
- title: 'Nessun cliente trovato',
- );
- }
- return ListView.builder(
- padding:
- const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
- itemCount: clienti.length,
- itemBuilder: (_, i) => _ClienteTile(
- cliente: clienti[i],
- onTap: () => _onClienteTap(clienti[i]),
- ),
- );
- },
- loading: () => const Center(child: CircularProgressIndicator()),
- error: (e, _) => Center(child: Text('Errore: $e')),
- ),
- ),
- ],
- ),
- ),
- );
- }
- void _onClienteTap(Cliente cliente) {
- if (cliente.codBlocco == '001') {
- ScaffoldMessenger.of(context).showSnackBar(
- const SnackBar(
- content: Text('Cliente bloccato: impossibile selezionare')),
- );
- return;
- }
- Navigator.pop(context, cliente);
- }
- }
- class _ClienteTile extends StatelessWidget {
- final Cliente cliente;
- final VoidCallback onTap;
- const _ClienteTile({required this.cliente, required this.onTap});
- @override
- Widget build(BuildContext context) {
- final theme = Theme.of(context);
- final cs = theme.colorScheme;
- final bgColor = creditScoreBg(cliente.creditScoreColor);
- return Card(
- margin: const EdgeInsets.only(bottom: 8),
- elevation: 0,
- color: Colors.white,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(12),
- side: BorderSide(color: cs.outlineVariant),
- ),
- child: InkWell(
- borderRadius: BorderRadius.circular(12),
- onTap: onTap,
- child: Padding(
- padding: const EdgeInsets.all(12),
- child: Row(
- children: [
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- children: [
- if ((cliente.codCliente ?? '').isNotEmpty)
- Container(
- padding: const EdgeInsets.symmetric(
- horizontal: 8, vertical: 4),
- decoration: BoxDecoration(
- color: bgColor ?? cs.surfaceContainerHighest,
- borderRadius: BorderRadius.circular(4),
- ),
- child: Text(
- cliente.codCliente ?? '',
- style: TextStyle(
- fontSize: 12,
- height: 16 / 12,
- fontWeight: FontWeight.w500,
- color: bgColor != null
- ? Colors.white
- : cs.onSurfaceVariant,
- ),
- ),
- ),
- const SizedBox(width: 8),
- Expanded(
- child: Text(
- cliente.ragioneSociale ?? '',
- style: theme.textTheme.bodyMedium
- ?.copyWith(fontWeight: FontWeight.w600),
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- ),
- ),
- ],
- ),
- const SizedBox(height: 4),
- Row(
- children: [
- if ((cliente.telefono ?? '').isNotEmpty) ...[
- Icon(Icons.phone,
- size: 14, color: cs.onSurfaceVariant),
- const SizedBox(width: 4),
- Text(cliente.telefono ?? '',
- style: theme.textTheme.bodySmall
- ?.copyWith(color: cs.onSurfaceVariant)),
- const SizedBox(width: 12),
- ],
- if ((cliente.cellulare ?? '').isNotEmpty) ...[
- Icon(Icons.smartphone,
- size: 14, color: cs.onSurfaceVariant),
- const SizedBox(width: 4),
- Text(cliente.cellulare ?? '',
- style: theme.textTheme.bodySmall
- ?.copyWith(color: cs.onSurfaceVariant)),
- ],
- ],
- ),
- ],
- ),
- ),
- if (cliente.codBlocco == '001')
- Icon(Icons.block, color: Colors.red, size: 24)
- else if (cliente.codBlocco != null &&
- cliente.codBlocco!.isNotEmpty)
- Icon(Icons.warning_amber_rounded,
- color: Colors.amber, size: 24),
- ],
- ),
- ),
- ),
- );
- }
- }
- final customerListForAgentProvider =
- FutureProvider.family<List<Cliente>, int>((ref, idAgente) {
- return ref.read(clientiDaoProvider).getActiveClients(idAgente);
- });
- final customerSearchForAgentProvider =
- FutureProvider.family<List<Cliente>, ({int idAgente, String filter})>(
- (ref, params) {
- return ref
- .read(clientiDaoProvider)
- .getClienti(params.idAgente, params.filter);
- },
- );
|