227 lines
8.7 KiB
Dart
227 lines
8.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:vbvs_app/common/color/appConstants.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/date/CalendarController.dart';
|
|
import 'SleepdateWidget.dart';
|
|
|
|
class SleepCalendarWidget extends StatefulWidget {
|
|
final int? timestamp;
|
|
final ValueChanged<DateTime>? onDateSelected;
|
|
|
|
const SleepCalendarWidget({
|
|
super.key,
|
|
this.timestamp,
|
|
this.onDateSelected,
|
|
});
|
|
|
|
@override
|
|
State<SleepCalendarWidget> createState() => _SleepCalendarWidgetState();
|
|
}
|
|
|
|
class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
|
|
CalendarController calendarController = Get.find();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
final initialDate = widget.timestamp != null
|
|
? DateTime.fromMillisecondsSinceEpoch(widget.timestamp!)
|
|
: DateTime.now();
|
|
calendarController.displayedMonth.value = initialDate;
|
|
calendarController.selectedDate.value = initialDate;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
List<Map<String, dynamic>> showLabel = [
|
|
{"level": 1, "name": "优秀", "color": Color(0xFF4CAF50)},
|
|
{"level": 2, "name": "良好", "color": Color(0xFF8BC34A)},
|
|
{"level": 3, "name": "合格", "color": Color(0xFFFFC107)},
|
|
{"level": 4, "name": "注意", "color": Color(0xFFF44336)},
|
|
{"level": 5, "name": "无报告", "color": Color(0xFF9E9E9E)},
|
|
];
|
|
|
|
return Container(
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(20.rpx),
|
|
topRight: Radius.circular(20.rpx),
|
|
),
|
|
),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Container(
|
|
width: double.infinity,
|
|
constraints: BoxConstraints(minHeight: 90.rpx),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF313541),
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(20.rpx),
|
|
topRight: Radius.circular(20.rpx),
|
|
),
|
|
),
|
|
child: Padding(
|
|
padding:
|
|
EdgeInsetsDirectional.fromSTEB(65.rpx, 0.rpx, 65.rpx, 0.rpx),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
ClickableContainer(
|
|
backgroundColor: Colors.transparent,
|
|
highlightColor: Colors.grey,
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
8.rpx, 8.rpx, 8.rpx, 8.rpx),
|
|
onTap: () => calendarController.previousMonth(),
|
|
child: Icon(
|
|
Icons.arrow_back_ios_new,
|
|
color: const Color(0xFF6D6F73),
|
|
size: 24.rpx,
|
|
),
|
|
),
|
|
Obx(() => Text(
|
|
'${calendarController.displayedMonth.value.year}年${calendarController.displayedMonth.value.month}月',
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 30.rpx,
|
|
letterSpacing: 0.0,
|
|
),
|
|
)),
|
|
ClickableContainer(
|
|
backgroundColor: Colors.transparent,
|
|
highlightColor: Colors.grey,
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
8.rpx, 8.rpx, 8.rpx, 8.rpx),
|
|
onTap: () => calendarController.nextMonth(),
|
|
child: Icon(
|
|
Icons.arrow_forward_ios,
|
|
color: const Color(0xFF6D6F73),
|
|
size: 24.rpx,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
width: double.infinity,
|
|
constraints: BoxConstraints(minHeight: 720.rpx),
|
|
decoration: const BoxDecoration(color: Color(0xFF242835)),
|
|
child: Padding(
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
65.rpx, 13.rpx, 65.rpx, 38.rpx),
|
|
child: Obx(() {
|
|
final daysInMonth = calendarController.getDaysInMonth();
|
|
final calendarRows =
|
|
calendarController.getCalendarRows(daysInMonth);
|
|
final selectedDate = calendarController.selectedDate.value;
|
|
|
|
return Column(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
// Weekdays Header
|
|
Container(
|
|
constraints: BoxConstraints(minHeight: 90.rpx),
|
|
child: Row(
|
|
children: [
|
|
for (var day in ["一", "二", "三", "四", "五", "六", "日"])
|
|
Expanded(
|
|
child: Center(
|
|
child: Text(
|
|
day,
|
|
style: TextStyle(
|
|
color: stringToColor("#FFFFFF"),
|
|
fontSize:
|
|
AppConstants().normal_text_fontSize,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
// Calendar days
|
|
Column(
|
|
children: calendarRows.map((week) {
|
|
return Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: week.map((date) {
|
|
if (date.year == 0) {
|
|
return Expanded(
|
|
child: Padding(
|
|
padding: EdgeInsets.all(0.rpx),
|
|
child: SizedBox.shrink(),
|
|
),
|
|
);
|
|
}
|
|
final isSelected = selectedDate != null &&
|
|
date.year == selectedDate.year &&
|
|
date.month == selectedDate.month &&
|
|
date.day == selectedDate.day;
|
|
return Expanded(
|
|
child: SleepdateWidget(
|
|
date: date,
|
|
isSelected: isSelected,
|
|
onTap: () {
|
|
calendarController.selectDate(date);
|
|
if (widget.onDateSelected != null) {
|
|
widget.onDateSelected!(date);
|
|
}
|
|
print(date);
|
|
Get.back();
|
|
},
|
|
),
|
|
);
|
|
}).toList(),
|
|
);
|
|
}).toList(),
|
|
),
|
|
SizedBox(height: 55.rpx),
|
|
Wrap(
|
|
spacing: 20.rpx,
|
|
runSpacing: 20.rpx,
|
|
children: showLabel.map<Widget>((item) {
|
|
return Container(
|
|
padding: EdgeInsets.all(5.rpx),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Container(
|
|
width: 20.rpx,
|
|
height: 20.rpx,
|
|
decoration: BoxDecoration(
|
|
color: item["color"],
|
|
borderRadius: BorderRadius.circular(10.rpx),
|
|
),
|
|
),
|
|
SizedBox(width: 8.rpx),
|
|
Text(
|
|
item["name"],
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 24.rpx,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}).toList(),
|
|
),
|
|
|
|
],
|
|
);
|
|
}),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
|