diff --git a/README.md b/README.md
index 97b379c..663d271 100644
--- a/README.md
+++ b/README.md
@@ -1,90 +1,46 @@
-
+# Bodybuilding Trainer and Nutrition App
-# Code with GitHub Copilot
-
-_GitHub Copilot can help you code by offering autocomplete-style suggestions right in VS Code and Codespaces._
+_Enhance and expand a Bodybuilding Trainer and Nutrition App with advanced features and functionality tailored for a professional bodybuilder._
-
-
-## Step 1: Leverage Codespaces with VS Code for Copilot
-
-_Welcome to "Develop With AI Powered Code Suggestions Using GitHub Copilot and VS Code"! :wave:_
-
-GitHub Copilot is an AI pair programmer that helps you write code faster and with less work. It draws context from comments and code to suggest individual lines and whole functions instantly. GitHub Copilot is powered by OpenAI Codex, a generative pretrained language model created by OpenAI.
+## App Overview
-**Copilot works with many code editors including VS Code, Visual Studio, JetBrains IDE, and Neovim.**
+The Bodybuilding Trainer and Nutrition App is designed to provide professional bodybuilders with a comprehensive tool for managing their training schedules, nutrition plans, hormone tracking, and progress tracking. The app includes core features such as training schedules, nutrition and diet plans, hormone tracking system, body stats tracking, recurring notifications, and progress photos. It also offers advanced features for trainers to manage multiple clients, personalized schedules, and detailed tracking of stats and progress.
-Additionally, GitHub Copilot is trained on all languages that appear in public repositories. For each language, the quality of suggestions you receive may depend on the volume and diversity of training data for that language.
+## Folder Structure
-Using Copilot inside a Codespace shows just how easy it is to get up and running with GitHub's suite of [Collaborative Coding](https://github.com/features#features-collaboration) tools.
+The app follows a modular folder structure to ensure clean and maintainable code. The main folders are:
-> **Note**
-> This skills exercise will focus on leveraging GitHub Codespace. It is recommended that you complete the GitHub skill, [Codespaces](https://github.com/skills/code-with-codespaces), before moving forward with this exercise.
+- `lib/screens`: Contains screens like dashboards, profiles, and tracking.
+- `lib/widgets`: Contains reusable UI components (e.g., cards, graphs).
+- `lib/models`: Contains data models (e.g., hormones, user profiles).
+- `lib/services`: Contains backend integrations and logic.
+- `lib/database`: Contains SQLite database integration.
-### :keyboard: Activity: Enable Copilot inside a Codespace
+## Setup Instructions
-**We recommend opening another browser tab to work through the following activities so you can keep these instructions open for reference.**
-
-Before you open up a codespace on a repository, you can create a development container and define specific extensions or configurations that will be used or installed in your codespace. Let's create this development container and add copilot to the list of extensions.
-
-1. Navigating back to your **Code** tab of your repository, click the **Add file** drop-down button, and then click `Create new file`.
-1. Type or paste the following in the empty text field prompt to name your file.
+1. Clone the repository:
```
- .devcontainer/devcontainer.json
+ git clone https://github.com/sakura-source/Werdany.git
```
-1. In the body of the new **.devcontainer/devcontainer.json** file, add the following content:
+2. Navigate to the project directory:
```
- {
- // Name this configuration
- "name": "Codespace for Skills!",
- "customizations": {
- "vscode": {
- "extensions": [
- "GitHub.copilot"
- ]
- }
- }
- }
+ cd Werdany
+ ```
+3. Install dependencies:
+ ```
+ flutter pub get
+ ```
+4. Run the app:
+ ```
+ flutter run
```
-1. Select the option to **Commit directly to the `main` branch**, and then click the **Commit new file** button.
-1. Navigate back to the home page of your repository by clicking the **Code** tab located at the top left of the screen.
-1. Click the **Code** button located in the middle of the page.
-1. Click the **Codespaces** tab on the box that pops up.
-1. Click the **Create codespace on main** button.
-
- **Wait about 2 minutes for the codespace to spin itself up.**
-
-1. Verify your codespace is running. The browser should contain a VS Code web-based editor and a terminal should be present such as the below:
- 
-1. The `copilot` extension should show up in the VS Code extension list. Click the extensions sidebar tab. You should see the following:
- 
-
-**Wait about 60 seconds then refresh your repository landing page for the next step.**
-
-
---
Get help: [Post in our discussion board](https://github.com/orgs/skills/discussions/categories/code-with-copilot) • [Review the GitHub status page](https://www.githubstatus.com/)
diff --git a/lib/database/database_helper.dart b/lib/database/database_helper.dart
new file mode 100644
index 0000000..c131589
--- /dev/null
+++ b/lib/database/database_helper.dart
@@ -0,0 +1,99 @@
+import 'package:sqflite/sqflite.dart';
+import 'package:path/path.dart';
+
+class DatabaseHelper {
+ static final DatabaseHelper _instance = DatabaseHelper._internal();
+ factory DatabaseHelper() => _instance;
+ DatabaseHelper._internal();
+
+ Database? _database;
+
+ Future get database async {
+ if (_database != null) return _database!;
+ _database = await _initDatabase();
+ return _database!;
+ }
+
+ Future _initDatabase() async {
+ String path = join(await getDatabasesPath(), 'app_database.db');
+ return await openDatabase(
+ path,
+ version: 1,
+ onCreate: (db, version) async {
+ await db.execute('''
+ CREATE TABLE body_stats (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ weight REAL,
+ muscleMass REAL,
+ fatPercentage REAL
+ )
+ ''');
+ await db.execute('''
+ CREATE TABLE hormones (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT,
+ dosage REAL,
+ schedule TEXT,
+ purpose TEXT
+ )
+ ''');
+ await db.execute('''
+ CREATE TABLE diet_plans (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ calories INTEGER,
+ protein INTEGER,
+ carbs INTEGER,
+ fats INTEGER
+ )
+ ''');
+ await db.execute('''
+ CREATE TABLE progress_photos (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ photoPath TEXT,
+ date TEXT
+ )
+ ''');
+ await db.execute('''
+ CREATE TABLE trainer_profiles (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT,
+ clients TEXT
+ )
+ ''');
+ },
+ );
+ }
+
+ Future insert(String table, Map data) async {
+ final db = await database;
+ await db.insert(
+ table,
+ data,
+ conflictAlgorithm: ConflictAlgorithm.replace,
+ );
+ }
+
+ Future update(String table, Map data, String where, List whereArgs) async {
+ final db = await database;
+ await db.update(
+ table,
+ data,
+ where: where,
+ whereArgs: whereArgs,
+ );
+ }
+
+ Future delete(String table, String where, List whereArgs) async {
+ final db = await database;
+ await db.delete(
+ table,
+ where: where,
+ whereArgs: whereArgs,
+ );
+ }
+
+ Future>> query(String table) async {
+ final db = await database;
+ return await db.query(table);
+ }
+}
diff --git a/lib/models/body_stats.dart b/lib/models/body_stats.dart
new file mode 100644
index 0000000..2cfb2b3
--- /dev/null
+++ b/lib/models/body_stats.dart
@@ -0,0 +1,23 @@
+class BodyStats {
+ double weight;
+ double muscleMass;
+ double fatPercentage;
+
+ BodyStats({required this.weight, required this.muscleMass, required this.fatPercentage});
+
+ factory BodyStats.fromJson(Map json) {
+ return BodyStats(
+ weight: json['weight'],
+ muscleMass: json['muscleMass'],
+ fatPercentage: json['fatPercentage'],
+ );
+ }
+
+ Map toJson() {
+ return {
+ 'weight': weight,
+ 'muscleMass': muscleMass,
+ 'fatPercentage': fatPercentage,
+ };
+ }
+}
diff --git a/lib/models/diet_plan.dart b/lib/models/diet_plan.dart
new file mode 100644
index 0000000..8070da9
--- /dev/null
+++ b/lib/models/diet_plan.dart
@@ -0,0 +1,35 @@
+class DietPlan {
+ int id;
+ int calories;
+ int protein;
+ int carbs;
+ int fats;
+
+ DietPlan({
+ required this.id,
+ required this.calories,
+ required this.protein,
+ required this.carbs,
+ required this.fats,
+ });
+
+ factory DietPlan.fromJson(Map json) {
+ return DietPlan(
+ id: json['id'],
+ calories: json['calories'],
+ protein: json['protein'],
+ carbs: json['carbs'],
+ fats: json['fats'],
+ );
+ }
+
+ Map toJson() {
+ return {
+ 'id': id,
+ 'calories': calories,
+ 'protein': protein,
+ 'carbs': carbs,
+ 'fats': fats,
+ };
+ }
+}
diff --git a/lib/models/hormone.dart b/lib/models/hormone.dart
new file mode 100644
index 0000000..a425956
--- /dev/null
+++ b/lib/models/hormone.dart
@@ -0,0 +1,35 @@
+class Hormone {
+ int id;
+ String name;
+ double dosage;
+ String schedule;
+ String purpose;
+
+ Hormone({
+ required this.id,
+ required this.name,
+ required this.dosage,
+ required this.schedule,
+ required this.purpose,
+ });
+
+ factory Hormone.fromJson(Map json) {
+ return Hormone(
+ id: json['id'],
+ name: json['name'],
+ dosage: json['dosage'],
+ schedule: json['schedule'],
+ purpose: json['purpose'],
+ );
+ }
+
+ Map toJson() {
+ return {
+ 'id': id,
+ 'name': name,
+ 'dosage': dosage,
+ 'schedule': schedule,
+ 'purpose': purpose,
+ };
+ }
+}
diff --git a/lib/models/trainer_profile.dart b/lib/models/trainer_profile.dart
new file mode 100644
index 0000000..2d5ae1d
--- /dev/null
+++ b/lib/models/trainer_profile.dart
@@ -0,0 +1,107 @@
+class TrainerProfile {
+ int id;
+ String name;
+ String email;
+ List clients;
+
+ TrainerProfile({
+ required this.id,
+ required this.name,
+ required this.email,
+ required this.clients,
+ });
+
+ factory TrainerProfile.fromJson(Map json) {
+ return TrainerProfile(
+ id: json['id'],
+ name: json['name'],
+ email: json['email'],
+ clients: List.from(json['clients'].map((client) => Client.fromJson(client))),
+ );
+ }
+
+ Map toJson() {
+ return {
+ 'id': id,
+ 'name': name,
+ 'email': email,
+ 'clients': clients.map((client) => client.toJson()).toList(),
+ };
+ }
+}
+
+class Client {
+ int id;
+ String name;
+ String email;
+ String phone;
+ String address;
+ List schedules;
+
+ Client({
+ required this.id,
+ required this.name,
+ required this.email,
+ required this.phone,
+ required this.address,
+ required this.schedules,
+ });
+
+ factory Client.fromJson(Map json) {
+ return Client(
+ id: json['id'],
+ name: json['name'],
+ email: json['email'],
+ phone: json['phone'],
+ address: json['address'],
+ schedules: List.from(json['schedules'].map((schedule) => Schedule.fromJson(schedule))),
+ );
+ }
+
+ Map toJson() {
+ return {
+ 'id': id,
+ 'name': name,
+ 'email': email,
+ 'phone': phone,
+ 'address': address,
+ 'schedules': schedules.map((schedule) => schedule.toJson()).toList(),
+ };
+ }
+}
+
+class Schedule {
+ int id;
+ String name;
+ String description;
+ DateTime startDate;
+ DateTime endDate;
+
+ Schedule({
+ required this.id,
+ required this.name,
+ required this.description,
+ required this.startDate,
+ required this.endDate,
+ });
+
+ factory Schedule.fromJson(Map json) {
+ return Schedule(
+ id: json['id'],
+ name: json['name'],
+ description: json['description'],
+ startDate: DateTime.parse(json['startDate']),
+ endDate: DateTime.parse(json['endDate']),
+ );
+ }
+
+ Map toJson() {
+ return {
+ 'id': id,
+ 'name': name,
+ 'description': description,
+ 'startDate': startDate.toIso8601String(),
+ 'endDate': endDate.toIso8601String(),
+ };
+ }
+}
diff --git a/lib/screens/about_screen.dart b/lib/screens/about_screen.dart
new file mode 100644
index 0000000..766ad91
--- /dev/null
+++ b/lib/screens/about_screen.dart
@@ -0,0 +1,58 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class AboutScreen extends StatelessWidget {
+ final HormoneTrackerService hormoneTrackerService = HormoneTrackerService();
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('About'),
+ ),
+ body: FutureBuilder>(
+ future: hormoneTrackerService.getAboutData(),
+ builder: (context, snapshot) {
+ if (snapshot.connectionState == ConnectionState.waiting) {
+ return Center(child: CircularProgressIndicator());
+ } else if (snapshot.hasError) {
+ return Center(child: Text('Error: ${snapshot.error}'));
+ } else {
+ final aboutData = snapshot.data!;
+ return Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ aboutData['appName'],
+ style: TextStyle(
+ fontSize: 24,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 16),
+ Text(aboutData['description']),
+ SizedBox(height: 16),
+ Text(
+ 'Developers:',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ...aboutData['developers'].map((developer) {
+ return ListTile(
+ title: Text(developer['name']),
+ subtitle: Text(developer['email']),
+ );
+ }).toList(),
+ ],
+ ),
+ );
+ }
+ },
+ ),
+ );
+ }
+}
diff --git a/lib/screens/ai_recommendations_screen.dart b/lib/screens/ai_recommendations_screen.dart
new file mode 100644
index 0000000..d4b3688
--- /dev/null
+++ b/lib/screens/ai_recommendations_screen.dart
@@ -0,0 +1,69 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class AIRecommendationsScreen extends StatefulWidget {
+ @override
+ _AIRecommendationsScreenState createState() => _AIRecommendationsScreenState();
+}
+
+class _AIRecommendationsScreenState extends State {
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+ List> _recommendations = [];
+
+ @override
+ void initState() {
+ super.initState();
+ _loadRecommendations();
+ }
+
+ Future _loadRecommendations() async {
+ final recommendations = await _hormoneTrackerService.getAIRecommendations();
+ setState(() {
+ _recommendations = recommendations;
+ });
+ }
+
+ void _acceptRecommendation(int id) async {
+ await _hormoneTrackerService.acceptAIRecommendation(id);
+ _loadRecommendations();
+ }
+
+ void _rejectRecommendation(int id) async {
+ await _hormoneTrackerService.rejectAIRecommendation(id);
+ _loadRecommendations();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('AI Recommendations'),
+ ),
+ body: ListView.builder(
+ itemCount: _recommendations.length,
+ itemBuilder: (context, index) {
+ final recommendation = _recommendations[index];
+ return Card(
+ child: ListTile(
+ title: Text(recommendation['title']),
+ subtitle: Text(recommendation['description']),
+ trailing: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ IconButton(
+ icon: Icon(Icons.check),
+ onPressed: () => _acceptRecommendation(recommendation['id']),
+ ),
+ IconButton(
+ icon: Icon(Icons.close),
+ onPressed: () => _rejectRecommendation(recommendation['id']),
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/lib/screens/body_stats_screen.dart b/lib/screens/body_stats_screen.dart
new file mode 100644
index 0000000..9faa525
--- /dev/null
+++ b/lib/screens/body_stats_screen.dart
@@ -0,0 +1,184 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/body_stats_service.dart';
+import 'package:your_app/models/body_stats.dart';
+import 'package:your_app/widgets/body_stat_chart.dart';
+import 'package:your_app/widgets/body_stats_card.dart';
+
+class BodyStatsScreen extends StatefulWidget {
+ @override
+ _BodyStatsScreenState createState() => _BodyStatsScreenState();
+}
+
+class _BodyStatsScreenState extends State {
+ List _bodyStats = [];
+ final BodyStatsService _bodyStatsService = BodyStatsService();
+
+ @override
+ void initState() {
+ super.initState();
+ _loadBodyStats();
+ }
+
+ Future _loadBodyStats() async {
+ final stats = await _bodyStatsService.getBodyStats();
+ setState(() {
+ _bodyStats = stats;
+ });
+ }
+
+ void _addBodyStat(BodyStats stat) async {
+ await _bodyStatsService.addBodyStat(stat);
+ _loadBodyStats();
+ }
+
+ void _editBodyStat(BodyStats stat) async {
+ await _bodyStatsService.updateBodyStat(stat);
+ _loadBodyStats();
+ }
+
+ void _deleteBodyStat(int id) async {
+ await _bodyStatsService.deleteBodyStat(id);
+ _loadBodyStats();
+ }
+
+ void _showAddBodyStatDialog() {
+ final weightController = TextEditingController();
+ final muscleMassController = TextEditingController();
+ final fatPercentageController = TextEditingController();
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Add Body Stat'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: weightController,
+ decoration: InputDecoration(labelText: 'Weight'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: muscleMassController,
+ decoration: InputDecoration(labelText: 'Muscle Mass'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: fatPercentageController,
+ decoration: InputDecoration(labelText: 'Fat Percentage'),
+ keyboardType: TextInputType.number,
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _addBodyStat(
+ BodyStats(
+ weight: double.parse(weightController.text),
+ muscleMass: double.parse(muscleMassController.text),
+ fatPercentage: double.parse(fatPercentageController.text),
+ ),
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Add'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ void _showEditBodyStatDialog(BodyStats stat) {
+ final weightController = TextEditingController(text: stat.weight.toString());
+ final muscleMassController = TextEditingController(text: stat.muscleMass.toString());
+ final fatPercentageController = TextEditingController(text: stat.fatPercentage.toString());
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Body Stat'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: weightController,
+ decoration: InputDecoration(labelText: 'Weight'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: muscleMassController,
+ decoration: InputDecoration(labelText: 'Muscle Mass'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: fatPercentageController,
+ decoration: InputDecoration(labelText: 'Fat Percentage'),
+ keyboardType: TextInputType.number,
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _editBodyStat(
+ BodyStats(
+ weight: double.parse(weightController.text),
+ muscleMass: double.parse(muscleMassController.text),
+ fatPercentage: double.parse(fatPercentageController.text),
+ ),
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Body Stats'),
+ ),
+ body: Column(
+ children: [
+ Expanded(
+ child: ListView.builder(
+ itemCount: _bodyStats.length,
+ itemBuilder: (context, index) {
+ return BodyStatsCard(
+ bodyStats: _bodyStats[index],
+ onEdit: _showEditBodyStatDialog,
+ onDelete: _deleteBodyStat,
+ );
+ },
+ ),
+ ),
+ ElevatedButton(
+ onPressed: _showAddBodyStatDialog,
+ child: Text('Manage Body Stats'),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/body_tracking_screen.dart b/lib/screens/body_tracking_screen.dart
new file mode 100644
index 0000000..ff6a550
--- /dev/null
+++ b/lib/screens/body_tracking_screen.dart
@@ -0,0 +1,65 @@
+import 'package:flutter/material.dart';
+import 'package:fl_chart/fl_chart.dart';
+import 'package:your_app/services/body_stats_service.dart';
+import 'package:your_app/models/body_stats.dart';
+import 'package:your_app/widgets/body_stat_chart.dart';
+
+class BodyTrackingScreen extends StatefulWidget {
+ @override
+ _BodyTrackingScreenState createState() => _BodyTrackingScreenState();
+}
+
+class _BodyTrackingScreenState extends State {
+ List _bodyStats = [];
+ final BodyStatsService _bodyStatsService = BodyStatsService();
+
+ @override
+ void initState() {
+ super.initState();
+ _loadBodyStats();
+ }
+
+ Future _loadBodyStats() async {
+ final stats = await _bodyStatsService.getBodyStats();
+ setState(() {
+ _bodyStats = stats;
+ });
+ }
+
+ void _addBodyStat(BodyStats stat) async {
+ await _bodyStatsService.addBodyStat(stat);
+ _loadBodyStats();
+ }
+
+ void _editBodyStat(BodyStats stat) async {
+ await _bodyStatsService.updateBodyStat(stat);
+ _loadBodyStats();
+ }
+
+ void _deleteBodyStat(int id) async {
+ await _bodyStatsService.deleteBodyStat(id);
+ _loadBodyStats();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Body Tracking'),
+ ),
+ body: Column(
+ children: [
+ Expanded(
+ child: BodyStatChart(bodyStats: _bodyStats),
+ ),
+ ElevatedButton(
+ onPressed: () {
+ // Add logic to add, edit, and delete body stats
+ },
+ child: Text('Manage Body Stats'),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/cloud_backup_screen.dart b/lib/screens/cloud_backup_screen.dart
new file mode 100644
index 0000000..dc38253
--- /dev/null
+++ b/lib/screens/cloud_backup_screen.dart
@@ -0,0 +1,89 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class CloudBackupScreen extends StatefulWidget {
+ @override
+ _CloudBackupScreenState createState() => _CloudBackupScreenState();
+}
+
+class _CloudBackupScreenState extends State {
+ bool _isBackupEnabled = false;
+ bool _isSyncing = false;
+ String _backupStatus = 'Not backed up';
+
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+
+ @override
+ void initState() {
+ super.initState();
+ _loadBackupSettings();
+ }
+
+ Future _loadBackupSettings() async {
+ // Load backup settings from the service
+ // For now, we'll use dummy data
+ setState(() {
+ _isBackupEnabled = true;
+ _backupStatus = 'Last backup: 2023-09-01';
+ });
+ }
+
+ Future _toggleBackup(bool value) async {
+ setState(() {
+ _isBackupEnabled = value;
+ });
+ if (value) {
+ await _startBackup();
+ }
+ }
+
+ Future _startBackup() async {
+ setState(() {
+ _isSyncing = true;
+ _backupStatus = 'Backing up...';
+ });
+
+ try {
+ await _hormoneTrackerService.syncWithCloud();
+ setState(() {
+ _backupStatus = 'Last backup: ${DateTime.now().toString()}';
+ });
+ } catch (e) {
+ setState(() {
+ _backupStatus = 'Backup failed';
+ });
+ } finally {
+ setState(() {
+ _isSyncing = false;
+ });
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Cloud Backup'),
+ ),
+ body: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SwitchListTile(
+ title: Text('Enable Cloud Backup'),
+ value: _isBackupEnabled,
+ onChanged: _toggleBackup,
+ ),
+ SizedBox(height: 16),
+ Text(
+ 'Backup Status: $_backupStatus',
+ style: TextStyle(fontSize: 16),
+ ),
+ if (_isSyncing) CircularProgressIndicator(),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart
new file mode 100644
index 0000000..cc493be
--- /dev/null
+++ b/lib/screens/dashboard_screen.dart
@@ -0,0 +1,173 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/body_stats_service.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+import 'package:your_app/models/body_stats.dart';
+import 'package:your_app/widgets/photo_comparison_widget.dart';
+import 'package:your_app/widgets/hormone_card.dart';
+import 'package:your_app/widgets/progress_visualization.dart';
+import 'package:your_app/screens/hormone_schedule_screen.dart';
+import 'package:your_app/screens/training_plan_screen.dart';
+import 'package:your_app/screens/nutrition_plan_screen.dart';
+import 'package:your_app/screens/progress_photos_screen.dart';
+import 'package:your_app/screens/body_stats_screen.dart';
+import 'package:your_app/screens/reminders_screen.dart';
+
+class DashboardScreen extends StatefulWidget {
+ @override
+ _DashboardScreenState createState() => _DashboardScreenState();
+}
+
+class _DashboardScreenState extends State {
+ List _bodyStats = [];
+ List> _hormones = [];
+ final BodyStatsService _bodyStatsService = BodyStatsService();
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+
+ @override
+ void initState() {
+ super.initState();
+ _loadData();
+ }
+
+ Future _loadData() async {
+ final bodyStats = await _bodyStatsService.getBodyStats();
+ final hormones = await _hormoneTrackerService.getHormones();
+ setState(() {
+ _bodyStats = bodyStats;
+ _hormones = hormones;
+ });
+ }
+
+ void _navigateToScreen(Widget screen) {
+ Navigator.push(
+ context,
+ MaterialPageRoute(builder: (context) => screen),
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Dashboard'),
+ ),
+ body: ListView(
+ children: [
+ Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Body Stats',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text('Weight: ${_bodyStats.isNotEmpty ? _bodyStats.last.weight : 'N/A'}'),
+ Text('Muscle Mass: ${_bodyStats.isNotEmpty ? _bodyStats.last.muscleMass : 'N/A'}'),
+ Text('Fat Percentage: ${_bodyStats.isNotEmpty ? _bodyStats.last.fatPercentage : 'N/A'}'),
+ SizedBox(height: 16),
+ ProgressVisualization(bodyStats: _bodyStats),
+ ],
+ ),
+ ),
+ ),
+ Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Recent Progress Photos',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ PhotoComparisonWidget(
+ beforePhoto: 'https://example.com/before.jpg',
+ afterPhoto: 'https://example.com/after.jpg',
+ ),
+ ],
+ ),
+ ),
+ ),
+ Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Upcoming Training Schedules and Hormone Dosages',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ ..._hormones.map((hormone) => HormoneCard(
+ id: hormone['id'],
+ name: hormone['name'],
+ dosage: hormone['dosage'],
+ schedule: hormone['schedule'],
+ purpose: hormone['purpose'],
+ hormoneTrackerService: _hormoneTrackerService,
+ )),
+ ],
+ ),
+ ),
+ ),
+ Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Navigation',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ ElevatedButton(
+ onPressed: () => _navigateToScreen(HormoneScheduleScreen()),
+ child: Text('Hormone Schedule'),
+ ),
+ ElevatedButton(
+ onPressed: () => _navigateToScreen(TrainingPlanScreen()),
+ child: Text('Training Plan'),
+ ),
+ ElevatedButton(
+ onPressed: () => _navigateToScreen(NutritionPlanScreen()),
+ child: Text('Nutrition Plan'),
+ ),
+ ElevatedButton(
+ onPressed: () => _navigateToScreen(ProgressPhotosScreen()),
+ child: Text('Progress Photos'),
+ ),
+ ElevatedButton(
+ onPressed: () => _navigateToScreen(BodyStatsScreen()),
+ child: Text('Body Stats'),
+ ),
+ ElevatedButton(
+ onPressed: () => _navigateToScreen(RemindersScreen()),
+ child: Text('Reminders'),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/diet_plan_screen.dart b/lib/screens/diet_plan_screen.dart
new file mode 100644
index 0000000..1549666
--- /dev/null
+++ b/lib/screens/diet_plan_screen.dart
@@ -0,0 +1,73 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/diet_plan_service.dart';
+import 'package:your_app/models/diet_plan.dart';
+import 'package:your_app/widgets/diet_card.dart';
+
+class DietPlanScreen extends StatefulWidget {
+ @override
+ _DietPlanScreenState createState() => _DietPlanScreenState();
+}
+
+class _DietPlanScreenState extends State {
+ List _dietPlans = [];
+ final DietPlanService _dietPlanService = DietPlanService();
+
+ @override
+ void initState() {
+ super.initState();
+ _loadDietPlans();
+ }
+
+ Future _loadDietPlans() async {
+ final plans = await _dietPlanService.getDietPlans();
+ setState(() {
+ _dietPlans = plans;
+ });
+ }
+
+ void _addDietPlan(DietPlan plan) async {
+ await _dietPlanService.addDietPlan(plan);
+ _loadDietPlans();
+ }
+
+ void _editDietPlan(DietPlan plan) async {
+ await _dietPlanService.updateDietPlan(plan);
+ _loadDietPlans();
+ }
+
+ void _deleteDietPlan(int id) async {
+ await _dietPlanService.deleteDietPlan(id);
+ _loadDietPlans();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Diet Plans'),
+ ),
+ body: Column(
+ children: [
+ Expanded(
+ child: ListView.builder(
+ itemCount: _dietPlans.length,
+ itemBuilder: (context, index) {
+ return DietCard(
+ dietPlan: _dietPlans[index],
+ onEdit: _editDietPlan,
+ onDelete: _deleteDietPlan,
+ );
+ },
+ ),
+ ),
+ ElevatedButton(
+ onPressed: () {
+ // Add logic to add, edit, and delete diet plans
+ },
+ child: Text('Manage Diet Plans'),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/feedback_screen.dart b/lib/screens/feedback_screen.dart
new file mode 100644
index 0000000..6f6c3f4
--- /dev/null
+++ b/lib/screens/feedback_screen.dart
@@ -0,0 +1,52 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class FeedbackScreen extends StatefulWidget {
+ @override
+ _FeedbackScreenState createState() => _FeedbackScreenState();
+}
+
+class _FeedbackScreenState extends State {
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+ final TextEditingController _feedbackController = TextEditingController();
+
+ void _submitFeedback() async {
+ final feedback = _feedbackController.text;
+ if (feedback.isNotEmpty) {
+ await _hormoneTrackerService.submitFeedback(feedback);
+ _feedbackController.clear();
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text('Feedback submitted successfully')),
+ );
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Feedback'),
+ ),
+ body: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ children: [
+ TextField(
+ controller: _feedbackController,
+ decoration: InputDecoration(
+ labelText: 'Your Feedback',
+ border: OutlineInputBorder(),
+ ),
+ maxLines: 5,
+ ),
+ SizedBox(height: 16),
+ ElevatedButton(
+ onPressed: _submitFeedback,
+ child: Text('Submit'),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/screens/help_screen.dart b/lib/screens/help_screen.dart
new file mode 100644
index 0000000..02e33b1
--- /dev/null
+++ b/lib/screens/help_screen.dart
@@ -0,0 +1,75 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class HelpScreen extends StatefulWidget {
+ @override
+ _HelpScreenState createState() => _HelpScreenState();
+}
+
+class _HelpScreenState extends State {
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+ List> _helpResources = [];
+
+ @override
+ void initState() {
+ super.initState();
+ _loadHelpResources();
+ }
+
+ Future _loadHelpResources() async {
+ final resources = await _hormoneTrackerService.getHelpResources();
+ setState(() {
+ _helpResources = resources;
+ });
+ }
+
+ void _searchHelpResources(String query) {
+ final filteredResources = _helpResources.where((resource) {
+ final resourceName = resource['name'].toLowerCase();
+ final searchQuery = query.toLowerCase();
+ return resourceName.contains(searchQuery);
+ }).toList();
+
+ setState(() {
+ _helpResources = filteredResources;
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Help & Support'),
+ ),
+ body: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: TextField(
+ decoration: InputDecoration(
+ labelText: 'Search Help Resources',
+ border: OutlineInputBorder(),
+ ),
+ onChanged: _searchHelpResources,
+ ),
+ ),
+ Expanded(
+ child: ListView.builder(
+ itemCount: _helpResources.length,
+ itemBuilder: (context, index) {
+ final resource = _helpResources[index];
+ return ListTile(
+ title: Text(resource['name']),
+ subtitle: Text(resource['description']),
+ onTap: () {
+ // Open the help resource link
+ },
+ );
+ },
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/hormone_schedule_screen.dart b/lib/screens/hormone_schedule_screen.dart
new file mode 100644
index 0000000..d9df7d5
--- /dev/null
+++ b/lib/screens/hormone_schedule_screen.dart
@@ -0,0 +1,193 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class HormoneScheduleScreen extends StatefulWidget {
+ @override
+ _HormoneScheduleScreenState createState() => _HormoneScheduleScreenState();
+}
+
+class _HormoneScheduleScreenState extends State {
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+ List> _hormones = [];
+
+ @override
+ void initState() {
+ super.initState();
+ _loadHormones();
+ }
+
+ Future _loadHormones() async {
+ final hormones = await _hormoneTrackerService.getHormones();
+ setState(() {
+ _hormones = hormones;
+ });
+ }
+
+ Future _addHormone(String name, double dosage, String schedule, String purpose) async {
+ await _hormoneTrackerService.addHormone(name, dosage, schedule, purpose);
+ _loadHormones();
+ }
+
+ Future _editHormone(int id, String name, double dosage, String schedule, String purpose) async {
+ await _hormoneTrackerService.editHormone(id, name, dosage, schedule, purpose);
+ _loadHormones();
+ }
+
+ Future _deleteHormone(int id) async {
+ await _hormoneTrackerService.deleteHormone(id);
+ _loadHormones();
+ }
+
+ void _showAddHormoneDialog() {
+ final nameController = TextEditingController();
+ final dosageController = TextEditingController();
+ final scheduleController = TextEditingController();
+ final purposeController = TextEditingController();
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Add Hormone'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: dosageController,
+ decoration: InputDecoration(labelText: 'Dosage'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _addHormone(
+ nameController.text,
+ double.parse(dosageController.text),
+ scheduleController.text,
+ purposeController.text,
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Add'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ void _showEditHormoneDialog(Map hormone) {
+ final nameController = TextEditingController(text: hormone['name']);
+ final dosageController = TextEditingController(text: hormone['dosage'].toString());
+ final scheduleController = TextEditingController(text: hormone['schedule']);
+ final purposeController = TextEditingController(text: hormone['purpose']);
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Hormone'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: dosageController,
+ decoration: InputDecoration(labelText: 'Dosage'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _editHormone(
+ hormone['id'],
+ nameController.text,
+ double.parse(dosageController.text),
+ scheduleController.text,
+ purposeController.text,
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Hormone Schedule'),
+ ),
+ body: ListView.builder(
+ itemCount: _hormones.length,
+ itemBuilder: (context, index) {
+ final hormone = _hormones[index];
+ return ListTile(
+ title: Text(hormone['name']),
+ subtitle: Text('Dosage: ${hormone['dosage']} - Schedule: ${hormone['schedule']}'),
+ trailing: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ IconButton(
+ icon: Icon(Icons.edit),
+ onPressed: () => _showEditHormoneDialog(hormone),
+ ),
+ IconButton(
+ icon: Icon(Icons.delete),
+ onPressed: () => _deleteHormone(hormone['id']),
+ ),
+ ],
+ ),
+ );
+ },
+ ),
+ floatingActionButton: FloatingActionButton(
+ onPressed: _showAddHormoneDialog,
+ child: Icon(Icons.add),
+ ),
+ );
+ }
+}
diff --git a/lib/screens/notification_center_screen.dart b/lib/screens/notification_center_screen.dart
new file mode 100644
index 0000000..76d46b4
--- /dev/null
+++ b/lib/screens/notification_center_screen.dart
@@ -0,0 +1,170 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+import 'package:your_app/widgets/reminder_card.dart';
+
+class NotificationCenterScreen extends StatefulWidget {
+ @override
+ _NotificationCenterScreenState createState() => _NotificationCenterScreenState();
+}
+
+class _NotificationCenterScreenState extends State {
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+ List> _reminders = [];
+
+ @override
+ void initState() {
+ super.initState();
+ _loadReminders();
+ }
+
+ Future _loadReminders() async {
+ final reminders = await _hormoneTrackerService.getReminders();
+ setState(() {
+ _reminders = reminders;
+ });
+ }
+
+ Future _addReminder(String name, String schedule, String purpose) async {
+ await _hormoneTrackerService.addReminder(name, schedule, purpose);
+ _loadReminders();
+ }
+
+ Future _editReminder(int id, String name, String schedule, String purpose) async {
+ await _hormoneTrackerService.editReminder(id, name, schedule, purpose);
+ _loadReminders();
+ }
+
+ Future _deleteReminder(int id) async {
+ await _hormoneTrackerService.deleteReminder(id);
+ _loadReminders();
+ }
+
+ void _showAddReminderDialog() {
+ final nameController = TextEditingController();
+ final scheduleController = TextEditingController();
+ final purposeController = TextEditingController();
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Add Reminder'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _addReminder(
+ nameController.text,
+ scheduleController.text,
+ purposeController.text,
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Add'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ void _showEditReminderDialog(Map reminder) {
+ final nameController = TextEditingController(text: reminder['name']);
+ final scheduleController = TextEditingController(text: reminder['schedule']);
+ final purposeController = TextEditingController(text: reminder['purpose']);
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Reminder'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _editReminder(
+ reminder['id'],
+ nameController.text,
+ scheduleController.text,
+ purposeController.text,
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Notification Center'),
+ ),
+ body: ListView.builder(
+ itemCount: _reminders.length,
+ itemBuilder: (context, index) {
+ final reminder = _reminders[index];
+ return ReminderCard(
+ id: reminder['id'],
+ name: reminder['name'],
+ schedule: reminder['schedule'],
+ purpose: reminder['purpose'],
+ hormoneTrackerService: _hormoneTrackerService,
+ );
+ },
+ ),
+ floatingActionButton: FloatingActionButton(
+ onPressed: _showAddReminderDialog,
+ child: Icon(Icons.add),
+ ),
+ );
+ }
+}
diff --git a/lib/screens/nutrition_plan_screen.dart b/lib/screens/nutrition_plan_screen.dart
new file mode 100644
index 0000000..2861adc
--- /dev/null
+++ b/lib/screens/nutrition_plan_screen.dart
@@ -0,0 +1,213 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/nutrition_plan_service.dart';
+import 'package:your_app/models/nutrition_plan.dart';
+import 'package:your_app/widgets/nutrition_plan_card.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class NutritionPlanScreen extends StatefulWidget {
+ @override
+ _NutritionPlanScreenState createState() => _NutritionPlanScreenState();
+}
+
+class _NutritionPlanScreenState extends State {
+ List _nutritionPlans = [];
+ final NutritionPlanService _nutritionPlanService = NutritionPlanService();
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+
+ @override
+ void initState() {
+ super.initState();
+ _loadNutritionPlans();
+ }
+
+ Future _loadNutritionPlans() async {
+ final plans = await _nutritionPlanService.getNutritionPlans();
+ setState(() {
+ _nutritionPlans = plans;
+ });
+ }
+
+ void _addNutritionPlan(NutritionPlan plan) async {
+ await _nutritionPlanService.addNutritionPlan(plan);
+ _loadNutritionPlans();
+ }
+
+ void _editNutritionPlan(NutritionPlan plan) async {
+ await _nutritionPlanService.updateNutritionPlan(plan);
+ _loadNutritionPlans();
+ }
+
+ void _deleteNutritionPlan(int id) async {
+ await _nutritionPlanService.deleteNutritionPlan(id);
+ _loadNutritionPlans();
+ }
+
+ void _showAddNutritionPlanDialog() {
+ final nameController = TextEditingController();
+ final caloriesController = TextEditingController();
+ final proteinController = TextEditingController();
+ final carbsController = TextEditingController();
+ final fatsController = TextEditingController();
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Add Nutrition Plan'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: caloriesController,
+ decoration: InputDecoration(labelText: 'Calories'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: proteinController,
+ decoration: InputDecoration(labelText: 'Protein (g)'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: carbsController,
+ decoration: InputDecoration(labelText: 'Carbs (g)'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: fatsController,
+ decoration: InputDecoration(labelText: 'Fats (g)'),
+ keyboardType: TextInputType.number,
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _addNutritionPlan(
+ NutritionPlan(
+ id: 0,
+ name: nameController.text,
+ calories: int.parse(caloriesController.text),
+ protein: int.parse(proteinController.text),
+ carbs: int.parse(carbsController.text),
+ fats: int.parse(fatsController.text),
+ ),
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Add'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ void _showEditNutritionPlanDialog(NutritionPlan plan) {
+ final nameController = TextEditingController(text: plan.name);
+ final caloriesController = TextEditingController(text: plan.calories.toString());
+ final proteinController = TextEditingController(text: plan.protein.toString());
+ final carbsController = TextEditingController(text: plan.carbs.toString());
+ final fatsController = TextEditingController(text: plan.fats.toString());
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Nutrition Plan'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: caloriesController,
+ decoration: InputDecoration(labelText: 'Calories'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: proteinController,
+ decoration: InputDecoration(labelText: 'Protein (g)'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: carbsController,
+ decoration: InputDecoration(labelText: 'Carbs (g)'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: fatsController,
+ decoration: InputDecoration(labelText: 'Fats (g)'),
+ keyboardType: TextInputType.number,
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _editNutritionPlan(
+ NutritionPlan(
+ id: plan.id,
+ name: nameController.text,
+ calories: int.parse(caloriesController.text),
+ protein: int.parse(proteinController.text),
+ carbs: int.parse(carbsController.text),
+ fats: int.parse(fatsController.text),
+ ),
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Nutrition Plans'),
+ ),
+ body: Column(
+ children: [
+ Expanded(
+ child: ListView.builder(
+ itemCount: _nutritionPlans.length,
+ itemBuilder: (context, index) {
+ return NutritionPlanCard(
+ nutritionPlan: _nutritionPlans[index],
+ onEdit: _editNutritionPlan,
+ onDelete: _deleteNutritionPlan,
+ );
+ },
+ ),
+ ),
+ ElevatedButton(
+ onPressed: _showAddNutritionPlanDialog,
+ child: Text('Manage Nutrition Plans'),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/progress_photos_screen.dart b/lib/screens/progress_photos_screen.dart
new file mode 100644
index 0000000..f82881c
--- /dev/null
+++ b/lib/screens/progress_photos_screen.dart
@@ -0,0 +1,82 @@
+import 'package:flutter/material.dart';
+import 'package:image_picker/image_picker.dart';
+import 'package:your_app/services/progress_photos_service.dart';
+import 'package:your_app/widgets/photo_comparison_widget.dart';
+
+class ProgressPhotosScreen extends StatefulWidget {
+ @override
+ _ProgressPhotosScreenState createState() => _ProgressPhotosScreenState();
+}
+
+class _ProgressPhotosScreenState extends State {
+ List _photos = [];
+ final ProgressPhotosService _progressPhotosService = ProgressPhotosService();
+
+ @override
+ void initState() {
+ super.initState();
+ _loadPhotos();
+ }
+
+ Future _loadPhotos() async {
+ final photos = await _progressPhotosService.getPhotos();
+ setState(() {
+ _photos = photos;
+ });
+ }
+
+ Future _pickPhoto() async {
+ final ImagePicker picker = ImagePicker();
+ final XFile? photo = await picker.pickImage(source: ImageSource.gallery);
+ if (photo != null) {
+ await _progressPhotosService.addPhoto(photo);
+ _loadPhotos();
+ }
+ }
+
+ void _deletePhoto(int id) async {
+ await _progressPhotosService.deletePhoto(id);
+ _loadPhotos();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Progress Photos'),
+ ),
+ body: Column(
+ children: [
+ Expanded(
+ child: GridView.builder(
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 2,
+ crossAxisSpacing: 4.0,
+ mainAxisSpacing: 4.0,
+ ),
+ itemCount: _photos.length,
+ itemBuilder: (context, index) {
+ return GestureDetector(
+ onLongPress: () => _deletePhoto(_photos[index].id),
+ child: Image.file(
+ File(_photos[index].path),
+ fit: BoxFit.cover,
+ ),
+ );
+ },
+ ),
+ ),
+ ElevatedButton(
+ onPressed: _pickPhoto,
+ child: Text('Upload Photo'),
+ ),
+ if (_photos.length >= 2)
+ PhotoComparisonWidget(
+ beforePhoto: _photos[_photos.length - 2],
+ afterPhoto: _photos[_photos.length - 1],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/reminders_screen.dart b/lib/screens/reminders_screen.dart
new file mode 100644
index 0000000..ff9bdcb
--- /dev/null
+++ b/lib/screens/reminders_screen.dart
@@ -0,0 +1,170 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+import 'package:your_app/widgets/reminder_card.dart';
+
+class RemindersScreen extends StatefulWidget {
+ @override
+ _RemindersScreenState createState() => _RemindersScreenState();
+}
+
+class _RemindersScreenState extends State {
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+ List> _reminders = [];
+
+ @override
+ void initState() {
+ super.initState();
+ _loadReminders();
+ }
+
+ Future _loadReminders() async {
+ final reminders = await _hormoneTrackerService.getReminders();
+ setState(() {
+ _reminders = reminders;
+ });
+ }
+
+ Future _addReminder(String name, String schedule, String purpose) async {
+ await _hormoneTrackerService.addReminder(name, schedule, purpose);
+ _loadReminders();
+ }
+
+ Future _editReminder(int id, String name, String schedule, String purpose) async {
+ await _hormoneTrackerService.editReminder(id, name, schedule, purpose);
+ _loadReminders();
+ }
+
+ Future _deleteReminder(int id) async {
+ await _hormoneTrackerService.deleteReminder(id);
+ _loadReminders();
+ }
+
+ void _showAddReminderDialog() {
+ final nameController = TextEditingController();
+ final scheduleController = TextEditingController();
+ final purposeController = TextEditingController();
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Add Reminder'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _addReminder(
+ nameController.text,
+ scheduleController.text,
+ purposeController.text,
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Add'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ void _showEditReminderDialog(Map reminder) {
+ final nameController = TextEditingController(text: reminder['name']);
+ final scheduleController = TextEditingController(text: reminder['schedule']);
+ final purposeController = TextEditingController(text: reminder['purpose']);
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Reminder'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _editReminder(
+ reminder['id'],
+ nameController.text,
+ scheduleController.text,
+ purposeController.text,
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Reminders'),
+ ),
+ body: ListView.builder(
+ itemCount: _reminders.length,
+ itemBuilder: (context, index) {
+ final reminder = _reminders[index];
+ return ReminderCard(
+ id: reminder['id'],
+ name: reminder['name'],
+ schedule: reminder['schedule'],
+ purpose: reminder['purpose'],
+ hormoneTrackerService: _hormoneTrackerService,
+ );
+ },
+ ),
+ floatingActionButton: FloatingActionButton(
+ onPressed: _showAddReminderDialog,
+ child: Icon(Icons.add),
+ ),
+ );
+ }
+}
diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart
new file mode 100644
index 0000000..6c50ee6
--- /dev/null
+++ b/lib/screens/settings_screen.dart
@@ -0,0 +1,17 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+import 'package:your_app/widgets/settings_menu.dart';
+
+class SettingsScreen extends StatelessWidget {
+ final HormoneTrackerService hormoneTrackerService = HormoneTrackerService();
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Settings'),
+ ),
+ body: SettingsMenu(hormoneTrackerService: hormoneTrackerService),
+ );
+ }
+}
diff --git a/lib/screens/trainer_dashboard_screen.dart b/lib/screens/trainer_dashboard_screen.dart
new file mode 100644
index 0000000..39c680d
--- /dev/null
+++ b/lib/screens/trainer_dashboard_screen.dart
@@ -0,0 +1,73 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/trainer_profile_service.dart';
+import 'package:your_app/models/trainer_profile.dart';
+import 'package:your_app/widgets/client_card.dart';
+
+class TrainerDashboardScreen extends StatefulWidget {
+ @override
+ _TrainerDashboardScreenState createState() => _TrainerDashboardScreenState();
+}
+
+class _TrainerDashboardScreenState extends State {
+ List _clients = [];
+ final TrainerProfileService _trainerProfileService = TrainerProfileService();
+
+ @override
+ void initState() {
+ super.initState();
+ _loadClients();
+ }
+
+ Future _loadClients() async {
+ final clients = await _trainerProfileService.getClients();
+ setState(() {
+ _clients = clients;
+ });
+ }
+
+ void _addClient(TrainerProfile client) async {
+ await _trainerProfileService.addClient(client);
+ _loadClients();
+ }
+
+ void _editClient(TrainerProfile client) async {
+ await _trainerProfileService.updateClient(client);
+ _loadClients();
+ }
+
+ void _deleteClient(int id) async {
+ await _trainerProfileService.deleteClient(id);
+ _loadClients();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Trainer Dashboard'),
+ ),
+ body: Column(
+ children: [
+ Expanded(
+ child: ListView.builder(
+ itemCount: _clients.length,
+ itemBuilder: (context, index) {
+ return ClientCard(
+ client: _clients[index],
+ onEdit: _editClient,
+ onDelete: _deleteClient,
+ );
+ },
+ ),
+ ),
+ ElevatedButton(
+ onPressed: () {
+ // Add logic to add, edit, and delete clients
+ },
+ child: Text('Manage Clients'),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/training_plan_screen.dart b/lib/screens/training_plan_screen.dart
new file mode 100644
index 0000000..1c73251
--- /dev/null
+++ b/lib/screens/training_plan_screen.dart
@@ -0,0 +1,179 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+import 'package:your_app/widgets/training_plan_card.dart';
+
+class TrainingPlanScreen extends StatefulWidget {
+ @override
+ _TrainingPlanScreenState createState() => _TrainingPlanScreenState();
+}
+
+class _TrainingPlanScreenState extends State {
+ List _trainingPlans = [];
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+
+ @override
+ void initState() {
+ super.initState();
+ _loadTrainingPlans();
+ }
+
+ Future _loadTrainingPlans() async {
+ final plans = await _hormoneTrackerService.getTrainingPlans();
+ setState(() {
+ _trainingPlans = plans;
+ });
+ }
+
+ void _addTrainingPlan(TrainingPlan plan) async {
+ await _hormoneTrackerService.addTrainingPlan(plan);
+ _loadTrainingPlans();
+ }
+
+ void _editTrainingPlan(TrainingPlan plan) async {
+ await _hormoneTrackerService.updateTrainingPlan(plan);
+ _loadTrainingPlans();
+ }
+
+ void _deleteTrainingPlan(int id) async {
+ await _hormoneTrackerService.deleteTrainingPlan(id);
+ _loadTrainingPlans();
+ }
+
+ void _showAddTrainingPlanDialog() {
+ final nameController = TextEditingController();
+ final scheduleController = TextEditingController();
+ final purposeController = TextEditingController();
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Add Training Plan'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _addTrainingPlan(
+ TrainingPlan(
+ id: 0,
+ name: nameController.text,
+ schedule: scheduleController.text,
+ purpose: purposeController.text,
+ ),
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Add'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ void _showEditTrainingPlanDialog(TrainingPlan plan) {
+ final nameController = TextEditingController(text: plan.name);
+ final scheduleController = TextEditingController(text: plan.schedule);
+ final purposeController = TextEditingController(text: plan.purpose);
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Training Plan'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _editTrainingPlan(
+ TrainingPlan(
+ id: plan.id,
+ name: nameController.text,
+ schedule: scheduleController.text,
+ purpose: purposeController.text,
+ ),
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Training Plans'),
+ ),
+ body: Column(
+ children: [
+ Expanded(
+ child: ListView.builder(
+ itemCount: _trainingPlans.length,
+ itemBuilder: (context, index) {
+ return TrainingPlanCard(
+ trainingPlan: _trainingPlans[index],
+ onEdit: _editTrainingPlan,
+ onDelete: _deleteTrainingPlan,
+ hormoneTrackerService: _hormoneTrackerService,
+ );
+ },
+ ),
+ ),
+ ElevatedButton(
+ onPressed: _showAddTrainingPlanDialog,
+ child: Text('Manage Training Plans'),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/user_profile_screen.dart b/lib/screens/user_profile_screen.dart
new file mode 100644
index 0000000..998eff0
--- /dev/null
+++ b/lib/screens/user_profile_screen.dart
@@ -0,0 +1,210 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+import 'package:your_app/models/hormone.dart';
+
+class UserProfileScreen extends StatefulWidget {
+ @override
+ _UserProfileScreenState createState() => _UserProfileScreenState();
+}
+
+class _UserProfileScreenState extends State {
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+ List _hormones = [];
+
+ @override
+ void initState() {
+ super.initState();
+ _loadHormones();
+ }
+
+ Future _loadHormones() async {
+ final hormones = await _hormoneTrackerService.getHormones();
+ setState(() {
+ _hormones = hormones.map((hormone) => Hormone.fromJson(hormone)).toList();
+ });
+ }
+
+ Future _addHormone(Hormone hormone) async {
+ await _hormoneTrackerService.addHormone(
+ hormone.name,
+ hormone.dosage,
+ hormone.schedule,
+ hormone.purpose,
+ );
+ _loadHormones();
+ }
+
+ Future _editHormone(Hormone hormone) async {
+ await _hormoneTrackerService.editHormone(
+ hormone.id,
+ hormone.name,
+ hormone.dosage,
+ hormone.schedule,
+ hormone.purpose,
+ );
+ _loadHormones();
+ }
+
+ Future _deleteHormone(int id) async {
+ await _hormoneTrackerService.deleteHormone(id);
+ _loadHormones();
+ }
+
+ void _showAddHormoneDialog() {
+ final nameController = TextEditingController();
+ final dosageController = TextEditingController();
+ final scheduleController = TextEditingController();
+ final purposeController = TextEditingController();
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Add Hormone'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: dosageController,
+ decoration: InputDecoration(labelText: 'Dosage'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _addHormone(
+ Hormone(
+ id: 0,
+ name: nameController.text,
+ dosage: double.parse(dosageController.text),
+ schedule: scheduleController.text,
+ purpose: purposeController.text,
+ ),
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Add'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ void _showEditHormoneDialog(Hormone hormone) {
+ final nameController = TextEditingController(text: hormone.name);
+ final dosageController = TextEditingController(text: hormone.dosage.toString());
+ final scheduleController = TextEditingController(text: hormone.schedule);
+ final purposeController = TextEditingController(text: hormone.purpose);
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Hormone'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: dosageController,
+ decoration: InputDecoration(labelText: 'Dosage'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ _editHormone(
+ Hormone(
+ id: hormone.id,
+ name: nameController.text,
+ dosage: double.parse(dosageController.text),
+ schedule: scheduleController.text,
+ purpose: purposeController.text,
+ ),
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('User Profile'),
+ ),
+ body: ListView.builder(
+ itemCount: _hormones.length,
+ itemBuilder: (context, index) {
+ final hormone = _hormones[index];
+ return ListTile(
+ title: Text(hormone.name),
+ subtitle: Text('Dosage: ${hormone.dosage}, Schedule: ${hormone.schedule}, Purpose: ${hormone.purpose}'),
+ trailing: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ IconButton(
+ icon: Icon(Icons.edit),
+ onPressed: () => _showEditHormoneDialog(hormone),
+ ),
+ IconButton(
+ icon: Icon(Icons.delete),
+ onPressed: () => _deleteHormone(hormone.id),
+ ),
+ ],
+ ),
+ );
+ },
+ ),
+ floatingActionButton: FloatingActionButton(
+ onPressed: _showAddHormoneDialog,
+ child: Icon(Icons.add),
+ ),
+ );
+ }
+}
diff --git a/lib/services/ai_recommendation_service.dart b/lib/services/ai_recommendation_service.dart
new file mode 100644
index 0000000..f393760
--- /dev/null
+++ b/lib/services/ai_recommendation_service.dart
@@ -0,0 +1,25 @@
+import 'package:http/http.dart' as http;
+import 'dart:convert';
+
+class AIRecommendationService {
+ static final AIRecommendationService _instance = AIRecommendationService._internal();
+ factory AIRecommendationService() => _instance;
+ AIRecommendationService._internal();
+
+ Future> fetchRecommendations(Map userData) async {
+ final response = await http.post(
+ Uri.parse('https://api.example.com/ai-recommendations'),
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': 'Bearer YOUR_API_TOKEN',
+ },
+ body: json.encode(userData),
+ );
+
+ if (response.statusCode == 200) {
+ return json.decode(response.body);
+ } else {
+ throw Exception('Failed to fetch AI recommendations');
+ }
+ }
+}
diff --git a/lib/services/api_service.dart b/lib/services/api_service.dart
new file mode 100644
index 0000000..59071ca
--- /dev/null
+++ b/lib/services/api_service.dart
@@ -0,0 +1,63 @@
+import 'package:http/http.dart' as http;
+import 'dart:convert';
+
+class ApiService {
+ final String baseUrl;
+ final String authToken;
+
+ ApiService({required this.baseUrl, required this.authToken});
+
+ Future getRequest(String endpoint) async {
+ final response = await http.get(
+ Uri.parse('$baseUrl/$endpoint'),
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': 'Bearer $authToken',
+ },
+ );
+ return _handleResponse(response);
+ }
+
+ Future postRequest(String endpoint, Map data) async {
+ final response = await http.post(
+ Uri.parse('$baseUrl/$endpoint'),
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': 'Bearer $authToken',
+ },
+ body: json.encode(data),
+ );
+ return _handleResponse(response);
+ }
+
+ Future putRequest(String endpoint, Map data) async {
+ final response = await http.put(
+ Uri.parse('$baseUrl/$endpoint'),
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': 'Bearer $authToken',
+ },
+ body: json.encode(data),
+ );
+ return _handleResponse(response);
+ }
+
+ Future deleteRequest(String endpoint) async {
+ final response = await http.delete(
+ Uri.parse('$baseUrl/$endpoint'),
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': 'Bearer $authToken',
+ },
+ );
+ return _handleResponse(response);
+ }
+
+ http.Response _handleResponse(http.Response response) {
+ if (response.statusCode >= 200 && response.statusCode < 300) {
+ return response;
+ } else {
+ throw Exception('Failed to load data: ${response.statusCode}');
+ }
+ }
+}
diff --git a/lib/services/body_stats_service.dart b/lib/services/body_stats_service.dart
new file mode 100644
index 0000000..a28ec7a
--- /dev/null
+++ b/lib/services/body_stats_service.dart
@@ -0,0 +1,66 @@
+import 'package:sqflite/sqflite.dart';
+import 'package:path/path.dart';
+import 'package:your_app/models/body_stats.dart';
+
+class BodyStatsService {
+ static final BodyStatsService _instance = BodyStatsService._internal();
+ factory BodyStatsService() => _instance;
+ BodyStatsService._internal();
+
+ Database? _database;
+
+ Future get database async {
+ if (_database != null) return _database!;
+ _database = await _initDatabase();
+ return _database!;
+ }
+
+ Future _initDatabase() async {
+ String path = join(await getDatabasesPath(), 'body_stats.db');
+ return await openDatabase(
+ path,
+ version: 1,
+ onCreate: (db, version) {
+ return db.execute(
+ 'CREATE TABLE body_stats(id INTEGER PRIMARY KEY, weight REAL, muscleMass REAL, fatPercentage REAL)',
+ );
+ },
+ );
+ }
+
+ Future addBodyStat(BodyStats stat) async {
+ final db = await database;
+ await db.insert(
+ 'body_stats',
+ stat.toJson(),
+ conflictAlgorithm: ConflictAlgorithm.replace,
+ );
+ }
+
+ Future updateBodyStat(BodyStats stat) async {
+ final db = await database;
+ await db.update(
+ 'body_stats',
+ stat.toJson(),
+ where: 'id = ?',
+ whereArgs: [stat.id],
+ );
+ }
+
+ Future deleteBodyStat(int id) async {
+ final db = await database;
+ await db.delete(
+ 'body_stats',
+ where: 'id = ?',
+ whereArgs: [id],
+ );
+ }
+
+ Future> getBodyStats() async {
+ final db = await database;
+ final List> maps = await db.query('body_stats');
+ return List.generate(maps.length, (i) {
+ return BodyStats.fromJson(maps[i]);
+ });
+ }
+}
diff --git a/lib/services/hormone_tracker_service.dart b/lib/services/hormone_tracker_service.dart
new file mode 100644
index 0000000..950dbc2
--- /dev/null
+++ b/lib/services/hormone_tracker_service.dart
@@ -0,0 +1,78 @@
+import 'package:sqflite/sqflite.dart';
+import 'package:path/path.dart';
+
+class HormoneTrackerService {
+ static final HormoneTrackerService _instance = HormoneTrackerService._internal();
+ factory HormoneTrackerService() => _instance;
+ HormoneTrackerService._internal();
+
+ Database _database;
+
+ Future get database async {
+ if (_database != null) return _database;
+ _database = await _initDatabase();
+ return _database;
+ }
+
+ Future _initDatabase() async {
+ String path = join(await getDatabasesPath(), 'hormone_tracker.db');
+ return await openDatabase(
+ path,
+ version: 1,
+ onCreate: (db, version) async {
+ await db.execute('''
+ CREATE TABLE hormones (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT,
+ dosage REAL,
+ schedule TEXT,
+ purpose TEXT
+ )
+ ''');
+ },
+ );
+ }
+
+ Future addHormone(String name, double dosage, String schedule, String purpose) async {
+ final db = await database;
+ await db.insert(
+ 'hormones',
+ {
+ 'name': name,
+ 'dosage': dosage,
+ 'schedule': schedule,
+ 'purpose': purpose,
+ },
+ conflictAlgorithm: ConflictAlgorithm.replace,
+ );
+ }
+
+ Future editHormone(int id, String name, double dosage, String schedule, String purpose) async {
+ final db = await database;
+ await db.update(
+ 'hormones',
+ {
+ 'name': name,
+ 'dosage': dosage,
+ 'schedule': schedule,
+ 'purpose': purpose,
+ },
+ where: 'id = ?',
+ whereArgs: [id],
+ );
+ }
+
+ Future deleteHormone(int id) async {
+ final db = await database;
+ await db.delete(
+ 'hormones',
+ where: 'id = ?',
+ whereArgs: [id],
+ );
+ }
+
+ Future>> getHormones() async {
+ final db = await database;
+ return await db.query('hormones');
+ }
+}
diff --git a/lib/services/hybrid_recommendation_service.dart b/lib/services/hybrid_recommendation_service.dart
new file mode 100644
index 0000000..c8a8c6e
--- /dev/null
+++ b/lib/services/hybrid_recommendation_service.dart
@@ -0,0 +1,23 @@
+import 'package:your_app/services/ai_recommendation_service.dart';
+import 'package:your_app/services/rule_based_recommendation_service.dart';
+
+class HybridRecommendationService {
+ static final HybridRecommendationService _instance = HybridRecommendationService._internal();
+ factory HybridRecommendationService() => _instance;
+ HybridRecommendationService._internal();
+
+ final AIRecommendationService _aiService = AIRecommendationService();
+ final RuleBasedRecommendationService _ruleBasedService = RuleBasedRecommendationService();
+
+ Future> fetchRecommendations(Map userData) async {
+ try {
+ // Use rule-based system for common scenarios
+ final ruleBasedRecommendation = _ruleBasedService.fetchRecommendations(userData);
+ return ruleBasedRecommendation;
+ } catch (e) {
+ // Use AI model for personalized recommendations
+ final aiRecommendation = await _aiService.fetchRecommendations(userData);
+ return aiRecommendation;
+ }
+ }
+}
diff --git a/lib/services/notification_service.dart b/lib/services/notification_service.dart
new file mode 100644
index 0000000..0f53ba6
--- /dev/null
+++ b/lib/services/notification_service.dart
@@ -0,0 +1,62 @@
+import 'package:flutter_local_notifications/flutter_local_notifications.dart';
+
+class NotificationService {
+ final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
+ FlutterLocalNotificationsPlugin();
+
+ NotificationService() {
+ _initializeNotifications();
+ }
+
+ void _initializeNotifications() async {
+ const AndroidInitializationSettings initializationSettingsAndroid =
+ AndroidInitializationSettings('app_icon');
+
+ final InitializationSettings initializationSettings =
+ InitializationSettings(android: initializationSettingsAndroid);
+
+ await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
+ }
+
+ Future showNotification(
+ int id, String title, String body, DateTime scheduledTime) async {
+ const AndroidNotificationDetails androidPlatformChannelSpecifics =
+ AndroidNotificationDetails(
+ 'your_channel_id',
+ 'your_channel_name',
+ 'your_channel_description',
+ importance: Importance.max,
+ priority: Priority.high,
+ showWhen: false,
+ );
+
+ const NotificationDetails platformChannelSpecifics =
+ NotificationDetails(android: androidPlatformChannelSpecifics);
+
+ await _flutterLocalNotificationsPlugin.zonedSchedule(
+ id,
+ title,
+ body,
+ scheduledTime,
+ platformChannelSpecifics,
+ androidAllowWhileIdle: true,
+ uiLocalNotificationDateInterpretation:
+ UILocalNotificationDateInterpretation.absoluteTime,
+ );
+ }
+
+ Future scheduleTrainingSessionNotification(
+ int id, String title, String body, DateTime scheduledTime) async {
+ await showNotification(id, title, body, scheduledTime);
+ }
+
+ Future scheduleMealPlanNotification(
+ int id, String title, String body, DateTime scheduledTime) async {
+ await showNotification(id, title, body, scheduledTime);
+ }
+
+ Future scheduleHormoneScheduleNotification(
+ int id, String title, String body, DateTime scheduledTime) async {
+ await showNotification(id, title, body, scheduledTime);
+ }
+}
diff --git a/lib/services/rule_based_recommendation_service.dart b/lib/services/rule_based_recommendation_service.dart
new file mode 100644
index 0000000..9524ce0
--- /dev/null
+++ b/lib/services/rule_based_recommendation_service.dart
@@ -0,0 +1,44 @@
+class RuleBasedRecommendationService {
+ static final RuleBasedRecommendationService _instance = RuleBasedRecommendationService._internal();
+ factory RuleBasedRecommendationService() => _instance;
+ RuleBasedRecommendationService._internal();
+
+ List> _rules = [
+ {
+ 'condition': (Map userData) => userData['goal'] == 'muscle_gain',
+ 'recommendation': {
+ 'hormone': 'Testosterone',
+ 'dosage': 200,
+ 'schedule': 'Weekly',
+ 'purpose': 'Increase muscle mass'
+ }
+ },
+ {
+ 'condition': (Map userData) => userData['goal'] == 'weight_loss',
+ 'recommendation': {
+ 'hormone': 'Clenbuterol',
+ 'dosage': 40,
+ 'schedule': 'Daily',
+ 'purpose': 'Promote fat loss'
+ }
+ },
+ {
+ 'condition': (Map userData) => userData['goal'] == 'maintenance',
+ 'recommendation': {
+ 'hormone': 'HGH',
+ 'dosage': 2,
+ 'schedule': 'Daily',
+ 'purpose': 'Maintain overall health'
+ }
+ },
+ ];
+
+ Map fetchRecommendations(Map userData) {
+ for (var rule in _rules) {
+ if (rule['condition'](userData)) {
+ return rule['recommendation'];
+ }
+ }
+ throw Exception('No matching recommendation found');
+ }
+}
diff --git a/lib/services/sync_service.dart b/lib/services/sync_service.dart
new file mode 100644
index 0000000..f46dc3c
--- /dev/null
+++ b/lib/services/sync_service.dart
@@ -0,0 +1,88 @@
+import 'package:sqflite/sqflite.dart';
+import 'package:path/path.dart';
+import 'package:http/http.dart' as http;
+import 'dart:convert';
+import 'package:your_app/services/hormone_tracker_service.dart';
+import 'package:your_app/services/api_service.dart';
+
+class SyncService {
+ static final SyncService _instance = SyncService._internal();
+ factory SyncService() => _instance;
+ SyncService._internal();
+
+ Database? _database;
+ final ApiService _apiService = ApiService(baseUrl: 'https://api.example.com', authToken: 'your_auth_token');
+
+ Future get database async {
+ if (_database != null) return _database!;
+ _database = await _initDatabase();
+ return _database!;
+ }
+
+ Future _initDatabase() async {
+ String path = join(await getDatabasesPath(), 'sync_database.db');
+ return await openDatabase(
+ path,
+ version: 1,
+ onCreate: (db, version) async {
+ await db.execute('''
+ CREATE TABLE sync_status (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ table_name TEXT,
+ last_sync TEXT
+ )
+ ''');
+ },
+ );
+ }
+
+ Future syncData() async {
+ await _syncHormones();
+ }
+
+ Future _syncHormones() async {
+ final db = await database;
+ final hormones = await db.query('hormones');
+ final response = await _apiService.postRequest('sync/hormones', {'hormones': hormones});
+
+ if (response.statusCode == 200) {
+ await db.insert(
+ 'sync_status',
+ {
+ 'table_name': 'hormones',
+ 'last_sync': DateTime.now().toIso8601String(),
+ },
+ conflictAlgorithm: ConflictAlgorithm.replace,
+ );
+ } else {
+ throw Exception('Failed to synchronize hormones');
+ }
+ }
+
+ Future checkForUpdates() async {
+ final db = await database;
+ final response = await _apiService.getRequest('updates');
+
+ if (response.statusCode == 200) {
+ final updates = json.decode(response.body);
+ for (var update in updates) {
+ if (update['table'] == 'hormones') {
+ await db.insert(
+ 'hormones',
+ update['data'],
+ conflictAlgorithm: ConflictAlgorithm.replace,
+ );
+ }
+ }
+ } else {
+ throw Exception('Failed to check for updates');
+ }
+ }
+
+ Future runPeriodicSync() async {
+ while (true) {
+ await syncData();
+ await Future.delayed(Duration(hours: 1));
+ }
+ }
+}
diff --git a/lib/widgets/about_info.dart b/lib/widgets/about_info.dart
new file mode 100644
index 0000000..d6a1c71
--- /dev/null
+++ b/lib/widgets/about_info.dart
@@ -0,0 +1,53 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class AboutInfo extends StatelessWidget {
+ final HormoneTrackerService hormoneTrackerService = HormoneTrackerService();
+
+ @override
+ Widget build(BuildContext context) {
+ return FutureBuilder>(
+ future: hormoneTrackerService.getAboutData(),
+ builder: (context, snapshot) {
+ if (snapshot.connectionState == ConnectionState.waiting) {
+ return Center(child: CircularProgressIndicator());
+ } else if (snapshot.hasError) {
+ return Center(child: Text('Error: ${snapshot.error}'));
+ } else {
+ final aboutData = snapshot.data!;
+ return Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ aboutData['appName'],
+ style: TextStyle(
+ fontSize: 24,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 16),
+ Text(aboutData['description']),
+ SizedBox(height: 16),
+ Text(
+ 'Developers:',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ...aboutData['developers'].map((developer) {
+ return ListTile(
+ title: Text(developer['name']),
+ subtitle: Text(developer['email']),
+ );
+ }).toList(),
+ ],
+ ),
+ );
+ }
+ },
+ );
+ }
+}
diff --git a/lib/widgets/body_stat_chart.dart b/lib/widgets/body_stat_chart.dart
new file mode 100644
index 0000000..2683da8
--- /dev/null
+++ b/lib/widgets/body_stat_chart.dart
@@ -0,0 +1,61 @@
+import 'package:flutter/material.dart';
+import 'package:fl_chart/fl_chart.dart';
+import 'package:your_app/models/body_stats.dart';
+
+class BodyStatChart extends StatelessWidget {
+ final List bodyStats;
+
+ BodyStatChart({required this.bodyStats});
+
+ @override
+ Widget build(BuildContext context) {
+ return LineChart(
+ LineChartData(
+ lineBarsData: [
+ LineChartBarData(
+ spots: bodyStats
+ .map((stat) => FlSpot(
+ stat.date.millisecondsSinceEpoch.toDouble(),
+ stat.weight,
+ ))
+ .toList(),
+ isCurved: true,
+ colors: [Colors.blue],
+ barWidth: 4,
+ belowBarData: BarAreaData(show: false),
+ ),
+ LineChartBarData(
+ spots: bodyStats
+ .map((stat) => FlSpot(
+ stat.date.millisecondsSinceEpoch.toDouble(),
+ stat.muscleMass,
+ ))
+ .toList(),
+ isCurved: true,
+ colors: [Colors.green],
+ barWidth: 4,
+ belowBarData: BarAreaData(show: false),
+ ),
+ LineChartBarData(
+ spots: bodyStats
+ .map((stat) => FlSpot(
+ stat.date.millisecondsSinceEpoch.toDouble(),
+ stat.fatPercentage,
+ ))
+ .toList(),
+ isCurved: true,
+ colors: [Colors.red],
+ barWidth: 4,
+ belowBarData: BarAreaData(show: false),
+ ),
+ ],
+ titlesData: FlTitlesData(
+ leftTitles: SideTitles(showTitles: true),
+ bottomTitles: SideTitles(showTitles: true),
+ ),
+ borderData: FlBorderData(show: true),
+ gridData: FlGridData(show: true),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/body_stats_card.dart b/lib/widgets/body_stats_card.dart
new file mode 100644
index 0000000..4111b37
--- /dev/null
+++ b/lib/widgets/body_stats_card.dart
@@ -0,0 +1,56 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/models/body_stats.dart';
+import 'package:your_app/services/body_stats_service.dart';
+
+class BodyStatsCard extends StatelessWidget {
+ final BodyStats bodyStats;
+ final Function(BodyStats) onEdit;
+ final Function(int) onDelete;
+
+ BodyStatsCard({
+ required this.bodyStats,
+ required this.onEdit,
+ required this.onDelete,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Body Stats',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text('Weight: ${bodyStats.weight} kg'),
+ SizedBox(height: 8),
+ Text('Muscle Mass: ${bodyStats.muscleMass} kg'),
+ SizedBox(height: 8),
+ Text('Fat Percentage: ${bodyStats.fatPercentage} %'),
+ SizedBox(height: 16),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ IconButton(
+ icon: Icon(Icons.edit),
+ onPressed: () => onEdit(bodyStats),
+ ),
+ IconButton(
+ icon: Icon(Icons.delete),
+ onPressed: () => onDelete(bodyStats.id),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/calendar_view.dart b/lib/widgets/calendar_view.dart
new file mode 100644
index 0000000..2b25474
--- /dev/null
+++ b/lib/widgets/calendar_view.dart
@@ -0,0 +1,63 @@
+import 'package:flutter/material.dart';
+import 'package:table_calendar/table_calendar.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class CalendarView extends StatefulWidget {
+ @override
+ _CalendarViewState createState() => _CalendarViewState();
+}
+
+class _CalendarViewState extends State {
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+ Map> _events = {};
+ List _selectedEvents = [];
+
+ @override
+ void initState() {
+ super.initState();
+ _loadEvents();
+ }
+
+ Future _loadEvents() async {
+ final hormones = await _hormoneTrackerService.getHormones();
+ setState(() {
+ _events = _groupEventsByDate(hormones);
+ });
+ }
+
+ Map> _groupEventsByDate(List> hormones) {
+ Map> events = {};
+ for (var hormone in hormones) {
+ DateTime date = DateTime.parse(hormone['schedule']);
+ if (events[date] == null) events[date] = [];
+ events[date]!.add(hormone);
+ }
+ return events;
+ }
+
+ void _onDaySelected(DateTime day, List events) {
+ setState(() {
+ _selectedEvents = events;
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: [
+ TableCalendar(
+ events: _events,
+ onDaySelected: _onDaySelected,
+ calendarStyle: CalendarStyle(
+ todayColor: Colors.blue,
+ selectedColor: Colors.orange,
+ ),
+ ),
+ ..._selectedEvents.map((event) => ListTile(
+ title: Text(event['name']),
+ subtitle: Text('Dosage: ${event['dosage']} - Purpose: ${event['purpose']}'),
+ )),
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/client_card.dart b/lib/widgets/client_card.dart
new file mode 100644
index 0000000..657a32a
--- /dev/null
+++ b/lib/widgets/client_card.dart
@@ -0,0 +1,57 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/models/trainer_profile.dart';
+
+class ClientCard extends StatelessWidget {
+ final Client client;
+ final Function(Client) onEdit;
+ final Function(int) onDelete;
+
+ ClientCard({
+ required this.client,
+ required this.onEdit,
+ required this.onDelete,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ client.name,
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text('Email: ${client.email}'),
+ SizedBox(height: 8),
+ Text('Phone: ${client.phone}'),
+ SizedBox(height: 8),
+ Text('Address: ${client.address}'),
+ SizedBox(height: 8),
+ Text('Schedules:'),
+ ...client.schedules.map((schedule) => Text(schedule.name)).toList(),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ IconButton(
+ icon: Icon(Icons.edit),
+ onPressed: () => onEdit(client),
+ ),
+ IconButton(
+ icon: Icon(Icons.delete),
+ onPressed: () => onDelete(client.id),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/custom_button.dart b/lib/widgets/custom_button.dart
new file mode 100644
index 0000000..e82f0b3
--- /dev/null
+++ b/lib/widgets/custom_button.dart
@@ -0,0 +1,25 @@
+import 'package:flutter/material.dart';
+
+class CustomButton extends StatelessWidget {
+ final String text;
+ final VoidCallback onPressed;
+
+ CustomButton({required this.text, required this.onPressed});
+
+ @override
+ Widget build(BuildContext context) {
+ return ElevatedButton(
+ onPressed: onPressed,
+ style: ElevatedButton.styleFrom(
+ padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
+ textStyle: TextStyle(fontSize: 16.0),
+ primary: Theme.of(context).primaryColor,
+ onPrimary: Colors.white,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ ),
+ ),
+ child: Text(text),
+ );
+ }
+}
diff --git a/lib/widgets/custom_card.dart b/lib/widgets/custom_card.dart
new file mode 100644
index 0000000..895933c
--- /dev/null
+++ b/lib/widgets/custom_card.dart
@@ -0,0 +1,27 @@
+import 'package:flutter/material.dart';
+
+class CustomCard extends StatelessWidget {
+ final Widget child;
+ final EdgeInsetsGeometry padding;
+ final EdgeInsetsGeometry margin;
+ final Color color;
+
+ CustomCard({
+ required this.child,
+ this.padding = const EdgeInsets.all(16.0),
+ this.margin = const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
+ this.color = Colors.white,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ margin: margin,
+ color: color,
+ child: Padding(
+ padding: padding,
+ child: child,
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/diet_card.dart b/lib/widgets/diet_card.dart
new file mode 100644
index 0000000..780cede
--- /dev/null
+++ b/lib/widgets/diet_card.dart
@@ -0,0 +1,57 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/models/diet_plan.dart';
+
+class DietCard extends StatelessWidget {
+ final DietPlan dietPlan;
+ final Function(DietPlan) onEdit;
+ final Function(int) onDelete;
+
+ DietCard({
+ required this.dietPlan,
+ required this.onEdit,
+ required this.onDelete,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Diet Plan',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text('Calories: ${dietPlan.calories}'),
+ SizedBox(height: 8),
+ Text('Protein: ${dietPlan.protein}g'),
+ SizedBox(height: 8),
+ Text('Carbs: ${dietPlan.carbs}g'),
+ SizedBox(height: 8),
+ Text('Fats: ${dietPlan.fats}g'),
+ SizedBox(height: 16),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ IconButton(
+ icon: Icon(Icons.edit),
+ onPressed: () => onEdit(dietPlan),
+ ),
+ IconButton(
+ icon: Icon(Icons.delete),
+ onPressed: () => onDelete(dietPlan.id),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/help_resource.dart b/lib/widgets/help_resource.dart
new file mode 100644
index 0000000..42b73d1
--- /dev/null
+++ b/lib/widgets/help_resource.dart
@@ -0,0 +1,46 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class HelpResource extends StatelessWidget {
+ final String name;
+ final String description;
+ final String link;
+ final HormoneTrackerService hormoneTrackerService;
+
+ HelpResource({
+ required this.name,
+ required this.description,
+ required this.link,
+ required this.hormoneTrackerService,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ name,
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text(description),
+ SizedBox(height: 8),
+ TextButton(
+ onPressed: () {
+ // Open the help resource link
+ },
+ child: Text('Learn More'),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/hormone_card.dart b/lib/widgets/hormone_card.dart
new file mode 100644
index 0000000..283d0bd
--- /dev/null
+++ b/lib/widgets/hormone_card.dart
@@ -0,0 +1,42 @@
+import 'package:flutter/material.dart';
+
+class HormoneCard extends StatelessWidget {
+ final String name;
+ final double dosage;
+ final String schedule;
+ final String purpose;
+
+ HormoneCard({
+ required this.name,
+ required this.dosage,
+ required this.schedule,
+ required this.purpose,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ name,
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text('Dosage: $dosage'),
+ SizedBox(height: 8),
+ Text('Schedule: $schedule'),
+ SizedBox(height: 8),
+ Text('Purpose: $purpose'),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/messaging_system.dart b/lib/widgets/messaging_system.dart
new file mode 100644
index 0000000..9274ab1
--- /dev/null
+++ b/lib/widgets/messaging_system.dart
@@ -0,0 +1,78 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class MessagingSystem extends StatefulWidget {
+ final Function(int, String) onSendMessage;
+
+ MessagingSystem({required this.onSendMessage});
+
+ @override
+ _MessagingSystemState createState() => _MessagingSystemState();
+}
+
+class _MessagingSystemState extends State {
+ final TextEditingController _messageController = TextEditingController();
+ final HormoneTrackerService _hormoneTrackerService = HormoneTrackerService();
+ List> _messages = [];
+
+ @override
+ void initState() {
+ super.initState();
+ _loadMessages();
+ }
+
+ Future _loadMessages() async {
+ final messages = await _hormoneTrackerService.getMessages();
+ setState(() {
+ _messages = messages;
+ });
+ }
+
+ void _sendMessage() {
+ final message = _messageController.text;
+ if (message.isNotEmpty) {
+ widget.onSendMessage(1, message); // Assuming clientId is 1 for now
+ _messageController.clear();
+ _loadMessages();
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: [
+ Expanded(
+ child: ListView.builder(
+ itemCount: _messages.length,
+ itemBuilder: (context, index) {
+ final message = _messages[index];
+ return ListTile(
+ title: Text(message['content']),
+ subtitle: Text(message['timestamp']),
+ );
+ },
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Row(
+ children: [
+ Expanded(
+ child: TextField(
+ controller: _messageController,
+ decoration: InputDecoration(
+ hintText: 'Enter your message',
+ ),
+ ),
+ ),
+ IconButton(
+ icon: Icon(Icons.send),
+ onPressed: _sendMessage,
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/nutrition_plan_card.dart b/lib/widgets/nutrition_plan_card.dart
new file mode 100644
index 0000000..02bffd6
--- /dev/null
+++ b/lib/widgets/nutrition_plan_card.dart
@@ -0,0 +1,132 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/models/nutrition_plan.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class NutritionPlanCard extends StatelessWidget {
+ final NutritionPlan nutritionPlan;
+ final Function(NutritionPlan) onEdit;
+ final Function(int) onDelete;
+ final HormoneTrackerService hormoneTrackerService;
+
+ NutritionPlanCard({
+ required this.nutritionPlan,
+ required this.onEdit,
+ required this.onDelete,
+ required this.hormoneTrackerService,
+ });
+
+ void _editNutritionPlan(BuildContext context) {
+ final nameController = TextEditingController(text: nutritionPlan.name);
+ final caloriesController = TextEditingController(text: nutritionPlan.calories.toString());
+ final proteinController = TextEditingController(text: nutritionPlan.protein.toString());
+ final carbsController = TextEditingController(text: nutritionPlan.carbs.toString());
+ final fatsController = TextEditingController(text: nutritionPlan.fats.toString());
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Nutrition Plan'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: caloriesController,
+ decoration: InputDecoration(labelText: 'Calories'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: proteinController,
+ decoration: InputDecoration(labelText: 'Protein (g)'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: carbsController,
+ decoration: InputDecoration(labelText: 'Carbs (g)'),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: fatsController,
+ decoration: InputDecoration(labelText: 'Fats (g)'),
+ keyboardType: TextInputType.number,
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ onEdit(
+ NutritionPlan(
+ id: nutritionPlan.id,
+ name: nameController.text,
+ calories: int.parse(caloriesController.text),
+ protein: int.parse(proteinController.text),
+ carbs: int.parse(carbsController.text),
+ fats: int.parse(fatsController.text),
+ ),
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Nutrition Plan',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text('Name: ${nutritionPlan.name}'),
+ SizedBox(height: 8),
+ Text('Calories: ${nutritionPlan.calories}'),
+ SizedBox(height: 8),
+ Text('Protein: ${nutritionPlan.protein}g'),
+ SizedBox(height: 8),
+ Text('Carbs: ${nutritionPlan.carbs}g'),
+ SizedBox(height: 8),
+ Text('Fats: ${nutritionPlan.fats}g'),
+ SizedBox(height: 16),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ IconButton(
+ icon: Icon(Icons.edit),
+ onPressed: () => _editNutritionPlan(context),
+ ),
+ IconButton(
+ icon: Icon(Icons.delete),
+ onPressed: () => onDelete(nutritionPlan.id),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/photo_comparison_widget.dart b/lib/widgets/photo_comparison_widget.dart
new file mode 100644
index 0000000..c827277
--- /dev/null
+++ b/lib/widgets/photo_comparison_widget.dart
@@ -0,0 +1,24 @@
+import 'package:flutter/material.dart';
+
+class PhotoComparisonWidget extends StatelessWidget {
+ final String beforePhoto;
+ final String afterPhoto;
+
+ PhotoComparisonWidget({
+ required this.beforePhoto,
+ required this.afterPhoto,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: [
+ Text('Before'),
+ Image.network(beforePhoto),
+ SizedBox(height: 16),
+ Text('After'),
+ Image.network(afterPhoto),
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/progress_comparison.dart b/lib/widgets/progress_comparison.dart
new file mode 100644
index 0000000..3cd178a
--- /dev/null
+++ b/lib/widgets/progress_comparison.dart
@@ -0,0 +1,46 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/models/body_stats.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class ProgressComparison extends StatelessWidget {
+ final List bodyStats;
+ final String beforePhoto;
+ final String afterPhoto;
+ final HormoneTrackerService hormoneTrackerService;
+
+ ProgressComparison({
+ required this.bodyStats,
+ required this.beforePhoto,
+ required this.afterPhoto,
+ required this.hormoneTrackerService,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: [
+ Text('Progress Comparison', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
+ SizedBox(height: 16),
+ Text('Before'),
+ Image.network(beforePhoto),
+ SizedBox(height: 16),
+ Text('After'),
+ Image.network(afterPhoto),
+ SizedBox(height: 16),
+ Text('Key Metrics', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
+ SizedBox(height: 8),
+ Text('Weight: ${bodyStats.isNotEmpty ? bodyStats.last.weight : 'N/A'}'),
+ Text('Muscle Mass: ${bodyStats.isNotEmpty ? bodyStats.last.muscleMass : 'N/A'}'),
+ Text('Fat Percentage: ${bodyStats.isNotEmpty ? bodyStats.last.fatPercentage : 'N/A'}'),
+ SizedBox(height: 16),
+ ElevatedButton(
+ onPressed: () {
+ // Fetch progress data from hormoneTrackerService
+ hormoneTrackerService.getHormones();
+ },
+ child: Text('Fetch Progress Data'),
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/progress_graph.dart b/lib/widgets/progress_graph.dart
new file mode 100644
index 0000000..a97d040
--- /dev/null
+++ b/lib/widgets/progress_graph.dart
@@ -0,0 +1,61 @@
+import 'package:flutter/material.dart';
+import 'package:fl_chart/fl_chart.dart';
+import 'package:your_app/models/body_stats.dart';
+
+class ProgressGraph extends StatelessWidget {
+ final List bodyStats;
+
+ ProgressGraph({required this.bodyStats});
+
+ @override
+ Widget build(BuildContext context) {
+ return LineChart(
+ LineChartData(
+ lineBarsData: [
+ LineChartBarData(
+ spots: bodyStats
+ .map((stat) => FlSpot(
+ stat.date.millisecondsSinceEpoch.toDouble(),
+ stat.weight,
+ ))
+ .toList(),
+ isCurved: true,
+ colors: [Colors.blue],
+ barWidth: 4,
+ belowBarData: BarAreaData(show: false),
+ ),
+ LineChartBarData(
+ spots: bodyStats
+ .map((stat) => FlSpot(
+ stat.date.millisecondsSinceEpoch.toDouble(),
+ stat.muscleMass,
+ ))
+ .toList(),
+ isCurved: true,
+ colors: [Colors.green],
+ barWidth: 4,
+ belowBarData: BarAreaData(show: false),
+ ),
+ LineChartBarData(
+ spots: bodyStats
+ .map((stat) => FlSpot(
+ stat.date.millisecondsSinceEpoch.toDouble(),
+ stat.fatPercentage,
+ ))
+ .toList(),
+ isCurved: true,
+ colors: [Colors.red],
+ barWidth: 4,
+ belowBarData: BarAreaData(show: false),
+ ),
+ ],
+ titlesData: FlTitlesData(
+ leftTitles: SideTitles(showTitles: true),
+ bottomTitles: SideTitles(showTitles: true),
+ ),
+ borderData: FlBorderData(show: true),
+ gridData: FlGridData(show: true),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/progress_visualization.dart b/lib/widgets/progress_visualization.dart
new file mode 100644
index 0000000..1ef3481
--- /dev/null
+++ b/lib/widgets/progress_visualization.dart
@@ -0,0 +1,61 @@
+import 'package:flutter/material.dart';
+import 'package:fl_chart/fl_chart.dart';
+import 'package:your_app/models/body_stats.dart';
+
+class ProgressVisualization extends StatelessWidget {
+ final List bodyStats;
+
+ ProgressVisualization({required this.bodyStats});
+
+ @override
+ Widget build(BuildContext context) {
+ return LineChart(
+ LineChartData(
+ lineBarsData: [
+ LineChartBarData(
+ spots: bodyStats
+ .map((stat) => FlSpot(
+ stat.date.millisecondsSinceEpoch.toDouble(),
+ stat.weight,
+ ))
+ .toList(),
+ isCurved: true,
+ colors: [Colors.blue],
+ barWidth: 4,
+ belowBarData: BarAreaData(show: false),
+ ),
+ LineChartBarData(
+ spots: bodyStats
+ .map((stat) => FlSpot(
+ stat.date.millisecondsSinceEpoch.toDouble(),
+ stat.muscleMass,
+ ))
+ .toList(),
+ isCurved: true,
+ colors: [Colors.green],
+ barWidth: 4,
+ belowBarData: BarAreaData(show: false),
+ ),
+ LineChartBarData(
+ spots: bodyStats
+ .map((stat) => FlSpot(
+ stat.date.millisecondsSinceEpoch.toDouble(),
+ stat.fatPercentage,
+ ))
+ .toList(),
+ isCurved: true,
+ colors: [Colors.red],
+ barWidth: 4,
+ belowBarData: BarAreaData(show: false),
+ ),
+ ],
+ titlesData: FlTitlesData(
+ leftTitles: SideTitles(showTitles: true),
+ bottomTitles: SideTitles(showTitles: true),
+ ),
+ borderData: FlBorderData(show: true),
+ gridData: FlGridData(show: true),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/reminder_card.dart b/lib/widgets/reminder_card.dart
new file mode 100644
index 0000000..0a1b1e0
--- /dev/null
+++ b/lib/widgets/reminder_card.dart
@@ -0,0 +1,110 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class ReminderCard extends StatelessWidget {
+ final int id;
+ final String name;
+ final String schedule;
+ final String purpose;
+ final HormoneTrackerService hormoneTrackerService;
+
+ ReminderCard({
+ required this.id,
+ required this.name,
+ required this.schedule,
+ required this.purpose,
+ required this.hormoneTrackerService,
+ });
+
+ void _editReminder(BuildContext context) {
+ final nameController = TextEditingController(text: name);
+ final scheduleController = TextEditingController(text: schedule);
+ final purposeController = TextEditingController(text: purpose);
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Reminder'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ hormoneTrackerService.editReminder(
+ id,
+ nameController.text,
+ scheduleController.text,
+ purposeController.text,
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ name,
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text('Schedule: $schedule'),
+ SizedBox(height: 8),
+ Text('Purpose: $purpose'),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ IconButton(
+ icon: Icon(Icons.edit),
+ onPressed: () => _editReminder(context),
+ ),
+ IconButton(
+ icon: Icon(Icons.delete),
+ onPressed: () {
+ hormoneTrackerService.deleteReminder(id);
+ },
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/settings_menu.dart b/lib/widgets/settings_menu.dart
new file mode 100644
index 0000000..7fc11e3
--- /dev/null
+++ b/lib/widgets/settings_menu.dart
@@ -0,0 +1,52 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class SettingsMenu extends StatelessWidget {
+ final HormoneTrackerService hormoneTrackerService;
+
+ SettingsMenu({required this.hormoneTrackerService});
+
+ @override
+ Widget build(BuildContext context) {
+ return ListView(
+ children: [
+ ListTile(
+ title: Text('Notification Settings'),
+ onTap: () {
+ // Navigate to notification settings screen
+ },
+ ),
+ ListTile(
+ title: Text('Profile Settings'),
+ onTap: () {
+ // Navigate to profile settings screen
+ },
+ ),
+ ListTile(
+ title: Text('App Theme'),
+ onTap: () {
+ // Navigate to app theme settings screen
+ },
+ ),
+ ListTile(
+ title: Text('Privacy Policy'),
+ onTap: () {
+ // Navigate to privacy policy screen
+ },
+ ),
+ ListTile(
+ title: Text('Terms of Service'),
+ onTap: () {
+ // Navigate to terms of service screen
+ },
+ ),
+ ListTile(
+ title: Text('Logout'),
+ onTap: () {
+ // Handle logout
+ },
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/settings_option.dart b/lib/widgets/settings_option.dart
new file mode 100644
index 0000000..1c0ca2e
--- /dev/null
+++ b/lib/widgets/settings_option.dart
@@ -0,0 +1,82 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class SettingsOption extends StatelessWidget {
+ final String name;
+ final String value;
+ final String description;
+ final HormoneTrackerService hormoneTrackerService;
+
+ SettingsOption({
+ required this.name,
+ required this.value,
+ required this.description,
+ required this.hormoneTrackerService,
+ });
+
+ void _editSetting(BuildContext context) {
+ final valueController = TextEditingController(text: value);
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Setting'),
+ content: TextField(
+ controller: valueController,
+ decoration: InputDecoration(labelText: 'Value'),
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ hormoneTrackerService.updateSetting(name, valueController.text);
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ name,
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text('Value: $value'),
+ SizedBox(height: 8),
+ Text('Description: $description'),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ IconButton(
+ icon: Icon(Icons.edit),
+ onPressed: () => _editSetting(context),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/training_plan_card.dart b/lib/widgets/training_plan_card.dart
new file mode 100644
index 0000000..f376c0f
--- /dev/null
+++ b/lib/widgets/training_plan_card.dart
@@ -0,0 +1,107 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/models/training_plan.dart';
+import 'package:your_app/services/hormone_tracker_service.dart';
+
+class TrainingPlanCard extends StatelessWidget {
+ final TrainingPlan trainingPlan;
+ final Function(TrainingPlan) onEdit;
+ final Function(int) onDelete;
+ final HormoneTrackerService hormoneTrackerService;
+
+ TrainingPlanCard({
+ required this.trainingPlan,
+ required this.onEdit,
+ required this.onDelete,
+ required this.hormoneTrackerService,
+ });
+
+ void _editTrainingPlan(BuildContext context) {
+ final nameController = TextEditingController(text: trainingPlan.name);
+ final scheduleController = TextEditingController(text: trainingPlan.schedule);
+ final purposeController = TextEditingController(text: trainingPlan.purpose);
+
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: Text('Edit Training Plan'),
+ content: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ TextField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: 'Name'),
+ ),
+ TextField(
+ controller: scheduleController,
+ decoration: InputDecoration(labelText: 'Schedule'),
+ ),
+ TextField(
+ controller: purposeController,
+ decoration: InputDecoration(labelText: 'Purpose'),
+ ),
+ ],
+ ),
+ actions: [
+ TextButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ hormoneTrackerService.editTrainingPlan(
+ trainingPlan.id,
+ nameController.text,
+ scheduleController.text,
+ purposeController.text,
+ );
+ Navigator.of(context).pop();
+ },
+ child: Text('Save'),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ trainingPlan.name,
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 8),
+ Text('Schedule: ${trainingPlan.schedule}'),
+ SizedBox(height: 8),
+ Text('Purpose: ${trainingPlan.purpose}'),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ IconButton(
+ icon: Icon(Icons.edit),
+ onPressed: () => _editTrainingPlan(context),
+ ),
+ IconButton(
+ icon: Icon(Icons.delete),
+ onPressed: () => onDelete(trainingPlan.id),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/main.dart b/main.dart
new file mode 100644
index 0000000..e0730ac
--- /dev/null
+++ b/main.dart
@@ -0,0 +1,37 @@
+import 'package:flutter/material.dart';
+import 'package:your_app/screens/dashboard_screen.dart';
+
+void main() {
+ runApp(MyApp());
+}
+
+class MyApp extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'Bodybuilding Trainer and Nutrition App',
+ theme: ThemeData(
+ primarySwatch: Colors.blue,
+ visualDensity: VisualDensity.adaptivePlatformDensity,
+ textTheme: TextTheme(
+ headline1: TextStyle(fontSize: 32.0, fontWeight: FontWeight.bold),
+ headline6: TextStyle(fontSize: 20.0, fontStyle: FontStyle.italic),
+ bodyText2: TextStyle(fontSize: 14.0, fontFamily: 'Hind'),
+ ),
+ cardTheme: CardTheme(
+ margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ ),
+ ),
+ buttonTheme: ButtonThemeData(
+ padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ ),
+ ),
+ ),
+ home: DashboardScreen(),
+ );
+ }
+}