Merge branch 'Enzo'
continuous-integration/drone/push Build is passing Details

profile
Enzo 1 year ago
commit 8834a0e780

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import '../common/colo_extension.dart';
import '../../common/colo_extension.dart';
enum RoundButtonType { bgGradient, bgSGradient, textGradient }

@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/stats.dart';
class ContainerStats extends StatelessWidget {
const ContainerStats(this.value, this.designation, this.icon, {Key? key})
: super(key: key);
final String value;
final String designation;
final IconData icon;
@override
Widget build(BuildContext context) {
return Container(
height: 100,
width: 100,
padding: const EdgeInsets.all(8),
margin: const EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: const Color(0xffe1e1e1),
),
boxShadow: const [
BoxShadow(
color: Colors.black12,
offset: Offset(3, 3),
blurRadius: 3,
),
]),
child: Stack(
children: [
StatIcon(
icon: icon,
iconColor: TColor.white,
iconBackground: TColor.secondaryColor1,
),
Align(
alignment: Alignment.bottomLeft,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
designation,
style: const TextStyle(fontSize: 10),
),
Text(
value,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w800,
),
),
],
),
)
],
),
);
}
}

@ -0,0 +1,71 @@
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/container/container_stats.dart';
class LigneContainerStats extends StatelessWidget {
const LigneContainerStats(this.value1, this.value2, this.value3,
this.designation1, this.designation2, this.designation3,
this.icon1, this.icon2, this.icon3,
{Key? key})
: super(key: key);
final String value1;
final String value2;
final String value3;
final String designation1;
final String designation2;
final String designation3;
final IconData icon1;
final IconData icon2;
final IconData icon3;
@override
Widget build(BuildContext context) {
return Column(
children: [
Divider(height: 30),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
children: [
const Text(
'Statistiques',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w800,
),
),
SizedBox(width: 8),
Icon(
Icons.pie_chart_rounded,
size: 15,
color: TColor.secondaryColor1,
),
],
),
),
SizedBox(height: 20),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child:Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ContainerStats(value1, designation1, icon1),
const SizedBox(width: 20),
ContainerStats(value2, designation2, icon2),
const SizedBox(width: 20),
ContainerStats(value3, designation3, icon3),
],)
),
Divider(height: 30),
],
);
}
}

@ -0,0 +1,70 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/modele/utile/home_view/data_home_view.dart';
class GraphAltitudeByTime extends StatefulWidget {
final Size media;
final DataHomeView data;
const GraphAltitudeByTime(this.media, this.data, {Key? key})
: super(key: key);
@override
State<GraphAltitudeByTime> createState() => _GraphAltitudeByTime();
}
class _GraphAltitudeByTime extends State<GraphAltitudeByTime> {
@override
Widget build(BuildContext context) {
final double maxY =
context.watch<User>().listActivity[0].getMaxAltitude() + 2;
final double minY =
context.watch<User>().listActivity[0].getMinAltitude() - 2;
final lineBarsData = [
LineChartBarData(
spots: widget.data.altitudeSeconde,
isCurved: false,
gradient: LinearGradient(
colors: TColor.primaryG,
),
dotData: const FlDotData(show: false))
];
return Container(
padding: const EdgeInsets.only(left: 15),
height: widget.media.width * 0.5,
width: double.maxFinite,
child: LineChart(LineChartData(
lineBarsData: lineBarsData,
borderData: FlBorderData(show: false),
maxY: maxY,
minY: minY,
gridData: FlGridData(
drawVerticalLine: false,
drawHorizontalLine: true,
horizontalInterval: (maxY - minY) / 5,
getDrawingHorizontalLine: (value) {
return FlLine(
color: TColor.gray.withOpacity(0.15),
strokeWidth: 2,
);
}),
titlesData: FlTitlesData(
leftTitles: const AxisTitles(),
topTitles: const AxisTitles(),
bottomTitles: const AxisTitles(),
rightTitles: AxisTitles(
sideTitles: SideTitles(
reservedSize: 60,
showTitles: true,
getTitlesWidget: (value, meta) {
return Text("${double.parse(value.toStringAsFixed(2))} m");
},
)),
))));
}
}

@ -0,0 +1,223 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/modele/utile/home_view/data_home_view.dart';
class GraphBpmAndSpeedByTime extends StatefulWidget {
final Size media;
final DataHomeView data;
const GraphBpmAndSpeedByTime(this.media, this.data, {Key? key})
: super(key: key);
@override
State<GraphBpmAndSpeedByTime> createState() => _GraphBpmAndSpeedByTime();
}
class _GraphBpmAndSpeedByTime extends State<GraphBpmAndSpeedByTime> {
TextEditingController bpmController = TextEditingController();
List<int> showingTooltipOnSpots = [0];
SideTitles get rightTitles => SideTitles(
getTitlesWidget: rightTitleWidgets,
showTitles: true,
interval: 20,
reservedSize: 40,
);
Widget rightTitleWidgets(double value, TitleMeta meta) {
String text;
switch (value.toInt()) {
case 0:
text = '0%';
break;
case 20:
text = '20%';
break;
case 40:
text = '40%';
break;
case 60:
text = '60%';
break;
case 80:
text = '80%';
break;
case 100:
text = '100%';
break;
default:
return Container();
}
return Text(text,
style: TextStyle(
color: TColor.gray,
fontSize: 12,
),
textAlign: TextAlign.center);
}
List<LineChartBarData> get lineBarsData1 => [
lineChartBarData1_1,
lineChartBarData1_2,
];
LineChartBarData get lineChartBarData1_1 => LineChartBarData(
isCurved: true,
gradient: LinearGradient(colors: [
TColor.primaryColor2.withOpacity(0.5),
TColor.primaryColor1.withOpacity(0.5),
]),
barWidth: 4,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(show: false),
spots: widget.data.vitesseSecondes,
);
LineChartBarData get lineChartBarData1_2 => LineChartBarData(
isCurved: true,
gradient: LinearGradient(colors: [
TColor.secondaryColor2.withOpacity(0.5),
TColor.secondaryColor1.withOpacity(0.5),
]),
barWidth: 2,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(
show: false,
),
spots: widget.data.bpmSecondes2,
);
@override
Widget build(BuildContext context) {
final lineBarsData = [
LineChartBarData(
spots: widget.data.bpmSecondes,
isCurved: false,
barWidth: 2,
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(colors: [
TColor.secondaryColor1.withOpacity(0.4),
TColor.secondaryColor2.withOpacity(0.1),
], begin: Alignment.topCenter, end: Alignment.bottomCenter),
),
dotData: const FlDotData(show: false),
gradient: LinearGradient(
colors: TColor.secondaryG,
),
),
];
final tooltipsOnBar = lineBarsData[0];
return Container(
padding: const EdgeInsets.only(left: 15),
height: widget.media.width * 0.3,
width: double.maxFinite,
child: LineChart(
LineChartData(
showingTooltipIndicators: showingTooltipOnSpots.map((index) {
return ShowingTooltipIndicators([
LineBarSpot(
tooltipsOnBar,
lineBarsData.indexOf(tooltipsOnBar),
tooltipsOnBar.spots[index],
),
]);
}).toList(),
lineTouchData: LineTouchData(
enabled: true,
handleBuiltInTouches: false,
touchCallback: (FlTouchEvent event, LineTouchResponse? response) {
if (response == null || response.lineBarSpots == null) {
return;
}
if (event is FlTapUpEvent) {
final spotIndex = response.lineBarSpots!.first.spotIndex;
showingTooltipOnSpots.clear();
setState(() {
showingTooltipOnSpots.add(spotIndex);
});
}
},
mouseCursorResolver:
(FlTouchEvent event, LineTouchResponse? response) {
if (response == null || response.lineBarSpots == null) {
return SystemMouseCursors.basic;
}
return SystemMouseCursors.click;
},
getTouchedSpotIndicator:
(LineChartBarData barData, List<int> spotIndexes) {
return spotIndexes.map((index) {
return TouchedSpotIndicatorData(
const FlLine(
color: Colors.transparent,
),
FlDotData(
show: true,
getDotPainter: (spot, percent, barData, index) =>
FlDotCirclePainter(
radius: 3,
color: Colors.white,
strokeWidth: 3,
strokeColor: TColor.secondaryColor1,
),
),
);
}).toList();
},
touchTooltipData: LineTouchTooltipData(
tooltipBgColor: TColor.secondaryColor1,
tooltipRoundedRadius: 20,
getTooltipItems: (List<LineBarSpot> lineBarsSpot) {
return lineBarsSpot.map((lineBarSpot) {
return LineTooltipItem(
"Seconde ${lineBarSpot.x.toInt() / 10} ",
const TextStyle(
color: Colors.white,
fontSize: 10,
fontWeight: FontWeight.bold,
),
);
}).toList();
},
),
),
lineBarsData: lineBarsData1,
minY: 0,
maxY: 110,
titlesData: FlTitlesData(
show: true,
leftTitles: const AxisTitles(),
topTitles: const AxisTitles(),
bottomTitles: const AxisTitles(),
rightTitles: AxisTitles(
sideTitles: rightTitles,
)),
gridData: FlGridData(
show: true,
drawHorizontalLine: true,
horizontalInterval: 25,
drawVerticalLine: false,
getDrawingHorizontalLine: (value) {
return FlLine(
color: TColor.gray.withOpacity(0.15),
strokeWidth: 2,
);
},
),
borderData: FlBorderData(
show: true,
border: Border.all(
color: Colors.transparent,
),
),
),
));
}
}

