refactor(ui): Update some UI and fix some bugs

This commit is contained in:
anhtunz
2025-01-11 16:43:19 +07:00
parent c2c685da86
commit a17831d0ac
16 changed files with 688 additions and 464 deletions

View File

@@ -71,7 +71,8 @@ extension PageExtension on BuildContext {
extension DurationExtension on BuildContext {
Duration get lowDuration => const Duration(milliseconds: 150);
Duration get normalDuration => const Duration(milliseconds: 500);
Duration dynamicMilliSecondDuration(int milliseconds) => Duration(milliseconds: milliseconds);
Duration dynamicMilliSecondDuration(int milliseconds) =>
Duration(milliseconds: milliseconds);
Duration dynamicMinutesDuration(int minutes) => Duration(minutes: minutes);
}

View File

@@ -36,7 +36,7 @@ class NetworkManager {
/// string if the request fails
Future<String> getDataFromServer(String path) async {
final url = Uri.https(ApplicationConstants.DOMAIN, path);
log("GET url: $url");
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET url: $url");
final headers = await getHeaders();
final response = await http.get(url, headers: headers);
if (response.statusCode == StatusCodeConstants.OK ||
@@ -61,7 +61,7 @@ class NetworkManager {
Future<String> getDataFromServerWithParams(
String path, Map<String, dynamic> params) async {
final url = Uri.https(ApplicationConstants.DOMAIN, path, params);
log("GET Params url: $url");
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET Params url: $url");
final headers = await getHeaders();
final response = await http.get(url, headers: headers);
if (response.statusCode == StatusCodeConstants.CREATED ||
@@ -78,7 +78,7 @@ class NetworkManager {
/// to be sent. Returns the HTTP status code of the response.
Future<int> createDataInServer(String path, Map<String, dynamic> body) async {
final url = Uri.https(ApplicationConstants.DOMAIN, path);
log("POST url: $url");
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] POST url: $url");
final headers = await getHeaders();
final response =
await http.post(url, headers: headers, body: jsonEncode(body));
@@ -91,7 +91,7 @@ class NetworkManager {
/// to be updated. Returns the HTTP status code of the response.
Future<int> updateDataInServer(String path, Map<String, dynamic> body) async {
final url = Uri.https(ApplicationConstants.DOMAIN, path);
log("PUT url: $url");
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] PUT url: $url");
final headers = await getHeaders();
final response =
await http.put(url, headers: headers, body: jsonEncode(body));
@@ -106,7 +106,7 @@ class NetworkManager {
/// failure or an error.
Future<int> deleteDataInServer(String path) async {
final url = Uri.https(ApplicationConstants.DOMAIN, path);
log("DELETE url: $url");
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] DELETE url: $url");
final headers = await getHeaders();
final response = await http.delete(url, headers: headers);
return response.statusCode;

View File

@@ -271,6 +271,12 @@ class APIServices {
return data;
}
Future<String> getOwnerDevieByState(Map<String, dynamic> params) async {
String? data = await NetworkManager.instance!
.getDataFromServerWithParams(APIPathConstants.DEVICE_PATH, params);
return data;
}
Future<int> createDeviceByAdmin(Map<String, dynamic> body) async {
int? statusCode = await NetworkManager.instance!
.createDataInServer(APIPathConstants.DEVICE_PATH, body);

View File

@@ -1,5 +1,8 @@
import 'dart:developer';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:sfm_app/bloc/devices_manager_bloc.dart';
import 'package:sfm_app/feature/devices/device_model.dart';
import 'package:sfm_app/product/extention/context_extention.dart';
import 'package:sfm_app/product/services/language_services.dart';
@@ -7,15 +10,17 @@ import 'package:sfm_app/product/services/language_services.dart';
import '../constant/app/app_constants.dart';
class SharedPieChart extends StatelessWidget {
const SharedPieChart({
super.key,
required this.deviceByState,
});
const SharedPieChart(
{super.key,
required this.deviceByState,
required this.devicesManagerBloc});
final Map<String, List<Device>> deviceByState;
final DevicesManagerBloc devicesManagerBloc;
@override
Widget build(BuildContext context) {
int touchedIndex = -1;
TextStyle titleStyle = const TextStyle(
color: Colors.white,
fontSize: 20,
@@ -31,56 +36,98 @@ class SharedPieChart extends StatelessWidget {
deviceByState[ApplicationConstants.INPROGRESS_STATE]?.length ?? 0;
int errorCount =
deviceByState[ApplicationConstants.ERROR_STATE]?.length ?? 0;
return Padding(
padding: context.paddingLowHorizontal,
return AspectRatio(
aspectRatio: 1.5,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
width: context.dynamicWidth(0.5),
height: context.dynamicHeight(0.3),
padding: const EdgeInsets.all(10),
child: PieChart(
PieChartData(
sections: [
PieChartSectionData(
color: Colors.grey,
value: offlineCount.toDouble(),
title: offlineCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
children: <Widget>[
const SizedBox(
height: 18,
),
Expanded(
child: AspectRatio(
aspectRatio: 1,
child: PieChart(
PieChartData(
pieTouchData: PieTouchData(
touchCallback: (FlTouchEvent event, pieTouchResponse) {
if (!event.isInterestedForInteractions ||
pieTouchResponse == null ||
pieTouchResponse.touchedSection == null) {
touchedIndex = -1;
return;
}
int newTouchedIndex =
pieTouchResponse.touchedSection!.touchedSectionIndex;
// Chỉ gọi updateDevicesOnTapPieChart nếu touchedIndex thay đổi
if (newTouchedIndex != touchedIndex) {
touchedIndex = newTouchedIndex;
log("TouchedIndex: $touchedIndex");
log("Event: ${event.isInterestedForInteractions}");
Future.delayed(
context.lowDuration,
() => updateDevicesOnTapPieChart(newTouchedIndex),
);
}
// touchedIndex =
// pieTouchResponse.touchedSection!.touchedSectionIndex;
// // log("TouchedIndex: $touchedIndex");
// // log("Event: ${event.isInterestedForInteractions}");
// // int currentTouchedIndex = touchedIndex;
// if (currentTouchedIndex != touchedIndex) {
// touchedIndex = currentTouchedIndex;
// log("TouchedIndex: $touchedIndex");
// log("Event: ${event.isInterestedForInteractions}");
// Future.delayed(
// context.lowDuration,
// () => updateDevicesOnTapPieChart(touchedIndex),
// );
// }
},
),
PieChartSectionData(
color: Colors.green,
value: normalCount.toDouble(),
title: normalCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
),
PieChartSectionData(
color: Colors.red,
value: warningCount.toDouble(),
title: warningCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
),
PieChartSectionData(
color: Colors.yellow,
value: inProgressCount.toDouble(),
title: inProgressCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
),
PieChartSectionData(
color: Colors.black, // Có thể thêm màu cho trạng thái lỗi
value: errorCount.toDouble(),
title: errorCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
),
],
centerSpaceRadius: context.dynamicWidth(0.1),
sectionsSpace: 2,
sections: [
PieChartSectionData(
color: Colors.grey,
value: offlineCount.toDouble(),
title: offlineCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
),
PieChartSectionData(
color: Colors.green,
value: normalCount.toDouble(),
title: normalCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
),
PieChartSectionData(
color: Colors.red,
value: warningCount.toDouble(),
title: warningCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
),
PieChartSectionData(
color: Colors.yellow,
value: inProgressCount.toDouble(),
title: inProgressCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
),
PieChartSectionData(
color: Colors.black, // Có thể thêm màu cho trạng thái lỗi
value: errorCount.toDouble(),
title: errorCount.toString(),
radius: context.dynamicWidth(0.2),
titleStyle: titleStyle,
),
],
centerSpaceRadius: context.dynamicWidth(0.05),
sectionsSpace: 2,
),
),
),
),
@@ -88,52 +135,88 @@ class SharedPieChart extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Indicator(
color: Colors.grey,
text: appLocalization(context).inactive_devices_message,
isSquare: true,
),
SizedBox(
height: context.lowValue,
),
Indicator(
color: Colors.green,
text: appLocalization(context).active_devices_message,
isSquare: true,
),
SizedBox(
height: context.lowValue,
),
Indicator(
color: Colors.red,
text: appLocalization(context).warning_devices_message,
isSquare: true,
),
SizedBox(
height: context.lowValue,
),
Indicator(
color: Colors.yellow,
text: appLocalization(context).in_progress_message,
isSquare: true,
),
SizedBox(
height: context.lowValue,
),
Indicator(
color: Colors.black,
text: appLocalization(context).error_message_uppercase,
isSquare: true,
),
// const SizedBox(
// height: 18,
// ),
if (offlineCount != 0)
Column(
children: [
Indicator(
color: Colors.grey,
text: appLocalization(context).inactive_devices_message,
isSquare: true,
),
SizedBox(
height: context.lowValue,
),
],
),
if (normalCount != 0)
Column(
children: [
Indicator(
color: Colors.green,
text: appLocalization(context).active_devices_message,
isSquare: true,
),
SizedBox(
height: context.lowValue,
),
],
),
if (warningCount != 0)
Column(
children: [
Indicator(
color: Colors.red,
text: appLocalization(context).warning_devices_message,
isSquare: true,
),
SizedBox(
height: context.lowValue,
),
],
),
if (inProgressCount != 0)
Column(
children: [
Indicator(
color: Colors.yellow,
text: appLocalization(context).in_progress_message,
isSquare: true,
),
SizedBox(
height: context.lowValue,
),
],
),
if (errorCount != 0)
Indicator(
color: Colors.black,
text: appLocalization(context).error_message_uppercase,
isSquare: true,
),
],
),
const SizedBox(
width: 10,
),
],
),
);
}
void updateDevicesOnTapPieChart(int touchedIndex) {
log("Update PieChart On Tap Function");
if (touchedIndex == 0) {
devicesManagerBloc.getDeviceByState(-1);
} else if (touchedIndex == 1) {
devicesManagerBloc.getDeviceByState(0);
} else if (touchedIndex == 2) {
devicesManagerBloc.getDeviceByState(1);
} else if (touchedIndex == 3) {
devicesManagerBloc.getDeviceByState(2);
} else {
devicesManagerBloc.getDeviceByState(-2);
}
}
}
class Indicator extends StatelessWidget {

View File

@@ -16,6 +16,7 @@ class AppThemeDark extends AppTheme {
useMaterial3: true,
scheme: FlexScheme.flutterDash,
subThemesData: const FlexSubThemesData(
snackBarBackgroundSchemeColor: SchemeColor.black,
inputDecoratorRadius: 30,
interactionEffects: true,
tintedDisabledControls: true,
@@ -30,24 +31,4 @@ class AppThemeDark extends AppTheme {
),
visualDensity: FlexColorScheme.comfortablePlatformDensity,
);
// ThemeData.dark().copyWith(
// useMaterial3: true,
// colorScheme: _buildColorScheme,
// );
// ColorScheme get _buildColorScheme => FlexColorScheme.dark().toScheme;
// ColorScheme(
// brightness: Brightness.dark,
// primary: Colors.blue.shade900,
// onPrimary: Colors.blue,
// secondary: Colors.white,
// onSecondary: Colors.white70,
// error: Colors.red,
// onError: Colors.orange,
// background: Colors.black,
// onBackground: Colors.white70,
// surface: Colors.grey,
// onSurface: Colors.white,
// );
}

View File

@@ -17,6 +17,7 @@ class AppThemeLight extends AppTheme {
scheme: FlexScheme.flutterDash,
bottomAppBarElevation: 20.0,
subThemesData: const FlexSubThemesData(
snackBarBackgroundSchemeColor: SchemeColor.surfaceBright,
inputDecoratorRadius: 30,
interactionEffects: true,
tintedDisabledControls: true,

View File

@@ -129,7 +129,7 @@ class DeviceUtils {
message = appLocalization(context).in_progress_message;
} else if (state == 3) {
message = appLocalization(context).in_progress_message;
}
} else if (state == -2) {}
return message;
}
@@ -144,6 +144,10 @@ class DeviceUtils {
return sortedDevices;
}
List<Device> sortDeviceAZByName(List<Device> devices) {
return devices..sort((a, b) => (a.name ?? '').compareTo(b.name ?? ''));
}
Color getTableRowColor(int state) {
if (state == 1) {
return Colors.red;
@@ -251,12 +255,14 @@ class DeviceUtils {
}
IconData getSignalIcon(BuildContext context, String signal) {
if (signal == appLocalization(context).gf_weak_signal_message) {
if (signal == appLocalization(context).low_message_uppercase) {
return Icons.signal_cellular_alt_1_bar;
} else if (signal == appLocalization(context).gf_moderate_signal_message) {
} else if (signal == appLocalization(context).moderate_message_uppercase) {
return Icons.signal_cellular_alt_2_bar;
} else {
} else if (signal == appLocalization(context).good_message_uppercase) {
return Icons.signal_cellular_alt;
} else {
return Icons.signal_cellular_connected_no_internet_4_bar_rounded;
}
}
@@ -312,12 +318,12 @@ class DeviceUtils {
}
Color getSignalIconColor(BuildContext context, String signal) {
if (signal == appLocalization(context).gf_weak_signal_message) {
return Colors.red;
} else if (signal == appLocalization(context).gf_moderate_signal_message) {
return Colors.yellow;
} else {
if (signal == appLocalization(context).good_message_uppercase) {
return Colors.green;
} else if (signal == appLocalization(context).moderate_message_uppercase) {
return Colors.orangeAccent;
} else {
return Colors.red;
}
}
}