focus-flow/apps/focus_flow_flutter/lib/widgets/today_pane.dart

73 lines
2.2 KiB
Dart

/// Renders the Today Pane widget for the FocusFlow Flutter UI.
library;
import 'package:flutter/material.dart';
import 'package:scheduler_core/scheduler_core.dart';
import '../controllers/scheduler_command_controller.dart';
import '../controllers/scheduler_read_controller.dart';
import 'read_state_view.dart';
import 'schedule_components.dart';
class TodayPane extends StatelessWidget {
const TodayPane({
required this.controller,
this.commandController,
super.key,
});
final UiReadController<TodayState> controller;
final SchedulerCommandController? commandController;
@override
Widget build(BuildContext context) {
return ReadStateView<TodayState>(
controller: controller,
title: 'Today',
emptyTitle: 'Today is clear',
emptyMessage: 'No scheduled work is waiting in this view.',
dataBuilder: (context, state) =>
TodayContent(state: state, commandController: commandController),
);
}
}
class TodayContent extends StatelessWidget {
const TodayContent({required this.state, this.commandController, super.key});
final TodayState state;
final SchedulerCommandController? commandController;
@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.all(16),
children: [
Text('Today', style: Theme.of(context).textTheme.headlineMedium),
const SizedBox(height: 12),
for (final notice in state.pendingNotices)
NoticeBanner(message: notice.message),
CompactPanel(items: state.compactState.compactItems),
Text('Timeline', style: Theme.of(context).textTheme.titleMedium),
const SizedBox(height: 8),
for (final item in state.timelineItems)
TimelineRow(
item: item,
onDone: _canComplete(item) && commandController != null
? () {
return commandController!.completeFlexibleTask(
taskId: item.taskId!,
);
}
: null,
),
],
);
}
bool _canComplete(TodayTimelineItem item) {
return item.taskType == TaskType.flexible &&
item.taskStatus == TaskStatus.planned &&
item.taskId != null;
}
}