test base project

This commit is contained in:
Azmat-7860
2026-09-15 09:09:11 +05:30
commit 8094da30c4
471 changed files with 27174 additions and 0 deletions
+240
View File
@@ -0,0 +1,240 @@
int calcDaysBetween(DateTime from, DateTime to) {
from = DateTime(from.year, from.month, from.day);
to = DateTime(to.year, to.month, to.day);
return (to.difference(from).inHours ~/ 24);
}
int calcSecondsBetween(DateTime from, DateTime to) {
from = DateTime(
from.year, from.month, from.day, from.hour, from.minute, from.second);
to = DateTime(to.year, to.month, to.day, to.hour, to.minute, to.second);
return to.difference(from).inSeconds;
}
String customGroup(DateTime transactionDate) {
String response = '';
DateTime latestDate = DateTime.now();
int nDaysInBetween = calcDaysBetween(transactionDate, latestDate);
int years = nDaysInBetween ~/ 365;
if (years == 1) {
response = 'Last year';
} else if (years > 1 && years <= 5) {
response = '$years years ago';
} else if (years > 5) {
response = 'More than 5 years ago';
} else {
nDaysInBetween -= 365 * years;
int months = nDaysInBetween ~/ 30;
if (months == 1) {
response = 'Last month';
} else if (months > 1 && months <= 6) {
response = '$months months ago';
} else if (months >= 6) {
response = 'More than 6 months ago';
} else {
int days = latestDate.day - transactionDate.day;
if (days == 1) {
response = 'Yesterday';
} else if (days > 1 && days <= 7) {
response = 'This week';
} else if (days > 7 && days <= 14) {
response = 'Last week';
} else if (days > 14 && days <= 30) {
int weeks = days ~/ 7;
response = '$weeks weeks ago';
} else {
response = 'Today';
}
}
}
return response;
}
int customGroupComparator(String group1, String group2) {
int comparison = -1;
int group1Match = 0;
int group2Match = 0;
List<String> dateGroups = [
r'Today',
r'Yesterday',
r'This week',
r'Last week',
r'\d{1} weeks ago',
r'Last month',
r'\d{1} months ago',
r'More than 6 months ago',
r'Last year',
r'\d{1} years ago',
r'More than 5 years ago',
];
for (var i = 0; i < dateGroups.length; i++) {
if (RegExp(dateGroups[i]).hasMatch(group1)) {
group1Match = i;
}
if (RegExp(dateGroups[i]).hasMatch(group2)) {
group2Match = i;
}
}
// check
if (group1Match == group2Match) {
comparison = group1.compareTo(group2);
} else if (group1Match < group2Match) {
comparison = -1;
} else {
comparison = 1;
}
return comparison;
}
String dateFormatter(String dateGroup, DateTime transactionDate) {
String formattedDate = '';
if (dateGroup == 'Today') {
formattedDate = _formatTime1(transactionDate);
} else if (dateGroup == 'Yesterday') {
formattedDate =
"Yesterday at ${formatTime2(transactionDate.hour, transactionDate.minute)}";
} else {
formattedDate =
"${transactionDate.day}-${transactionDate.month}-${transactionDate.year} at ${formatTime2(transactionDate.hour, transactionDate.minute)}";
}
return formattedDate;
}
String formatTime2(int hrs, int mins) {
int newHrs = 0;
String midDayStatus = '';
String minutesAsString=mins<10?"0$mins":"$mins";
if (hrs > 12 && hrs < 24) {
midDayStatus = 'PM';
newHrs = hrs - 12;
} else if (hrs == 12 && mins > 0) {
midDayStatus = 'PM';
newHrs = 12;
} else if (hrs < 12) {
midDayStatus = 'AM';
newHrs = hrs;
} else if (hrs == 24) {
midDayStatus = 'AM';
newHrs = 00;
}
return "$newHrs:$minutesAsString $midDayStatus";
}
String formatTime3(String date) {
DateTime someDate = DateTime.parse(date);
int hrs = someDate.hour;
dynamic mins = someDate.minute;
int newHrs = 0;
String midDayStatus = '';
if (hrs > 12 && hrs < 24) {
midDayStatus = 'PM';
newHrs = hrs - 12;
} else if (hrs == 12 && mins > 0) {
midDayStatus = 'PM';
newHrs = 12;
} else if (hrs < 12) {
midDayStatus = 'AM';
newHrs = hrs;
} else if (hrs == 24) {
midDayStatus = 'AM';
newHrs = 00;
}
if (mins<=9) {
mins="0$mins";
}
return "$newHrs:$mins $midDayStatus";
}
String _formatTime1(DateTime transactionDate) {
DateTime latestDate = DateTime.now();
int seconds = calcSecondsBetween(transactionDate, latestDate);
int minutes = seconds ~/ 60;
int hours = minutes ~/ 60;
String response = '';
if (hours == 1) {
response = 'an hour ago';
} else if (hours > 1 && hours < 24) {
response = '$hours hours ago';
} else {
if (minutes > 30) {
response = 'half an hour ago';
} else if (minutes <= 30 && minutes > 1) {
response = '$minutes minutes ago';
} else if (minutes == 1) {
response = 'a minute ago';
} else {
if (seconds <= 0) {
response = 'just now';
} else if (seconds == 1) {
response = 'a second ago';
} else {
response = '$seconds seconds ago';
}
}
}
return response;
}
String dateToWords(DateTime transactionDate) {
String day = _formatDay(transactionDate.day);
String month = _findMonthInWords(transactionDate.month);
return "$day $month, ${transactionDate.year}";
}
//? FUNCTION FOR RETRIEVING ORDINALS
String _formatDay(int day) {
String suffix = '';
if (day >= 11 && day<=13) {
suffix = 'th';
} else {
switch (day % 10) {
case 1:
suffix = 'st';
break;
case 2:
suffix = 'nd';
break;
case 3:
suffix = 'rd';
break;
default:
suffix = 'th';
}
}
return "$day$suffix";
}
String _findMonthInWords(int month) {
List<String> months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
return months[month - 1];
}
+151
View File
@@ -0,0 +1,151 @@
import 'package:flutter/material.dart';
import '../database/login_info_storage.dart';
import '../database/user_data_storage.dart';
import '../screens/Login Screen/login_screen.dart';
Future<bool> _deleteLoggedInUserData() async {
List<bool> deletionStatus = await Future.wait(
[LoginInfoStorage().deleteFile(), UserDataStorage().deleteFile()]);
return deletionStatus.first && deletionStatus.last;
}
void showErrorAlert(BuildContext context, Map<String, dynamic> error) {
Map<String, dynamic> errorTypes = {
'error': _CommonError(context, error),
'internetConnectionError': _LocalError(context, error),
'localDBError': _LocalError(context, error),
'authenticationError': _CommonError(context, error),
'apiAuthorizationError': _HazardousError(context, error),
'corruptedTokenError': _HazardousError(context, error)
};
String currentError = error.keys.first;
// String currentError = error['operationMessage'];
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: Text(
"Error",
textAlign: TextAlign.center,
),
content: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: errorTypes[currentError].errorDescription,
),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
actionsAlignment: MainAxisAlignment.center,
actions: [
Container(
height: 48,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.blueGrey.shade100,
offset: Offset(0, 4),
blurRadius: 5.0)
],
gradient: RadialGradient(
colors: [Color(0xff0070BA), Color(0xff1546A0)],
radius: 8.4,
center: Alignment(-0.24, -0.36)),
borderRadius: BorderRadius.circular(10),
),
child: ElevatedButton(
onPressed: errorTypes[currentError].onClose,
child: Text('OK'),
style: ElevatedButton.styleFrom(
// OLD: primary: Colors.transparent, // removed in Flutter 3.27 - by Azmat
backgroundColor: Colors.transparent, // Flutter 3.27 renamed primary - by Azmat
shadowColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
)),
)
],
));
}
class _CommonError {
BuildContext context;
Map<String, dynamic> error;
_CommonError(this.context, this.error);
List<Widget> get errorDescription => <Widget>[
Padding(
padding: EdgeInsets.only(top: 24, bottom: 12),
child: Text(
error[error['operationMessage']],
textAlign: TextAlign.center,
),
),
];
void onClose() {
Navigator.of(context).pop();
}
}
class _LocalError {
BuildContext context;
Map<String, dynamic> error;
_LocalError(this.context, this.error);
List<Widget> get errorDescription => <Widget>[
error.keys.first == 'internetConnectionError'
? ColorFiltered(
colorFilter:
ColorFilter.mode(Color(0xFF0070BA), BlendMode.color),
child: ColorFiltered(
colorFilter:
ColorFilter.mode(Colors.grey, BlendMode.saturation),
child: Image.asset(
'assets/images/notification_assets/no-wifi.png',
height: 48,
width: 48,
),
))
: Image.asset(
'assets/images/notification_assets/file-error.png',
height: 48,
width: 48,
),
Padding(
padding: EdgeInsets.only(top: 24, bottom: 12),
child: Text(
error[error.keys.first],
textAlign: TextAlign.center,
),
),
];
void onClose() {
Navigator.of(context).pop();
}
}
class _HazardousError {
BuildContext context;
Map<String, dynamic> error;
_HazardousError(this.context, this.error);
List<Widget> get errorDescription => <Widget>[
Padding(
padding: EdgeInsets.only(top: 24, bottom: 12),
child: Text(
error[error.keys.first],
textAlign: TextAlign.center,
),
),
];
void onClose() async {
final logOutStatus = await _deleteLoggedInUserData();
if (logOutStatus) {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => LoginScreen()),
(route) => false);
}
}
}
+27
View File
@@ -0,0 +1,27 @@
/// Flutter icons HadWinIcons
/// Copyright (C) 2022 by original authors @ fluttericon.com, fontello.com
/// This font was generated by FlutterIcon.com, which is derived from Fontello.
///
/// To use this font, place it in your fonts/ directory and include the
/// following in your pubspec.yaml
///
/// flutter:
/// fonts:
/// - family: HadWinIcons
/// fonts:
/// - asset: fonts/HadWinIcons.ttf
///
///
///
import 'package:flutter/widgets.dart';
class HadWinIcons {
HadWinIcons._();
static const _kFontFam = 'HadWinIcons';
static const String? _kFontPkg = null;
static const IconData wallet_business_and_trade = IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData wallet_education_29 = IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData line_awesome_wallet_solid = IconData(0xe803, fontFamily: _kFontFam, fontPackage: _kFontPkg);
}
+191
View File
@@ -0,0 +1,191 @@
import 'dart:io';
import 'package:fade_shimmer/fade_shimmer.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'display_error_alert.dart';
class HadWinMarkdownViewer extends StatefulWidget {
final String screenName;
final String urlRequested;
const HadWinMarkdownViewer({
Key? key,
required this.screenName,
required this.urlRequested,
}) : super(key: key);
@override
HadWinMarkdownViewerState createState() => HadWinMarkdownViewerState();
}
class HadWinMarkdownViewerState extends State<HadWinMarkdownViewer> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(
widget.screenName,
style: const TextStyle(fontSize: 24),
),
centerTitle: true,
backgroundColor: Colors.transparent,
foregroundColor: const Color(0xff243656),
elevation: 0,
),
body: Column(
children: [
Expanded(
child: Container(
height: 100,
width: MediaQuery.of(context).size.width - 20,
padding: const EdgeInsets.only(
left: 16.18,
right: 16.18,
bottom: 16.18,
top: 6.18,
),
child: FutureBuilder<String>(
future: getTextData(widget.urlRequested),
builder: (context, snapshot) {
if (snapshot.hasData) {
print('testing');
// return MarkdownWidgetBuilder(
// markdownData: snapshot.data!,
// styleConfig: MarkdownWidgetConfig(
// markdownTheme: MarkdownTheme(
// blockquoteDecoration: BoxDecoration(
// color: Color(0xffcaf0f8),
// ),
// blockquoteTextStyle: TextStyle(
// color: Color(0xff0077b6),
// ),
// tableConfig: TableConfig(
// headerStyle: TextStyle(
// fontWeight: FontWeight.w700,
// ),
// bodyTextConfig: TextConfig(
// textAlign: TextAlign.center,
// ),
// ),
// titleConfig: TitleConfig(
// commonStyle: GoogleFonts.ubuntu(),
// showDivider: false,
// ),
// ulConfig: UlConfig(
// textStyle: GoogleFonts.workSans(),
// dotWidget: (deep, index) => Text(
// "${index + 1}.\t",
// style: GoogleFonts.ubuntu(),
// ),
// ),
// olConfig: OlConfig(
// textStyle: GoogleFonts.workSans(),
// indexWidget: (deep, index) => Text(
// "${index + 1}.\t",
// style: GoogleFonts.ubuntu(),
// ),
// ),
// pConfig: PConfig(
// textStyle: GoogleFonts.workSans(),
// onLinkTap: (url) {
// launchExternalURL(url!).then(
// (value) =>
// debugPrint("requested to access $url"),
// );
// },
// emStyle: const TextStyle(
// fontWeight: FontWeight.w600,
// backgroundColor: Color(0xffccff33),
// fontStyle: FontStyle.italic,
// ),
// ),
// codeConfig: CodeConfig(
// codeStyle: GoogleFonts.spaceMono(
// backgroundColor: Color(0xff4a4e69),
// fontWeight: FontWeight.w600,
// color: Colors.white,
// ),
// ),
// ),
// ),
// builder: (context, content) {
// return content;
// },
// );
}
return docsLoading();
},
),
),
),
],
),
);
}
Future<String> getTextData(String url) async {
var response;
try {
response = await http.get(Uri.parse(url));
} on SocketException {
showErrorAlert(
context,
{'internetConnectionError': 'no internet connection'},
);
} catch (e) {
showErrorAlert(context, {'error': "something went wrong"});
}
return response.body;
}
Widget docsLoading() {
return ListView.separated(
itemBuilder: (context, index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding:
const EdgeInsets.symmetric(horizontal: 5, vertical: 1.618),
child: const FadeShimmer(
height: 27,
width: 100,
radius: 7.2,
highlightColor: Color(0xffced4da),
baseColor: Color(0xffe9ecef),
),
),
...List.generate(
4,
(i) => Container(
padding:
const EdgeInsets.symmetric(horizontal: 5, vertical: 1.618),
child: FadeShimmer(
height: 21,
width: MediaQuery.of(context).size.width - 24,
radius: 7.2,
highlightColor: const Color(0xffced4da),
baseColor: const Color(0xffe9ecef),
),
),
).toList(),
],
);
},
separatorBuilder: (_, b) => const SizedBox(
height: 10,
),
itemCount: 5,
);
}
}
+54
View File
@@ -0,0 +1,54 @@
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import '../resources/api_constants.dart';
Future<Map<String, dynamic>> getData(
{required String urlPath, String? authKey}) async {
String backendServiceHost = "${ApiConstants.baseUrl}$urlPath";
var response;
try {
response = await http.get(
Uri.parse(backendServiceHost),
headers: <String, String>{
'Content-Type': 'application/json',
if (authKey != null) 'Authorization': authKey
},
);
} on SocketException {
return {'internetConnectionError': 'no internet connection'};
}
return jsonDecode(response.body);
}
Future<Map<String, dynamic>> sendData(
{required String urlPath,
required Map<String, dynamic> data,
String? authKey}) async {
String backendServiceHost = "${ApiConstants.baseUrl}" + urlPath;
var response;
try {
response = await http.post(
Uri.parse(backendServiceHost),
headers: <String, String>{
'Content-Type': 'application/json',
if (authKey != null) 'Authorization': authKey
},
body: jsonEncode(data),
);
} on SocketException {
return {'internetConnectionError': 'no internet connection'};
}
return jsonDecode(response.body);
}
Future<int> checkUrlValidity(String url) async {
try {
final response = await http.get(Uri.parse(url));
return response.statusCode;
} catch (e) {
return 404;
}
}
+29
View File
@@ -0,0 +1,29 @@
// page slide transition effect
import 'package:flutter/material.dart';
class SlideRightRoute extends PageRouteBuilder {
final Widget page;
SlideRightRoute({required this.page})
: super(
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>
page,
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
SlideTransition(
textDirection: TextDirection.rtl,
position: Tween<Offset>(
begin: const Offset(-1, 0),
end: Offset.zero,
).animate(animation),
child: child,
),
);
}
+12
View File
@@ -0,0 +1,12 @@
import 'package:url_launcher/url_launcher.dart';
Future<void> launchExternalURL(String url) async {
Uri uri =Uri.parse(url);
if (await canLaunchUrl(uri)) {
await launchUrl(uri,mode: LaunchMode.externalApplication);
}
// else {
// throw 'Could not launch $url';
// }
}