@ -0,0 +1,213 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/modele/utile/home_view/data_home_view.dart';
class GraphBpmByTime extends StatefulWidget {
final Size media;
final DataHomeView data;
const GraphBpmByTime(this.media, this.data, {Key? key}) : super(key: key);
@override
State<GraphBpmByTime> createState() => _GraphBpmByTime();
}
class _GraphBpmByTime extends State<GraphBpmByTime> {
TextEditingController bpmController = TextEditingController();
// Il faut chercher à le suprimer
List<int> showingTooltipOnSpots = [0];
List<LineChartBarData> get lineBarsData1 => [
lineChartBarData1_1,
lineChartBarData1_2,
];
LineChartBarData get lineChartBarData1_1 => LineChartBarData(
isCurved: true,
gradient: LinearGradient(colors: [
TColor.primaryColor2.withOpacity(0.5),
TColor.primaryColor1.withOpacity(0.5),
]),
barWidth: 4,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(show: false),
spots: widget.data.vitesseSecondes,
);
LineChartBarData get lineChartBarData1_2 => LineChartBarData(
isCurved: true,
gradient: LinearGradient(colors: [
TColor.secondaryColor2.withOpacity(0.5),
TColor.secondaryColor1.withOpacity(0.5),
]),
barWidth: 2,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(
show: false,
),
spots: widget.data.bpmSecondes2,
);
@override
Widget build(BuildContext context) {
Size media = MediaQuery.of(context).size;
final lineBarsData = [
LineChartBarData(
spots: widget.data.bpmSecondes,
isCurved: false,
barWidth: 2,
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(colors: [
TColor.secondaryColor1.withOpacity(0.4),
TColor.secondaryColor2.withOpacity(0.1),
], begin: Alignment.topCenter, end: Alignment.bottomCenter),
),
dotData: const FlDotData(show: false),
gradient: LinearGradient(
colors: TColor.secondaryG,
),
),
];
final tooltipsOnBar = lineBarsData[0];
return ClipRRect(
borderRadius: BorderRadius.circular(25),
child: Container(
height: media.height * 0.3,
width: double.maxFinite,
decoration: BoxDecoration(
color: TColor.primaryColor2.withOpacity(0.3),
borderRadius: BorderRadius.circular(25),
),
child: Stack(
alignment: Alignment.topLeft,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Rythme cardiaque",
style: TextStyle(
color: TColor.black,
fontSize: 16,
fontWeight: FontWeight.w700),
),
TextField(
controller: bpmController,
readOnly: true,
style: TextStyle(
color: TColor.primaryColor1.withOpacity(0.8),
fontWeight: FontWeight.w700,
fontSize: 18),
decoration: const InputDecoration(
border: InputBorder
.none, // Ajoutez cette ligne pour supprimer la bordure
),
),
],
),
),
LineChart(
LineChartData(
showingTooltipIndicators: showingTooltipOnSpots.map((index) {
return ShowingTooltipIndicators([
LineBarSpot(
tooltipsOnBar,
lineBarsData.indexOf(tooltipsOnBar),
tooltipsOnBar.spots[index],
),
]);
}).toList(),
lineTouchData: LineTouchData(
enabled: true,
handleBuiltInTouches: false,
touchCallback:
(FlTouchEvent event, LineTouchResponse? response) {
if (response == null || response.lineBarSpots == null) {
return;
}
if (event is FlTapUpEvent) {
final spotIndex = response.lineBarSpots!.first.spotIndex;
showingTooltipOnSpots.clear();
setState(() {
showingTooltipOnSpots.add(spotIndex);
});
}
},
mouseCursorResolver:
(FlTouchEvent event, LineTouchResponse? response) {
if (response == null || response.lineBarSpots == null) {
return SystemMouseCursors.basic;
}
return SystemMouseCursors.click;
},
getTouchedSpotIndicator:
(LineChartBarData barData, List<int> spotIndexes) {
return spotIndexes.map((index) {
return TouchedSpotIndicatorData(
FlLine(
color: TColor.secondaryColor1,
),
FlDotData(
show: true,
getDotPainter: (spot, percent, barData, index) =>
FlDotCirclePainter(
radius: 3,
color: Colors.white,
strokeWidth: 3,
strokeColor: TColor.secondaryColor1,
),
),
);
}).toList();
},
touchTooltipData: LineTouchTooltipData(
tooltipBgColor: TColor.secondaryColor1,
tooltipRoundedRadius: 20,
getTooltipItems: (List<LineBarSpot> lineBarsSpot) {
return lineBarsSpot.map((lineBarSpot) {
bpmController.text = "${lineBarSpot.y} BPM";
return LineTooltipItem(
"Seconde ${lineBarSpot.x.toInt() / 10}",
const TextStyle(
color: Colors.white,
fontSize: 10,
fontWeight: FontWeight.bold,
),
);
}).toList();
},
),
),
lineBarsData: lineBarsData,
minY: 50,
maxY: 250,
titlesData: const FlTitlesData(
show: false,
),
gridData: const FlGridData(show: false),
borderData: FlBorderData(
show: true,
border: Border.all(
color: Colors.transparent,
),
),
),
)
],
),
),
);
}
}

