feat: add status bar in control screen

This commit is contained in:
Syaroful 2024-10-09 11:45:19 +07:00
parent c9ad942a6c
commit 5ddc748bc9
4 changed files with 168 additions and 61 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

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/state/result_state.dart';
import 'package:agrilink_vocpro/features/control/provider/control_provider.dart';
import 'package:agrilink_vocpro/features/control/widgets/control_button_widget.dart';
import 'package:bootstrap_icons/bootstrap_icons.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -22,11 +22,43 @@ class ControlScreen extends StatelessWidget {
scrolledUnderElevation: 0,
),
body: RefreshIndicator(
displacement: 10,
onRefresh: () async =>
await context.read<ControlProvider>().getRelayStatus(),
child: SafeArea(
child: ListView(
children: [
Consumer<ControlProvider>(builder: (context, provider, child) {
switch (provider.relayState) {
case ResultState.loading:
return const StatusBarWidget(
text: 'Memuat...',
icon: BootstrapIcons.cloud,
color: Colors.cyan,
isLoading: true,
);
case ResultState.hasData:
return const StatusBarWidget(
text: 'Berhasil terhubung',
icon: BootstrapIcons.check_circle,
color: Colors.teal,
);
case ResultState.noData:
return const StatusBarWidget(
text: 'Data tidak ditemukan',
icon: BootstrapIcons.exclamation_circle,
color: Colors.amber,
);
case ResultState.initial:
return const SizedBox.shrink();
case ResultState.error:
return const StatusBarWidget(
text: 'Tidak dapat terhubung',
icon: BootstrapIcons.exclamation_circle,
color: Colors.red,
);
}
}),
SizedBox(height: 16.h),
GridView(
padding: EdgeInsets.all(16.r),
@ -43,7 +75,11 @@ class ControlScreen extends StatelessWidget {
title: 'Katup Air',
subtitle: 'Relay 1',
isActive: provider.control_1,
onTap: () {},
onTap: () {
provider.control_1 != true
? provider.switchControl1(true)
: provider.switchControl1(false);
},
),
ControlButtonWidget(
title: 'Lampu Utama',
@ -60,74 +96,46 @@ class ControlScreen extends StatelessWidget {
}
}
class ControlButtonWidget extends StatelessWidget {
const ControlButtonWidget({
class StatusBarWidget extends StatelessWidget {
const StatusBarWidget({
super.key,
required this.title,
required this.subtitle,
required this.isActive,
required this.onTap,
required this.text,
required this.icon,
required this.color,
this.isLoading = false,
});
final String title;
final String subtitle;
final bool isActive;
final Function() onTap;
final String text;
final IconData icon;
final Color color;
final bool isLoading;
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(16.r),
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 16.w),
margin: EdgeInsets.all(16.r),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.r),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 1.r,
blurRadius: 16.r,
offset: Offset(0, 12.r),
color: color.withAlpha(50),
borderRadius: BorderRadius.circular(8.r),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(title, style: AppTheme.labelMedium),
Text(subtitle, style: AppTheme.labelSmall),
Icon(
icon,
color: color,
size: 16.r,
),
SizedBox(width: 8.w),
Text(text, style: AppTheme.titleSmall.copyWith(color: color)),
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Consumer<ControlProvider>(
builder: (context, provider, child) {
switch (provider.relayState) {
case ResultState.loading:
return CircleAvatar(
radius: 20.r,
backgroundColor: Colors.transparent,
child: const CupertinoActivityIndicator(),
);
default:
return InkWell(
highlightColor: Colors.black,
onTap: onTap,
child: CircleAvatar(
radius: 20.r,
backgroundColor: isActive
? AppColor.secondary
: Colors.grey.shade400,
child: const Icon(
BootstrapIcons.power,
color: Colors.white,
),
),
);
}
},
),
],
)
if (isLoading)
Center(
child: CupertinoActivityIndicator(
radius: 8.r,
))
else
const SizedBox.shrink(),
],
),
);

View File

@ -0,0 +1,85 @@
import 'package:agrilink_vocpro/core/constant/app_color.dart';
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
import 'package:agrilink_vocpro/core/state/result_state.dart';
import 'package:agrilink_vocpro/features/control/provider/control_provider.dart';
import 'package:bootstrap_icons/bootstrap_icons.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
class ControlButtonWidget extends StatelessWidget {
const ControlButtonWidget({
super.key,
required this.title,
required this.subtitle,
required this.isActive,
required this.onTap,
});
final String title;
final String subtitle;
final bool isActive;
final Function() onTap;
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(16.r),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.r),
boxShadow: [
BoxShadow(
color: isActive
? AppColor.secondary.withOpacity(0.2)
: Colors.grey.withOpacity(0.2),
spreadRadius: 1.r,
blurRadius: 16.r,
offset: Offset(0, 12.r),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: AppTheme.labelMedium),
Text(subtitle, style: AppTheme.labelSmall),
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Consumer<ControlProvider>(
builder: (context, provider, child) {
switch (provider.relayState) {
case ResultState.loading:
return CircleAvatar(
radius: 20.r,
backgroundColor: Colors.transparent,
child: const CupertinoActivityIndicator(),
);
default:
return InkWell(
highlightColor: Colors.black,
onTap: onTap,
child: CircleAvatar(
radius: 20.r,
backgroundColor: isActive
? AppColor.secondary
: Colors.grey.shade400,
child: const Icon(
BootstrapIcons.power,
color: Colors.white,
),
),
);
}
},
),
],
)
],
),
);
}
}

View File

@ -1,5 +1,7 @@
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_screenutil/flutter_screenutil.dart';
class PlantsScreen extends StatelessWidget {
const PlantsScreen({super.key});
@ -9,7 +11,19 @@ class PlantsScreen extends StatelessWidget {
return Scaffold(
body: SafeArea(
child: Center(
child: Text('Coming Soon', style: AppTheme.labelMedium),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.eco_rounded, size: 100.r, color: AppColor.secondary),
Text('Coming Soon', style: AppTheme.titleLarge),
SizedBox(height: 8.h),
Text(
'This featureis under development',
textAlign: TextAlign.center,
style: AppTheme.labelSmall,
),
],
),
)),
);
}