feat: add basic route, splash, and login screen

This commit is contained in:
Syaroful 2024-09-23 16:34:20 +07:00
parent 0c4ab9995c
commit 0ce3129da5
24 changed files with 477 additions and 73 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

View File

@ -11,4 +11,5 @@ class AppColor {
static const Color greenTextDark = Color(0xFF00913A); static const Color greenTextDark = Color(0xFF00913A);
static const Color textDisable = Color(0xFFBDBDBD); static const Color textDisable = Color(0xFFBDBDBD);
static const Color textDark = Color(0xFF4B4B51);
} }

View File

@ -7,15 +7,16 @@ class AppTheme {
letterSpacing: 1, letterSpacing: 1,
color: Colors.black, color: Colors.black,
); );
static TextStyle titleLarge = const TextStyle( static TextStyle titleLarge = const TextStyle(
fontSize: 16, fontSize: 17,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Colors.black, color: Colors.black,
); );
static TextStyle titleMedium = const TextStyle( static TextStyle titleMedium = TextStyle(
fontSize: 14, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w400,
color: Colors.black, color: Colors.grey.shade600,
); );
static TextStyle titleSmall = const TextStyle( static TextStyle titleSmall = const TextStyle(
fontSize: 12, fontSize: 12,
@ -23,13 +24,24 @@ class AppTheme {
color: Colors.black, color: Colors.black,
); );
static TextStyle labelLarge = const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black,
);
static TextStyle labelMedium = const TextStyle( static TextStyle labelMedium = const TextStyle(
fontSize: 12, fontSize: 14,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w500,
color: Colors.black, color: Colors.black,
); );
static TextStyle labelSmall = const TextStyle( static TextStyle labelSmall = const TextStyle(
fontSize: 10, fontSize: 12,
fontWeight: FontWeight.w400,
color: Colors.grey,
);
static TextStyle hintStyle = const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Colors.grey, color: Colors.grey,
); );

View File

@ -0,0 +1,57 @@
import 'package:agrilink_vocpro/features/auth/view/login_screen.dart';
import 'package:agrilink_vocpro/features/dashboard/view/dashboard_screen.dart';
import 'package:agrilink_vocpro/features/home/pages/humidity/view/humidity_screen.dart';
import 'package:agrilink_vocpro/features/splash/view/splash_screen.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class AppRoute {
static const String root = '/';
static const String login = '/login';
static const String dashboard = '/dashboard';
static const String home = '/home';
static const String profile = '/profile';
static const String setting = '/setting';
static const String humidity = '/dashboard/humidity';
static const String temperature = '/temperature';
static const String soil = '/soil';
static const String light = '/light';
static const String water = '/water';
static const String acidity = '/acidity';
static final GoRouter router = GoRouter(
initialLocation: root,
routes: [
//splash
GoRoute(
path: root,
builder: (context, state) => const SplashScreen(),
),
//login
GoRoute(
path: login,
builder: (context, state) => const LoginScreen(),
),
//dashboard
GoRoute(
path: dashboard,
builder: (context, state) => const DashboardScreen(),
),
GoRoute(
path: dashboard,
builder: (context, state) => const DashboardScreen(),
routes: [
GoRoute(
path: 'humidity',
builder: (context, state) => const HumidityScreen(),
),
],
),
],
errorBuilder: (context, state) => Scaffold(
body: Center(
child: Text('Error: ${state.error}'),
),
),
);
}

View File

@ -1,7 +1,7 @@
enum ResultState { enum ResultState {
initial, initial,
loading, loading,
noData,
hasData, hasData,
noData,
error, error,
} }

View File

