import 'package:flutter/material.dart'; import 'package:Stocky/Pages/controllers/MainController.dart'; import 'package:Stocky/Pages/views/tasks_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:flutter_advanced_avatar/flutter_advanced_avatar.dart'; import 'package:get/get.dart'; class HomeScreen extends GetWidget { HomeScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.backgroundColor, appBar: _buildAppBar(context), drawer: _buildDrawer(context), body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.all(16), child: _buildFilterChips(context), ), Obx( () => controller.isProj.value ? SizedBox( height: 220, child: Padding( padding: const EdgeInsets.all(8.0), child: _buildScrollableSection( context, child: _buildProjectsSection(context), ), ), ) : SizedBox(), ), // Задачи / Процессы Padding( padding: const EdgeInsets.all(8.0), child: Obx( () => controller.isTask.value ? _buildProcessSection(context) : SizedBox(), ), ), ], ), ), ); } Widget _buildScrollableSection( BuildContext context, { required Widget child, }) { return LayoutBuilder( builder: (context, constraints) { return SingleChildScrollView(child: child); }, ); } AppBar _buildAppBar(BuildContext context) { return AppBar( title: const Text('Рабочая область'), backgroundColor: AppColors.backgroundColor, actions: [ IconButton( icon: Icon( EvaIcons.bellOutline, size: 26, color: Colors.blueGrey[700], ), onPressed: () { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Оповещения'), backgroundColor: Colors.blueAccent, ), ); }, ), ], ); } Widget _buildFilterChips(BuildContext context) { return Row( children: [ Obx( () => FilterChip( label: const Text('Задачи'), selected: controller.isTask.value, onSelected: (bool selected) { controller.isTask.value = selected; }, selectedColor: Colors.blueAccent.withOpacity(0.1), checkmarkColor: Colors.blueAccent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), ), ), const SizedBox(width: 8), Obx( () => FilterChip( label: const Text('Проекты'), selected: controller.isProj.value, onSelected: (bool selected) { controller.isProj.value = selected; }, selectedColor: Colors.blueAccent.withOpacity(0.1), checkmarkColor: Colors.blueAccent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), ), ), ], ); } Widget _buildProjectsSection(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Projects', style: AppStyles.sectionHeader.copyWith( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), SizedBox( height: 160, child: ListView.builder( scrollDirection: Axis.horizontal, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.only(right: 8), itemCount: 4, itemBuilder: (context, index) => _buildProjectCard(context, index + 1), ), ), ], ); } Widget _buildProjectCard(BuildContext context, int index) { final projectColors = [ [Colors.indigo[900]!, Colors.indigo[400]!], [Colors.blue[900]!, Colors.blue[400]!], [Colors.red[900]!, Colors.red[400]!], [Colors.green[900]!, Colors.green[400]!], ]; final titles = [ 'Front End Development', 'Graphic Design', 'Graphic Design', 'Graphic Design', ]; final dates = [ 'September 2020', 'October 2020', 'October 2020', 'October 2020', ]; return Padding( padding: const EdgeInsets.only(right: 12), child: Container( width: 160, decoration: BoxDecoration( gradient: LinearGradient( colors: projectColors[index - 1], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(24), ), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white.withOpacity(0.3), shape: BoxShape.circle, ), child: Icon( EvaIcons.personOutline, color: Colors.white, size: 20, ), ), const SizedBox(width: 8), Text( 'Project $index', style: TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500, ), ), ], ), const SizedBox(height: 12), Text( titles[index - 1], style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 8), Text( dates[index - 1], style: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 12, ), ), ], ), ), ); } Widget _buildProcessSection(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Активные задачи', style: AppStyles.sectionHeader.copyWith( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), Obx(() { if (controller.tasks.isEmpty) { return Center(child: Text('Нет активных задач')); } return RefreshIndicator( onRefresh: () => controller.fetchTasks(), child: Column( children: controller.tasks .map((task) => _buildProcessTaskCard(context, task)) .toList(), ), ); }), ], ); } Widget _buildProcessTaskCard(BuildContext context, Task task) { final now = DateTime.now(); final startDate = task.startTime; String formatTime(DateTime dt) => dt.toString().substring(11, 16); // HH:mm String formatDateTime(DateTime dt) { if (dt.year == now.year && dt.month == now.month && dt.day == now.day) { return 'Сегодня в ${formatTime(dt)}'; } else if (dt.year == now.year) { return '${dt.day.toString().padLeft(2, '0')}.${dt.month.toString().padLeft(2, '0')} в ${formatTime(dt)}'; } else { return '${dt.day.toString().padLeft(2, '0')}.${dt.month.toString().padLeft(2, '0')}.${dt.year} в ${formatTime(dt)}'; } } final int subtaskCount = task.subtasks?.length ?? 0; final String subtaskLabel = subtaskCount == 1 ? '1 пункт' : subtaskCount < 5 ? '$subtaskCount пункта' : '$subtaskCount пунктов'; return InkWell( onTap: () { Get.dialog(_buildTaskExecutionDialog(task), barrierDismissible: true); }, child: Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 4, spreadRadius: 1, ), ], ), child: Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.pink[50], shape: BoxShape.circle, ), child: Icon( EvaIcons.shoppingCartOutline, color: Colors.pink[400], size: 24, ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( task.title, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black87, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 4), if (task.description.isNotEmpty == true) Text( task.description, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 12, color: Colors.grey[700]), ), ], ), ), if (subtaskCount > 0) Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( formatDateTime(startDate), style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), if (subtaskCount > 0) Text( subtaskLabel, style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), ], ), ], ), ), ); } Widget _buildDrawer(BuildContext context) { return Drawer( child: ListView( padding: EdgeInsets.zero, children: [ Obx( () => DrawerHeader( decoration: BoxDecoration(color: Colors.blue[900]), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AdvancedAvatar( name: controller.username.value, autoTextSize: true, size: 80, statusAlignment: Alignment.topRight, ), const SizedBox(height: 12), Text( controller.username.value, style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), ], ), ), ), ListTile( leading: const Icon(Icons.home), title: const Text('Главная'), onTap: () { Navigator.pop(context); }, ), ListTile( leading: const Icon(Icons.calendar_today), title: const Text('Задачи'), onTap: () { Navigator.pop(context); Get.to(TasksScreen()); // Переход на страницу задач }, ), ListTile( leading: const Icon(Icons.settings), title: const Text('Настройки'), onTap: () { Navigator.pop(context); }, ), Divider(), ListTile( leading: const Icon(Icons.logout), title: const Text('Выход'), onTap: () { // Логика выхода Navigator.pop(context); }, ), ], ), ); } Widget _buildTaskExecutionDialog(Task task) { return Dialog( insetPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 60), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), child: ConstrainedBox( constraints: const BoxConstraints(maxHeight: 500), child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(16), child: StatefulBuilder( builder: (context, setState) { final bool isUnassigned = task.executor.isEmpty; final bool allSubtasksDone = task.items.isNotEmpty && task.items.every((item) => item.isDone); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( task.title, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), const SizedBox(height: 8), if (task.description.isNotEmpty) Text( task.description, style: const TextStyle( fontSize: 15, color: Colors.grey, ), textAlign: TextAlign.center, ), if (task.description.isNotEmpty) const SizedBox(height: 16), if (task.items.isNotEmpty) Column( children: task.items .map( (item) => ListTile( contentPadding: EdgeInsets.zero, title: Text(item.text), leading: item.isDone ? const Icon( Icons.check_circle, color: Colors.green, ) : const Icon( Icons.radio_button_unchecked, color: Colors.grey, ), onTap: () { setState(() { item.isDone = !item.isDone; }); controller.updateTask(task); }, ), ) .toList(), ), // Автор — внизу, перед кнопками if (task.author.isNotEmpty) Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Text( 'Автор: ${task.author}', style: const TextStyle( fontSize: 13, color: Colors.grey, ), ), ), const SizedBox(height: 16), // Кнопки Wrap( spacing: 12, runSpacing: 8, alignment: WrapAlignment.center, children: [ // Кнопка "Взять заявку" if (isUnassigned) ElevatedButton( onPressed: () { controller.assignTaskToCurrentUser(task); // Обновляем состояние, чтобы скрыть кнопку "Взять" // и, возможно, показать новые данные setState(() {}); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue[600], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text( 'Взять заявку', style: TextStyle(color: Colors.white), ), ), // Кнопка "Завершить" — появляется, если все подзадачи сделаны if (allSubtasksDone) ElevatedButton( onPressed: () { controller.completeTask(task); Get.back(); // закрываем диалог ТОЛЬКО при завершении }, style: ElevatedButton.styleFrom( backgroundColor: Colors.green[600], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text( 'Завершить', style: TextStyle(color: Colors.white), ), ), // Кнопка "Закрыть" — всегда доступна OutlinedButton( onPressed: Get.back, style: OutlinedButton.styleFrom( side: const BorderSide(color: Colors.grey), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text('Закрыть'), ), ], ), ], ); }, ), ), ), ), ); } }