登录流程已全部重构

This commit is contained in:
zhutao
2025-09-23 11:47:29 +08:00
parent a4992a063b
commit 8988b3feea
71 changed files with 2036 additions and 901 deletions

View File

@@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
class TitleCard extends StatelessWidget {
final String title;
final Widget icon;
final Widget child;
const TitleCard({
super.key,
required this.title,
required this.icon,
required this.child,
});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: EdgeInsets.all(15),
margin: EdgeInsets.only(top: 15),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(color: Theme.of(context).colorScheme.shadow, blurRadius: 7),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(bottom: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 10,
children: [
icon,
Text(
title,
style: Theme.of(context).textTheme.titleMedium,
),
],
),
),
child,
],
),
);
}
}

View File

@@ -0,0 +1,248 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:food_health/api/dto/user_profile_dto.dart';
import 'package:food_health/api/endpoints/user_api.dart';
import 'package:food_health/config/theme/color_ext.dart';
import 'package:food_health/stores/app_store.dart';
import 'package:food_health/stores/user_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 {
const UserCard({super.key});
@override
State<UserCard> createState() => _UserCardState();
}
class _UserCardState extends State<UserCard> {
void _goEditProfile() async {
var isUpload = await context.push(RoutePaths.myEdit);
if (isUpload == true && mounted) {
UserStore userStore = context.read<UserStore>();
userStore.init();
}
}
///退出登陆
void _handLogout() async {
await showCupertinoDialog(
context: context,
builder: (_) => CupertinoAlertDialog(
title: Text("Log Out?"),
content: Text("Are you sure you want to log out? Youll need to sign in again to access your account."),
actions: [
CupertinoDialogAction(
child: Text("Cancel"),
onPressed: () {
context.pop();
},
),
CupertinoDialogAction(
child: Text("Log Out"),
onPressed: () {
context.pop();
var appStore = context.read<AppStore>();
appStore.logout();
context.go(RoutePaths.login);
},
),
],
),
);
}
///注销账号
void _handDelete() async {
await showCupertinoDialog(
context: context,
builder: (_) => CupertinoAlertDialog(
title: Text("Delete Account?"),
content: Text("Are you sure you want to delete your account? You wont be able to recover your account."),
actions: [
CupertinoDialogAction(
onPressed: () {
context.pop();
},
child: Text("Cancel"),
),
CupertinoDialogAction(
child: Text("Delete"),
onPressed: () async {
context.pop();
EasyLoading.show();
await deleteAccountApi();
EasyLoading.dismiss();
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: Consumer<UserStore>(
builder: (context, store, _) {
return Column(
children: [
avatarWidget(),
Container(
margin: const EdgeInsets.only(top: 12),
child: Text(getNotEmpty(store.profile.name) ?? "user", style: Theme.of(context).textTheme.titleMedium),
),
Container(
margin: const EdgeInsets.only(top: 5),
child: Text(store.profile.email ?? "", style: Theme.of(context).textTheme.labelMedium),
),
buildTitledTags(
title: "Age Range",
tag: getNotEmpty(store.profile.ageRange),
),
buildTitledTags(
title: "Activity Level",
tag: getNotEmpty(store.profile.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: _goEditProfile,
),
btnItem(
title: "Logout",
icon: RemixIcons.logout_circle_line,
decoration: BoxDecoration(color: Theme.of(context).colorScheme.surfaceContainer),
onTap: _handLogout,
),
Container(
margin: const EdgeInsets.only(top: 10),
child: InkWell(
onTap: _handDelete,
child: Text(
"Delete Account ",
style: TextStyle(color: Colors.red, fontSize: 14),
),
),
),
],
);
},
),
);
}
///头像
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),
),
],
),
),
);
}
}