feat(proj): init

This commit is contained in:
vl.arkhangelskii
2026-09-21 04:06:43 +03:00
commit c956b94983
1076 changed files with 50876 additions and 0 deletions
@@ -0,0 +1,95 @@
import 'package:flutter/foundation.dart';
import 'package:please_pay_me/core/state/async_value.dart';
import 'package:please_pay_me/data/api/api_client.dart';
import 'package:please_pay_me/data/models/job.dart';
import 'package:please_pay_me/data/repositories/repositories.dart';
class JobsController extends ChangeNotifier {
JobsController({required JobRepository jobs}) : _jobs = jobs;
final JobRepository _jobs;
AsyncValue<List<Job>> _state = const AsyncValue.loading();
bool _mutating = false;
AsyncValue<List<Job>> get state => _state;
bool get isMutating => _mutating;
List<Job> get items => _state.valueOrNull ?? const [];
/// Nearest payday across all jobs — shown on the overview screen.
UpcomingPay? get nextPay {
final pays = items.expand((job) => job.nextPays).toList()
..sort((a, b) => a.date.compareTo(b.date));
return pays.isEmpty ? null : pays.first;
}
Future<void> load({bool silent = false}) async {
if (!silent) {
_state = const AsyncValue.loading();
notifyListeners();
}
try {
_state = AsyncValue.data(await _jobs.list());
} on ApiException catch (error) {
_state = AsyncValue.error(error.message);
}
notifyListeners();
}
Future<String?> create({
required String name,
required double salaryAmount,
required List<int> payDays,
required double firstPayPercent,
required WeekendPolicy weekendPolicy,
}) {
return _mutate(
() => _jobs.create(
name: name,
salaryAmount: salaryAmount,
payDays: payDays,
firstPayPercent: firstPayPercent,
weekendPolicy: weekendPolicy,
),
);
}
Future<String?> update({
required int jobId,
required String name,
required double salaryAmount,
required List<int> payDays,
required double firstPayPercent,
required WeekendPolicy weekendPolicy,
}) {
return _mutate(
() => _jobs.update(
jobId: jobId,
name: name,
salaryAmount: salaryAmount,
payDays: payDays,
firstPayPercent: firstPayPercent,
weekendPolicy: weekendPolicy,
),
);
}
Future<String?> delete(int jobId) => _mutate(() => _jobs.delete(jobId));
Future<String?> _mutate(Future<void> Function() action) async {
_mutating = true;
notifyListeners();
try {
await action();
await load(silent: true);
return null;
} on ApiException catch (error) {
return error.message;
} finally {
_mutating = false;
notifyListeners();
}
}
}