Completed language selection bottomSheet in profile with bloc state management
This commit is contained in:
BIN
assets/icons/radio_button_checked.png
Normal file
BIN
assets/icons/radio_button_checked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
assets/icons/radio_button_unchecked.png
Normal file
BIN
assets/icons/radio_button_unchecked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/icons/search.png
Normal file
BIN
assets/icons/search.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
22
lib/common_bloc/language_selection_bloc.dart
Normal file
22
lib/common_bloc/language_selection_bloc.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
abstract class LanguageEvent{}
|
||||
|
||||
class UpdateLanguage extends LanguageEvent{
|
||||
final String language;
|
||||
UpdateLanguage(this.language);
|
||||
}
|
||||
|
||||
|
||||
class LanguageState{
|
||||
final String selectedLanguage;
|
||||
LanguageState(this.selectedLanguage);
|
||||
}
|
||||
|
||||
class LanguageBloc extends Bloc<LanguageEvent , LanguageState>{
|
||||
LanguageBloc() : super(LanguageState("English / Englis")){
|
||||
on<UpdateLanguage>((event, emit){
|
||||
emit(LanguageState(event.language));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../common_bloc/bottom_navigation_bloc.dart';
|
||||
|
||||
|
||||
class CustomBottomNavBar extends StatelessWidget {
|
||||
const CustomBottomNavBar({super.key});
|
||||
|
||||
@@ -74,7 +72,6 @@ class CustomBottomNavBar extends StatelessWidget {
|
||||
required bool isActive,
|
||||
}) {
|
||||
final color = isActive ? const Color(0xFFBB474A) : Color(0xFFBB474A).withOpacity(0.6);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () =>
|
||||
context.read<NavigationBloc>().add(NavigationTabChanged(index)),
|
||||
@@ -93,7 +90,6 @@ class CustomBottomNavBar extends StatelessWidget {
|
||||
)
|
||||
else
|
||||
const SizedBox(height: 7),
|
||||
|
||||
Image.asset(iconPath, scale: 4, color: color),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
|
||||
113
lib/common_packages/language_selection_bottomsheet.dart
Normal file
113
lib/common_packages/language_selection_bottomsheet.dart
Normal file
@@ -0,0 +1,113 @@
|
||||
import 'package:citycards_customer/common_bloc/language_selection_bloc.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class LanguageSelectionBottomsheet extends StatelessWidget {
|
||||
LanguageSelectionBottomsheet({super.key});
|
||||
|
||||
List<String> languages = [
|
||||
"English / Englis",
|
||||
"Dutch / Nederlands",
|
||||
"Spanish / Español",
|
||||
"French / Français",
|
||||
"Japanese / 日本語",
|
||||
];
|
||||
|
||||
TextEditingController searchController = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
width: 40,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF2D3134),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: const Text(
|
||||
"Change Language",
|
||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 22),
|
||||
TextField(
|
||||
controller: searchController,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Languages",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xBBC83B61).withOpacity(0.4),
|
||||
),
|
||||
suffixIcon: Image.asset("assets/icons/search.png", scale: 4),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xBBC83B61).withOpacity(0.4),
|
||||
width: .4,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: const BorderSide(
|
||||
color: Color(0xFFF95F62),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
BlocBuilder<LanguageBloc, LanguageState>(
|
||||
builder: (context, state) {
|
||||
return Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: languages.length,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
final item = languages[index];
|
||||
return ListTile(
|
||||
dense: true,
|
||||
leading: GestureDetector(
|
||||
onTap: () {
|
||||
context.read<LanguageBloc>().add(
|
||||
UpdateLanguage(item),
|
||||
);
|
||||
},
|
||||
child: state.selectedLanguage == item
|
||||
? Image.asset(
|
||||
"assets/icons/radio_button_checked.png",
|
||||
scale: 4,
|
||||
)
|
||||
: Image.asset(
|
||||
"assets/icons/radio_button_unchecked.png",
|
||||
scale: 4,
|
||||
),
|
||||
),
|
||||
title: CustomText(
|
||||
text: item,
|
||||
size: 16,
|
||||
color: state.selectedLanguage == item ? Color(0xFFF95F62) : Color(0xFF000000).withOpacity(.6),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:citycards_customer/common_packages/app_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_textfield.dart';
|
||||
@@ -22,20 +23,13 @@ class ContactUsPage extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Header bar
|
||||
Container(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(color: Color(0xFFD9D9D9), width: 0.7),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Image.asset("assets/logo/logo_city_cards.png", scale: 4),
|
||||
Image.asset("assets/icons/shopping_cart.png", scale: 4),
|
||||
],
|
||||
),
|
||||
CommonAppBar(isWhiteLogo: false, isProfilePage: true),
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Color(0xFFD9D9D9),
|
||||
),
|
||||
const SizedBox(height: 22),
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:citycards_customer/Profile/profile_page_view.dart';
|
||||
import 'package:citycards_customer/common_bloc/language_selection_bloc.dart';
|
||||
import 'package:citycards_customer/contact_us/contact_us_view.dart';
|
||||
import 'package:citycards_customer/edit_profile/edit_profile_view.dart';
|
||||
import 'package:citycards_customer/faq/faq_view.dart';
|
||||
@@ -10,7 +11,6 @@ import '../common_bloc/bottom_navigation_bloc.dart';
|
||||
import '../home/views/home_page_view.dart';
|
||||
import 'route_constants.dart';
|
||||
|
||||
|
||||
class AppRouter {
|
||||
Route onGenerateRoute(RouteSettings settings) {
|
||||
switch (settings.name) {
|
||||
@@ -18,14 +18,20 @@ class AppRouter {
|
||||
case RouteConstants.home:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return BlocProvider(create: (_) => NavigationBloc(), child: const HomePage());
|
||||
return BlocProvider(
|
||||
create: (_) => NavigationBloc(),
|
||||
child: const HomePage(),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
case RouteConstants.profile:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return const ProfilePage();
|
||||
return BlocProvider(
|
||||
create: (_) => LanguageBloc(),
|
||||
child: const ProfilePage(),
|
||||
);
|
||||
},
|
||||
);
|
||||
case RouteConstants.editProfile:
|
||||
|
||||
@@ -24,6 +24,13 @@ class EditProfilePage extends StatelessWidget {
|
||||
children: [
|
||||
// Header
|
||||
CommonAppBar(isWhiteLogo: false, isProfilePage: true),
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Color(0xFFD9D9D9),
|
||||
),
|
||||
const SizedBox(height: 22),
|
||||
|
||||
// Back + title
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:citycards_customer/common_packages/app_bar.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_expansion_tile.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -16,20 +17,13 @@ class FaqPage extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(color: Color(0xFFD9D9D9), width: 0.7),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Image.asset("assets/logo/logo_city_cards.png", scale: 4),
|
||||
Image.asset("assets/icons/shopping_cart.png", scale: 4),
|
||||
],
|
||||
),
|
||||
CommonAppBar(isWhiteLogo: false, isProfilePage: true),
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Color(0xFFD9D9D9),
|
||||
),
|
||||
const SizedBox(height: 22),
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'core/app_router.dart';
|
||||
import 'core/route_constants.dart';
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:citycards_customer/common_packages/app_bar.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@@ -13,20 +14,13 @@ class PrivacyPolicyPage extends StatelessWidget {
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(color: Color(0xFFD9D9D9), width: 0.7),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Image.asset("assets/logo/logo_city_cards.png", scale: 4),
|
||||
Image.asset("assets/icons/shopping_cart.png", scale: 4),
|
||||
],
|
||||
),
|
||||
CommonAppBar(isWhiteLogo: false, isProfilePage: true),
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Color(0xFFD9D9D9),
|
||||
),
|
||||
const SizedBox(height: 22),
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import 'package:citycards_customer/common_bloc/language_selection_bloc.dart';
|
||||
import 'package:citycards_customer/common_packages/app_bar.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:citycards_customer/common_packages/language_selection_bottomsheet.dart';
|
||||
import 'package:citycards_customer/core/route_constants.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class ProfilePage extends StatelessWidget {
|
||||
const ProfilePage({super.key});
|
||||
@@ -17,14 +20,17 @@ class ProfilePage extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
CommonAppBar(isWhiteLogo: false, isProfilePage: true),
|
||||
SizedBox(height: 12),
|
||||
Divider(height: 1, color: Color(0xFFD9D9D9)),
|
||||
SizedBox(height: 22),
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: (){
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Icon(Icons.arrow_back, size: 24)),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Icon(Icons.arrow_back, size: 24),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Text("My profile", style: TextStyle(fontSize: 12)),
|
||||
],
|
||||
@@ -96,9 +102,20 @@ class ProfilePage extends StatelessWidget {
|
||||
_buildListTile(
|
||||
icon: "assets/icons/change_language.png",
|
||||
title: 'Change language',
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
builder: (context) => BlocProvider(
|
||||
create: (_)=> LanguageBloc(),
|
||||
child: LanguageSelectionBottomsheet()),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Support & Legal Section
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:citycards_customer/common_packages/app_bar.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@@ -13,20 +14,13 @@ class TermsAndCondition extends StatelessWidget {
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(color: Color(0xFFD9D9D9), width: 0.7),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Image.asset("assets/logo/logo_city_cards.png", scale: 4),
|
||||
Image.asset("assets/icons/shopping_cart.png", scale: 4),
|
||||
],
|
||||
),
|
||||
CommonAppBar(isWhiteLogo: false, isProfilePage: true),
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Color(0xFFD9D9D9),
|
||||
),
|
||||
const SizedBox(height: 22),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user