Files
GroundedHelper/frontend/lib/Grounded/designs/GoalPicker.dart
alvocool 9c858b8146 Square every corner, enlarge the main surfaces and add a to-do list
Rounded rectangles and round controls are now square across the app; only
status dots, glows, the sun, rings and the breathing circle stay round.
Cards, rows, thumbnails, featured cards, category tiles, the standing card
and the nav are larger. Home gets a quick To-do list kept on the device
(TodoItem in InternalMemory), seeded with sample items in mock mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KhQh614DMeYoQEH9SoMRUw
2026-11-02 14:50:31 +03:00

128 lines
4.0 KiB
Dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../about/external/data/Goal.dart';
import '../about/internal/application/TextType.dart';
import '../utils/Colors.dart';
import '../utils/CommonUtils.dart';
import 'text/Text.dart';
/// The goal chooser, shared by the task form and the routine builder. Opened
/// only once the goals have been loaded — `selectField` loads on tap.
///
/// Resolves to the chosen goal, to a bare `Goal()` (no id) for "no goal", or
/// to null when dismissed without a choice.
Future<Goal?> showGoalPicker(
BuildContext context,
List<Goal> goals, {
String? selectedId,
}) {
return showModalBottomSheet<Goal>(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
barrierColor: colorBlack.withValues(alpha: 0.55),
builder: (BuildContext sheetContext) {
final List<Goal> active = goals.where((goal) => !goal.archived).toList();
return Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(sheetContext).size.height * 0.75,
),
decoration: const BoxDecoration(
color: colorSheetBackground,
borderRadius: BorderRadius.only(
topLeft: Radius.zero,
topRight: Radius.zero,
),
),
child: ListView(
shrinkWrap: true,
padding: const EdgeInsets.fromLTRB(24, 24, 24, 32),
children: [
text("BELONGS TO", 9, TextType.Bold,
color: colorGrey2, letterSpacing: 1.2),
const SizedBox(height: 8),
text("Which goal is this for?", 24, TextType.Light,
color: colorPrimaryDark),
const SizedBox(height: 18),
_goalOption(
sheetContext,
Goal(),
"No goal",
"Stands on its own",
colorGrey,
selectedId == null,
),
...active.map((goal) => _goalOption(
sheetContext,
goal,
goal.title,
goal.targetDate == null
? "${goal.remainingTasks} open"
: "${goal.remainingTasks} open · ${targetLabel(goal.targetDate)}",
goalColor(goal.colourHex),
goal.id == selectedId,
)),
if (active.isEmpty) ...[
const SizedBox(height: 8),
text("No goals yet. Create one from the Goals screen.", 12,
TextType.Regular,
color: colorGrey2),
],
],
),
);
},
);
}
Widget _goalOption(
BuildContext sheetContext,
Goal goal,
String title,
String caption,
Color accent,
bool selected,
) {
return GestureDetector(
onTap: () => Navigator.pop(sheetContext, goal),
behavior: HitTestBehavior.opaque,
child: Container(
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.fromLTRB(14, 13, 14, 13),
decoration: BoxDecoration(
color: colorWhite,
borderRadius: BorderRadius.zero,
border: Border.all(
color: selected ? accent.withValues(alpha: 0.5) : colorBorder,
width: selected ? 1.5 : 1,
),
),
child: Row(
children: [
Container(
width: 12,
height: 12,
decoration: BoxDecoration(color: accent, shape: BoxShape.circle),
),
const SizedBox(width: 14),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
text(title, 14, TextType.Medium, color: colorPrimaryDark),
const SizedBox(height: 3),
text(caption, 11, TextType.Regular, color: colorGrey2),
],
),
),
if (selected)
Icon(CupertinoIcons.checkmark_alt, size: 17, color: accent),
],
),
),
);
}