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:
@@ -351,9 +351,9 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
: null,
|
||||
),
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Icon(m.icon, size: 20, color: isSelected ? Colors.white : _kSubText),
|
||||
Icon(m.icon, size: 23, color: isSelected ? Colors.white : _kSubText),
|
||||
const SizedBox(height: 4),
|
||||
Text(m.label, style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: isSelected ? Colors.white : _kSubText)),
|
||||
Text(m.label, style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: isSelected ? Colors.white : _kSubText)),
|
||||
]),
|
||||
),
|
||||
),
|
||||
@@ -376,15 +376,15 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
const CircularProgressIndicator(strokeWidth: 3, color: _kPrimary),
|
||||
const Icon(Icons.restaurant, size: 22, color: _kPrimary),
|
||||
const Icon(Icons.restaurant, size: 25, color: _kPrimary),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const Text('正在识别食物...', style: TextStyle(fontSize: 15, color: _kSubText)),
|
||||
const Text('正在识别食物...', style: TextStyle(fontSize: 18, color: _kSubText)),
|
||||
if (state.errorMessage != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
Text(state.errorMessage!, style: const TextStyle(fontSize: 13, color: AppTheme.error), textAlign: TextAlign.center),
|
||||
Text(state.errorMessage!, style: const TextStyle(fontSize: 16, color: AppTheme.error), textAlign: TextAlign.center),
|
||||
],
|
||||
]),
|
||||
),
|
||||
@@ -411,16 +411,16 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(color: _kPrimaryLight, borderRadius: BorderRadius.circular(8)),
|
||||
child: const Text('识别结果', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: _kPrimary)),
|
||||
child: const Text('识别结果', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: _kPrimary)),
|
||||
),
|
||||
const Spacer(),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(color: const Color(0xFFFFF8EE), borderRadius: BorderRadius.circular(8)),
|
||||
child: Text('共 $totalCal kcal', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: _kWarning)),
|
||||
child: Text('共 $totalCal kcal', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: _kWarning)),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.add_circle_outline, size: 22, color: _kPrimary),
|
||||
icon: const Icon(Icons.add_circle_outline, size: 25, color: _kPrimary),
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: () => ref.read(dietProvider.notifier).addFood(),
|
||||
@@ -457,7 +457,7 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
color: food.selected ? _kPrimary : Colors.white,
|
||||
border: Border.all(color: food.selected ? _kPrimary : const Color(0xFFCCCCCC), width: 2),
|
||||
),
|
||||
child: food.selected ? const Icon(Icons.check, size: 14, color: Colors.white) : null,
|
||||
child: food.selected ? const Icon(Icons.check, size: 17, color: Colors.white) : null,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@@ -466,7 +466,7 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
TextField(
|
||||
controller: TextEditingController(text: food.name),
|
||||
onChanged: (v) => ref.read(dietProvider.notifier).updateFoodName(food.id, v),
|
||||
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: _kText),
|
||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: _kText),
|
||||
decoration: const InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
@@ -480,13 +480,13 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
child: TextField(
|
||||
controller: TextEditingController(text: food.portion),
|
||||
onChanged: (v) => ref.read(dietProvider.notifier).updateFoodPortion(food.id, v),
|
||||
style: const TextStyle(fontSize: 12, color: _kSubText),
|
||||
style: const TextStyle(fontSize: 15, color: _kSubText),
|
||||
decoration: const InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
hintText: '份量',
|
||||
hintStyle: TextStyle(fontSize: 12, color: AppTheme.textHint),
|
||||
hintStyle: TextStyle(fontSize: 15, color: AppTheme.textHint),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -497,24 +497,24 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
controller: TextEditingController(text: food.calories.toString()),
|
||||
onChanged: (v) => ref.read(dietProvider.notifier).updateFoodCalories(food.id, int.tryParse(v) ?? 0),
|
||||
keyboardType: TextInputType.number,
|
||||
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _kWarning),
|
||||
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: _kWarning),
|
||||
textAlign: TextAlign.right,
|
||||
decoration: const InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
hintText: '0',
|
||||
hintStyle: TextStyle(fontSize: 12),
|
||||
hintStyle: TextStyle(fontSize: 15),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
const Text('kcal', style: TextStyle(fontSize: 11, color: _kSubText)),
|
||||
const Text('kcal', style: TextStyle(fontSize: 14, color: _kSubText)),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close, size: 16, color: Color(0xFFBBBBBB)),
|
||||
icon: const Icon(Icons.close, size: 19, color: Color(0xFFBBBBBB)),
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: () => ref.read(dietProvider.notifier).removeFood(food.id),
|
||||
@@ -552,8 +552,8 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
),
|
||||
),
|
||||
Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Text('$totalCalories', style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w800, color: Colors.white)),
|
||||
Text('kcal', style: const TextStyle(fontSize: 10, color: Colors.white70)),
|
||||
Text('$totalCalories', style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w800, color: Colors.white)),
|
||||
Text('kcal', style: const TextStyle(fontSize: 13, color: Colors.white70)),
|
||||
]),
|
||||
],
|
||||
),
|
||||
@@ -561,7 +561,7 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
const Text('本餐热量', style: TextStyle(fontSize: 14, color: Colors.white70)),
|
||||
const Text('本餐热量', style: TextStyle(fontSize: 17, color: Colors.white70)),
|
||||
const SizedBox(height: 4),
|
||||
Row(children: [
|
||||
Expanded(child: _macroBar('碳水', 0.55, const Color(0xFFFFF9C4))),
|
||||
@@ -582,7 +582,7 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
Row(children: [
|
||||
Container(width: 6, height: 6, decoration: BoxDecoration(color: color, shape: BoxShape.circle)),
|
||||
const SizedBox(width: 4),
|
||||
Text(label, style: const TextStyle(fontSize: 10, color: Colors.white70)),
|
||||
Text(label, style: const TextStyle(fontSize: 13, color: Colors.white70)),
|
||||
]),
|
||||
const SizedBox(height: 3),
|
||||
ClipRRect(
|
||||
@@ -607,10 +607,10 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
Container(
|
||||
width: 32, height: 32,
|
||||
decoration: BoxDecoration(color: _kPrimaryLight, borderRadius: BorderRadius.circular(8)),
|
||||
child: const Icon(Icons.auto_awesome, size: 16, color: _kPrimary),
|
||||
child: const Icon(Icons.auto_awesome, size: 19, color: _kPrimary),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(child: Text(text, style: const TextStyle(fontSize: 13, color: _kText, height: 1.6))),
|
||||
Expanded(child: Text(text, style: const TextStyle(fontSize: 16, color: _kText, height: 1.6))),
|
||||
]),
|
||||
),
|
||||
);
|
||||
@@ -650,11 +650,11 @@ class _DietCapturePageState extends ConsumerState<DietCapturePage> {
|
||||
backgroundColor: _kPrimary,
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppTheme.radiusMd)),
|
||||
textStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppTheme.rMd)),
|
||||
textStyle: const TextStyle(fontSize: 19, fontWeight: FontWeight.w600),
|
||||
),
|
||||
child: const Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
Icon(Icons.check_circle_outline, size: 20),
|
||||
Icon(Icons.check_circle_outline, size: 23),
|
||||
SizedBox(width: 8),
|
||||
Text('保存记录'),
|
||||
]),
|
||||
|
||||
Reference in New Issue
Block a user