feat: 实现用户画像、占卜历史与后端用户管理模块
This commit is contained in:
@@ -120,9 +120,20 @@ class SettingsMenuTile extends StatelessWidget {
|
||||
}
|
||||
|
||||
class ProfileHeaderCard extends StatelessWidget {
|
||||
const ProfileHeaderCard({super.key, required this.account});
|
||||
const ProfileHeaderCard({
|
||||
super.key,
|
||||
required this.account,
|
||||
required this.displayName,
|
||||
required this.bio,
|
||||
required this.avatarUrl,
|
||||
required this.onEditTap,
|
||||
});
|
||||
|
||||
final String account;
|
||||
final String displayName;
|
||||
final String bio;
|
||||
final String? avatarUrl;
|
||||
final VoidCallback onEditTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -137,22 +148,83 @@ class ProfileHeaderCard extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 28,
|
||||
backgroundColor: colors.surfaceContainerHighest,
|
||||
child: Icon(Icons.person_rounded, color: colors.primary),
|
||||
Container(
|
||||
width: 56,
|
||||
height: 56,
|
||||
decoration: BoxDecoration(
|
||||
color: colors.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: _AvatarContent(avatarUrl: avatarUrl),
|
||||
),
|
||||
const SizedBox(width: AppSpacing.md),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(account, style: Theme.of(context).textTheme.titleMedium),
|
||||
Text(
|
||||
displayName,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
account,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
if (bio.isNotEmpty) ...[
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
Text(
|
||||
bio,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
Icon(Icons.edit_outlined, color: colors.outline, size: 20),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Material(
|
||||
color: colors.surface,
|
||||
elevation: 2,
|
||||
shadowColor: colors.shadow.withValues(alpha: 0.35),
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
child: InkWell(
|
||||
onTap: onEditTap,
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.md,
|
||||
vertical: AppSpacing.sm,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
border: Border.all(
|
||||
color: colors.primary.withValues(alpha: 0.24),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.edit_rounded, color: colors.primary, size: 18),
|
||||
const SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.settingsEditProfileAction,
|
||||
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
||||
color: colors.primary,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -160,6 +232,32 @@ class ProfileHeaderCard extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _AvatarContent extends StatelessWidget {
|
||||
const _AvatarContent({required this.avatarUrl});
|
||||
|
||||
final String? avatarUrl;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colors = Theme.of(context).colorScheme;
|
||||
final url = avatarUrl?.trim() ?? '';
|
||||
if (url.isNotEmpty) {
|
||||
return ClipOval(
|
||||
child: Image.network(
|
||||
url,
|
||||
width: 56,
|
||||
height: 56,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return Icon(Icons.person_rounded, color: colors.primary, size: 30);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
return Icon(Icons.person_rounded, color: colors.primary, size: 30);
|
||||
}
|
||||
}
|
||||
|
||||
class WalletHeroCard extends StatelessWidget {
|
||||
const WalletHeroCard({
|
||||
super.key,
|
||||
|
||||
Reference in New Issue
Block a user