@ -1,6 +1,5 @@
import 'package:agrilink_vocpro/core/constant/app_color.dart'; import 'package:agrilink_vocpro/core/constant/app_color.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class AppButton extends StatelessWidget { class AppButton extends StatelessWidget {
const AppButton({ const AppButton({
@ -24,14 +23,14 @@ class AppButton extends StatelessWidget {
onPressed: onPressed, onPressed: onPressed,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
shadowColor: Colors.transparent, shadowColor: Colors.transparent,
textStyle: TextStyle( textStyle: const TextStyle(
fontSize: 14.sp, fontWeight: FontWeight.w500, fontFamily: 'Onest'), fontSize: 14, fontWeight: FontWeight.w500, fontFamily: 'Urbanist'),
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
foregroundColor: foregroundColor, foregroundColor: foregroundColor,
minimumSize: Size(double.infinity, 48.h), minimumSize: const Size(double.infinity, 48),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
side: borderSide ?? BorderSide.none, side: borderSide ?? BorderSide.none,
borderRadius: BorderRadius.circular(10.r), borderRadius: BorderRadius.circular(10),
), ),
), ),
child: Text(text), child: Text(text),

View File

@ -1,9 +1,9 @@
import 'package:agrilink_vocpro/core/constant/app_color.dart'; import 'package:agrilink_vocpro/core/constant/app_color.dart';
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class CustomTextField extends StatelessWidget { class AppTextfield extends StatelessWidget {
const CustomTextField({ const AppTextfield({
super.key, super.key,
required this.controller, required this.controller,
this.hintText = 'Enter Here', this.hintText = 'Enter Here',
@ -20,16 +20,16 @@ class CustomTextField extends StatelessWidget {
controller: controller, controller: controller,
decoration: InputDecoration( decoration: InputDecoration(
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: AppColor.textDisable, width: 1.r), borderSide: const BorderSide(color: AppColor.textDisable, width: 1),
borderRadius: BorderRadius.circular(8.r), borderRadius: BorderRadius.circular(8),
gapPadding: 10.r), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: AppColor.primary, width: 1.r), borderSide: const BorderSide(color: AppColor.primary, width: 1),
borderRadius: BorderRadius.circular(8.r), borderRadius: BorderRadius.circular(8),
gapPadding: 10.r), ),
hintText: hintText, hintText: hintText,
// hintStyle: AppTheme.hintStyle, hintStyle: AppTheme.hintStyle,
suffixIcon: suffixIcon), suffixIcon: (suffixIcon != null) ? suffixIcon : null),
); );
} }
} }

View File

@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
class AuthProvider extends ChangeNotifier {
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
void controllerClear() {
emailController.clear();
passwordController.clear();
notifyListeners();
}
}

View File

@ -0,0 +1,74 @@
import 'package:agrilink_vocpro/core/constant/app_color.dart';
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:agrilink_vocpro/core/widgets/app_button.dart';
import 'package:agrilink_vocpro/core/widgets/app_textfield.dart';
import 'package:agrilink_vocpro/features/auth/provider/auth_provider.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
class LoginScreen extends StatelessWidget {
const LoginScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: SafeArea(
child: Consumer<AuthProvider>(builder: (context, authP, child) {
return ListView(
padding: const EdgeInsets.all(16),
children: [
const SizedBox(height: 40),
Text(
'Hello Wellcome back 👋',
style: AppTheme.titleLarge,
),
Text(
'Happy to have you back',
style: AppTheme.titleMedium,
),
const SizedBox(height: 40),
Text('Email address', style: AppTheme.labelLarge),
const SizedBox(height: 4),
AppTextfield(
controller: authP.emailController,
hintText: 'Masukkan username',
),
const SizedBox(height: 24),
Text('Password', style: AppTheme.labelLarge),
const SizedBox(height: 4),
AppTextfield(
controller: authP.passwordController,
hintText: 'Masukkan password',
),
const SizedBox(height: 24),
GestureDetector(
onTap: () {
print('Forgot password?');
},
child: Text(
'Forgot password?',
textAlign: TextAlign.end,
style: AppTheme.labelMedium
.copyWith(color: AppColor.secondary),
),
),
const SizedBox(height: 24),
AppButton(
onPressed: () {
GoRouter.of(context).go(AppRoute.dashboard);
},
text: 'Login'),
],
);
}),
),
),
);
}
}

View File

