- Flutter frontend with Provider state management - FastAPI backend with SQLAlchemy ORM - Internationalization support (EN/DE) - Clean Architecture folder structure - GoRouter for navigation - GetIt for dependency injection
152 lines
3.5 KiB
Dart
152 lines
3.5 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:uuid/uuid.dart';
|
|
|
|
import '../../../../core/errors/failures.dart';
|
|
import '../../../../core/logging/app_logger.dart';
|
|
import '../../domain/entities/task_entity.dart';
|
|
import '../../domain/enums/priority.dart';
|
|
import '../../domain/repositories/task_repository.dart';
|
|
|
|
enum FormStatus { initial, loading, success, error }
|
|
|
|
class TaskFormViewModel extends ChangeNotifier {
|
|
final TaskRepository repository;
|
|
final AppLogger logger;
|
|
|
|
TaskFormViewModel({
|
|
required this.repository,
|
|
required this.logger,
|
|
});
|
|
|
|
FormStatus _status = FormStatus.initial;
|
|
Failure? _failure;
|
|
TaskEntity? _existingTask;
|
|
|
|
String _title = '';
|
|
String _description = '';
|
|
DateTime _date = DateTime.now();
|
|
String? _time;
|
|
Priority _priority = Priority.medium;
|
|
|
|
String? _titleError;
|
|
|
|
FormStatus get status => _status;
|
|
Failure? get failure => _failure;
|
|
bool get isEditing => _existingTask != null;
|
|
|
|
String get title => _title;
|
|
String get description => _description;
|
|
DateTime get date => _date;
|
|
String? get time => _time;
|
|
Priority get priority => _priority;
|
|
String? get titleError => _titleError;
|
|
|
|
void initForCreate(DateTime? initialDate) {
|
|
_existingTask = null;
|
|
_title = '';
|
|
_description = '';
|
|
_date = initialDate ?? DateTime.now();
|
|
_time = null;
|
|
_priority = Priority.medium;
|
|
_status = FormStatus.initial;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> initForEdit(String taskId) async {
|
|
_status = FormStatus.loading;
|
|
notifyListeners();
|
|
|
|
final result = await repository.getTaskById(taskId);
|
|
|
|
result.when(
|
|
success: (task) {
|
|
_existingTask = task;
|
|
_title = task.title;
|
|
_description = task.description ?? '';
|
|
_date = task.date;
|
|
_time = task.time;
|
|
_priority = task.priority;
|
|
_status = FormStatus.initial;
|
|
},
|
|
error: (failure) {
|
|
_failure = failure;
|
|
_status = FormStatus.error;
|
|
},
|
|
);
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
void setTitle(String value) {
|
|
_title = value;
|
|
_titleError = null;
|
|
notifyListeners();
|
|
}
|
|
|
|
void setDescription(String value) {
|
|
_description = value;
|
|
notifyListeners();
|
|
}
|
|
|
|
void setDate(DateTime value) {
|
|
_date = value;
|
|
notifyListeners();
|
|
}
|
|
|
|
void setTime(String? value) {
|
|
_time = value;
|
|
notifyListeners();
|
|
}
|
|
|
|
void setPriority(Priority value) {
|
|
_priority = value;
|
|
notifyListeners();
|
|
}
|
|
|
|
bool validate() {
|
|
if (_title.trim().isEmpty) {
|
|
_titleError = 'Title is required';
|
|
notifyListeners();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Future<bool> save() async {
|
|
if (!validate()) return false;
|
|
|
|
_status = FormStatus.loading;
|
|
notifyListeners();
|
|
|
|
final task = TaskEntity(
|
|
id: _existingTask?.id ?? const Uuid().v4(),
|
|
title: _title.trim(),
|
|
description: _description.trim().isEmpty ? null : _description.trim(),
|
|
date: _date,
|
|
time: _time,
|
|
priority: _priority,
|
|
isDone: _existingTask?.isDone ?? false,
|
|
createdAt: _existingTask?.createdAt,
|
|
);
|
|
|
|
final result = isEditing
|
|
? await repository.updateTask(task)
|
|
: await repository.createTask(task);
|
|
|
|
return result.when(
|
|
success: (_) {
|
|
_status = FormStatus.success;
|
|
logger.info(isEditing ? 'Task updated' : 'Task created');
|
|
notifyListeners();
|
|
return true;
|
|
},
|
|
error: (failure) {
|
|
_failure = failure;
|
|
_status = FormStatus.error;
|
|
notifyListeners();
|
|
return false;
|
|
},
|
|
);
|
|
}
|
|
}
|