@ -41,12 +41,12 @@ class Stats extends StatelessWidget {
Text.rich(
TextSpan(
text: value,
style: TextStyle(
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w900,
),
children: [
TextSpan(text: ' '),
const TextSpan(text: ' '),
TextSpan(
text: unit,
style: TextStyle(
@ -56,10 +56,10 @@ class Stats extends StatelessWidget {
),
]),
),
SizedBox(height: 6),
const SizedBox(height: 6),
Text(
label,
style: TextStyle(
style: const TextStyle(
fontSize: 10,
fontWeight: FontWeight.w500,
),

@ -1,5 +1,5 @@
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/helpers.dart';
import 'package:smartfit_app_mobile/common_widget/not_use/helpers.dart';
import 'package:flutter/material.dart';
class Dates extends StatelessWidget {
@ -45,7 +45,7 @@ class DateBox extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5),
decoration: BoxDecoration(
gradient: active
? LinearGradient(colors: [
? LinearGradient(colors: [
TColor.primaryColor2,
TColor.primaryColor1,
], begin: Alignment.topCenter)
@ -77,4 +77,4 @@ class DateBox extends StatelessWidget {
),
);
}
}
}

@ -1,8 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import '../common/colo_extension.dart';
import '../../common/colo_extension.dart';
class OnBoardingPage extends StatelessWidget {
final Map pObj;
@ -10,10 +9,8 @@ class OnBoardingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
return
SizedBox(
var media = MediaQuery.of(context).size;
return SizedBox(
width: media.width,
height: media.height,
child: Column(
@ -51,4 +48,4 @@ class OnBoardingPage extends StatelessWidget {
),
);
}
}
}

@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/view/home/notification_view.dart';
class EnteteHomeView extends StatelessWidget {
const EnteteHomeView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Bienvenue,",
style: TextStyle(color: TColor.gray, fontSize: 12),
),
Text(
"Benjelloun Othmane",
style: TextStyle(
color: TColor.black,
fontSize: 20,
fontWeight: FontWeight.w700),
),
],
),
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const NotificationView(),
),
);
},
icon: Image.asset(
"assets/img/notification_active.png",
width: 25,
height: 25,
fit: BoxFit.fitHeight,
))
],
);
}
}