@ -1,7 +1,7 @@
import 'package:agrilink_vocpro/core/constant/app_color.dart';
import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/constant/app_theme.dart';
import 'package:agrilink_vocpro/features/humidity/widgets/circle_chart.dart'; import 'package:agrilink_vocpro/features/home/pages/humidity/widgets/circle_chart.dart';
import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class HumidityScreen extends StatelessWidget { class HumidityScreen extends StatelessWidget {
@ -11,8 +11,12 @@ class HumidityScreen extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('Humidity', style: AppTheme.titleLarge), title: Text('Humidity', style: AppTheme.labelLarge),
centerTitle: true, centerTitle: true,
leading: IconButton(
icon: const Icon(CupertinoIcons.back),
onPressed: () => Navigator.pop(context),
),
backgroundColor: Colors.white, backgroundColor: Colors.white,
actions: const [ actions: const [
Padding( Padding(
@ -33,7 +37,10 @@ class HumidityScreen extends StatelessWidget {
const SizedBox( const SizedBox(
height: 320, height: 320,
width: double.infinity, width: double.infinity,
child: CircleChart(humidityPercentage: 60.5), child: CircleChart(
percentage: 60.5,
icon: BootstrapIcons.droplet_half,
),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
], ],

View File

@ -1,11 +1,15 @@
import 'package:bootstrap_icons/bootstrap_icons.dart';
import 'package:fl_chart/fl_chart.dart'; import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class CircleChart extends StatefulWidget { class CircleChart extends StatefulWidget {
const CircleChart({super.key, required this.humidityPercentage}); const CircleChart({
super.key,
required this.percentage,
required this.icon,
});
final double humidityPercentage; final double percentage;
final IconData icon;
@override @override
State<CircleChart> createState() => _CircleChartState(); State<CircleChart> createState() => _CircleChartState();
@ -17,7 +21,7 @@ class _CircleChartState extends State<CircleChart> {
void initState() { void initState() {
super.initState(); super.initState();
Future.delayed(Duration.zero, () async { Future.delayed(Duration.zero, () async {
for (double i = 0; i <= widget.humidityPercentage; i++) { for (double i = 0; i <= widget.percentage; i++) {
await Future.delayed(const Duration(milliseconds: 25), () { await Future.delayed(const Duration(milliseconds: 25), () {
setState(() { setState(() {
currentPercentage = i; currentPercentage = i;
@ -62,8 +66,7 @@ class _CircleChartState extends State<CircleChart> {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon(BootstrapIcons.droplet_fill, Icon(widget.icon, size: 32, color: _getAnimatedColor(value)),
size: 32, color: _getAnimatedColor(value)),
Text( Text(
'${value.toStringAsFixed(0)}%', // Animated percentage text '${value.toStringAsFixed(0)}%', // Animated percentage text
style: const TextStyle( style: const TextStyle(
@ -81,11 +84,11 @@ class _CircleChartState extends State<CircleChart> {
); );
} }
List<PieChartSectionData> _createSections(double humidityPercentage) { List<PieChartSectionData> _createSections(double percentage) {
return [ return [
PieChartSectionData( PieChartSectionData(
color: Colors.white, color: Colors.white,
value: humidityPercentage, value: percentage,
title: '', title: '',
radius: 50, // Size of the pie slice radius: 50, // Size of the pie slice
titleStyle: const TextStyle( titleStyle: const TextStyle(
@ -96,7 +99,7 @@ class _CircleChartState extends State<CircleChart> {
), ),
PieChartSectionData( PieChartSectionData(
color: Colors.white24, color: Colors.white24,
value: 100 - humidityPercentage, value: 100 - percentage,
title: '', title: '',
radius: 50, radius: 50,
), ),
@ -105,6 +108,6 @@ class _CircleChartState extends State<CircleChart> {
Color _getAnimatedColor(double percentage) { Color _getAnimatedColor(double percentage) {
return Color.lerp( return Color.lerp(
Colors.green, Colors.blue, percentage / widget.humidityPercentage)!; Colors.green, Colors.blue, percentage / widget.percentage)!;
} }
} }

View File

@ -0,0 +1,50 @@
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
import 'package:agrilink_vocpro/features/home/pages/humidity/widgets/circle_chart.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SoilMoistureScreen extends StatelessWidget {
const SoilMoistureScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Soil Moisture', style: AppTheme.labelMedium),
centerTitle: true,
backgroundColor: Colors.white,
leading: IconButton(
icon: const Icon(CupertinoIcons.back),
onPressed: () => Navigator.pop(context),
),
actions: const [
Padding(
padding: EdgeInsets.only(right: 16),
child: Icon(
Icons.water_outlined,
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(
percentage: 60.5,
icon: Icons.water_outlined,
),
),
const SizedBox(height: 16),
],
),
),
);
}
}

View File

@ -0,0 +1,48 @@
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
import 'package:bootstrap_icons/bootstrap_icons.dart';
import 'package:flutter/material.dart';
class TemperatureScreen extends StatelessWidget {
const TemperatureScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Temperature', style: AppTheme.titleLarge),
centerTitle: true,
backgroundColor: Colors.white,
actions: const [
Padding(
padding: EdgeInsets.only(right: 16),
child: Icon(
BootstrapIcons.thermometer_half,
color: Colors.red,
),
)
],
),
body: SafeArea(
child: ListView(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.05,
),
Center(
child: SizedBox(
height: 320,
width: 320,
child: CircularProgressIndicator(
strokeWidth: 10,
backgroundColor: Colors.grey.shade200,
value: 0.5,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.red),
),
)),
const SizedBox(height: 16),
],
),
),
);
}
}

View File

@ -1,11 +1,15 @@
import 'package:agrilink_vocpro/core/constant/app_color.dart'; import 'package:agrilink_vocpro/core/constant/app_color.dart';
import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/constant/app_theme.dart';
import 'package:agrilink_vocpro/core/extension/extention.dart'; import 'package:agrilink_vocpro/core/extension/extention.dart';
import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:agrilink_vocpro/features/home/pages/soil_moisture/view/soil_moisture_screen.dart';
import 'package:agrilink_vocpro/features/home/pages/temperature/view/temperature_screen.dart';
import 'package:agrilink_vocpro/features/home/provider/home_provider.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/home/widgets/data_display_widget.dart';
import 'package:agrilink_vocpro/features/humidity/view/humidity_screen.dart'; import 'package:agrilink_vocpro/features/home/pages/humidity/view/humidity_screen.dart';
import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class HomeScreen extends StatelessWidget { class HomeScreen extends StatelessWidget {
@ -14,14 +18,6 @@ class HomeScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar(
title: Text(
'Home',
style: AppTheme.titleMedium,
),
centerTitle: true,
backgroundColor: Colors.white,
),
body: SafeArea( body: SafeArea(
child: RefreshIndicator( child: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
@ -29,12 +25,35 @@ class HomeScreen extends StatelessWidget {
}, },
child: ListView( child: ListView(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
children: [
Row(
children: [
const CircleAvatar(
radius: 24,
backgroundColor: AppColor.primary,
child: Icon(
Icons.person,
color: Colors.white,
size: 24,
),
),
const SizedBox(width: 16),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'${getGreeting(DateTime.now().toString())}, Fikril', getGreeting(DateTime.now().toString()),
style: AppTheme.titleMedium,
),
Text(
'Fikril Mahesaputra',
style: AppTheme.titleLarge, style: AppTheme.titleLarge,
), ),
const SizedBox(height: 12), ],
),
],
),
const SizedBox(height: 24),
Consumer<HomeProvider>(builder: (context, provider, child) { Consumer<HomeProvider>(builder: (context, provider, child) {
return Container( return Container(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
@ -83,7 +102,7 @@ class HomeScreen extends StatelessWidget {
); );
}), }),
const SizedBox(height: 16), const SizedBox(height: 16),
Text('Recent Activity', style: AppTheme.titleMedium), Text('Linked Device', style: AppTheme.titleMedium),
const SizedBox(height: 16), const SizedBox(height: 16),
GridView( GridView(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@ -104,19 +123,22 @@ class HomeScreen extends StatelessWidget {
color: AppColor.secondary, color: AppColor.secondary,
iconColor: Colors.white, iconColor: Colors.white,
onTap: () async { onTap: () async {
Navigator.push( context.push(AppRoute.humidity, extra: '60');
context,
MaterialPageRoute(
builder: (context) => const HumidityScreen()));
}, },
), ),
const DataDisplayerWidget( DataDisplayerWidget(
title: 'Temperature', title: 'Temperature',
subtitle: 'suhu greenhouse', subtitle: 'suhu greenhouse',
value: '28', value: '28',
unit: '°C', unit: '°C',
icon: BootstrapIcons.thermometer_half, icon: BootstrapIcons.thermometer_half,
color: Colors.white, color: Colors.white,
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const TemperatureScreen()));
},
), ),
const DataDisplayerWidget( const DataDisplayerWidget(
title: 'Light', title: 'Light',
@ -126,13 +148,29 @@ class HomeScreen extends StatelessWidget {
icon: BootstrapIcons.sun, icon: BootstrapIcons.sun,
color: Colors.white, color: Colors.white,
), ),
const DataDisplayerWidget( DataDisplayerWidget(
title: 'Soil Moisture', title: 'Soil Moisture',
subtitle: 'kelembaban tanah', subtitle: 'kelembaban tanah',
value: '40', value: '40',
unit: '%', unit: '%',
icon: Icons.water_outlined, icon: Icons.water_outlined,
color: Colors.white, color: Colors.white,
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SoilMoistureScreen(),
),
);
},
),
const DataDisplayerWidget(
title: 'Acid Level',
subtitle: 'tingkat keasaman',
value: '6.5',
unit: '',
icon: BootstrapIcons.pie_chart,
color: Colors.white,
) )
], ],
) )

View File

@ -1,4 +1,8 @@
import 'dart:async';
import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class SplashScreen extends StatefulWidget { class SplashScreen extends StatefulWidget {
const SplashScreen({super.key}); const SplashScreen({super.key});
@ -8,8 +12,64 @@ class SplashScreen extends StatefulWidget {
} }
class _SplashScreenState extends State<SplashScreen> { class _SplashScreenState extends State<SplashScreen> {
bool isLoggedIn = false;
@override
void initState() {
super.initState();
_initialize();
}
Future<void> _initialize() async {
// final authProvider = Provider.of<AuthProvider>(context, listen: false);
// bool isLoggedIn = await _checkLoginStatus(authProvider);
_navigateAfterSplash(isLoggedIn);
}
// Future<bool> _checkLoginStatus(AuthProvider authProvider) async {
// SharedPreferences prefs = await SharedPreferences.getInstance();
// if (prefs.getKeys().isEmpty) return false;
// if (prefs.getBool('isLoggedIn') == true) {
// String? token = prefs.getString('token');
// String? refreshToken = prefs.getString('refreshToken');
// if (token != null && !JwtDecoder.isExpired(token)) {
// return true;
// } else if (refreshToken != null && !JwtDecoder.isExpired(refreshToken)) {
// final result = await authProvider.refreshToken();
// return result == ResultState.hasData;
// } else {
// prefs.remove('token');
// return false;
// }
// }
// return false;
// }
void _navigateAfterSplash(bool isLoggedIn) {
Timer(const Duration(seconds: 2), () {
if (isLoggedIn == true) {
context.go(AppRoute.dashboard);
} else {
context.go(AppRoute.login);
}
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const Placeholder(); return Scaffold(
body: SafeArea(
child: Center(
child: Image.asset(
'assets/images/app_logo.png',
width: 80,
),
),
),
);
} }
} }

View File

@ -1,7 +1,7 @@
import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:agrilink_vocpro/features/auth/provider/auth_provider.dart';
import 'package:agrilink_vocpro/features/dashboard/provider/dashboard_provider.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/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'; import 'package:provider/provider.dart';
@ -17,10 +17,11 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MultiProvider( return MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(create: (context) => AuthProvider()),
ChangeNotifierProvider(create: (context) => HomeProvider()), ChangeNotifierProvider(create: (context) => HomeProvider()),
ChangeNotifierProvider(create: (context) => DashboardProvider()), ChangeNotifierProvider(create: (context) => DashboardProvider()),
], ],
child: MaterialApp( child: MaterialApp.router(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: 'Flutter Demo', title: 'Flutter Demo',
theme: ThemeData( theme: ThemeData(
@ -28,7 +29,7 @@ class MyApp extends StatelessWidget {
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal), colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
useMaterial3: true, useMaterial3: true,
), ),
home: const DashboardScreen(), routerConfig: AppRoute.router,
), ),
); );
} }

View File

@ -5,8 +5,10 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
} }

View File

@ -49,6 +49,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.18.0" version: "1.18.0"
crypto:
dependency: transitive
description:
name: crypto
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
url: "https://pub.dev"
source: hosted
version: "3.0.5"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -126,14 +134,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
flutter_screenutil:
dependency: "direct main"
description:
name: flutter_screenutil
sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de"
url: "https://pub.dev"
source: hosted
version: "5.9.3"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -152,6 +152,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.7" version: "14.2.7"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82
url: "https://pub.dev"
source: hosted
version: "6.2.1"
http:
dependency: transitive
description:
name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev"
source: hosted
version: "1.2.2"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
@ -248,6 +264,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.0" version: "1.9.0"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
url: "https://pub.dev"
source: hosted
version: "2.1.4"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7"
url: "https://pub.dev"
source: hosted
version: "2.2.10"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
url: "https://pub.dev"
source: hosted
version: "2.4.0"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:

View File

@ -39,9 +39,9 @@ dependencies:
intl: ^0.19.0 intl: ^0.19.0
dio: ^5.7.0 dio: ^5.7.0
go_router: ^14.2.7 go_router: ^14.2.7
flutter_screenutil: ^5.9.3
bootstrap_icons: ^1.11.3 bootstrap_icons: ^1.11.3
fl_chart: ^0.69.0 fl_chart: ^0.69.0
google_fonts: ^6.2.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: