feat: UI 清新风全面改造 — 朝露主题 + shadcn_ui + 全局字号放大
- 全新"朝露"主题:深青绿主色(#2D6A4F),暖白底,完整设计Token - 引入 shadcn_ui 组件库,MaterialApp 注入 ShadTheme - 新增 4 个公共组件:AppCard、AppMenuItem、AppEmptyState、AppTabChip - 全面消除硬编码颜色,统一使用 AppTheme Token - 全局字号 +3~4pt,图标等比放大 +3px - home/medication/profile/settings/login 等核心页面重写 - 路由和功能逻辑零改动
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../core/app_theme.dart';
|
||||
import '../core/navigation_provider.dart';
|
||||
import '../providers/auth_provider.dart';
|
||||
import '../providers/data_providers.dart';
|
||||
@@ -17,12 +19,12 @@ class _DietRecordListPageState extends ConsumerState<DietRecordListPage> {
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF8F9FC),
|
||||
backgroundColor: AppTheme.bg,
|
||||
appBar: AppBar(title: const Text('饮食记录')),
|
||||
body: FutureBuilder<List<Map<String, dynamic>>>(
|
||||
future: _future,
|
||||
builder: (ctx, snap) {
|
||||
if (snap.connectionState == ConnectionState.waiting) return const Center(child: CircularProgressIndicator(color: Color(0xFF6C5CE7)));
|
||||
if (snap.connectionState == ConnectionState.waiting) return const Center(child: CircularProgressIndicator(color: AppTheme.primary));
|
||||
final data = snap.data ?? [];
|
||||
if (data.isEmpty) return _empty(context, '饮食记录', '暂无饮食记录,可通过「拍饮食」录入');
|
||||
return ListView.builder(
|
||||
@@ -46,18 +48,18 @@ class _DietRecordListPageState extends ConsumerState<DietRecordListPage> {
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16)),
|
||||
child: Row(children: [
|
||||
Container(width: 44, height: 44, decoration: BoxDecoration(color: const Color(0xFFEDEAFF), borderRadius: BorderRadius.circular(12)), child: Center(child: Text(mealIcons[d['mealType']?.toString()] ?? '🍽️', style: const TextStyle(fontSize: 20)))),
|
||||
Container(width: 44, height: 44, decoration: BoxDecoration(color: AppTheme.primaryLight, borderRadius: BorderRadius.circular(12)), child: Center(child: Text(mealIcons[d['mealType']?.toString()] ?? '🍽️', style: const TextStyle(fontSize: 23)))),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Row(children: [
|
||||
Text(mealLabel, style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600)),
|
||||
Text(mealLabel, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
|
||||
const SizedBox(width: 8),
|
||||
Text('${d['totalCalories'] ?? 0}千卡', style: const TextStyle(fontSize: 13, color: Color(0xFF6C5CE7))),
|
||||
Text('${d['totalCalories'] ?? 0}千卡', style: const TextStyle(fontSize: 16, color: AppTheme.primary)),
|
||||
]),
|
||||
const SizedBox(height: 4),
|
||||
Text(items.map((f) => f['name']).join(' · '), style: const TextStyle(fontSize: 13, color: Color(0xFF888888)), maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
Text(items.map((f) => f['name']).join(' · '), style: const TextStyle(fontSize: 16, color: Color(0xFF888888)), maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
])),
|
||||
const Icon(Icons.chevron_right, size: 18, color: Color(0xFFCCCCCC)),
|
||||
const Icon(Icons.chevron_right, size: 21, color: Color(0xFFCCCCCC)),
|
||||
]),
|
||||
),
|
||||
);
|
||||
@@ -76,12 +78,12 @@ class DietRecordDetailPage extends ConsumerWidget {
|
||||
@override Widget build(BuildContext context, WidgetRef ref) {
|
||||
final service = ref.watch(dietServiceProvider);
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF8F9FC),
|
||||
backgroundColor: AppTheme.bg,
|
||||
appBar: AppBar(title: const Text('饮食详情')),
|
||||
body: FutureBuilder<List<Map<String, dynamic>>>(
|
||||
future: service.getRecords(),
|
||||
builder: (ctx, snap) {
|
||||
if (!snap.hasData) return const Center(child: CircularProgressIndicator(color: Color(0xFF6C5CE7)));
|
||||
if (!snap.hasData) return const Center(child: CircularProgressIndicator(color: AppTheme.primary));
|
||||
final d = snap.data!.firstWhere((r) => r['id']?.toString() == id, orElse: () => <String, dynamic>{});
|
||||
if (d.isEmpty) return const Center(child: Text('记录不存在'));
|
||||
final items = (d['foodItems'] as List?)?.cast<Map<String, dynamic>>() ?? [];
|
||||
@@ -89,11 +91,11 @@ class DietRecordDetailPage extends ConsumerWidget {
|
||||
final mealNames = {'Breakfast':'早餐','Lunch':'午餐','Dinner':'晚餐','Snack':'加餐'};
|
||||
return ListView(padding: const EdgeInsets.all(16), children: [
|
||||
Container(padding: const EdgeInsets.all(16), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16)), child: Row(children: [
|
||||
Container(width: 48, height: 48, decoration: BoxDecoration(color: const Color(0xFFEDEAFF), borderRadius: BorderRadius.circular(14)), child: const Icon(Icons.restaurant, size: 24, color: Color(0xFF6C5CE7))),
|
||||
Container(width: 48, height: 48, decoration: BoxDecoration(color: AppTheme.primaryLight, borderRadius: BorderRadius.circular(14)), child: const Icon(Icons.restaurant, size: 28, color: AppTheme.primary)),
|
||||
const SizedBox(width: 14),
|
||||
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(mealNames[d['mealType']?.toString()] ?? '', style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700)),
|
||||
Text('$totalCal 千卡 · ${d['recordedAt'] ?? ''}', style: const TextStyle(fontSize: 13, color: Color(0xFF999999))),
|
||||
Text(mealNames[d['mealType']?.toString()] ?? '', style: const TextStyle(fontSize: 21, fontWeight: FontWeight.w700)),
|
||||
Text('$totalCal 千卡 · ${d['recordedAt'] ?? ''}', style: const TextStyle(fontSize: 16, color: Color(0xFF999999))),
|
||||
]),
|
||||
])),
|
||||
const SizedBox(height: 16),
|
||||
@@ -103,10 +105,10 @@ class DietRecordDetailPage extends ConsumerWidget {
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(14)),
|
||||
child: Row(children: [
|
||||
Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(f['name']?.toString() ?? '', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
|
||||
if ((f['portion']?.toString() ?? '').isNotEmpty) Text(f['portion']!.toString(), style: const TextStyle(fontSize: 13, color: Color(0xFF888888))),
|
||||
Text(f['name']?.toString() ?? '', style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w600)),
|
||||
if ((f['portion']?.toString() ?? '').isNotEmpty) Text(f['portion']!.toString(), style: const TextStyle(fontSize: 16, color: Color(0xFF888888))),
|
||||
])),
|
||||
Text('${f['calories'] ?? 0} kcal', style: const TextStyle(fontSize: 15, color: Color(0xFF6C5CE7), fontWeight: FontWeight.w600)),
|
||||
Text('${f['calories'] ?? 0} kcal', style: const TextStyle(fontSize: 18, color: AppTheme.primary, fontWeight: FontWeight.w600)),
|
||||
]),
|
||||
)),
|
||||
]);
|
||||
@@ -139,9 +141,9 @@ class _ExercisePlanPageState extends ConsumerState<ExercisePlanPage> {
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF8F9FC),
|
||||
backgroundColor: AppTheme.bg,
|
||||
appBar: AppBar(title: const Text('运动计划')),
|
||||
floatingActionButton: FloatingActionButton(onPressed: () { pushRoute(ref, 'exerciseCreate'); }, backgroundColor: const Color(0xFF6C5CE7), child: const Icon(Icons.add)),
|
||||
floatingActionButton: FloatingActionButton(onPressed: () { pushRoute(ref, 'exerciseCreate'); }, backgroundColor: AppTheme.primary, child: const Icon(Icons.add)),
|
||||
body: FutureBuilder<List<Map<String, dynamic>>>(
|
||||
future: _future,
|
||||
builder: (ctx, snap) {
|
||||
@@ -179,14 +181,14 @@ class _ExercisePlanPageState extends ConsumerState<ExercisePlanPage> {
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16)),
|
||||
child: Row(children: [
|
||||
Container(width: 44, height: 44, decoration: BoxDecoration(color: const Color(0xFFEDEAFF), borderRadius: BorderRadius.circular(12)), child: const Icon(Icons.directions_run, size: 22, color: Color(0xFF6C5CE7))),
|
||||
Container(width: 44, height: 44, decoration: BoxDecoration(color: AppTheme.primaryLight, borderRadius: BorderRadius.circular(12)), child: const Icon(Icons.directions_run, size: 25, color: AppTheme.primary)),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(exerciseName, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
|
||||
Text(exerciseName, style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w600)),
|
||||
const SizedBox(height: 2),
|
||||
Text('$startDate 起 · ${items.first['durationMinutes'] ?? 0}分钟/天', style: const TextStyle(fontSize: 13, color: Color(0xFF888888))),
|
||||
Text('$startDate 起 · ${items.first['durationMinutes'] ?? 0}分钟/天', style: const TextStyle(fontSize: 16, color: Color(0xFF888888))),
|
||||
const SizedBox(height: 6),
|
||||
Text('$done/$total 天已完成', style: const TextStyle(fontSize: 12, color: Color(0xFF6C5CE7))),
|
||||
Text('$done/$total 天已完成', style: const TextStyle(fontSize: 15, color: AppTheme.primary)),
|
||||
])),
|
||||
GestureDetector(
|
||||
onTap: todayItem != null ? () => _checkIn(p['id']?.toString() ?? '', todayItem['id']?.toString() ?? '') : null,
|
||||
@@ -194,10 +196,10 @@ class _ExercisePlanPageState extends ConsumerState<ExercisePlanPage> {
|
||||
duration: const Duration(milliseconds: 300),
|
||||
width: 40, height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: todayDone ? const Color(0xFFDCFCE7) : (todayItem != null ? const Color(0xFFEDEAFF) : const Color(0xFFF5F5F5)),
|
||||
color: todayDone ? const Color(0xFFDCFCE7) : (todayItem != null ? AppTheme.primaryLight : const Color(0xFFF5F5F5)),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Icon(todayDone ? Icons.check_circle : Icons.check_circle_outline, size: 24, color: todayDone ? const Color(0xFF43A047) : const Color(0xFFBBBBBB)),
|
||||
child: Icon(todayDone ? Icons.check_circle : Icons.check_circle_outline, size: 28, color: todayDone ? AppTheme.success : const Color(0xFFBBBBBB)),
|
||||
),
|
||||
),
|
||||
]),
|
||||
@@ -238,7 +240,7 @@ class _ExercisePlanCreatePageState extends ConsumerState<ExercisePlanCreatePage>
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF8F9FC),
|
||||
backgroundColor: AppTheme.bg,
|
||||
appBar: AppBar(title: const Text('新建计划')),
|
||||
body: ListView(padding: const EdgeInsets.all(16), children: [
|
||||
_field('运动名称', _nameCtrl, hint: '如: 散步、慢跑、太极'),
|
||||
@@ -249,27 +251,27 @@ class _ExercisePlanCreatePageState extends ConsumerState<ExercisePlanCreatePage>
|
||||
const SizedBox(height: 16),
|
||||
_dateField('结束日期', _end, (d) => setState(() => _end = d)),
|
||||
const SizedBox(height: 32),
|
||||
SizedBox(width: double.infinity, child: ElevatedButton(onPressed: _save, style: ElevatedButton.styleFrom(backgroundColor: const Color(0xFF6C5CE7), foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), padding: const EdgeInsets.symmetric(vertical: 14)), child: const Text('保存计划', style: TextStyle(fontSize: 16)))),
|
||||
SizedBox(width: double.infinity, child: ElevatedButton(onPressed: _save, style: ElevatedButton.styleFrom(backgroundColor: AppTheme.primary, foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), padding: const EdgeInsets.symmetric(vertical: 14)), child: const Text('保存计划', style: TextStyle(fontSize: 19)))),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _field(String label, TextEditingController ctrl, {String? hint, bool number = false}) {
|
||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(label, style: const TextStyle(fontSize: 14, color: Color(0xFF666666))),
|
||||
Text(label, style: const TextStyle(fontSize: 17, color: Color(0xFF666666))),
|
||||
const SizedBox(height: 6),
|
||||
TextField(controller: ctrl, keyboardType: number ? TextInputType.number : null, decoration: InputDecoration(hintText: hint, filled: true, fillColor: Colors.white, border: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none)), style: const TextStyle(fontSize: 16)),
|
||||
TextField(controller: ctrl, keyboardType: number ? TextInputType.number : null, decoration: InputDecoration(hintText: hint, filled: true, fillColor: Colors.white, border: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none)), style: const TextStyle(fontSize: 19)),
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _dateField(String label, DateTime val, ValueChanged<DateTime> onChanged) {
|
||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(label, style: const TextStyle(fontSize: 14, color: Color(0xFF666666))),
|
||||
Text(label, style: const TextStyle(fontSize: 17, color: Color(0xFF666666))),
|
||||
const SizedBox(height: 6),
|
||||
GestureDetector(
|
||||
onTap: () async { final d = await showDatePicker(context: context, initialDate: val, firstDate: DateTime(2024), lastDate: DateTime(2030)); if (d != null) onChanged(d); },
|
||||
child: Container(width: double.infinity, padding: const EdgeInsets.all(14), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)),
|
||||
child: Text('${val.year}-${val.month.toString().padLeft(2,'0')}-${val.day.toString().padLeft(2,'0')}', style: const TextStyle(fontSize: 16))),
|
||||
child: Text('${val.year}-${val.month.toString().padLeft(2,'0')}-${val.day.toString().padLeft(2,'0')}', style: const TextStyle(fontSize: 19))),
|
||||
),
|
||||
]);
|
||||
}
|
||||
@@ -295,7 +297,7 @@ class _FollowUpListPageState extends ConsumerState<FollowUpListPage> {
|
||||
future: _future,
|
||||
builder: (ctx, snap) {
|
||||
if (snap.connectionState == ConnectionState.waiting) {
|
||||
return const Center(child: CircularProgressIndicator(color: Color(0xFF8B9CF7)));
|
||||
return const Center(child: CircularProgressIndicator(color: AppTheme.primaryLight));
|
||||
}
|
||||
final list = snap.data ?? [];
|
||||
if (list.isEmpty) {
|
||||
@@ -305,7 +307,7 @@ class _FollowUpListPageState extends ConsumerState<FollowUpListPage> {
|
||||
const SizedBox(height: 12),
|
||||
Text('暂无随访安排', style: Theme.of(context).textTheme.bodyMedium),
|
||||
const SizedBox(height: 4),
|
||||
const Text('医生创建随访后将显示在这里', style: TextStyle(fontSize: 13, color: Color(0xFF999999))),
|
||||
const Text('医生创建随访后将显示在这里', style: TextStyle(fontSize: 16, color: Color(0xFF999999))),
|
||||
]),
|
||||
);
|
||||
}
|
||||
@@ -335,8 +337,8 @@ class _FollowUpItem extends StatelessWidget {
|
||||
Color _statusColor(String? status) {
|
||||
switch (status) {
|
||||
case 'Upcoming': return const Color(0xFF4F6EF7);
|
||||
case 'Completed': return const Color(0xFF43A047);
|
||||
case 'Cancelled': return const Color(0xFFE53935);
|
||||
case 'Completed': return AppTheme.success;
|
||||
case 'Cancelled': return AppTheme.error;
|
||||
default: return const Color(0xFF999999);
|
||||
}
|
||||
}
|
||||
@@ -363,27 +365,27 @@ class _FollowUpItem extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(10), blurRadius: 4, offset: const Offset(0, 2))],
|
||||
boxShadow: [BoxShadow(color: AppTheme.primary.withAlpha(10), blurRadius: 4, offset: const Offset(0, 2))],
|
||||
),
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Row(children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(color: bg, borderRadius: BorderRadius.circular(8)),
|
||||
child: Text(label, style: TextStyle(fontSize: 12, color: color, fontWeight: FontWeight.w500)),
|
||||
child: Text(label, style: TextStyle(fontSize: 15, color: color, fontWeight: FontWeight.w500)),
|
||||
),
|
||||
const Spacer(),
|
||||
if (item['doctorName'] != null)
|
||||
Text('👨⚕️ ${item['doctorName']}', style: const TextStyle(fontSize: 12, color: Color(0xFF999999))),
|
||||
Text('👨⚕️ ${item['doctorName']}', style: const TextStyle(fontSize: 15, color: Color(0xFF999999))),
|
||||
]),
|
||||
const SizedBox(height: 12),
|
||||
Text(item['title']?.toString() ?? '', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
|
||||
Text(item['title']?.toString() ?? '', style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w600)),
|
||||
const SizedBox(height: 4),
|
||||
if (item['scheduledAt'] != null)
|
||||
Text(_formatDateTime(item['scheduledAt']?.toString()), style: TextStyle(fontSize: 14, color: Colors.grey[500])),
|
||||
Text(_formatDateTime(item['scheduledAt']?.toString()), style: TextStyle(fontSize: 17, color: Colors.grey[500])),
|
||||
if ((item['notes']?.toString() ?? '').isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
Text(item['notes']?.toString() ?? '', style: TextStyle(fontSize: 13, color: Colors.grey[600])),
|
||||
Text(item['notes']?.toString() ?? '', style: TextStyle(fontSize: 16, color: Colors.grey[600])),
|
||||
],
|
||||
]),
|
||||
);
|
||||
@@ -467,11 +469,11 @@ class _HealthArchivePageState extends ConsumerState<HealthArchivePage> {
|
||||
}
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
if (_loading) return Scaffold(appBar: AppBar(title: const Text('健康档案')), body: const Center(child: CircularProgressIndicator(color: Color(0xFF6C5CE7))));
|
||||
if (_loading) return Scaffold(appBar: AppBar(title: const Text('健康档案')), body: const Center(child: CircularProgressIndicator(color: AppTheme.primary)));
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF8F9FC),
|
||||
backgroundColor: AppTheme.bg,
|
||||
appBar: AppBar(title: const Text('健康档案'), actions: [
|
||||
TextButton(onPressed: _save, child: const Text('保存', style: TextStyle(color: Color(0xFF6C5CE7), fontWeight: FontWeight.w600))),
|
||||
TextButton(onPressed: _save, child: const Text('保存', style: TextStyle(color: AppTheme.primary, fontWeight: FontWeight.w600))),
|
||||
]),
|
||||
body: ListView(padding: const EdgeInsets.all(16), children: [
|
||||
_sectionTitle('个人资料'),
|
||||
@@ -500,21 +502,21 @@ class _HealthArchivePageState extends ConsumerState<HealthArchivePage> {
|
||||
|
||||
Widget _sectionTitle(String title) => Padding(
|
||||
padding: const EdgeInsets.only(left: 4, top: 16, bottom: 8),
|
||||
child: Text(title, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w700, color: Color(0xFF6C5CE7))),
|
||||
child: Text(title, style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w700, color: AppTheme.primary)),
|
||||
);
|
||||
|
||||
Widget _editableCard({required List<Widget> children}) => Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: const Color(0xFF6C5CE7).withAlpha(8), blurRadius: 8, offset: const Offset(0, 2))]),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: AppTheme.primary.withAlpha(8), blurRadius: 8, offset: const Offset(0, 2))]),
|
||||
child: Column(children: children),
|
||||
);
|
||||
|
||||
Widget _field(String label, TextEditingController ctrl, {String? hint}) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(label, style: const TextStyle(fontSize: 13, color: Color(0xFF888888))),
|
||||
Text(label, style: const TextStyle(fontSize: 16, color: Color(0xFF888888))),
|
||||
const SizedBox(height: 4),
|
||||
TextField(controller: ctrl, decoration: InputDecoration(hintText: hint, filled: true, fillColor: const Color(0xFFF4F5FA), contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), border: OutlineInputBorder(borderRadius: BorderRadius.circular(10), borderSide: BorderSide.none)), style: const TextStyle(fontSize: 15)),
|
||||
TextField(controller: ctrl, decoration: InputDecoration(hintText: hint, filled: true, fillColor: const Color(0xFFF4F5FA), contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), border: OutlineInputBorder(borderRadius: BorderRadius.circular(10), borderSide: BorderSide.none)), style: const TextStyle(fontSize: 18)),
|
||||
]),
|
||||
);
|
||||
}
|
||||
@@ -581,7 +583,7 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
|
||||
),
|
||||
Text(
|
||||
'${_currentMonth.year}年${_currentMonth.month}月',
|
||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
|
||||
style: const TextStyle(fontSize: 21, fontWeight: FontWeight.w600),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.chevron_right, size: 32),
|
||||
@@ -594,7 +596,7 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
|
||||
Widget _buildWeekdayHeader() {
|
||||
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
return Row(children: weekdays.map((day) => Expanded(
|
||||
child: Center(child: Text(day, style: TextStyle(fontSize: 14, color: Colors.grey[500]))),
|
||||
child: Center(child: Text(day, style: TextStyle(fontSize: 17, color: Colors.grey[500]))),
|
||||
)).toList());
|
||||
}
|
||||
|
||||
@@ -631,7 +633,7 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
|
||||
|
||||
return Container(
|
||||
decoration: isToday ? BoxDecoration(
|
||||
color: const Color(0xFF8B9CF7),
|
||||
color: AppTheme.primary,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
) : null,
|
||||
child: Stack(
|
||||
@@ -640,7 +642,7 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
|
||||
Text(
|
||||
'$day',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontSize: 19,
|
||||
color: isToday ? Colors.white : Colors.black,
|
||||
fontWeight: isToday ? FontWeight.w600 : FontWeight.normal,
|
||||
),
|
||||
@@ -670,8 +672,8 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
|
||||
|
||||
Color _getEventColor(String type) {
|
||||
switch (type) {
|
||||
case 'medication': return const Color(0xFF8B9CF7);
|
||||
case 'exercise': return const Color(0xFF43A047);
|
||||
case 'medication': return AppTheme.primary;
|
||||
case 'exercise': return AppTheme.success;
|
||||
case 'followup': return const Color(0xFFF59E0B);
|
||||
default: return Colors.grey;
|
||||
}
|
||||
@@ -679,8 +681,8 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
|
||||
|
||||
Widget _buildLegend() {
|
||||
final items = [
|
||||
{'color': const Color(0xFF8B9CF7), 'label': '用药提醒'},
|
||||
{'color': const Color(0xFF43A047), 'label': '运动计划'},
|
||||
{'color': AppTheme.primary, 'label': '用药提醒'},
|
||||
{'color': AppTheme.success, 'label': '运动计划'},
|
||||
{'color': const Color(0xFFF59E0B), 'label': '复查随访'},
|
||||
];
|
||||
return Container(
|
||||
@@ -688,7 +690,7 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: items.map((item) => Row(children: [
|
||||
Container(width: 10, height: 10, decoration: BoxDecoration(color: item['color'] as Color, borderRadius: BorderRadius.circular(5))),
|
||||
const SizedBox(width: 4),
|
||||
Text(item['label'] as String, style: TextStyle(fontSize: 12, color: Colors.grey[600])),
|
||||
Text(item['label'] as String, style: TextStyle(fontSize: 15, color: Colors.grey[600])),
|
||||
const SizedBox(width: 20),
|
||||
])).toList()),
|
||||
);
|
||||
@@ -782,7 +784,7 @@ class StaticTextPage extends ConsumerWidget {
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Text(contents[type] ?? '内容加载中...', style: const TextStyle(fontSize: 14, height: 1.8, color: Color(0xFF333333))),
|
||||
child: Text(contents[type] ?? '内容加载中...', style: const TextStyle(fontSize: 17, height: 1.8, color: Color(0xFF333333))),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -831,10 +833,10 @@ class _SwipeDeleteTileState extends State<_SwipeDeleteTile> with SingleTickerPro
|
||||
return Stack(children: [
|
||||
Positioned.fill(child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||
decoration: BoxDecoration(color: const Color(0xFFE53935), borderRadius: BorderRadius.circular(16)),
|
||||
decoration: BoxDecoration(color: AppTheme.error, borderRadius: BorderRadius.circular(16)),
|
||||
child: const Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Padding(padding: EdgeInsets.only(right: 20), child: Icon(Icons.delete_outline, color: Colors.white, size: 24)),
|
||||
child: Padding(padding: EdgeInsets.only(right: 20), child: Icon(Icons.delete_outline, color: Colors.white, size: 28)),
|
||||
),
|
||||
)),
|
||||
GestureDetector(
|
||||
|
||||
Reference in New Issue
Block a user