@ -13,7 +13,8 @@ class Stats extends StatelessWidget {
.getTotalCalorie();
String heartrate = Provider.of<User>(context, listen: false)
.listActivity[0]
.getTotalAvgHeartRate();
.getAvgBpm()
.toString();
String time = Provider.of<User>(context, listen: false)
.listActivity[0]
.getTotalTime();
@ -24,7 +25,7 @@ class Stats extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
children: [
Text(
const Text(
'Statistiques',
style: TextStyle(
fontSize: 14,
@ -45,7 +46,7 @@ class Stats extends StatelessWidget {
scrollDirection: Axis.horizontal,
child: Row(
children: [
SizedBox(width: 30),
const SizedBox(width: 15),
InfoStat(
icon: Icons.timer,
iconColor: Color.fromARGB(255, 255, 255, 255),
@ -126,7 +127,6 @@ class InfoStat extends StatelessWidget {
iconColor: iconColor,
iconBackground: iconBackground,
),
Change(time: time),
Align(
alignment: Alignment.bottomLeft,
child: Column(
@ -153,36 +153,6 @@ class InfoStat extends StatelessWidget {
}
}
class Change extends StatelessWidget {
const Change({
Key? key,
required this.time,
}) : super(key: key);
final String time;
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.topRight,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 1,
horizontal: 4,
),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(500),
),
child: Text(
time,
style: const TextStyle(fontSize: 10, color: Colors.white),
),
),
);
}
}
class StatIcon extends StatelessWidget {
const StatIcon({
Key? key,

@ -7,8 +7,6 @@ class Steps extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("lhwaa");
String steps = Provider.of<User>(context, listen: false)
.listActivity[0]
.getTotalSteps();

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import '../common/colo_extension.dart';
import '../../common/colo_extension.dart';
class RoundTextField extends StatelessWidget {
final TextEditingController? controller;

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/view/login/signup_view.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/view/main_tab/main_tab_view.dart';
void main() {
runApp(ChangeNotifierProvider(
@ -36,7 +36,7 @@ class MyApp extends StatelessWidget {
primaryColor: TColor.primaryColor1,
fontFamily: "Poppins"),
//home: const StartedView(),
home: const SignUpView(),
home: const MainTabView(),
);
}
}

@ -1,10 +1,12 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:smartfit_app_mobile/common_widget/graph.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:smartfit_app_mobile/common_widget/graph/graph.dart';
class ActivityOfUser {
late String _nomActivite;
late String _imageName;
late List<dynamic> _contentActivity;
late int _dataSession;
List<dynamic> get contentActivity => _contentActivity;
@ -12,8 +14,21 @@ class ActivityOfUser {
_nomActivite = nom;
_imageName = "assets/img/workout1.svg";
_contentActivity = listeDynamic;
_dataSession = getDataSession();
}
// ----- Retourne l'indice de la ligne qui contient les données de la session -- //
int getDataSession() {
for (int i = _contentActivity.length - 1; i != 0; i--) {
if (_contentActivity[i][0] == "Data" &&
_contentActivity[i][2] == "session") {
return i;
}
}
return 0;
}
// ----------------- BPM ------------------ //
List<FlSpot> getHeartRateWithTime() {
List<FlSpot> result = List.empty(growable: true);
int firtTimeStamp = 0;
@ -40,6 +55,35 @@ class ActivityOfUser {
return result;
}
int getMaxBpm() {
for (int i = 0; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "max_heart_rate") {
return _contentActivity[_dataSession][i + 1];
}
}
return 0;
}
int getMinBpm() {
for (int i = 0; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "min_heart_rate") {
return _contentActivity[_dataSession][i + 1];
}
}
return 0;
}
int getAvgBpm() {
for (int i = 0; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "avg_heart_rate") {
return _contentActivity[_dataSession][i + 1];
}
}
return 0;
}
// -------------------------- FIN BPM ---------------------- //
// ---------------------- Distance ---------------------- //
List<FlSpot> getDistanceWithTime() {
List<FlSpot> result = List.empty(growable: true);
int firtTimeStamp = 0;
@ -57,6 +101,18 @@ class ActivityOfUser {
return result;
}
String getTotalDistance() {
for (int i = 0; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "total_distance") {
return _contentActivity[_dataSession][i + 1].toString();
}
}
return "null";
}
// ---------------------- FIN Distance ---------------------- //
// ---------------------- Calories ---------------------- //
List<FlSpot> getCalories() {
List<FlSpot> result = List.empty(growable: true);
int firtTimeStamp = 0;
@ -64,7 +120,6 @@ class ActivityOfUser {
if (ligne.length >= 39 &&
ligne[0] == "Data" &&
ligne[39] == "total_calories") {
print(ligne[39]);
if (firtTimeStamp == 0) {
firtTimeStamp = ligne[4];
}
@ -76,80 +131,40 @@ class ActivityOfUser {
return result;
}
String getTotalSteps() {
print(_contentActivity.length);
for (int i = 0;
i < _contentActivity[_contentActivity.length - 3].length;
i++) {
print(_contentActivity[_contentActivity.length - 3][i]);
if (_contentActivity[_contentActivity.length - 3][i] == "total_strides") {
return _contentActivity[_contentActivity.length - 3][i + 1].toString();
}
}
return "NAN";
}
String getTotalCalorie() {
print(_contentActivity.length);
for (int i = 0;
i < _contentActivity[_contentActivity.length - 3].length;
i++) {
print(_contentActivity[_contentActivity.length - 3][i]);
if (_contentActivity[_contentActivity.length - 3][i] ==
"total_calories") {
return _contentActivity[_contentActivity.length - 3][i + 1].toString();
for (int i = 0; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "total_calories") {
return _contentActivity[_dataSession][i + 1].toString();
}
}
return "NAN";
return "null";
}
String getTotalAvgHeartRate() {
print(_contentActivity.length);
for (int i = 0;
i < _contentActivity[_contentActivity.length - 3].length;
i++) {
print(_contentActivity[_contentActivity.length - 3][i]);
// ---------------------- FIN Calories ---------------------- //
if (_contentActivity[_contentActivity.length - 3][i] ==
"total_calories") {
return _contentActivity[_contentActivity.length - 3][i + 1].toString();
// ---------------------- Step ------------------------------//
String getTotalSteps() {
for (int i = 0; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "total_strides") {
return _contentActivity[_dataSession][i + 1].toString();
}
}
return "NAN";
return "null";
}
// ----------------------- FIN Step ------------------------ //
// ------------------------- Time ----------------------------- //
String getTotalTime() {
print(_contentActivity.length);
for (int i = 0;
i < _contentActivity[_contentActivity.length - 3].length;
i++) {
print(_contentActivity[_contentActivity.length - 3][i]);
if (_contentActivity[_contentActivity.length - 3][i] ==
"total_elapsed_time") {
return _contentActivity[_contentActivity.length - 3][i + 1].toString();
for (int i = 0; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "total_elapsed_time") {
return _contentActivity[_dataSession][i + 1].toString();
}
}
return "NAN";
}
String getTotalDistance() {
print(_contentActivity.length);
for (int i = 0;
i < _contentActivity[_contentActivity.length - 3].length;
i++) {
print(_contentActivity[_contentActivity.length - 3][i]);
if (_contentActivity[_contentActivity.length - 3][i] ==
"total_distance") {
return _contentActivity[_contentActivity.length - 3][i + 1].toString();
}
}
return "NAN";
return "null";
}
// ---------------------------- FIN time -------------------- //
// ---------------------------------------- Altitude -------------------- //
List<FlSpot> getAltitudeWithTime() {
List<FlSpot> result = List.empty(growable: true);
int firtTimeStamp = 0;
@ -167,20 +182,27 @@ class ActivityOfUser {
return result;
}
double getDistance() {
double result = 0.0;
for (int i = _contentActivity.length - 1; i >= 0; i--) {
if (_contentActivity[i].length >= 8 &&
_contentActivity[i][0] == "Data" &&
_contentActivity[i][6] == "distance") {
if (_contentActivity[i][7] > result) {
result = _contentActivity[i][7].toDouble();
}
double getMaxAltitude() {
for (int i = 4; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "max_altitude") {
return _contentActivity[_dataSession][i + 1];
}
}
return result;
return 0.0;
}
double getMinAltitude() {
for (int i = 4; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "min_altitude") {
return _contentActivity[_dataSession][i + 1];
}
}
return 0.0;
}
// -------------------------- FIN altitude ---------------------- //
// -------------------------- Speed ---------------------- //
List<FlSpot> getSpeedWithTime() {
List<FlSpot> result = List.empty(growable: true);
int firtTimeStamp = 0;
@ -229,6 +251,41 @@ class ActivityOfUser {
return result;
}
double getMaxSpeed() {
for (int i = 4; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "max_speed") {
return _contentActivity[_dataSession][i + 1];
}
}
return 0.0;
}
double getAvgSpeed() {
for (int i = 4; i < _contentActivity[_dataSession].length; i++) {
if (_contentActivity[_dataSession][i] == "avg_speed") {
return _contentActivity[_dataSession][i + 1];
}
}
return 0.0;
}
// -------------------------- FIN Speed ---------------------- //
// -------------------------- Localisation ------------------- //
List<LatLng> getPosition() {
List<LatLng> list = List.empty(growable: true);
for (List<dynamic> ligne in _contentActivity) {
if (ligne[0] == "Data" && ligne[6] == "position_lat") {
list.add(LatLng(ligne[7], ligne[10]));
}
}
return list;
}
// -------------------------- FIN Localisation ---------------------- //
Map<String, dynamic> toMap() {
return {
'nomActivite': _nomActivite,

@ -1,5 +1,6 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:csv/csv.dart';
import 'package:fit_tool/fit_tool.dart';
import 'package:path_provider/path_provider.dart';
@ -26,7 +27,10 @@ class ManagerFile {
return fitFile.toRows();
}
List<dynamic> readFitFileWeb(Uint8List bytes) {
final fitFile = FitFile.fromBytes(bytes);
return fitFile.toRows();
}
// ------------- Get The path of application --- //
Future<String> get localPath async {
final directory = await getApplicationDocumentsDirectory();

@ -5,7 +5,7 @@ class User extends ChangeNotifier {
String username = "VOID";
String email = "VOID";
String token = "VOID";
List<ActivityOfUser> listActivity = List.empty();
List<ActivityOfUser> listActivity = List.empty(growable: true);
void addActivity(ActivityOfUser activity) {
listActivity.add(activity);

@ -0,0 +1,11 @@
import 'package:fl_chart/fl_chart.dart';
class DataHomeView {
late List<FlSpot> bpmSecondes;
late List<FlSpot> bpmSecondes2;
late List<FlSpot> vitesseSecondes;
late List<FlSpot> altitudeSeconde;
DataHomeView(this.bpmSecondes, this.bpmSecondes2, this.vitesseSecondes,
this.altitudeSeconde);
}

@ -0,0 +1,38 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/modele/activity.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/modele/utile/home_view/data_home_view.dart';
class HomeViewUtil {
DataHomeView initData(BuildContext context) {
ActivityOfUser activity = Provider.of<User>(context).listActivity[0];
List<FlSpot> bpmSecondes = activity.getHeartRateWithTime();
List<FlSpot> vitesseSecondes = activity.getSpeedWithTime();
List<FlSpot> altitudeSeconde = activity.getAltitudeWithTime();
List<FlSpot> bpmSecondes2 = List.from(bpmSecondes);
return DataHomeView(bpmSecondes, normaliserDeuxiemeElement(bpmSecondes2),
normaliserDeuxiemeElement(vitesseSecondes), altitudeSeconde);
}
List<FlSpot> normaliserDeuxiemeElement(List<FlSpot> liste) {
// Trouver le plus grand élément dans la liste
double maxElement = 0.0;
for (var spot in liste) {
if (spot.y > maxElement) {
maxElement = spot.y;
}
}
// Calculer le facteur de normalisation
double normalisationFactor = maxElement != 0.0 ? 100 / maxElement : 1.0;
// Mettre à jour tous les éléments de la liste
for (int i = 0; i < liste.length; i++) {
liste[i] = FlSpot(liste[i].x, liste[i].y * normalisationFactor);
}
return liste;
}
}

@ -0,0 +1,16 @@
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
class MapUtil {
Set<Polyline> initPolines(BuildContext context, int largueur, Color couleur) {
Set<Polyline> _polylines = {};
_polylines.add(Polyline(
polylineId: const PolylineId("Polyline"),
color: couleur,
points: context.watch<User>().listActivity[0].getPosition(),
width: largueur));
return _polylines;
}
}

@ -1,6 +1,8 @@
import 'package:provider/provider.dart';
import 'package:responsive_builder/responsive_builder.dart';
import 'package:smartfit_app_mobile/view/home/mobile/mobile_Activity_view.dart';
import 'package:smartfit_app_mobile/view/home/web/web_Activity_view.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/view/activity/mobile/mobile_Activity_view.dart';
import 'package:smartfit_app_mobile/view/activity/web/web_Activity_view.dart';
import 'package:flutter/material.dart';
class Activity extends StatelessWidget {
@ -8,9 +10,21 @@ class Activity extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScreenTypeLayout.builder(
mobile: (_) => const MobileActivity(),
desktop: (_) => const WebActivity(),
);
if (context.watch<User>().listActivity.isEmpty) {
return const Scaffold(
body: Column(
children: [
Text("C'est vide"),
Text("C'est vide"),
Text("C'est vide"),
Text("C'est vide")
],
));
} else {
return ScreenTypeLayout.builder(
mobile: (_) => const MobileActivity(),
desktop: (_) => const WebActivity(),
);
}
}
}

@ -1,18 +1,7 @@
import 'dart:convert';
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:file_picker/file_picker.dart';
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/modele/api/i_data_strategy.dart';
import 'package:smartfit_app_mobile/modele/api/request_api.dart';
import 'package:smartfit_app_mobile/modele/activity.dart';
import 'package:smartfit_app_mobile/modele/manager_file.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/common_widget/workout_row.dart';
import 'package:flutter/material.dart';
import 'package:tuple/tuple.dart';
import '../../common/colo_extension.dart';
import 'package:responsive_builder/responsive_builder.dart';
import 'package:smartfit_app_mobile/view/activity/mobile/mobile_list_activity.dart';
import 'package:smartfit_app_mobile/view/activity/web/web_list_activity.dart';
class ListActivity extends StatefulWidget {
const ListActivity({super.key});
@ -22,228 +11,11 @@ class ListActivity extends StatefulWidget {
}
class _ListActivityState extends State<ListActivity> {
FilePickerResult? result;
IDataStrategy strategy = RequestApi();
//late File x = File(file.path);
Future<void> readFile(String nom) async {
ManagerFile x = ManagerFile();
PlatformFile t = result!.files.single;
String? y = t.path;
if (t.path == null) {
print("t");
} else {
List<dynamic> result = await x.readFitFile(y!);
print("test11");
print(result);
print("test22");
print(ActivityOfUser(nom, result).getHeartRateWithTime());
print("test33");
Provider.of<User>(context, listen: false)
.addActivity(ActivityOfUser(nom, result));
//print(x.getDistanceWithTime(ActivityOfUser(result)));
//print(x.getDistance(ActivityOfUser(result)));
//print(x.getAltitudeWithTime(ActivityOfUser(result)));
//print(x.getSpeedWithTime(ActivityOfUser(result)));
}
}
Future<void> createUser() async {
String mds = "1234";
var byte = utf8.encode(mds);
var digest = sha256.convert(byte);
print(digest.toString());
print("Appel");
Tuple2<bool, String> res =
await strategy.postUser("toto@gmail.com", digest.toString(), "toto");
print(res.item1);
print(res.item2);
}
Future<void> login() async {
String mds = "1234";
var byte = utf8.encode(mds);
var digest = sha256.convert(byte);
print(digest.toString());
print("Appel");
Tuple2<bool, String> res =
await strategy.connexion("toto@gmail.com", digest.toString());
print(res.item1);
print(res.item2);
}
Future<void> deleteUser() async {
String token =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiYjA3OThmMjAtN2ZiMy0xMWVlLWJhZmQtMDI0MjBhNWEwMDFmIiwiZXhwIjoxNzA0ODgyNDI3fQ.2_bnvEC7_pwchielF3Kpu9fFtXDv_KabdOU8T07UnWI";
print("Appel");
Tuple2<bool, String> res = await strategy.deleteUser(token);
print(res.item1);
print(res.item2);
}
Future<void> getFiles() async {
String token =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiOGUyYWVmMTItN2ZiNC0xMWVlLWJhZmQtMDI0MjBhNWEwMDFmIiwiZXhwIjoxNzA0ODgyNzk3fQ.b_zsOHj2C-Y28CrcozbSjEz8BUWL8kgjjx5CDhES8PI";
print("Appel");
Tuple2 res = await strategy.getFiles(token);
print(res.item1);
print(res.item2);
}
Future<void> modifAttribut() async {
String nameAtt = "username";
String newValue = "toto2";
String token =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiOGUyYWVmMTItN2ZiNC0xMWVlLWJhZmQtMDI0MjBhNWEwMDFmIiwiZXhwIjoxNzA0ODgzMDM4fQ.umN7LmUDbKUOeIToLcsOUIioQ7u4wsReHggRDB68VPQ";
print("Appel");
Tuple2 res = await strategy.modifAttribut(token, nameAtt, newValue);
print(res.item1);
print(res.item2);
}
Future<void> uploadFile() async {
PlatformFile t = result!.files.single;
String token =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiOGUyYWVmMTItN2ZiNC0xMWVlLWJhZmQtMDI0MjBhNWEwMDFmIiwiZXhwIjoxNzA0ODgzNjM5fQ.0TmfJ9eYnszw4_RkNwPkMzkJxvsIFs5BI9uhQ7qYb0g";
String? lol = t.path!;
print("Appel");
Tuple2 res = await strategy.uploadFile(token, File(lol));
print(res.item1);
print(res.item2);
}
Future<void> getOneFile() async {
String ui = "fc6e234c-7fc6-11ee-bafd-02420a5a001f";
String token =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiOGUyYWVmMTItN2ZiNC0xMWVlLWJhZmQtMDI0MjBhNWEwMDFmIiwiZXhwIjoxNzA0ODgzOTE3fQ.TUdrGEo7A0auQlUfO5RQm874QWuGXFBSKbJ8qTGPF2M";
print("Appel");
Tuple2 res = await strategy.getFile(token, ui);
print(res.item1);
print(res.item2);
ManagerFile x = ManagerFile();
File file = File("${await x.localPath}/Walking_2023-11-08T10_57_28.fit");
await file.create();
await file.writeAsBytes(res.item2);
print(await x.localPath);
print("Save");
print(await x
.readFitFile("${await x.localPath}/Walking_2023-11-08T10_57_28.fit"));
}
Future<void> getInfoUser() async {
String token =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiOGUyYWVmMTItN2ZiNC0xMWVlLWJhZmQtMDI0MjBhNWEwMDFmIiwiZXhwIjoxNzA0ODgzOTE3fQ.TUdrGEo7A0auQlUfO5RQm874QWuGXFBSKbJ8qTGPF2M";
Tuple2 res = await strategy.getInfoUser(token);
print(res.item1);
print(res.item2);
}
List lastWorkoutArr = [];
@override
Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: TColor.white,
body: SingleChildScrollView(
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"List Activités",
style: TextStyle(
color: TColor.black,
fontSize: 16,
fontWeight: FontWeight.w700),
),
TextButton(
onPressed: () async {
result = await FilePicker.platform.pickFiles();
if (result == null) {
print("No file selected");
} else {
for (var element in result!.files) {
readFile(element.name);
print(element.name);
}
}
},
child: Text(
"Ajouter",
style: TextStyle(
color: TColor.gray,
fontSize: 14,
fontWeight: FontWeight.w700),
),
)
],
),
Provider.of<User>(context, listen: true).listActivity.isEmpty
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20),
Text(
"Vous n'avez pas d'activités pour le moment, veuillez en ajouter.",
style: TextStyle(
color: TColor.gray,
fontSize: 11,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w400,
),
)
])
: ListView.builder(
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: Provider.of<User>(context, listen: true)
.listActivity
.length,
itemBuilder: (context, index) {
var activityObj =
Provider.of<User>(context, listen: true)
.listActivity[index] as ActivityOfUser;
var activityMap = activityObj.toMap();
return InkWell(
onTap: () {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
Provider.of<User>(context, listen: false)
.insertActivity(0, activityObj);
},
child: WorkoutRow(
wObj: activityMap,
onDelete: () {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
},
onClick: () {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
Provider.of<User>(context, listen: false)
.insertActivity(0, activityObj);
},
));
}),
SizedBox(
height: media.width * 0.1,
),
],
),
),
),
),
return ScreenTypeLayout.builder(
mobile: (_) => const MobileListActivity(),
desktop: (_) => const WebListActivity(),
);
}
}

@ -1,5 +1,6 @@
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/common_widget/steps.dart';
import 'package:smartfit_app_mobile/common_widget/graph.dart';
import 'package:smartfit_app_mobile/common_widget/graph/graph.dart';
import 'package:smartfit_app_mobile/common_widget/info.dart' hide Stats;
import 'package:smartfit_app_mobile/common_widget/stats.dart';
import 'package:flutter/material.dart';

@ -0,0 +1,151 @@
import 'package:file_picker/file_picker.dart';
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/modele/api/i_data_strategy.dart';
import 'package:smartfit_app_mobile/modele/api/request_api.dart';
import 'package:smartfit_app_mobile/modele/activity.dart';
import 'package:smartfit_app_mobile/modele/manager_file.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/common_widget/container/workout_row.dart';
import 'package:flutter/material.dart';
class MobileListActivity extends StatefulWidget {
const MobileListActivity({super.key});
@override
State<MobileListActivity> createState() => _MobileListActivity();
}
class _MobileListActivity extends State<MobileListActivity> {
FilePickerResult? result;
IDataStrategy strategy = RequestApi();
Future<void> readFile(String nom) async {
ManagerFile x = ManagerFile();
PlatformFile t = result!.files.single;
String? y = t.path;
if (t.path == null) {
print("t");
} else {
List<dynamic> result = await x.readFitFile(y!);
print("test11");
print(result);
print("test22");
print(ActivityOfUser(nom, result).getHeartRateWithTime());
print("test33");
Provider.of<User>(context, listen: false)
.addActivity(ActivityOfUser(nom, result));
//print(x.getDistanceWithTime(ActivityOfUser(result)));
//print(x.getDistance(ActivityOfUser(result)));
//print(x.getAltitudeWithTime(ActivityOfUser(result)));
//print(x.getSpeedWithTime(ActivityOfUser(result)));
}
}
List lastWorkoutArr = [];
@override
Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: TColor.white,
body: SingleChildScrollView(
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"List Activités",
style: TextStyle(
color: TColor.black,
fontSize: 16,
fontWeight: FontWeight.w700),
),
TextButton(
onPressed: () async {
result = await FilePicker.platform.pickFiles();
if (result == null) {
print("No file selected");
} else {
for (var element in result!.files) {
readFile(element.name);
print(element.name);
}
}
},
child: Text(
"Ajouter",
style: TextStyle(
color: TColor.gray,
fontSize: 14,
fontWeight: FontWeight.w700),
),
)
],
),
Provider.of<User>(context, listen: true).listActivity.isEmpty
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20),
Text(
"Vous n'avez pas d'activités pour le moment, veuillez en ajouter.",
style: TextStyle(
color: TColor.gray,
fontSize: 11,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w400,
),
)
])
: ListView.builder(
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: Provider.of<User>(context, listen: true)
.listActivity
.length,
itemBuilder: (context, index) {
var activityObj =
Provider.of<User>(context, listen: true)
.listActivity[index] as ActivityOfUser;
var activityMap = activityObj.toMap();
return InkWell(
onTap: () {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
Provider.of<User>(context, listen: false)
.insertActivity(0, activityObj);
},
child: WorkoutRow(
wObj: activityMap,
onDelete: () {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
},
onClick: () {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
Provider.of<User>(context, listen: false)
.insertActivity(0, activityObj);
},
));
}),
SizedBox(
height: media.width * 0.1,
),
],
),
),
),
),
);
}
}

