Polish health app UI

This commit is contained in:
MingNian
2026-06-26 14:37:17 +08:00
parent 86c7957144
commit df37076c46
46 changed files with 717 additions and 514 deletions

View File

@@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import '../../core/app_colors.dart';
import '../../core/app_theme.dart';
import '../../core/navigation_provider.dart';
import '../../providers/data_providers.dart';
import '../../services/in_app_notification_service.dart';
@@ -147,7 +146,7 @@ class _NotificationCenterPageState
final unread = _history?.unreadCount ?? 0;
return Scaffold(
backgroundColor: const Color(0xFFF8FAFF),
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
@@ -248,19 +247,19 @@ class _NotificationCenterPageState
return ListView(
physics: const AlwaysScrollableScrollPhysics(),
padding: const EdgeInsets.fromLTRB(16, 12, 16, 32),
padding: const EdgeInsets.fromLTRB(16, 14, 16, 32),
children: [
if (unread > 0) _UnreadHint(unreadCount: unread),
const SizedBox(height: 8),
if (today.isNotEmpty) ...[
const _SectionTitle('今天'),
const SizedBox(height: 8),
const SizedBox(height: 10),
...today.map(_buildDismissible),
],
if (earlier.isNotEmpty) ...[
if (today.isNotEmpty) const SizedBox(height: 14),
if (today.isNotEmpty) const SizedBox(height: 18),
const _SectionTitle('更早'),
const SizedBox(height: 8),
const SizedBox(height: 10),
...earlier.map(_buildDismissible),
],
],
@@ -268,7 +267,7 @@ class _NotificationCenterPageState
}
Widget _buildDismissible(InAppNotification item) => Padding(
padding: const EdgeInsets.only(bottom: 10),
padding: const EdgeInsets.only(bottom: 12),
child: Dismissible(
key: ValueKey(item.id),
direction: DismissDirection.endToStart,
@@ -281,7 +280,7 @@ class _NotificationCenterPageState
end: Alignment.centerRight,
colors: [AppColors.error.withValues(alpha: 0.6), AppColors.error],
),
borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.circular(28),
),
child: const Row(
mainAxisSize: MainAxisSize.min,
@@ -312,15 +311,21 @@ class _UnreadHint extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 8),
return Container(
margin: const EdgeInsets.fromLTRB(0, 4, 0, 12),
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(
color: const Color(0xFFFFFBEB),
borderRadius: BorderRadius.circular(999),
border: Border.all(color: const Color(0xFFFDE68A)),
),
child: Row(
children: [
Container(
width: 6,
height: 6,
width: 8,
height: 8,
decoration: const BoxDecoration(
color: Color(0xFFEF4444),
color: Color(0xFFF97316),
shape: BoxShape.circle,
),
),
@@ -329,8 +334,8 @@ class _UnreadHint extends StatelessWidget {
'你有 $unreadCount 条未读消息',
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
color: AppColors.textSecondary,
fontWeight: FontWeight.w800,
color: Color(0xFF92400E),
),
),
],
@@ -344,15 +349,21 @@ class _SectionTitle extends StatelessWidget {
const _SectionTitle(this.text);
@override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.fromLTRB(2, 12, 2, 6),
Widget build(BuildContext context) => Container(
margin: const EdgeInsets.fromLTRB(0, 12, 0, 2),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: const Color(0xFFF8FAFC),
borderRadius: BorderRadius.circular(999),
border: Border.all(color: const Color(0xFFE5E7EB)),
),
child: Row(
children: [
Container(
width: 4,
height: 16,
width: 8,
height: 8,
decoration: BoxDecoration(
color: AppColors.primary,
gradient: AppColors.doctorGradient,
borderRadius: BorderRadius.circular(99),
),
),
@@ -366,8 +377,18 @@ class _SectionTitle extends StatelessWidget {
),
),
const SizedBox(width: 10),
const Expanded(
child: Divider(height: 1, thickness: 1, color: AppColors.divider),
Expanded(
child: Container(
height: 1,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
const Color(0xFFE5E7EB),
const Color(0xFFE5E7EB).withValues(alpha: 0),
],
),
),
),
),
],
),
@@ -385,26 +406,32 @@ class _NotificationCard extends StatelessWidget {
final visual = _NotificationVisual.of(item);
return Material(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.circular(28),
elevation: 0,
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.circular(28),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 13),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.circular(28),
border: Border.all(
color: item.isRead
? AppColors.border
: visual.color.withValues(alpha: 0.34),
width: item.isRead ? 1 : 1.2,
? const Color(0xFFF1F5F9)
: visual.color.withValues(alpha: 0.24),
width: 1,
),
boxShadow: [
BoxShadow(
color: const Color(0xFF101828).withValues(alpha: 0.03),
blurRadius: 8,
offset: const Offset(0, 2),
color: const Color(0xFF0F172A).withValues(alpha: 0.08),
blurRadius: 22,
offset: const Offset(0, 10),
),
BoxShadow(
color: visual.color.withValues(alpha: item.isRead ? 0 : 0.08),
blurRadius: 18,
offset: const Offset(0, 8),
),
],
),
@@ -416,21 +443,24 @@ class _NotificationCard extends StatelessWidget {
clipBehavior: Clip.none,
children: [
Container(
width: 44,
height: 44,
width: 48,
height: 48,
decoration: BoxDecoration(
color: visual.lightColor,
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(18),
border: Border.all(
color: visual.color.withValues(alpha: 0.12),
),
),
child: Icon(visual.icon, size: 22, color: visual.color),
child: Icon(visual.icon, size: 23, color: visual.color),
),
if (!item.isRead)
Positioned(
top: -2,
right: -2,
child: Container(
width: 9,
height: 9,
width: 10,
height: 10,
decoration: BoxDecoration(
color: const Color(0xFFEF4444),
shape: BoxShape.circle,
@@ -440,7 +470,7 @@ class _NotificationCard extends StatelessWidget {
),
],
),
const SizedBox(width: 12),
const SizedBox(width: 13),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -463,25 +493,36 @@ class _NotificationCard extends StatelessWidget {
),
),
),
const SizedBox(width: 6),
Text(
_formatTime(item.createdAt),
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: AppColors.textSecondary,
const SizedBox(width: 8),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
),
decoration: BoxDecoration(
color: const Color(0xFFF8FAFC),
borderRadius: BorderRadius.circular(999),
),
child: Text(
_formatTime(item.createdAt),
style: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.w700,
color: AppColors.textSecondary,
),
),
),
],
),
const SizedBox(height: 5),
const SizedBox(height: 6),
Text(
item.message,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 14,
height: 1.45,
height: 1.5,
fontWeight: FontWeight.w500,
color: AppColors.textSecondary,
),
),