// lib/Pages/views/tasks_screen.dart import 'package:flutter/material.dart'; import 'package:Stocky/Pages/controllers/MainController.dart'; import 'package:Stocky/Pages/views/task_screen.dart'; import 'package:Stocky/classes/styles.dart'; import 'package:Stocky/models/task_adapter.dart'; import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:swipeable_tile/swipeable_tile.dart'; import 'package:get/get.dart'; class TasksScreen extends GetWidget { const TasksScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.backgroundColor, appBar: _buildAppBar(context), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildDateSelector(context), const SizedBox(height: 20), _buildTasksList(context), ], ), ), ), floatingActionButton: FloatingActionButton( onPressed: () { // После создания — синхронизация не нужна: addTask сам всё делает Get.to(() => const TaskFormScreen()); }, child: const Icon(Icons.add), ), ); } AppBar _buildAppBar(BuildContext context) { return AppBar( backgroundColor: Colors.white, elevation: 0, title: const Text( 'Sep 2020', style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold), ), actions: [ IconButton( icon: Icon(EvaIcons.search, size: 26, color: Colors.blueGrey[700]), onPressed: () {}, ), ], ); } Widget _buildDateSelector(BuildContext context) { return Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.blue[900], borderRadius: BorderRadius.circular(24), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: List.generate(7, (index) { final dayName = [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', ][index]; final dayNumber = 20 + index; return GestureDetector( onTap: () { // Логика выбора даты (опционально) }, child: Container( width: 40, height: 40, decoration: BoxDecoration( color: dayNumber == 21 ? Colors.white : Colors.transparent, borderRadius: BorderRadius.circular(20), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( dayName, style: TextStyle( fontSize: 10, color: dayNumber == 21 ? Colors.blue[900] : Colors.white, ), ), const SizedBox(height: 2), Text( dayNumber.toString(), style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: dayNumber == 21 ? Colors.blue[900] : Colors.white, ), ), ], ), ), ); }), ), ); } Widget _buildTasksList(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Tasks', style: AppStyles.sectionHeader.copyWith( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), Obx(() { // 🔑 ФИЛЬТРУЕМ: скрываем задачи, помеченные на удаление final visibleTasks = controller.tasks .where((task) => task.isDeletedLocally != true) .toList(); if (visibleTasks.isEmpty) { return Center( child: Text( 'No tasks found', style: TextStyle(color: Colors.grey[600]), ), ); } return Column( children: visibleTasks .map((task) => _buildTaskCard(context, task)) .toList(), ); }), ], ); } Widget _buildTaskCard(BuildContext context, Task task) { final startDate = task.startTime; String formatTime(DateTime dt) => dt.toString().substring(11, 16); // HH:mm return SwipeableTile.card( color: Colors.white, shadow: BoxShadow( color: Colors.black.withOpacity(0.35), blurRadius: 4, offset: const Offset(2, 2), ), key: ValueKey(task.id), // ← лучше использовать id, а не UniqueKey() horizontalPadding: 8, verticalPadding: 8, child: InkWell( onTap: () { Get.dialog(_buildTaskExecutionDialog(task), barrierDismissible: true); }, onLongPress: () => Get.to( TaskFormScreen(task: task), ), // ← синхронизация происходит автоматически через updateTask borderRadius: BorderRadius.circular(16), child: Padding( padding: const EdgeInsets.all(16), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.pink[50], shape: BoxShape.circle, ), child: Icon( _getTaskIcon('meeting'), size: 24, color: Colors.pink[400], ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( task.title, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black87, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 4), Text( '${formatTime(startDate)} to ${formatTime(startDate.add(Duration(hours: 2)))}', style: const TextStyle( fontSize: 13, color: Colors.grey, height: 1.4, ), ), ], ), ), IconButton( onPressed: () { // Доп. действия (например, меню) }, icon: const Icon(Icons.more_vert, color: Colors.grey), ), ], ), ), ), onSwiped: (direction) => controller.deleteTask(task), backgroundBuilder: (context, direction, progress) { return Container( color: Colors.redAccent, child: const Align( alignment: Alignment.centerRight, child: Padding( padding: EdgeInsets.all(8.0), child: Text( 'Удалить', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, ), ), ), ), ); }, ); } IconData _getTaskIcon(String category) { switch (category.toLowerCase()) { case 'client call': return Icons.phone_rounded; default: return EvaIcons.shoppingCartOutline; } } Widget _buildTaskExecutionDialog(Task task) { // Здесь можно реализовать логику выполнения подзадач // Пока оставим как есть (без сохранения изменений) return Material( color: Colors.transparent, child: Padding( padding: const EdgeInsets.all(30.0), child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( task.title, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), Text(task.description, style: const TextStyle(fontSize: 16)), const SizedBox(height: 16), ...task.items.map( (item) => ListTile( title: Text(item.text), leading: item.isDone ? const Icon(Icons.check_circle, color: Colors.green) : const Icon(Icons.radio_button_unchecked), ), ), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton(onPressed: Get.back, child: const Text('Закрыть')), ], ), ], ), ), ), ); } }