@ -1,5 +1,5 @@
import 'package:smartfit_app_mobile/common_widget/steps.dart';
import 'package:smartfit_app_mobile/common_widget/graph.dart';
import 'package:smartfit_app_mobile/common_widget/graph/graph.dart';
import 'package:smartfit_app_mobile/common_widget/info.dart' hide Stats;
import 'package:smartfit_app_mobile/common_widget/stats.dart';
import 'package:flutter/material.dart';

@ -0,0 +1,163 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/modele/manager_file.dart';
import 'package:universal_html/html.dart' as html;
import 'package:file_picker/file_picker.dart';
import 'package:provider/provider.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/modele/api/i_data_strategy.dart';
import 'package:smartfit_app_mobile/modele/api/request_api.dart';
import 'package:smartfit_app_mobile/modele/activity.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/common_widget/container/workout_row.dart';
class WebListActivity extends StatefulWidget {
const WebListActivity({super.key});
@override
State<WebListActivity> createState() => _WebListActivityState();
}
class _WebListActivityState extends State<WebListActivity> {
FilePickerResult? result;
IDataStrategy strategy = RequestApi();
//late File x = File(file.path);
List<String> parseFile(Uint8List bytes) {
String csvString =
utf8.decode(bytes); // Convertit les bytes en chaîne UTF-8
List<String> lines =
LineSplitter.split(csvString).toList(); // Sépare les lignes
for (String line in lines) {
print(line); // Affiche chaque ligne du fichier
}
return lines; // Ou retournez les lignes du fichier
}
void readFile(html.File file) async {
ManagerFile x = ManagerFile();
final reader = html.FileReader();
reader.readAsArrayBuffer(file);
reader.onLoadEnd.listen((event) {
if (reader.readyState == html.FileReader.DONE) {
Uint8List bytes = reader.result as Uint8List;
List<dynamic> result = x.readFitFileWeb(bytes);
Provider.of<User>(context, listen: false)
.addActivity(ActivityOfUser(file.name, result));
}
});
}
List lastWorkoutArr = [];
@override
Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: TColor.white,
body: SingleChildScrollView(
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"List Activités",
style: TextStyle(
color: TColor.black,
fontSize: 16,
fontWeight: FontWeight.w700),
),
TextButton(
onPressed: () async {
html.FileUploadInputElement uploadInput =
html.FileUploadInputElement();
uploadInput.click();
uploadInput.onChange.listen((e) {
final files = uploadInput.files;
if (files != null && files.isNotEmpty) {
readFile(
files[0]); // Lecture du fichier sélectionné
}
});
},
child: Text(
"Ajouter",
style: TextStyle(
color: TColor.gray,
fontSize: 14,
fontWeight: FontWeight.w700),
),
)
],
),
Provider.of<User>(context, listen: true).listActivity.isEmpty
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20),
Text(
"Vous n'avez pas d'activités pour le moment, veuillez en ajouter.",
style: TextStyle(
color: TColor.gray,
fontSize: 11,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w400,
),
)
])
: ListView.builder(
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: Provider.of<User>(context, listen: true)
.listActivity
.length,
itemBuilder: (context, index) {
var activityObj =
Provider.of<User>(context, listen: true)
.listActivity[index] as ActivityOfUser;
var activityMap = activityObj.toMap();
return InkWell(
onTap: () {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
Provider.of<User>(context, listen: false)
.insertActivity(0, activityObj);
},
child: WorkoutRow(
wObj: activityMap,
onDelete: () {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
},
onClick: () {
Provider.of<User>(context, listen: false)
.removeActivity(activityObj);
Provider.of<User>(context, listen: false)
.insertActivity(0, activityObj);
},
));
}),
SizedBox(
height: media.width * 0.1,
),
],
),
),
),
),
);
}
}

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:responsive_builder/responsive_builder.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/view/home/mobile/mobile_homeview.dart';
import 'package:smartfit_app_mobile/view/home/web/web_homeview.dart';
@ -13,9 +15,21 @@ class HomeView extends StatefulWidget {
class _HomeViewState extends State<HomeView> {
@override
Widget build(BuildContext context) {
return ScreenTypeLayout.builder(
mobile: (_) => const MobileHomeView(),
desktop: (_) => const WebHomeView(),
);
if (context.watch<User>().listActivity.isEmpty) {
return const Scaffold(
body: Column(
children: [
Text("C'est vide"),
Text("C'est vide"),
Text("C'est vide"),
Text("C'est vide")
],
));
} else {
return ScreenTypeLayout.builder(
mobile: (_) => const MobileHomeView(),
desktop: (_) => const WebHomeView(),
);
}
}
}

File diff suppressed because it is too large Load Diff

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import '../../common/colo_extension.dart';
import '../../common_widget/notification_row.dart';
import '../../common_widget/not_use/notification_row.dart';
class NotificationView extends StatefulWidget {
const NotificationView({super.key});
@ -12,12 +12,36 @@ class NotificationView extends StatefulWidget {
class _NotificationViewState extends State<NotificationView> {
List notificationArr = [
{"image": "assets/img/workout1.svg", "title": "Hey, c'est l'heure du sport", "time": "Il y a 3 minutes"},
{"image": "assets/img/workout1.svg", "title": "Ne manque pas ton entrainement", "time": "Il y a 7 minutes"},
{"image": "assets/img/workout1.svg", "title": "Hey, c'est l'heure du sport", "time": "Il y a 5 jours"},
{"image": "assets/img/workout1.svg", "title": "Ne manque pas ton entrainement", "time": "29 Mai"},
{"image": "assets/img/workout1.svg", "title": "Hey, c'est l'heure du sport", "time": "8 Avril"},
{"image": "assets/img/workout1.svg", "title": "Ne manque pas ton entrainement", "time": "8 Avril"},
{
"image": "assets/img/workout1.svg",
"title": "Hey, c'est l'heure du sport",
"time": "Il y a 3 minutes"
},
{
"image": "assets/img/workout1.svg",
"title": "Ne manque pas ton entrainement",
"time": "Il y a 7 minutes"
},
{
"image": "assets/img/workout1.svg",
"title": "Hey, c'est l'heure du sport",
"time": "Il y a 5 jours"
},
{
"image": "assets/img/workout1.svg",
"title": "Ne manque pas ton entrainement",
"time": "29 Mai"
},
{
"image": "assets/img/workout1.svg",
"title": "Hey, c'est l'heure du sport",
"time": "8 Avril"
},
{
"image": "assets/img/workout1.svg",
"title": "Ne manque pas ton entrainement",
"time": "8 Avril"
},
];
@override
@ -75,13 +99,18 @@ class _NotificationViewState extends State<NotificationView> {
),
backgroundColor: TColor.white,
body: ListView.separated(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 25),
itemBuilder: ((context, index) {
var nObj = notificationArr[index] as Map? ?? {};
return NotificationRow(nObj: nObj);
}), separatorBuilder: (context, index){
return Divider(color: TColor.gray.withOpacity(0.5), height: 1, );
}, itemCount: notificationArr.length),
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 25),
itemBuilder: ((context, index) {
var nObj = notificationArr[index] as Map? ?? {};
return NotificationRow(nObj: nObj);
}),
separatorBuilder: (context, index) {
return Divider(
color: TColor.gray.withOpacity(0.5),
height: 1,
);
},
itemCount: notificationArr.length),
);
}
}
}

