customer_card.dart 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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:
  52. creditScoreBg(cliente.creditScoreColor) ??
  53. cs.surfaceVariant,
  54. borderRadius: BorderRadius.circular(4),
  55. ),
  56. child: Text(
  57. cliente.codCliente ?? '',
  58. style: TextStyle(
  59. fontSize: 12,
  60. height: 16 / 12,
  61. fontWeight: FontWeight.w500,
  62. color:
  63. creditScoreBg(cliente.creditScoreColor) !=
  64. null
  65. ? Colors.white
  66. : cs.onSurfaceVariant,
  67. ),
  68. ),
  69. ),
  70. ],
  71. ],
  72. ),
  73. const SizedBox(height: 4),
  74. Text(
  75. cliente.email ?? '',
  76. style: theme.textTheme.bodyMedium?.copyWith(
  77. color: cs.onSurfaceVariant,
  78. ),
  79. maxLines: 1,
  80. overflow: TextOverflow.ellipsis,
  81. ),
  82. const SizedBox(height: 16),
  83. Row(
  84. children: [
  85. Icon(Icons.phone, size: 20, color: cs.onSurfaceVariant),
  86. const SizedBox(width: 8),
  87. Expanded(
  88. child: Text(
  89. cliente.telefono ?? '',
  90. style: theme.textTheme.bodyMedium?.copyWith(
  91. color: cs.onSurfaceVariant,
  92. ),
  93. maxLines: 1,
  94. overflow: TextOverflow.ellipsis,
  95. ),
  96. ),
  97. ],
  98. ),
  99. const SizedBox(height: 4),
  100. Row(
  101. children: [
  102. Icon(
  103. Icons.business,
  104. size: 20,
  105. color: cs.onSurfaceVariant,
  106. ),
  107. const SizedBox(width: 8),
  108. Expanded(
  109. child: Text(
  110. cliente.indirizzo ?? '',
  111. style: theme.textTheme.bodyMedium?.copyWith(
  112. color: cs.onSurfaceVariant,
  113. ),
  114. maxLines: 1,
  115. overflow: TextOverflow.ellipsis,
  116. ),
  117. ),
  118. ],
  119. ),
  120. const SizedBox(height: 8),
  121. Row(
  122. children: [
  123. Icon(
  124. Icons.location_on,
  125. size: 20,
  126. color: cs.onSurfaceVariant,
  127. ),
  128. const SizedBox(width: 8),
  129. Expanded(
  130. child: Text(
  131. [
  132. if ((cliente.citta ?? '').isNotEmpty)
  133. cliente.citta,
  134. if ((cliente.provincia ?? '').isNotEmpty)
  135. cliente.provincia,
  136. ].join(', '),
  137. style: theme.textTheme.bodyMedium?.copyWith(
  138. color: cs.onSurfaceVariant,
  139. ),
  140. maxLines: 1,
  141. overflow: TextOverflow.ellipsis,
  142. ),
  143. ),
  144. ],
  145. ),
  146. ],
  147. ),
  148. ),
  149. Divider(height: 1, color: cs.outlineVariant),
  150. const SizedBox(height: 16),
  151. Row(
  152. children: [
  153. Expanded(
  154. child: OutlinedButton.icon(
  155. onPressed: () {
  156. context.go('/dashboard/customers/${cliente.idCliente}');
  157. },
  158. icon: const Icon(Icons.info_outline, size: 18),
  159. label: const Text('Dettagli'),
  160. style: OutlinedButton.styleFrom(
  161. foregroundColor: cs.secondary,
  162. side: BorderSide(
  163. color: cs.secondary.withValues(alpha: 0.3),
  164. ),
  165. ),
  166. ),
  167. ),
  168. const SizedBox(width: 8),
  169. Expanded(
  170. child: FilledButton.icon(
  171. onPressed: () => context.go(
  172. '/dashboard/orders/new?cliente=${cliente.idCliente}',
  173. ),
  174. icon: const Icon(
  175. Icons.add_shopping_cart_outlined,
  176. size: 18,
  177. ),
  178. label: const Text('Ordine'),
  179. ),
  180. ),
  181. ],
  182. ),
  183. ],
  184. ),
  185. ),
  186. ),
  187. );
  188. }
  189. }