customer_card.dart 7.4 KB

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