File diff suppressed because it is too large Load Diff

@ -3,8 +3,8 @@ import 'package:flutter_svg/svg.dart';
import 'package:smartfit_app_mobile/modele/utile/login_user.dart';
import 'package:smartfit_app_mobile/view/main_tab/main_tab_view.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/round_text_field.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart';
import 'package:tuple/tuple.dart';
class MobileLoginView extends StatefulWidget {

@ -3,8 +3,8 @@ import 'package:flutter_svg/svg.dart';
import 'package:smartfit_app_mobile/modele/utile/signup_user.dart';
import 'package:smartfit_app_mobile/view/login/login_view.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/round_text_field.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart';
import 'package:tuple/tuple.dart';
class MobileSignUpView extends StatefulWidget {

@ -3,8 +3,8 @@ import 'package:flutter_svg/svg.dart';
import 'package:smartfit_app_mobile/modele/utile/login_user.dart';
import 'package:smartfit_app_mobile/view/main_tab/main_tab_view.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/round_text_field.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart';
import 'package:tuple/tuple.dart';
class WebLoginView extends StatefulWidget {

@ -3,8 +3,8 @@ import 'package:flutter_svg/svg.dart';
import 'package:smartfit_app_mobile/modele/utile/signup_user.dart';
import 'package:smartfit_app_mobile/view/login/login_view.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/round_text_field.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/text_field/round_text_field.dart';
import 'package:tuple/tuple.dart';
class WebSignUpView extends StatefulWidget {

@ -1,6 +1,6 @@
import 'package:smartfit_app_mobile/view/activity/list_activity.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/tab_button.dart';
import 'package:smartfit_app_mobile/common_widget/button/tab_button.dart';
import 'package:smartfit_app_mobile/view/activity/activity.dart';
import 'package:smartfit_app_mobile/view/home/home_view.dart';
import 'package:flutter/material.dart';

@ -0,0 +1,46 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/modele/utile/maps/maps_utile.dart';
class MobileMyMaps extends StatefulWidget {
const MobileMyMaps({super.key});
@override
State<MobileMyMaps> createState() => _MobileMyMaps();
}
class _MobileMyMaps extends State<MobileMyMaps> {
final Completer<GoogleMapController> _googleMapController = Completer();
CameraPosition? _cameraPosition;
Set<Polyline> _polylines = {};
@override
Widget build(BuildContext context) {
_polylines = MapUtil().initPolines(context, 10, TColor.primaryColor1);
_cameraPosition =
CameraPosition(target: _polylines.first.points.first, zoom: 18);
return Scaffold(
body: _getMap(),
);
}
Widget _getMap() {
return Stack(
children: [
GoogleMap(
initialCameraPosition: _cameraPosition!,
mapType: MapType.normal,
onMapCreated: (GoogleMapController controller) {
if (!_googleMapController.isCompleted) {
_googleMapController.complete(controller);
}
},
polylines: _polylines,
)
],
);
}
}

@ -1,154 +1,29 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:provider/provider.dart';
import 'package:responsive_builder/responsive_builder.dart';
import 'package:smartfit_app_mobile/modele/user.dart';
import 'package:smartfit_app_mobile/view/map/mobile/mobile_my_map.dart';
import 'package:smartfit_app_mobile/view/map/web/web_my_map.dart';
import 'package:smartfit_app_mobile/view/profile/profile_view.dart';
class MyMap extends StatefulWidget {
const MyMap({ Key? key }) : super(key: key);
const MyMap({Key? key}) : super(key: key);
@override
State<MyMap> createState() => _MyMapState();
}
class _MyMapState extends State<MyMap> {
Completer<GoogleMapController> _googleMapController = Completer();
CameraPosition? _cameraPosition;
Location? _location;
LocationData? _currentLocation;
List<LatLng> _polylineCoordinates = [];
Set<Polyline> _polylines = {};
Set<Marker> _markers = {}; // Add a set to store markers
@override
void initState() {
_init();
super.initState();
}
_init() async {
_location = Location();
_cameraPosition = CameraPosition(
target: LatLng(0, 0), // this is just the example lat and lng for initializing
zoom: 20
);
_initLocation();
}
//function to listen when we move position
_initLocation() {
_location?.getLocation().then((location) {
_currentLocation = location;
});
_location?.onLocationChanged.listen((newLocation) {
setState(() {
_currentLocation = newLocation;
_polylineCoordinates.add(LatLng(
_currentLocation?.latitude ?? 0,
_currentLocation?.longitude ?? 0,
));
_updatePolyline();
});
moveToPosition(LatLng(_currentLocation?.latitude ?? 0,
_currentLocation?.longitude ?? 0));
});
}
_updatePolyline() {
setState(() {
_polylines.clear();
_polylines.add(Polyline(
polylineId: PolylineId("polyline"),
color: TColor.primaryColor1,
points: _polylineCoordinates,
width: 10,
));
});
}
// Updated _updateMarker to use the custom marker
_updateMarker(LatLng position) async {
final markerId = MarkerId('marker');
final marker = Marker(
markerId: markerId,
position: position
);
_markers.clear();
_markers.add(marker);
}
moveToPosition(LatLng latLng) async {
GoogleMapController mapController = await _googleMapController.future;
mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: latLng,
zoom: 15
)
)
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildBody(),
);
}
Widget _buildBody() {
return _getMap();
}
Widget _getMarker() {
return Container(
width: 25,
height: 25,
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100),
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(0,3),
spreadRadius: 4,
blurRadius: 6
)
]
),
child: ClipOval(child: Image.asset("assets/img/u1.png")),
);
}
Widget _getMap() {
return Stack(
children: [
GoogleMap(
initialCameraPosition: _cameraPosition!,
mapType: MapType.normal,
onMapCreated: (GoogleMapController controller) {
if (!_googleMapController.isCompleted) {
_googleMapController.complete(controller);
}
},
polylines: _polylines,
markers: _markers,
),
Positioned.fill(
child: Align(
alignment: Alignment.center,
child: _getMarker()
return context.watch<User>().listActivity.isEmpty
? ScreenTypeLayout.builder(
mobile: (_) => const ProfileView(),
desktop: (_) => const ProfileView(),
)
)
],
);
: ScreenTypeLayout.builder(
mobile: (_) => const MobileMyMaps(),
desktop: (_) => const WebMyMaps(),
);
}
}

