diff --git a/lib/core/container/export_vmod.dart b/lib/core/container/export_vmod.dart index 64d9fa1..8fea4c5 100644 --- a/lib/core/container/export_vmod.dart +++ b/lib/core/container/export_vmod.dart @@ -11,9 +11,9 @@ export 'package:rijig_mobile/features/auth/service/otp_service.dart'; export 'package:rijig_mobile/globaldata/trash/trash_repository.dart'; export 'package:rijig_mobile/globaldata/trash/trash_service.dart'; export 'package:rijig_mobile/globaldata/trash/trash_viewmodel.dart'; -export 'package:rijig_mobile/features/home/presentation/viewmodel/about_vmod.dart'; -export 'package:rijig_mobile/features/home/repositories/about_repository.dart'; -export 'package:rijig_mobile/features/home/service/about_service.dart'; +export 'package:rijig_mobile/globaldata/about/about_vmod.dart'; +export 'package:rijig_mobile/globaldata/about/about_repository.dart'; +export 'package:rijig_mobile/globaldata/about/about_service.dart'; export 'package:rijig_mobile/globaldata/article/article_repository.dart'; export 'package:rijig_mobile/globaldata/article/article_service.dart'; export 'package:rijig_mobile/globaldata/article/article_vmod.dart'; diff --git a/lib/core/router.dart b/lib/core/router.dart index 60a55d1..0ca86e9 100644 --- a/lib/core/router.dart +++ b/lib/core/router.dart @@ -45,6 +45,7 @@ final router = GoRouter( // Rute untuk halaman-halaman utama GoRoute(path: '/home', builder: (context, state) => HomeScreen()), + GoRoute(path: '/dataperforma', builder: (context, state) => DatavisualizedScreen()), GoRoute(path: '/activity', builder: (context, state) => ActivityScreen()), GoRoute( path: '/requestpickup', diff --git a/lib/core/utils/exportimportview.dart b/lib/core/utils/exportimportview.dart index 4ebb0f2..40e2b74 100644 --- a/lib/core/utils/exportimportview.dart +++ b/lib/core/utils/exportimportview.dart @@ -3,6 +3,7 @@ export 'package:rijig_mobile/core/utils/navigation.dart'; export 'package:rijig_mobile/features/activity/presentation/screen/activity_screen.dart'; export 'package:rijig_mobile/features/cart/presentation/screens/cart_screen.dart'; export 'package:rijig_mobile/features/home/presentation/screen/home_screen.dart'; +export 'package:rijig_mobile/features/home/datavisualized/presentation/screen/datavisualized_screen.dart'; export 'package:rijig_mobile/features/profil/presentation/screen/profil_screen.dart'; export 'package:rijig_mobile/features/requestpick/presentation/screen/requestpickup_screen.dart'; export 'package:rijig_mobile/features/auth/presentation/screen/inputpin_screen.dart'; diff --git a/lib/features/home/datavisualized/presentation/screen/datavisualized_screen.dart b/lib/features/home/datavisualized/presentation/screen/datavisualized_screen.dart new file mode 100644 index 0000000..2a6ddf0 --- /dev/null +++ b/lib/features/home/datavisualized/presentation/screen/datavisualized_screen.dart @@ -0,0 +1,755 @@ +import 'package:charts_painter/chart.dart'; +import 'package:flutter/material.dart'; +import 'package:rijig_mobile/core/utils/guide.dart'; +import 'package:rijig_mobile/widget/appbar.dart'; +import 'package:el_tooltip/el_tooltip.dart'; + +class DatavisualizedScreen extends StatefulWidget { + const DatavisualizedScreen({super.key}); + + @override + State createState() => _DatavisualizedScreenState(); +} + +class _DatavisualizedScreenState extends State { + final List dataSampahTerjual = [ + 15.5, + 23.2, + 18.7, + 31.4, + 28.9, + 42.1, + 35.8, + ]; + final List namaHari = [ + 'Sen', + 'Sel', + 'Rab', + 'Kam', + 'Jum', + 'Sab', + 'Min', + ]; + + int? selectedIndex; + final List tooltipControllers = []; + + @override + void initState() { + super.initState(); + // Initialize tooltip controllers + for (int i = 0; i < dataSampahTerjual.length; i++) { + tooltipControllers.add(ElTooltipController()); + } + } + + @override + void dispose() { + _hideAllTooltips(); + for (var controller in tooltipControllers) { + controller.dispose(); + } + super.dispose(); + } + + // Simple method to hide all tooltips + void _hideAllTooltips() { + for (var controller in tooltipControllers) { + try { + controller.hide(); + } catch (e) { + // Ignore errors - controller might already be disposed + } + } + } + + // Main selection handler - used by both bar clicks and day name clicks + void _handleSelection(int index) { + // If same item is selected, deselect it + if (selectedIndex == index) { + _clearSelection(); + return; + } + + // Hide all tooltips first + _hideAllTooltips(); + + // Update selection + setState(() { + selectedIndex = index; + }); + + // Show tooltip after a brief delay + Future.delayed(const Duration(milliseconds: 100), () { + if (mounted && selectedIndex == index) { + tooltipControllers[index].show(); + } + }); + } + + // Clear selection and hide tooltips + void _clearSelection() { + _hideAllTooltips(); + setState(() { + selectedIndex = null; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar(judul: "Performa"), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Header summary card + _buildHeaderCard(), + const SizedBox(height: 24), + + // Chart section + _buildChartSection(), + const SizedBox(height: 12), + + // Day labels (clickable) + _buildDayLabels(), + const SizedBox(height: 16), + + // Selected item info card + if (selectedIndex != null) _buildSelectedItemCard(), + + // Statistics cards + _buildStatisticsCards(), + ], + ), + ), + ); + } + + Widget _buildHeaderCard() { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.blue.shade50, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.blue.shade200), + ), + child: Row( + children: [ + Icon(Icons.recycling, color: Colors.blue.shade700, size: 28), + const SizedBox(width: 12), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Sampah Terjual Minggu Ini', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.blue.shade700, + ), + ), + Text( + 'Total: ${dataSampahTerjual.reduce((a, b) => a + b).toStringAsFixed(1)} kg', + style: TextStyle( + fontSize: 14, + color: Colors.blue.shade600, + ), + ), + ], + ), + ], + ), + ); + } + + Widget _buildChartSection() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Grafik Penjualan Sampah (kg)', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.grey.shade800, + ), + ), + const SizedBox(height: 16), + Container( + height: 300, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.grey.shade300, + blurRadius: 8, + offset: const Offset(0, 4), + ), + ], + ), + child: Stack( + children: [ + // Chart + Chart( + state: ChartState( + behaviour: ChartBehaviour( + onItemClicked: (item) { + final clickedIndex = dataSampahTerjual.indexWhere( + (data) => data == item.item.value, + ); + if (clickedIndex != -1) { + _handleSelection(clickedIndex); + } + }, + ), + data: ChartData.fromList( + dataSampahTerjual + .asMap() + .entries + .map((entry) => ChartItem(entry.value)) + .toList(), + ), + itemOptions: BarItemOptions( + padding: const EdgeInsets.symmetric(horizontal: 4), + barItemBuilder: (itemBuilderData) { + final isSelected = selectedIndex == itemBuilderData.itemIndex; + return BarItem( + color: isSelected ? Colors.orange.shade600 : primaryColor, + ); + }, + ), + backgroundDecorations: [ + GridDecoration( + showVerticalGrid: false, + showHorizontalGrid: true, + horizontalAxisStep: 10, + gridColor: Colors.grey.shade300, + ), + ], + foregroundDecorations: [ + SparkLineDecoration( + lineColor: Colors.orange.shade400, + lineWidth: 2, + ), + ], + ), + height: 250, + ), + // Tooltips overlay + ..._buildTooltipOverlays(), + ], + ), + ), + ], + ); + } + + List _buildTooltipOverlays() { + return dataSampahTerjual.asMap().entries.map((entry) { + final index = entry.key; + final value = entry.value; + final chartWidth = MediaQuery.of(context).size.width - 64; + final barWidth = chartWidth / dataSampahTerjual.length; + + return Positioned( + left: (index * barWidth) + (barWidth / 2) - 20, + top: 50, + bottom: 50, + width: 40, + child: ElTooltip( + controller: tooltipControllers[index], + position: ElTooltipPosition.topCenter, + color: Colors.black87, + showArrow: true, + showModal: false, + showChildAboveOverlay: false, + content: _buildTooltipContent(index, value), + child: Container(width: 40, color: Colors.transparent), + ), + ); + }).toList(); + } + + Widget _buildTooltipContent(int index, double value) { + return GestureDetector( + onTap: () { + tooltipControllers[index].hide(); + _showDetailDialog(index); + }, + child: Container( + constraints: const BoxConstraints(minWidth: 100), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + namaHari[index], + style: const TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 4), + Text( + '${value.toStringAsFixed(1)} kg', + style: const TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 6), + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + decoration: BoxDecoration( + color: Colors.white24, + borderRadius: BorderRadius.circular(10), + ), + child: const Text( + '👆 Tap untuk detail', + style: TextStyle(color: Colors.white70, fontSize: 10), + ), + ), + ], + ), + ), + ); + } + + Widget _buildDayLabels() { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: namaHari.asMap().entries.map((entry) { + final index = entry.key; + final isSelected = selectedIndex == index; + + return GestureDetector( + onTap: () => _handleSelection(index), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: isSelected ? Colors.orange.shade100 : Colors.transparent, + borderRadius: BorderRadius.circular(6), + ), + child: Text( + entry.value, + style: TextStyle( + fontSize: 12, + fontWeight: isSelected ? FontWeight.bold : FontWeight.w500, + color: isSelected ? Colors.orange.shade700 : Colors.grey.shade700, + ), + ), + ), + ); + }).toList(), + ), + ); + } + + Widget _buildSelectedItemCard() { + return Container( + margin: const EdgeInsets.only(bottom: 16), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.orange.shade50, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.orange.shade200), + ), + child: Row( + children: [ + Icon(Icons.info_outline, color: Colors.orange.shade700), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Data Terpilih: ${namaHari[selectedIndex!]}', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.orange.shade700, + fontSize: 14, + ), + ), + Text( + 'Sampah terjual: ${dataSampahTerjual[selectedIndex!].toStringAsFixed(1)} kg', + style: TextStyle( + color: Colors.orange.shade600, + fontSize: 13, + ), + ), + ], + ), + ), + // Close button + GestureDetector( + onTap: _clearSelection, + child: Container( + padding: const EdgeInsets.all(4), + margin: const EdgeInsets.only(right: 8), + decoration: BoxDecoration( + color: Colors.orange.shade200, + borderRadius: BorderRadius.circular(12), + ), + child: Icon( + Icons.close, + size: 16, + color: Colors.orange.shade700, + ), + ), + ), + // Detail button + GestureDetector( + onTap: () => _navigateToDetailPage(selectedIndex!), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + decoration: BoxDecoration( + color: Colors.orange.shade700, + borderRadius: BorderRadius.circular(6), + ), + child: const Text( + 'Detail', + style: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ); + } + + Widget _buildStatisticsCards() { + return Column( + children: [ + const SizedBox(height: 8), + Row( + children: [ + Expanded( + child: _buildStatCard( + 'Rata-rata', + '${(dataSampahTerjual.reduce((a, b) => a + b) / dataSampahTerjual.length).toStringAsFixed(1)} kg', + Icons.trending_up, + Colors.blue, + ), + ), + const SizedBox(width: 12), + Expanded( + child: _buildStatCard( + 'Tertinggi', + '${dataSampahTerjual.reduce((a, b) => a > b ? a : b).toStringAsFixed(1)} kg', + Icons.star, + Colors.orange, + ), + ), + ], + ), + const SizedBox(height: 12), + Row( + children: [ + Expanded( + child: _buildStatCard( + 'Terendah', + '${dataSampahTerjual.reduce((a, b) => a < b ? a : b).toStringAsFixed(1)} kg', + Icons.trending_down, + Colors.red, + ), + ), + const SizedBox(width: 12), + Expanded( + child: _buildStatCard( + 'Hari Aktif', + '${dataSampahTerjual.where((data) => data > 0).length} hari', + Icons.calendar_today, + Colors.green, + ), + ), + ], + ), + ], + ); + } + + Widget _buildStatCard(String title, String value, IconData icon, Color color) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: color.withValues(alpha: 0.1), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: color.withValues(alpha: 0.3)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon(icon, color: color, size: 24), + const SizedBox(height: 8), + Text( + title, + style: TextStyle( + fontSize: 12, + color: Colors.grey.shade600, + fontWeight: FontWeight.w500, + ), + ), + const SizedBox(height: 4), + Text( + value, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: color, + ), + ), + ], + ), + ); + } + + void _showDetailDialog(int index) { + showDialog( + context: context, + builder: (context) => AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + title: Row( + children: [ + Icon(Icons.bar_chart, color: primaryColor), + const SizedBox(width: 8), + Text('Detail ${namaHari[index]}'), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildDialogInfoRow('Hari:', namaHari[index]), + const SizedBox(height: 8), + _buildDialogInfoRow( + 'Jumlah:', + '${dataSampahTerjual[index].toStringAsFixed(1)} kg', + ), + const SizedBox(height: 8), + _buildDialogInfoRow( + 'Persentase:', + '${((dataSampahTerjual[index] / dataSampahTerjual.reduce((a, b) => a + b)) * 100).toStringAsFixed(1)}%', + ), + const SizedBox(height: 8), + _buildDialogInfoRow( + 'Ranking:', + '#${_getRanking(index)} dari ${dataSampahTerjual.length} hari', + ), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('Tutup'), + ), + ElevatedButton( + onPressed: () { + Navigator.pop(context); + _navigateToDetailPage(index); + }, + style: ElevatedButton.styleFrom( + backgroundColor: primaryColor, + foregroundColor: Colors.white, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + ), + child: const Text('Lihat Detail'), + ), + ], + ), + ); + } + + Widget _buildDialogInfoRow(String label, String value) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 80, + child: Text( + label, + style: TextStyle( + fontWeight: FontWeight.w500, + color: Colors.grey.shade600, + ), + ), + ), + Expanded( + child: Text( + value, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + ], + ); + } + + int _getRanking(int index) { + final sortedData = dataSampahTerjual + .asMap() + .entries + .toList() + ..sort((a, b) => b.value.compareTo(a.value)); + return sortedData.indexWhere((entry) => entry.key == index) + 1; + } + + void _navigateToDetailPage(int index) { + _hideAllTooltips(); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => DetailHariScreen( + hari: namaHari[index], + jumlahSampah: dataSampahTerjual[index], + index: index, + allData: dataSampahTerjual, + allDays: namaHari, + ), + ), + ).then((_) { + if (mounted) { + _clearSelection(); + } + }); + } +} + +class DetailHariScreen extends StatelessWidget { + final String hari; + final double jumlahSampah; + final int index; + final List allData; + final List allDays; + + const DetailHariScreen({ + super.key, + required this.hari, + required this.jumlahSampah, + required this.index, + required this.allData, + required this.allDays, + }); + + @override + Widget build(BuildContext context) { + final totalSampah = allData.reduce((a, b) => a + b); + final persentase = (jumlahSampah / totalSampah) * 100; + final ranking = _getRanking(); + + return Scaffold( + appBar: AppBar( + title: Text('Detail $hari'), + backgroundColor: primaryColor, + foregroundColor: Colors.white, + ), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Card( + elevation: 4, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Container( + width: double.infinity, + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + gradient: LinearGradient( + colors: [primaryColor.withValues(alpha: 0.1), Colors.white], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: primaryColor, + borderRadius: BorderRadius.circular(10), + ), + child: const Icon( + Icons.recycling, + color: Colors.white, + size: 24, + ), + ), + const SizedBox(width: 16), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Penjualan Sampah', + style: TextStyle( + fontSize: 16, + color: Colors.grey.shade600, + ), + ), + Text( + hari, + style: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ], + ), + const SizedBox(height: 16), + Text( + '${jumlahSampah.toStringAsFixed(1)} kg', + style: TextStyle( + fontSize: 32, + fontWeight: FontWeight.bold, + color: primaryColor, + ), + ), + const SizedBox(height: 8), + Text( + 'Persentase: ${persentase.toStringAsFixed(1)}%', + style: TextStyle( + fontSize: 16, + color: Colors.grey.shade600, + ), + ), + Text( + 'Ranking: #$ranking dari ${allData.length} hari', + style: TextStyle( + fontSize: 16, + color: Colors.grey.shade600, + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + } + + int _getRanking() { + final sortedData = allData + .asMap() + .entries + .toList() + ..sort((a, b) => b.value.compareTo(a.value)); + return sortedData.indexWhere((entry) => entry.key == index) + 1; + } +} \ No newline at end of file diff --git a/lib/features/home/presentation/components/about_comp.dart b/lib/features/home/presentation/components/about_comp.dart index 5d97f02..88ebef4 100644 --- a/lib/features/home/presentation/components/about_comp.dart +++ b/lib/features/home/presentation/components/about_comp.dart @@ -4,7 +4,7 @@ import 'package:carousel_slider/carousel_slider.dart'; import 'package:provider/provider.dart'; import 'package:rijig_mobile/core/router.dart'; import 'package:rijig_mobile/core/utils/guide.dart'; -import 'package:rijig_mobile/features/home/presentation/viewmodel/about_vmod.dart'; +import 'package:rijig_mobile/globaldata/about/about_vmod.dart'; import 'package:rijig_mobile/widget/skeletonize.dart'; class AboutComponent extends StatefulWidget { diff --git a/lib/features/home/presentation/components/about_detail_comp.dart b/lib/features/home/presentation/components/about_detail_comp.dart index 615c978..fcc8c5f 100644 --- a/lib/features/home/presentation/components/about_detail_comp.dart +++ b/lib/features/home/presentation/components/about_detail_comp.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:provider/provider.dart'; -import 'package:rijig_mobile/features/home/presentation/viewmodel/about_vmod.dart'; +import 'package:rijig_mobile/globaldata/about/about_vmod.dart'; import 'package:rijig_mobile/widget/appbar.dart'; import 'package:rijig_mobile/widget/skeletonize.dart'; diff --git a/lib/features/home/presentation/screen/home_screen.dart b/lib/features/home/presentation/screen/home_screen.dart index 79dc9bc..8babd01 100644 --- a/lib/features/home/presentation/screen/home_screen.dart +++ b/lib/features/home/presentation/screen/home_screen.dart @@ -7,10 +7,11 @@ import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; import 'package:iconsax_flutter/iconsax_flutter.dart'; import 'package:provider/provider.dart'; +import 'package:rijig_mobile/core/router.dart'; import 'package:rijig_mobile/core/utils/guide.dart'; import 'package:rijig_mobile/features/home/presentation/components/about_comp.dart'; import 'package:rijig_mobile/features/home/presentation/components/article_list.dart'; -import 'package:rijig_mobile/features/home/presentation/viewmodel/about_vmod.dart'; +import 'package:rijig_mobile/globaldata/about/about_vmod.dart'; import 'package:rijig_mobile/globaldata/article/article_vmod.dart'; import 'package:rijig_mobile/widget/card_withicon.dart'; @@ -89,7 +90,9 @@ class _HomeScreenState extends State { icon: Iconsax.trash, text: 'Sampah', number: '245 kg', - onTap: () {}, + onTap: () { + router.push('/dataperforma'); + }, ), CardWithIcon( icon: Iconsax.timer, diff --git a/lib/features/home/model/about_model.dart b/lib/globaldata/about/about_model.dart similarity index 100% rename from lib/features/home/model/about_model.dart rename to lib/globaldata/about/about_model.dart diff --git a/lib/features/home/repositories/about_repository.dart b/lib/globaldata/about/about_repository.dart similarity index 91% rename from lib/features/home/repositories/about_repository.dart rename to lib/globaldata/about/about_repository.dart index 681b442..65ee705 100644 --- a/lib/features/home/repositories/about_repository.dart +++ b/lib/globaldata/about/about_repository.dart @@ -1,5 +1,5 @@ import 'package:rijig_mobile/core/api/api_services.dart'; -import 'package:rijig_mobile/features/home/model/about_model.dart'; +import 'package:rijig_mobile/globaldata/about/about_model.dart'; class AboutRepository { final Https _https = Https(); diff --git a/lib/features/home/service/about_service.dart b/lib/globaldata/about/about_service.dart similarity index 77% rename from lib/features/home/service/about_service.dart rename to lib/globaldata/about/about_service.dart index d52ff81..1b54b72 100644 --- a/lib/features/home/service/about_service.dart +++ b/lib/globaldata/about/about_service.dart @@ -1,5 +1,5 @@ -import 'package:rijig_mobile/features/home/repositories/about_repository.dart'; -import 'package:rijig_mobile/features/home/model/about_model.dart'; +import 'package:rijig_mobile/globaldata/about/about_repository.dart'; +import 'package:rijig_mobile/globaldata/about/about_model.dart'; class AboutService { final AboutRepository _aboutRepository; diff --git a/lib/features/home/presentation/viewmodel/about_vmod.dart b/lib/globaldata/about/about_vmod.dart similarity index 88% rename from lib/features/home/presentation/viewmodel/about_vmod.dart rename to lib/globaldata/about/about_vmod.dart index ec97142..8b1fbf0 100644 --- a/lib/features/home/presentation/viewmodel/about_vmod.dart +++ b/lib/globaldata/about/about_vmod.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:rijig_mobile/features/home/service/about_service.dart'; -import 'package:rijig_mobile/features/home/model/about_model.dart'; +import 'package:rijig_mobile/globaldata/about/about_service.dart'; +import 'package:rijig_mobile/globaldata/about/about_model.dart'; class AboutViewModel extends ChangeNotifier { final AboutService _aboutService; diff --git a/pubspec.lock b/pubspec.lock index fd8e9e2..5d022c7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + charts_painter: + dependency: "direct main" + description: + name: charts_painter + sha256: "5314ef91979b59b60a869df86caba09e7a3ce56da1fb18530ea7bbd2da77fa70" + url: "https://pub.dev" + source: hosted + version: "3.1.1" checked_yaml: dependency: transitive description: @@ -169,6 +177,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.2" + el_tooltip: + dependency: "direct main" + description: + name: el_tooltip + sha256: "0860b00e9390a31dd98369dc16d3b6fa2668fc52df712bd00e86d8931787fc17" + url: "https://pub.dev" + source: hosted + version: "2.2.1" equatable: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 12dbb28..4fe89bb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,12 +9,14 @@ environment: dependencies: carousel_slider: ^5.0.0 + charts_painter: ^3.1.1 collection: ^1.19.1 concentric_transition: ^1.0.3 connectivity_plus: ^6.1.4 cupertino_icons: ^1.0.8 custom_refresh_indicator: ^4.0.1 device_info_plus: ^11.4.0 + el_tooltip: ^2.2.1 fl_chart: ^1.0.0 flutter: sdk: flutter