feat: Complete Flutter app structure for LifeFlow

ADDED:
- analysis_options.yaml (Flutter linting rules)
- .gitignore (Flutter-specific)
- All missing screen files:
  - routines/routines_screen.dart
  - calendar/calendar_screen.dart
  - stats/stats_screen.dart
  - settings/settings_screen.dart
- RoutineCard widget with category colors
- Models barrel export (models.dart)
- Fixed AppTheme (removed duplicate class)

APP STRUCTURE:
├── lib/
│   ├── main.dart (entry point with navigation)
│   ├── models/ (Routine, Activity, Gamification)
│   ├── repositories/ (RoutineRepository with Riverpod)
│   ├── screens/ (Dashboard, Routines, Calendar, Stats, Settings)
│   └── theme/ (AppTheme, AppColors)
│
FEATURES READY:
- Bottom navigation (5 tabs)
- Dashboard with progress ring
- Routine cards with category icons
- Settings screen with options
- Light/Dark theme support
- Riverpod state management setup

NOTE: This is a skeleton app that compiles but needs:
- Hive initialization
- Actual data persistence
- Notification setup
- More screen implementations

To build APK, run: flutter build apk --release
This commit is contained in:
LemonNexus 2026-02-14 12:49:20 +00:00
parent 545e092d3b
commit a21873ebc3
9 changed files with 349 additions and 40 deletions

44
.gitignore vendored Normal file
View File

@ -0,0 +1,44 @@
# Flutter/Dart
.dart_tool/
.packages
build/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/android/app/debug
/android/app/profile
/android/app/release
/android/key.properties
/ios/Flutter/.last_build_id
/ios/Pods/
/macos/Flutter/ephemeral/
/windows/flutter/ephemeral/
/linux/flutter/ephemeral/
# IDE
.idea/
.vscode/
*.iml
*.ipr
*.iws
# OS
.DS_Store
Thumbs.db
# Secrets
*.jks
*.keystore
key.properties
local.properties
# Temporary files
*.log
*.tmp
*.swp
*~
# Test coverage
coverage/
.test_coverage.dart

10
analysis_options.yaml Normal file
View File

@ -0,0 +1,10 @@
include: package:flutter_lints/flutter.yaml
linter:
rules:
avoid_print: false
prefer_single_quotes: true
prefer_const_constructors: true
prefer_const_literals_to_create_immutables: true
avoid_unnecessary_containers: true
use_key_in_widget_constructors: true

View File

@ -0,0 +1,3 @@
export 'routine.dart';
export 'activity.dart';
export 'gamification.dart';

View File

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
class CalendarScreen extends StatelessWidget {
const CalendarScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Calendar'),
),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.calendar_today, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text(
'Calendar view coming soon',
style: TextStyle(fontSize: 18, color: Colors.grey),
),
],
),
),
);
}
}

View File

@ -0,0 +1,42 @@
import 'package:flutter/material.dart';
class RoutinesScreen extends StatelessWidget {
const RoutinesScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('My Routines'),
actions: [
IconButton(
icon: const Icon(Icons.filter_list),
onPressed: () {},
),
],
),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.checklist, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text(
'Your routines will appear here',
style: TextStyle(fontSize: 18, color: Colors.grey),
),
SizedBox(height: 8),
Text(
'Tap + to add your first routine',
style: TextStyle(color: Colors.grey),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
}
}

View File

