feat: add bottom nav bar
This commit is contained in:
parent
b6987dd086
commit
0c4ab9995c
BIN
agrilink_vocpro/assets/images/green_house_image.jpg
Normal file
BIN
agrilink_vocpro/assets/images/green_house_image.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 564 KiB |
|
|
@ -1,12 +1,13 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AppColor {
|
class AppColor {
|
||||||
static const Color primary = Color(0xFF00B14F);
|
static const Color primary = Color(0xFF227267);
|
||||||
static const Color greenLight = Color(0xFFE6F4F1);
|
static const Color darkGreen = Color(0xFF16423C);
|
||||||
static const Color greenDark = Color(0xFF00913A);
|
static const Color secondary = Color(0xFF399C8F);
|
||||||
|
static const Color ternary = Color(0xFF48BBAC);
|
||||||
|
|
||||||
static const Color greenText = Color(0xFF00B14F);
|
static const Color greenText = Color(0xFF00B14F);
|
||||||
static const Color greenTextLight = Color(0xFFE6F4F1);
|
static const Color greenTextLight = Color(0xFFE9EFEC);
|
||||||
static const Color greenTextDark = Color(0xFF00913A);
|
static const Color greenTextDark = Color(0xFF00913A);
|
||||||
|
|
||||||
static const Color textDisable = Color(0xFFBDBDBD);
|
static const Color textDisable = Color(0xFFBDBDBD);
|
||||||
|
|
|
||||||
|
|
@ -1 +1,36 @@
|
||||||
class AppTheme {}
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AppTheme {
|
||||||
|
static TextStyle headline1 = const TextStyle(
|
||||||
|
fontSize: 32,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
letterSpacing: 1,
|
||||||
|
color: Colors.black,
|
||||||
|
);
|
||||||
|
static TextStyle titleLarge = const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black,
|
||||||
|
);
|
||||||
|
static TextStyle titleMedium = const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black,
|
||||||
|
);
|
||||||
|
static TextStyle titleSmall = const TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black,
|
||||||
|
);
|
||||||
|
|
||||||
|
static TextStyle labelMedium = const TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.black,
|
||||||
|
);
|
||||||
|
static TextStyle labelSmall = const TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.grey,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,26 @@
|
||||||
class Extenstion {
|
import 'package:intl/intl.dart';
|
||||||
static String capitalize(String s) {
|
|
||||||
return s[0].toUpperCase() + s.substring(1);
|
String capitalize(String s) {
|
||||||
|
return s[0].toUpperCase() + s.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String dateFormater(String date) {
|
||||||
|
final DateTime dateTime = DateTime.parse(date);
|
||||||
|
final DateFormat formatter = DateFormat('dd MMM yyyy');
|
||||||
|
return formatter.format(dateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
String getGreeting(String time) {
|
||||||
|
DateTime parsedTime = DateTime.parse(time);
|
||||||
|
int hour = parsedTime.hour;
|
||||||
|
|
||||||
|
if (hour >= 5 && hour < 12) {
|
||||||
|
return 'Selamat Pagi';
|
||||||
|
} else if (hour >= 12 && hour < 15) {
|
||||||
|
return 'Selamat Siang';
|
||||||
|
} else if (hour >= 15 && hour < 18) {
|
||||||
|
return 'Selamat Sore';
|
||||||
|
} else {
|
||||||
|
return 'Selamat Malam';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import 'package:agrilink_vocpro/features/home/view/home_screen.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class DashboardProvider extends ChangeNotifier {
|
||||||
|
int _currentIndex = 0;
|
||||||
|
int get currentIndex => _currentIndex;
|
||||||
|
|
||||||
|
final date = DateTime.now();
|
||||||
|
|
||||||
|
void setCurrentIndex(int index) {
|
||||||
|
_currentIndex = index;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Widget> _screens = [
|
||||||
|
const HomeScreen(),
|
||||||
|
const Center(child: Text('Control')),
|
||||||
|
const Center(child: Text('Plants')),
|
||||||
|
const Center(child: Text('Settings')),
|
||||||
|
];
|
||||||
|
|
||||||
|
List<Widget> get screens => _screens;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
import 'package:agrilink_vocpro/features/dashboard/provider/dashboard_provider.dart';
|
||||||
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../../core/constant/app_color.dart';
|
||||||
|
|
||||||
|
class DashboardScreen extends StatelessWidget {
|
||||||
|
const DashboardScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Consumer<DashboardProvider>(builder: (context, provider, child) {
|
||||||
|
return Scaffold(
|
||||||
|
body: provider.screens[provider.currentIndex],
|
||||||
|
bottomNavigationBar: BottomNavigationBar(
|
||||||
|
iconSize: 24,
|
||||||
|
selectedFontSize: 12,
|
||||||
|
selectedItemColor: AppColor.secondary,
|
||||||
|
unselectedFontSize: 12,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
type: BottomNavigationBarType.fixed,
|
||||||
|
currentIndex: provider.currentIndex,
|
||||||
|
onTap: provider.setCurrentIndex,
|
||||||
|
items: const [
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(BootstrapIcons.house),
|
||||||
|
activeIcon: Icon(BootstrapIcons.house_fill),
|
||||||
|
label: 'Home',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(BootstrapIcons.toggle_off),
|
||||||
|
activeIcon: Icon(BootstrapIcons.toggle_on),
|
||||||
|
label: 'Control',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(BootstrapIcons.flower1),
|
||||||
|
activeIcon: Icon(BootstrapIcons.flower1),
|
||||||
|
label: 'Plants',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(BootstrapIcons.gear),
|
||||||
|
activeIcon: Icon(BootstrapIcons.gear_fill),
|
||||||
|
label: 'Setting',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class HomeProvider extends ChangeNotifier {
|
||||||
|
final DateTime currentDate = DateTime.now();
|
||||||
|
}
|
||||||
145
agrilink_vocpro/lib/features/home/view/home_screen.dart
Normal file
145
agrilink_vocpro/lib/features/home/view/home_screen.dart
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
import 'package:agrilink_vocpro/core/constant/app_color.dart';
|
||||||
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
|
import 'package:agrilink_vocpro/core/extension/extention.dart';
|
||||||
|
import 'package:agrilink_vocpro/features/home/provider/home_provider.dart';
|
||||||
|
import 'package:agrilink_vocpro/features/home/widgets/data_display_widget.dart';
|
||||||
|
import 'package:agrilink_vocpro/features/humidity/view/humidity_screen.dart';
|
||||||
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class HomeScreen extends StatelessWidget {
|
||||||
|
const HomeScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(
|
||||||
|
'Home',
|
||||||
|
style: AppTheme.titleMedium,
|
||||||
|
),
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
child: RefreshIndicator(
|
||||||
|
onRefresh: () async {
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
},
|
||||||
|
child: ListView(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${getGreeting(DateTime.now().toString())}, Fikril',
|
||||||
|
style: AppTheme.titleLarge,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Consumer<HomeProvider>(builder: (context, provider, child) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
height: MediaQuery.of(context).size.height * 0.17,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.secondary,
|
||||||
|
image: const DecorationImage(
|
||||||
|
image:
|
||||||
|
AssetImage('assets/images/green_house_image.jpg'),
|
||||||
|
fit: BoxFit.cover),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.ternary.withAlpha(200),
|
||||||
|
borderRadius: BorderRadius.circular(32),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8, horizontal: 16),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text("Fikril's Greenhouse",
|
||||||
|
style: AppTheme.labelMedium
|
||||||
|
.copyWith(color: Colors.white)),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 12, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.primary,
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
dateFormater(DateTime.now().toString()),
|
||||||
|
style: AppTheme.labelMedium
|
||||||
|
.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text('Recent Activity', style: AppTheme.titleMedium),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
GridView(
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
shrinkWrap: true,
|
||||||
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 2,
|
||||||
|
crossAxisSpacing: 16,
|
||||||
|
mainAxisSpacing: 16,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
DataDisplayerWidget(
|
||||||
|
title: 'Humidity',
|
||||||
|
subtitle: 'kelembaban udara',
|
||||||
|
value: '60',
|
||||||
|
unit: '%',
|
||||||
|
icon: BootstrapIcons.droplet_half,
|
||||||
|
textColor: Colors.white,
|
||||||
|
color: AppColor.secondary,
|
||||||
|
iconColor: Colors.white,
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const HumidityScreen()));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const DataDisplayerWidget(
|
||||||
|
title: 'Temperature',
|
||||||
|
subtitle: 'suhu greenhouse',
|
||||||
|
value: '28',
|
||||||
|
unit: '°C',
|
||||||
|
icon: BootstrapIcons.thermometer_half,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
const DataDisplayerWidget(
|
||||||
|
title: 'Light',
|
||||||
|
subtitle: 'intensitas cahaya',
|
||||||
|
value: '1000',
|
||||||
|
unit: 'lux',
|
||||||
|
icon: BootstrapIcons.sun,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
const DataDisplayerWidget(
|
||||||
|
title: 'Soil Moisture',
|
||||||
|
subtitle: 'kelembaban tanah',
|
||||||
|
value: '40',
|
||||||
|
unit: '%',
|
||||||
|
icon: Icons.water_outlined,
|
||||||
|
color: Colors.white,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class DataDisplayerWidget extends StatelessWidget {
|
||||||
|
const DataDisplayerWidget({
|
||||||
|
super.key,
|
||||||
|
required this.title,
|
||||||
|
required this.subtitle,
|
||||||
|
required this.value,
|
||||||
|
required this.icon,
|
||||||
|
required this.color,
|
||||||
|
this.iconColor = Colors.teal,
|
||||||
|
this.textColor = Colors.black,
|
||||||
|
required this.unit,
|
||||||
|
this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final String subtitle;
|
||||||
|
final String value;
|
||||||
|
final IconData icon;
|
||||||
|
final Color color;
|
||||||
|
final Color iconColor;
|
||||||
|
final Color textColor;
|
||||||
|
final String unit;
|
||||||
|
final VoidCallback? onTap;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
onTap != null ? onTap!() : null;
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: color,
|
||||||
|
padding: const EdgeInsets.all(12), // Padding di dalam button
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(16), // Bentuk sudut yang bundar
|
||||||
|
),
|
||||||
|
elevation: 20, // Efek bayangan
|
||||||
|
shadowColor: Colors.grey.withOpacity(0.2),
|
||||||
|
),
|
||||||
|
child: SizedBox(
|
||||||
|
height:
|
||||||
|
MediaQuery.of(context).size.height * 0.2, // Mengatur tinggi button
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Icon(icon, color: iconColor, size: 32),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: AppTheme.labelMedium.copyWith(color: textColor),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
subtitle,
|
||||||
|
style: AppTheme.labelSmall
|
||||||
|
.copyWith(color: textColor.withOpacity(0.5)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
value,
|
||||||
|
style: AppTheme.headline1.copyWith(color: textColor),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(unit,
|
||||||
|
style: AppTheme.titleMedium.copyWith(color: textColor)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import 'package:agrilink_vocpro/core/constant/app_color.dart';
|
||||||
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
|
import 'package:agrilink_vocpro/features/humidity/widgets/circle_chart.dart';
|
||||||
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class HumidityScreen extends StatelessWidget {
|
||||||
|
const HumidityScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('Humidity', style: AppTheme.titleLarge),
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
actions: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: 16),
|
||||||
|
child: Icon(
|
||||||
|
BootstrapIcons.droplet_half,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
child: ListView(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height * 0.05,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 320,
|
||||||
|
width: double.infinity,
|
||||||
|
child: CircleChart(humidityPercentage: 60.5),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
110
agrilink_vocpro/lib/features/humidity/widgets/circle_chart.dart
Normal file
110
agrilink_vocpro/lib/features/humidity/widgets/circle_chart.dart
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CircleChart extends StatefulWidget {
|
||||||
|
const CircleChart({super.key, required this.humidityPercentage});
|
||||||
|
|
||||||
|
final double humidityPercentage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CircleChart> createState() => _CircleChartState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CircleChartState extends State<CircleChart> {
|
||||||
|
double currentPercentage = 0;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
Future.delayed(Duration.zero, () async {
|
||||||
|
for (double i = 0; i <= widget.humidityPercentage; i++) {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 25), () {
|
||||||
|
setState(() {
|
||||||
|
currentPercentage = i;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
ShaderMask(
|
||||||
|
shaderCallback: (Rect bounds) {
|
||||||
|
return RadialGradient(
|
||||||
|
center: Alignment.center,
|
||||||
|
radius: 0.6,
|
||||||
|
colors: <Color>[
|
||||||
|
Colors.white,
|
||||||
|
_getAnimatedColor(currentPercentage)
|
||||||
|
],
|
||||||
|
tileMode: TileMode.mirror,
|
||||||
|
).createShader(bounds);
|
||||||
|
},
|
||||||
|
child: PieChart(
|
||||||
|
PieChartData(
|
||||||
|
sections: _createSections(currentPercentage),
|
||||||
|
centerSpaceRadius: MediaQuery.of(context).size.width * 0.25,
|
||||||
|
sectionsSpace: 0,
|
||||||
|
startDegreeOffset: 270,
|
||||||
|
borderData: FlBorderData(show: false),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween<double>(begin: 0, end: currentPercentage),
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(BootstrapIcons.droplet_fill,
|
||||||
|
size: 32, color: _getAnimatedColor(value)),
|
||||||
|
Text(
|
||||||
|
'${value.toStringAsFixed(0)}%', // Animated percentage text
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 28,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PieChartSectionData> _createSections(double humidityPercentage) {
|
||||||
|
return [
|
||||||
|
PieChartSectionData(
|
||||||
|
color: Colors.white,
|
||||||
|
value: humidityPercentage,
|
||||||
|
title: '',
|
||||||
|
radius: 50, // Size of the pie slice
|
||||||
|
titleStyle: const TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PieChartSectionData(
|
||||||
|
color: Colors.white24,
|
||||||
|
value: 100 - humidityPercentage,
|
||||||
|
title: '',
|
||||||
|
radius: 50,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
Color _getAnimatedColor(double percentage) {
|
||||||
|
return Color.lerp(
|
||||||
|
Colors.green, Colors.blue, percentage / widget.humidityPercentage)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
import 'package:agrilink_vocpro/features/splash/view/splash_screen.dart';
|
import 'package:agrilink_vocpro/features/dashboard/provider/dashboard_provider.dart';
|
||||||
|
import 'package:agrilink_vocpro/features/dashboard/view/dashboard_screen.dart';
|
||||||
|
import 'package:agrilink_vocpro/features/home/provider/home_provider.dart';
|
||||||
|
import 'package:agrilink_vocpro/features/home/view/home_screen.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
|
|
@ -11,14 +15,21 @@ class MyApp extends StatelessWidget {
|
||||||
// This widget is the root of your application.
|
// This widget is the root of your application.
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MultiProvider(
|
||||||
title: 'Flutter Demo',
|
providers: [
|
||||||
theme: ThemeData(
|
ChangeNotifierProvider(create: (context) => HomeProvider()),
|
||||||
scaffoldBackgroundColor: Colors.white,
|
ChangeNotifierProvider(create: (context) => DashboardProvider()),
|
||||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
|
],
|
||||||
useMaterial3: true,
|
child: MaterialApp(
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
title: 'Flutter Demo',
|
||||||
|
theme: ThemeData(
|
||||||
|
scaffoldBackgroundColor: Colors.white,
|
||||||
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
|
||||||
|
useMaterial3: true,
|
||||||
|
),
|
||||||
|
home: const DashboardScreen(),
|
||||||
),
|
),
|
||||||
home: const SplashScreen(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
|
bootstrap_icons:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: bootstrap_icons
|
||||||
|
sha256: c3f19c363ceadf5493532108c6db7e3112eef62a371a1b1eb5c67968d95a1aef
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.11.3"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -65,6 +73,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
|
equatable:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: equatable
|
||||||
|
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.5"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -89,6 +105,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.0"
|
||||||
|
fl_chart:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: fl_chart
|
||||||
|
sha256: "94307bef3a324a0d329d3ab77b2f0c6e5ed739185ffc029ed28c0f9b019ea7ef"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.69.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ name: agrilink_vocpro
|
||||||
description: "A new Flutter project."
|
description: "A new Flutter project."
|
||||||
# The following line prevents the package from being accidentally published to
|
# The following line prevents the package from being accidentally published to
|
||||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
# The following defines the version and build number for your application.
|
# The following defines the version and build number for your application.
|
||||||
# A version number is three numbers separated by dots, like 1.2.43
|
# A version number is three numbers separated by dots, like 1.2.43
|
||||||
|
|
@ -31,7 +31,6 @@ dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
|
|
@ -41,6 +40,8 @@ dependencies:
|
||||||
dio: ^5.7.0
|
dio: ^5.7.0
|
||||||
go_router: ^14.2.7
|
go_router: ^14.2.7
|
||||||
flutter_screenutil: ^5.9.3
|
flutter_screenutil: ^5.9.3
|
||||||
|
bootstrap_icons: ^1.11.3
|
||||||
|
fl_chart: ^0.69.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
@ -58,15 +59,15 @@ dev_dependencies:
|
||||||
|
|
||||||
# The following section is specific to Flutter packages.
|
# The following section is specific to Flutter packages.
|
||||||
flutter:
|
flutter:
|
||||||
|
|
||||||
# The following line ensures that the Material Icons font is
|
# The following line ensures that the Material Icons font is
|
||||||
# included with your application, so that you can use the icons in
|
# included with your application, so that you can use the icons in
|
||||||
# the material Icons class.
|
# the material Icons class.
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
# assets:
|
assets:
|
||||||
# - images/a_dot_burr.jpeg
|
- assets/images/
|
||||||
|
- assets/icons/
|
||||||
# - images/a_dot_ham.jpeg
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user