Add board service and repository, update routes and assets
- Introduced BoardService and BoardRepository for managing board-related data. - Updated app routes to reflect the new board screen structure. - Added new board-related assets to the asset manager. - Refactored BoardScreen navigation to utilize the new provider structure.
This commit is contained in:
@@ -19,8 +19,10 @@ import 'package:tm_app/data/services/your_tenders_service.dart';
|
|||||||
import 'package:tm_app/view_models/final_completion_of_documents_view_model.dart';
|
import 'package:tm_app/view_models/final_completion_of_documents_view_model.dart';
|
||||||
|
|
||||||
import '../../data/repositories/auth_repository.dart';
|
import '../../data/repositories/auth_repository.dart';
|
||||||
|
import '../../data/repositories/board_repositories.dart';
|
||||||
import '../../data/repositories/profile_repository.dart';
|
import '../../data/repositories/profile_repository.dart';
|
||||||
import '../../data/services/auth_service.dart';
|
import '../../data/services/auth_service.dart';
|
||||||
|
import '../../data/services/board_service.dart';
|
||||||
import '../../data/services/profile_service.dart';
|
import '../../data/services/profile_service.dart';
|
||||||
import '../../data/services/tenders_service.dart';
|
import '../../data/services/tenders_service.dart';
|
||||||
import '../../view_models/auth_view_model.dart';
|
import '../../view_models/auth_view_model.dart';
|
||||||
@@ -86,6 +88,10 @@ List<SingleChildWidget> get apiClients {
|
|||||||
create: (context) => NotificationsService(networkManager: context.read()),
|
create: (context) => NotificationsService(networkManager: context.read()),
|
||||||
lazy: true,
|
lazy: true,
|
||||||
),
|
),
|
||||||
|
Provider(
|
||||||
|
create: (context) => BoardService(networkManager: context.read()),
|
||||||
|
lazy: true,
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +143,10 @@ List<SingleChildWidget> get repositories {
|
|||||||
NotificationsRepository(notificationsService: context.read()),
|
NotificationsRepository(notificationsService: context.read()),
|
||||||
lazy: true,
|
lazy: true,
|
||||||
),
|
),
|
||||||
|
Provider(
|
||||||
|
create: (context) => BoardRepository(boardService: context.read()),
|
||||||
|
lazy: true,
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
enum TaskStatus { toDo, inProgress, done }
|
||||||
|
|
||||||
|
extension TaskStatusExtension on TaskStatus {
|
||||||
|
// تبدیل enum به string
|
||||||
|
String get value => name;
|
||||||
|
|
||||||
|
// تبدیل string به enum
|
||||||
|
static TaskStatus fromString(String? status) {
|
||||||
|
if (status == null) {
|
||||||
|
return TaskStatus.toDo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TaskStatus.values.firstWhere(
|
||||||
|
(e) => e.name == status,
|
||||||
|
orElse: () => TaskStatus.toDo,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get displayNameEn {
|
||||||
|
switch (this) {
|
||||||
|
case TaskStatus.toDo:
|
||||||
|
return 'To Do';
|
||||||
|
case TaskStatus.inProgress:
|
||||||
|
return 'In Progress';
|
||||||
|
case TaskStatus.done:
|
||||||
|
return 'Done';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import '../../data/services/model/board_response/board_response.dart';
|
||||||
|
import '../enums/task_status.dart';
|
||||||
|
|
||||||
|
extension BoardDataExtension on BoardData {
|
||||||
|
// تبدیل status string به TaskStatus enum
|
||||||
|
TaskStatus get statusEnum => TaskStatusExtension.fromString(status);
|
||||||
|
|
||||||
|
// کپی BoardData با status جدید
|
||||||
|
BoardData copyWithStatus(TaskStatus newStatus) {
|
||||||
|
return copyWith(status: newStatus.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../data/repositories/board_repositories.dart';
|
||||||
|
import '../../view_models/board_view_model.dart';
|
||||||
|
|
||||||
|
/// Lazy BoardViewModel provider
|
||||||
|
/// Wraps screens that need BoardViewModel
|
||||||
|
Widget boardProvider({required Widget child}) {
|
||||||
|
return ChangeNotifierProvider(
|
||||||
|
create:
|
||||||
|
(context) =>
|
||||||
|
BoardViewModel(boardRepository: context.read<BoardRepository>()),
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tm_app/views/board/board_screen.dart';
|
import 'package:tm_app/views/board/pages/board_screen.dart';
|
||||||
import 'package:tm_app/views/completion_of_documents/pages/complectopn_of_documents_screen.dart';
|
import 'package:tm_app/views/completion_of_documents/pages/complectopn_of_documents_screen.dart';
|
||||||
import 'package:tm_app/views/detail/pages/detail_screen.dart';
|
import 'package:tm_app/views/detail/pages/detail_screen.dart';
|
||||||
import 'package:tm_app/views/forget_password_create/pages/forgot_password_create_screen.dart';
|
import 'package:tm_app/views/forget_password_create/pages/forgot_password_create_screen.dart';
|
||||||
@@ -18,6 +18,7 @@ import '../../views/profile/pages/profile_screen.dart';
|
|||||||
import '../../views/splash/pages/splash_screen.dart';
|
import '../../views/splash/pages/splash_screen.dart';
|
||||||
import '../../views/tenders/pages/tenders_screen.dart';
|
import '../../views/tenders/pages/tenders_screen.dart';
|
||||||
import '../../views/your_tenders/pages/your_tenders_screen.dart';
|
import '../../views/your_tenders/pages/your_tenders_screen.dart';
|
||||||
|
import '../providers/board_provider.dart';
|
||||||
import '../providers/final_completion_provider.dart';
|
import '../providers/final_completion_provider.dart';
|
||||||
import '../providers/forgot_password_provider.dart';
|
import '../providers/forgot_password_provider.dart';
|
||||||
import '../providers/home_provider.dart';
|
import '../providers/home_provider.dart';
|
||||||
@@ -272,7 +273,7 @@ class BoardRouteData extends GoRouteData with _$BoardRouteData {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, GoRouterState state) {
|
Widget build(BuildContext context, GoRouterState state) {
|
||||||
return const BoardScreen();
|
return boardProvider(child: const BoardScreen());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import '../../core/utils/result.dart';
|
||||||
|
import '../services/board_service.dart';
|
||||||
|
import '../services/model/board_response/board_response.dart';
|
||||||
|
|
||||||
|
class BoardRepository {
|
||||||
|
final BoardService _boardService;
|
||||||
|
BoardRepository({required BoardService boardService})
|
||||||
|
: _boardService = boardService;
|
||||||
|
|
||||||
|
Future<Result<BoardResponse>> getBoard() async {
|
||||||
|
return _boardService.getBoard();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import '../../../core/network/network_manager.dart';
|
||||||
|
import '../../core/config/app_config.dart';
|
||||||
|
import '../../core/utils/result.dart';
|
||||||
|
import 'model/board_response/board_response.dart';
|
||||||
|
|
||||||
|
class BoardService {
|
||||||
|
BoardService({required NetworkManager networkManager})
|
||||||
|
: _networkManager = networkManager;
|
||||||
|
|
||||||
|
final NetworkManager _networkManager;
|
||||||
|
|
||||||
|
Future<Result<BoardResponse>> getBoard() async {
|
||||||
|
final uri = '${AppConfig.apiBaseUrl}/api/v1/board';
|
||||||
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
|
|
||||||
|
// final result = await _networkManager.makeRequest(
|
||||||
|
// uri,
|
||||||
|
// (json) => BoardResponse.fromJson(json),
|
||||||
|
// method: 'GET',
|
||||||
|
// );
|
||||||
|
// return result;
|
||||||
|
|
||||||
|
return Result.ok(
|
||||||
|
BoardResponse(
|
||||||
|
success: true,
|
||||||
|
message: 'Board data fetched successfully',
|
||||||
|
data: tasks,
|
||||||
|
error: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BoardData> tasks = [
|
||||||
|
BoardData(
|
||||||
|
id: '1',
|
||||||
|
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),
|
||||||
|
assignedTo: 'Pratyush Tewari',
|
||||||
|
isReady: false,
|
||||||
|
status: 'toDo',
|
||||||
|
),
|
||||||
|
BoardData(
|
||||||
|
id: '2',
|
||||||
|
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),
|
||||||
|
assignedTo: 'Pratyush Tewari',
|
||||||
|
isReady: true,
|
||||||
|
status: 'toDo',
|
||||||
|
),
|
||||||
|
BoardData(
|
||||||
|
id: '3',
|
||||||
|
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),
|
||||||
|
assignedTo: 'Pratyush Tewari',
|
||||||
|
isReady: false,
|
||||||
|
status: 'inProgress',
|
||||||
|
),
|
||||||
|
BoardData(
|
||||||
|
id: '4',
|
||||||
|
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),
|
||||||
|
assignedTo: 'Pratyush Tewari',
|
||||||
|
isReady: true,
|
||||||
|
status: 'inProgress',
|
||||||
|
),
|
||||||
|
BoardData(
|
||||||
|
id: '5',
|
||||||
|
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),
|
||||||
|
assignedTo: 'Pratyush Tewari',
|
||||||
|
isReady: false,
|
||||||
|
status: 'done',
|
||||||
|
),
|
||||||
|
];
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
import '../error/error_model.dart';
|
||||||
|
|
||||||
|
part 'board_response.freezed.dart';
|
||||||
|
part 'board_response.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class BoardResponse with _$BoardResponse {
|
||||||
|
const factory BoardResponse({
|
||||||
|
required bool? success,
|
||||||
|
required String? message,
|
||||||
|
required List<BoardData>? data,
|
||||||
|
required ErrorModel? error,
|
||||||
|
}) = _BoardResponse;
|
||||||
|
|
||||||
|
factory BoardResponse.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$BoardResponseFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class BoardData with _$BoardData {
|
||||||
|
const factory BoardData({
|
||||||
|
required String? id,
|
||||||
|
required String? description,
|
||||||
|
required DateTime? deadline,
|
||||||
|
required String? assignedTo,
|
||||||
|
required bool? isReady,
|
||||||
|
required String? status,
|
||||||
|
}) = _BoardData;
|
||||||
|
|
||||||
|
factory BoardData.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$BoardDataFromJson(json);
|
||||||
|
}
|
||||||
@@ -0,0 +1,596 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'board_response.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$BoardResponse {
|
||||||
|
|
||||||
|
bool? get success; String? get message; List<BoardData>? get data; ErrorModel? get error;
|
||||||
|
/// Create a copy of BoardResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$BoardResponseCopyWith<BoardResponse> get copyWith => _$BoardResponseCopyWithImpl<BoardResponse>(this as BoardResponse, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this BoardResponse to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is BoardResponse&&(identical(other.success, success) || other.success == success)&&(identical(other.message, message) || other.message == message)&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.error, error) || other.error == error));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,success,message,const DeepCollectionEquality().hash(data),error);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'BoardResponse(success: $success, message: $message, data: $data, error: $error)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $BoardResponseCopyWith<$Res> {
|
||||||
|
factory $BoardResponseCopyWith(BoardResponse value, $Res Function(BoardResponse) _then) = _$BoardResponseCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
bool? success, String? message, List<BoardData>? data, ErrorModel? error
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$ErrorModelCopyWith<$Res>? get error;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$BoardResponseCopyWithImpl<$Res>
|
||||||
|
implements $BoardResponseCopyWith<$Res> {
|
||||||
|
_$BoardResponseCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final BoardResponse _self;
|
||||||
|
final $Res Function(BoardResponse) _then;
|
||||||
|
|
||||||
|
/// Create a copy of BoardResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? success = freezed,Object? message = freezed,Object? data = freezed,Object? error = freezed,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<BoardData>?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ErrorModel?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
/// Create a copy of BoardResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ErrorModelCopyWith<$Res>? get error {
|
||||||
|
if (_self.error == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ErrorModelCopyWith<$Res>(_self.error!, (value) {
|
||||||
|
return _then(_self.copyWith(error: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [BoardResponse].
|
||||||
|
extension BoardResponsePatterns on BoardResponse {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _BoardResponse value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardResponse() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _BoardResponse value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardResponse():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _BoardResponse value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardResponse() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool? success, String? message, List<BoardData>? data, ErrorModel? error)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardResponse() when $default != null:
|
||||||
|
return $default(_that.success,_that.message,_that.data,_that.error);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool? success, String? message, List<BoardData>? data, ErrorModel? error) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardResponse():
|
||||||
|
return $default(_that.success,_that.message,_that.data,_that.error);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool? success, String? message, List<BoardData>? data, ErrorModel? error)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardResponse() when $default != null:
|
||||||
|
return $default(_that.success,_that.message,_that.data,_that.error);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _BoardResponse implements BoardResponse {
|
||||||
|
const _BoardResponse({required this.success, required this.message, required final List<BoardData>? data, required this.error}): _data = data;
|
||||||
|
factory _BoardResponse.fromJson(Map<String, dynamic> json) => _$BoardResponseFromJson(json);
|
||||||
|
|
||||||
|
@override final bool? success;
|
||||||
|
@override final String? message;
|
||||||
|
final List<BoardData>? _data;
|
||||||
|
@override List<BoardData>? get data {
|
||||||
|
final value = _data;
|
||||||
|
if (value == null) return null;
|
||||||
|
if (_data is EqualUnmodifiableListView) return _data;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override final ErrorModel? error;
|
||||||
|
|
||||||
|
/// Create a copy of BoardResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$BoardResponseCopyWith<_BoardResponse> get copyWith => __$BoardResponseCopyWithImpl<_BoardResponse>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$BoardResponseToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _BoardResponse&&(identical(other.success, success) || other.success == success)&&(identical(other.message, message) || other.message == message)&&const DeepCollectionEquality().equals(other._data, _data)&&(identical(other.error, error) || other.error == error));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,success,message,const DeepCollectionEquality().hash(_data),error);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'BoardResponse(success: $success, message: $message, data: $data, error: $error)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$BoardResponseCopyWith<$Res> implements $BoardResponseCopyWith<$Res> {
|
||||||
|
factory _$BoardResponseCopyWith(_BoardResponse value, $Res Function(_BoardResponse) _then) = __$BoardResponseCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
bool? success, String? message, List<BoardData>? data, ErrorModel? error
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $ErrorModelCopyWith<$Res>? get error;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$BoardResponseCopyWithImpl<$Res>
|
||||||
|
implements _$BoardResponseCopyWith<$Res> {
|
||||||
|
__$BoardResponseCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _BoardResponse _self;
|
||||||
|
final $Res Function(_BoardResponse) _then;
|
||||||
|
|
||||||
|
/// Create a copy of BoardResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? success = freezed,Object? message = freezed,Object? data = freezed,Object? error = freezed,}) {
|
||||||
|
return _then(_BoardResponse(
|
||||||
|
success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,data: freezed == data ? _self._data : data // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<BoardData>?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ErrorModel?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of BoardResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ErrorModelCopyWith<$Res>? get error {
|
||||||
|
if (_self.error == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ErrorModelCopyWith<$Res>(_self.error!, (value) {
|
||||||
|
return _then(_self.copyWith(error: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$BoardData {
|
||||||
|
|
||||||
|
String? get id; String? get description; DateTime? get deadline; String? get assignedTo; bool? get isReady; String? get status;
|
||||||
|
/// Create a copy of BoardData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$BoardDataCopyWith<BoardData> get copyWith => _$BoardDataCopyWithImpl<BoardData>(this as BoardData, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this BoardData to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is BoardData&&(identical(other.id, id) || other.id == id)&&(identical(other.description, description) || other.description == description)&&(identical(other.deadline, deadline) || other.deadline == deadline)&&(identical(other.assignedTo, assignedTo) || other.assignedTo == assignedTo)&&(identical(other.isReady, isReady) || other.isReady == isReady)&&(identical(other.status, status) || other.status == status));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,id,description,deadline,assignedTo,isReady,status);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'BoardData(id: $id, description: $description, deadline: $deadline, assignedTo: $assignedTo, isReady: $isReady, status: $status)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $BoardDataCopyWith<$Res> {
|
||||||
|
factory $BoardDataCopyWith(BoardData value, $Res Function(BoardData) _then) = _$BoardDataCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String? id, String? description, DateTime? deadline, String? assignedTo, bool? isReady, String? status
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$BoardDataCopyWithImpl<$Res>
|
||||||
|
implements $BoardDataCopyWith<$Res> {
|
||||||
|
_$BoardDataCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final BoardData _self;
|
||||||
|
final $Res Function(BoardData) _then;
|
||||||
|
|
||||||
|
/// Create a copy of BoardData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = freezed,Object? description = freezed,Object? deadline = freezed,Object? assignedTo = freezed,Object? isReady = freezed,Object? status = freezed,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,deadline: freezed == deadline ? _self.deadline : deadline // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,assignedTo: freezed == assignedTo ? _self.assignedTo : assignedTo // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,isReady: freezed == isReady ? _self.isReady : isReady // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool?,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [BoardData].
|
||||||
|
extension BoardDataPatterns on BoardData {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _BoardData value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardData() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _BoardData value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardData():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _BoardData value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardData() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String? id, String? description, DateTime? deadline, String? assignedTo, bool? isReady, String? status)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardData() when $default != null:
|
||||||
|
return $default(_that.id,_that.description,_that.deadline,_that.assignedTo,_that.isReady,_that.status);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String? id, String? description, DateTime? deadline, String? assignedTo, bool? isReady, String? status) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardData():
|
||||||
|
return $default(_that.id,_that.description,_that.deadline,_that.assignedTo,_that.isReady,_that.status);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String? id, String? description, DateTime? deadline, String? assignedTo, bool? isReady, String? status)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _BoardData() when $default != null:
|
||||||
|
return $default(_that.id,_that.description,_that.deadline,_that.assignedTo,_that.isReady,_that.status);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _BoardData implements BoardData {
|
||||||
|
const _BoardData({required this.id, required this.description, required this.deadline, required this.assignedTo, required this.isReady, required this.status});
|
||||||
|
factory _BoardData.fromJson(Map<String, dynamic> json) => _$BoardDataFromJson(json);
|
||||||
|
|
||||||
|
@override final String? id;
|
||||||
|
@override final String? description;
|
||||||
|
@override final DateTime? deadline;
|
||||||
|
@override final String? assignedTo;
|
||||||
|
@override final bool? isReady;
|
||||||
|
@override final String? status;
|
||||||
|
|
||||||
|
/// Create a copy of BoardData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$BoardDataCopyWith<_BoardData> get copyWith => __$BoardDataCopyWithImpl<_BoardData>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$BoardDataToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _BoardData&&(identical(other.id, id) || other.id == id)&&(identical(other.description, description) || other.description == description)&&(identical(other.deadline, deadline) || other.deadline == deadline)&&(identical(other.assignedTo, assignedTo) || other.assignedTo == assignedTo)&&(identical(other.isReady, isReady) || other.isReady == isReady)&&(identical(other.status, status) || other.status == status));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,id,description,deadline,assignedTo,isReady,status);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'BoardData(id: $id, description: $description, deadline: $deadline, assignedTo: $assignedTo, isReady: $isReady, status: $status)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$BoardDataCopyWith<$Res> implements $BoardDataCopyWith<$Res> {
|
||||||
|
factory _$BoardDataCopyWith(_BoardData value, $Res Function(_BoardData) _then) = __$BoardDataCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String? id, String? description, DateTime? deadline, String? assignedTo, bool? isReady, String? status
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$BoardDataCopyWithImpl<$Res>
|
||||||
|
implements _$BoardDataCopyWith<$Res> {
|
||||||
|
__$BoardDataCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _BoardData _self;
|
||||||
|
final $Res Function(_BoardData) _then;
|
||||||
|
|
||||||
|
/// Create a copy of BoardData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = freezed,Object? description = freezed,Object? deadline = freezed,Object? assignedTo = freezed,Object? isReady = freezed,Object? status = freezed,}) {
|
||||||
|
return _then(_BoardData(
|
||||||
|
id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,deadline: freezed == deadline ? _self.deadline : deadline // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,assignedTo: freezed == assignedTo ? _self.assignedTo : assignedTo // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,isReady: freezed == isReady ? _self.isReady : isReady // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool?,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'board_response.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_BoardResponse _$BoardResponseFromJson(Map<String, dynamic> json) =>
|
||||||
|
_BoardResponse(
|
||||||
|
success: json['success'] as bool?,
|
||||||
|
message: json['message'] as String?,
|
||||||
|
data:
|
||||||
|
(json['data'] as List<dynamic>?)
|
||||||
|
?.map((e) => BoardData.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
error:
|
||||||
|
json['error'] == null
|
||||||
|
? null
|
||||||
|
: ErrorModel.fromJson(json['error'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$BoardResponseToJson(_BoardResponse instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'success': instance.success,
|
||||||
|
'message': instance.message,
|
||||||
|
'data': instance.data,
|
||||||
|
'error': instance.error,
|
||||||
|
};
|
||||||
|
|
||||||
|
_BoardData _$BoardDataFromJson(Map<String, dynamic> json) => _BoardData(
|
||||||
|
id: json['id'] as String?,
|
||||||
|
description: json['description'] as String?,
|
||||||
|
deadline:
|
||||||
|
json['deadline'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['deadline'] as String),
|
||||||
|
assignedTo: json['assignedTo'] as String?,
|
||||||
|
isReady: json['isReady'] as bool?,
|
||||||
|
status: json['status'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$BoardDataToJson(_BoardData instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'description': instance.description,
|
||||||
|
'deadline': instance.deadline?.toIso8601String(),
|
||||||
|
'assignedTo': instance.assignedTo,
|
||||||
|
'isReady': instance.isReady,
|
||||||
|
'status': instance.status,
|
||||||
|
};
|
||||||
@@ -47,12 +47,21 @@ class $AssetsIconsGen {
|
|||||||
/// File path: assets/icons/arrows.svg
|
/// File path: assets/icons/arrows.svg
|
||||||
String get arrows => 'assets/icons/arrows.svg';
|
String get arrows => 'assets/icons/arrows.svg';
|
||||||
|
|
||||||
|
/// File path: assets/icons/board.svg
|
||||||
|
String get board => 'assets/icons/board.svg';
|
||||||
|
|
||||||
|
/// File path: assets/icons/board_active.svg
|
||||||
|
String get boardActive => 'assets/icons/board_active.svg';
|
||||||
|
|
||||||
/// File path: assets/icons/calendar.svg
|
/// File path: assets/icons/calendar.svg
|
||||||
String get calendar => 'assets/icons/calendar.svg';
|
String get calendar => 'assets/icons/calendar.svg';
|
||||||
|
|
||||||
/// File path: assets/icons/clipboard-text.svg
|
/// File path: assets/icons/clipboard-text.svg
|
||||||
String get clipboardText => 'assets/icons/clipboard-text.svg';
|
String get clipboardText => 'assets/icons/clipboard-text.svg';
|
||||||
|
|
||||||
|
/// File path: assets/icons/clock.svg
|
||||||
|
String get clock => 'assets/icons/clock.svg';
|
||||||
|
|
||||||
/// File path: assets/icons/close-circle.svg
|
/// File path: assets/icons/close-circle.svg
|
||||||
String get closeCircle => 'assets/icons/close-circle.svg';
|
String get closeCircle => 'assets/icons/close-circle.svg';
|
||||||
|
|
||||||
@@ -178,8 +187,11 @@ class $AssetsIconsGen {
|
|||||||
arrowUp,
|
arrowUp,
|
||||||
arrowDownSmall,
|
arrowDownSmall,
|
||||||
arrows,
|
arrows,
|
||||||
|
board,
|
||||||
|
boardActive,
|
||||||
calendar,
|
calendar,
|
||||||
clipboardText,
|
clipboardText,
|
||||||
|
clock,
|
||||||
closeCircle,
|
closeCircle,
|
||||||
dangerFill,
|
dangerFill,
|
||||||
danger,
|
danger,
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../core/enums/task_status.dart';
|
||||||
|
import '../core/utils/result.dart';
|
||||||
|
import '../data/repositories/board_repositories.dart';
|
||||||
|
import '../data/services/model/board_response/board_response.dart';
|
||||||
|
|
||||||
|
class BoardViewModel with ChangeNotifier {
|
||||||
|
final BoardRepository _boardRepository;
|
||||||
|
BoardViewModel({required BoardRepository boardRepository})
|
||||||
|
: _boardRepository = boardRepository;
|
||||||
|
|
||||||
|
bool _isLoading = false;
|
||||||
|
String? _errorMessage;
|
||||||
|
List<BoardData> _boardData = [];
|
||||||
|
|
||||||
|
bool get isLoading => _isLoading;
|
||||||
|
String? get errorMessage => _errorMessage;
|
||||||
|
List<BoardData> get boardData => _boardData;
|
||||||
|
bool get hasData => _boardData.isNotEmpty;
|
||||||
|
|
||||||
|
Future<void> getBoard() async {
|
||||||
|
_isLoading = true;
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
|
final result = await _boardRepository.getBoard();
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case Ok<BoardResponse>():
|
||||||
|
// تبدیل به لیست قابل تغییر
|
||||||
|
_boardData = List.from(result.value.data ?? []);
|
||||||
|
break;
|
||||||
|
case Error<BoardResponse>():
|
||||||
|
_errorMessage = result.error.toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
// update task status
|
||||||
|
void updateTaskStatus(String taskId, String newStatus) {
|
||||||
|
final taskIndex = _boardData.indexWhere((task) => task.id == taskId);
|
||||||
|
if (taskIndex != -1) {
|
||||||
|
_boardData[taskIndex] = _boardData[taskIndex].copyWith(status: newStatus);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValidMove(TaskStatus currentStatus, TaskStatus targetStatus) {
|
||||||
|
if (currentStatus == TaskStatus.toDo) {
|
||||||
|
return targetStatus == TaskStatus.inProgress;
|
||||||
|
} else if (currentStatus == TaskStatus.inProgress) {
|
||||||
|
return targetStatus == TaskStatus.toDo || targetStatus == TaskStatus.done;
|
||||||
|
} else if (currentStatus == TaskStatus.done) {
|
||||||
|
return targetStatus == TaskStatus.inProgress;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BoardData> getTasksByStatus(TaskStatus status) {
|
||||||
|
return boardData.where((task) => task.status == status.value).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateTaskStatus(BoardData task, TaskStatus newStatus) {
|
||||||
|
if (task.status == newStatus.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final oldStatus = task.status;
|
||||||
|
|
||||||
|
// update task status in ViewModel
|
||||||
|
updateTaskStatus(task.id!, newStatus.value);
|
||||||
|
|
||||||
|
// _showStatusChangeMessage(context, task, oldStatus, newStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +1,17 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tm_app/core/extensions/board_data_extension.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/data/services/model/board_response/board_response.dart';
|
||||||
import 'package:tm_app/views/shared/desktop_navigation_widget.dart';
|
import 'package:tm_app/views/shared/desktop_navigation_widget.dart';
|
||||||
|
|
||||||
import '../../core/constants/assets.dart';
|
import '../../../core/constants/assets.dart';
|
||||||
|
import '../../../core/enums/task_status.dart';
|
||||||
class TaskItem {
|
import '../../../core/utils/app_toast.dart';
|
||||||
final String id;
|
import '../../../view_models/board_view_model.dart';
|
||||||
final String description;
|
import '../strings/board_strings.dart';
|
||||||
final DateTime deadline;
|
|
||||||
final String assignedTo;
|
|
||||||
final bool isReady;
|
|
||||||
TaskStatus status;
|
|
||||||
|
|
||||||
TaskItem({
|
|
||||||
required this.id,
|
|
||||||
required this.description,
|
|
||||||
required this.deadline,
|
|
||||||
required this.assignedTo,
|
|
||||||
required this.isReady,
|
|
||||||
required this.status,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
enum TaskStatus { toDo, inProgress, done }
|
|
||||||
|
|
||||||
class BoardScreen extends StatefulWidget {
|
class BoardScreen extends StatefulWidget {
|
||||||
const BoardScreen({super.key});
|
const BoardScreen({super.key});
|
||||||
@@ -34,117 +21,94 @@ class BoardScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _BoardScreenState extends State<BoardScreen> {
|
class _BoardScreenState extends State<BoardScreen> {
|
||||||
List<TaskItem> tasks = [
|
late BoardViewModel _boardViewModel;
|
||||||
TaskItem(
|
|
||||||
id: '1',
|
|
||||||
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),
|
|
||||||
assignedTo: 'Pratyush Tewari',
|
|
||||||
isReady: false,
|
|
||||||
status: TaskStatus.toDo,
|
|
||||||
),
|
|
||||||
TaskItem(
|
|
||||||
id: '2',
|
|
||||||
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),
|
|
||||||
assignedTo: 'Pratyush Tewari',
|
|
||||||
isReady: true,
|
|
||||||
status: TaskStatus.toDo,
|
|
||||||
),
|
|
||||||
TaskItem(
|
|
||||||
id: '3',
|
|
||||||
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),
|
|
||||||
assignedTo: 'Pratyush Tewari',
|
|
||||||
isReady: false,
|
|
||||||
status: TaskStatus.inProgress,
|
|
||||||
),
|
|
||||||
TaskItem(
|
|
||||||
id: '4',
|
|
||||||
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),
|
|
||||||
assignedTo: 'Pratyush Tewari',
|
|
||||||
isReady: true,
|
|
||||||
status: TaskStatus.inProgress,
|
|
||||||
),
|
|
||||||
TaskItem(
|
|
||||||
id: '5',
|
|
||||||
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),
|
|
||||||
assignedTo: 'Pratyush Tewari',
|
|
||||||
isReady: false,
|
|
||||||
status: TaskStatus.done,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
void _updateTaskStatus(TaskItem task, TaskStatus newStatus) {
|
@override
|
||||||
if (task.status == newStatus) {
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_boardViewModel = context.read<BoardViewModel>();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
|
_boardViewModel.getBoard();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateTaskStatus(BoardData task, TaskStatus newStatus) {
|
||||||
|
if (task.statusEnum == newStatus) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final oldStatus = task.status;
|
final oldStatus = task.statusEnum;
|
||||||
setState(() {
|
|
||||||
task.status = newStatus;
|
// update task status in ViewModel
|
||||||
});
|
_boardViewModel.updateTaskStatus(task.id!, newStatus.value);
|
||||||
|
|
||||||
_showStatusChangeMessage(context, task, oldStatus, newStatus);
|
_showStatusChangeMessage(context, task, oldStatus, newStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showStatusChangeMessage(
|
void _showStatusChangeMessage(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
TaskItem task,
|
BoardData task,
|
||||||
TaskStatus oldStatus,
|
TaskStatus oldStatus,
|
||||||
TaskStatus newStatus,
|
TaskStatus newStatus,
|
||||||
) {
|
) {
|
||||||
final statusNames = {
|
final statusNames = {
|
||||||
TaskStatus.toDo: 'To Do',
|
TaskStatus.toDo: BoardStrings.toDo,
|
||||||
TaskStatus.inProgress: 'In Progress',
|
TaskStatus.inProgress: BoardStrings.inProgress,
|
||||||
TaskStatus.done: 'Done',
|
TaskStatus.done: BoardStrings.done,
|
||||||
};
|
};
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
AppToast.success(
|
||||||
SnackBar(
|
context,
|
||||||
content: Text(
|
BoardStrings.taskMovedMessage(
|
||||||
'Task "${task.description}" moved from ${statusNames[oldStatus]} to ${statusNames[newStatus]}',
|
statusNames[oldStatus]!,
|
||||||
style: const TextStyle(fontFamily: 'Peyda'),
|
statusNames[newStatus]!,
|
||||||
),
|
|
||||||
duration: const Duration(seconds: 2),
|
|
||||||
backgroundColor: AppColors.successColor,
|
|
||||||
behavior: SnackBarBehavior.floating,
|
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TaskItem> _getTasksByStatus(TaskStatus status) {
|
|
||||||
return tasks.where((task) => task.status == status).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
SizeConfig.init(context);
|
SizeConfig.init(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.backgroundColor,
|
backgroundColor: AppColors.backgroundColor,
|
||||||
|
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
const DesktopNavigationWidget(
|
const DesktopNavigationWidget(
|
||||||
currentIndex: 2, // Tenders index
|
currentIndex: 2, // Tenders index
|
||||||
),
|
),
|
||||||
SizedBox(
|
Consumer<BoardViewModel>(
|
||||||
|
builder: (context, viewModel, child) {
|
||||||
|
if (viewModel.isLoading) {
|
||||||
|
return const Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: AppColors.secondary50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (viewModel.errorMessage != null) {
|
||||||
|
return Expanded(
|
||||||
|
child: Center(child: Text(viewModel.errorMessage!)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (viewModel.hasData == false) {
|
||||||
|
return const Expanded(
|
||||||
|
child: Center(child: Text(BoardStrings.emptyListText)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: SizedBox(
|
||||||
width: 740,
|
width: 740,
|
||||||
height: 735,
|
height: 735,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 64),
|
const SizedBox(height: 32),
|
||||||
Text(
|
Text(
|
||||||
'My board',
|
BoardStrings.boardTitle,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20.0.sp(),
|
fontSize: 20.0.sp(),
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -165,36 +129,45 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
// To Do
|
// To Do
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _BoardColumn(
|
child: _BoardColumn(
|
||||||
title: 'To do',
|
title: BoardStrings.toDo,
|
||||||
color: AppColors.primary20,
|
color: AppColors.primary20,
|
||||||
textColor: const Color(0xFF1976D2),
|
textColor: const Color(0xFF1976D2),
|
||||||
tasks: _getTasksByStatus(TaskStatus.toDo),
|
tasks: viewModel.getTasksByStatus(
|
||||||
|
TaskStatus.toDo,
|
||||||
|
),
|
||||||
status: TaskStatus.toDo,
|
status: TaskStatus.toDo,
|
||||||
onTaskDropped: _updateTaskStatus,
|
onTaskDropped: _updateTaskStatus,
|
||||||
|
isValidMove: viewModel.isValidMove,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
// In Progress
|
// In Progress
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _BoardColumn(
|
child: _BoardColumn(
|
||||||
title: 'In progress',
|
title: BoardStrings.inProgress,
|
||||||
color: AppColors.orange20,
|
color: AppColors.orange20,
|
||||||
textColor: AppColors.orange,
|
textColor: AppColors.orange,
|
||||||
tasks: _getTasksByStatus(TaskStatus.inProgress),
|
tasks: viewModel.getTasksByStatus(
|
||||||
|
TaskStatus.inProgress,
|
||||||
|
),
|
||||||
status: TaskStatus.inProgress,
|
status: TaskStatus.inProgress,
|
||||||
onTaskDropped: _updateTaskStatus,
|
onTaskDropped: _updateTaskStatus,
|
||||||
|
isValidMove: viewModel.isValidMove,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
// Done
|
// Done
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _BoardColumn(
|
child: _BoardColumn(
|
||||||
title: 'Done',
|
title: BoardStrings.done,
|
||||||
color: AppColors.secondary20,
|
color: AppColors.secondary20,
|
||||||
textColor: AppColors.secondary70,
|
textColor: AppColors.secondary70,
|
||||||
tasks: _getTasksByStatus(TaskStatus.done),
|
tasks: viewModel.getTasksByStatus(
|
||||||
|
TaskStatus.done,
|
||||||
|
),
|
||||||
status: TaskStatus.done,
|
status: TaskStatus.done,
|
||||||
onTaskDropped: _updateTaskStatus,
|
onTaskDropped: _updateTaskStatus,
|
||||||
|
isValidMove: viewModel.isValidMove,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -204,6 +177,10 @@ class _BoardScreenState extends State<BoardScreen> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -214,9 +191,10 @@ class _BoardColumn extends StatelessWidget {
|
|||||||
final String title;
|
final String title;
|
||||||
final Color color;
|
final Color color;
|
||||||
final Color textColor;
|
final Color textColor;
|
||||||
final List<TaskItem> tasks;
|
final List<BoardData> tasks;
|
||||||
final TaskStatus status;
|
final TaskStatus status;
|
||||||
final Function(TaskItem, TaskStatus) onTaskDropped;
|
final Function(BoardData, TaskStatus) onTaskDropped;
|
||||||
|
final bool Function(TaskStatus, TaskStatus) isValidMove;
|
||||||
|
|
||||||
const _BoardColumn({
|
const _BoardColumn({
|
||||||
required this.title,
|
required this.title,
|
||||||
@@ -225,13 +203,14 @@ class _BoardColumn extends StatelessWidget {
|
|||||||
required this.tasks,
|
required this.tasks,
|
||||||
required this.status,
|
required this.status,
|
||||||
required this.onTaskDropped,
|
required this.onTaskDropped,
|
||||||
|
required this.isValidMove,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DragTarget<TaskItem>(
|
return DragTarget<BoardData>(
|
||||||
onWillAcceptWithDetails: (details) {
|
onWillAcceptWithDetails: (details) {
|
||||||
return details.data.status != status;
|
return isValidMove(details.data.statusEnum, status);
|
||||||
},
|
},
|
||||||
onAcceptWithDetails: (details) {
|
onAcceptWithDetails: (details) {
|
||||||
onTaskDropped(details.data, status);
|
onTaskDropped(details.data, status);
|
||||||
@@ -288,7 +267,7 @@ class _BoardColumn extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _TaskCard extends StatelessWidget {
|
class _TaskCard extends StatelessWidget {
|
||||||
final TaskItem task;
|
final BoardData task;
|
||||||
|
|
||||||
const _TaskCard({required this.task});
|
const _TaskCard({required this.task});
|
||||||
|
|
||||||
@@ -298,7 +277,7 @@ class _TaskCard extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Draggable<TaskItem>(
|
return Draggable<BoardData>(
|
||||||
data: task,
|
data: task,
|
||||||
feedback: Material(
|
feedback: Material(
|
||||||
elevation: 8,
|
elevation: 8,
|
||||||
@@ -348,9 +327,9 @@ class _TaskCard extends StatelessWidget {
|
|||||||
padding: EdgeInsets.symmetric(horizontal: 10.0.w()),
|
padding: EdgeInsets.symmetric(horizontal: 10.0.w()),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color:
|
color:
|
||||||
task.status == TaskStatus.toDo
|
task.statusEnum == TaskStatus.toDo
|
||||||
? AppColors.primary20
|
? AppColors.primary20
|
||||||
: task.status == TaskStatus.inProgress
|
: task.statusEnum == TaskStatus.inProgress
|
||||||
? AppColors.orange10
|
? AppColors.orange10
|
||||||
: AppColors.secondary10,
|
: AppColors.secondary10,
|
||||||
borderRadius: BorderRadius.circular(4),
|
borderRadius: BorderRadius.circular(4),
|
||||||
@@ -359,7 +338,7 @@ class _TaskCard extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Deadline :',
|
'${BoardStrings.deadlineLabel} :',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14.0,
|
fontSize: 14.0,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -367,7 +346,7 @@ class _TaskCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
_formatDate(task.deadline),
|
_formatDate(task.deadline ?? DateTime.now()),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14.0,
|
fontSize: 14.0,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -379,7 +358,7 @@ class _TaskCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
Text(
|
Text(
|
||||||
task.description,
|
task.description!,
|
||||||
style: TextStyle(fontSize: 14, color: AppColors.grey70),
|
style: TextStyle(fontSize: 14, color: AppColors.grey70),
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
@@ -389,7 +368,7 @@ class _TaskCard extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: task.isReady ? AppColors.primary20 : AppColors.red0,
|
color: task.isReady ?? false ? AppColors.primary20 : AppColors.red0,
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -399,16 +378,18 @@ class _TaskCard extends StatelessWidget {
|
|||||||
width: 8,
|
width: 8,
|
||||||
height: 8,
|
height: 8,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: task.isReady ? AppColors.textBlue : AppColors.error,
|
color: task.isReady! ? AppColors.textBlue : AppColors.error,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
Text(
|
Text(
|
||||||
task.isReady ? 'Ready' : 'Incomplete',
|
task.isReady!
|
||||||
|
? BoardStrings.readyLabel
|
||||||
|
: BoardStrings.incompleteLabel,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: task.isReady ? AppColors.textBlue : AppColors.red20,
|
color: task.isReady! ? AppColors.textBlue : AppColors.red20,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -421,7 +402,7 @@ class _TaskCard extends StatelessWidget {
|
|||||||
SvgPicture.asset(AssetsManager.profile),
|
SvgPicture.asset(AssetsManager.profile),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Text(
|
Text(
|
||||||
task.assignedTo,
|
task.assignedTo!,
|
||||||
style: TextStyle(fontSize: 12, color: AppColors.grey60),
|
style: TextStyle(fontSize: 12, color: AppColors.grey60),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
class BoardStrings {
|
||||||
|
BoardStrings._();
|
||||||
|
|
||||||
|
static const String boardTitle = 'My Board';
|
||||||
|
static const String toDo = 'To Do';
|
||||||
|
static const String inProgress = 'In Progress';
|
||||||
|
static const String done = 'Done';
|
||||||
|
static const String emptyListText = 'No tasks found';
|
||||||
|
static const String deadlineLabel = 'Deadline';
|
||||||
|
static const String readyLabel = 'Ready';
|
||||||
|
static const String incompleteLabel = 'Incomplete';
|
||||||
|
static String taskMovedMessage(String oldStatus, String newStatus) =>
|
||||||
|
'Task moved from $oldStatus to $newStatus';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user