import 'package:flutter/cupertino.dart'; import 'package:please_pay_me/core/format/formatters.dart'; import 'package:please_pay_me/data/models/job.dart'; import 'package:please_pay_me/features/work/job_form_sheet.dart'; import 'package:please_pay_me/features/work/jobs_controller.dart'; import 'package:please_pay_me/theme/theme.dart'; import 'package:please_pay_me/ui/ui.dart'; import 'package:provider/provider.dart'; /// Jobs and their payday schedule. class WorkScreen extends StatelessWidget { const WorkScreen({super.key}); @override Widget build(BuildContext context) { final controller = context.watch(); return CupertinoPageScaffold( backgroundColor: AppColors.of(context, AppColors.groupedBackground), child: CustomScrollView( physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()), slivers: [ AppLargeNavBar( title: 'Работа', trailing: CupertinoButton( padding: EdgeInsets.zero, minimumSize: Size.zero, onPressed: () => showJobFormSheet(context: context, controller: controller), child: const AppIcon(CupertinoIcons.add_circled, color: AppColors.accent), ), ), CupertinoSliverRefreshControl(onRefresh: () => controller.load(silent: true)), SliverToBoxAdapter( child: controller.state.map( loading: () => AppListSection( children: List.generate(2, (_) => const AppSkeletonRow()), ), error: (message) => AppErrorView(message: message, onRetry: controller.load), data: (jobs) => jobs.isEmpty ? AppEmptyState( icon: CupertinoIcons.briefcase, title: 'Работа не добавлена', message: 'Укажите оклад и дни выплат — приложение подскажет даты зарплаты.', actionLabel: 'Добавить работу', onAction: () => showJobFormSheet(context: context, controller: controller), ) : Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ for (final job in jobs) ...[ _JobCard(job: job, controller: controller), const SizedBox(height: AppSpacing.s5), ], ], ), ), ), const SliverToBoxAdapter(child: SizedBox(height: AppSpacing.s7)), ], ), ); } } class _JobCard extends StatelessWidget { const _JobCard({required this.job, required this.controller}); final Job job; final JobsController controller; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ AppListSection( header: job.name, separatorIndent: 60, children: [ AppListTile( leading: const AppIconBadge( icon: CupertinoIcons.briefcase_fill, color: AppColors.accent, ), title: 'Оклад', value: formatMoney(job.salaryAmount, currency: job.currency), showChevron: false, ), AppListTile( leading: const AppIconBadge( icon: CupertinoIcons.calendar, color: AppColors.systemOrange, ), title: 'Дни выплат', value: job.payDays.map((day) => '$day').join(' и '), showChevron: false, ), AppListTile( leading: const AppIconBadge( icon: CupertinoIcons.arrow_left_right, color: AppColors.systemGray, ), title: 'Выходные', value: job.weekendPolicy.label, showChevron: false, ), AppListTile( title: 'Настроить', onTap: () => _openActions(context), ), ], ), if (job.nextPays.isNotEmpty) ...[ const SizedBox(height: AppSpacing.s4), AppListSection( header: 'Ближайшие выплаты', children: [ for (final pay in job.nextPays) AppListTile( title: formatDay(pay.date), subtitle: '${pay.percent.round()}% оклада · ${pay.scheduledDay} числа', value: formatMoney(pay.amount, currency: job.currency), showChevron: false, ), ], ), ], ], ); } Future _openActions(BuildContext context) async { final index = await showAppActionSheet( context: context, title: job.name, actions: const [ AppActionSheetAction(label: 'Редактировать', isDefault: true), AppActionSheetAction(label: 'Удалить', destructive: true), ], ); if (index == null || !context.mounted) return; if (index == 0) { await showJobFormSheet(context: context, controller: controller, initial: job); return; } final confirmed = await showAppAlert( context: context, title: 'Удалить «${job.name}»?', message: 'График выплат тоже будет удалён.', confirmLabel: 'Удалить', cancelLabel: 'Отмена', destructive: true, ); if (confirmed != true) return; final error = await controller.delete(job.id); if (context.mounted) { await showAppToast(context, message: error ?? 'Работа удалена'); } } }