customer_card.dart 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import 'package:flutter/material.dart';
  2. import 'package:go_router/go_router.dart';
  3. import 'package:ristoris/database/database.dart';
  4. Color? _creditScoreBg(String? colorName) {
  5. switch (colorName?.toUpperCase()) {
  6. case 'VERDE':
  7. return const Color(0xFF008000);
  8. case 'VERDE CHIARO':
  9. return const Color(0xFF90EE90);
  10. case 'VERDE SCURO':
  11. return const Color(0xFF006400);
  12. case 'GIALLO':
  13. return const Color(0xFFFFA500);
  14. case 'GRIGIO':
  15. return const Color(0xFF808080);
  16. case 'ROSSO VIVO':
  17. return const Color(0xFFA80000);
  18. case 'ROSSO SCURO':
  19. return const Color(0xFF8B0000);
  20. case 'ROSSO':
  21. return const Color(0xFFFF0000);
  22. default:
  23. return null;
  24. }
  25. }
  26. class CustomerCard extends StatelessWidget {
  27. final Cliente cliente;
  28. const CustomerCard({super.key, required this.cliente});
  29. @override
  30. Widget build(BuildContext context) {
  31. final theme = Theme.of(context);
  32. final cs = theme.colorScheme;
  33. return Card(
  34. elevation: 0,
  35. color: Colors.white,
  36. clipBehavior: Clip.antiAlias,
  37. shape: RoundedRectangleBorder(
  38. borderRadius: BorderRadius.circular(12),
  39. side: BorderSide(color: cs.outlineVariant),
  40. ),
  41. child: InkWell(
  42. onTap: () => context.push('/dashboard/customers/${cliente.idCliente}'),
  43. child: Padding(
  44. padding: const EdgeInsets.all(16),
  45. child: Column(
  46. crossAxisAlignment: CrossAxisAlignment.start,
  47. children: [
  48. Row(
  49. crossAxisAlignment: CrossAxisAlignment.start,
  50. children: [
  51. Expanded(
  52. child: Text(
  53. cliente.ragioneSociale ?? '',
  54. style: theme.textTheme.bodyMedium?.copyWith(
  55. color: cs.primary,
  56. ),
  57. maxLines: 2,
  58. overflow: TextOverflow.ellipsis,
  59. ),
  60. ),
  61. if ((cliente.codCliente ?? '').isNotEmpty) ...[
  62. const SizedBox(width: 8),
  63. Container(
  64. padding: const EdgeInsets.symmetric(
  65. horizontal: 8,
  66. vertical: 4,
  67. ),
  68. decoration: BoxDecoration(
  69. color: _creditScoreBg(cliente.creditScoreColor) ??
  70. cs.surfaceVariant,
  71. borderRadius: BorderRadius.circular(4),
  72. ),
  73. child: Text(
  74. cliente.codCliente ?? '',
  75. style: TextStyle(
  76. fontSize: 12,
  77. height: 16 / 12,
  78. fontWeight: FontWeight.w500,
  79. color: _creditScoreBg(cliente.creditScoreColor) != null
  80. ? Colors.white
  81. : cs.onSurfaceVariant,
  82. ),
  83. ),
  84. ),
  85. ],
  86. ],
  87. ),
  88. const SizedBox(height: 4),
  89. Text(
  90. cliente.email ?? '',
  91. style: theme.textTheme.bodyMedium?.copyWith(
  92. color: cs.onSurfaceVariant,
  93. ),
  94. maxLines: 1,
  95. overflow: TextOverflow.ellipsis,
  96. ),
  97. const SizedBox(height: 16),
  98. Row(
  99. children: [
  100. Icon(Icons.phone, size: 20, color: cs.onSurfaceVariant),
  101. const SizedBox(width: 8),
  102. Expanded(
  103. child: Text(
  104. cliente.telefono ?? '',
  105. style: theme.textTheme.bodyMedium?.copyWith(
  106. color: cs.onSurfaceVariant,
  107. ),
  108. maxLines: 1,
  109. overflow: TextOverflow.ellipsis,
  110. ),
  111. ),
  112. ],
  113. ),
  114. Row(
  115. children: [
  116. Icon(Icons.business, size: 20, color: cs.onSurfaceVariant),
  117. const SizedBox(width: 8),
  118. Expanded(
  119. child: Text(
  120. cliente.indirizzo ?? '',
  121. style: theme.textTheme.bodyMedium?.copyWith(
  122. color: cs.onSurfaceVariant,
  123. ),
  124. maxLines: 1,
  125. overflow: TextOverflow.ellipsis,
  126. ),
  127. ),
  128. ],
  129. ),
  130. const SizedBox(height: 8),
  131. Row(
  132. children: [
  133. Icon(Icons.location_on, size: 20, color: cs.onSurfaceVariant),
  134. const SizedBox(width: 8),
  135. Expanded(
  136. child: Text(
  137. [
  138. if ((cliente.citta ?? '').isNotEmpty) cliente.citta,
  139. if ((cliente.provincia ?? '').isNotEmpty)
  140. cliente.provincia,
  141. ].join(', '),
  142. style: theme.textTheme.bodyMedium?.copyWith(
  143. color: cs.onSurfaceVariant,
  144. ),
  145. maxLines: 1,
  146. overflow: TextOverflow.ellipsis,
  147. ),
  148. ),
  149. ],
  150. ),
  151. const SizedBox(height: 16),
  152. Divider(height: 1, color: cs.outlineVariant),
  153. const SizedBox(height: 12),
  154. Row(
  155. children: [
  156. Expanded(
  157. child: OutlinedButton.icon(
  158. onPressed: () {
  159. context.go('/dashboard/customers/${cliente.idCliente}');
  160. },
  161. icon: const Icon(Icons.info_outline, size: 18),
  162. label: const Text('Dettagli'),
  163. style: OutlinedButton.styleFrom(
  164. foregroundColor: cs.secondary,
  165. side: BorderSide(
  166. color: cs.secondary.withValues(alpha: 0.3),
  167. ),
  168. ),
  169. ),
  170. ),
  171. const SizedBox(width: 8),
  172. Expanded(
  173. child: FilledButton.icon(
  174. onPressed: () => context.go(
  175. '/dashboard/orders/new?cliente=${cliente.idCliente}',
  176. ),
  177. icon: const Icon(Icons.shopping_cart, size: 18),
  178. label: const Text('Nuovo ordine'),
  179. ),
  180. ),
  181. ],
  182. ),
  183. ],
  184. ),
  185. ),
  186. ),
  187. );
  188. }
  189. }