all bookmark categorized and arabic validation bug
This commit is contained in:
parent
cfe5b5bf20
commit
30db38c60b
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"all_bookmarks":"كل العلامات المرجعية",
|
"all_bookmarks":"كل العلامات المرجعية",
|
||||||
"economy_title":" الاقتصاد",
|
"economy_title":"اقتصاد",
|
||||||
"social_title":"اجتماعي",
|
"social_title":"اجتماعي",
|
||||||
"environment_title":"البيئة",
|
"environment_title":"بيئة",
|
||||||
"bookmarks": "الإشارات المرجعية",
|
"bookmarks": "الإشارات المرجعية",
|
||||||
"feedback_title": "تعليق",
|
"feedback_title": "تعليق",
|
||||||
"feedback_failed_msg": "لم يتم إرسال تعليقاتك. يرجى المحاولة مرة أخرى.",
|
"feedback_failed_msg": "لم يتم إرسال تعليقاتك. يرجى المحاولة مرة أخرى.",
|
||||||
|
|||||||
@ -32,7 +32,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
|
|||||||
bool _obscureNewPassword = true;
|
bool _obscureNewPassword = true;
|
||||||
bool _obscureConfirmPassword = true;
|
bool _obscureConfirmPassword = true;
|
||||||
bool _isPasswordUpdated = false; // Variable to toggle UI
|
bool _isPasswordUpdated = false; // Variable to toggle UI
|
||||||
|
bool hasValidated = false;
|
||||||
String? _oldPassword;
|
String? _oldPassword;
|
||||||
String? _newPassword;
|
String? _newPassword;
|
||||||
String? _confirmPassword;
|
String? _confirmPassword;
|
||||||
@ -242,10 +242,11 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
|
|||||||
pathColorWhenOn: Colors.grey.shade300,
|
pathColorWhenOn: Colors.grey.shade300,
|
||||||
pathColorWhenOff: Colors.grey.shade300,
|
pathColorWhenOff: Colors.grey.shade300,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
||||||
final formState = _formKey.currentState;
|
final formState = _formKey.currentState;
|
||||||
ref.read(localeProvider.notifier).toggleLocale();
|
ref.read(localeProvider.notifier).toggleLocale();
|
||||||
Future.delayed(Duration(milliseconds: 100), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
if (formState?.validate() == false) {
|
if (hasValidated && formState?.validate() == false) {
|
||||||
formState?.validate();
|
formState?.validate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -581,6 +582,9 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
|
|||||||
width: screenWidth / 1.1,
|
width: screenWidth / 1.1,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
if ((_formKey.currentState?.validate() ?? false)) {
|
if ((_formKey.currentState?.validate() ?? false)) {
|
||||||
await updatePassword(
|
await updatePassword(
|
||||||
widget.userId,
|
widget.userId,
|
||||||
|
|||||||
@ -27,7 +27,7 @@ class _RegisterScreenState extends ConsumerState<RegisterScreen> {
|
|||||||
final _emailController = TextEditingController();
|
final _emailController = TextEditingController();
|
||||||
final _passwordController = TextEditingController();
|
final _passwordController = TextEditingController();
|
||||||
final _confirmpasswordController = TextEditingController();
|
final _confirmpasswordController = TextEditingController();
|
||||||
|
bool hasValidated = false;
|
||||||
bool _obscurePassword = true;
|
bool _obscurePassword = true;
|
||||||
bool _obscureConfirmPassword = true;
|
bool _obscureConfirmPassword = true;
|
||||||
bool isChecked = false;
|
bool isChecked = false;
|
||||||
@ -219,6 +219,7 @@ class _RegisterScreenState extends ConsumerState<RegisterScreen> {
|
|||||||
if (_formKey.currentState?.validate() ?? false) {
|
if (_formKey.currentState?.validate() ?? false) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
hasValidated = true;
|
||||||
isRegistering = true; // Disable the button
|
isRegistering = true; // Disable the button
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@ -386,7 +387,7 @@ class _RegisterScreenState extends ConsumerState<RegisterScreen> {
|
|||||||
final formState = _formKey.currentState;
|
final formState = _formKey.currentState;
|
||||||
ref.read(localeProvider.notifier).toggleLocale();
|
ref.read(localeProvider.notifier).toggleLocale();
|
||||||
Future.delayed(Duration(milliseconds: 100), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
if (formState?.validate() == false) {
|
if (hasValidated && formState?.validate() == false) {
|
||||||
formState?.validate();
|
formState?.validate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -36,7 +36,7 @@ class ProfileScreen extends ConsumerStatefulWidget {
|
|||||||
class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||||
final _pb = PocketBase('https://pb.venbait.in');
|
final _pb = PocketBase('https://pb.venbait.in');
|
||||||
// final _pb = PocketBase('http://127.0.0.1:8090');
|
// final _pb = PocketBase('http://127.0.0.1:8090');
|
||||||
|
bool hasValidated = false;
|
||||||
// Add focus nodes and hint states
|
// Add focus nodes and hint states
|
||||||
final List<FocusNode> _focusNodes = List.generate(4, (_) => FocusNode());
|
final List<FocusNode> _focusNodes = List.generate(4, (_) => FocusNode());
|
||||||
final List<bool> _showHints = [
|
final List<bool> _showHints = [
|
||||||
@ -488,7 +488,13 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
|||||||
pathColorWhenOn: Colors.grey.shade300,
|
pathColorWhenOn: Colors.grey.shade300,
|
||||||
pathColorWhenOff: Colors.grey.shade300,
|
pathColorWhenOff: Colors.grey.shade300,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
final formState = _formKey.currentState;
|
||||||
ref.read(localeProvider.notifier).toggleLocale();
|
ref.read(localeProvider.notifier).toggleLocale();
|
||||||
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
|
if (hasValidated && formState?.validate() == false) {
|
||||||
|
formState?.validate();
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -947,6 +953,9 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
|||||||
// ElevatedButton.icon(
|
// ElevatedButton.icon(
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
hasValidated = true;
|
||||||
|
});
|
||||||
if ((_formKey.currentState?.validate() ?? false) &&
|
if ((_formKey.currentState?.validate() ?? false) &&
|
||||||
(isChecked)) {
|
(isChecked)) {
|
||||||
_formKey.currentState?.save();
|
_formKey.currentState?.save();
|
||||||
|
|||||||
@ -125,6 +125,7 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final hasValidated = useState(false);
|
||||||
final locale = ref.watch(localeProvider);
|
final locale = ref.watch(localeProvider);
|
||||||
final emailCtl = useTextEditingController();
|
final emailCtl = useTextEditingController();
|
||||||
final pwCtl = useTextEditingController();
|
final pwCtl = useTextEditingController();
|
||||||
@ -270,6 +271,7 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
hasValidated.value=true;
|
||||||
final isValid = formKey.currentState!.validate();
|
final isValid = formKey.currentState!.validate();
|
||||||
if (!isValid) return;
|
if (!isValid) return;
|
||||||
final session = await context.loaderWithErrorDialog(
|
final session = await context.loaderWithErrorDialog(
|
||||||
@ -677,7 +679,7 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
final formState = formKey.currentState;
|
final formState = formKey.currentState;
|
||||||
ref.read(localeProvider.notifier).toggleLocale();
|
ref.read(localeProvider.notifier).toggleLocale();
|
||||||
Future.delayed(Duration(milliseconds: 100), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
if (formState?.validate() == false) {
|
if (hasValidated.value && formState?.validate() == false) {
|
||||||
formState?.validate();
|
formState?.validate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -24,19 +24,11 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
|||||||
final _pb = PocketBase('https://pb.venbait.in');
|
final _pb = PocketBase('https://pb.venbait.in');
|
||||||
List<Map<String, dynamic>> dataList = [];
|
List<Map<String, dynamic>> dataList = [];
|
||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
|
Map<String, Map<String, dynamic>> groupedMap = {};
|
||||||
|
int? expandedIndex = 0;
|
||||||
// Current selected tab index
|
// Current selected tab index
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
// Tab categories
|
|
||||||
// final List<String> tabs = [
|
|
||||||
// 'All Bookmarks',
|
|
||||||
// 'Economy',
|
|
||||||
// 'Social',
|
|
||||||
// 'Environment',
|
|
||||||
// ];
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -105,8 +97,36 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
|||||||
'id': item['id'],
|
'id': item['id'],
|
||||||
};
|
};
|
||||||
}).toList();
|
}).toList();
|
||||||
print('dataList $dataList');
|
// print('dataList $dataList');
|
||||||
});
|
});
|
||||||
|
groupedMap = {};
|
||||||
|
for (var item in dataList) {
|
||||||
|
String? mainTopic = item['main_topic'];
|
||||||
|
String subtitle = item['subtitle'];
|
||||||
|
|
||||||
|
|
||||||
|
// Ignore if main_topic is null
|
||||||
|
if (mainTopic == null) continue;
|
||||||
|
|
||||||
|
// If main_topic doesn't exist in groupedMap, create a new entry
|
||||||
|
if (!groupedMap.containsKey(mainTopic)) {
|
||||||
|
groupedMap[mainTopic] = {'main_topic': mainTopic,
|
||||||
|
'valueColor': item['valueColor'],
|
||||||
|
'SubTopic': []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add subtitle as a key with its corresponding map value
|
||||||
|
groupedMap[mainTopic]!['SubTopic'].add ({
|
||||||
|
'subtitle': subtitle,
|
||||||
|
'isBookmark': item['isBookmark'],
|
||||||
|
'value': item['value'],
|
||||||
|
'title':item['title'],
|
||||||
|
'value_source':item['value_source'],
|
||||||
|
'data_set':item['data_set'],
|
||||||
|
'id': item['id'],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -267,11 +287,11 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
final List<String> tabs = [
|
final List<Map<String, dynamic>> tabs = [
|
||||||
AppLocalizations.of(context)!.all_bookmarks,
|
{ 'title':AppLocalizations.of(context)!.all_bookmarks, 'color': Colors.black},
|
||||||
AppLocalizations.of(context)!.economy_title,
|
{ 'title': AppLocalizations.of(context)!.economy_title, 'color': Colors.black},
|
||||||
AppLocalizations.of(context)!.social_title,
|
{ 'title':AppLocalizations.of(context)!.social_title, 'color': Colors.black},
|
||||||
AppLocalizations.of(context)!.environment_title,
|
{ 'title': AppLocalizations.of(context)!.environment_title, 'color': Colors.black},
|
||||||
];
|
];
|
||||||
|
|
||||||
ref.listen<Locale?>(localeProvider, (previous, next) {
|
ref.listen<Locale?>(localeProvider, (previous, next) {
|
||||||
@ -281,11 +301,19 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
|||||||
|
|
||||||
List<Map<String, dynamic>> bookmarks = dataList.where((item) => item['isBookmark'] == true).toList();
|
List<Map<String, dynamic>> bookmarks = dataList.where((item) => item['isBookmark'] == true).toList();
|
||||||
List<Map<String, dynamic>> filteredBookmarks = dataList
|
List<Map<String, dynamic>> filteredBookmarks = dataList
|
||||||
.where((bookmark) =>
|
.where((bookmark) {
|
||||||
bookmark['main_topic'].toString().trim().toLowerCase() == tabs[selectedTabIndex].toString().trim().toLowerCase())
|
String mainTopic = bookmark['main_topic'].toString().trim().toLowerCase();
|
||||||
.toList();
|
String selectedTabTitle = tabs[selectedTabIndex]['title'].toString().trim().toLowerCase();
|
||||||
|
|
||||||
print('filtered $filteredBookmarks');
|
// Debugging prints
|
||||||
|
print("main_topic: '$mainTopic', selected_tab_title: '$selectedTabTitle'");
|
||||||
|
|
||||||
|
return mainTopic == selectedTabTitle;
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
// print( 'filtered one :${filteredBookmarks['main_topic']} , Tabs : ${tabs[selectedTabIndex]["title"]}');
|
||||||
|
List<Map<String, dynamic>> transformedList = groupedMap.values.toList();
|
||||||
|
// print('filtered $filteredBookmarks');
|
||||||
return BaseScaffold(
|
return BaseScaffold(
|
||||||
title: Text(AppLocalizations.of(context)!.bookmarks,),
|
title: Text(AppLocalizations.of(context)!.bookmarks,),
|
||||||
body: Column(
|
body: Column(
|
||||||
@ -301,23 +329,68 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
|||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: selectedTabIndex == 0
|
child: selectedTabIndex == 0
|
||||||
? Padding(
|
? (bookmarks.isNotEmpty
|
||||||
padding: const EdgeInsets.all(8.0),
|
? SingleChildScrollView(
|
||||||
child: GridView.builder(
|
child: Column(
|
||||||
gridDelegate:
|
children: List.generate(transformedList.length, (i) {
|
||||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
final mainTopic = transformedList[i];
|
||||||
crossAxisCount: 2,
|
print('oustside1 $mainTopic');
|
||||||
crossAxisSpacing: 10.0,
|
final list=List.from(mainTopic['SubTopic'] ?? []);
|
||||||
mainAxisSpacing: 10.0,
|
print('oustside2 $list');
|
||||||
mainAxisExtent: 100,
|
return CustomExpandableTile(
|
||||||
),
|
index: i,
|
||||||
itemCount: bookmarks.length,
|
isExpanded: expandedIndex == i,
|
||||||
itemBuilder: (context, index) {
|
onTap: (int index) { // 🔹 Expecting an index
|
||||||
return _buildBox(bookmarks[index], context);
|
setState(() {
|
||||||
},
|
expandedIndex = (expandedIndex == index) ? null : index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
title: mainTopic['main_topic'] ?? 'No Topic',
|
||||||
|
childWidget:
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
// borderRadius: BorderRadius.all(Radius.circular(20))
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: GridView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: NeverScrollableScrollPhysics(),
|
||||||
|
gridDelegate:
|
||||||
|
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 2,
|
||||||
|
crossAxisSpacing: 10.0,
|
||||||
|
mainAxisSpacing: 10.0,
|
||||||
|
mainAxisExtent: 100,
|
||||||
|
),
|
||||||
|
itemCount:list.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return _buildBoxes(mainTopic['SubTopic'][index], context,mainTopic['valueColor']);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
filteredBookmarks: List.from(mainTopic['SubTopic'] ?? []), titleBackgroundColor: mainTopic['valueColor'],
|
||||||
|
// Ensure it's a new list
|
||||||
|
);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
|
)
|
||||||
):filteredBookmarks.isEmpty
|
: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.info_outline,
|
||||||
|
size: 100, color: Colors.grey[400]),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
context.translate('No BookMark Added','لم يتم إضافة أي علامة مرجعية'),
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 16, color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
))
|
||||||
|
:filteredBookmarks.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@ -348,7 +421,6 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
|||||||
return _buildBox(filteredBookmarks[index], context);
|
return _buildBox(filteredBookmarks[index], context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -371,7 +443,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
|||||||
print(hexColor); // Prints: 0xFFAA8E83
|
print(hexColor); // Prints: 0xFFAA8E83
|
||||||
|
|
||||||
debugPrint("Box clicked: ${data['title']}");
|
debugPrint("Box clicked: ${data['title']}");
|
||||||
context.go(
|
context.push(
|
||||||
'/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle');
|
'/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle');
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -456,10 +528,110 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildBoxes(Map<String, dynamic> data, BuildContext context, Color styleColor) {
|
||||||
|
// Color borderColor = data['valueColor'];
|
||||||
|
print('inside function $data');
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
final data_set = data['data_set'];
|
||||||
|
|
||||||
|
// final Color colorPattern = data['valueColor'];
|
||||||
|
final encodedMainTopic = data['main_topic'];
|
||||||
|
final encodedTitle = data['title'];
|
||||||
|
String hexColor = colorToHex(styleColor);
|
||||||
|
|
||||||
|
debugPrint( '/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle');
|
||||||
|
|
||||||
|
// String hexColor = colorToHex(colorPattern); // Get hex string
|
||||||
|
// print(hexColor); // Prints: 0xFFAA8E83
|
||||||
|
|
||||||
|
// debugPrint("Box clicked: ${data['title']}");
|
||||||
|
context.push(
|
||||||
|
'/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.4,
|
||||||
|
height: 100,
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
border: Border.all(color: styleColor),
|
||||||
|
),
|
||||||
|
child:
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
data['title'] ?? '',
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
debugPrint("Icon clicked in: ${data['title']}");
|
||||||
|
removeBookmark(data['id']);
|
||||||
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
// SnackBar(
|
||||||
|
// content: Text(
|
||||||
|
// context.translate('Removed From Bookmark','تمت الإزالة من العلامات المرجعية'),
|
||||||
|
// // style: TextStyle(color: Color(0xFF2F692C),
|
||||||
|
// // fontWeight: FontWeight.w500),
|
||||||
|
// ),
|
||||||
|
// // backgroundColor: Color(0xFFD6E9C6),
|
||||||
|
// duration: Duration(seconds: 2),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
},
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
BookmarkAssetPath.delete,
|
||||||
|
semanticsLabel: 'share',
|
||||||
|
width:23,
|
||||||
|
height: 20,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
data['value_source'] ?? '',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.w500, color: Colors.grey),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
data['value'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 28,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: styleColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TabBarHeader extends StatelessWidget {
|
class TabBarHeader extends StatelessWidget {
|
||||||
final List<String> tabs;
|
final List<Map<String, dynamic>> tabs;
|
||||||
final int selectedIndex;
|
final int selectedIndex;
|
||||||
final ValueChanged<int> onTabSelected;
|
final ValueChanged<int> onTabSelected;
|
||||||
|
|
||||||
@ -480,7 +652,7 @@ class TabBarHeader extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: tabs.asMap().entries.map((entry) {
|
children: tabs.asMap().entries.map((entry) {
|
||||||
int index = entry.key;
|
int index = entry.key;
|
||||||
String text = entry.value;
|
String text = entry.value['title'];
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
TextButton(
|
TextButton(
|
||||||
@ -505,7 +677,7 @@ class TabBarHeader extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildDivider() {
|
Widget buildDivider() {
|
||||||
return Container(
|
return SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
child: const VerticalDivider(
|
child: const VerticalDivider(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
@ -514,4 +686,124 @@ class TabBarHeader extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CustomExpandableTile extends StatefulWidget {
|
||||||
|
final String title;
|
||||||
|
final Color titleBackgroundColor;
|
||||||
|
final List filteredBookmarks;
|
||||||
|
final int index;
|
||||||
|
final bool isExpanded;
|
||||||
|
final ValueChanged<int> onTap;
|
||||||
|
final Widget childWidget;
|
||||||
|
|
||||||
|
const CustomExpandableTile({
|
||||||
|
required this.title,
|
||||||
|
required this.titleBackgroundColor,
|
||||||
|
required this.filteredBookmarks,
|
||||||
|
required this.index,
|
||||||
|
required this.isExpanded,
|
||||||
|
required this.onTap,
|
||||||
|
required this.childWidget,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_CustomExpandableTileState createState() => _CustomExpandableTileState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomExpandableTileState extends State<CustomExpandableTile> {
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState(); // Initialize isExpanded based on widget's property
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
double myheight = MediaQuery.of(context).size.height;
|
||||||
|
// print(widget.filteredBookmarks);
|
||||||
|
return Card(
|
||||||
|
elevation: 0,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => widget.onTap(widget.index),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white, // Ensuring the background outside the rounded container is white
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: widget.titleBackgroundColor,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(35))
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 16, bottom: 5, top: 5, right: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
widget.title,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
widget.isExpanded
|
||||||
|
? Icons.keyboard_arrow_up
|
||||||
|
: Icons.keyboard_arrow_down,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 28.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ClipRRect(
|
||||||
|
child: AnimatedContainer(
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
width: double.infinity,
|
||||||
|
color: Colors.white,
|
||||||
|
height:widget.isExpanded ? myheight * 0.4 : 0,
|
||||||
|
child:widget.isExpanded
|
||||||
|
? SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
widget.childWidget,
|
||||||
|
// Container(
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// color: Colors.white,
|
||||||
|
// // borderRadius: BorderRadius.all(Radius.circular(20))
|
||||||
|
// ),
|
||||||
|
// padding: const EdgeInsets.all(16),
|
||||||
|
// child: GridView.builder(
|
||||||
|
// shrinkWrap: true,
|
||||||
|
// physics: NeverScrollableScrollPhysics(),
|
||||||
|
// gridDelegate:
|
||||||
|
// const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
// crossAxisCount: 2,
|
||||||
|
// crossAxisSpacing: 10.0,
|
||||||
|
// mainAxisSpacing: 10.0,
|
||||||
|
// mainAxisExtent: 100,
|
||||||
|
// ),
|
||||||
|
// itemCount: widget.filteredBookmarks.length,
|
||||||
|
// itemBuilder: (context, index) {
|
||||||
|
// return _buildBox(widget.filteredBookmarks[index], context,widget.titleBackgroundColor);
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||||||
|
|
||||||
|
|
||||||
class Userguide extends StatefulWidget {
|
class Userguide extends StatefulWidget {
|
||||||
const Userguide({super.key});
|
Userguide({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<Userguide> createState() => _UserguideState();
|
State<Userguide> createState() => _UserguideState();
|
||||||
@ -20,6 +20,7 @@ class _UserguideState extends State<Userguide> {
|
|||||||
{'routePath':'faq','color': Color(0xFF7296BE), 'text': 'FAQs', 'icon': 'mdi:faq', 'text-ar': 'لأسئلة الشائعة'},
|
{'routePath':'faq','color': Color(0xFF7296BE), 'text': 'FAQs', 'icon': 'mdi:faq', 'text-ar': 'لأسئلة الشائعة'},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
Widget buildDynamicWidget(dynamic icons, Color color) {
|
Widget buildDynamicWidget(dynamic icons, Color color) {
|
||||||
if (icons is IconData) {
|
if (icons is IconData) {
|
||||||
return Icon(
|
return Icon(
|
||||||
@ -46,41 +47,41 @@ class _UserguideState extends State<Userguide> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: false,
|
canPop: false,
|
||||||
onPopInvokedWithResult: (didPop, result) {
|
onPopInvokedWithResult: (didPop, result) {
|
||||||
if (didPop) return;
|
if (didPop) return;
|
||||||
context.go('/myhomepage');
|
context.go('/myhomepage');
|
||||||
},
|
},
|
||||||
child: BaseScaffold(
|
child: BaseScaffold(
|
||||||
showDivider: true,
|
showDivider: true,
|
||||||
bottomColor: Colors.white,
|
bottomColor: Colors.white,
|
||||||
dividerColor: Colors.grey[300],
|
dividerColor: Colors.grey[300],
|
||||||
appbarColor: Colors.white,
|
appbarColor: Colors.white,
|
||||||
title: Text(AppLocalizations.of(context)!.guide_title) ,
|
title: Text(AppLocalizations.of(context)!.guide_title) ,
|
||||||
body: Container(
|
body: Container(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16 , vertical: 20),
|
padding: const EdgeInsets.symmetric(horizontal: 16 , vertical: 20),
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: 2, // Two columns
|
crossAxisCount: 2,
|
||||||
crossAxisSpacing: 10.0,
|
crossAxisSpacing: 10.0,
|
||||||
mainAxisSpacing: 10.0,
|
mainAxisSpacing: 10.0,
|
||||||
mainAxisExtent:MediaQuery.of(context).size.height* 0.15 ,
|
childAspectRatio: 1.7,
|
||||||
|
// mainAxisExtent:MediaQuery.of(context).size.height* 0.15 ,
|
||||||
|
),
|
||||||
|
itemCount: guideList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return HoverContainer(
|
||||||
|
iconName: guideList[index]['icon'],
|
||||||
|
title: context.translate(guideList[index]['text'], guideList[index]['text-ar']),
|
||||||
|
routePath: guideList[index]['routePath'],
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
itemCount: guideList.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return HoverContainer(
|
|
||||||
iconName: guideList[index]['icon'],
|
|
||||||
title: context.translate(guideList[index]['text'], guideList[index]['text-ar']),
|
|
||||||
routePath: guideList[index]['routePath'],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,69 +109,69 @@ class _HoverContainerState extends State<HoverContainer> {
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () { context.push('/user-guide/${widget.routePath}');},
|
onTap: () { context.push('/user-guide/${widget.routePath}');},
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
onEnter: (_) => setState(() => isHovered = true),
|
onEnter: (_) => setState(() => isHovered = true),
|
||||||
onExit: (_) => setState(() => isHovered = true),
|
onExit: (_) => setState(() => isHovered = true),
|
||||||
child : Container(
|
child : Container(
|
||||||
padding: EdgeInsets.only(top: 4, right: 4, left: 4, bottom: 6),
|
padding: EdgeInsets.only(top: 4, right: 4, left: 4, bottom: 6),
|
||||||
height: screenHeight* 0.23 ,
|
|
||||||
width: screenWidth*0.30,
|
|
||||||
margin: EdgeInsets.all(1),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
boxShadow: isHovered
|
|
||||||
? [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black.withValues(alpha:0.2),
|
|
||||||
blurRadius:2,
|
|
||||||
spreadRadius: 1,
|
|
||||||
offset: Offset(0, 4),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
: [],
|
|
||||||
border: Border.all(
|
|
||||||
color: Color(0xFF7DAFBC),
|
|
||||||
width: 1.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
// duration: Duration(milliseconds: 200),
|
|
||||||
|
|
||||||
child: LayoutBuilder(builder: (context, constraints){
|
width: screenWidth*0.30,
|
||||||
double containerWidth = constraints.maxWidth;
|
margin: EdgeInsets.all(1),
|
||||||
// double containerHeight = constraints.maxHeight;
|
decoration: BoxDecoration(
|
||||||
return Column(
|
color: Colors.white,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
borderRadius: BorderRadius.circular(10),
|
||||||
children: [
|
boxShadow: isHovered
|
||||||
IconifyIcon(icon: widget.iconName,
|
? [
|
||||||
color: Color((0xFF7DAFBC)),
|
BoxShadow(
|
||||||
size: containerWidth * 0.25,),
|
color: Colors.black.withOpacity(0.2),
|
||||||
// buildDynamicWidget(data['icon'], Color(0xFF7DAFBC)),
|
blurRadius:2,
|
||||||
SizedBox(width: 10,height: containerWidth * 0.04,), // Space between icon and text
|
spreadRadius: 1,
|
||||||
Container(
|
offset: Offset(0, 4),
|
||||||
width: containerWidth* 0.85,
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 4),
|
|
||||||
margin: EdgeInsets.only(bottom: 3),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Color(0xFF7DAFBC),
|
|
||||||
borderRadius: BorderRadius.circular(5),
|
|
||||||
border: Border.all(color: Color(0xFF7DAFBC)),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
widget.title,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white, // Text color
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
),
|
||||||
|
]
|
||||||
|
: [],
|
||||||
|
border: Border.all(
|
||||||
|
color: Color(0xFF7DAFBC),
|
||||||
|
width: 1.0
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
);
|
alignment: Alignment.center,
|
||||||
},),
|
// duration: Duration(milliseconds: 200),
|
||||||
|
|
||||||
|
child: LayoutBuilder(builder: (context, constraints){
|
||||||
|
double containerWidth = constraints.maxWidth;
|
||||||
|
double containerHeight = constraints.maxHeight;
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
IconifyIcon(icon: widget.iconName,
|
||||||
|
color: Color((0xFF7DAFBC)),
|
||||||
|
size: containerHeight * 0.45,),
|
||||||
|
// buildDynamicWidget(data['icon'], Color(0xFF7DAFBC)),
|
||||||
|
SizedBox(width: 10,height: containerHeight * 0.04,), // Space between icon and text
|
||||||
|
Container(
|
||||||
|
width: containerWidth* 0.85,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 4),
|
||||||
|
margin: EdgeInsets.only(bottom: 3),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFF7DAFBC),
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
border: Border.all(color: Color(0xFF7DAFBC))
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
widget.title,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white, // Text color
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user