fix: apply review feedback — type safety, overdue logic, dead code
- _EmptyState: accept PetType enum directly; use .emoji getter (drops string conversion round-trip and duplicate emoji mapping) - TaskCard: compute _isOverdue from task.deadline when task is provided (previously isOverdue never fired when using the task: param) - userNameProvider: derive from userProvider.name instead of hardcoded 'Zuf' (name was split across two independent providers) - _petMessage: add explicit 'neutral' branch, remove unreachable 'sleepy' branch (PetMood enum has no .sleepy; neutral was silently falling to _) - EnergyBar/EnergyBadge: assert both params not null simultaneously (EnergyBar() / EnergyBadge() previously compiled silently with default low) - todayTasksProvider: fix comment — no date filtering in MVP Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,8 @@ class TasksNotifier extends Notifier<List<TaskEntity>> {
|
||||
final tasksProvider =
|
||||
NotifierProvider<TasksNotifier, List<TaskEntity>>(TasksNotifier.new);
|
||||
|
||||
/// Alias — today's tasks (same provider, filtered by status in screens).
|
||||
/// Alias for [tasksProvider]. Returns all tasks — no date filtering in MVP.
|
||||
/// Screens are responsible for splitting into pending/completed.
|
||||
final todayTasksProvider = tasksProvider;
|
||||
|
||||
/// Pending tasks only, ordered by sort order.
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
/// Provider for current user name.
|
||||
final userNameProvider = Provider<String>((ref) => 'Zuf');
|
||||
import 'pet_providers.dart';
|
||||
|
||||
/// Derived provider for the current user's display name.
|
||||
final userNameProvider = Provider<String>((ref) => ref.watch(userProvider).name);
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import '../../../core/router/routes.dart';
|
||||
import '../../../core/theme/kittie_colors.dart';
|
||||
import '../../../domain/entities/pet_type.dart';
|
||||
import '../../../shared/utils/czech_date.dart';
|
||||
import '../../../shared/widgets/energy_bar.dart';
|
||||
import '../../../shared/widgets/pet_bubble.dart';
|
||||
@@ -34,7 +35,7 @@ class TasksScreen extends ConsumerWidget {
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: tasks.isEmpty
|
||||
? _EmptyState(petType: userState.petType.name)
|
||||
? _EmptyState(petType: userState.petType)
|
||||
: SingleChildScrollView(
|
||||
padding: const EdgeInsets.fromLTRB(20, 16, 20, 100),
|
||||
child: Column(
|
||||
@@ -157,26 +158,21 @@ class TasksScreen extends ConsumerWidget {
|
||||
static String _petMessage(String mood, String petName) {
|
||||
return switch (mood) {
|
||||
'happy' => '$petName je stastna! Jde ti to skvele \u{1F44F}',
|
||||
'neutral' => '$petName te ceka! Co dnes zvladneme? \u{2728}',
|
||||
'sad' => '$petName te podporuje. Zkus jeden ukol \u{1F495}',
|
||||
'sleepy' => '$petName odpociva... Klid je taky dulezity \u{1F4A4}',
|
||||
_ => '$petName te ceka! Co dnes zvladneme? \u{2728}',
|
||||
_ => '$petName je tady pro tebe \u{1F60A}',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class _EmptyState extends StatelessWidget {
|
||||
final String petType;
|
||||
final PetType petType;
|
||||
|
||||
const _EmptyState({required this.petType});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final emoji = switch (petType) {
|
||||
'dog' => '\u{1F436}',
|
||||
'cat' => '\u{1F431}',
|
||||
'capybara' => '\u{1F9AB}',
|
||||
_ => '\u{1F431}',
|
||||
};
|
||||
final emoji = petType.emoji;
|
||||
|
||||
return Center(
|
||||
child: Column(
|
||||
|
||||
@@ -27,7 +27,9 @@ enum EnergyLevel {
|
||||
/// - medium: orange bg, orange text, sun icon — "Stredni"
|
||||
/// - high: red bg, red text, fire icon — "Narocne"
|
||||
class EnergyBadge extends StatelessWidget {
|
||||
const EnergyBadge({super.key, this.level, this.energyLevel});
|
||||
const EnergyBadge({super.key, this.level, this.energyLevel})
|
||||
: assert(level != null || energyLevel != null,
|
||||
'Provide either level or energyLevel');
|
||||
|
||||
final EnergyLevel? level;
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ class EnergyBar extends StatelessWidget {
|
||||
this.fraction,
|
||||
this.energyLevel,
|
||||
this.label = 'ENERGIE',
|
||||
});
|
||||
}) : assert(fraction != null || energyLevel != null,
|
||||
'Provide either fraction or energyLevel');
|
||||
|
||||
/// Fill amount from 0.0 (empty) to 1.0 (full).
|
||||
final double? fraction;
|
||||
|
||||
@@ -47,6 +47,10 @@ class TaskCard extends StatelessWidget {
|
||||
int get _energyLevel => task?.energyLevel ?? energyLevel ?? 2;
|
||||
bool get _isDone => task?.isCompleted ?? isDone;
|
||||
bool get _isSelfCare => task?.isSelfCare ?? isSelfCare;
|
||||
bool get _isOverdue {
|
||||
if (task?.deadline != null) return task!.deadline!.isBefore(DateTime.now());
|
||||
return isOverdue;
|
||||
}
|
||||
VoidCallback? get _toggleCallback => onComplete ?? onToggle;
|
||||
|
||||
@override
|
||||
@@ -57,7 +61,7 @@ class TaskCard extends StatelessWidget {
|
||||
constraints: const BoxConstraints(minHeight: AppConstants.minTouchTarget),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: isOverdue
|
||||
color: _isOverdue
|
||||
? KittieColors.redLight
|
||||
: KittieColors.creamDark,
|
||||
borderRadius: BorderRadius.circular(AppConstants.cardBorderRadius),
|
||||
|
||||
Reference in New Issue
Block a user