Enhance color theme and update board screen UI
- Added new color definitions for secondary and orange shades in AppColors. - Updated TaskItem model to remove title and improve description handling. - Refactored BoardScreen to utilize new color definitions and improve task display. - Enhanced task status messaging and UI consistency across task cards.
This commit is contained in:
@@ -95,6 +95,14 @@ class AppColors {
|
|||||||
static Color get iconColor =>
|
static Color get iconColor =>
|
||||||
_isDarkMode ? const Color(0xFF999999) : const Color(0xFF888888);
|
_isDarkMode ? const Color(0xFF999999) : const Color(0xFF888888);
|
||||||
|
|
||||||
|
static Color get secondary70 =>
|
||||||
|
_isDarkMode ? const Color(0xFF80C491) : const Color(0xFF1A5E66);
|
||||||
|
|
||||||
|
static Color get secondary20 =>
|
||||||
|
_isDarkMode
|
||||||
|
? const Color.fromRGBO(80, 89, 78, 0.9)
|
||||||
|
: const Color(0xFFC2EAEF);
|
||||||
|
|
||||||
static Color get primary10 =>
|
static Color get primary10 =>
|
||||||
_isDarkMode
|
_isDarkMode
|
||||||
? const Color.fromRGBO(104, 151, 151, 0.2)
|
? const Color.fromRGBO(104, 151, 151, 0.2)
|
||||||
@@ -160,6 +168,14 @@ class AppColors {
|
|||||||
static Color get orange20 =>
|
static Color get orange20 =>
|
||||||
_isDarkMode ? const Color(0xFF6B5E4B) : const Color(0xFFF6D7AB);
|
_isDarkMode ? const Color(0xFF6B5E4B) : const Color(0xFFF6D7AB);
|
||||||
|
|
||||||
|
static Color get orange =>
|
||||||
|
_isDarkMode ? const Color(0xFFE5821E) : const Color(0xFFC07A25);
|
||||||
|
|
||||||
|
static Color get secondary10 =>
|
||||||
|
_isDarkMode
|
||||||
|
? const Color.fromRGBO(46, 49, 45, 0.75)
|
||||||
|
: const Color(0xFFC2EAEF);
|
||||||
|
|
||||||
static Color get red0 =>
|
static Color get red0 =>
|
||||||
_isDarkMode
|
_isDarkMode
|
||||||
? const Color(0xFF312F2F)
|
? const Color(0xFF312F2F)
|
||||||
@@ -174,7 +190,6 @@ class AppColors {
|
|||||||
// static const Color red0 = Color(0xFF312F2F);
|
// static const Color red0 = Color(0xFF312F2F);
|
||||||
// static const Color red10 = Color(0xFF524545);
|
// static const Color red10 = Color(0xFF524545);
|
||||||
static const Color red = Color(0xFFFF3B30);
|
static const Color red = Color(0xFFFF3B30);
|
||||||
static const Color orange = Color(0xFFE5821E);
|
|
||||||
|
|
||||||
// Other colors
|
// Other colors
|
||||||
static const Color lightBlue = Color(0xFFe8ecfc);
|
static const Color lightBlue = Color(0xFFe8ecfc);
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:tm_app/core/theme/colors.dart';
|
import 'package:tm_app/core/theme/colors.dart';
|
||||||
import 'package:tm_app/core/utils/size_config.dart';
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
import 'package:tm_app/views/shared/desktop_navigation_widget.dart';
|
import 'package:tm_app/views/shared/desktop_navigation_widget.dart';
|
||||||
|
|
||||||
// مدل Task برای نگهداری اطلاعات هر کارت
|
import '../../core/constants/assets.dart';
|
||||||
|
|
||||||
class TaskItem {
|
class TaskItem {
|
||||||
final String id;
|
final String id;
|
||||||
final String title;
|
|
||||||
final String description;
|
final String description;
|
||||||
final DateTime deadline;
|
final DateTime deadline;
|
||||||
final String assignedTo;
|
final String assignedTo;
|
||||||
@@ -15,7 +16,6 @@ class TaskItem {
|
|||||||
|
|
||||||
TaskItem({
|
TaskItem({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.title,
|
|
||||||
required this.description,
|
required this.description,
|
||||||
required this.deadline,
|
required this.deadline,
|
||||||
required this.assignedTo,
|
required this.assignedTo,
|
||||||
@@ -34,12 +34,11 @@ class BoardScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _BoardScreenState extends State<BoardScreen> {
|
class _BoardScreenState extends State<BoardScreen> {
|
||||||
// لیست تسکهای نمونه
|
|
||||||
List<TaskItem> tasks = [
|
List<TaskItem> tasks = [
|
||||||
TaskItem(
|
TaskItem(
|
||||||
id: '1',
|
id: '1',
|
||||||
title: 'موضوع مناقصه',
|
description:
|
||||||
description: 'لورم سد می تورتور اوی پوروس سنکتوس. موربی لائورت تورتور...',
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua',
|
||||||
deadline: DateTime(2025, 6, 15),
|
deadline: DateTime(2025, 6, 15),
|
||||||
assignedTo: 'Pratyush Tewari',
|
assignedTo: 'Pratyush Tewari',
|
||||||
isReady: false,
|
isReady: false,
|
||||||
@@ -47,8 +46,8 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
),
|
),
|
||||||
TaskItem(
|
TaskItem(
|
||||||
id: '2',
|
id: '2',
|
||||||
title: 'موضوع مناقصه',
|
description:
|
||||||
description: 'لورم سد موربی لائورت تورتور...',
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua',
|
||||||
deadline: DateTime(2025, 6, 15),
|
deadline: DateTime(2025, 6, 15),
|
||||||
assignedTo: 'Pratyush Tewari',
|
assignedTo: 'Pratyush Tewari',
|
||||||
isReady: true,
|
isReady: true,
|
||||||
@@ -56,9 +55,8 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
),
|
),
|
||||||
TaskItem(
|
TaskItem(
|
||||||
id: '3',
|
id: '3',
|
||||||
title: 'موضوع مناقصه',
|
|
||||||
description:
|
description:
|
||||||
'لورم ایپسوم. سد می تورتور اوی پوروس سنکتوس. موربی لائورت تورتور...',
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua',
|
||||||
deadline: DateTime(2025, 6, 15),
|
deadline: DateTime(2025, 6, 15),
|
||||||
assignedTo: 'Pratyush Tewari',
|
assignedTo: 'Pratyush Tewari',
|
||||||
isReady: false,
|
isReady: false,
|
||||||
@@ -66,8 +64,8 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
),
|
),
|
||||||
TaskItem(
|
TaskItem(
|
||||||
id: '4',
|
id: '4',
|
||||||
title: 'موضوع مناقصه',
|
description:
|
||||||
description: 'لورم ایپسوم امت...',
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua',
|
||||||
deadline: DateTime(2025, 6, 15),
|
deadline: DateTime(2025, 6, 15),
|
||||||
assignedTo: 'Pratyush Tewari',
|
assignedTo: 'Pratyush Tewari',
|
||||||
isReady: true,
|
isReady: true,
|
||||||
@@ -75,8 +73,8 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
),
|
),
|
||||||
TaskItem(
|
TaskItem(
|
||||||
id: '5',
|
id: '5',
|
||||||
title: 'موضوع مناقصه',
|
description:
|
||||||
description: 'لورم سد می تورتور اوی پوروس سنکتوس. موربی لائورت تورتور...',
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua',
|
||||||
deadline: DateTime(2025, 6, 15),
|
deadline: DateTime(2025, 6, 15),
|
||||||
assignedTo: 'Pratyush Tewari',
|
assignedTo: 'Pratyush Tewari',
|
||||||
isReady: false,
|
isReady: false,
|
||||||
@@ -84,9 +82,7 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
// متد برای تغییر وضعیت task
|
|
||||||
void _updateTaskStatus(TaskItem task, TaskStatus newStatus) {
|
void _updateTaskStatus(TaskItem task, TaskStatus newStatus) {
|
||||||
// اگر وضعیت تغییر نکرده، نیازی به آپدیت نیست
|
|
||||||
if (task.status == newStatus) {
|
if (task.status == newStatus) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -96,11 +92,9 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
task.status = newStatus;
|
task.status = newStatus;
|
||||||
});
|
});
|
||||||
|
|
||||||
// نمایش پیام تایید
|
|
||||||
_showStatusChangeMessage(context, task, oldStatus, newStatus);
|
_showStatusChangeMessage(context, task, oldStatus, newStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
// نمایش پیام تغییر وضعیت
|
|
||||||
void _showStatusChangeMessage(
|
void _showStatusChangeMessage(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
TaskItem task,
|
TaskItem task,
|
||||||
@@ -116,7 +110,7 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
'کارت "${task.title}" از ${statusNames[oldStatus]} به ${statusNames[newStatus]} منتقل شد',
|
'Task "${task.description}" moved from ${statusNames[oldStatus]} to ${statusNames[newStatus]}',
|
||||||
style: const TextStyle(fontFamily: 'Peyda'),
|
style: const TextStyle(fontFamily: 'Peyda'),
|
||||||
),
|
),
|
||||||
duration: const Duration(seconds: 2),
|
duration: const Duration(seconds: 2),
|
||||||
@@ -127,7 +121,6 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// گرفتن تسکهای هر دسته
|
|
||||||
List<TaskItem> _getTasksByStatus(TaskStatus status) {
|
List<TaskItem> _getTasksByStatus(TaskStatus status) {
|
||||||
return tasks.where((task) => task.status == status).toList();
|
return tasks.where((task) => task.status == status).toList();
|
||||||
}
|
}
|
||||||
@@ -169,7 +162,7 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// ستون To Do
|
// To Do
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _BoardColumn(
|
child: _BoardColumn(
|
||||||
title: 'To do',
|
title: 'To do',
|
||||||
@@ -181,24 +174,24 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
// ستون In Progress
|
// In Progress
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _BoardColumn(
|
child: _BoardColumn(
|
||||||
title: 'In progress',
|
title: 'In progress',
|
||||||
color: const Color(0xFFFFF3E0),
|
color: AppColors.orange20,
|
||||||
textColor: const Color(0xFFF57C00),
|
textColor: AppColors.orange,
|
||||||
tasks: _getTasksByStatus(TaskStatus.inProgress),
|
tasks: _getTasksByStatus(TaskStatus.inProgress),
|
||||||
status: TaskStatus.inProgress,
|
status: TaskStatus.inProgress,
|
||||||
onTaskDropped: _updateTaskStatus,
|
onTaskDropped: _updateTaskStatus,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
// ستون Done
|
// Done
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _BoardColumn(
|
child: _BoardColumn(
|
||||||
title: 'Done',
|
title: 'Done',
|
||||||
color: const Color(0xFFE8F5E9),
|
color: AppColors.secondary20,
|
||||||
textColor: const Color(0xFF388E3C),
|
textColor: AppColors.secondary70,
|
||||||
tasks: _getTasksByStatus(TaskStatus.done),
|
tasks: _getTasksByStatus(TaskStatus.done),
|
||||||
status: TaskStatus.done,
|
status: TaskStatus.done,
|
||||||
onTaskDropped: _updateTaskStatus,
|
onTaskDropped: _updateTaskStatus,
|
||||||
@@ -217,7 +210,6 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ویجت ستون بورد
|
|
||||||
class _BoardColumn extends StatelessWidget {
|
class _BoardColumn extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final Color color;
|
final Color color;
|
||||||
@@ -239,7 +231,6 @@ class _BoardColumn extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DragTarget<TaskItem>(
|
return DragTarget<TaskItem>(
|
||||||
onWillAcceptWithDetails: (details) {
|
onWillAcceptWithDetails: (details) {
|
||||||
// فقط اگر task از ستون دیگری باشد، قبول کن
|
|
||||||
return details.data.status != status;
|
return details.data.status != status;
|
||||||
},
|
},
|
||||||
onAcceptWithDetails: (details) {
|
onAcceptWithDetails: (details) {
|
||||||
@@ -249,7 +240,8 @@ class _BoardColumn extends StatelessWidget {
|
|||||||
final isHovering = candidateData.isNotEmpty;
|
final isHovering = candidateData.isNotEmpty;
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isHovering ? color.withOpacity(0.3) : AppColors.primary0,
|
color:
|
||||||
|
isHovering ? color.withValues(alpha: 0.3) : AppColors.primary0,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isHovering ? textColor : AppColors.borderBlue,
|
color: isHovering ? textColor : AppColors.borderBlue,
|
||||||
@@ -259,7 +251,6 @@ class _BoardColumn extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// هدر ستون
|
|
||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 34,
|
height: 34,
|
||||||
@@ -271,14 +262,14 @@ class _BoardColumn extends StatelessWidget {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
title,
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: AppColors.primaryColor,
|
color: textColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// لیست تسکها
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
@@ -296,7 +287,6 @@ class _BoardColumn extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ویجت کارت Task
|
|
||||||
class _TaskCard extends StatelessWidget {
|
class _TaskCard extends StatelessWidget {
|
||||||
final TaskItem task;
|
final TaskItem task;
|
||||||
|
|
||||||
@@ -339,7 +329,7 @@ class _TaskCard extends StatelessWidget {
|
|||||||
border: Border.all(color: AppColors.grey30),
|
border: Border.all(color: AppColors.grey30),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withOpacity(0.05),
|
color: Colors.black.withValues(alpha: 0.05),
|
||||||
blurRadius: 4,
|
blurRadius: 4,
|
||||||
offset: const Offset(0, 2),
|
offset: const Offset(0, 2),
|
||||||
),
|
),
|
||||||
@@ -353,12 +343,16 @@ class _TaskCard extends StatelessWidget {
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// Deadline
|
|
||||||
Container(
|
Container(
|
||||||
height: 24.0,
|
height: 24.0,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.0.w()),
|
padding: EdgeInsets.symmetric(horizontal: 10.0.w()),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColors.primary20,
|
color:
|
||||||
|
task.status == TaskStatus.toDo
|
||||||
|
? AppColors.primary20
|
||||||
|
: task.status == TaskStatus.inProgress
|
||||||
|
? AppColors.orange10
|
||||||
|
: AppColors.secondary10,
|
||||||
borderRadius: BorderRadius.circular(4),
|
borderRadius: BorderRadius.circular(4),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -383,58 +377,29 @@ class _TaskCard extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Row(
|
|
||||||
// children: [
|
|
||||||
// Text(
|
|
||||||
// 'Deadline:',
|
|
||||||
// style: TextStyle(
|
|
||||||
// fontSize: 12,
|
|
||||||
// color: AppColors.grey60,
|
|
||||||
// fontWeight: FontWeight.w500,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// const SizedBox(width: 8),
|
|
||||||
// Text(
|
|
||||||
// _formatDate(task.deadline),
|
|
||||||
// style: TextStyle(
|
|
||||||
// fontSize: 12,
|
|
||||||
// color: AppColors.primaryTextColor,
|
|
||||||
// fontWeight: FontWeight.w600,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
// عنوان
|
|
||||||
Text(
|
|
||||||
task.title,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColors.primaryTextColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
// توضیحات
|
|
||||||
Text(
|
Text(
|
||||||
task.description,
|
task.description,
|
||||||
style: TextStyle(fontSize: 12, color: AppColors.grey60, height: 1.5),
|
style: TextStyle(fontSize: 14, color: AppColors.grey70),
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
// وضعیت و اطلاعات کاربر
|
|
||||||
Row(
|
Container(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||||
children: [
|
decoration: BoxDecoration(
|
||||||
// وضعیت
|
color: task.isReady ? AppColors.primary20 : AppColors.red0,
|
||||||
Row(
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
width: 8,
|
width: 8,
|
||||||
height: 8,
|
height: 8,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: task.isReady ? Colors.blue : Colors.red,
|
color: task.isReady ? AppColors.textBlue : AppColors.error,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -442,23 +407,22 @@ class _TaskCard extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
task.isReady ? 'Ready' : 'Incomplete',
|
task.isReady ? 'Ready' : 'Incomplete',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 12,
|
||||||
color: task.isReady ? Colors.blue : Colors.red,
|
color: task.isReady ? AppColors.textBlue : AppColors.red20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// آیکون کاربر و نام
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.account_circle, size: 16, color: AppColors.grey60),
|
SvgPicture.asset(AssetsManager.profile),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Text(
|
Text(
|
||||||
task.assignedTo,
|
task.assignedTo,
|
||||||
style: TextStyle(fontSize: 11, color: AppColors.grey60),
|
style: TextStyle(fontSize: 12, color: AppColors.grey60),
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user