@ -0,0 +1,133 @@
import 'package:flutter/material.dart';
import '../../models/routine.dart';
class RoutineCard extends StatelessWidget {
final Routine routine;
final VoidCallback? onTap;
final VoidCallback? onComplete;
const RoutineCard({
super.key,
required this.routine,
this.onTap,
this.onComplete,
});
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
// Icon
Container(
width: 56,
height: 56,
decoration: BoxDecoration(
color: _getCategoryColor().withOpacity(0.1),
borderRadius: BorderRadius.circular(16),
),
child: Center(
child: Text(
routine.category.icon,
style: const TextStyle(fontSize: 28),
),
),
),
const SizedBox(width: 16),
// Info
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
routine.name,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 4),
Text(
'${routine.schedule.time} · ${routine.category.displayName}',
style: TextStyle(
fontSize: 13,
color: Colors.grey[600],
),
),
if (routine.description != null && routine.description!.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
routine.description!,
style: TextStyle(
fontSize: 12,
color: Colors.grey[500],
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
// Complete button
if (onComplete != null)
IconButton(
onPressed: onComplete,
icon: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: _getCategoryColor().withOpacity(0.1),
shape: BoxShape.circle,
),
child: Icon(
Icons.check,
color: _getCategoryColor(),
),
),
),
],
),
),
),
);
}
Color _getCategoryColor() {
return routine.category.color;
}
}
// Extension for category colors
extension CategoryColor on RoutineCategory {
Color get color {
switch (this) {
case RoutineCategory.medication:
return const Color(0xFFE74C3C);
case RoutineCategory.vitamin:
return const Color(0xFFF39C12);
case RoutineCategory.appointment:
return const Color(0xFF9B59B6);
case RoutineCategory.sleep:
return const Color(0xFF8E44AD);
case RoutineCategory.food:
return const Color(0xFFE67E22);
case RoutineCategory.hydration:
return const Color(0xFF3498DB);
case RoutineCategory.exercise:
return const Color(0xFF27AE60);
case RoutineCategory.hygiene:
return const Color(0xFF1ABC9C);
case RoutineCategory.selfCare:
return const Color(0xFF16A085);
case RoutineCategory.custom:
return const Color(0xFF4A90E2);
}
}
}

View File

@ -0,0 +1,62 @@
import 'package:flutter/material.dart';
class SettingsScreen extends StatelessWidget {
const SettingsScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Settings'),
),
body: ListView(
children: [
ListTile(
leading: const Icon(Icons.person),
title: const Text('Account'),
trailing: const Icon(Icons.chevron_right),
onTap: () {},
),
ListTile(
leading: const Icon(Icons.notifications),
title: const Text('Notifications'),
trailing: const Icon(Icons.chevron_right),
onTap: () {},
),
ListTile(
leading: const Icon(Icons.palette),
title: const Text('Appearance'),
trailing: const Icon(Icons.chevron_right),
onTap: () {},
),
const Divider(),
ListTile(
leading: const Icon(Icons.backup),
title: const Text('Backup & Sync'),
trailing: const Icon(Icons.chevron_right),
onTap: () {},
),
ListTile(
leading: const Icon(Icons.privacy_tip),
title: const Text('Privacy'),
trailing: const Icon(Icons.chevron_right),
onTap: () {},
),
const Divider(),
ListTile(
leading: const Icon(Icons.help),
title: const Text('Help & Support'),
trailing: const Icon(Icons.chevron_right),
onTap: () {},
),
ListTile(
leading: const Icon(Icons.info),
title: const Text('About'),
trailing: const Icon(Icons.chevron_right),
onTap: () {},
),
],
),
);
}
}

View File

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
class StatsScreen extends StatelessWidget {
const StatsScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Statistics'),
),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.insights, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text(
'Your stats will appear here',
style: TextStyle(fontSize: 18, color: Colors.grey),
),
],
),
),
);
}
}

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AppTheme { class AppColors {
// Primary Colors // Primary Colors
static const Color primary = Color(0xFF4A90E2); static const Color primary = Color(0xFF4A90E2);
static const Color primaryLight = Color(0xFF7BB3F0); static const Color primaryLight = Color(0xFF7BB3F0);
@ -27,45 +27,6 @@ class AppTheme {
static const Color warning = Color(0xFFF39C12); static const Color warning = Color(0xFFF39C12);
static const Color error = Color(0xFFE74C3C); static const Color error = Color(0xFFE74C3C);
static const Color info = Color(0xFF3498DB); static const Color info = Color(0xFF3498DB);
static Color getCategoryColor(RoutineCategory category) {
switch (category) {
case RoutineCategory.medication:
return medication;
case RoutineCategory.vitamin:
return vitamin;
case RoutineCategory.appointment:
return appointment;
case RoutineCategory.sleep:
return sleep;
case RoutineCategory.food:
return food;
case RoutineCategory.hydration:
return hydration;
case RoutineCategory.exercise:
return exercise;
case RoutineCategory.hygiene:
return hygiene;
case RoutineCategory.selfCare:
return selfCare;
case RoutineCategory.custom:
return primary;
}
}
}
// Temporary enum for compilation
enum RoutineCategory {
medication,
vitamin,
appointment,
sleep,
food,
hydration,
exercise,
hygiene,
selfCare,
custom,
} }
class AppTheme { class AppTheme {