diff --git a/assets/icon/outline/arrow-right.svg b/assets/icon/outline/arrow-right.svg
new file mode 100644
index 0000000..0bf5006
--- /dev/null
+++ b/assets/icon/outline/arrow-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icon/outline/empty-wallet.svg b/assets/icon/outline/empty-wallet.svg
new file mode 100644
index 0000000..3e5c996
--- /dev/null
+++ b/assets/icon/outline/empty-wallet.svg
@@ -0,0 +1,6 @@
+
diff --git a/assets/icon/outline/frame.svg b/assets/icon/outline/frame.svg
new file mode 100644
index 0000000..d4253ed
--- /dev/null
+++ b/assets/icon/outline/frame.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/icon/outline/logout.svg b/assets/icon/outline/logout.svg
new file mode 100644
index 0000000..9bc1219
--- /dev/null
+++ b/assets/icon/outline/logout.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/icon/outline/message-question.svg b/assets/icon/outline/message-question.svg
new file mode 100644
index 0000000..5d7c520
--- /dev/null
+++ b/assets/icon/outline/message-question.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/icon/outline/notification.svg b/assets/icon/outline/notification.svg
new file mode 100644
index 0000000..ca6c260
--- /dev/null
+++ b/assets/icon/outline/notification.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/icon/outline/profile.svg b/assets/icon/outline/profile.svg
new file mode 100644
index 0000000..098203e
--- /dev/null
+++ b/assets/icon/outline/profile.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/icon/outline/shield.svg b/assets/icon/outline/shield.svg
new file mode 100644
index 0000000..25a5895
--- /dev/null
+++ b/assets/icon/outline/shield.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icon/outline/shop-add.svg b/assets/icon/outline/shop-add.svg
new file mode 100644
index 0000000..8a946c1
--- /dev/null
+++ b/assets/icon/outline/shop-add.svg
@@ -0,0 +1,10 @@
+
diff --git a/assets/icon/outline/star.svg b/assets/icon/outline/star.svg
new file mode 100644
index 0000000..ece9bd4
--- /dev/null
+++ b/assets/icon/outline/star.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icon/outline/ticket-discount.svg b/assets/icon/outline/ticket-discount.svg
new file mode 100644
index 0000000..5616812
--- /dev/null
+++ b/assets/icon/outline/ticket-discount.svg
@@ -0,0 +1,6 @@
+
diff --git a/lib/core/gen/assets.gen.dart b/lib/core/gen/assets.gen.dart
index 5537cbd..b0119ec 100644
--- a/lib/core/gen/assets.gen.dart
+++ b/lib/core/gen/assets.gen.dart
@@ -40,20 +40,62 @@ class $AssetsLogoGen {
class $AssetsIconOutlineGen {
const $AssetsIconOutlineGen();
+ /// File path: assets/icon/outline/arrow-right.svg
+ SvgGenImage get arrowRight => const SvgGenImage(
+ 'assets/icon/outline/arrow-right.svg',
+ size: Size(18.0, 18.0),
+ );
+
+ /// File path: assets/icon/outline/empty-wallet.svg
+ SvgGenImage get emptyWallet => const SvgGenImage(
+ 'assets/icon/outline/empty-wallet.svg',
+ size: Size(18.0, 18.0),
+ );
+
+ /// File path: assets/icon/outline/frame.svg
+ SvgGenImage get frame => const SvgGenImage(
+ 'assets/icon/outline/frame.svg',
+ size: Size(18.0, 18.0),
+ );
+
/// File path: assets/icon/outline/home.svg
SvgGenImage get home =>
const SvgGenImage('assets/icon/outline/home.svg', size: Size(24.0, 24.0));
+ /// File path: assets/icon/outline/logout.svg
+ SvgGenImage get logout => const SvgGenImage(
+ 'assets/icon/outline/logout.svg',
+ size: Size(18.0, 18.0),
+ );
+
/// File path: assets/icon/outline/map.svg
SvgGenImage get map =>
const SvgGenImage('assets/icon/outline/map.svg', size: Size(24.0, 24.0));
+ /// File path: assets/icon/outline/message-question.svg
+ SvgGenImage get messageQuestion => const SvgGenImage(
+ 'assets/icon/outline/message-question.svg',
+ size: Size(18.0, 18.0),
+ );
+
/// File path: assets/icon/outline/notification-bing.svg
SvgGenImage get notificationBing => const SvgGenImage(
'assets/icon/outline/notification-bing.svg',
size: Size(24.0, 24.0),
);
+ /// File path: assets/icon/outline/notification.svg
+ SvgGenImage get notification => const SvgGenImage(
+ 'assets/icon/outline/notification.svg',
+ size: Size(18.0, 18.0),
+ );
+
+ /// File path: assets/icon/outline/profile.svg
+ SvgGenImage get profile => const SvgGenImage(
+ 'assets/icon/outline/profile.svg',
+ size: Size(18.0, 18.0),
+ );
+
/// File path: assets/icon/outline/search.svg
SvgGenImage get search => const SvgGenImage(
'assets/icon/outline/search.svg',
@@ -66,17 +108,50 @@ class $AssetsIconOutlineGen {
size: Size(24.0, 24.0),
);
+ /// File path: assets/icon/outline/shield.svg
+ SvgGenImage get shield => const SvgGenImage(
+ 'assets/icon/outline/shield.svg',
+ size: Size(18.0, 18.0),
+ );
+
+ /// File path: assets/icon/outline/shop-add.svg
+ SvgGenImage get shopAdd => const SvgGenImage(
+ 'assets/icon/outline/shop-add.svg',
+ size: Size(18.0, 18.0),
+ );
+
+ /// File path: assets/icon/outline/star.svg
+ SvgGenImage get star =>
+ const SvgGenImage('assets/icon/outline/star.svg', size: Size(18.0, 18.0));
+
+ /// File path: assets/icon/outline/ticket-discount.svg
+ SvgGenImage get ticketDiscount => const SvgGenImage(
+ 'assets/icon/outline/ticket-discount.svg',
+ size: Size(18.0, 18.0),
+ );
+
/// File path: assets/icon/outline/user.svg
SvgGenImage get user =>
const SvgGenImage('assets/icon/outline/user.svg', size: Size(24.0, 24.0));
/// List of all assets
List get values => [
+ arrowRight,
+ emptyWallet,
+ frame,
home,
+ logout,
map,
+ messageQuestion,
notificationBing,
+ notification,
+ profile,
search,
setting,
+ shield,
+ shopAdd,
+ star,
+ ticketDiscount,
user,
];
}
diff --git a/lib/core/routes/app_router.dart b/lib/core/routes/app_router.dart
index 77c4ef6..429095f 100644
--- a/lib/core/routes/app_router.dart
+++ b/lib/core/routes/app_router.dart
@@ -5,20 +5,24 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:proxibuy/presentation/providers/category/cubit/categories_children_cubit.dart';
import 'package:proxibuy/presentation/providers/category/cubit/categories_cubit.dart';
-import 'package:proxibuy/presentation/providers/user_info_cubit.dart';
import 'package:proxibuy/presentation/ui/screens/auth/auth_page.dart';
+import 'package:proxibuy/presentation/ui/screens/setting/edit_profile_page.dart';
import 'package:proxibuy/presentation/ui/screens/home/screens/categories_screen.dart';
import 'package:proxibuy/presentation/ui/screens/home/screens/explore_screen.dart';
import 'package:proxibuy/presentation/ui/screens/home/home_page.dart';
import 'package:proxibuy/presentation/ui/screens/home/screens/home_screen.dart';
import 'package:proxibuy/presentation/ui/screens/home/screens/setting_screen.dart';
import 'package:proxibuy/presentation/ui/screens/product/product_page.dart';
+import 'package:proxibuy/presentation/ui/screens/setting/notifications_etting_page.dart';
import 'package:proxibuy/presentation/ui/theme/responsive.dart';
class AppRouter {
static final initial = '/';
+ static final auth = '/auth';
static final explore = '/explore';
static final setting = '/settings';
+ static final editProfile = 'edit-profile';
+ static final notificationsSetting = 'notification';
static final product = '/product';
static final categories = '/categories';
@@ -30,51 +34,21 @@ class AppRouter {
static GoRouter createRouter = GoRouter(
navigatorKey: navigatorKey,
initialLocation: initial,
+ redirect: (context, state) {
+ return null;
+ },
routes: [
- // GoRoute(
- // path: initial,
- // builder: (BuildContext context, GoRouterState state) {
- // return BlocConsumer(
- // listener: (context, state) {
- // if (state is UserInfoSuccess || state is UserInfoFail) {
- // FlutterNativeSplash.remove();
- // }
- // },
- // builder: (context, state) {
- // if (state is UserInfoSuccess) {
- // return const HomePage();
- // } else {
- // return const AuthPage();
- // }
- // },
- // );
- // },
- // routes: [
- // GoRoute(
- // path: product,
- // builder: (BuildContext context, GoRouterState state) {
- // return ProductPage();
- // },
- // routes: [],
- // ),
- // ],
- // ),
-
+ GoRoute(
+ path: auth,
+ builder: (context, state) {
+ return AuthPage();
+ },
+ ),
StatefulShellRoute.indexedStack(
builder: (context, state, navigationShell) =>
- BlocBuilder(
- builder: (context, userState) {
- if (userState is UserInfoSuccess) {
- if (home.contains(state.fullPath)) {
- return HomePage(child: navigationShell);
- } else {
- return navigationShell;
- }
- } else {
- return AuthPage();
- }
- },
- ),
+ home.contains(state.fullPath)
+ ? HomePage(child: navigationShell)
+ : navigationShell,
branches: [
StatefulShellBranch(routes: [
GoRoute(
@@ -140,9 +114,24 @@ class AppRouter {
]),
StatefulShellBranch(routes: [
GoRoute(
- path: setting,
- builder: (context, state) => SettingScreen(),
- ),
+ path: setting,
+ builder: (context, state) => SettingScreen(),
+ routes: [
+ GoRoute(
+ path: editProfile,
+ name: editProfile,
+ builder: (context, state) {
+ return EditProfilePage();
+ },
+ ),
+ GoRoute(
+ path: notificationsSetting,
+ name: notificationsSetting,
+ builder: (context, state) {
+ return NotificationsEttingPage();
+ },
+ ),
+ ]),
]),
],
),
diff --git a/lib/data/models/setting_btns_model.dart b/lib/data/models/setting_btns_model.dart
new file mode 100644
index 0000000..de9f8e0
--- /dev/null
+++ b/lib/data/models/setting_btns_model.dart
@@ -0,0 +1,10 @@
+import 'package:flutter/cupertino.dart';
+import 'package:proxibuy/core/gen/assets.gen.dart';
+
+class SettingBtnsModel {
+ final String title;
+ final SvgGenImage icon;
+ final Function(BuildContext context)? onPressed;
+
+ SettingBtnsModel({required this.title, required this.icon, this.onPressed});
+}
diff --git a/lib/main.dart b/lib/main.dart
index 9b71de0..4fa3aba 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -22,10 +22,8 @@ void main() async {
BlocProvider(create: (context) => ThemModeCubit()),
BlocProvider(
create: (context) => CategoriesChildrenCubit()),
- BlocProvider(
- create: (context) => CategoriesCubit()..getAllCategories()),
- BlocProvider(
- create: (context) => UserInfoCubit()..getUserInfo()),
+ BlocProvider(create: (context) => CategoriesCubit()),
+ BlocProvider(create: (context) => UserInfoCubit()),
],
child: const MyApp(),
));
diff --git a/lib/presentation/ui/screens/auth/auth_page.dart b/lib/presentation/ui/screens/auth/auth_page.dart
index 1f3ecfb..0f4c405 100644
--- a/lib/presentation/ui/screens/auth/auth_page.dart
+++ b/lib/presentation/ui/screens/auth/auth_page.dart
@@ -26,7 +26,10 @@ class _AuthPageState extends State {
appBar: AppBar(
title: Text(
'Auth',
- style: Theme.of(context).textTheme.titleLarge,
+ style: Theme.of(context)
+ .textTheme
+ .titleLarge
+ ?.copyWith(color: Theme.of(context).colorScheme.onSurface),
),
backgroundColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
diff --git a/lib/presentation/ui/screens/home/home_desk_page.dart b/lib/presentation/ui/screens/home/home_desk_page.dart
index 4ad3756..29f075b 100644
--- a/lib/presentation/ui/screens/home/home_desk_page.dart
+++ b/lib/presentation/ui/screens/home/home_desk_page.dart
@@ -18,7 +18,6 @@ class HomeDeskPage extends StatefulWidget {
}
class _HomeDeskPageState extends State {
- int selectedIndex = 0;
List deskScreens = [
ScreenModel(
title: 'Home',
@@ -34,10 +33,14 @@ class _HomeDeskPageState extends State {
route: AppRouter.setting),
];
+ int _getSelectedIndex(BuildContext context) {
+ final g = GoRouterState.of(context);
+ final String location = g.fullPath.toString();
+ return deskScreens
+ .indexWhere((element) => element.route.startsWith(location));
+ }
+
void _onItemTapped(BuildContext context, int index) {
- setState(() {
- selectedIndex = index;
- });
switch (index) {
case 0:
context.go(AppRouter.initial);
@@ -64,10 +67,6 @@ class _HomeDeskPageState extends State {
}
Padding navBar(BuildContext context) {
- final defaultBorder = OutlineInputBorder(
- borderRadius: BorderRadius.circular(8),
- borderSide:
- BorderSide(color: Theme.of(context).colorScheme.surface, width: 2));
return Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
@@ -89,7 +88,7 @@ class _HomeDeskPageState extends State {
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
- color: selectedIndex == index
+ color: _getSelectedIndex(context) == index
? themeColor(context)
?.primaryLightSurface
.withAlpha(90)
@@ -103,7 +102,7 @@ class _HomeDeskPageState extends State {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
deskScreens[index].icon.svg(
- color: selectedIndex == index
+ color: _getSelectedIndex(context) == index
? Theme.of(context).primaryColor
: Theme.of(context)
.colorScheme
@@ -115,7 +114,8 @@ class _HomeDeskPageState extends State {
.textTheme
.labelLarge
?.copyWith(
- color: selectedIndex == index
+ color: _getSelectedIndex(context) ==
+ index
? Theme.of(context).primaryColor
: Theme.of(context)
.colorScheme
@@ -142,18 +142,16 @@ class _HomeDeskPageState extends State {
child: Container(
constraints: BoxConstraints(maxWidth: 800),
child: TextField(
- decoration: InputDecoration(
- hintText: 'what are you looking for?',
- suffixIcon: Padding(
- padding: const EdgeInsets.all(8.0),
- child: Assets.icon.outline.search.svg(
- color: Theme.of(context).colorScheme.onSurface,
- width: 16,
- height: 16),
- ),
- enabledBorder: defaultBorder,
- border: defaultBorder),
- ),
+ decoration: defaultInputDecoration(context).copyWith(
+ hintText: 'what are you looking for?',
+ suffixIcon: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Assets.icon.outline.search.svg(
+ color: Theme.of(context).colorScheme.onSurface,
+ width: 16,
+ height: 16),
+ ),
+ )),
)),
32.w,
IconButton(
diff --git a/lib/presentation/ui/screens/home/home_page.dart b/lib/presentation/ui/screens/home/home_page.dart
index 4b5d2e7..492a400 100644
--- a/lib/presentation/ui/screens/home/home_page.dart
+++ b/lib/presentation/ui/screens/home/home_page.dart
@@ -44,7 +44,7 @@ class _HomePageState extends State {
int _getSelectedIndex(BuildContext context) {
final g = GoRouterState.of(context);
final String location = g.fullPath.toString();
- return screens.indexWhere((element) => element.route == location);
+ return screens.indexWhere((element) => element.route.startsWith(location));
}
@override
diff --git a/lib/presentation/ui/screens/home/screens/home_screen.dart b/lib/presentation/ui/screens/home/screens/home_screen.dart
index 50434e8..32d15e6 100644
--- a/lib/presentation/ui/screens/home/screens/home_screen.dart
+++ b/lib/presentation/ui/screens/home/screens/home_screen.dart
@@ -163,7 +163,10 @@ class _HomeScreenState extends State {
padding: const EdgeInsets.only(left: 2.0),
child: SelectableText(
"Proxibuy",
- style: Theme.of(context).textTheme.headlineSmall,
+ style: Theme.of(context)
+ .textTheme
+ .headlineSmall
+ ?.copyWith(color: Theme.of(context).colorScheme.onSurface),
),
),
actions: [
diff --git a/lib/presentation/ui/screens/home/screens/setting_screen.dart b/lib/presentation/ui/screens/home/screens/setting_screen.dart
index 998fbaf..2eda973 100644
--- a/lib/presentation/ui/screens/home/screens/setting_screen.dart
+++ b/lib/presentation/ui/screens/home/screens/setting_screen.dart
@@ -1,13 +1,178 @@
import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+import 'package:proxibuy/core/gen/assets.gen.dart';
+import 'package:proxibuy/core/routes/app_router.dart';
+import 'package:proxibuy/data/models/setting_btns_model.dart';
+import 'package:proxibuy/presentation/ui/theme/responsive.dart';
-class SettingScreen extends StatelessWidget {
+class SettingScreen extends StatefulWidget {
const SettingScreen({super.key});
+ @override
+ State createState() => _SettingScreenState();
+}
+
+class _SettingScreenState extends State {
+ final List _generalBtns = [
+ SettingBtnsModel(
+ title: 'Edit Profile',
+ icon: Assets.icon.outline.profile,
+ onPressed: (context) {
+ context.goNamed(AppRouter.editProfile);
+ },
+ ),
+ SettingBtnsModel(
+ title: 'Notifications',
+ icon: Assets.icon.outline.notification,
+ onPressed: (context) {
+ context.goNamed(AppRouter.notificationsSetting);
+ },
+ ),
+ SettingBtnsModel(title: 'Security', icon: Assets.icon.outline.frame),
+ SettingBtnsModel(
+ title: 'Transactions & Wallets', icon: Assets.icon.outline.emptyWallet),
+ SettingBtnsModel(
+ title: 'Discounts & Prizes', icon: Assets.icon.outline.ticketDiscount),
+ SettingBtnsModel(title: 'Favorite Stores', icon: Assets.icon.outline.star),
+ SettingBtnsModel(
+ title: 'Store Introduction', icon: Assets.icon.outline.shopAdd),
+ ];
+
+ final List _preferencesBtns = [
+ SettingBtnsModel(
+ title: 'Legal & Policies', icon: Assets.icon.outline.shield),
+ SettingBtnsModel(
+ title: 'Help & Support', icon: Assets.icon.outline.messageQuestion),
+ SettingBtnsModel(title: 'Logout', icon: Assets.icon.outline.logout),
+ ];
@override
Widget build(BuildContext context) {
- return Scaffold(
- body: Center(
- child: Text('Setting'),
+ return Responsive(context).builder(
+ mobile: Scaffold(
+ appBar: AppBar(
+ title: Text(
+ 'Setting',
+ style: Theme.of(context)
+ .textTheme
+ .titleLarge
+ ?.copyWith(color: Theme.of(context).colorScheme.onSurface),
+ ),
+ ),
+ body: SingleChildScrollView(
+ child: Column(
+ children: [
+ ListTile(
+ title: SelectableText(
+ 'General',
+ style: Theme.of(context).textTheme.titleMedium,
+ ),
+ ),
+ ListView.builder(
+ itemCount: _generalBtns.length,
+ physics: BouncingScrollPhysics(),
+ shrinkWrap: true,
+ itemBuilder: (context, index) {
+ return settingItem(context, item: _generalBtns[index]);
+ },
+ ),
+ ListTile(
+ title: SelectableText(
+ 'Preferences',
+ style: Theme.of(context).textTheme.titleMedium,
+ ),
+ ),
+ ListView.builder(
+ itemCount: _preferencesBtns.length,
+ physics: BouncingScrollPhysics(),
+ shrinkWrap: true,
+ itemBuilder: (context, index) {
+ return settingItem(context, item: _preferencesBtns[index]);
+ },
+ )
+ ],
+ ),
+ ),
+ ),
+ desktop: Responsive(context).maxWidthInDesktop(
+ maxWidth: 1200,
+ child: (contxet, mw) => Scaffold(
+ body: SingleChildScrollView(
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Expanded(
+ child: Column(
+ children: [
+ ListTile(
+ title: SelectableText(
+ 'General',
+ style: Theme.of(context).textTheme.titleMedium,
+ ),
+ ),
+ ListView.builder(
+ itemCount: _generalBtns.length,
+ physics: BouncingScrollPhysics(),
+ shrinkWrap: true,
+ itemBuilder: (context, index) {
+ return settingItem(context,
+ item: _generalBtns[index]);
+ },
+ ),
+ ],
+ ),
+ ),
+ Expanded(
+ child: Column(
+ children: [
+ ListTile(
+ title: SelectableText(
+ 'Preferences',
+ style: Theme.of(context).textTheme.titleMedium,
+ ),
+ ),
+ ListView.builder(
+ itemCount: _preferencesBtns.length,
+ physics: BouncingScrollPhysics(),
+ shrinkWrap: true,
+ itemBuilder: (context, index) {
+ return settingItem(context,
+ item: _preferencesBtns[index]);
+ },
+ )
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ Container settingItem(BuildContext context,
+ {required final SettingBtnsModel item}) {
+ return Container(
+ margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16),
+ padding: EdgeInsets.symmetric(vertical: 8),
+ decoration: BoxDecoration(
+ boxShadow: [
+ BoxShadow(
+ color: Colors.black.withOpacity(0.15),
+ spreadRadius: 2,
+ blurRadius: 12,
+ offset: Offset(0, 4),
+ ),
+ ],
+ borderRadius: BorderRadius.circular(8),
+ color: Theme.of(context).colorScheme.surface,
+ ),
+ child: ListTile(
+ onTap: () => item.onPressed?.call(context),
+ leading: item.icon.svg(color: Theme.of(context).colorScheme.onSurface),
+ trailing: Assets.icon.outline.arrowRight
+ .svg(color: Theme.of(context).colorScheme.onSurface),
+ title: Text(item.title),
),
);
}
diff --git a/lib/presentation/ui/screens/setting/edit_profile_page.dart b/lib/presentation/ui/screens/setting/edit_profile_page.dart
new file mode 100644
index 0000000..dea8c7b
--- /dev/null
+++ b/lib/presentation/ui/screens/setting/edit_profile_page.dart
@@ -0,0 +1,188 @@
+import 'package:flutter/material.dart';
+import 'package:proxibuy/core/gen/assets.gen.dart';
+import 'package:proxibuy/core/utils/empty_space.dart';
+import 'package:proxibuy/presentation/ui/theme/responsive.dart';
+import 'package:proxibuy/presentation/ui/theme/theme.dart';
+import 'package:proxibuy/presentation/ui/widgets/dialog/dialog_manager.dart';
+
+class EditProfilePage extends StatelessWidget {
+ const EditProfilePage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text(
+ 'Edit Profile',
+ style: Theme.of(context)
+ .textTheme
+ .titleLarge
+ ?.copyWith(color: Theme.of(context).colorScheme.onSurface),
+ ),
+ ),
+ body: Responsive(context).builder(
+ mobile: Form(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0).copyWith(bottom: 32),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Column(
+ children: [
+ Center(
+ child: SizedBox(
+ width: 64, height: 64, child: CircleAvatar())),
+ 16.h,
+ Text(
+ 'Username',
+ style: Theme.of(context).textTheme.titleMedium,
+ ),
+ 32.h,
+ TextFormField(
+ decoration: defaultInputDecoration(context).copyWith(
+ labelText: 'First Name',
+ )),
+ 16.h,
+ TextFormField(
+ decoration: defaultInputDecoration(context).copyWith(
+ labelText: 'Last Name',
+ )),
+ 16.h,
+ TextFormField(
+ decoration: defaultInputDecoration(context).copyWith(
+ labelText: 'Phone',
+ )),
+ 16.h,
+ TextFormField(
+ decoration: defaultInputDecoration(context).copyWith(
+ labelText: 'Email',
+ )),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Login with Password',
+ style: Theme.of(context).textTheme.titleLarge,
+ ),
+ subtitle: Text('Change Password'),
+ value: false,
+ onChanged: (value) {
+ DialogManager(context).changePasswordBS();
+ },
+ ),
+ ],
+ ),
+ SizedBox(
+ width: double.infinity,
+ height: 46,
+ child: ElevatedButton(
+ onPressed: () {},
+ child: Text(
+ 'Confirm Changes',
+ style: Theme.of(context)
+ .textTheme
+ .labelLarge
+ ?.copyWith(color: Colors.white),
+ )),
+ )
+ ],
+ ),
+ ),
+ ),
+ desktop: Responsive(context).maxWidthInDesktop(
+ maxWidth: 800,
+ child: (context, mw) {
+ return Form(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0).copyWith(bottom: 32),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Column(
+ children: [
+ Center(
+ child: SizedBox(
+ width: 128,
+ height: 128,
+ child: CircleAvatar())),
+ 16.h,
+ Text(
+ 'Username',
+ style: Theme.of(context).textTheme.titleLarge,
+ ),
+ 32.h,
+ Row(
+ children: [
+ Expanded(
+ child: TextFormField(
+ decoration:
+ defaultInputDecoration(context)
+ .copyWith(
+ labelText: 'First Name',
+ )),
+ ),
+ 16.w,
+ Expanded(
+ child: TextFormField(
+ decoration:
+ defaultInputDecoration(context)
+ .copyWith(
+ labelText: 'Last Name',
+ )),
+ ),
+ ],
+ ),
+ 16.h,
+ Row(
+ children: [
+ Expanded(
+ child: TextFormField(
+ decoration:
+ defaultInputDecoration(context)
+ .copyWith(
+ labelText: 'Phone',
+ )),
+ ),
+ 16.w,
+ Expanded(
+ child: TextFormField(
+ decoration:
+ defaultInputDecoration(context)
+ .copyWith(
+ labelText: 'Email',
+ )),
+ ),
+ ],
+ ),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Login with Password Only',
+ style: Theme.of(context).textTheme.titleLarge,
+ ),
+ subtitle: Text('Change Password'),
+ value: false,
+ onChanged: (value) {},
+ ),
+ ],
+ ),
+ SizedBox(
+ width: double.infinity,
+ height: 46,
+ child: ElevatedButton(
+ onPressed: () {},
+ child: Text(
+ 'Confirm Changes',
+ style: Theme.of(context)
+ .textTheme
+ .labelLarge
+ ?.copyWith(color: Colors.white),
+ )),
+ )
+ ],
+ ),
+ ),
+ );
+ })),
+ );
+ }
+}
diff --git a/lib/presentation/ui/screens/setting/notifications_etting_page.dart b/lib/presentation/ui/screens/setting/notifications_etting_page.dart
new file mode 100644
index 0000000..7e59a01
--- /dev/null
+++ b/lib/presentation/ui/screens/setting/notifications_etting_page.dart
@@ -0,0 +1,194 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:proxibuy/core/utils/empty_space.dart';
+import 'package:proxibuy/presentation/ui/theme/responsive.dart';
+
+class NotificationsEttingPage extends StatefulWidget {
+ const NotificationsEttingPage({super.key});
+
+ @override
+ State createState() =>
+ _NotificationsEttingPageState();
+}
+
+class _NotificationsEttingPageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text(
+ 'Notifications',
+ style: Theme.of(context)
+ .textTheme
+ .titleLarge
+ ?.copyWith(color: Theme.of(context).colorScheme.onSurface),
+ ),
+ ),
+ body: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Responsive(context).builder(
+ desktop: Responsive(context).maxWidthInDesktop(
+ maxWidth: 1000,
+ child: (context, mw) {
+ return Row(
+ children: [
+ Expanded(
+ child: Column(
+ children: [
+ ListTile(
+ title: Text(
+ 'Notification Categories',
+ style: Theme.of(context).textTheme.titleLarge,
+ ),
+ ),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Special Offers',
+ ),
+ value: true,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Order Status',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Account Notifications',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Product Updates',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ ],
+ )),
+ 16.w,
+ Expanded(
+ child: Column(
+ children: [
+ ListTile(
+ title: Text(
+ 'Notification Frequency Control',
+ style: Theme.of(context).textTheme.titleLarge,
+ ),
+ ),
+ 16.h,
+ CheckboxListTile.adaptive(
+ title: Text(
+ 'Daily',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ CheckboxListTile.adaptive(
+ title: Text(
+ 'Weekly',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ CheckboxListTile.adaptive(
+ title: Text(
+ 'monthly',
+ ),
+ value: true,
+ onChanged: (value) {},
+ ),
+ ],
+ ))
+ ],
+ );
+ }),
+ mobile: Column(
+ children: [
+ ListTile(
+ title: Text(
+ 'Notification Categories',
+ style: Theme.of(context).textTheme.titleLarge,
+ ),
+ ),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Special Offers',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Order Status',
+ ),
+ value: true,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Account Notifications',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ SwitchListTile.adaptive(
+ title: Text(
+ 'Product Updates',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ ListTile(
+ title: Text(
+ 'Notification Frequency Control',
+ style: Theme.of(context).textTheme.titleLarge,
+ ),
+ ),
+ 16.h,
+ CheckboxListTile.adaptive(
+ title: Text(
+ 'Daily',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ CheckboxListTile.adaptive(
+ title: Text(
+ 'Weekly',
+ ),
+ value: false,
+ onChanged: (value) {},
+ ),
+ 16.h,
+ CheckboxListTile.adaptive(
+ title: Text(
+ 'monthly',
+ ),
+ value: true,
+ onChanged: (value) {},
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/ui/theme/theme.dart b/lib/presentation/ui/theme/theme.dart
index 8338785..179207b 100644
--- a/lib/presentation/ui/theme/theme.dart
+++ b/lib/presentation/ui/theme/theme.dart
@@ -21,11 +21,29 @@ final ThemeData appTheme = ThemeData(
appBarTheme: const AppBarTheme(
surfaceTintColor: lightBackground,
backgroundColor: lightBackground,
+ toolbarTextStyle: TextStyle(color: fontDark),
+ centerTitle: true,
elevation: 2,
titleTextStyle: TextStyle(
color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
+ switchTheme: SwitchThemeData(
+ thumbColor: MaterialStateProperty.resolveWith(
+ (Set states) {
+ return Colors.white; // Thumb color when switch is off
+ },
+ ),
+ trackColor: MaterialStateProperty.resolveWith(
+ (Set states) {
+ if (states.contains(MaterialState.selected)) {
+ return primarySwatch; // Thumb color when switch is on
+ }
+ return Colors.grey[300]!; // Thumb color when switch is off
+ },
+ ),
+ ),
+
// Text Theme
textTheme: const TextTheme(
displayLarge:
@@ -102,6 +120,8 @@ final ThemeData darkTheme = ThemeData(
appBarTheme: const AppBarTheme(
backgroundColor: darkBackground,
surfaceTintColor: darkBackground,
+ centerTitle: true,
+ toolbarTextStyle: TextStyle(color: fontLight),
elevation: 2,
titleTextStyle: TextStyle(
color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
@@ -168,3 +188,21 @@ final ThemeData darkTheme = ThemeData(
CustomColors? themeColor(BuildContext context) {
return Theme.of(context).extension();
}
+
+OutlineInputBorder defaultBorder(BuildContext context) => OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8),
+ borderSide:
+ BorderSide(color: Theme.of(context).colorScheme.onSurface, width: 2));
+OutlineInputBorder defaultFocusedBorder(
+ BuildContext context) =>
+ OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8),
+ borderSide: BorderSide(
+ color: themeColor(context)!.primarySwatch.shade400, width: 2));
+
+InputDecoration defaultInputDecoration(BuildContext context) => InputDecoration(
+ floatingLabelStyle:
+ TextStyle(color: themeColor(context)!.primarySwatch.shade400),
+ enabledBorder: defaultBorder(context),
+ border: defaultBorder(context),
+ focusedBorder: defaultFocusedBorder(context));
diff --git a/lib/presentation/ui/widgets/dialog/dialog_manager.dart b/lib/presentation/ui/widgets/dialog/dialog_manager.dart
index c498efe..5b0a633 100644
--- a/lib/presentation/ui/widgets/dialog/dialog_manager.dart
+++ b/lib/presentation/ui/widgets/dialog/dialog_manager.dart
@@ -1,10 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
+import 'package:go_router/go_router.dart';
+import 'package:proxibuy/core/utils/empty_space.dart';
+import 'package:proxibuy/presentation/ui/theme/theme.dart';
class DialogManager {
final BuildContext context;
- DialogManager({required this.context});
+ DialogManager(this.context);
// Future _showDialog(Widget widget) async {
// await showDialog(
@@ -16,4 +19,74 @@ class DialogManager {
// },
// );
// }
+ Future _showBottomSheet(Widget widget) async {
+ await showModalBottomSheet(
+ context: context,
+ backgroundColor: Theme.of(context).scaffoldBackgroundColor,
+ builder: (context) {
+ return Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: widget,
+ );
+ },
+ );
+ }
+
+ void changePasswordBS() async {
+ await _showBottomSheet(Form(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Column(
+ children: [
+ ListTile(
+ title: Text(
+ 'Login with Password',
+ style: Theme.of(context).textTheme.titleLarge,
+ ),
+ subtitle: Text('"To confirm, please enter a password."'),
+ ),
+ 32.h,
+ TextFormField(
+ decoration: defaultInputDecoration(context).copyWith(
+ labelText: 'Password',
+ )),
+ 16.h,
+ TextFormField(
+ decoration: defaultInputDecoration(context).copyWith(
+ labelText: 're-Password',
+ )),
+ 32.h,
+ TextButton(onPressed: () {}, child: Text('Forgot Your Password?'))
+ ],
+ ),
+ Row(
+ children: [
+ Expanded(
+ child: SizedBox(
+ height: 46,
+ child: ElevatedButton(onPressed: () {}, child: Text('Confirm')),
+ )),
+ 12.w,
+ Expanded(
+ child: SizedBox(
+ height: 46,
+ child: OutlinedButton(
+ style: OutlinedButton.styleFrom(
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(8),
+ ),
+ side: BorderSide(
+ color: Theme.of(context).primaryColor,
+ ),
+ ),
+ onPressed: () {},
+ child: Text('Cancel')),
+ ))
+ ],
+ )
+ ],
+ ),
+ ));
+ }
}