import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/controller/device/body_device_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/mh/muser_info_controller.dart'; class NewHomePage extends StatefulWidget { const NewHomePage({super.key}); @override State createState() => _NewHomePageState(); } class _NewHomePageState extends State { MUserInfoController userInfoController = Get.find(); BodyDeviceController deviceController = Get.find(); double borderRadius = 16.rpx; var formFieldController = FormFieldController(null); get gloablController => Get.find(); // get userInfoController => Get.find(); var sleepDays = [].obs; var sleep_mac = "".obs; Map scoreColor = { "-1": "#d3d3d3", "1": "#4e8408", "2": "#7bbb33", "3": "#e15b8d", "4": "#ff0000", }; Map scoreName = { "-1": "暂无", "1": "优秀", "2": "良好", "3": "合格", "4": "注意", }; @override void initState() { super.initState(); } getWeekName(int i) { String v = ""; switch (i) { case 1: v = "周一"; break; case 2: v = "周二"; break; case 3: v = "周三"; break; case 4: v = "周四"; break; case 5: v = "周五"; break; case 6: v = "周六"; break; case 7: v = "周日"; break; } return v; } @override Widget build(BuildContext context) { int login = userInfoController.model.login!; return GestureDetector( onTap: () => FocusScope.of(context).unfocus(), child: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/new_background.png'), // 本地图片 fit: BoxFit.fill, // 填满整个 Container ), ), child: Scaffold( backgroundColor: Colors.transparent, appBar: AppBar( iconTheme: IconThemeData(color: themeController.currentColor.sc3), backgroundColor: Colors.transparent, automaticallyImplyLeading: false, titleSpacing: 0, title: Row( children: [ // 左侧头像 SizedBox(width: 40.rpx), CircleAvatar( radius: 27.rpx, // 可根据需求调整 backgroundImage: login == 1 ? (userInfoController.model.user!.avatar == null || userInfoController.model.user!.avatar!.isEmpty ? const AssetImage( "assets/images/people_avatar.png", ) : NetworkImage( userInfoController.model.user!.avatar!, )) : const AssetImage( "assets/images/people_avatar.png", ), ), SizedBox(width: 23.rpx), // 左侧头像和文本之间的间距 Text( 'Eason Chan', style: TextStyle(fontSize: 30.rpx, color: Colors.white), ), const Spacer(), // 左右分隔 // Container( // width: 61.rpx, // height: 78.rpx, // alignment: const Alignment(0, 0), // child: Image.asset( // "assets/images/xiaoe.png", // fit: BoxFit.cover, // ), // ), // SizedBox(width: 46.rpx), // icon 之间的间距 ClickableContainer( backgroundColor: Colors.transparent, highlightColor: Colors.transparent, padding: EdgeInsets.only(right: 0), onTap: () {}, child: Container( height: 60.rpx, width: 75.rpx, child: SvgPicture.asset( 'assets/img/icon/xiaoe.svg', // color: Colors.white, ))), // SizedBox(width: 40.rpx), ], ), centerTitle: false, ), body: SafeArea( child: Container( width: MediaQuery.sizeOf(context).width, height: MediaQuery.sizeOf(context).height * 1.123, // decoration: BoxDecoration( // color: AppColors.bg_color, // image: DecorationImage( // image: AssetImage("assets/images/background.png"), // fit: BoxFit.cover, // ), // ), decoration: BoxDecoration( ), child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.max, children: [ Container( padding: EdgeInsets.fromLTRB(26.rpx, 10.rpx, 26.rpx, 40.rpx), width: double.infinity, child: Padding( padding: EdgeInsets.symmetric(horizontal: 30.rpx), child: Column( children: [ Padding( padding: EdgeInsets.fromLTRB(17.rpx, 30.rpx, 0, 0), child: Row( children: [ Text('上海 22° 多云', style: TextStyle( fontSize: 26.rpx, color: Colors.white)), Icon(Icons.cloud, size: 30.rpx, color: Colors.white), ], ), ), ], ))), Container( padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx), child: Column( children: [ if (gloablController.model.deviceList.length > 0) Container( child: Column( children: [ Container( width: MediaQuery.sizeOf(context).width, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(borderRadius), ), child: Column( mainAxisSize: MainAxisSize.max, children: [ Padding( padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 16.rpx, 16.rpx, 8.rpx), child: Container( width: MediaQuery.sizeOf(context) .width, height: MediaQuery.sizeOf(context) .height * 0.065, decoration: BoxDecoration( color: FlutterFlowTheme.of(context) .secondaryBackground, ), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ ValueListenableBuilder( valueListenable: formFieldController, builder: (c, a, s) => FlutterFlowDropDown< String>( controller: formFieldController, options: gloablController .model.JunheDevices .map((d) => "${d["mac"]}") .toList(), optionLabels: gloablController .model.JunheDevices .map((d) { var s = d["name"] ?? d["mac"]; if (s == null) { return ""; } else { return "$s"; } }).toList(), onChanged: (val) { // print("$val"); // if (val == null) { // sleepDays.value = []; // } else { // getSleeps( // formFieldController // .value); // } // // sleep_mac.value = val!; }, width: 360.rpx, height: 72.rpx, maxHeight: 200.rpx, textStyle: TextStyle( fontSize: 28.rpx, overflow: TextOverflow .ellipsis), hintText: '', icon: Icon( Icons .keyboard_arrow_down_rounded, color: FlutterFlowTheme.of( context) .secondaryText, size: 48.rpx, ), fillColor: stringToColor( "#F3F5F6"), elevation: 2, borderColor: stringToColor( "#F3F5F6"), borderWidth: 2, borderRadius: 18, margin: EdgeInsetsDirectional .fromSTEB( 32.rpx, 8.rpx, 32.rpx, 8.rpx), hidesUnderline: true, isOverButton: false, isSearchable: false, isMultiSelect: false, ), ), InkWell( onTap: () { // if (formFieldController // .value != // null) { // Get.toNamed( // "/sleepWebview", // arguments: [ // formFieldController // .value // ]); // } }, child: Row( mainAxisSize: MainAxisSize.max, children: [ Text( '睡眠报告', style: FlutterFlowTheme .of(context) .bodyMedium .override( fontFamily: 'Readex Pro', letterSpacing: 0, fontSize: 30.rpx), ), SizedBox( width: 12.rpx, ), SvgPicture.asset( "assets/images/table.svg", width: 28.rpx, height: 28.rpx), SizedBox( width: 20.rpx, ), ], ), ), ], ), ), ), Container( padding: EdgeInsets.only( top: 0.rpx, bottom: 20.rpx, left: 16.rpx, right: 16.rpx), width: double.infinity, decoration: BoxDecoration(), child: Row( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.start, children: [ ...List.generate( sleepDays.value.length, (index) { var day = sleepDays[index]; return Expanded( child: Container( padding: EdgeInsets.only( top: 10.rpx, bottom: 20.rpx), width: 100, // decoration: BoxDecoration( // color: index == 2 // ? stringToColor("#F3F5F6") // : Colors.white, // borderRadius: // BorderRadius.circular( // borderRadius), // ), child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment .start, crossAxisAlignment: CrossAxisAlignment .center, children: [ Text( day['week'], style: FlutterFlowTheme .of(context) .bodyMedium .override( fontFamily: 'Readex Pro', fontSize: 30.rpx, letterSpacing: 0, ), ), Text( day['date'], style: FlutterFlowTheme .of(context) .bodyMedium .override( fontFamily: 'Readex Pro', letterSpacing: 0, fontSize: 24.rpx, ), ), SizedBox( height: 6.rpx, ), Column( children: [ Row( mainAxisSize: MainAxisSize .max, mainAxisAlignment: MainAxisAlignment .center, children: [ Text( '${day['score'] ?? "-"}', style: FlutterFlowTheme.of( context) .bodyMedium .override( fontFamily: 'Readex Pro', fontSize: 48.rpx, letterSpacing: 0, ), ), if (day['score'] != null) SizedBox( width: 2.rpx, ), if (day['score'] != null) Text( '分', style: FlutterFlowTheme.of( context) .bodyMedium .override( fontFamily: 'Readex Pro', letterSpacing: 0, fontSize: 26.rpx, ), ), ], ), Container( width: 120.rpx, height: 52.rpx, decoration: BoxDecoration( color: stringToColor( day['scoreColor'] ?? "#f3f5f6"), borderRadius: BorderRadius .circular( 26.rpx), shape: BoxShape .rectangle, ), alignment: Alignment .center, child: Text( '${day['scoreType'] ?? "暂无"}', style: FlutterFlowTheme.of( context) .bodyMedium .override( fontFamily: 'Readex Pro', color: day['scoreType'] != null ? Colors .white : stringToColor( "#ced1d7"), letterSpacing: 0, fontSize: 28.rpx, ), ), ) ], ) ], ), ), ); }) ], ), ), ], ), ), ...List.generate( gloablController.model.deviceList.length, (index) { var device = gloablController .model.deviceList[index]; String rname = device['roomName']; if (index != 0) { String lrname = gloablController.model .deviceList[index - 1]["roomName"]; if (lrname == rname) { rname = ""; } } return Column(children: [ Padding( padding: EdgeInsetsDirectional.fromSTEB( 20.rpx, 20.rpx, 0, 0), child: Container( decoration: BoxDecoration(), alignment: AlignmentDirectional(-1, 0), child: rname.isNotEmpty ? Text( "$rname", style: FlutterFlowTheme.of( context) .bodyMedium .override( fontFamily: 'Readex Pro', color: Colors.white, fontSize: 32.rpx, letterSpacing: 0, ), ) : SizedBox( height: 10.rpx, ), ), ), // getDeviceList(context, device) ]); }), Padding( padding: EdgeInsetsDirectional.fromSTEB( 0, 40.rpx, 0, 100.rpx), child: Container( width: MediaQuery.sizeOf(context).width, height: 84.rpx, decoration: BoxDecoration(), child: FFButtonWidget( onPressed: () { // print('Button pressed ...'); // Get.toNamed("/homeDeviceType"); }, text: '添加新设备', icon: Icon( Icons.add, size: 60.rpx, ), options: FFButtonOptions( height: 80.rpx, padding: EdgeInsetsDirectional.fromSTEB( 48.rpx, 0, 48.rpx, 0), iconPadding: EdgeInsetsDirectional.fromSTEB( 0, 0, 0, 0), color: stringToColor("#182B7C"), textStyle: FlutterFlowTheme.of(context) .titleSmall .override( fontFamily: 'Readex Pro', color: Colors.white, letterSpacing: 0, fontSize: 30.rpx), elevation: 3, borderSide: BorderSide( color: Colors.transparent, width: 1, ), borderRadius: BorderRadius.circular( borderRadius), ), ), ), ), ], ), ), if (gloablController.model.deviceList.length == 0) Padding( padding: EdgeInsetsDirectional.fromSTEB( 0, 0, 0, 80.rpx), child: Container( width: MediaQuery.sizeOf(context).width, padding: EdgeInsets.only( top: 90.rpx, bottom: 80.rpx), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(borderRadius), ), child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( '检测到您当前暂无设备!', style: FlutterFlowTheme.of(context) .bodyMedium .override( fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7), fontSize: 32.rpx, letterSpacing: 0, ), ), SizedBox( height: MediaQuery.sizeOf(context).height * 0.037, ), Container( width: MediaQuery.sizeOf(context).width * 0.54, height: 90.rpx, decoration: BoxDecoration( color: FlutterFlowTheme.of(context) .secondaryBackground, borderRadius: BorderRadius.circular(0), ), child: FFButtonWidget( onPressed: () { // print('Button pressed ...'); Get.toNamed("/homeDeviceType"); }, text: '立即添加一台', icon: Icon( Icons.add, color: FlutterFlowTheme.of(context) .primaryText, size: 60.rpx, ), options: FFButtonOptions( iconPadding: EdgeInsetsDirectional.fromSTEB( 0, 0, 0, 0), color: Colors.white, textStyle: FlutterFlowTheme.of(context) .titleSmall .override( fontFamily: 'Readex Pro', color: FlutterFlowTheme.of( context) .primaryText, letterSpacing: 0, fontSize: 30.rpx), elevation: 3, borderSide: BorderSide( color: Color(0xFFABB0C0), width: 1, ), borderRadius: BorderRadius.circular(45.rpx), ), ), ), ], ), ), ), ], ), ) ], ), ), ) // Padding( // padding: EdgeInsets.symmetric(horizontal: 30.rpx), // child: Column( // children: [ // Padding( // padding: EdgeInsets.fromLTRB(17.rpx, 30.rpx, 0, 0), // child: Row( // children: [ // Text('上海 22° 多云', // style: TextStyle( // fontSize: 26.rpx, color: Colors.white)), // Icon(Icons.cloud, // size: 30.rpx, color: Colors.white), // ], // ), // ), // ], // )) ), ), )); } } class ScoreItem { final String weekday; // 如“周四” final String dateStr; // 如“07/03” final int score; final bool isToday; ScoreItem({ required this.weekday, required this.dateStr, required this.score, this.isToday = false, }); } class ScoreCard extends StatelessWidget { final String selectedUser; final List scoreList; final ValueChanged? onUserChanged; final VoidCallback? onChartPressed; const ScoreCard({ super.key, required this.selectedUser, required this.scoreList, this.onUserChanged, this.onChartPressed, }); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: const Color(0xff0F2B44), borderRadius: BorderRadius.circular(16), ), padding: const EdgeInsets.all(12), child: Column( children: [ // 顶部用户选择 + 图标按钮 Row( children: [ DropdownButtonHideUnderline( child: DropdownButton( value: selectedUser, borderRadius: BorderRadius.circular(12), dropdownColor: const Color(0xff0F2B44), iconEnabledColor: Colors.white, style: const TextStyle(color: Colors.white), items: ['Eason Chan', 'Jay Chou', 'G.E.M.'] .map((user) => DropdownMenuItem( value: user, child: Text(user), )) .toList(), onChanged: onUserChanged, ), ), const Spacer(), IconButton( onPressed: onChartPressed, icon: const Icon(Icons.bar_chart, color: Colors.white), ), ], ), const SizedBox(height: 12), // 日期+分数 横向滚动展示 SizedBox( height: 70, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: scoreList.length, separatorBuilder: (_, __) => const SizedBox(width: 12), itemBuilder: (context, index) { final item = scoreList[index]; final isToday = item.isToday; return Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: isToday ? Colors.white.withOpacity(0.1) : Colors.transparent, borderRadius: BorderRadius.circular(12), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(item.weekday, style: const TextStyle( color: Colors.white70, fontSize: 12)), Text(item.dateStr, style: const TextStyle( color: Colors.white54, fontSize: 10)), const SizedBox(height: 4), Text( item.score.toString(), style: TextStyle( color: Colors.white, fontWeight: isToday ? FontWeight.bold : FontWeight.normal, fontSize: 16, ), ), ], ), ); }, ), ) ], ), ); } }