Camara e chat IA

This commit is contained in:
2026-05-17 17:05:01 +01:00
parent e8fa39c594
commit 5158d140ca
9 changed files with 196 additions and 121 deletions

View File

@@ -42,8 +42,11 @@ class _WeekScreenState extends State<WeekScreen> {
DateTime get _startOfWeek {
final now = DateTime.now();
return DateTime(now.year, now.month, now.day)
.subtract(Duration(days: now.weekday - 1));
return DateTime(
now.year,
now.month,
now.day,
).subtract(Duration(days: now.weekday - 1));
}
String _dateKey(DateTime d) =>
@@ -107,7 +110,7 @@ class _WeekScreenState extends State<WeekScreen> {
_isLoading = false;
});
} catch (e) {
print('Error loading day items: $e');
debugPrint('Error loading day items: $e');
setState(() => _isLoading = false);
}
}
@@ -123,8 +126,9 @@ class _WeekScreenState extends State<WeekScreen> {
final available = List<Map<String, dynamic>>.from(allItems);
final existingIds = _dayItems.map((i) => i['id']).toSet();
final toShow =
available.where((i) => !existingIds.contains(i['id'])).toList();
final toShow = available
.where((i) => !existingIds.contains(i['id']))
.toList();
if (!mounted) return;
final selected = await showModalBottomSheet<List<int>>(
@@ -193,10 +197,12 @@ class _WeekScreenState extends State<WeekScreen> {
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 8),
child: Row(
children: days.map((day) {
final isSelected = day.year == _selectedDay.year &&
final isSelected =
day.year == _selectedDay.year &&
day.month == _selectedDay.month &&
day.day == _selectedDay.day;
final isToday = day.year == DateTime.now().year &&
final isToday =
day.year == DateTime.now().year &&
day.month == DateTime.now().month &&
day.day == DateTime.now().day;
return Expanded(
@@ -280,39 +286,39 @@ class _WeekScreenState extends State<WeekScreen> {
child: _isLoading
? const Center(child: CircularProgressIndicator())
: _dayItems.isEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.calendar_today_outlined,
size: 56,
color: Colors.grey[400],
),
const SizedBox(height: 12),
const Text(
'Nenhum item para este dia',
style: TextStyle(
color: Color(0xFF666666),
fontSize: 16,
),
),
const SizedBox(height: 4),
const Text(
'Toque em + para adicionar',
style: TextStyle(
color: Color(0xFF999999),
fontSize: 13,
),
),
],
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.calendar_today_outlined,
size: 56,
color: Colors.grey[400],
),
)
: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 16),
itemCount: _dayItems.length,
itemBuilder: (_, i) => _buildItemTile(_dayItems[i]),
),
const SizedBox(height: 12),
const Text(
'Nenhum item para este dia',
style: TextStyle(
color: Color(0xFF666666),
fontSize: 16,
),
),
const SizedBox(height: 4),
const Text(
'Toque em + para adicionar',
style: TextStyle(
color: Color(0xFF999999),
fontSize: 13,
),
),
],
),
)
: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 16),
itemCount: _dayItems.length,
itemBuilder: (_, i) => _buildItemTile(_dayItems[i]),
),
),
],
),
@@ -326,11 +332,12 @@ class _WeekScreenState extends State<WeekScreen> {
Widget _buildItemTile(Map<String, dynamic> item) {
final images = item['item_images'] as List?;
final imageUrl =
(images != null && images.isNotEmpty) ? images.first['image_url'] : null;
final category = ITEM_CATEGORIES.firstWhere(
final imageUrl = (images != null && images.isNotEmpty)
? images.first['image_url']
: null;
final category = itemCategories.firstWhere(
(c) => c.id == item['categoria'],
orElse: () => ITEM_CATEGORIES.last,
orElse: () => itemCategories.last,
);
return Card(
@@ -346,7 +353,8 @@ class _WeekScreenState extends State<WeekScreen> {
width: 56,
height: 56,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => _icon(category.icon),
errorBuilder: (context, error, stackTrace) =>
_icon(category.icon),
)
: _icon(category.icon),
),
@@ -367,7 +375,7 @@ class _WeekScreenState extends State<WeekScreen> {
return Container(
width: 56,
height: 56,
color: const Color(0xFF0066CC).withOpacity(0.1),
color: const Color(0xFF0066CC).withValues(alpha: 0.1),
alignment: Alignment.center,
child: Text(icon, style: const TextStyle(fontSize: 26)),
);
@@ -393,10 +401,9 @@ class _ItemPickerSheetState extends State<_ItemPickerSheet> {
Widget build(BuildContext context) {
final filtered = widget.items
.where(
(i) => (i['nome'] ?? '')
.toString()
.toLowerCase()
.contains(_query.toLowerCase()),
(i) => (i['nome'] ?? '').toString().toLowerCase().contains(
_query.toLowerCase(),
),
)
.toList();
@@ -457,13 +464,12 @@ class _ItemPickerSheetState extends State<_ItemPickerSheet> {
final id = item['id'] as int;
final selected = _selected.contains(id);
final images = item['item_images'] as List?;
final imageUrl =
(images != null && images.isNotEmpty)
? images.first['image_url']
: null;
final category = ITEM_CATEGORIES.firstWhere(
final imageUrl = (images != null && images.isNotEmpty)
? images.first['image_url']
: null;
final category = itemCategories.firstWhere(
(c) => c.id == item['categoria'],
orElse: () => ITEM_CATEGORIES.last,
orElse: () => itemCategories.last,
);
return CheckboxListTile(
value: selected,
@@ -487,20 +493,24 @@ class _ItemPickerSheetState extends State<_ItemPickerSheet> {
width: 48,
height: 48,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => Container(
width: 48,
height: 48,
color: const Color(0xFF0066CC)
.withOpacity(0.1),
alignment: Alignment.center,
child: Text(category.icon),
),
errorBuilder:
(context, error, stackTrace) =>
Container(
width: 48,
height: 48,
color: const Color(
0xFF0066CC,
).withValues(alpha: 0.1),
alignment: Alignment.center,
child: Text(category.icon),
),
)
: Container(
width: 48,
height: 48,
color: const Color(0xFF0066CC)
.withOpacity(0.1),
color: const Color(
0xFF0066CC,
).withValues(alpha: 0.1),
alignment: Alignment.center,
child: Text(category.icon),
),
@@ -527,10 +537,7 @@ class _ItemPickerSheetState extends State<_ItemPickerSheet> {
),
child: Text(
'Adicionar (${_selected.length})',
style: const TextStyle(
color: Colors.white,
fontSize: 16,
),
style: const TextStyle(color: Colors.white, fontSize: 16),
),
),
),