@ -0,0 +1,47 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/modele/utile/maps/maps_utile.dart';
class WebMyMaps extends StatefulWidget {
const WebMyMaps({super.key});
@override
State<WebMyMaps> createState() => _WebMyMaps();
}
class _WebMyMaps extends State<WebMyMaps> {
final Completer<GoogleMapController> _googleMapController = Completer();
CameraPosition? _cameraPosition;
Set<Polyline> _polylines = {};
@override
Widget build(BuildContext context) {
_polylines = MapUtil().initPolines(context, 10, TColor.primaryColor1);
_cameraPosition =
CameraPosition(target: _polylines.first.points.first, zoom: 18);
return Scaffold(
body: _getMap(),
);
}
Widget _getMap() {
return Stack(
children: [
GoogleMap(
initialCameraPosition: _cameraPosition!,
mapType: MapType.normal,
onMapCreated: (GoogleMapController controller) {
if (!_googleMapController.isCompleted) {
_googleMapController.complete(controller);
}
},
polylines: _polylines,
)
],
);
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,131 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
class MobileMyMaps extends StatefulWidget {
const MobileMyMaps({super.key});
@override
State<MobileMyMaps> createState() => _MobileMyMaps();
}
class _MobileMyMaps extends State<MobileMyMaps> {
Completer<GoogleMapController> _googleMapController = Completer();
CameraPosition? _cameraPosition;
Location? _location;
LocationData? _currentLocation;
List<LatLng> _polylineCoordinates = [];
Set<Polyline> _polylines = {};
Set<Marker> _markers = {}; // Add a set to store markers
@override
void initState() {
_init();
super.initState();
}
_init() async {
_location = Location();
_cameraPosition = const CameraPosition(
target: LatLng(
0, 0), // this is just the example lat and lng for initializing
zoom: 20);
_initLocation();
}
//function to listen when we move position
_initLocation() {
_location?.getLocation().then((location) {
_currentLocation = location;
});
_location?.onLocationChanged.listen((newLocation) {
setState(() {
_currentLocation = newLocation;
_polylineCoordinates.add(LatLng(
_currentLocation?.latitude ?? 0,
_currentLocation?.longitude ?? 0,
));
_updatePolyline();
});
moveToPosition(LatLng(
_currentLocation?.latitude ?? 0, _currentLocation?.longitude ?? 0));
});
}
_updatePolyline() {
setState(() {
_polylines.clear();
_polylines.add(Polyline(
polylineId: PolylineId("polyline"),
color: TColor.primaryColor1,
points: _polylineCoordinates,
width: 10,
));
});
}
/*
// Updated _updateMarker to use the custom marker
_updateMarker(LatLng position) async {
final markerId = MarkerId('marker');
final marker = Marker(markerId: markerId, position: position);
_markers.clear();
_markers.add(marker);
}*/
moveToPosition(LatLng latLng) async {
GoogleMapController mapController = await _googleMapController.future;
mapController.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(target: latLng, zoom: 15)));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _getMap(),
);
}
Widget _getMarker() {
return Container(
width: 25,
height: 25,
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100),
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(0, 3),
spreadRadius: 4,
blurRadius: 6)
]),
child: ClipOval(child: Image.asset("assets/img/u1.png")),
);
}
Widget _getMap() {
return Stack(
children: [
GoogleMap(
initialCameraPosition: _cameraPosition!,
mapType: MapType.normal,
onMapCreated: (GoogleMapController controller) {
if (!_googleMapController.isCompleted) {
_googleMapController.complete(controller);
}
},
polylines: _polylines,
markers: _markers,
),
Positioned.fill(
child: Align(alignment: Alignment.center, child: _getMarker()))
],
);
}
}

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/on_boarding_page.dart';
import 'package:smartfit_app_mobile/common_widget/on_boarding/on_boarding_page.dart';
import 'package:smartfit_app_mobile/view/login/signup_view.dart';
class OnBoardingView extends StatefulWidget {

@ -1,7 +1,7 @@
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/view/on_boarding/on_boarding_view.dart';
import 'package:flutter/material.dart';
import '../../common_widget/round_button.dart';
import '../../common_widget/button/round_button.dart';
import 'package:flutter_svg/flutter_svg.dart';
class StartedView extends StatefulWidget {

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:animated_toggle_switch/animated_toggle_switch.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/setting_row.dart';
import 'package:smartfit_app_mobile/common_widget/title_subtitle_cell.dart';

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:animated_toggle_switch/animated_toggle_switch.dart';
import 'package:smartfit_app_mobile/common/colo_extension.dart';
import 'package:smartfit_app_mobile/common_widget/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/button/round_button.dart';
import 'package:smartfit_app_mobile/common_widget/setting_row.dart';
import 'package:smartfit_app_mobile/common_widget/title_subtitle_cell.dart';

@ -55,6 +55,7 @@ dependencies:
tuple: ^2.0.2
crypto: ^3.0.3
responsive_builder: ^0.7.0
universal_html: ^2.2.4
dev_dependencies:
flutter_test:

@ -26,6 +26,9 @@
<meta name="apple-mobile-web-app-title" content="smartfit_app_mobile">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- MAP GOOGLE-->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD2Jgh9NXhtKaH8qRyGfkCeMDusBJ4xcRY"></script>
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>

Loading…
Cancel
Save