feat: update user

This commit is contained in:
efrilm
2025-08-19 15:05:08 +07:00
parent bfd4604897
commit 7919825955
37 changed files with 2531 additions and 897 deletions
@@ -7,7 +7,7 @@ import '../../../../common/constant/app_constant.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/painter/wave_painter.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/auth/auth.dart';
import '../../../../domain/user/user.dart';
import '../../../components/spacer/spacer.dart';
class HomeHeader extends StatefulWidget {
@@ -0,0 +1,108 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../../application/auth/auth_bloc.dart';
import '../../../../../application/user/user_edit_form/user_edit_form_bloc.dart';
import '../../../../../common/theme/theme.dart';
import '../../../../../domain/user/user.dart';
import '../../../../../injection.dart';
import '../../../../components/appbar/appbar.dart';
import '../../../../components/button/button.dart';
import '../../../../components/spacer/spacer.dart';
import '../../../../components/toast/flushbar.dart';
import 'widgets/name_field.dart';
@RoutePage()
class ProfileEditPage extends StatefulWidget implements AutoRouteWrapper {
final User user;
const ProfileEditPage({super.key, required this.user});
@override
State<ProfileEditPage> createState() => _ProfileEditPageState();
@override
Widget wrappedRoute(BuildContext context) =>
BlocProvider(create: (_) => getIt<UserEditFormBloc>(), child: this);
}
class _ProfileEditPageState extends State<ProfileEditPage> {
TextEditingController nameController = TextEditingController();
@override
void initState() {
super.initState();
nameController = TextEditingController(text: widget.user.name);
}
@override
Widget build(BuildContext context) {
return BlocListener<UserEditFormBloc, UserEditFormState>(
listenWhen: (p, c) => p.failureOrUserOption != c.failureOrUserOption,
listener: (context, state) {
state.failureOrUserOption.fold(
() => null,
(either) => either.fold(
(f) => AppFlushbar.showUserFailureToast(context, f),
(user) {
if (context.mounted) {
context.read<AuthBloc>().add(AuthEvent.fetchCurrentUser());
context.router.back();
}
},
),
);
},
child: Scaffold(
backgroundColor: AppColor.background,
body: CustomScrollView(
slivers: [
// SliverAppBar with gradient
SliverAppBar(
expandedHeight: 120,
floating: false,
pinned: true,
elevation: 0,
backgroundColor: AppColor.primary,
flexibleSpace: CustomAppBar(title: 'Profile Edit'),
),
SliverToBoxAdapter(
child: BlocBuilder<UserEditFormBloc, UserEditFormState>(
builder: (context, state) {
return Container(
margin: EdgeInsets.all(AppValue.margin),
padding: EdgeInsets.all(AppValue.padding),
decoration: BoxDecoration(
color: AppColor.white,
borderRadius: BorderRadius.circular(AppValue.radius),
),
child: Form(
autovalidateMode: state.showErrorMessages
? AutovalidateMode.always
: AutovalidateMode.disabled,
child: Column(
children: [
ProfileEditNameField(controller: nameController),
SpaceHeight(24),
AppElevatedButton(
text: 'Save',
isLoading: state.isSubmitting,
onPressed: () {
context.read<UserEditFormBloc>().add(
UserEditFormEvent.submitted(),
);
},
),
],
),
),
);
},
),
),
],
),
),
);
}
}
@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:line_icons/line_icons.dart';
import '../../../../../../application/user/user_edit_form/user_edit_form_bloc.dart';
import '../../../../../components/field/field.dart';
class ProfileEditNameField extends StatelessWidget {
final TextEditingController controller;
const ProfileEditNameField({super.key, required this.controller});
@override
Widget build(BuildContext context) {
return AppTextFormField(
title: 'Name',
prefixIcon: LineIcons.user,
hintText: 'Please enter your name',
controller: controller,
onChanged: (value) {
context.read<UserEditFormBloc>().add(
UserEditFormEvent.nameChanged(value),
);
},
validator: (value) {
if (context.read<UserEditFormBloc>().state.name.isEmpty) {
return 'Please enter your name';
}
return null;
},
);
}
}
@@ -98,7 +98,9 @@ class ProfilePage extends StatelessWidget implements AutoRouteWrapper {
),
),
ActionIconButton(
onTap: () {},
onTap: () => context.router.push(
ProfileEditRoute(user: state.user),
),
icon: LineIcons.userEdit,
),
],
@@ -1,9 +1,11 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:line_icons/line_icons.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/auth/auth.dart';
import '../../../../domain/user/user.dart';
import '../../../router/app_router.gr.dart';
import 'divider.dart';
import 'profile_tile.dart';
@@ -45,9 +47,7 @@ class ProfileAccountInfo extends StatelessWidget {
icon: LineIcons.envelope,
title: 'Email',
subtitle: user.email,
onTap: () {
// Edit email
},
showArrow: false,
),
ProfileDivider(),
@@ -64,7 +64,7 @@ class ProfileAccountInfo extends StatelessWidget {
icon: LineIcons.userEdit,
title: 'Ubah Profil',
subtitle: 'Ubah profil kamu',
showArrow: false,
onTap: () => context.router.push(ProfileEditRoute(user: user)),
),
],
),
@@ -4,7 +4,7 @@ import 'dart:math' as math;
import '../../../../common/extension/extension.dart';
import '../../../../common/painter/wave_painter.dart';
import '../../../../common/theme/theme.dart';
import '../../../../domain/auth/auth.dart';
import '../../../../domain/user/user.dart';
import '../../../components/spacer/spacer.dart';
class ProfileHeader extends StatefulWidget {