181 lines
5.0 KiB
Dart
181 lines
5.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:food_health/api/dto/user_profile_dto.dart';
|
|
import 'package:food_health/config/theme/custom_colors.dart';
|
|
import 'package:food_health/providers/app_store.dart';
|
|
import 'package:food_health/router/config/route_paths.dart';
|
|
import 'package:food_health/utils/common.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:remixicon/remixicon.dart';
|
|
|
|
class UserCard extends StatefulWidget {
|
|
final UserProfileDto detail;
|
|
final Function() onEdit;
|
|
|
|
const UserCard({
|
|
super.key,
|
|
required this.detail,
|
|
required this.onEdit,
|
|
});
|
|
|
|
@override
|
|
State<UserCard> createState() => _UserCardState();
|
|
}
|
|
|
|
class _UserCardState extends State<UserCard> {
|
|
void _goEdit() {
|
|
widget.onEdit();
|
|
}
|
|
|
|
void _handLogout() {
|
|
var appStore = context.read<AppStore>();
|
|
appStore.logout();
|
|
context.go(RoutePaths.login);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.all(16),
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).colorScheme.surface,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Theme.of(context).colorScheme.shadow,
|
|
blurRadius: 7,
|
|
offset: const Offset(0, 4),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
children: [
|
|
avatarWidget(),
|
|
Container(
|
|
margin: const EdgeInsets.only(top: 12),
|
|
child: Text(getNotEmpty(widget.detail.name) ?? "user", style: Theme.of(context).textTheme.titleMedium),
|
|
),
|
|
Container(
|
|
margin: const EdgeInsets.only(top: 5),
|
|
child: Text(widget.detail.email ?? "", style: Theme.of(context).textTheme.labelMedium),
|
|
),
|
|
buildTitledTags(
|
|
title: "Age Range",
|
|
tag: getNotEmpty(widget.detail.ageRange),
|
|
),
|
|
buildTitledTags(
|
|
title: "Activity Level",
|
|
tag: getNotEmpty(widget.detail.activityLevel),
|
|
),
|
|
SizedBox(height: 20),
|
|
btnItem(
|
|
title: "Edit Profile",
|
|
icon: RemixIcons.edit_box_line,
|
|
color: Colors.white,
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
colors: [
|
|
Theme.of(context).colorScheme.primary,
|
|
Theme.of(context).colorScheme.primaryEnd,
|
|
],
|
|
),
|
|
),
|
|
onTap: _goEdit,
|
|
),
|
|
btnItem(
|
|
title: "Logout",
|
|
icon: RemixIcons.logout_circle_line,
|
|
decoration: BoxDecoration(color: Theme.of(context).colorScheme.surfaceContainer),
|
|
onTap: _handLogout,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
///头像
|
|
Widget avatarWidget() {
|
|
return Container(
|
|
width: 70,
|
|
height: 70,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
gradient: LinearGradient(
|
|
colors: [
|
|
Theme.of(context).colorScheme.primary,
|
|
Theme.of(context).colorScheme.primaryEnd,
|
|
],
|
|
),
|
|
),
|
|
child: Icon(
|
|
RemixIcons.user_3_line,
|
|
color: Colors.white,
|
|
size: 30,
|
|
),
|
|
);
|
|
}
|
|
|
|
///标题标签
|
|
Widget buildTitledTags({
|
|
required String title,
|
|
String? tag,
|
|
}) {
|
|
return Container(
|
|
margin: const EdgeInsets.only(top: 20),
|
|
width: double.infinity,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(title, style: Theme.of(context).textTheme.bodyMedium),
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 3),
|
|
margin: const EdgeInsets.only(top: 5),
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Text(
|
|
tag ?? "Untitled",
|
|
style: Theme.of(context).textTheme.labelMedium?.copyWith(
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
///按钮
|
|
Widget btnItem({
|
|
required String title,
|
|
required IconData icon,
|
|
required BoxDecoration decoration,
|
|
Color color = Colors.black,
|
|
required Function() onTap,
|
|
}) {
|
|
return InkWell(
|
|
onTap: onTap,
|
|
child: Container(
|
|
margin: const EdgeInsets.only(top: 15),
|
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
|
decoration: decoration.copyWith(
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(icon, size: 20, color: color),
|
|
SizedBox(width: 10),
|
|
Text(
|
|
title,
|
|
style: TextStyle(color: color, fontWeight: FontWeight.w500),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|