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
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
class test {}
+128
View File
@@ -0,0 +1,128 @@
import 'dart:async';
import 'dart:io';
import 'package:authsec_flutter_hybrid/LocalStorage/TableQuery.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
class DatabaseHelper {
DatabaseHelper.internal();
static final DatabaseHelper instance = DatabaseHelper.internal();
TableQuery tablequery = TableQuery();
// factory DatabaseHelper() => instance;
static DatabaseHelper? _instance;
static Database? _database;
DatabaseHelper._privateConstructor();
factory DatabaseHelper() {
_instance ??= DatabaseHelper._privateConstructor();
return _instance!;
}
Future<Database> get database async {
if (_database != null) {
print('get database ... $_database');
return _database!;
}
_database = await initDatabase();
return _database!;
}
Future<Database> initDatabase() async {
try {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, 'my_database.db');
print('database path is $path');
// final db = await openDatabase('my_database.db');
var openDb = await openDatabase(
path,
version: 1,
onCreate: (db, version) => _createDatabaseTables(db),
onUpgrade: (db, int oldversion, int newversion) async {
if (oldversion < newversion) {
print("Version Upgrade");
}
},
);
// Check if the table exists
// var tableResult = await openDb.query('sqlite_master',
// columns: ['name'],
// where: 'type = ? AND name = ?',
// whereArgs: ['table', 'company']);
// if (tableResult.isEmpty) {
// print('Table does not exist');
// } else {
// print('table data is $tableResult');
// print('company Table exists');
// }
print('open db is...... ${openDb.database}');
return openDb;
} catch (e) {
print('Error initializing database: $e');
rethrow; // rethrow the error to see the full stack trace
}
}
Future<void> _createDatabaseTables(Database db) async {
tablequery.createOtherTable(db);
}
// create other table
// Future<void> _createOtherTable(Database db) async {
// _createTable(db, 'research_status', 'status_name');
// }
// Future<void> _createTable(
// Database db, String tableName, String fieldName) async {
// var tableExists = await _isTableExists(db, tableName);
// if (!tableExists) {
// print('$tableName making.....');
// await db.execute(
// '''
// CREATE TABLE $tableName (
// id INTEGER PRIMARY KEY AUTOINCREMENT,
// accountId TEXT,
// createdAt TEXT,
// createdBy TEXT,
// updatedAt TEXT,
// updatedBy TEXT,
// extn1 TEXT,
// extn2 TEXT,
// extn3 TEXT,
// extn4 TEXT,
// extn5 TEXT,
// extn6 TEXT,
// extn7 TEXT,
// extn8 TEXT,
// extn9 TEXT,
// extn10 TEXT,
// extn11 TEXT,
// extn12 TEXT,
// extn13 TEXT,
// extn14 TEXT,
// extn15 TEXT,
// active INTEGER,
// description TEXT,
// $fieldName TEXT
// )''');
// } else {
// print('$tableName table exist');
// }
// }
// Future<bool> _isTableExists(Database db, String tableName) async {
// var result = await db.rawQuery(
// 'SELECT * FROM sqlite_master WHERE type = ? AND name = ?',
// ['table', tableName],
// );
// return result.isNotEmpty;
// }
}
+100
View File
@@ -0,0 +1,100 @@
import 'package:sqflite/sqflite.dart';
class TableQuery {
Future<void> createOtherTable(Database db) async {
// Table Query
// OLD: _createGauravt2(db, 'Gauravt2'); // demo table from old template - disabled for clean base - by Azmat
// OLD: _createGauravtest1(db, 'Gauravtest1'); // demo table from old template - disabled for clean base - by Azmat
}
// Table Query Data
Future<void> _createGauravt2(Database db, String tableName) async {
var tableExists = await _isTableExists(db, tableName);
if (!tableExists) {
print('$tableName making.....');
await db.execute(
'''
CREATE TABLE $tableName (
id INTEGER PRIMARY KEY AUTOINCREMENT,
accountId TEXT,
createdAt TEXT,
createdBy TEXT,
updatedAt TEXT,
updatedBy TEXT,
extn1 TEXT,
extn2 TEXT,
extn3 TEXT,
extn4 TEXT,
extn5 TEXT,
extn6 TEXT,
extn7 TEXT,
extn8 TEXT,
extn9 TEXT,
extn10 TEXT,
extn11 TEXT,
extn12 TEXT,
extn13 TEXT,
extn14 TEXT,
extn15 TEXT,
phone TEXT,
nme TEXT,
imageupload TEXT,
)''');
} else {
print('$tableName table exist');
}
}
Future<void> _createGauravtest1(Database db, String tableName) async {
var tableExists = await _isTableExists(db, tableName);
if (!tableExists) {
print('$tableName making.....');
await db.execute(
'''
CREATE TABLE $tableName (
id INTEGER PRIMARY KEY AUTOINCREMENT,
accountId TEXT,
createdAt TEXT,
createdBy TEXT,
updatedAt TEXT,
updatedBy TEXT,
extn1 TEXT,
extn2 TEXT,
extn3 TEXT,
extn4 TEXT,
extn5 TEXT,
extn6 TEXT,
extn7 TEXT,
extn8 TEXT,
extn9 TEXT,
extn10 TEXT,
extn11 TEXT,
extn12 TEXT,
extn13 TEXT,
extn14 TEXT,
extn15 TEXT,
college TEXT,
Name TEXT,
)''');
} else {
print('$tableName table exist');
}
}
Future<bool> _isTableExists(Database db, String tableName) async {
var result = await db.rawQuery(
'SELECT * FROM sqlite_master WHERE type = ? AND name = ?',
['table', tableName],
);
return result.isNotEmpty;
}
}
+97
View File
@@ -0,0 +1,97 @@
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
// OLD: import 'databasehelper.dart'; // wrong case fails on Linux Docker - by Azmat
import 'DatabaseHelper.dart'; // fixed case capital D+H for Linux build - by Azmat
class UniController {
final conn = DatabaseHelper.instance;
// get entity
Future<List<Map<String, dynamic>>> getentities(String tableName) async {
Database db = await conn.database;
return await db.query(tableName);
}
// insert
Future<int> insertEntity(
Map<String, dynamic> entity, String tableName) async {
Database db = await conn.database;
// entity['active'] = entity['active'] ? 1 : 0;
// Insert data
var entityId = await db.insert(tableName, entity);
if (entityId != null && entityId > 0) {
print('$tableName Id data is inserted. $tableName Id ID: $entityId');
} else {
print('Failed to insert $tableName.');
}
return entityId;
}
// insert multiple table
Future<void> insertEntities(
List<Map<String, dynamic>> entities, String tableName) async {
Database db = await conn.database;
Batch batch = db.batch();
print('multiple entity is com is $entities');
for (var entity in entities) {
insertEntity(entity, tableName);
}
await batch.commit();
}
// update Entity
Future<int> update(String tableName, int entityId,
Map<String, dynamic> updatedEntity) async {
Database db = await conn.database;
int rowsAffected = await db.update(tableName, updatedEntity,
where: 'id = ?', whereArgs: [entityId]);
if (rowsAffected > 0) {
print('$tableName data updated successfully.');
} else {
print('Failed to update $tableName data.');
}
return rowsAffected;
}
// Deleting entity
Future<int> delete(String tableName, int entityId) async {
Database db = await conn.database;
// Delete the company
int rowsAffected =
await db.delete(tableName, where: 'id = ?', whereArgs: [entityId]);
if (rowsAffected > 0) {
print('$tableName data deleted successfully.');
} else {
print('Failed to delete comp $tableName any data.');
}
return rowsAffected;
}
// get count
Future<int> getDataCount(String tableNmae) async {
Database db = await conn.database;
// Get the count of rows in the company table
int count = Sqflite.firstIntValue(
await db.rawQuery('SELECT COUNT(*) FROM $tableNmae'))!
.toInt();
print('Number of $tableNmae in the table: $count');
return count;
}
}
+168
View File
@@ -0,0 +1,168 @@
// import 'dart:io';
// import 'package:connectivity/connectivity.dart';
// import 'package:sqflite_common_ffi/sqflite_ffi.dart';
// import '../../providers/token_manager.dart';
// import '../../resources/api_constants.dart';
// import 'UniController.dart';
// import 'companycontroller.dart';
// import 'databasehelper.dart';
// class LocalSyncronizationData {
// final String baseUrl = ApiConstants.baseUrl;
// final UniController uniController = UniController();
// final companycontroller companyController = companycontroller();
// final conn = DatabaseHelper.instance;
// static Future<bool> isInternet() async {
// var connectivityResult = await (Connectivity().checkConnectivity());
// if (connectivityResult == ConnectivityResult.mobile) {
// final result = await InternetAddress.lookup('www.google.com');
// if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
// print('mobile network connected');
// return true;
// } else {
// return false;
// }
// // if (await DataConnectionChecker().hasConnection) {
// // print("Mobile data detected & internet connection confirmed.");
// // return true;
// // }else{
// // print('No internet :( Reason:');
// // return false;
// // }
// } else if (connectivityResult == ConnectivityResult.wifi) {
// final result = await InternetAddress.lookup('www.google.com');
// if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
// print('wifi connected');
// return true;
// } else {
// print('wifi not connected');
// return false;
// }
// } else {
// print(
// "Neither mobile data or WIFI detected, not internet connection found.");
// return false;
// }
// }
// // Future saveCompanyToMysql() async {
// // Database db = await conn.database;
// // final token = await TokenManager.getToken();
// // print('company db is $db');
// // final List<Map<String, dynamic>> localEntities =
// // await db.query('company', orderBy: 'id DESC');
// // if (localEntities.isNotEmpty) {
// // final entities = (localEntities).cast<Map<String, dynamic>>();
// // for (var element in entities) {
// // companyService.createEntity1(token!, element);
// // }
// // }
// // }
// // for research status sync
// Future fetchResearchStatusData() async {
// List userList = [];
// Database db = await conn.database;
// try {
// final List<Map<String, dynamic>> localEntities =
// await db.query('research_status', orderBy: 'id DESC');
// if (localEntities.isNotEmpty) {
// final entities = (localEntities).cast<Map<String, dynamic>>();
// for (var element in entities) {
// userList.add(element);
// }
// }
// } catch (e) {
// print(e.toString());
// }
// return userList;
// }
// Future<List<Map<String, dynamic>>> fetchAllInfo() async {
// Database db = await conn.database;
// List<Map<String, dynamic>> researchList = [];
// try {
// final maps = await db.query('research_status');
// for (var item in maps!) {
// researchList.add(item);
// }
// } catch (e) {
// print(e.toString());
// }
// return researchList;
// }
// Future saveReserachToMysql(List researchList) async {
// final token = await TokenManager.getToken();
// for (var i = 0; i < researchList.length; i++) {
// Map<String, dynamic> data = {
// "id": researchList[i]['id'].toString(),
// "status_name": researchList[i]['status_name'],
// "description": researchList[i]['description'],
// "active": researchList[i]['active'],
// };
// final response = researchService.createEntity1(token!, data);
// print('eserach res is $response');
// }
// }
// // from online to offline for research status
// Future fetchResearchStatusDataOnline() async {
// List userList = [];
// Database db = await conn.database;
// final token = await TokenManager.getToken();
// try {
// final List<Map<String, dynamic>> entities =
// await researchService.getEntities1(token!);
// if (entities.isNotEmpty) {
// for (var element in entities) {
// userList.add(element);
// }
// }
// } catch (e) {
// print(e.toString());
// }
// return userList;
// }
// Future<List<Map<String, dynamic>>> fetchReserachOnlineInfo() async {
// Database db = await conn.database;
// List<Map<String, dynamic>> researchList = [];
// final token = await TokenManager.getToken();
// try {
// final List<Map<String, dynamic>> maps =
// await researchService.getEntities1(token!);
// for (var item in maps!) {
// researchList.add(item);
// }
// } catch (e) {
// print(e.toString());
// }
// return researchList;
// }
// Future saveReserachToMysqlOnline(List list) async {
// for (var element in list) {
// uniController.insertEntity(element, 'research_status');
// }
// }
// }
+167
View File
@@ -0,0 +1,167 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class ColorConstant {
static Color gray5001 = fromHex('#f6f7fb');
static Color gray5002 = fromHex('#f8f9fa');
static Color black900B2 = fromHex('#b2000000');
static Color gray5003 = fromHex('#fafcff');
static Color lightBlue100 = fromHex('#b0e5fc');
static Color gray80049 = fromHex('#493c3c43');
static Color yellow9003f = fromHex('#3feb9612');
static Color red200 = fromHex('#fa9a9a');
static Color gray4004c = fromHex('#4cc4c4c4');
static Color blueA200 = fromHex('#468ee5');
static Color greenA100 = fromHex('#b5eacd');
static Color black9003f = fromHex('#3f000000');
static Color gray30099 = fromHex('#99e4e4e4');
static Color black90087 = fromHex('#87000000');
static Color whiteA70099 = fromHex('#99ffffff');
static Color black90001 = fromHex('#000000');
static Color blueGray90002 = fromHex('#24363c');
static Color blueGray90001 = fromHex('#2e3637');
static Color blueGray700 = fromHex('#535763');
static Color blueGray900 = fromHex('#262b35');
static Color black90003 = fromHex('#0b0a0a');
static Color black90002 = fromHex('#090b0d');
static Color redA700 = fromHex('#d80027');
static Color black90004 = fromHex('#000000');
static Color gray400 = fromHex('#c4c4c4');
static Color blue900 = fromHex('#003399');
static Color blueGray100 = fromHex('#d6dae2');
static Color blue700 = fromHex('#1976d2');
static Color blueGray300 = fromHex('#9ea8ba');
static Color amber500 = fromHex('#feb909');
static Color redA200 = fromHex('#fe555d');
static Color gray80099 = fromHex('#993c3c43');
static Color black9000c = fromHex('#0c000000');
static Color gray200 = fromHex('#efefef');
static Color gray60026 = fromHex('#266d6d6d');
static Color blue50 = fromHex('#e0ebff');
static Color indigo400 = fromHex('#4168d7');
static Color blueGray1006c = fromHex('#6cd1d3d4');
static Color black90011 = fromHex('#11000000');
static Color gray40001 = fromHex('#b3b3b3');
static Color whiteA70067 = fromHex('#67ffffff');
static Color gray10001 = fromHex('#fbf1f2');
static Color black90019 = fromHex('#19000000');
static Color blueGray40001 = fromHex('#888888');
static Color whiteA700 = fromHex('#ffffff');
static Color blueGray50 = fromHex('#eaecf0');
static Color red700 = fromHex('#d03329');
static Color blueA700 = fromHex('#0061ff');
static Color blueGray10001 = fromHex('#d6d6d6');
static Color gray60019 = fromHex('#197e7e7e');
static Color green600 = fromHex('#349765');
static Color blueA70001 = fromHex('#0068ff');
static Color gray50 = fromHex('#f9fbff');
static Color red100 = fromHex('#f6d6d4');
static Color blueGray20001 = fromHex('#adb5bd');
static Color black900 = fromHex('#000919');
static Color blueGray800 = fromHex('#37334d');
static Color blue5001 = fromHex('#eef4ff');
static Color deepOrange400 = fromHex('#d58c48');
static Color deepOrangeA400 = fromHex('#ff4b00');
static Color gray70011 = fromHex('#11555555');
static Color indigoA20033 = fromHex('#334871e3');
static Color gray90002 = fromHex('#0d062d');
static Color gray700 = fromHex('#666666');
static Color blueGray200 = fromHex('#bac1ce');
static Color blueGray400 = fromHex('#74839d');
static Color blue800 = fromHex('#2953c7');
static Color blueGray600 = fromHex('#5f6c86');
static Color gray900 = fromHex('#2a2a2a');
static Color gray90001 = fromHex('#212529');
static Color gray300 = fromHex('#d2efe0');
static Color gray30001 = fromHex('#e3e4e5');
static Color gray100 = fromHex('#f3f4f5');
static Color black90075 = fromHex('#75000000');
static Color deepOrangeA10033 = fromHex('#33dfa874');
static Color gray70026 = fromHex('#26555555');
static Color black90033 = fromHex('#33000000');
static Color blue200 = fromHex('#a6c8ff');
static Color fromHex(String hexString) {
final buffer = StringBuffer();
if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
buffer.write(hexString.replaceFirst('#', ''));
return Color(int.parse(buffer.toString(), radix: 16));
}
}
+465
View File
@@ -0,0 +1,465 @@
class ImageConstant {
//cloudnsuresp.svg
static String imgLogoSplash =
'assets/images/cloudnsuresp.svg';
static String imgRectangle458706x396 =
'assets/images/img_rectangle458_706x396.png';
static String imgVscodeiconsfiletypeexcel =
'assets/images/img_vscodeiconsfiletypeexcel.svg';
static String imgGroup10737 = 'assets/images/img_group10737.svg';
static String imgX32locationRed700 =
'assets/images/img_x32location_red_700.svg';
static String imgCar = 'assets/images/img_car.svg';
static String imgArrowrightWhiteA700 =
'assets/images/img_arrowright_white_a700.svg';
static String imgMinussolid = 'assets/images/img_minussolid.svg';
static String imgSearchWhiteA70020x20 =
'assets/images/img_search_white_a700_20x20.svg';
static String imgSettings24x24 = 'assets/images/img_settings_24x24.svg';
static String imgArrowgrowthsolidRed700 =
'assets/images/img_arrowgrowthsolid_red_700.svg';
static String imgPlus1 = 'assets/images/img_plus_1.svg';
static String imgArrowupBlueGray400 =
'assets/images/img_arrowup_blue_gray_400.svg';
static String imgTwitter20x20 = 'assets/images/img_twitter_20x20.svg';
static String imgClose18x18 = 'assets/images/img_close_18x18.svg';
static String imgRectangle102x1021 =
'assets/images/img_rectangle_102x102_1.png';
static String imgRectangle1 = 'assets/images/img_rectangle1.png';
static String imgGrid = 'assets/images/img_grid.svg';
static String imgClose24x24 = 'assets/images/img_close_24x24.svg';
static String imgRefresh = 'assets/images/img_refresh.svg';
static String imgPlus40x40 = 'assets/images/img_plus_40x40.svg';
static String imgVectorBlueA70034x360 =
'assets/images/img_vector_blue_a700_34x360.svg';
static String imgMenu1 = 'assets/images/img_menu_1.svg';
static String imgInfo = 'assets/images/img_info.svg';
static String imgFile24x24 = 'assets/images/img_file_24x24.svg';
static String imgVector = 'assets/images/img_vector.svg';
static String imgArrowleft = 'assets/images/img_arrowleft.svg';
static String imgGroup9839 = 'assets/images/img_group9839.svg';
static String imgImage125 = 'assets/images/img_image125.png';
static String imgWordpresslogo1 = 'assets/images/img_wordpresslogo1.png';
static String imgRectangle126x1266 =
'assets/images/img_rectangle_126x126_6.png';
static String imgArrowdown = 'assets/images/img_arrowdown.svg';
static String imgGroup10785 = 'assets/images/img_group10785.svg';
static String imgContrast = 'assets/images/img_contrast.svg';
static String imgLinkedin = 'assets/images/img_linkedin.svg';
static String imgClose = 'assets/images/img_close.svg';
static String imgMusic = 'assets/images/img_music.svg';
static String imgLock = 'assets/images/img_lock.svg';
static String imgEllipse1224x241 = 'assets/images/img_ellipse12_24x24_1.png';
static String img8148x48 = 'assets/images/img_81_48x48.png';
static String imgProfileimglarge40x404 =
'assets/images/img_profileimglarge_40x40_4.png';
static String imgMenu = 'assets/images/img_menu.svg';
static String imgFile16x16 = 'assets/images/img_file_16x16.svg';
static String imgRefresh24x24 = 'assets/images/img_refresh_24x24.svg';
static String imgChartsmicroBlue5045x150 =
'assets/images/img_chartsmicro_blue_50_45x150.svg';
static String imgSearchBlueGray400 =
'assets/images/img_search_blue_gray_400.svg';
static String imgSort = 'assets/images/img_sort.svg';
static String imgDownload = 'assets/images/img_download.svg';
static String imgClock = 'assets/images/img_clock.svg';
static String imgSettings1 = 'assets/images/img_settings_1.svg';
static String imgPic50x503 = 'assets/images/img_pic_50x50_3.png';
static String imgRectangle1314190x3962 =
'assets/images/img_rectangle1314_190x396_2.png';
static String imgFacebook = 'assets/images/img_facebook.svg';
static String imgRectangle116x161 =
'assets/images/img_rectangle1_16x16_1.png';
static String imgFlagargentina1 = 'assets/images/img_flagargentina1.png';
static String imgFingerprint = 'assets/images/img_fingerprint.svg';
static String imgGoogleadsenselogo =
'assets/images/img_googleadsenselogo.png';
static String imgRectangle116x16 = 'assets/images/img_rectangle1_16x16.png';
static String imgArrowrightBlueGray400 =
'assets/images/img_arrowright_blue_gray_400.svg';
static String imgPic44x44 = 'assets/images/img_pic_44x44.png';
static String imgAppstoreicon = 'assets/images/img_appstoreicon.png';
static String imgChart = 'assets/images/img_chart.png';
static String imgArrowright = 'assets/images/img_arrowright.svg';
static String imgRupaylogo1 = 'assets/images/img_rupaylogo1.png';
static String imgRectangle126x1267 =
'assets/images/img_rectangle_126x126_7.png';
static String imgProfileimglarge25 =
'assets/images/img_profileimglarge_25.png';
static String imgRectangle126x1261 =
'assets/images/img_rectangle_126x126_1.png';
static String imgEllipse1524x24 = 'assets/images/img_ellipse15_24x24.png';
static String imgPic3 = 'assets/images/img_pic_3.png';
static String imgPic50x502 = 'assets/images/img_pic_50x50_2.png';
static String imgPic4 = 'assets/images/img_pic_4.png';
static String imgRupaylogo118x56 = 'assets/images/img_rupaylogo1_18x56.png';
static String imgEllipse360x602 = 'assets/images/img_ellipse3_60x60_2.png';
static String imgUser24x24 = 'assets/images/img_user_24x24.svg';
static String imgImage123 = 'assets/images/img_image123.png';
static String imgArrowrightBlueGray6001 =
'assets/images/img_arrowright_blue_gray_600_1.svg';
static String imgUser = 'assets/images/img_user.svg';
static String imgGlobeYellow80018x18 =
'assets/images/img_globe_yellow_800_18x18.svg';
static String imgPic1 = 'assets/images/img_pic_1.png';
static String imgGlobe = 'assets/images/img_globe.svg';
static String imgCalendarBlueGray400 =
'assets/images/img_calendar_blue_gray_400.svg';
static String imgClose53x53 = 'assets/images/img_close_53x53.svg';
static String imgDashboard = 'assets/images/img_dashboard.svg';
static String imgRectangle126x1263 =
'assets/images/img_rectangle_126x126_3.png';
static String imgAirplaneBlack900 =
'assets/images/img_airplane_black_900.svg';
static String imgForward = 'assets/images/img_forward.svg';
static String imgGroup10210 = 'assets/images/img_group10210.svg';
static String imgShare24x24 = 'assets/images/img_share_24x24.svg';
static String imgLightbulb = 'assets/images/img_lightbulb.svg';
static String imgSearchBlueGray900 =
'assets/images/img_search_blue_gray_900.svg';
static String imgImage122 = 'assets/images/img_image122.png';
static String imgPic44x441 = 'assets/images/img_pic_44x44_1.png';
static String imgSignal10x56 = 'assets/images/img_signal_10x56.svg';
static String imgUiiconmoonlight = 'assets/images/img_uiiconmoonlight.svg';
static String img1200pxpdffileicon =
'assets/images/img_1200pxpdffileicon.png';
static String imgSettings = 'assets/images/img_settings.svg';
static String imgChartsmicroBlue501 =
'assets/images/img_chartsmicro_blue_50_1.svg';
static String imgArrowdownBlueGray200 =
'assets/images/img_arrowdown_blue_gray_200.svg';
static String imgGlobeWhiteA700 = 'assets/images/img_globe_white_a700.svg';
static String imgFire = 'assets/images/img_fire.svg';
static String imgVector3Gray90001 =
'assets/images/img_vector3_gray_900_01.svg';
static String imgEllipse5150x150 = 'assets/images/img_ellipse5_150x150.png';
static String imgClose32x48 = 'assets/images/img_close_32x48.svg';
static String imgArrowdownBlueGray600 =
'assets/images/img_arrowdown_blue_gray_600.svg';
static String imgCheckmark16x16 = 'assets/images/img_checkmark_16x16.svg';
static String imgCheckmarkGreen600 =
'assets/images/img_checkmark_green_600.svg';
static String imgArrowrightBlueGray600 =
'assets/images/img_arrowright_blue_gray_600.svg';
static String imgSearchBlueGray200 =
'assets/images/img_search_blue_gray_200.svg';
static String imgRectangle126x1262 =
'assets/images/img_rectangle_126x126_2.png';
static String imgCalendar24x24 = 'assets/images/img_calendar_24x24.svg';
static String imgVectorRed600 = 'assets/images/img_vector_red_600.svg';
static String imgSignal = 'assets/images/img_signal.svg';
static String imgProfileimglarge40x403 =
'assets/images/img_profileimglarge_40x40_3.png';
static String imgLinkedin11 = 'assets/images/img_linkedin_1_1.svg';
static String imgPlay = 'assets/images/img_play.svg';
static String imgUpload = 'assets/images/img_upload.svg';
static String imgEllipse1224x242 = 'assets/images/img_ellipse12_24x24_2.png';
static String imgMap = 'assets/images/img_map.svg';
static String imgLock24x24 = 'assets/images/img_lock_24x24.svg';
static String imgRectangle458530x396 =
'assets/images/img_rectangle458_530x396.png';
static String imgEllipse5418x18 = 'assets/images/img_ellipse54_18x18.png';
static String imgGroup10720 = 'assets/images/img_group10720.svg';
static String imgNotification = 'assets/images/img_notification.svg';
static String imgSignalGray500 = 'assets/images/img_signal_gray_500.svg';
static String imgRectangle126x1265 =
'assets/images/img_rectangle_126x126_5.png';
static String imgMobile = 'assets/images/img_mobile.svg';
static String imgArrowdownBlueGray400 =
'assets/images/img_arrowdown_blue_gray_400.svg';
static String imgEllipse28 = 'assets/images/img_ellipse28.png';
static String imgGroup185 = 'assets/images/img_group185.svg';
static String imgCheck1 = 'assets/images/img_check1.png';
static String imgPic44x443 = 'assets/images/img_pic_44x44_3.png';
static String imgPic50x501 = 'assets/images/img_pic_50x50_1.png';
static String imgVolume = 'assets/images/img_volume.svg';
static String imgSearch = 'assets/images/img_search.svg';
static String imgMail = 'assets/images/img_mail.svg';
static String imgGlobeYellow800 = 'assets/images/img_globe_yellow_800.svg';
static String imgGlobe18x18 = 'assets/images/img_globe_18x18.svg';
static String imgBluetoothbsolid = 'assets/images/img_bluetoothbsolid.svg';
static String imgFile = 'assets/images/img_file.svg';
static String imgSearchWhiteA700 = 'assets/images/img_search_white_a700.svg';
static String imgFile26x26 = 'assets/images/img_file_26x26.svg';
static String imgPlusWhiteA700 = 'assets/images/img_plus_white_a700.svg';
static String imgEdit = 'assets/images/img_edit.svg';
static String imgRectangle126x1268 =
'assets/images/img_rectangle_126x126_8.png';
static String imgWhatsapp = 'assets/images/img_whatsapp.svg';
static String imgCall = 'assets/images/img_call.svg';
static String imgLocation = 'assets/images/img_location.svg';
static String imgGroup10451 = 'assets/images/img_group10451.svg';
static String imgGroup97 = 'assets/images/img_group97.svg';
static String imgEllipse6624x24 = 'assets/images/img_ellipse66_24x24.png';
static String imgStar = 'assets/images/img_star.svg';
static String imgCheckmark = 'assets/images/img_checkmark.svg';
static String imgTwitter = 'assets/images/img_twitter.svg';
static String img2560pxstripel = 'assets/images/img_2560pxstripel.png';
static String imgSportscricket = 'assets/images/img_sportscricket.svg';
static String imgOverflowmenuWhiteA700 =
'assets/images/img_overflowmenu_white_a700.svg';
static String imgGoogle = 'assets/images/img_google.svg';
static String imgFrame9880 = 'assets/images/img_frame9880.svg';
static String imgVectorBlueA70013x141 =
'assets/images/img_vector_blue_a700_13x141.svg';
static String imgTicket = 'assets/images/img_ticket.svg';
static String imgSmartwatchwhitesportband =
'assets/images/img_smartwatchwhitesportband.svg';
static String imgProfileimglarge40x402 =
'assets/images/img_profileimglarge_40x40_2.png';
static String imgPic = 'assets/images/img_pic.png';
static String imgEllipse1324x252 = 'assets/images/img_ellipse13_24x25_2.png';
static String imgOverflowmenu1 = 'assets/images/img_overflowmenu_1.svg';
static String imgFlagargentina11 = 'assets/images/img_flagargentina1_1.png';
static String imgGlobeWhiteA70018x18 =
'assets/images/img_globe_white_a700_18x18.svg';
static String imgEye = 'assets/images/img_eye.svg';
static String imgSearchBlueA700 = 'assets/images/img_search_blue_a700.svg';
static String imgPic2 = 'assets/images/img_pic_2.png';
static String imgQuestion = 'assets/images/img_question.svg';
static String imgMicrophone20x20 = 'assets/images/img_microphone_20x20.svg';
static String imgEllipse1324x251 = 'assets/images/img_ellipse13_24x25_1.png';
static String imgCheckmark56x56 = 'assets/images/img_checkmark_56x56.svg';
static String imgTicket20x20 = 'assets/images/img_ticket_20x20.svg';
static String imgLocation20x20 = 'assets/images/img_location_20x20.svg';
static String imgFlagargentina132x48 =
'assets/images/img_flagargentina1_32x48.png';
static String imgTrash = 'assets/images/img_trash.svg';
static String imgProfileimglarge40x401 =
'assets/images/img_profileimglarge_40x40_1.png';
static String imgCalendar = 'assets/images/img_calendar.svg';
static String imgEllipse2718x18 = 'assets/images/img_ellipse27_18x18.png';
static String imgSearchBlueA100 = 'assets/images/img_search_blue_a100.svg';
static String imgPic44x442 = 'assets/images/img_pic_44x44_2.png';
static String imgImage124 = 'assets/images/img_image124.png';
static String imgCheckbox = 'assets/images/img_checkbox.svg';
static String imgCompanylogo = 'assets/images/img_companylogo.png';
static String imgMinimize = 'assets/images/img_minimize.svg';
static String imgGroup1830 = 'assets/images/img_group1830.svg';
static String imgMicrophone = 'assets/images/img_microphone.svg';
static String imgArrowupGreen600 = 'assets/images/img_arrowup_green_600.svg';
static String img1200pxdocxicon = 'assets/images/img_1200pxdocxicon.png';
static String imgRectangle126x1264 =
'assets/images/img_rectangle_126x126_4.png';
static String imgMoonoutline = 'assets/images/img_moonoutline.svg';
static String imgUnsplashenrurz62wui50x50 =
'assets/images/img_unsplashenrurz62wui_50x50.png';
static String imgEllipse360x601 = 'assets/images/img_ellipse3_60x60_1.png';
static String imgQuestion24x24 = 'assets/images/img_question_24x24.svg';
static String imgArrowrightBlueA7001 =
'assets/images/img_arrowright_blue_a700_1.svg';
static String imgLock53x53 = 'assets/images/img_lock_53x53.svg';
static String imgOverflowmenu16x16 =
'assets/images/img_overflowmenu_16x16.svg';
static String imgBrightness = 'assets/images/img_brightness.svg';
static String imgArrowleftBlueGray900 =
'assets/images/img_arrowleft_blue_gray_900.svg';
static String imgGroup2507 = 'assets/images/img_group2507.svg';
static String imgOverflowmenu = 'assets/images/img_overflowmenu.svg';
static String imageNotFound = 'assets/images/image_not_found.png';
}
+120
View File
@@ -0,0 +1,120 @@
import 'package:flutter/material.dart';
// This is where the magic happens.
// This functions are responsible to make UI responsive across all the mobile devices.
Size size = WidgetsBinding.instance.window.physicalSize /
WidgetsBinding.instance.window.devicePixelRatio;
// Caution! If you think these are static values and are used to build a static UI, you mustnt.
// These are the Viewport values of your Figma Design.
// These are used in the code as a reference to create your UI Responsively.
const num FIGMA_DESIGN_WIDTH = 428;
const num FIGMA_DESIGN_HEIGHT = 926;
const num FIGMA_DESIGN_STATUS_BAR = 47;
///This method is used to get device viewport width.
get width {
return size.width;
}
///This method is used to get device viewport height.
get height {
num statusBar =
MediaQueryData.fromWindow(WidgetsBinding.instance.window).viewPadding.top;
num bottomBar = MediaQueryData.fromWindow(WidgetsBinding.instance.window)
.viewPadding
.bottom;
num screenHeight = size.height - statusBar - bottomBar;
return screenHeight;
}
///This method is used to set padding/margin (for the left and Right side) & width of the screen or widget according to the Viewport width.
double getHorizontalSize(double px) {
return ((px * width) / FIGMA_DESIGN_WIDTH);
}
///This method is used to set padding/margin (for the top and bottom side) & height of the screen or widget according to the Viewport height.
double getVerticalSize(double px) {
return ((px * height) / (FIGMA_DESIGN_HEIGHT - FIGMA_DESIGN_STATUS_BAR));
}
///This method is used to set smallest px in image height and width
double getSize(double px) {
var height = getVerticalSize(px);
var width = getHorizontalSize(px);
if (height < width) {
return height.toInt().toDouble();
} else {
return width.toInt().toDouble();
}
}
///This method is used to set text font size according to Viewport
double getFontSize(double px) {
return getSize(px);
}
///This method is used to set padding responsively
EdgeInsetsGeometry getPadding({
double? all,
double? left,
double? top,
double? right,
double? bottom,
}) {
return getMarginOrPadding(
all: all,
left: left,
top: top,
right: right,
bottom: bottom,
);
}
///This method is used to set margin responsively
EdgeInsetsGeometry getMargin({
double? all,
double? left,
double? top,
double? right,
double? bottom,
}) {
return getMarginOrPadding(
all: all,
left: left,
top: top,
right: right,
bottom: bottom,
);
}
///This method is used to get padding or margin responsively
EdgeInsetsGeometry getMarginOrPadding({
double? all,
double? left,
double? top,
double? right,
double? bottom,
}) {
if (all != null) {
left = all;
top = all;
right = all;
bottom = all;
}
return EdgeInsets.only(
left: getHorizontalSize(
left ?? 0,
),
top: getVerticalSize(
top ?? 0,
),
right: getHorizontalSize(
right ?? 0,
),
bottom: getVerticalSize(
bottom ?? 0,
),
);
}
Binary file not shown.
@@ -0,0 +1,50 @@
import 'package:dio/dio.dart';
import '../../resources/api_constants.dart';
class DashboardBuilderApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
Future<List<Map<String, dynamic>>> getEntities(String token) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/Dashboard/Dashboard');
final entities = (response.data as List).cast<Map<String, dynamic>>();
return entities;
} catch (e) {
throw Exception('Failed to get all entities: $e');
}
}
Future<void> createEntity(String token, Map<String, dynamic> entity) async {
try {
print("in post api" + entity.toString());
dio.options.headers['Authorization'] = 'Bearer $token';
await dio.post('$baseUrl/Dashboard/Dashboard', data: entity);
print(entity);
} catch (e) {
throw Exception('Failed to create entity: $e');
}
}
Future<void> updateEntity(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
await dio.put('$baseUrl/Dashboard/Dashboard/$entityId', data: entity);
print(entity);
} catch (e) {
throw Exception('Failed to update entity: $e');
}
}
Future<void> deleteEntity(String token, int entityId) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
await dio.delete('$baseUrl/Dashboard/Dashboard/$entityId');
} catch (e) {
throw Exception('Failed to delete entity: $e');
}
}
}
@@ -0,0 +1,119 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../providers/token_manager.dart';
import 'Dashboard_api_service.dart';
class CreateEntityScreen extends StatefulWidget {
const CreateEntityScreen({super.key});
@override
_CreateEntityScreenState createState() => _CreateEntityScreenState();
}
class _CreateEntityScreenState extends State<CreateEntityScreen> {
final DashboardBuilderApiService apiService = DashboardBuilderApiService();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
bool isisdashboard = false;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Create Dashboard')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(labelText: 'name'),
onSaved: (value) => formData['name'] = value,
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'model'),
onSaved: (value) => formData['model'] = value,
),
const SizedBox(height: 16),
Switch(
value: isisdashboard,
onChanged: (newValue) {
setState(() {
isisdashboard = newValue;
});
},
),
const SizedBox(width: 8),
const Text('isdashboard'),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
formData['isdashboard'] = isisdashboard;
final token = await TokenManager.getToken();
try {
print("token is : $token");
print(formData);
await apiService.createEntity(token!, formData);
Navigator.pop(context);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to create entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
},
child: const SizedBox(
width: double.infinity,
height: 50,
child: const Center(
child: Text(
'SUBMIT',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
],
),
),
),
),
);
}
}
@@ -0,0 +1,303 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:flutter/services.dart';
import '../../providers/token_manager.dart';
import 'Dashboard_api_service.dart';
import 'Dashboard_create_entity_screen.dart';
import 'Dashboard_update_entity_screen.dart';
class dashboard_entity_list_screen extends StatefulWidget {
static const String routeName = '/entity-list';
@override
_dashboard_entity_list_screenState createState() =>
_dashboard_entity_list_screenState();
}
class _dashboard_entity_list_screenState
extends State<dashboard_entity_list_screen> {
final DashboardBuilderApiService apiService = DashboardBuilderApiService();
List<Map<String, dynamic>> entities = [];
bool showCardView = true; // Add this variable to control the view mode
@override
void initState() {
super.initState();
fetchEntities();
}
Future<void> fetchEntities() async {
try {
final token = await TokenManager.getToken();
if (token != null) {
final fetchedEntities = await apiService.getEntities(token);
setState(() {
entities = fetchedEntities;
});
}
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to fetch entities: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
Future<void> deleteEntity(Map<String, dynamic> entity) async {
try {
final token = await TokenManager.getToken();
await apiService.deleteEntity(token!, entity['id']);
setState(() {
entities.remove(entity);
});
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to delete entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Dashboard List'),
actions: [
// Add a switch in the app bar to toggle between card view and normal view
Switch(
activeColor: Colors.greenAccent,
inactiveThumbColor: Colors.white,
value: showCardView,
onChanged: (value) {
setState(() {
showCardView = value;
});
},
),
],
),
body: entities.isEmpty
? const Center(
child: Text('No entities found.'),
)
: ListView.builder(
itemCount: entities.length,
itemBuilder: (BuildContext context, int index) {
final entity = entities[index];
return _buildListItem(entity);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const CreateEntityScreen(),
),
).then((_) {
fetchEntities();
});
},
child: const Icon(Icons.add),
),
);
}
// Function to build list items
Widget _buildListItem(Map<String, dynamic> entity) {
return showCardView ? _buildCardView(entity) : _buildNormalView(entity);
}
// Function to build card view for a list item
Widget _buildCardView(Map<String, dynamic> entity) {
return Card(
elevation: 2,
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: _buildNormalView(entity));
}
// Function to build normal view for a list item
Widget _buildNormalView(Map<String, dynamic> entity) {
return ListTile(
title: Text(entity['id'].toString()),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(entity['name'] ?? 'No name provided'),
const SizedBox(height: 4),
Text(entity['model'] ?? 'No model provided'),
const SizedBox(height: 4),
Text(entity['isdashboard'].toString() ?? 'No isdashboard provided'),
const SizedBox(height: 4),
// Added address text
],
),
trailing: _buildPopupMenu(entity),
);
}
// Function to build popup menu for a list item
Widget _buildPopupMenu(Map<String, dynamic> entity) {
return PopupMenuButton<String>(
itemBuilder: (BuildContext context) {
return [
const PopupMenuItem<String>(
value: 'edit',
child: Row(
children: [
Icon(Icons.edit),
SizedBox(width: 8),
Text('Edit'),
],
),
),
const PopupMenuItem<String>(
value: 'delete',
child: Row(
children: [
Icon(Icons.delete),
SizedBox(width: 8),
Text('Delete'),
],
),
),
const PopupMenuItem<String>(
value: 'WHO',
child: Row(
children: [
Icon(Icons.manage_accounts_outlined),
SizedBox(width: 8),
Text('WHO'),
],
),
),
];
},
onSelected: (String value) {
if (value == 'edit') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UpdateEntityScreen(entity: entity),
),
).then((_) {
fetchEntities();
});
} else if (value == 'delete') {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Confirm Deletion'),
content:
const Text('Are you sure you want to delete this entity?'),
actions: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Delete'),
onPressed: () {
Navigator.of(context).pop();
deleteEntity(entity);
},
),
],
);
},
);
} else if (value == 'WHO') {
_showAdditionalFieldsDialog(context, entity);
}
},
);
}
// Function to show additional fields in a dialog
void _showAdditionalFieldsDialog(
BuildContext context,
Map<String, dynamic> entity,
) {
final dateFormat =
DateFormat('yyyy-MM-dd HH:mm:ss'); // Define your desired date format
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Additional Fields'),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Created At: ${_formatTimestamp(entity['createdAt'], dateFormat)}'),
Text('Created By: ${entity['createdBy'] ?? 'N/A'}'),
Text('Updated By: ${entity['updatedBy'] ?? 'N/A'}'),
Text(
'Updated At: ${_formatTimestamp(entity['updatedAt'], dateFormat)}'),
Text('Account ID: ${entity['accountId'] ?? 'N/A'}'),
],
),
actions: [
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
String _formatTimestamp(dynamic timestamp, DateFormat dateFormat) {
if (timestamp is int) {
// If it's an integer, assume it's a Unix timestamp in milliseconds
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
return dateFormat.format(dateTime);
} else if (timestamp is String) {
// If it's a string, assume it's already formatted as a date
return timestamp;
} else {
// Handle other cases here if needed
return 'N/A';
}
}
}
@@ -0,0 +1,146 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'dart:math';
import 'package:flutter/services.dart';
import '../../providers/token_manager.dart';
import 'Dashboard_api_service.dart';
class UpdateEntityScreen extends StatefulWidget {
final Map<String, dynamic> entity;
UpdateEntityScreen({required this.entity});
@override
_UpdateEntityScreenState createState() => _UpdateEntityScreenState();
}
class _UpdateEntityScreenState extends State<UpdateEntityScreen> {
final DashboardBuilderApiService apiService = DashboardBuilderApiService();
final _formKey = GlobalKey<FormState>();
bool isisdashboard = false;
@override
void initState() {
super.initState();
isisdashboard = widget.entity['isdashboard'] ?? false; // Set initial value
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Update Dashboard')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
initialValue: widget.entity['name'],
decoration: const InputDecoration(labelText: 'name'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a name';
}
return null;
},
onSaved: (value) {
widget.entity['name'] = value;
},
),
const SizedBox(height: 16),
TextFormField(
initialValue: widget.entity['model'],
decoration: const InputDecoration(labelText: 'model'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a model';
}
return null;
},
onSaved: (value) {
widget.entity['model'] = value;
},
),
const SizedBox(height: 16),
Row(
children: [
Switch(
value: isisdashboard,
onChanged: (newValue) {
setState(() {
isisdashboard = newValue;
});
},
),
const SizedBox(width: 8),
const Text('isdashboard'),
],
),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
widget.entity['isdashboard'] = isisdashboard;
final token = await TokenManager.getToken();
try {
await apiService.updateEntity(
token!,
widget.entity[
'id'], // Assuming 'id' is the key in your entity map
widget.entity);
Navigator.pop(context);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to update entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
},
child: Container(
width: double.infinity,
height: 50,
child: const Center(
child: Text(
'UPDATE',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
],
),
),
),
),
);
}
}
+61
View File
@@ -0,0 +1,61 @@
import 'dart:convert';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class LoginInfoStorage {
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get _userLoginDataFile async {
final path = await _localPath;
return File('$path/hadwin_user_login_info_storage.json');
}
Future<bool> setPersistentLoginData(String userId, String authToken) async {
try {
final file = await _userLoginDataFile;
var ss = file.writeAsString(
jsonEncode({'userId': userId, 'authToken': authToken}));
print('ssss is ..........');
print(ss);
//* THE USER_ID AND AUTHENTICATION_TOKEN HAS BEEN SAVED
return file
.writeAsString(jsonEncode({'userId': userId, 'authToken': authToken}))
.then((value) {
//* THE USER_ID HAS BEEN SAVED
return true;
});
} catch (e) {
//* THE USER_ID AND AUTHENTICATION_TOKEN COULD NOT BE SAVED
return false;
}
}
Future<Map<String, dynamic>> get getPersistentLoginData async {
try {
final file = await _userLoginDataFile;
final contents = await file.readAsString();
return jsonDecode(contents);
} catch (e) {
return {'userId': null, 'authToken': null};
}
}
Future<bool> deleteFile() async {
try {
final file = await _userLoginDataFile;
await file.delete();
//* THE LOGIN DATA FILE HAS BEEN DELETED
return true;
} catch (e) {
//* THE LOGIN DATA FILE HAS NOT BEEN DELETED
return false;
}
}
}
+54
View File
@@ -0,0 +1,54 @@
import 'dart:convert';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class UserDataStorage {
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get _userDataFile async {
final path = await _localPath;
return File('$path/hadwin_user_data.json');
}
Future<Map<String, dynamic>> getUserData() async {
try {
final file = await _userDataFile;
final contents = await file.readAsString();
return jsonDecode(contents);
} catch (e) {
return {"localDBError": "unable to parse data"};
}
}
Future<bool> saveUserData(Map<String, dynamic> userData) async {
try {
final file = await _userDataFile;
print('userdata as is ..... ');
print(file.writeAsString(userData as String));
return file.writeAsString(jsonEncode(userData)).then((value) => true);
} catch (e) {
return false;
}
}
Future<bool> deleteFile() async {
try {
final file = await _userDataFile;
await file.delete();
//* THE USER DATA FILE HAS BEEN DELETED
return true;
} catch (e) {
//* THE USER DATA FILE HAS NOT BEEN DELETED
return false;
}
}
}
+31
View File
@@ -0,0 +1,31 @@
library hadwin_components;
export 'resources/api_constants.dart';
//business logic
//components
// export 'components/wallet_screen/available_cards_loading.dart';
export 'screens/settings_screen/credits_loading.dart';
// export 'components/contacts_screen/contacts_loading.dart';
export 'screens/sign_up_screen/sign_up_steps.dart';
//database
//resources
export 'providers/tab_navigation_provider.dart';
//screens
export 'screens/sign_up_screen/sign_up_screen.dart';
//utilities
export 'utilities/slide_right_route.dart';
export 'utilities/make_api_request.dart';
export 'utilities/url_external_launcher.dart';
export 'utilities/custom_date_grouping.dart';
export 'utilities/display_error_alert.dart';
export 'utilities/hadwin_markdown_viewer.dart';
+48
View File
@@ -0,0 +1,48 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import '../Screens/Login Screen/login_screen.dart';
import '../resources/api_constants.dart';
class LogoutButton extends StatefulWidget {
@override
_LogoutButtonState createState() => _LogoutButtonState();
}
class _LogoutButtonState extends State<LogoutButton> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
_logoutUser();
},
child: const Text('Logout'),
);
}
Future<void> _logoutUser() async {
try {
// Perform API logout request here
// Replace `apiLogoutEndpoint` with the actual logout endpoint URL
String logouturl = "${ApiConstants.baseUrl}" + "/token/logout";
var response = await http.post(Uri.parse(logouturl));
// Handle logout success
if (response.statusCode == 200) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const LoginScreen(),
),
);
} else {
// Handle logout failure
// Display an error message or take appropriate action
}
} catch (error) {
// Handle any exceptions or errors that occur during the logout process
}
}
}
+223
View File
@@ -0,0 +1,223 @@
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:sqlite3/sqlite3.dart';
import 'screens/splash_screen/splash_screen.dart';
//const simplePeriodicTask = "simplePeriodicTask";
// void showNotification(String v, FlutterLocalNotificationsPlugin flp) async {
// var android = const AndroidNotificationDetails(
// 'channel id',
// 'channel NAME',
// priority: Priority.high,
// importance: Importance.max,
// );
// var iOS = const IOSNotificationDetails();
// var platform = NotificationDetails(android: android, iOS: iOS);
// await flp.show(0, 'CloudnSure', '$v', platform, payload: 'VIS \n $v');
// }
void main() async {
WidgetsFlutterBinding.ensureInitialized();
print(sqlite3.version);
sqfliteFfiInit();
// Initialize the database factory for sqflite_common_ffi
databaseFactory = databaseFactoryFfi;
//Request notification permissions
// await _requestNotificationPermissions();
// await Workmanager().initialize(callbackDispatcher);
// await Workmanager().registerPeriodicTask(
// "5",
// simplePeriodicTask,
// existingWorkPolicy: ExistingWorkPolicy.replace,
// frequency: const Duration(minutes: 15),
// initialDelay: const Duration(seconds: 5),
// constraints: Constraints(networkType: NetworkType.connected),
// );
runApp(MyApp());
}
// Future<void> _requestNotificationPermissions() async {
// final status = await Permission.notification.request();
// if (status.isGranted) {
// print('Notification permissions granted');
// } else {
// print('Notification permissions denied');
// }
// }
// void callbackDispatcher() {
// Workmanager().executeTask((task, inputData) async {
// FlutterLocalNotificationsPlugin flp = FlutterLocalNotificationsPlugin();
// var android = const AndroidInitializationSettings('@mipmap/ic_launcher');
// var iOS = const IOSInitializationSettings();
// var initSettings = InitializationSettings(android: android, iOS: iOS);
// flp.initialize(initSettings);
// String baseUrl = ApiConstants.baseUrl;
// final apiUrl = '$baseUrl/user_notifications/get_unseen';
// final token = await TokenManager.getToken();
// final response = await http.get(
// Uri.parse(apiUrl),
// headers: {
// 'Authorization': 'Bearer $token',
// 'Content-Type': 'application/json',
// },
// );
// if (response.statusCode <= 209) {
// final List<dynamic> data = jsonDecode(response.body);
// List<Map<String, dynamic>> notifications =
// data.cast<Map<String, dynamic>>();
// notifications.forEach((element) async {
// showNotification(element['notification'], flp);
// int id = element['id'];
// final apiUrl2 = '$baseUrl/user_notifications/seen_success/$id';
// final response2 = await http.get(
// Uri.parse(apiUrl2),
// headers: {
// 'Authorization': 'Bearer $token',
// 'Content-Type': 'application/json',
// },
// );
// if (response2.statusCode <= 209) {
// print("seen request to web success");
// }
// });
// } else {
// print('Failed to fetch data');
// }
// return Future.value(true);
// });
// }
// class MyApp extends StatelessWidget {
// const MyApp({super.key});
//
// @override
// Widget build(BuildContext context) {
// return MaterialApp(
// debugShowCheckedModeBanner: false,
// title: 'Welcome to cloudNsure',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// visualDensity: VisualDensity.adaptivePlatformDensity,
// ),
// home: const LoginScreen(),
// routes: {
// // '/load': (context) => const ProjectListScreen(),
//
//
// },
// );
// }
// }
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
//
// class MyApp extends StatefulWidget {
// const MyApp({Key? key}) : super(key: key);
//
// @override
// _MyAppState createState() => _MyAppState();
// }
//
// class _MyAppState extends State<MyApp> {
//
//
// double getMargin(BuildContext context) {
// // Calculate the margin based on a percentage of screen width
// double screenWidth = MediaQuery.of(context).size.width;
// double marginPercentage = 0.2; // Adjust the percentage as needed
// return screenWidth * marginPercentage;
// }
//
// @override
// Widget build(BuildContext context) {
// return kIsWeb
// ? Container(
// margin: EdgeInsets.symmetric(
// horizontal: getMargin(context),
// ),
// child: MaterialApp(
// navigatorKey: navigatorKey,
// debugShowCheckedModeBanner: false,
// title: 'Welcome to cloudNsure',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// visualDensity: VisualDensity.adaptivePlatformDensity,
// ),
// home:SplashScreen(),
// routes: {
// '/drag': (context) => DragAndDropFormBuilder(
// projId: 11096,
// headerId: 1615,
// moduleId: 12867,
// backendId: 215,
// ),
// '/dash': (context) => Dashboard_screen(
// projId: 12802,
// moduleId: 12811,
// ),
// '/regi': (context) =>
// RegistrationDetailsScreen(email: 'gaurav@dekatc.com'),
// '/user': (context) => CreateUserScreen(),
// '/list': (context) =>
// ListBuilder_screen(projId: 13249, moduleId: 13258),
// '/log': (context) => const LiveLogsScreen(
// containerName: 'sukhantest_realnet_d-mysql',
// ),
// '/farm': (context) => SureFarmContent(projectId: 13261),
// '/g2': (context) => gtest2_entity_list_screen(),
// },
// ),
// )
// : MaterialApp(
// debugShowCheckedModeBanner: false,
// title: 'Welcome to cloudNsure',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// visualDensity: VisualDensity.adaptivePlatformDensity,
// ),
// home: SplashScreen(),
// routes: {
// // '/load': (context) => const ProjectListScreen(),
//
// // '/drag': (context) => DragAndDropFormBuilder(
// // projId: 13249,
// // headerId: 1550,
// // moduleId: 13258,
// // ),
// '/drag': (context) => DragAndDropFormBuilder(
// projId: 11096,
// headerId: 1538,
// moduleId: 12867,
// backendId: 215,
// ),
//
// '/dash': (context) => Dashboard_screen(
// projId: 12802,
// moduleId: 12811,
// ),
// },
// );
// }
// }
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: const SplashScreen(),
routes: {},
theme: ThemeData(
primaryColor: Colors.blue,
appBarTheme: const AppBarTheme(
color: Colors.blue,
),
),
);
}
}
@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
class TabNavigationProvider with ChangeNotifier {
List<int> _tabHistory = [0];
int get lastTab => _tabHistory.last;
void removeLastTab() {
_tabHistory.removeLast();
notifyListeners();
}
void updateTabs(int tab) {
if (tab == 0) {
_tabHistory = [0];
} else {
_tabHistory.removeWhere((element) => element == tab);
_tabHistory.add(tab);
}
notifyListeners();
}
}
+17
View File
@@ -0,0 +1,17 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class TokenManager {
static const storage = FlutterSecureStorage();
static Future<void> setToken(String token) async {
await storage.write(key: 'token', value: token);
}
static Future<String?> getToken() async {
return await storage.read(key: 'token');
}
static Future<void> removeToken() async {
await storage.delete(key: 'token');
}
}
+3
View File
@@ -0,0 +1,3 @@
class ApiConstants {
static const baseUrl = 'http://localhost:9292';
}
BIN
View File
Binary file not shown.
@@ -0,0 +1,106 @@
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
import 'dart:typed_data';
import 'dart:convert';
import '../../resources/api_constants.dart';
import '../LogoutService/Logoutservice.dart';
class ApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
Future<List<Map<String, dynamic>>> getEntities(String token) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/Bookmarks/Bookmarks');
if (response.statusCode == 401) {
LogoutService.logout();
}
final entities = (response.data as List).cast<Map<String, dynamic>>();
return entities;
} catch (e) {
throw Exception('Failed to get all entities: $e');
}
}
Future<void> createEntity(
String token, Map<String, dynamic> fData, dynamic selectedFile) async {
try {
String apiUrl = "$baseUrl/Bookmarks/Bookmarks";
final Uint8List fileBytes = selectedFile.bytes!;
final mimeType = lookupMimeType(selectedFile.name!);
FormData formData = FormData.fromMap({
'file': MultipartFile.fromBytes(
fileBytes,
filename: selectedFile.name!,
contentType: MediaType.parse(mimeType!),
),
'data': jsonEncode(
fData), // Convert the map to JSON and include it as a parameter
});
Dio dio = Dio(); // Create a new Dio instance
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.post(apiUrl, data: formData);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode == 200) {
// Handle successful response
print('File uploaded successfully');
} else {
print('Failed to upload file with status: ${response.statusCode}');
}
} catch (error) {
print('Error occurred during form submission: $error');
}
}
String lookupMimeType(String filePath) {
final ext = filePath.split('.').last;
switch (ext) {
case 'jpg':
case 'jpeg':
return 'image/jpeg';
case 'png':
return 'image/png';
case 'pdf':
return 'application/pdf';
// Add more cases for other file types as needed
default:
return 'application/octet-stream'; // Default MIME type
}
}
Future<void> updateEntity(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response =
await dio.put('$baseUrl/Bookmarks/Bookmarks/$entityId', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to update entity: $e');
}
}
Future<void> deleteEntity(String token, int entityId) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio.delete('$baseUrl/Bookmarks/Bookmarks/$entityId');
if (response.statusCode == 401) {
LogoutService.logout();
}
} catch (e) {
throw Exception('Failed to delete entity: $e');
}
}
}
@@ -0,0 +1,111 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../providers/token_manager.dart';
import 'Bookmarks_api_service.dart';
class CreateEntityScreen extends StatefulWidget {
const CreateEntityScreen({super.key});
@override
_CreateEntityScreenState createState() => _CreateEntityScreenState();
}
class _CreateEntityScreenState extends State<CreateEntityScreen> {
final ApiService apiService = ApiService();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
var selectedFileupload_Field;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Create Bookmarks')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration:
const InputDecoration(labelText: 'bookmark_firstletter'),
onSaved: (value) => formData['bookmark_firstletter'] = value,
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'bookmark_link'),
onSaved: (value) => formData['bookmark_link'] = value,
),
const SizedBox(height: 16),
TextFormField(
decoration:
const InputDecoration(labelText: 'fileupload_field'),
onSaved: (value) => formData['fileupload_field'] = value,
),
const SizedBox(height: 16),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
final token = await TokenManager.getToken();
try {
print("token is : $token");
print(formData);
await apiService.createEntity(
token!, formData, selectedFileupload_Field);
Navigator.pop(context);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to create entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
},
child: Container(
width: double.infinity,
height: 50,
child: const Center(
child: Text(
'SUBMIT',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
],
),
),
),
),
);
}
}
@@ -0,0 +1,562 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_decoration.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import 'Bookmarks_api_service.dart';
import 'package:url_launcher/url_launcher.dart';
class bookmarks_entity_list_screen extends StatefulWidget {
static const String routeName = '/entity-list';
@override
_bookmarks_entity_list_screenState createState() =>
_bookmarks_entity_list_screenState();
}
class _bookmarks_entity_list_screenState
extends State<bookmarks_entity_list_screen> {
final ApiService apiService = ApiService();
List<Map<String, dynamic>> entities = [];
bool showCardView = true; // Add this variable to control the view mode
@override
void initState() {
super.initState();
fetchEntities();
}
Future<void> fetchEntities() async {
try {
final token = await TokenManager.getToken();
if (token != null) {
final fetchedEntities = await apiService.getEntities(token);
setState(() {
entities = fetchedEntities;
});
}
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to fetch entities: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
Future<void> deleteEntity(Map<String, dynamic> entity) async {
try {
final token = await TokenManager.getToken();
await apiService.deleteEntity(token!, entity['id']);
setState(() {
entities.remove(entity);
});
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to delete entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Bookmarks")),
body: entities.isEmpty
? const Center(
child: Text('No BookMarks found.'),
)
: Container(
width: double.maxFinite,
padding: getPadding(left: 16, top: 16, right: 16, bottom: 16),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: getPadding(top: 22),
child: entities.length != 0
? ListView.separated(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
separatorBuilder: (context, index) {
return SizedBox(height: getVerticalSize(24));
},
itemCount: entities.length,
itemBuilder: (context, index) {
Map<String, dynamic> entity = entities[index];
return Container(
width: double.maxFinite,
child: Container(
padding: getPadding(
left: 16,
top: 5,
right: 5,
bottom: 17,
),
decoration: AppDecoration.outlineGray70011
.copyWith(
borderRadius: BorderRadiusStyle
.roundedBorder6,
color: Colors.grey[100]),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Padding(
padding: getPadding(
//right: 13,
),
child: Row(
children: [
Container(
width: MediaQuery.of(context)
.size
.width *
0.30,
// getHorizontalSize(
// 147,
// ),
margin: getMargin(
left: 8,
top: 3,
bottom: 1,
),
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
entity['bookmark_firstletter'] ??
'No bookmark_firstletter provided',
overflow: TextOverflow
.ellipsis,
textAlign:
TextAlign.left,
style: AppStyle
.txtGreenSemiBold16,
),
],
),
),
Spacer(),
// PopupMenuButton<String>(
// icon: Icon(Icons.more_vert,color: Colors.black,size: 16,),
// itemBuilder: (BuildContext context) {
// return [
// PopupMenuItem<String>(
// value: 'edit',
// child: Row(
// children: [
// Icon(
// Icons.edit,
// size: 16, // Adjust the icon size as needed
// ),
// SizedBox(width: 8),
// Text(
// 'Edit',
// style: AppStyle.txtGilroySemiBold16, // Adjust the text size as needed
// ),
// ],
// ),
// ),
// PopupMenuItem<String>(
// value: 'delete',
// child: Row(
// children: [
// Icon(
// Icons.delete,
// size: 16, // Adjust the icon size as needed
// ),
// SizedBox(width: 8),
// Text(
// 'Delete',
// style: AppStyle.txtGilroySemiBold16, // Adjust the text size as needed
// ),
// ],
// ),
// ),
// ];
// },
// onSelected: (String value) {
// if (value == 'edit') {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => UpdateDatabseScreen(
// projectId: widget.projectId,
// entity: entity,
// ),
// ),
// ).then((_) {
// fetchEntities();
// });
// } else if (value == 'delete') {
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return AlertDialog(
// title: const Text('Confirm Deletion'),
// content: const Text('Are you sure you want to delete?'),
// actions: [
// TextButton(
// child: const Text('Cancel'),
// onPressed: () {
// Navigator.of(context).pop();
// },
// ),
// TextButton(
// child: const Text('Delete'),
// onPressed: () {
// Navigator.of(context).pop();
// deleteEntity(entity, context).then((value) => {
// fetchEntities()
// });
// },
// ),
// ],
// );
// },
// );
// }
// },
// ),
],
),
),
Padding(
padding: getPadding(
top: 10,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
'BookMark Link',
overflow:
TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800,
),
GestureDetector(
onTap: () {
_launchURL(entity[
'bookmark_link']);
},
child: Text(
entity['bookmark_link'] ??
'No bookmark_link provided',
overflow:
TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Green600,
),
)
],
),
),
],
),
),
);
})
: Container(
height: MediaQuery.of(context).size.height,
child: const Center(
child: Text("No Databases available"),
)),
)
]))
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => const CreateEntityScreen(),
// ),
// ).then((_) {
// fetchEntities();
// });
// },
// child: const Icon(Icons.add),
// ),
);
}
// Function to build list items
Widget _buildListItem(Map<String, dynamic> entity) {
return showCardView ? _buildCardView(entity) : _buildNormalView(entity);
}
// Function to build card view for a list item
Widget _buildCardView(Map<String, dynamic> entity) {
return Card(
elevation: 2,
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: _buildNormalView(entity));
}
// Function to build normal view for a list item
// Widget _buildNormalView(Map<String, dynamic> entity) {
// return ListTile(
// title: Text(entity['id'].toString()),
// subtitle: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
//
// Text(entity['bookmark_firstletter'] ?? 'No bookmark_firstletter provided'),
// const SizedBox(height: 4),
// Text(entity['bookmark_link'] ?? 'No bookmark_link provided'),
// const SizedBox(height: 4),
// Text(entity['fileupload_field'] ?? 'No fileupload_field provided'),
// const SizedBox(height: 4), // Added address text
// ],
//
// ),
// trailing: _buildPopupMenu(entity),
// onTap: () {
// _showAdditionalFieldsDialog(context, entity);
// },
// );
// }
Widget _buildNormalView(Map<String, dynamic> entity) {
return ListTile(
title: Text(entity['id'].toString()),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(entity['bookmark_firstletter'] ??
'No bookmark_firstletter provided'),
const SizedBox(height: 4),
GestureDetector(
onTap: () {
_launchURL(entity['bookmark_link']);
},
child: Text(
entity['bookmark_link'] ?? 'No bookmark_link provided',
style: TextStyle(
color:
Colors.blue, // Change the color to make it look like a link
decoration: TextDecoration.underline, // Underline the link
),
),
),
const SizedBox(height: 4),
Text(entity['fileupload_field'] ?? 'No fileupload_field provided'),
const SizedBox(height: 4),
// Added address text
],
),
// trailing: _buildPopupMenu(entity),
// onTap: () {
// _showAdditionalFieldsDialog(context, entity);
// },
);
}
// Function to launch a URL in the browser
Future<void> _launchURL(String? url) async {
if (url != null) {
try {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to launch URL: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}
// // Function to build popup menu for a list item
// Widget _buildPopupMenu(Map<String, dynamic> entity) {
// return PopupMenuButton<String>(
// itemBuilder: (BuildContext context) {
// return [
// const PopupMenuItem<String>(
// value: 'edit',
// child: Row(
// children: [
// Icon(Icons.edit),
// SizedBox(width: 8),
// Text('Edit'),
// ],
// ),
// ),
// const PopupMenuItem<String>(
// value: 'delete',
// child: Row(
// children: [
// Icon(Icons.delete),
// SizedBox(width: 8),
// Text('Delete'),
// ],
// ),
// ),
// ];
// },
// onSelected: (String value) {
// if (value == 'edit') {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => UpdateEntityScreen(entity: entity),
// ),
// ).then((_) {
// fetchEntities();
// });
// } else if (value == 'delete') {
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return AlertDialog(
// title: const Text('Confirm Deletion'),
// content:
// const Text('Are you sure you want to delete this entity?'),
// actions: [
// TextButton(
// child: const Text('Cancel'),
// onPressed: () {
// Navigator.of(context).pop();
// },
// ),
// TextButton(
// child: const Text('Delete'),
// onPressed: () {
// Navigator.of(context).pop();
// deleteEntity(entity);
// },
// ),
// ],
// );
// },
// );
// }
// },
// );
// }
// Function to show additional fields in a dialog
void _showAdditionalFieldsDialog(
BuildContext context,
Map<String, dynamic> entity,
) {
final dateFormat =
DateFormat('yyyy-MM-dd HH:mm:ss'); // Define your desired date format
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Additional Fields'),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Created At: ${_formatTimestamp(entity['createdAt'], dateFormat)}'),
Text('Created By: ${entity['createdBy'] ?? 'N/A'}'),
Text('Updated By: ${entity['updatedBy'] ?? 'N/A'}'),
Text(
'Updated At: ${_formatTimestamp(entity['updatedAt'], dateFormat)}'),
Text('Account ID: ${entity['accountId'] ?? 'N/A'}'),
],
),
actions: [
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
String _formatTimestamp(dynamic timestamp, DateFormat dateFormat) {
if (timestamp is int) {
// If it's an integer, assume it's a Unix timestamp in milliseconds
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
return dateFormat.format(dateTime);
} else if (timestamp is String) {
// If it's a string, assume it's already formatted as a date
return timestamp;
} else {
// Handle other cases here if needed
return 'N/A';
}
}
}
@@ -0,0 +1,140 @@
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter/services.dart';
import '../../providers/token_manager.dart';
import 'Bookmarks_api_service.dart';
class UpdateEntityScreen extends StatefulWidget {
final Map<String, dynamic> entity;
UpdateEntityScreen({required this.entity});
@override
_UpdateEntityScreenState createState() => _UpdateEntityScreenState();
}
class _UpdateEntityScreenState extends State<UpdateEntityScreen> {
final ApiService apiService = ApiService();
final _formKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Update Bookmarks')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
initialValue: widget.entity['bookmark_firstletter'],
decoration:
const InputDecoration(labelText: 'bookmark_firstletter'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a bookmark_firstletter';
}
return null;
},
onSaved: (value) {
widget.entity['bookmark_firstletter'] = value;
},
),
const SizedBox(height: 16),
TextFormField(
initialValue: widget.entity['bookmark_link'],
decoration: const InputDecoration(labelText: 'bookmark_link'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a bookmark_link';
}
return null;
},
onSaved: (value) {
widget.entity['bookmark_link'] = value;
},
),
const SizedBox(height: 16),
TextFormField(
initialValue: widget.entity['fileupload_field'],
decoration:
const InputDecoration(labelText: 'fileupload_field'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a fileupload_field';
}
return null;
},
onSaved: (value) {
widget.entity['fileupload_field'] = value;
},
),
const SizedBox(height: 16),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
final token = await TokenManager.getToken();
try {
await apiService.updateEntity(
token!,
widget.entity[
'id'], // Assuming 'id' is the key in your entity map
widget.entity);
Navigator.pop(context);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to update entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
},
child: Container(
width: double.infinity,
height: 50,
child: const Center(
child: Text(
'UPDATE',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
],
),
),
),
),
);
}
}
Binary file not shown.
@@ -0,0 +1,293 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'dart:convert';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../LogoutService/Logoutservice.dart';
class RaisedTicketScreen extends StatefulWidget {
final Map<String, dynamic> userData;
const RaisedTicketScreen({Key? key, required this.userData})
: super(key: key);
@override
_RaisedTicketScreenState createState() => _RaisedTicketScreenState();
}
class _RaisedTicketScreenState extends State<RaisedTicketScreen> {
List<Map<String, dynamic>> tickets = [];
@override
void initState() {
super.initState();
fetchTickets();
}
Future<void> fetchTickets() async {
int userid = widget.userData['userId'];
String baseUrl = ApiConstants.baseUrl;
final token = await TokenManager.getToken();
String apiUrl = '$baseUrl/gettickets/$userid';
final response = await http.get(Uri.parse(apiUrl), headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
});
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body);
setState(() {
tickets = data.cast<Map<String, dynamic>>();
});
} else {
print('Failed to fetch data');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
actions: [
GestureDetector(
child: Icon(
Icons.add,
color: Colors.black,
size: 20,
),
onTap: () {
Navigator.of(context)
.push(
MaterialPageRoute(
builder: (context) => TicketFormScreen(
userData: widget.userData,
)),
)
.then((value) => {fetchTickets()});
},
),
const SizedBox(
width: 20,
)
],
centerTitle: true,
title: AppbarTitle(text: "Raised Tickets")),
body: ListView.builder(
itemCount: tickets.length,
itemBuilder: (context, index) {
final ticket = tickets[index];
return ListTile(
title: Text(
'Ticket ID: ${ticket['ticketid']}',
style: const TextStyle(fontSize: 12),
),
subtitle: Text('Ticket Name: ${ticket['ticketname']}',
style: const TextStyle(fontSize: 10)),
// Add more fields as needed
);
},
),
);
}
}
class TicketFormScreen extends StatefulWidget {
final Map<String, dynamic> userData;
const TicketFormScreen({Key? key, required this.userData}) : super(key: key);
@override
_TicketFormScreenState createState() => _TicketFormScreenState();
}
class _TicketFormScreenState extends State<TicketFormScreen> {
final TextEditingController titleController = TextEditingController();
final TextEditingController descriptionController = TextEditingController();
TextEditingController projectNameController = TextEditingController();
var screenshot;
Future<void> submitTicket(File file) async {
print(widget.userData);
String title = titleController.text;
String description = descriptionController.text;
String baseUrl = ApiConstants.baseUrl;
final token = await TokenManager.getToken();
String apiUrl = '$baseUrl/service_request/raise_ticket';
// Create a multipart request
var request = http.MultipartRequest('POST', Uri.parse(apiUrl));
request.headers['Authorization'] = 'Bearer $token';
// Add text fields to the request
request.fields['title'] = title;
request.fields['description'] = description;
request.fields['userid'] = widget.userData['userId'].toString();
request.fields['username'] = widget.userData['fullname'];
// Add file to the request
if (file != null) {
request.files.add(
await http.MultipartFile.fromPath('file', file.path),
);
}
try {
// Send the request
final response = await request.send();
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode == 200) {
Fluttertoast.showToast(
msg: 'Ticket submitted successfully',
backgroundColor: Colors.green,
);
print('Ticket submitted successfully');
Navigator.pop(context);
} else {
Fluttertoast.showToast(
msg: 'Failed to submit ticket.',
backgroundColor: Colors.red,
);
print('Failed to submit ticket. Status code: ${response.statusCode}');
}
} catch (e) {
// Handle exceptions
print('Error: $e');
}
}
Future<void> _pickImage() async {
final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
screenshot = File(pickedFile.path);
} else {
print('No image selected.');
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Raise a Ticket")),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Title",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Title",
controller: titleController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Description",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Description",
controller: descriptionController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Project Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Project Name",
controller: projectNameController,
margin: getMargin(top: 6))
])), // Adjusted the spacing
Row(
children: <Widget>[
Text('Pick Screenshot of issue'),
IconButton(
onPressed: () {
_pickImage(); // Call the function to pick an image
},
icon: Icon(Icons.file_copy),
),
SizedBox(width: 8.0),
// Display the selected screenshot file name
Text(screenshot != null ? screenshot.path.split('/').last : ''),
],
),
CustomButton(
height: getVerticalSize(50),
text: "Submit",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
submitTicket(screenshot);
},
),
],
),
),
);
}
}
@@ -0,0 +1,975 @@
import 'package:flutter/material.dart';
import 'dart:convert';
// class ReportEditor extends StatefulWidget {
// @override
// _ReportEditorState createState() => _ReportEditorState();
// }
//
// class _ReportEditorState extends State<ReportEditor> {
// List<Map<String, dynamic>> droppedFields = [];
// GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
// TextEditingController keyController = TextEditingController();
// TextEditingController valueController = TextEditingController();
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// key: _scaffoldKey,
// appBar: AppBar(title: Text('Report Editor')),
// body: Row(
// children: <Widget>[
// Container(
// width: 200,
// padding: EdgeInsets.all(10),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// Text('Drag and Drop Fields:'),
// Draggable<String>(
// data: 'Title',
// child: DragField(text: 'Title'),
// feedback: DragField(text: 'Title'),
// ),
// Draggable<String>(
// data: 'Phone Number',
// child: DragField(text: 'Phone Number'),
// feedback: DragField(text: 'Phone Number'),
// ),
// Draggable<String>(
// data: 'Date',
// child: DragField(text: 'Date'),
// feedback: DragField(text: 'Date'),
// ),
// ],
// ),
// ),
// Expanded(
// child: SingleChildScrollView(
// child: Container(
// color: Colors.white,
// child: Stack(
// children: [
// Container(
// margin: EdgeInsets.all(10),
// width: 793, // A4 width
// height: 1122, // A4 height
// decoration: BoxDecoration(
// border: Border.all(
// color: Colors.black,
// width: 1.0,
// ),
// ),
// ),
// Align(
// alignment: Alignment.bottomRight,
// child: Text('Scale Bar Report Editor'),
// ),
// ...droppedFields.asMap().entries.map((entry) {
// final index = entry.key;
// final field = entry.value;
// return DraggableField(
// key: Key(index.toString()),
// field: field,
// onDrag: (Offset position) {
// setState(() {
// droppedFields[index]['left'] = position.dx;
// droppedFields[index]['top'] = position.dy;
// });
// },
// onEdit: (String key, String value) {
// setState(() {
// droppedFields[index]['key'] = key;
// droppedFields[index]['value'] = value;
// });
// },
//
// );
// }).toList(),
// DraggableTarget(
// onAccept: (String field) {
// final RenderBox renderBox = context.findRenderObject() as RenderBox;
// final offset = renderBox.localToGlobal(Offset.zero);
// print(offset.dx);
// setState(() {
// droppedFields.add({
// 'type': field,
// 'left': offset.dx, // Set left coordinate
// 'top': offset.dy, // Set top coordinate
// 'key': field,
// 'value': '',
// 'isEditing': true, // Set the newly dropped field to be in edit mode
// });
// });
// },
// ),
//
// ],
// ),
// ),
// ),
// ),
// ],
// ),
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// _submitReport();
// },
// child: Icon(Icons.save),
// ),
// );
// }
//
// void _submitReport() {
// final reportJson = jsonEncode(droppedFields);
// print(reportJson);
//
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text('Report JSON created and printed!'),
// ),
// );
// }
// }
//
// class DragField extends StatelessWidget {
// final String text;
//
// DragField({required this.text});
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 120,
// padding: EdgeInsets.all(8),
// margin: EdgeInsets.symmetric(vertical: 5),
// decoration: BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.circular(5),
// ),
// child: Text(
// text,
// style: TextStyle(color: Colors.white),
// ),
// );
// }
// }
//
// class DraggableField extends StatefulWidget {
// final Map<String, dynamic> field;
// final Function(Offset) onDrag;
// final Function(String, String) onEdit;
//
// DraggableField({
// required Key key,
// required this.field,
// required this.onDrag,
// required this.onEdit,
// }) : super(key: key);
//
// @override
// _DraggableFieldState createState() => _DraggableFieldState();
// }
//
// class _DraggableFieldState extends State<DraggableField> {
// Offset position = Offset(0, 0);
//
// @override
// void initState() {
// super.initState();
// final left = widget.field['left'] as double;
// final top = widget.field['top'] as double;
// position = Offset(left, top);
// }
//
// @override
// Widget build(BuildContext context) {
// return Positioned(
// left: position.dx,
// top: position.dy,
// child: GestureDetector(
// onLongPress: () {
// widget.onEdit(widget.field['key'], widget.field['value']);
// setState(() {
// // Set the field to be in edit mode when long-pressed
// widget.field['isEditing'] = true;
// });
// },
// child: Draggable<String>(
// data: widget.field['type'],
// child: widget.field['isEditing']
// ? EditableField(
// key: widget.key as Key,
// keyText: widget.field['key'],
// valueText: widget.field['value'],
// onEdit: widget.onEdit,
// )
// : DragField(text: widget.field['type']),
// feedback: DragField(text: widget.field['type']),
// onDragEnd: (details) {
// setState(() {
// position = details.offset;
// widget.onDrag(details.offset);
// });
// },
// ),
// ),
// );
// }
// }
//
// class EditableField extends StatefulWidget {
// final String keyText;
// final String valueText;
// final Function(String, String) onEdit;
//
// EditableField({
// required Key key,
// required this.keyText,
// required this.valueText,
// required this.onEdit,
// }) : super(key: key);
//
// @override
// _EditableFieldState createState() => _EditableFieldState();
// }
//
// class _EditableFieldState extends State<EditableField> {
// TextEditingController keyController = TextEditingController();
// TextEditingController valueController = TextEditingController();
//
// @override
// void initState() {
// super.initState();
// keyController.text = widget.keyText;
// valueController.text = widget.valueText;
// }
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 120,
// padding: EdgeInsets.all(8),
// margin: EdgeInsets.symmetric(vertical: 5),
// decoration: BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.circular(5),
// ),
// child: Column(
// children: [
// TextFormField(
// controller: keyController,
// decoration: InputDecoration(labelText: 'Key'),
// onChanged: (value) {
// widget.onEdit(value, valueController.text);
// },
// ),
// TextFormField(
// controller: valueController,
// decoration: InputDecoration(labelText: 'Value'),
// onChanged: (value) {
// widget.onEdit(keyController.text, value);
// },
// ),
// ],
// ),
// );
// }
// }
//
// class DraggableTarget extends StatelessWidget {
// final Function(String) onAccept;
//
// DraggableTarget({required this.onAccept});
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 793,
// height: 1122,
// child: DragTarget<String>(
// builder: (context, candidateData, rejectedData) {
// return Center(
// child: Text('Drop Here', style: TextStyle(fontSize: 24)),
// );
// },
// onAccept: (String field) {
// onAccept(field);
// },
// ));
// }
// }
// import 'package:flutter/material.dart';
//
// class ReportEditor extends StatefulWidget {
// @override
// _ReportEditorState createState() => _ReportEditorState();
// }
//
// class _ReportEditorState extends State<ReportEditor> {
// List<Map<String, dynamic>> droppedFields = [];
// GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
// TextEditingController keyController = TextEditingController();
// TextEditingController valueController = TextEditingController();
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// key: _scaffoldKey,
// appBar: AppBar(title: Text('Report Editor')),
// body: Row(
// children: <Widget>[
// Container(
// width: 200,
// padding: EdgeInsets.all(10),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// Text('Drag and Drop Fields:'),
// Draggable<String>(
// data: 'Title',
// child: DragField(text: 'Title'),
// feedback: DragField(text: 'Title'),
// ),
// Draggable<String>(
// data: 'Phone Number',
// child: DragField(text: 'Phone Number'),
// feedback: DragField(text: 'Phone Number'),
// ),
// Draggable<String>(
// data: 'Date',
// child: DragField(text: 'Date'),
// feedback: DragField(text: 'Date'),
// ),
// ],
// ),
// ),
// Expanded(
// child: SingleChildScrollView(
// child: Container(
// color: Colors.white,
// child: Stack(
// children: [
// Container(
// margin: EdgeInsets.all(10),
// width: 793, // A4 width
// height: 1122, // A4 height
// decoration: BoxDecoration(
// border: Border.all(
// color: Colors.black,
// width: 1.0,
// ),
// ),
// ),
// Align(
// alignment: Alignment.bottomRight,
// child: Text('Scale Bar Report Editor'),
// ),
// ...droppedFields.asMap().entries.map((entry) {
// final index = entry.key;
// final field = entry.value;
// return DraggableField(
// key: Key(index.toString()),
// field: field,
// onDrag: (Offset position) {
// setState(() {
// droppedFields[index]['left'] = position.dx;
// droppedFields[index]['top'] = position.dy;
// });
// },
// onEdit: (String key, String value) {
// setState(() {
// droppedFields[index]['key'] = key;
// droppedFields[index]['value'] = value;
// });
// },
// onDelete: () {
// setState(() {
// droppedFields.removeAt(index);
// });
// },
// );
// }).toList(),
// DraggableTarget(
// onAccept: (String field) {
// final RenderBox renderBox = context.findRenderObject() as RenderBox;
// final offset = renderBox.localToGlobal(Offset.zero);
// setState(() {
// droppedFields.add({
// 'type': field,
// 'left': offset.dx, // Set left coordinate
// 'top': offset.dy, // Set top coordinate
// 'key': field,
// 'value': '',
// 'isEditing': true, // Set the newly dropped field to be in edit mode
// });
// });
// },
// ),
// ],
// ),
// ),
// ),
// ),
// ],
// ),
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// _submitReport();
// },
// child: Icon(Icons.save),
// ),
// );
// }
//
// void _submitReport() {
// final reportJson = jsonEncode(droppedFields);
// print(reportJson);
//
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text('Report JSON created and printed!'),
// ),
// );
// }
// }
//
//
// class DragField extends StatelessWidget {
// final String text;
//
// DragField({required this.text});
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 120,
// padding: EdgeInsets.all(8),
// margin: EdgeInsets.symmetric(vertical: 5),
// decoration: BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.circular(5),
// ),
// child: Text(
// text,
// style: TextStyle(color: Colors.white),
// ),
// );
// }
// }
//
// class DraggableField extends StatefulWidget {
// final Map<String, dynamic> field;
// final Function(Offset) onDrag;
// final Function(String, String) onEdit;
// final Function onDelete;
//
// DraggableField({
// required Key key,
// required this.field,
// required this.onDrag,
// required this.onEdit,
// required this.onDelete,
// }) : super(key: key);
//
// @override
// _DraggableFieldState createState() => _DraggableFieldState();
// }
//
// class _DraggableFieldState extends State<DraggableField> {
// Offset position = Offset(0, 0);
// bool isEditing = false;
//
// @override
// void initState() {
// super.initState();
// final left = widget.field['left'] as double;
// final top = widget.field['top'] as double;
// position = Offset(left, top);
// }
//
// @override
// Widget build(BuildContext context) {
// return Positioned(
// left: position.dx,
// top: position.dy,
// child: GestureDetector(
// onLongPress: () {
// widget.onEdit(widget.field['key'], widget.field['value']);
// setState(() {
// isEditing = true;
// });
// },
// child: Draggable<String>(
// data: widget.field['type'],
// child: isEditing
// ? EditableField(
// key: widget.key as Key,
// keyText: widget.field['key'],
// valueText: widget.field['value'],
// onEdit: widget.onEdit,
// )
// : Stack(
// children: [
// DragField(text: widget.field['type']),
// Positioned(
// top: -10,
// right: -10,
// child: IconButton(
// icon: Icon(Icons.delete),
// onPressed: () {
// widget.onDelete();
// },
// ),
// ),
// ],
// ),
// feedback: DragField(text: widget.field['type']),
// onDragEnd: (details) {
// setState(() {
// position = details.offset;
// widget.onDrag(details.offset);
// });
// },
// ),
// ),
// );
// }
// }
//
// class EditableField extends StatefulWidget {
// final String keyText;
// final String valueText;
// final Function(String, String) onEdit;
//
// EditableField({
// required Key key,
// required this.keyText,
// required this.valueText,
// required this.onEdit,
// }) : super(key: key);
//
// @override
// _EditableFieldState createState() => _EditableFieldState();
// }
//
// class _EditableFieldState extends State<EditableField> {
// TextEditingController keyController = TextEditingController();
// TextEditingController valueController = TextEditingController();
//
// @override
// void initState() {
// super.initState();
// keyController.text = widget.keyText;
// valueController.text = widget.valueText;
// }
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 120,
// padding: EdgeInsets.all(8),
// margin: EdgeInsets.symmetric(vertical: 5),
// decoration: BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.circular(5),
// ),
// child: Column(
// children: [
// TextFormField(
// controller: keyController,
// decoration: InputDecoration(labelText: 'Key'),
// onChanged: (value) {
// widget.onEdit(value, valueController.text);
// },
// ),
// TextFormField(
// controller: valueController,
// decoration: InputDecoration(labelText: 'Value'),
// onChanged: (value) {
// widget.onEdit(keyController.text, value);
// },
// ),
// ],
// ),
// );
// }
// }
//
// class DraggableTarget extends StatelessWidget {
// final Function(String) onAccept;
//
// DraggableTarget({required this.onAccept});
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 793,
// height: 1122,
// child: DragTarget<String>(
// builder: (context, candidateData, rejectedData) {
// return Center(
// child: Text('Drop Here', style: TextStyle(fontSize: 24)),
// );
// },
// onAccept: (String field) {
// onAccept(field);
// },
// ),
// );
// }
// }
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pdfLib;
import 'dart:io';
import 'dart:typed_data';
class ReportEditor extends StatefulWidget {
@override
_ReportEditorState createState() => _ReportEditorState();
}
class _ReportEditorState extends State<ReportEditor> {
List<Map<String, dynamic>> droppedFields = [];
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
TextEditingController keyController = TextEditingController();
TextEditingController valueController = TextEditingController();
Future<Uint8List> generatePdf() async {
final pdf = pdfLib.Document();
for (final field in droppedFields) {
final left = field['left'] as double;
final top = field['top'] as double;
final type = field['type'];
final key = field['key'];
final value = field['value'];
final widget = pdfLib.Container(
child: pdfLib.Text('$type: $key - $value'),
decoration: const pdfLib.BoxDecoration(
border: pdfLib.Border(),
),
padding: pdfLib.EdgeInsets.all(5),
);
pdf.addPage(
pdfLib.Page(
build: (context) {
return pdfLib.Positioned(
left: left,
top: top,
child: widget,
);
},
),
);
}
return pdf.save();
}
Future<void> savePdf() async {
final pdfBytes = await generatePdf();
final dir = await getApplicationDocumentsDirectory();
final pdfFile = File('${dir.path}/report.pdf');
await pdfFile.writeAsBytes(pdfBytes);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('PDF saved to ${pdfFile.path}'),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(title: Text('Report Editor')),
body: Row(
children: <Widget>[
Container(
width: 200,
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Drag and Drop Fields:'),
Draggable<String>(
data: 'Title',
child: DragField(text: 'Title'),
feedback: DragField(text: 'Title'),
),
Draggable<String>(
data: 'Phone Number',
child: DragField(text: 'Phone Number'),
feedback: DragField(text: 'Phone Number'),
),
Draggable<String>(
data: 'Date',
child: DragField(text: 'Date'),
feedback: DragField(text: 'Date'),
),
],
),
),
Expanded(
child: SingleChildScrollView(
child: Container(
color: Colors.white,
child: Stack(
children: [
Container(
margin: EdgeInsets.all(10),
width: 793, // A4 width
height: 1122, // A4 height
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1.0,
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Text('Scale Bar Report Editor'),
),
...droppedFields.asMap().entries.map((entry) {
final index = entry.key;
final field = entry.value;
return DraggableField(
key: Key(index.toString()),
field: field,
onDrag: (Offset position) {
setState(() {
droppedFields[index]['left'] = position.dx;
droppedFields[index]['top'] = position.dy;
});
},
onEdit: (String key, String value) {
setState(() {
droppedFields[index]['key'] = key;
droppedFields[index]['value'] = value;
});
},
);
}).toList(),
DraggableTarget(
onAccept: (String field) {
final RenderBox renderBox =
context.findRenderObject() as RenderBox;
final offset = renderBox.localToGlobal(Offset.zero);
setState(() {
droppedFields.add({
'type': field,
'left': offset.dx,
'top': offset.dy,
'key': field,
'value': '',
'isEditing': true,
});
});
},
),
],
),
),
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: savePdf,
child: Icon(Icons.save),
),
);
}
}
class DragField extends StatelessWidget {
final String text;
DragField({required this.text});
@override
Widget build(BuildContext context) {
return Container(
width: 120,
padding: EdgeInsets.all(8),
margin: EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(5),
),
child: Text(
text,
style: TextStyle(color: Colors.white),
),
);
}
}
class DraggableField extends StatefulWidget {
final Map<String, dynamic> field;
final Function(Offset) onDrag;
final Function(String, String) onEdit;
DraggableField({
required Key key,
required this.field,
required this.onDrag,
required this.onEdit,
}) : super(key: key);
@override
_DraggableFieldState createState() => _DraggableFieldState();
}
class _DraggableFieldState extends State<DraggableField> {
Offset position = Offset(0, 0);
@override
void initState() {
super.initState();
final left = widget.field['left'] as double;
final top = widget.field['top'] as double;
position = Offset(left, top);
}
@override
Widget build(BuildContext context) {
return Positioned(
left: position.dx,
top: position.dy,
child: GestureDetector(
onLongPress: () {
widget.onEdit(widget.field['key'], widget.field['value']);
setState(() {
widget.field['isEditing'] = true;
});
},
child: Draggable<String>(
data: widget.field['type'],
child: widget.field['isEditing']
? EditableField(
key: widget.key as Key,
keyText: widget.field['key'],
valueText: widget.field['value'],
onEdit: widget.onEdit,
)
: DragField(text: widget.field['type']),
feedback: DragField(text: widget.field['type']),
onDragEnd: (details) {
setState(() {
position = details.offset;
widget.onDrag(details.offset);
});
},
),
),
);
}
}
class EditableField extends StatefulWidget {
final String keyText;
final String valueText;
final Function(String, String) onEdit;
EditableField({
required Key key,
required this.keyText,
required this.valueText,
required this.onEdit,
}) : super(key: key);
@override
_EditableFieldState createState() => _EditableFieldState();
}
class _EditableFieldState extends State<EditableField> {
TextEditingController keyController = TextEditingController();
TextEditingController valueController = TextEditingController();
@override
void initState() {
super.initState();
keyController.text = widget.keyText;
valueController.text = widget.valueText;
}
@override
Widget build(BuildContext context) {
return Container(
width: 120,
padding: EdgeInsets.all(8),
margin: EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(5),
),
child: Column(
children: [
TextFormField(
controller: keyController,
decoration: InputDecoration(labelText: 'Key'),
onChanged: (value) {
widget.onEdit(value, valueController.text);
},
),
TextFormField(
controller: valueController,
decoration: InputDecoration(labelText: 'Value'),
onChanged: (value) {
widget.onEdit(keyController.text, value);
},
),
],
),
);
}
}
class DraggableTarget extends StatelessWidget {
final Function(String) onAccept;
DraggableTarget({required this.onAccept});
@override
Widget build(BuildContext context) {
return Container(
width: 793,
height: 1122,
child: DragTarget<String>(
builder: (context, candidateData, rejectedData) {
return Center(
child: Text('Drop Here', style: TextStyle(fontSize: 24)),
);
},
onAccept: (String field) {
onAccept(field);
},
),
);
}
}
void main() {
runApp(MaterialApp(
home: ReportEditor(),
));
}
Binary file not shown.
@@ -0,0 +1,342 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../Utils/color_constants.dart';
import '../../providers/token_manager.dart';
import '../../utilities/make_api_request.dart';
import '../main_app_screen/tabbed_layout_component.dart';
class LoginFormComponent extends StatefulWidget {
const LoginFormComponent({Key? key}) : super(key: key);
@override
LoginFormComponentState createState() {
return LoginFormComponentState();
}
}
class LoginFormComponentState extends State<LoginFormComponent> {
final _formKey = GlobalKey<FormState>();
String errorMessage1 = "";
String errorMessage2 = "";
String userInput = "";
String password = "";
bool isPasswordVisible = false;
bool stayLoggedIn = false;
void errorMessageSetter(int fieldNumber, String message) {
setState(() {
if (fieldNumber == 1) {
errorMessage1 = message;
} else {
errorMessage2 = message;
}
});
}
void tryLoggingIn() async {
final dataReceived = await sendData(
urlPath: "/token/session",
data: {"email": userInput, "password": password},
);
if (dataReceived.containsValue('ERROR')) {
var error = dataReceived['operationMessage'].toString();
// ignore: use_build_context_synchronously
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Text(error),
backgroundColor: Colors.redAccent,
))
.closed;
} else {
var token = dataReceived['item']['token'];
var user = dataReceived['item'];
await TokenManager.setToken(token);
if (stayLoggedIn) {
await _saveLoggedInUserData(token, user);
}
// ignore: use_build_context_synchronously
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(
content: Text("Login Successful"),
backgroundColor: Colors.green,
))
.closed
.then(
(value) => Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => TabbedLayoutComponent(),
),
(route) => false,
),
);
print('after login');
}
}
Future<bool> _saveLoggedInUserData(
String loggedInUserAuthKey, Map<String, dynamic> user) async {
try {
var userId = user['userId'].toString();
var firstName = user['firstName'].toString();
final prefs = await SharedPreferences.getInstance();
await prefs.setString('userData', json.encode(user));
await prefs.setBool('isLoggedIn', true);
await prefs.setString('token', loggedInUserAuthKey);
print('userId ....$userId');
print('firstName ....$firstName');
if (mounted) {
debugPrint("user data saved");
}
return true;
} catch (e) {
return false;
}
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Color(0xFFF5F7FA),
),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100,
),
],
),
child: TextFormField(
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
errorMessageSetter(
1, 'You must provide an email or username');
} else {
errorMessageSetter(1, "");
setState(() {
userInput = value;
});
}
return null;
},
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "Username or email address",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (errorMessage1 != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$errorMessage1",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
Container(
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
color: Colors.white,
boxShadow: [
const BoxShadow(
spreadRadius: 0.618,
blurRadius: 6.18,
offset: Offset(-4, -4),
color: Color(0xFFF5F7FA),
),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100,
),
],
),
child: TextFormField(
textInputAction: TextInputAction.done,
onFieldSubmitted: (value) => _validateLoginDetails(),
validator: (value) {
if (value == null || value.isEmpty) {
errorMessageSetter(2, 'Password cannot be empty');
} else {
errorMessageSetter(2, "");
setState(() {
password = value;
});
}
return null;
},
obscureText: !isPasswordVisible,
enableSuggestions: false,
autocorrect: false,
decoration: InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: const EdgeInsets.only(
left: 15, bottom: 11, top: 11, right: 15),
hintText: "Password",
hintStyle:
const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
suffixIcon: IconButton(
icon: Icon(
isPasswordVisible ? Icons.visibility : Icons.visibility_off,
),
onPressed: () {
setState(() {
isPasswordVisible = !isPasswordVisible;
});
},
),
),
),
),
if (errorMessage2 != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$errorMessage2",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
CheckboxListTile(
activeColor: ColorConstant.blue700,
title: const Text('Stay Logged In'),
value: stayLoggedIn,
onChanged: (value) {
setState(() {
stayLoggedIn = value!;
});
},
),
Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
width: double.infinity,
height: 64,
child: ElevatedButton(
onPressed: _validateLoginDetails,
style: ElevatedButton.styleFrom(
backgroundColor: ColorConstant.blue700,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: const Text(
'Log in',
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w600,
),
),
),
),
// Container(
// margin: const EdgeInsets.symmetric(vertical: 16.0),
// width: double.infinity,
// height: 64,
// decoration: BoxDecoration(
// boxShadow: [
// BoxShadow(
// color: Colors.blueGrey.shade100,
// offset: const Offset(0, 4),
// blurRadius: 5.0,
// ),
// ],
// gradient: const RadialGradient(
// colors: [Color(0xff0070BA), Color(0xff1546A0)],
// radius: 8.4,
// center: Alignment(-0.24, -0.36),
// ),
// borderRadius: BorderRadius.circular(20),
// ),
// child: ElevatedButton(
// onPressed: _validateLoginDetails,
// style: ElevatedButton.styleFrom(
// primary: Colors.transparent,
// shadowColor: Colors.transparent,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(20),
// ),
// ),
// child: const Text(
// 'Log in',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
],
),
);
}
void _validateLoginDetails() {
FocusManager.instance.primaryFocus?.unfocus();
if (_formKey.currentState!.validate()) {
if (errorMessage1 != "" || errorMessage2 != "") {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please provide all required details'),
backgroundColor: Colors.red,
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
onVisible: tryLoggingIn,
content: const Text('Processing...'),
backgroundColor: Colors.blue,
),
);
}
}
}
}
+586
View File
@@ -0,0 +1,586 @@
// import 'dart:convert';
// import 'package:flutter/material.dart';
// import 'package:authsec_flutter/hadwin_components.dart';
// import 'package:shared_preferences/shared_preferences.dart';
// import '../../Utils/color_constants.dart';
// import '../../Utils/image_constant.dart';
// import '../../Utils/size_utils.dart';
// import '../../providers/token_manager.dart';
// import '../../theme/app_style.dart';
// import '../../widgets/app_bar/appbar_title.dart';
// import '../../widgets/app_bar/custom_app_bar.dart';
// import '../../widgets/custom_button.dart';
// import '../../widgets/custom_image_view.dart';
// import '../../widgets/custom_text_form_field.dart';
// import '../forgot_password/forgotPasswordScreen.dart';
// import '../main_app_screen/newlanding_page.dart';
// import '../sign_up_screen/sign_up_step_1.dart';
//
//
//
// class LoginScreen extends StatefulWidget {
// const LoginScreen({Key? key}) : super(key: key);
//
// @override
// _LoginScreenState createState() => _LoginScreenState();
// }
//
// class _LoginScreenState extends State<LoginScreen> {
// TextEditingController inputFieldController = TextEditingController();
// TextEditingController inputFieldOneController = TextEditingController();
//
// String errorMessage1 = "";
// String errorMessage2 = "";
// bool isPasswordVisible = false;
// bool stayLoggedIn = false;
//
// @override
// initState(){
// super.initState();
// }
//
// GlobalKey<FormState> _formKey = GlobalKey<FormState>();
//
// void errorMessageSetter(int fieldNumber, String message) {
// setState(() {
// if (fieldNumber == 1) {
// errorMessage1 = message;
// } else {
// errorMessage2 = message;
// }
// });
// }
//
// void tryLoggingIn() async {
// final dataReceived = await sendData(
// urlPath: "/token/session",
// data: {"email": inputFieldController.text, "password": inputFieldOneController.text},
// );
//
// if (dataReceived.containsValue('ERROR')) {
// var error = dataReceived['operationMessage'].toString();
// // ignore: use_build_context_synchronously
// ScaffoldMessenger.of(context)
// .showSnackBar(SnackBar(
// content: Text(error),
// backgroundColor: Colors.redAccent,
// ))
// .closed;
// } else {
// var token = dataReceived['item']['token'];
// var user = dataReceived['item'];
// await TokenManager.setToken(token);
//
// if (stayLoggedIn) {
// await _saveLoggedInUserData(token, user);
// }
// // ignore: use_build_context_synchronously
// ScaffoldMessenger.of(context)
// .showSnackBar(const SnackBar(
// content: Text("Login Successful"),
// backgroundColor: Colors.green,
// ))
// .closed
// .then(
// (value) => Navigator.of(context).pushAndRemoveUntil(
// MaterialPageRoute(
// builder: (context) => TabbedLayoutComponentb(),
// ),
// (route) => false,
// ),
// );
//
// print('after login');
// }
// }
//
// Future<bool> _saveLoggedInUserData(
// String loggedInUserAuthKey, Map<String, dynamic> user) async {
// try {
// var userId = user['userId'].toString();
// var firstName = user['firstName'].toString();
//
// final prefs = await SharedPreferences.getInstance();
// await prefs.setString('userData', json.encode(user));
// await prefs.setBool('isLoggedIn', true);
// await prefs.setString('token', loggedInUserAuthKey);
//
// print('userId ....$userId');
// print('firstName ....$firstName');
//
// if (mounted) {
// debugPrint("user data saved");
// }
//
// return true;
// } catch (e) {
// return false;
// }
// }
//
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// backgroundColor: ColorConstant.gray50,
// appBar: CustomAppBar(
// height: getVerticalSize(54),
// leadingWidth: 40,
// centerTitle: true,
// title: AppbarTitle(text: "Login")),
// body: SingleChildScrollView(
// child: Form(
// key: _formKey,
// child: Container(
// width: double.maxFinite,
// padding:
// getPadding(left: 16, top: 22, right: 16, bottom: 22),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Padding(
// padding: getPadding(top: 19),
// child: Text("Email",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle.txtGilroyMedium16Bluegray900),),
//
// CustomTextFormField(
// focusNode: FocusNode(),
// controller: inputFieldController,
// hintText: "Enter Your Email",
// padding: TextFormFieldPadding.PaddingT12,
//
// margin: getMargin(top: 7),
// textInputType: TextInputType.emailAddress),
// Padding(
// padding: getPadding(top: 19),
// child: Text("Password",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style:
// AppStyle.txtGilroyMedium16Bluegray900)),
// CustomTextFormField(
// focusNode: FocusNode(),
// controller: inputFieldOneController,
// hintText: "Enter Password",
// margin: getMargin(top: 6),
// padding: TextFormFieldPadding.PaddingT12,
// textInputAction: TextInputAction.done,
// textInputType:TextInputType.visiblePassword,
// suffix: IconButton(
// icon: Icon(
// isPasswordVisible ? Icons.visibility_off : Icons.visibility,
// size: 12,
// ),
// onPressed: () {
// setState(() {
// isPasswordVisible = !isPasswordVisible;
// });
// },
// ),
// suffixConstraints: BoxConstraints(
// maxHeight: getVerticalSize(44)),
// isObscureText: !isPasswordVisible),
// Padding(
// padding: getPadding(top: 17),
// child: Row(children: [
// Checkbox(value: stayLoggedIn,
// activeColor: ColorConstant.blueA700,
// onChanged: (value) {
// setState(() {
// stayLoggedIn = value!;
// });
// },),
// Padding(
// padding:
// getPadding(left: 8, top: 1, bottom: 1),
// child: Text("Remember me",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle.txtGilroyMedium14)),
// Spacer(),
// GestureDetector(
// onTap: getLoginHelp,
// child: Padding(
// padding: getPadding(top: 3),
// child: Text("Forgot Password?",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style:
// AppStyle.txtGilroyMedium14BlueA700)),
// )
// ])),
// CustomButton(
// height: getVerticalSize(50),
// width: getHorizontalSize(396),
// text: "Log in",
// margin: getMargin(top: 25),
// onTap: (){
// if(inputFieldOneController.text==''||inputFieldController.text==''){
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('Please provide all required details'),
// backgroundColor: Colors.red,
// ),
// );
// }else{
// _validateLoginDetails();
// }
// },
// ),
// Padding(
// padding: getPadding(top: 26),
// child: Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Padding(
// padding: getPadding(top: 10, bottom: 7),
// child: Divider(
// height: getVerticalSize(1),
// thickness: getVerticalSize(1),
// color: ColorConstant.blueGray200)),
// Text("Or continue with",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle
// .txtGilroyRegular16Bluegray200),
// Padding(
// padding: getPadding(top: 10, bottom: 7),
// child: Divider(
// height: getVerticalSize(1),
// thickness: getVerticalSize(1),
// color: ColorConstant.blueGray200))
// ])),
// CustomButton(
// height: getVerticalSize(50),
// text: "Sign Up",
// margin: getMargin(top: 28),
// variant: ButtonVariant.OutlineBlueA700,
// padding: ButtonPadding.PaddingT14,
// fontStyle: ButtonFontStyle.GilroyMedium16BlueA700,
// onTap:goToSignUpScreen ,
// // prefixWidget: Container(
// // margin: getMargin(right: 8),
// // child: CustomImageView(
// // svgPath: ImageConstant.imgGoogle))
// ),
// CustomButton(
// height: getVerticalSize(50),
// text: "Sign in with Google",
// margin: getMargin(top: 28),
// variant: ButtonVariant.OutlineBlueA700,
// padding: ButtonPadding.PaddingT14,
// fontStyle: ButtonFontStyle.GilroyMedium16BlueA700,
// prefixWidget: Container(
// margin: getMargin(right: 8),
// child: CustomImageView(
// svgPath: ImageConstant.imgGoogle))),
// CustomButton(
// height: getVerticalSize(50),
// text: "Sign in with Facebook",
// margin: getMargin(top: 17),
// variant: ButtonVariant.OutlineBlueA700,
// padding: ButtonPadding.PaddingT14,
// fontStyle: ButtonFontStyle.GilroyMedium16BlueA700,
// prefixWidget: Container(
// padding:
// getPadding(left: 9, top: 4, right: 3),
// margin: getMargin(right: 8),
// decoration: BoxDecoration(
// color: ColorConstant.blue700,
// borderRadius: BorderRadius.circular(
// getHorizontalSize(3))),
// child: CustomImageView(
// svgPath: ImageConstant.imgFacebook))),
// CustomButton(
// height: getVerticalSize(50),
// text: "Sign in with Linkedin",
// margin: getMargin(top: 17),
// variant: ButtonVariant.OutlineBlueA700,
// padding: ButtonPadding.PaddingT14,
// fontStyle: ButtonFontStyle.GilroyMedium16BlueA700,
// prefixWidget: Container(
// margin: getMargin(right: 8),
// child: CustomImageView(
// svgPath: ImageConstant.imgLinkedin11))),
// Align(
// alignment: Alignment.center,
// child: Padding(
// padding: getPadding(top: 28, bottom: 5),
// child: RichText(
// text: TextSpan(children: [
// TextSpan(
// text: "",
// style: TextStyle(
// color: ColorConstant.fromHex(
// "#ff12282a"),
// fontSize: getFontSize(16),
// fontFamily: 'Gilroy',
// fontWeight: FontWeight.w400)),
// TextSpan(
// text: " ",
// style: TextStyle(
// color: ColorConstant.fromHex(
// "#ff12282a"),
// fontSize: getFontSize(16),
// fontFamily: 'Gilroy',
// fontWeight: FontWeight.w700)),
// TextSpan(
// text: "",
// style: TextStyle(
// color: ColorConstant.fromHex(
// "#ff0061ff"),
// fontSize: getFontSize(16),
// fontFamily: 'Gilroy',
// fontWeight: FontWeight.w700,
// decoration:
// TextDecoration.underline))
// ]),
// textAlign: TextAlign.left)))
// ]))),
// ),
// );
// }
//
// // onTapArrowleft6(BuildContext context) {
// // Navigator.pop(context);
// // }
//
// void _validateLoginDetails() {
// FocusManager.instance.primaryFocus?.unfocus();
// if (_formKey.currentState!.validate()) {
// if (errorMessage1 != "" || errorMessage2 != "") {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('Please provide all required details'),
// backgroundColor: Colors.red,
// ),
// );
// } else {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// onVisible: tryLoggingIn,
// content: const Text('Processing...'),
// backgroundColor: Colors.blue,
// ),
// );
// }
// }
// }
//
// void getLoginHelp() {
// //ForgotPasswordPage
// Navigator.push(
// context, MaterialPageRoute(builder: (context) => ForgotPasswordPage()));
// // Navigator.push(
// // context,
// // SlideRightRoute(
// // page: const HadWinMarkdownViewer(
// // screenName: 'Login Help',
// // urlRequested:
// // 'https://raw.githubusercontent.com/brownboycodes/HADWIN/master/docs/HADWIN_WIKI.md')));
// }
//
// void goToSignUpScreen() {
// // Navigator.push(context,
// // MaterialPageRoute(builder: (context) => SignUpUserScreen()))
// // .then((value) => const LoginScreen());
//
// Navigator.push(context,
// MaterialPageRoute(builder: (context) => SignUpUserScreenNew()))
// .then((value) => const LoginScreen());
//
//
// }
//
// }
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import '../../Utils/color_constants.dart';
import '../../utilities/hadwin_markdown_viewer.dart';
import '../../utilities/slide_right_route.dart';
import '../sign_up_screen/SignUpUser.dart';
import '../sign_up_screen/sign_up_step_1.dart';
import 'form_component.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
@override
Widget build(BuildContext context) {
Widget helpInfoContainer = SizedBox(
width: double.infinity,
height: 36,
child: Center(
child: InkWell(
onTap: getLoginHelp,
child: const Text(
'Having trouble logging in?',
style: TextStyle(fontSize: 14, color: Color(0xFF929BAB)),
), // FOR LOGIN HELP
),
),
);
Widget signUpContainer = const SizedBox(
width: double.infinity,
height: 36,
child: Center(
child: InkWell(
//onTap: goToSignUpScreen,
child: Text(
'Or Continue with',
style: TextStyle(fontSize: 14, color: Color(0xFF929BAB)),
), // FOR SIGN UP
),
),
);
List<Widget> loginScreenContents = <Widget>[
_spacing(30),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: SvgPicture.asset(
'assets/images/cloudnsuresp.svg',
width: 300,
),
),
_spacing(30),
const LoginFormComponent(), // ON LOGIN SCREEN
_spacing(10),
signUpContainer,
_spacing(10),
Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
width: double.infinity,
height: 64,
child: ElevatedButton(
onPressed: goToSignUpScreen,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(color: ColorConstant.blue700, width: 2.0),
),
),
child: Text(
'Sign Up',
style: TextStyle(
fontSize: 16,
color: ColorConstant.blue700,
fontWeight: FontWeight.w600,
),
),
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
width: double.infinity,
height: 64,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(color: ColorConstant.blue700, width: 2.0),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
'assets/images/img_google.svg',
),
const SizedBox(
width: 10,
),
Text(
'Sign in with Google',
style: TextStyle(
fontSize: 16,
color: Colors.grey, //ColorConstant.blue700,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
width: double.infinity,
height: 64,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(color: ColorConstant.blue700, width: 2.0),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
'assets/images/img_linkedin_1_1.svg',
),
const SizedBox(
width: 10,
),
Text(
'Sign in with LinkedIn',
style: TextStyle(
fontSize: 16,
color: Colors.grey, //ColorConstant.blue700,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
];
return Scaffold(
body: SingleChildScrollView(
padding: const EdgeInsets.all(45),
child: Column(
children: loginScreenContents,
),
),
);
}
void getLoginHelp() {
Navigator.push(
context,
SlideRightRoute(
page: const HadWinMarkdownViewer(
screenName: 'Login Help',
urlRequested:
'https://raw.githubusercontent.com/brownboycodes/HADWIN/master/docs/HADWIN_WIKI.md')));
}
void goToSignUpScreen() {
Navigator.push(context,
MaterialPageRoute(builder: (context) => SignUpUserScreenNew()))
.then((value) => const LoginScreen());
}
SizedBox _spacing(double height) => SizedBox(
height: height,
);
}
@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../main.dart';
import '../Login Screen/login_screen.dart';
class LogoutService {
static Future<void> logout() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('userData');
await prefs.remove('isLoggedIn');
const storage = FlutterSecureStorage();
await storage.delete(key: 'token');
navigatorKey.currentState!.pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => LoginScreen()),
(route) => false, // Remove all routes from the stack
);
}
}
@@ -0,0 +1,85 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
// OLD: import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; // removed no namespace AGP8 - by Azmat
import 'package:mobile_scanner/mobile_scanner.dart'; // migrated for AGP8 Java17 - by Azmat
class BarcodeScreen extends StatefulWidget {
const BarcodeScreen({super.key});
@override
_BarcodeScreenState createState() => _BarcodeScreenState();
}
class _BarcodeScreenState extends State<BarcodeScreen> {
final _formKey = GlobalKey<FormState>();
String scannedbar_code_scanner = 'No data';
// OLD scanBarcode via FlutterBarcodeScanner - removed no namespace AGP8 - by Azmat
final MobileScannerController barCodeController = MobileScannerController(); // mobile_scanner controller - by Azmat
Future<void> scanBarcode() async {
final String? result = await Navigator.push<String>(
context,
MaterialPageRoute(
builder: (context) => Scaffold(
appBar: AppBar(title: const Text('Scan Barcode')),
body: MobileScanner(
controller: barCodeController,
onDetect: (capture) => Navigator.pop(
context,
capture.barcodes.isNotEmpty ? (capture.barcodes.first.rawValue ?? '') : '',
),
),
),
),
);
if (!mounted) return;
setState(() {
scannedbar_code_scanner = result ?? '';
});
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('BAR CODE')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Center(
child: Column(
children: [
const Text(
'Scanned Barcode:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Text(
scannedbar_code_scanner,
style: const TextStyle(fontSize: 16),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: () {
scanBarcode(); // Trigger barcode scanning
},
icon: const Icon(Icons.camera_alt), // Camera icon
label: const Text('Scan Barcode'),
),
const SizedBox(height: 16),
],
),
),
),
),
),
);
}
}
@@ -0,0 +1,170 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import 'package:qr_flutter/qr_flutter.dart';
// import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:barcode_widget/barcode_widget.dart';
import '../Barcode/Barcode_create_entity_screen.dart';
import '../Qrcode/Qrcode_create_entity_screen.dart';
class QrBarCodeScreen extends StatefulWidget {
const QrBarCodeScreen({super.key});
@override
_QrBarCodeScreenState createState() => _QrBarCodeScreenState();
}
class _QrBarCodeScreenState extends State<QrBarCodeScreen> {
final _formKey = GlobalKey<FormState>();
TextEditingController qr_code_dataController = TextEditingController();
// Function to show the QR code in a dialog
void _showqr_code_dataDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Generated QR Code'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 200, // Set a fixed width for the QR code
height: 200, // Set a fixed height for the QR code
child: QrImageView(
data: qr_code_dataController.text,
version: QrVersions.auto,
embeddedImageStyle:
const QrEmbeddedImageStyle(size: Size(100, 100)),
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop(); // Close the dialog
},
child: const Text('Close'),
),
],
),
);
},
);
}
TextEditingController bar_code_dataController = TextEditingController();
// Function to show the barcode in a dialog
void _show_bar_code_dataDialog(String barcodeData) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Generated Bar Code'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Card(
color: Colors.white,
elevation: 6,
shadowColor: Colors.amber,
child: Padding(
padding: const EdgeInsets.all(16),
child: BarcodeWidget(
data: barcodeData,
barcode: Barcode.code128(),
color: Colors.black,
width: 200,
height: 100,
drawText: false,
),
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop(); // Close the dialog
},
child: const Text('Close'),
),
],
),
);
},
);
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('QR AND BAR CODE')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
// GENERATE QR CODE
TextFormField(
controller: qr_code_dataController,
decoration: const InputDecoration(labelText: 'qr_code_data'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
_showqr_code_dataDialog();
},
child: const Text('Generate Qr')),
// GENERATE BAR CODE
TextFormField(
controller: bar_code_dataController,
decoration: const InputDecoration(labelText: 'Bar Code Data'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
_show_bar_code_dataDialog(bar_code_dataController.text);
},
child: const Text('Generate Bar code'),
),
// QR CODE SCANNER
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const qrcodeScreen()));
},
child: const Text('QR Code Scanner'),
),
// BAR CODE SCANNER
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const BarcodeScreen()));
},
child: const Text('Bar Code Scanner'),
),
],
),
),
),
),
);
}
}
@@ -0,0 +1,85 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
// OLD: import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; // removed no namespace AGP8 - by Azmat
import 'package:mobile_scanner/mobile_scanner.dart'; // migrated for AGP8 Java17 - by Azmat
class qrcodeScreen extends StatefulWidget {
const qrcodeScreen({super.key});
@override
_qrcodeScreenState createState() => _qrcodeScreenState();
}
class _qrcodeScreenState extends State<qrcodeScreen> {
final _formKey = GlobalKey<FormState>();
String scannedqr_code_scanner = 'No data';
// OLD scanQRcode via FlutterBarcodeScanner - removed no namespace AGP8 - by Azmat
final MobileScannerController qrCodeController = MobileScannerController(); // mobile_scanner controller - by Azmat
Future<void> scanQRcode() async {
final String? result = await Navigator.push<String>(
context,
MaterialPageRoute(
builder: (context) => Scaffold(
appBar: AppBar(title: const Text('Scan QR')),
body: MobileScanner(
controller: qrCodeController,
onDetect: (capture) => Navigator.pop(
context,
capture.barcodes.isNotEmpty ? (capture.barcodes.first.rawValue ?? '') : '',
),
),
),
),
);
if (!mounted) return;
setState(() {
scannedqr_code_scanner = result ?? '';
});
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('QR Code')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Center(
child: Column(
children: [
const Text(
'Scanned QRcode:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Text(
scannedqr_code_scanner,
style: const TextStyle(fontSize: 16),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: () {
scanQRcode(); // Trigger barcode scanning
},
icon: const Icon(Icons.camera_alt), // Camera icon
label: const Text('Scan QRcode'),
),
const SizedBox(height: 16),
],
),
),
),
),
),
);
}
}
+127
View File
@@ -0,0 +1,127 @@
import 'package:flutter/material.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../SysParameters/SystemParameterScreen.dart';
class SetupScreen extends StatelessWidget {
const SetupScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Setup Screen")),
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildSetupBlock(context, 'User Maintenance', SysParameter()),
buildSetupBlock(context, 'User Group Maintenance', SysParameter()),
buildSetupBlock(context, 'Menu Maintenance', SysParameter()),
buildSetupBlock(context, 'Menu Access', SysParameter()),
buildSetupBlock(context, 'System Parameter', SysParameter()),
buildSetupBlock(context, 'Access Type', SysParameter()),
// buildSetupBlock(context, 'Report', ReportPage()),
buildSetupBlock(context, 'Dashboard', SysParameter()),
],
),
),
),
);
}
Widget buildSetupBlock(BuildContext context, String title, Widget screen) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => screen),
);
},
child: Card(
color: Colors.white,
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 40, 20, 40),
child: Column(
children: [
// Container(
// height: getSize(
// 55,
// ),
// width: getSize(
// 55,
// ),
// margin: getMargin(
// top: 2,
// ),
// child: Stack(
// alignment: Alignment.center,
// children: [
// Align(
// alignment: Alignment.center,
// child: Container(
// height: getSize(
// 55,
// ),
// width: getSize(
// 55,
// ),
// child: CircularProgressIndicator(
// value: 0.5,
// backgroundColor: ColorConstant.gray30099,
// color: ColorConstant.blueA700,
// ),
// ),
// ),
// Align(
// alignment: Alignment.center,
// child: Text(
// myProjectcount.toString(),
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle.txtGilroyBold18,
// ),
// ),
// ],
// ),
// ),
// Text(
// myProjectcount.toString(),
// style: const TextStyle(
// color: Colors.black,
// fontSize: 12,
// ),
// ),
const SizedBox(height: 3,),
Text(
title,
style: const TextStyle(
color: Colors.black,
fontSize: 10,
),
),
],
),
),
),
);
}
}
Binary file not shown.
@@ -0,0 +1,77 @@
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
import '../../resources/api_constants.dart';
import '../LogoutService/Logoutservice.dart';
class SystemParameterApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
Future<Map<String, dynamic>> getsystemparameters(String token, int id) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/sysparam/getSysParams/$id');
if (response.statusCode == 401) {
LogoutService.logout();
}
final entities = (response.data);
return entities;
} catch (e) {
throw Exception('Failed to get all projects: $e');
}
}
Future<void> updateParameter(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio
.put('$baseUrl/sysparam/updateSysParams/$entityId', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to update projects: $e');
}
}
Future<Map<String, dynamic>> createFile(
Uint8List fileBytes, String fileName, String token) async {
try {
String apiUrl = "$baseUrl/api/logos/upload?ref=test";
final mimeType = 'image/jpeg'; // You can set the appropriate MIME type
FormData formData = FormData.fromMap({
'file': MultipartFile.fromBytes(
fileBytes,
filename: fileName,
contentType: MediaType.parse(mimeType),
),
});
Dio dio = Dio(); // Create a new Dio instance
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.post(apiUrl, data: formData);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode == 200) {
print('File uploaded successfully');
return response.data; // Return the response data on success
} else {
print('Failed to upload file with status: ${response.statusCode}');
// You might want to handle this error case more explicitly
throw Exception('Failed to upload file');
}
} catch (error) {
print('Error occurred during form submission: $error');
// You might want to handle this error case more explicitly
throw Exception('Error during file upload: $error');
}
}
}
@@ -0,0 +1,533 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import 'SystemParameterApiService.dart';
class SysParameter extends StatefulWidget {
final int sysparameter=1;
// const SysParameter({Key? key, required this.sysparameter}) : super(key: key);
@override
_SysParameterState createState() => _SysParameterState();
}
class _SysParameterState extends State<SysParameter> {
TextEditingController schedulerTimerController = TextEditingController();
TextEditingController leaseTaxCodeController = TextEditingController();
TextEditingController vesselConfirmationController = TextEditingController();
TextEditingController rowToDisplayController = TextEditingController();
TextEditingController linkToDisplayController = TextEditingController();
TextEditingController rowToAddController = TextEditingController();
TextEditingController lovRowToDisplayController = TextEditingController();
TextEditingController lovLinkToDisplayController = TextEditingController();
TextEditingController oidServerNameController = TextEditingController();
TextEditingController oidBaseController = TextEditingController();
TextEditingController oidAdminUserController = TextEditingController();
TextEditingController oidServerPortController = TextEditingController();
TextEditingController userDefaultGroupController = TextEditingController();
TextEditingController defaultDepartmentController = TextEditingController();
TextEditingController defaultPositionController = TextEditingController();
TextEditingController singleChargeController = TextEditingController();
TextEditingController firstDayOfWeekController = TextEditingController();
TextEditingController hourPerShiftController = TextEditingController();
TextEditingController cnBillingFrequencyController = TextEditingController();
TextEditingController billingDepartmentCodeController = TextEditingController();
TextEditingController basePriceListController = TextEditingController();
TextEditingController nonContainerServiceController = TextEditingController();
TextEditingController ediMaeSchedulerController = TextEditingController();
TextEditingController ediSchedulerController = TextEditingController();
TextEditingController lastController = TextEditingController();
TextEditingController companynameController = TextEditingController();
bool isRegistrationAllow=false;
Map<String,dynamic> formData = {};
var logoname;
var logopath;
SystemParameterApiService apiService = SystemParameterApiService();
String? uploadimageurl;
Uint8List? _imageBytes; // Uint8List to store the image data
String? _imageFileName;
late Map<String,dynamic> sysparameter;
@override
void initState() {
_loadParameters();
}
Future<void> _loadParameters() async {
final token = await TokenManager.getToken();
try {
final projectData = await apiService.getsystemparameters(token!,widget.sysparameter);
setState(() {
sysparameter = projectData;
lastController.text = "('SYSADMIN','ITSUPPORTMSC')";
schedulerTimerController.text = sysparameter['schedulerTime'].toString()??'';
isRegistrationAllow = sysparameter['regitrationAllowed']??false;
leaseTaxCodeController.text = sysparameter['leaseTaxCode'].toString()??'';
vesselConfirmationController.text = sysparameter['vesselConfProcessLimit'].toString()??'';
rowToDisplayController.text = sysparameter['rowToDisplay'].toString()??'';
linkToDisplayController.text = sysparameter['linkToDisplay'].toString()??'';
rowToAddController.text = sysparameter['rowToAdd'].toString()??'';
lovRowToDisplayController.text = sysparameter['lovRowToDisplay'].toString()??'';
lovLinkToDisplayController.text = sysparameter['lovLinkToDisplay'].toString()??'';
oidServerNameController.text = sysparameter['oidserverName'].toString()??'';
oidBaseController.text = sysparameter['oidBase'].toString()??'';
oidAdminUserController.text = sysparameter['oidAdminUser'].toString()??'';
oidServerPortController.text = sysparameter['oidServerPort'].toString()??'';
userDefaultGroupController.text = sysparameter['userDefaultGroup'].toString()??'';
defaultDepartmentController.text = sysparameter['defaultDepartment'].toString()??'';
defaultPositionController.text = sysparameter['defaultPosition'].toString()??'';
singleChargeController.text = sysparameter['singleCharge'].toString()??'';
firstDayOfWeekController.text = sysparameter['firstDayOftheWeek'].toString()??'';
hourPerShiftController.text = sysparameter['hourPerShift'].toString()??'';
cnBillingFrequencyController.text = sysparameter['cnBillingFrequency'].toString()??'';
billingDepartmentCodeController.text = sysparameter['billingDepartmentCode'].toString()??'';
basePriceListController.text = sysparameter['basePriceList'].toString()??'';
nonContainerServiceController.text = sysparameter['nonContainerServiceOrder'].toString()??'';
ediMaeSchedulerController.text = sysparameter['ediMaeSchedulerONOFF'].toString()??'';
ediSchedulerController.text = sysparameter['ediSchedulerONOFF'].toString()??'';
lastController.text = "('SYSADMIN','ITSUPPORTMSC')"??'';
companynameController.text = sysparameter['company_Display_Name'].toString()??'';
print(sysparameter['schedulerTime']);
});
} catch (e) {
print('Failed to load projects: $e');
}
}
Future<void> _uploadImageFile() async {
final imagePicker = ImagePicker();
try {
final pickedImage =
await imagePicker.pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
final imageBytes = await pickedImage.readAsBytes();
setState(() {
_imageBytes = imageBytes;
_imageFileName = pickedImage.name; // Store the file name
});
}
_submitImage();
} catch (e) {
print(e);
}
}
Future<void> _submitImage() async {
if (_imageBytes == null) {
// Show an error message if no image is selected
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Please select an image.'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
return;
}
if (_imageFileName == null) {
// Handle the case where _imageFileName is null (no file name provided)
print('File name is missing.');
return;
}
try {
final token = await TokenManager.getToken();
Map<String,dynamic> fileuploadeddata = await apiService.createFile(_imageBytes!, _imageFileName!, token!);
logoname = fileuploadeddata['image_name'];
logopath = fileuploadeddata['image_path'];
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to upload image: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "System Parameter")),
body: Material(child:SingleChildScrollView( // Wrap the form in a SingleChildScrollView
scrollDirection: Axis.vertical, // Allow vertical scrolling
child:Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildFieldWithTooltip(
fieldName: 'Scheduler Timer',
controller: schedulerTimerController,
tooltip: 'Tooltip for Scheduler Timer',
),
_buildFieldWithTooltip(
fieldName: 'Lease Tax Code',
controller: leaseTaxCodeController,
tooltip: 'Tooltip for Lease Tax Code',
),
_buildFieldWithTooltip(
fieldName: 'Vessel Confirmation Process Limit',
controller: vesselConfirmationController,
tooltip: 'Tooltip for Vessel Confirmation Process Limit',
),
_buildFieldWithTooltip(
fieldName: 'Row To Display',
controller: rowToDisplayController,
tooltip: 'Tooltip for Row To Display',
),
_buildFieldWithTooltip(
fieldName: 'Link To Display',
controller: linkToDisplayController,
tooltip: 'Tooltip for Link To Display',
),
_buildFieldWithTooltip(
fieldName: 'Row To Add',
controller: rowToAddController,
tooltip: 'Tooltip for Row To Add',
),
_buildFieldWithTooltip(
fieldName: 'LOV Row To Display',
controller: lovRowToDisplayController,
tooltip: 'Tooltip for LOV Row To Display',
),
_buildFieldWithTooltip(
fieldName: 'LOV Link To Display',
controller: lovLinkToDisplayController,
tooltip: 'Tooltip for LOV Link To Display',
),
_buildFieldWithTooltip(
fieldName: 'OID Server Name',
controller: oidServerNameController,
tooltip: 'Tooltip for OID Server Name',
),
_buildFieldWithTooltip(
fieldName: 'OID Base',
controller: oidBaseController,
tooltip: 'Tooltip for OID Base',
),
_buildFieldWithTooltip(
fieldName: 'OID Admin User',
controller: oidAdminUserController,
tooltip: 'Tooltip for OID Admin User',
),
_buildFieldWithTooltip(
fieldName: 'OID Server Port',
controller: oidServerPortController,
tooltip: 'Tooltip for OID Server Port',
),
_buildFieldWithTooltip(
fieldName: 'User Default Group',
controller: userDefaultGroupController,
tooltip: 'Tooltip for User Default Group',
),
_buildFieldWithTooltip(
fieldName: 'Default Department',
controller: defaultDepartmentController,
tooltip: 'Tooltip for Default Department',
),
_buildFieldWithTooltip(
fieldName: 'Default Position',
controller: defaultPositionController,
tooltip: 'Tooltip for Default Position',
),
_buildFieldWithTooltip(
fieldName: 'Single Charge',
controller: singleChargeController,
tooltip: 'Tooltip for Single Charge',
),
_buildFieldWithTooltip(
fieldName: 'First Day of The Week',
controller: firstDayOfWeekController,
tooltip: 'Tooltip for First Day of The Week',
),
_buildFieldWithTooltip(
fieldName: 'Hour per Shift',
controller: hourPerShiftController,
tooltip: 'Tooltip for Hour per Shift',
),
_buildFieldWithTooltip(
fieldName: 'CN Billing Frequency',
controller: cnBillingFrequencyController,
tooltip: 'Tooltip for CN Billing Frequency',
),
_buildFieldWithTooltip(
fieldName: 'Billing Department Code',
controller: billingDepartmentCodeController,
tooltip: 'Tooltip for Billing Department Code',
),
_buildFieldWithTooltip(
fieldName: 'Base Price List',
controller: basePriceListController,
tooltip: 'Tooltip for Base Price List',
),
_buildFieldWithTooltip(
fieldName: 'Non-Container Service Order Auto-Approval Department Code',
controller: nonContainerServiceController,
tooltip: 'Tooltip for Non-Container Service Order Auto-Approval Department Code',
),
_buildFieldWithTooltip(
fieldName: 'EDI MAE Scheduler ON/OFF',
controller: ediMaeSchedulerController,
tooltip: 'Tooltip for EDI MAE Scheduler ON/OFF',
),
_buildFieldWithTooltip(
fieldName: 'EDI Scheduler ON/OFF',
controller: ediSchedulerController,
tooltip: 'Tooltip for EDI Scheduler ON/OFF',
),
_buildFieldWithTooltip(
fieldName: 'Company Name',
controller: companynameController,
tooltip: 'Company Name',
),
Text("Is Registration Allowed?",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
Row(
children: [
Radio(
value: true,
groupValue: isRegistrationAllow,
onChanged: (value) {
setState(() {
isRegistrationAllow = value as bool;
});
},
),
Text("Yes",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
Radio(
value: false,
groupValue: isRegistrationAllow,
onChanged: (value) {
setState(() {
isRegistrationAllow = value as bool;
});
},
),
Text("No",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
],
),
ElevatedButton(
onPressed: () {
_uploadImageFile();
},
style: ButtonStyle(
backgroundColor: _imageBytes==null?MaterialStateProperty.all<Color>(Colors.red):MaterialStateProperty.all<Color>(Colors.green), // Change to the desired color
),
child: _imageBytes == null
? Text("Pick a Company Logo",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800)
: Text("Company Logo uploaded Successful",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
),
Tooltip(
message: 'Allow customer code for MSC taulia CSV generation',
child: Column(
children: [
Text("i",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
CustomTextFormField(
focusNode: FocusNode(),
controller:lastController,
margin: getMargin(top: 7),
textInputType:
TextInputType.text),
],
)
// TextFormField(
// controller: lastController,
// decoration: const InputDecoration(
// labelText: 'i',
// ),
// ),
),
CustomButton(
height: getVerticalSize(50),
text: "Save",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
formData['regitrationAllowed'] = isRegistrationAllow;
formData['schedulerTime']=schedulerTimerController.text;
formData['leaseTaxCode']=leaseTaxCodeController.text;
formData['vesselConfProcessLimit']=vesselConfirmationController.text;
formData['rowToDisplay']=rowToDisplayController.text;
formData['linkToDisplay']=linkToDisplayController.text;
formData['rowToAdd']=rowToAddController.text;
formData['lovRowToDisplay']=lovRowToDisplayController.text;
formData['lovLinkToDisplay']=lovLinkToDisplayController.text;
formData['oidserverName']=oidServerNameController.text;
formData['oidBase']=oidBaseController.text;
formData['oidAdminUser']=oidAdminUserController.text;
formData['oidServerPort']=oidServerPortController.text;
formData['userDefaultGroup']=userDefaultGroupController.text;
formData['defaultDepartment']=defaultDepartmentController.text;
formData['defaultPosition']=defaultPositionController.text;
formData['singleCharge']=singleChargeController.text;
formData['firstDayOftheWeek']=firstDayOfWeekController.text;
formData['hourPerShift']=hourPerShiftController.text;
formData['cnBillingFrequency']=cnBillingFrequencyController.text;
formData['billingDepartmentCode']=billingDepartmentCodeController.text;
formData['basePriceList']=basePriceListController.text;
formData['nonContainerServiceOrder']=nonContainerServiceController.text;
formData['ediMaeSchedulerONOFF']=ediMaeSchedulerController.text;
formData['ediSchedulerONOFF']=ediSchedulerController.text;
//formData['']=lastController.text;
formData['upload_Logo_name']=logoname;
formData['upload_Logo_path']=logopath;
formData['company_Display_Name']=companynameController.text;
final token = await TokenManager.getToken();
try {
print("token is : $token");
print(formData);
if (formData != null) {
// Create new project
apiService.updateParameter(token!, widget.sysparameter, formData);
}
Navigator.pop(context);
// Add navigation or any other logic after successful create/update
} catch (e) {
print('error is $e');
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text(
'Failed to ${widget.sysparameter == null ? 'create' : 'update'} project: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
},
),
],
),
),
)));
}
Widget _buildFieldWithTooltip({
required String fieldName,
required TextEditingController controller,
required String tooltip,
}) {
return Tooltip(
message: tooltip,
child:
Padding(
padding: getPadding(top: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("$fieldName",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
CustomTextFormField(
focusNode: FocusNode(),
controller:controller,
hintText: "Enter Your $fieldName",
margin: getMargin(top: 7),
textInputType:
TextInputType.text)
])),
// TextFormField(
// controller: controller,
// decoration: InputDecoration(
// labelText: fieldName,
// ),
// ),
);
}
}
@@ -0,0 +1,279 @@
import 'package:flutter/material.dart';
import '../../providers/token_manager.dart';
import 'dynamic_form_service.dart';
class EditForm extends StatefulWidget {
final Map<String, dynamic> formData;
EditForm({required this.formData});
@override
_EditFormState createState() => _EditFormState();
}
class _EditFormState extends State<EditForm> {
TextEditingController formNameController = TextEditingController();
TextEditingController formDescController = TextEditingController();
TextEditingController relatedToController = TextEditingController();
TextEditingController pageEventController = TextEditingController();
TextEditingController buttonCaptionController = TextEditingController();
final DynamicForApiService apiService = DynamicForApiService();
List<dynamic> components = []; // List to store table data
List<dynamic> relatedToFixedDropdown = ['Menu', 'Related To',];
List<dynamic> pageEventFixedDropdown = ['OnClick', 'OnBlur',];
List<dynamic> typeFixedDropdown = ['text', 'dropdown','date','checkbox','textarea','togglebutton'];
List<dynamic> mappingFixedDropdown = ['TEXTFIELD1', 'TEXTFIELD2','TEXTFIELD3','TEXTFIELD4','TEXTFIELD5','TEXTFIELD6','TEXTFIELD7','TEXTFIELD8','TEXTFIELD9','TEXTFIELD10','TEXTFIELD11','TEXTFIELD12','TEXTFIELD13','TEXTFIELD14','TEXTFIELD15','TEXTFIELD16','TEXTFIELD17','TEXTFIELD18','TEXTFIELD19','TEXTFIELD20','TEXTFIELD21','TEXTFIELD22','TEXTFIELD23',
'TEXTFIELD24','TEXTFIELD25','TEXTFIELD26','LONGTEXT1','LONGTEXT2','LONGTEXT3','LONGTEXT4',];
List<dynamic> truefalseFixedDropdown = ['true', 'false',];
@override
void initState() {
super.initState();
// Initialize text controllers with the data from the selected row
formNameController.text = widget.formData['form_name'] ?? '';
formDescController.text = widget.formData['form_desc'] ?? '';
relatedToController.text = widget.formData['related_to'] ?? '';
pageEventController.text = widget.formData['page_event'] ?? '';
buttonCaptionController.text = widget.formData['button_caption'] ?? '';
// Initialize the components data, or you can load it from formData['components'].
// For this example, we'll use an empty list.
components = widget.formData['components'] ?? [];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Form'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
controller: formNameController,
decoration: InputDecoration(labelText: 'Form Name'),
),
TextFormField(
controller: formDescController,
decoration: InputDecoration(labelText: 'Form Description'),
),
DropdownButtonFormField<String>(
value: relatedToController.text,
decoration:
const InputDecoration(labelText: 'Select Related To'),
items: [
...relatedToFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
relatedToController.text = value!;
});
},
),
DropdownButtonFormField<String>(
value: pageEventController.text,
decoration:
const InputDecoration(labelText: 'Select Page Event'),
items: [
...pageEventFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
pageEventController.text = value!;
});
},
),
TextFormField(
controller: buttonCaptionController,
decoration: InputDecoration(labelText: 'Button Caption'),
),
const Text('Components Details'),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: const <DataColumn>[
DataColumn(label: Text('Label')),
DataColumn(label: Text('Type')),
DataColumn(label: Text('Mapping')),
DataColumn(label: Text('Mandatory')),
DataColumn(label: Text('Readonly')),
DataColumn(label: Text('Drop Values')),
DataColumn(label: Text('SP')),
DataColumn(label: Text('Actions'), numeric: false), // Add Actions column
],
rows: components.asMap().entries.map((entry) {
final index = entry.key;
final component = entry.value;
return DataRow(
cells: <DataCell>[
DataCell(TextField(
controller: TextEditingController(text: component['label'] ?? ''),
onChanged: (value){
component['label']=value;
},
)),
DataCell(
DropdownButtonFormField<String>(
value: component['type'],
decoration:
const InputDecoration(labelText: 'Select Type'),
items: [
...typeFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
component['type'] = value;
});
},
),
),
DataCell(
DropdownButtonFormField<String>(
value: component['mapping'],
decoration:
const InputDecoration(labelText: 'Select Mapping'),
items: [
...mappingFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
component['mapping'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['mandatory'] ?? ''),
onChanged: (value){
component['mandatory']=value;
},
)),
DataCell(
DropdownButtonFormField<String>(
value: component['readonly'],
decoration:
const InputDecoration(labelText: 'Select Read Only'),
items: [
...truefalseFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
component['readonly'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['drop_values'] ?? ''),
onChanged: (value){
component['drop_values']=value;
},
)),
DataCell(TextField(
controller: TextEditingController(text: component['sp'] ?? ''),
onChanged: (value){
component['sp']=value;
},
)),
DataCell(
ElevatedButton(
onPressed: () {
setState(() {
components.removeAt(index);
});
},
child: Text('Delete'),
),
),
],
);
}).toList(),
),
),
ElevatedButton(
onPressed: () {
// Add a new row to the components table
components.add({
'label': '',
'type': null,
'mapping': null,
'mandatory': '',
'readonly': null,
'drop_values': '',
'sp': '',
});
setState(() {}); // Refresh the UI to show the new row
},
child: Text('Add Row'),
),
ElevatedButton(
onPressed: () async {
// Save the updated data back to the original data list
widget.formData['form_name'] = formNameController.text;
widget.formData['form_desc'] = formDescController.text;
widget.formData['related_to'] = relatedToController.text;
widget.formData['page_event'] = pageEventController.text;
widget.formData['button_caption'] = buttonCaptionController.text;
widget.formData['components'] = components;
final token = await TokenManager.getToken();
apiService.updateDynamicForm(token!, widget.formData['form_id'], widget.formData);
Navigator.of(context).pop();
},
child: Text('Update'),
),
],
),
),
),
);
}
}
@@ -0,0 +1,333 @@
import 'package:flutter/material.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_dropdown_field.dart';
import '../../widgets/custom_text_form_field.dart';
import 'dynamic_form_service.dart';
class CreateForm extends StatefulWidget {
@override
_CreateFormState createState() => _CreateFormState();
}
class _CreateFormState extends State<CreateForm> {
TextEditingController formNameController = TextEditingController();
TextEditingController formDescController = TextEditingController();
TextEditingController relatedToController = TextEditingController();
TextEditingController pageEventController = TextEditingController();
TextEditingController buttonCaptionController = TextEditingController();
final DynamicForApiService apiService = DynamicForApiService();
List<Map<String, dynamic>> components = [];
List<dynamic> relatedToFixedDropdown = ['Menu', 'Related To',];
List<dynamic> pageEventFixedDropdown = ['OnClick', 'OnBlur',];
List<dynamic> typeFixedDropdown = ['text', 'dropdown','date','checkbox','textarea','togglebutton'];
List<dynamic> mappingFixedDropdown = ['TEXTFIELD1', 'TEXTFIELD2','TEXTFIELD3','TEXTFIELD4','TEXTFIELD5','TEXTFIELD6','TEXTFIELD7','TEXTFIELD8','TEXTFIELD9','TEXTFIELD10','TEXTFIELD11','TEXTFIELD12','TEXTFIELD13','TEXTFIELD14','TEXTFIELD15','TEXTFIELD16','TEXTFIELD17','TEXTFIELD18','TEXTFIELD19','TEXTFIELD20','TEXTFIELD21','TEXTFIELD22','TEXTFIELD23',
'TEXTFIELD24','TEXTFIELD25','TEXTFIELD26','LONGTEXT1','LONGTEXT2','LONGTEXT3','LONGTEXT4',];
List<dynamic> truefalseFixedDropdown = ['true', 'false',];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleft,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Create Dynamic Form"),),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Form Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Form Name",
controller: formNameController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Form Description",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Form Description",
controller: formDescController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Select Related To",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900,
),
CustomDropdownFormField(
items: [
...relatedToFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item, style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
relatedToController.text = value!;
});
},
)
],
),
),
Padding(
padding: getPadding(top: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Select Page Event",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900,
),
CustomDropdownFormField(
items: [
...pageEventFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
pageEventController.text = value!;
});
},
)
],
),
),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Button Caption",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Button Caption",
controller: buttonCaptionController,
margin: getMargin(top: 6))
])),
const Text('Components Details'),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: const <DataColumn>[
DataColumn(label: Text('Label')),
DataColumn(label: Text('Type')),
DataColumn(label: Text('Mapping')),
DataColumn(label: Text('Mandatory')),
DataColumn(label: Text('Readonly')),
DataColumn(label: Text('Drop Values')),
DataColumn(label: Text('SP')),
],
rows: components.asMap().entries.map((entry) {
final index = entry.key;
final component = entry.value;
bool? isReadonly = false;
return DataRow(
cells: <DataCell>[
DataCell(TextField(
controller: TextEditingController(text: component['label'] ?? ''),
onChanged: (value) {
component['label'] = value;
},
)),
DataCell(
DropdownButtonFormField<String>(
decoration:
const InputDecoration(labelText: 'Select Type'),
items: [
...typeFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
component['type'] = value;
});
},
),
),
DataCell(
DropdownButtonFormField<String>(
decoration:
const InputDecoration(labelText: 'Select Mapping'),
items: [
...mappingFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
component['mapping'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['mandatory'] ?? ''),
onChanged: (value) {
component['mandatory'] = value;
},
)),
DataCell(
DropdownButtonFormField<String>(
decoration:
const InputDecoration(labelText: 'Select Read Only'),
items: [
...truefalseFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
component['readonly'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['drop_values'] ?? ''),
onChanged: (value) {
component['drop_values'] = value;
},
)),
DataCell(TextField(
controller: TextEditingController(text: component['sp'] ?? ''),
onChanged: (value) {
component['sp'] = value;
},
)),
],
);
}).toList(),
),
),
CustomButton(
height: getVerticalSize(50),
text: "Add Row",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
components.add({
'label': '',
'type': '',
'mapping': '',
'mandatory': '',
'readonly': '',
'drop_values': '',
'sp': '',
});
setState(() {});
},
),
CustomButton(
height: getVerticalSize(50),
text: "Create Dynamic Form",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
final dynamicFormData = {
'form_name': formNameController.text,
'form_desc': formDescController.text,
'related_to': relatedToController.text,
'page_event': pageEventController.text,
'button_caption': buttonCaptionController.text,
'components': components,
};
final token = await TokenManager.getToken();
apiService.createDynamicForm(token!, dynamicFormData);
Navigator.of(context).pop();
},
),
],
),
),
),
);
}
}
@@ -0,0 +1,100 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../../resources/api_constants.dart';
import '../LogoutService/Logoutservice.dart';
class DynamicForApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
//api/dynamic_form_build
Future<void> BuildForms(String token, int id) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response =
await dio.get('$baseUrl/api/dynamic_form_build?form_id=$id');
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode! <= 209) {
Fluttertoast.showToast(
msg: 'Build success',
backgroundColor: Colors.red,
);
} else {
Fluttertoast.showToast(
msg: 'Unable to build',
backgroundColor: Colors.red,
);
throw Exception('Unexpected response type');
}
} catch (e) {
throw Exception('Failed to Build form: $e');
}
}
Future<List<Map<String, dynamic>>> getallDynamicForms(
String token,
) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/api/form_setup');
if (response.statusCode == 401) {
LogoutService.logout();
}
final responseData = response.data['items'];
if (responseData is List) {
final entities = responseData.cast<Map<String, dynamic>>();
return entities;
} else if (responseData is Map<String, dynamic>) {
return [responseData];
} else {
throw Exception('Unexpected response type');
}
} catch (e) {
throw Exception('Failed to get modules by projectId: $e');
}
}
Future<void> createDynamicForm(
String token, Map<String, dynamic> entity) async {
try {
print("in post api...$entity");
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio.post('$baseUrl/api/form_setup', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to create Dynamic form: $e');
}
}
Future<void> updateDynamicForm(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response =
await dio.put('$baseUrl/api/form_setup/$entityId', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to update Dynamic form: $e');
}
}
Future<void> deleteDynamicForm(String token, int entityId) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio.delete('$baseUrl/api/form_setup/$entityId');
if (response.statusCode == 401) {
LogoutService.logout();
}
} catch (e) {
throw Exception('Failed to delete Dynamic form: $e');
}
}
}
@@ -0,0 +1,224 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import '../../Utils/color_constants.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import 'UpdatedynamicForm.dart';
import 'create_dynamicform.dart';
import 'dynamic_form_service.dart';
class DynamicForm extends StatefulWidget {
@override
_DynamicFormState createState() => _DynamicFormState();
}
class _DynamicFormState extends State<DynamicForm> {
final DynamicForApiService apiService = DynamicForApiService();
late List<Map<String, dynamic>> allData = [];
bool isLoading = false;
@override
void initState() {
super.initState();
_loadDynamicForms();
}
Future<void> _loadDynamicForms() async {
final token = await TokenManager.getToken();
try {
final alData = await apiService.getallDynamicForms(token!);
setState(() {
allData = alData;
print('allData fetched...');
});
isLoading = true;
} catch (e) {
isLoading = true;
print('Failed to load allData: $e');
}
}
Future<void> deleteEntity(Map<String, dynamic> entity) async {
try {
final token = await TokenManager.getToken();
await apiService.deleteDynamicForm(token!, entity['form_id']);
setState(() {
allData.remove(entity);
});
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to delete entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
actions: [
GestureDetector(
child: Icon(
Icons.add,
color: Colors.black,
size: 20,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CreateForm(),
),
).then((value) => {_loadDynamicForms()});
},
),
const SizedBox(
width: 20,
)
],
centerTitle: true,
title: AppbarTitle(text: "Dynamic Form")),
body: isLoading == false
? const Center(child: CircularProgressIndicator())
: allData.isEmpty
? const Center(
child: Text('No Services available.'),
)
: Scrollable(
viewportBuilder:
(BuildContext context, ViewportOffset position) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: [
DataColumn(label: Text('Form Name')),
DataColumn(label: Text('Form Description')),
DataColumn(label: Text('Related To')),
DataColumn(label: Text('Page Event')),
DataColumn(label: Text('Button Caption')),
DataColumn(label: Text('Build')),
DataColumn(label: Text('Actions')),
],
rows: allData.map((module) {
return DataRow(
cells: [
DataCell(
Text('${module['form_name'] ?? 'N/A'}')),
DataCell(
Text('${module['form_desc'] ?? 'N/A'}')),
DataCell(
Text('${module['related_to'] ?? 'N/A'}')),
DataCell(
Text('${module['page_event'] ?? 'N/A'}')),
DataCell(Text(
'${module['button_caption'] ?? 'N/A'}')),
DataCell(Row(
children: [
ElevatedButton(
onPressed: () async {
print(module);
final token =
await TokenManager.getToken();
apiService.BuildForms(
token!, module['form_id']);
},
child: Text("build"),
style: ElevatedButton.styleFrom(
backgroundColor: ColorConstant.blue700,
),
)
],
)),
DataCell(Row(
children: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
EditForm(formData: module),
),
).then(
(value) => {_loadDynamicForms()});
},
icon: Icon(Icons.edit),
),
IconButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
'Confirm Deletion'),
content: const Text(
'Are you sure you want to delete this Module?'),
actions: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Delete'),
onPressed: () {
Navigator.of(context).pop();
deleteEntity(module);
},
),
],
);
},
);
},
icon: Icon(Icons.delete),
),
],
)),
],
);
}).toList(),
),
),
);
},
),
);
}
}
@@ -0,0 +1,130 @@
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import '../../Utils/color_constants.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../Login Screen/login_screen.dart';
class ForgotPasswordPage extends StatefulWidget {
@override
_ForgotPasswordPageState createState() => _ForgotPasswordPageState();
}
class _ForgotPasswordPageState extends State<ForgotPasswordPage> {
final TextEditingController emailController = TextEditingController();
String message = '';
bool isLoading = false; // Added to track loading state
Future<void> sendForgotPasswordRequest() async {
setState(() {
isLoading = true; // Show loading indicator when sending request
});
final email = emailController.text;
final token = await TokenManager.getToken();
const String baseUrl = ApiConstants.baseUrl;
final response = await http.post(
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
Uri.parse('$baseUrl/api/resources/forgotpassword?email=$email'),
);
if (response.statusCode == 200) {
setState(() {
message = 'An email with a reset link has been sent to $email.';
});
// Delay for 3 seconds and then navigate to the login page
Future.delayed(Duration(seconds: 3), () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => LoginScreen()));
});
} else {
setState(() {
message = 'Failed to send the reset link. Please try again.';
});
}
setState(() {
isLoading = false; // Hide loading indicator when the request is complete
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Forgot Password")),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Email",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Email",
controller: emailController,
margin: getMargin(top: 6))
])),
CustomButton(
height: getVerticalSize(50),
text: "Send me an access link",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
sendForgotPasswordRequest();
},
),
isLoading
? CircularProgressIndicator(
color: ColorConstant.blue700,
) // Show loading indicator when isLoading is true
: Text(message, style: AppStyle.txtGilroyMedium16Bluegray900),
if (message.contains('An email with a reset link'))
InkWell(
child: Text('Click here to return to login',
style: AppStyle.txtGilroyMedium16Bluegray900),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const LoginScreen()));
},
),
],
),
),
);
}
}
@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
class CustomizedFooter extends StatelessWidget {
final IconData homeIcon;
final IconData squareIcon;
final IconData addIcon;
final List<String> labels;
final List<Function()> onTapActions;
CustomizedFooter({
required this.homeIcon,
required this.squareIcon,
required this.addIcon,
required this.labels,
required this.onTapActions,
});
@override
Widget build(BuildContext context) {
assert(labels.length == 3 && onTapActions.length == 3);
return Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3),
),
],
),
child: BottomNavigationBar(
onTap: (index) {
onTapActions[index]();
},
items: [
BottomNavigationBarItem(
icon: Icon(homeIcon),
label: labels[0],
),
BottomNavigationBarItem(
icon: Icon(squareIcon),
label: labels[1],
),
BottomNavigationBarItem(
icon: Icon(addIcon),
label: labels[2],
),
],
),
);
}
}
@@ -0,0 +1,339 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg_provider/flutter_svg_provider.dart' as fs;
import '../../Utils/color_constants.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_style.dart';
import '../LogoutService/Logoutservice.dart';
import 'package:http/http.dart' as http;
class Listgroup524ItemWidget extends StatefulWidget {
final Map<String, dynamic> userData;
Listgroup524ItemWidget({required this.userData});
@override
State<Listgroup524ItemWidget> createState() => _Listgroup524ItemWidgetState();
}
class _Listgroup524ItemWidgetState extends State<Listgroup524ItemWidget> {
int myProjectcount = 0;
int sharedWithMeCount = 0;
int allprojectCount = 0;
@override
void initState() {
super.initState();
fetchData();
}
Future<void> fetchData() async {
print("working");
final token = await TokenManager.getToken();
print(token);
String baseUrl = ApiConstants.baseUrl;
var myProjectcountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_myproject'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
var sharedWithMeCountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_sharedwithme'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
var allProjectsCountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_allproject'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
if (myProjectcountres.statusCode == 401) {
LogoutService.logout();
}
print(myProjectcountres.statusCode);
if (myProjectcountres.statusCode <= 209 &&
sharedWithMeCountres.statusCode <= 209) {
final myProjectData = jsonDecode(myProjectcountres.body);
final sharedData = jsonDecode(sharedWithMeCountres.body);
final allData = jsonDecode(allProjectsCountres.body);
setState(() {
myProjectcount = myProjectData;
sharedWithMeCount = sharedData;
allprojectCount = allData;
});
} else {
// Handle errors
print('Failed to fetch data');
}
}
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "myproject"), // Get all projects
// ),
// );
},
child: Card(
color: Colors.white,
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Column(
children: [
Container(
height: getSize(
55,
),
width: getSize(
55,
),
margin: getMargin(
top: 2,
),
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.center,
child: Container(
height: getSize(
55,
),
width: getSize(
55,
),
child: CircularProgressIndicator(
value: 0.5,
backgroundColor: ColorConstant.gray30099,
color: ColorConstant.blueA700,
),
),
),
Align(
alignment: Alignment.center,
child: Text(
myProjectcount.toString(),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyBold18,
),
),
],
),
),
// Text(
// myProjectcount.toString(),
// style: const TextStyle(
// color: Colors.black,
// fontSize: 12,
// ),
// ),
const SizedBox(
height: 3,
),
const Text(
'My Projects',
style: TextStyle(
color: Colors.black,
fontSize: 10,
),
),
],
),
),
),
),
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "sharedproject"), // Get all projects
// ),
// );
},
child: Card(
color: Colors.white,
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Column(
children: [
Container(
height: getSize(
55,
),
width: getSize(
55,
),
margin: getMargin(
top: 2,
),
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.center,
child: Container(
height: getSize(
55,
),
width: getSize(
55,
),
child: CircularProgressIndicator(
value: 0.5,
backgroundColor: ColorConstant.gray30099,
color: ColorConstant.blueA700,
),
),
),
Align(
alignment: Alignment.center,
child: Text(
sharedWithMeCount.toString(),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyBold18,
),
),
],
),
),
// Text(
// myProjectcount.toString(),
// style: const TextStyle(
// color: Colors.black,
// fontSize: 12,
// ),
// ),
const SizedBox(
height: 3,
),
const Text(
'Shared with me',
style: TextStyle(
color: Colors.black,
fontSize: 10,
),
),
],
),
),
),
),
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "allproject"), // Get all projects
// ),
// );
},
child: Card(
color: Colors.white,
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Column(
children: [
Container(
height: getSize(
55,
),
width: getSize(
55,
),
margin: getMargin(
top: 2,
),
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.center,
child: Container(
height: getSize(
55,
),
width: getSize(
55,
),
child: CircularProgressIndicator(
value: 0.5,
backgroundColor: ColorConstant.gray30099,
color: ColorConstant.blueA700,
),
),
),
Align(
alignment: Alignment.center,
child: Text(
allprojectCount.toString(),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyBold18,
),
),
],
),
),
// Text(
// myProjectcount.toString(),
// style: const TextStyle(
// color: Colors.black,
// fontSize: 12,
// ),
// ),
const SizedBox(
height: 3,
),
const Text(
'All Projects',
style: TextStyle(
color: Colors.black,
fontSize: 10,
),
),
],
),
),
),
),
],
),
),
);
}
}
@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
// ignore: must_be_immutable
class ListtextItemWidget extends StatelessWidget {
ListtextItemWidget();
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Lorem ipsum",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold16,
),
Padding(
padding: getPadding(
top: 10,
),
child: Text(
"Lorem ipsum",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyRegular14,
),
),
],
),
Padding(
padding: getPadding(
top: 11,
bottom: 13,
),
child: Text(
"7.5",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold18,
),
),
],
);
}
}
@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
class LocalSplashScreenComponent extends StatelessWidget {
const LocalSplashScreenComponent({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff2f73b9),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/hadwin_system/hadwin-splash-screen-logo.png',
height: 128.0,
),
],
),
);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,88 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
class NotificationItem extends StatelessWidget {
final Map<String, dynamic> notification;
const NotificationItem({required this.notification});
@override
Widget build(BuildContext context) {
final notificationText = notification['notification'] as String;
final time = notification['time'] as String;
final timeDifference = calculateTimeDifference(time);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
// Text(
// notificationText,
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle.txtGilroySemiBold16,
// ),
Padding(
padding: getPadding(
top: 10,
),
child: Text(
notificationText,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyRegular14,
),
),
],
),
Padding(
padding: getPadding(
top: 11,
bottom: 13,
),
child: Text(
timeDifference,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold18,
),
),
],
);
ListTile(
title: Text(notificationText),
subtitle: Text(timeDifference),
);
}
String calculateTimeDifference(String time) {
final currentTime = DateTime.now();
final notificationTime = DateTime.parse(time);
final difference = currentTime.difference(notificationTime);
if (difference.inDays >= 365) {
final years = (difference.inDays / 365).floor();
return '${years} ${years == 1 ? 'year' : 'years'} ago';
} else if (difference.inDays >= 30) {
final months = (difference.inDays / 30).floor();
return '${months} ${months == 1 ? 'month' : 'months'} ago';
} else if (difference.inDays > 0) {
return '${difference.inDays} ${difference.inDays == 1 ? 'day' : 'days'} ago';
} else if (difference.inHours > 0) {
return '${difference.inHours} ${difference.inHours == 1 ? 'hour' : 'hours'} ago';
} else {
return 'Just now';
}
}
}
@@ -0,0 +1,957 @@
import 'package:intl/intl.dart';
import 'dart:async';
import 'dart:convert';
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
import 'package:flutter/material.dart';
import 'package:google_nav_bar/google_nav_bar.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../../Utils/color_constants.dart';
import '../../Utils/size_utils.dart';
import '../../providers/tab_navigation_provider.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_decoration.dart';
import '../../theme/app_style.dart';
import '../Bookmarks/Bookmarks_entity_list_screen.dart';
import '../Incident_Ticket/ticket_create.dart';
import '../LayoutReportBuilder/LayoutReportBuilder.dart';
import '../Login Screen/login_screen.dart';
import '../LogoutService/Logoutservice.dart';
import '../QrBarCode/Qr_BarCode/Qr_BarCode_create_entity_screen.dart';
import '../Setup/setup.dart';
import '../SysParameters/SystemParameterScreen.dart';
import '../dynamic_form/list_dynamic_form_screen.dart';
import '../profileManagement/Profilesettings.dart';
import '../profileManagement/about.dart';
import '../profileManagement/changepassword.dart';
class TabbedLayoutComponent extends StatefulWidget {
@override
_TabbedLayoutComponentState createState() => _TabbedLayoutComponentState();
}
class _TabbedLayoutComponentState extends State<TabbedLayoutComponent> {
int _currentTab = 0;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
Map<String, dynamic> userData = {};
@override
void initState() {
super.initState();
getUserData();
fetchData();
}
getUserData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var userdatastr = prefs.getString('userData');
if (userdatastr != null) {
try {
setState(() {
userData = json.decode(userdatastr);
});
print(userData['token']);
} catch (e) {
print("error is ..................$e");
}
}
}
void setTab(int index) {
setState(() {
_currentTab = index;
});
}
List<Map<String, dynamic>> notifications = [];
Future<void> fetchData() async {
String baseUrl = ApiConstants.baseUrl;
final apiUrl = '$baseUrl/notification/get_notification';
final token = await TokenManager.getToken();
final response = await http.get(
Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode <= 209) {
final List<dynamic> data = jsonDecode(response.body);
setState(() {
notifications = data.cast<Map<String, dynamic>>();
});
} else {
// Handle errors
print('Failed to fetch data');
}
}
@override
Widget build(BuildContext context) {
final userAuthKey = TokenManager.getToken().toString();
print('user auth key is .....' + userAuthKey);
List<Widget> screens = [
Padding(
padding: const EdgeInsets.all(10.0),
child: StaticChartsScreen(
userData: userData,
),
),
HomeDashboardScreen(
userData: userData,
),
// const SizedBox(height: 15),
Container(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Activity',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 16.0), // Adjust the spacing as needed
//ActivityList(), // This widget should contain the list of notifications
for (final notification in notifications)
NotificationItem(notification: notification),
],
),
),
)
];
return WillPopScope(
onWillPop: _onBackPress,
child: Scaffold(
key: _scaffoldKey,
appBar: AppBar(
backgroundColor: Colors.white,
toolbarHeight: 50,
leading: IconButton(
icon: const Icon(
Icons.circle_outlined,
color: Colors.black,
),
onPressed: () {}),
title: const Text(
"Authsec",
style: TextStyle(color: Colors.black),
),
actions: [
PopupMenuButton<String>(
icon: const Icon(
Icons.more_vert,
color: Colors.black,
),
onSelected: (String result) {
// Handle the selected option
print("Selected: $result");
},
itemBuilder: (BuildContext context) => [
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'Raise A Ticket',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RaisedTicketScreen(
userData: userData,
),
),
);
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'Profile Settings',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
// Closes the drawer
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ProfileSettingsScreen(userData: userData),
),
);
// Add your logic for menu 2 here
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'Change Password',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
// Closes the drawer
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResetPasswordScreen(
userEmail: userData['email'],
userData: userData), //go to get all entity
),
);
// Add your logic for menu 2 here
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'DynamicForm',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
// Closes the drawer
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DynamicForm(), //go to get all entity
),
);
// Add your logic for menu 2 here
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'Setup Screen',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const SetupScreen(), //go to get all entity
),
);
// Add your logic for menu 2 here
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'BookMark',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
// Closes the drawer
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
bookmarks_entity_list_screen(), //go to get all entity
),
);
// Add your logic for menu 2 here
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'System Parameter',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
SysParameter(), //go to get all entity
),
);
// Add your logic for menu 2 here
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'Addition Menu',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const QrBarCodeScreen(),
),
);
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'About',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
AboutScreen(), //go to get all entity
),
);
// Add your logic for menu 2 here
},
),
// NEW MENU
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'LogOut',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
_logoutUser();
},
),
],
),
],
),
backgroundColor: const Color(0xfffefefe),
extendBodyBehindAppBar: true,
//bottomNavigationBar: AppFooter(),
body: screens.isEmpty
? const Text("Loading...")
: ListView.builder(
itemCount: screens.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) => screens[index],
),
),
);
}
Future<void> _logoutUser() async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
// Remove 'userData' and 'isLoggedIn' from SharedPreferences
await prefs.remove('userData');
await prefs.remove('isLoggedIn');
String logouturl = "${ApiConstants.baseUrl}/token/logout";
var response = await http.get(Uri.parse(logouturl));
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode <= 209) {
// ignore: use_build_context_synchronously
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => const LoginScreen()),
(route) => false, // Remove all routes from the stack
);
} else {
const Text('failed to logout');
}
} catch (error) {
print('Error occurred during logout: $error');
}
}
Widget googleNavBar() {
return Container(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6.18, vertical: 1),
child: GNav(
haptic: false,
gap: 6,
activeColor: const Color(0xFF0070BA),
iconSize: 24,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 11),
duration: const Duration(milliseconds: 300),
color: const Color(0xFF243656),
tabs: [
GButton(
icon: FluentIcons.home_32_regular,
iconSize: 36,
text: 'Home',
onPressed: () {
print('home');
},
),
GButton(
icon: FluentIcons.people_32_regular,
iconSize: 36,
text: 'Contacts',
onPressed: () {
print('contacts');
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => AllContactsScreen(
// setTab: setTab,
// ),
// ),
// );
},
),
GButton(
icon: Icons.wallet,
text: 'Wallet',
iconSize: 34,
onPressed: () {
print('wallet');
},
),
],
selectedIndex: _currentTab,
onTabChange: _onTabChange,
),
),
);
}
void _onTabChange(int index) {
if (_currentTab == 1 || _currentTab == 2) {
FocusManager.instance.primaryFocus?.unfocus();
}
Provider.of<TabNavigationProvider>(context, listen: false)
.updateTabs(_currentTab);
setState(() {
_currentTab = index;
});
}
Future<bool> _onBackPress() {
if (_currentTab == 0) {
return Future.value(true);
} else {
int lastTab =
Provider.of<TabNavigationProvider>(context, listen: false).lastTab;
Provider.of<TabNavigationProvider>(context, listen: false)
.removeLastTab();
setTab(lastTab);
}
return Future.value(false);
}
}
class StaticChartsScreen extends StatefulWidget {
final Map<String, dynamic> userData;
const StaticChartsScreen({required this.userData, Key? key})
: super(key: key);
@override
_StaticChartsScreenState createState() => _StaticChartsScreenState();
}
class _StaticChartsScreenState extends State<StaticChartsScreen> {
int myProjectcount = 0;
int sharedWithMeCount = 0;
int allprojectCount = 0;
@override
void initState() {
super.initState();
fetchData();
}
Future<void> fetchData() async {
print("working");
final token = await TokenManager.getToken();
print(token);
String baseUrl = ApiConstants.baseUrl;
var myProjectcountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_myproject'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
var sharedWithMeCountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_sharedwithme'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
var allProjectsCountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_allproject'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
if (myProjectcountres.statusCode == 401) {
LogoutService.logout();
}
print(myProjectcountres.statusCode);
if (myProjectcountres.statusCode <= 209 &&
sharedWithMeCountres.statusCode <= 209) {
final myProjectData = jsonDecode(myProjectcountres.body);
final sharedData = jsonDecode(sharedWithMeCountres.body);
final allData = jsonDecode(allProjectsCountres.body);
setState(() {
myProjectcount = myProjectData;
sharedWithMeCount = sharedData;
allprojectCount = allData;
});
} else {
// Handle errors
print('Failed to fetch data');
}
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "myproject"), // Get all projects
// ),
// );
print('test1');
},
child: Card(
color: Colors.white,
elevation: 5.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
myProjectcount.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 12,
),
),
const Text(
'Test1',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
],
),
),
),
),
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "sharedproject"), // Get all projects
// ),
// );
print('test2');
},
child: Card(
color: Colors.white,
elevation: 5.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
sharedWithMeCount.toString(),
style: const TextStyle(
fontSize: 12,
),
),
const Text(
'Test2',
style: TextStyle(
fontSize: 12,
),
),
],
),
),
),
),
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "allproject"), // Get all projects
// ),
// );
print('test3');
},
child: Card(
color: Colors.white,
elevation: 5.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
allprojectCount.toString(),
style: const TextStyle(
fontSize: 12,
),
),
const Text(
'Test3',
style: TextStyle(
fontSize: 12,
),
),
],
),
),
),
),
],
);
}
}
class HomeDashboardScreen extends StatelessWidget {
final Map<String, dynamic> userData;
const HomeDashboardScreen({super.key, required this.userData});
@override
Widget build(BuildContext context) {
var firstName = userData['firstName'].toString();
return Container(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Card(
clipBehavior: Clip.antiAlias,
elevation: 0,
margin: getMargin(top: 5),
color: ColorConstant.whiteA70099,
shape: RoundedRectangleBorder(
borderRadius: BorderRadiusStyle.roundedBorder6),
child: Container(
height: getVerticalSize(224),
width:
MediaQuery.of(context).size.width, //getHorizontalSize(396),
// padding: getPadding(
// left: 16, top: 17, right: 16, bottom: 17),
decoration: AppDecoration.outlineGray70026
.copyWith(borderRadius: BorderRadiusStyle.roundedBorder6),
child: Stack(alignment: Alignment.centerRight, children: [
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: getPadding(left: 1),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("08",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding:
getPadding(top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness: getVerticalSize(1),
color:
ColorConstant.blueGray400,
indent: getHorizontalSize(9))))
]),
Padding(
padding: getPadding(top: 28),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text("06",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding: getPadding(
top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness:
getVerticalSize(1),
color: ColorConstant
.blueGray400,
indent:
getHorizontalSize(9))))
])),
Padding(
padding: getPadding(top: 28),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text("04",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding: getPadding(
top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness:
getVerticalSize(1),
color: ColorConstant
.blueGray400,
indent:
getHorizontalSize(9))))
])),
Padding(
padding: getPadding(top: 28),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text("02",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding: getPadding(
top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness:
getVerticalSize(1),
color: ColorConstant
.blueGray400,
indent:
getHorizontalSize(10))))
])),
Padding(
padding: getPadding(top: 28),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text("00",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding: getPadding(
top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness:
getVerticalSize(1),
color: ColorConstant
.blueGray400,
indent:
getHorizontalSize(9))))
]))
]))),
Align(
alignment: Alignment.centerRight,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
buildContainer(
height: 97,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(top: 45),
text: "08/21"),
buildContainer(
height: 138,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 23, top: 19),
text: "08/22"),
buildContainer(
height: 160,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 21, top: 5),
text: "08/23"),
buildContainer(
height: 83,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 21, top: 53),
text: "08/24"),
buildContainer(
height: 64,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 20, top: 65),
text: "08/25"),
buildContainer(
height: 126,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 21, top: 26),
text: "08/26"),
buildContainer(
height: 83,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 22, top: 53),
text: "08/27"),
],
),
)
]))),
));
// );
}
Widget buildContainer(
{required double height,
required double width,
required EdgeInsets margin,
required String text}) {
return Container(
width: getHorizontalSize(width),
margin: margin,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: getVerticalSize(height),
decoration: BoxDecoration(
color: ColorConstant.blueA700,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(getHorizontalSize(4)),
topRight: Radius.circular(getHorizontalSize(4)),
),
),
),
Padding(
padding: getPadding(top: 9),
child: Text(
text,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10,
),
),
],
),
);
}
}
class NotificationItem extends StatelessWidget {
final Map<String, dynamic> notification;
const NotificationItem({required this.notification});
@override
Widget build(BuildContext context) {
final notificationText = notification['notification'] as String;
final time = notification['time'] as String;
final timeDifference = calculateTimeDifference(time);
return ListTile(
title: Text(
notificationText,
style: TextStyle(fontSize: 12, color: Colors.grey[800]),
),
subtitle: Text(timeDifference),
);
}
String calculateTimeDifference(String time) {
final currentTime = DateTime.now();
final formatter = DateFormat('yyyy/MM/dd HH:mm:ss');
final notificationTime = formatter.parse(time);
final difference = currentTime.difference(notificationTime);
if (difference.inDays >= 365) {
final years = (difference.inDays / 365).floor();
return '${years} ${years == 1 ? 'year' : 'years'} ago';
} else if (difference.inDays >= 30) {
final months = (difference.inDays / 30).floor();
return '${months} ${months == 1 ? 'month' : 'months'} ago';
} else if (difference.inDays > 0) {
return '${difference.inDays} ${difference.inDays == 1 ? 'day' : 'days'} ago';
} else if (difference.inHours > 0) {
return '${difference.inHours} ${difference.inHours == 1 ? 'hour' : 'hours'} ago';
} else {
return 'Just now';
}
}
}
@@ -0,0 +1,524 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../Login Screen/login_screen.dart';
import '../LogoutService/Logoutservice.dart';
import 'apiserviceprofilemanagement.dart';
import 'package:http/http.dart' as http;
import 'changepassword.dart';
class ProfileSettingsScreen extends StatefulWidget {
final Map<String, dynamic> userData;
ProfileSettingsScreen({required this.userData});
@override
_ProfileSettingsScreenState createState() => _ProfileSettingsScreenState();
}
class _ProfileSettingsScreenState extends State<ProfileSettingsScreen> {
ApiServiceProfileManagement apiService = ApiServiceProfileManagement();
String? fetchedimageurl =
'http://43.205.154.152:30165/assets/images/profile-icon.png';
Uint8List? _imageBytes; // Uint8List to store the image data
String? _imageFileName;
final _formKey = GlobalKey<FormState>();
TextEditingController fullNameController = TextEditingController();
TextEditingController pronounsController = TextEditingController();
TextEditingController roleController = TextEditingController();
TextEditingController departmentController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController aboutMeController = TextEditingController();
@override
void initState() {
super.initState();
//fetchProfileImageData();
fetchUserProfileData();
}
Future<void> _uploadImageFile() async {
final imagePicker = ImagePicker();
try {
final pickedImage =
await imagePicker.pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
final imageBytes = await pickedImage.readAsBytes();
setState(() {
_imageBytes = imageBytes;
_imageFileName = pickedImage.name; // Store the file name
});
}
} catch (e) {
print(e);
}
}
//api/user-profile
Future<void> fetchUserProfileData() async {
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/user-profile';
try {
final response = await http.get(
Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
},
);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode >= 200 && response.statusCode <= 209) {
final Map<String, dynamic> jsonData = json.decode(response.body);
setState(() {
fullNameController.text =
jsonData['fullName'] != null ? jsonData['fullName'] : '';
pronounsController.text =
jsonData['pronouns'] != null ? jsonData['pronouns'] : '';
roleController.text =
jsonData['role'] != null ? jsonData['role'] : '';
departmentController.text =
jsonData['department'] != null ? jsonData['department'] : '';
emailController.text =
jsonData['email'] != null ? jsonData['email'] : '';
aboutMeController.text =
jsonData['about'] != null ? jsonData['about'] : '';
});
} else {
throw Exception('Failed to load data: ${response.statusCode}');
}
} catch (e) {
throw Exception('Failed to load data: $e');
}
}
Future<void> fetchProfileImageData() async {
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/retrieve-image';
try {
final response = await http.get(
Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
},
);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode >= 200 && response.statusCode <= 209) {
final Map<String, dynamic> jsonData = json.decode(response.body);
final trustedImageUrl = Uri.dataFromString(jsonData['image'],
mimeType: 'image/*', encoding: Encoding.getByName('utf-8'))
.toString();
fetchedimageurl = trustedImageUrl;
} else {
throw Exception('Failed to load data: ${response.statusCode}');
}
} catch (e) {
throw Exception('Failed to load data: $e');
}
}
Future<void> _submitImage() async {
if (_imageBytes == null) {
// Show an error message if no image is selected
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Please select an image.'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
return;
}
if (_imageFileName == null) {
// Handle the case where _imageFileName is null (no file name provided)
print('File name is missing.');
return;
}
try {
final token = await TokenManager.getToken();
await apiService.createFile(_imageBytes!, _imageFileName!, token!);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to upload image: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
Future<void> _updateProfile() async {
if (_formKey.currentState!.validate()) {
// Create a JSON object with the form data
final profileData = {
'fullName': fullNameController.text,
'pronouns': pronounsController.text,
'role': roleController.text,
'department': departmentController.text,
'email': emailController.text,
'aboutMe': aboutMeController.text,
};
//api/user-profile
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/user-profile';
try {
final response = await http.put(Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
body: json.encode(profileData));
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode <= 209) {
print("success");
Navigator.of(context).pop();
} else {
print(response.statusCode);
}
} catch (e) {
throw Exception('Failed to Update: $e');
}
}
}
Future<void> _logoutUser() async {
try {
String logouturl = "${ApiConstants.baseUrl}/token/logout";
var response = await http.get(Uri.parse(logouturl));
if (response.statusCode <= 209) {
// ignore: use_build_context_synchronously
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
(route) => false, // Remove all routes from the stack
);
} else {
const Text('failed to logout');
}
} catch (error) {
print('Error occurred during logout: $error');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "My Profile Settings")),
body: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
// Section: Show Profile Photo
Center(
child: Column(
children: [
CircleAvatar(
radius: 70, // Adjust as needed
backgroundImage: NetworkImage(
"$fetchedimageurl"), // Replace with your API URL
),
SizedBox(height: 10),
CustomButton(
height: getVerticalSize(50),
text: _imageBytes == null
? "Pick a Profile Photo"
: 'Upload Success',
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
if (_imageBytes != null) {
_submitImage();
} else {
_uploadImageFile();
}
},
),
],
),
),
SizedBox(height: 20),
// Section: Profile Form
Text(
'Your Profile Information',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Form(
key: _formKey,
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Your Full Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
controller: fullNameController,
hintText: "Enter Full Name",
validator: (value) {
if (value!.isEmpty) {
return 'Please enter your full name';
}
return null;
},
onChanged: (value) {
fullNameController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Pronouns",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Pronouns",
controller: pronounsController,
onChanged: (value) {
pronounsController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Role",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Role",
controller: roleController,
onChanged: (value) {
roleController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Department or Team",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Department or Team",
controller: departmentController,
onChanged: (value) {
departmentController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Email",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Email",
controller: emailController,
validator: (value) {
if (value!.isEmpty || !value!.contains('@')) {
return 'Please enter a valid email address';
}
return null;
},
onChanged: (value) {
emailController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("About Me",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "About Me",
controller: aboutMeController,
maxLines: 3,
onChanged: (value) {
aboutMeController.text = value;
},
margin: getMargin(top: 6))
])),
CustomButton(
height: getVerticalSize(50),
text: "Update Profile",
margin: getMargin(top: 24, bottom: 5),
onTap: _updateProfile,
),
],
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResetPasswordScreen(
userData: widget.userData,
userEmail: emailController.text,
), //go to get all entity
),
);
},
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
"Password:Change Password for your account Change password",
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.blue,
),
),
],
),
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () {
print("change password");
},
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'Security:Logout of all sessions except this current browser Logout other sessions',
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.blue,
),
),
],
),
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () {
_logoutUser();
},
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'Deactivation:Remove access to all organizations and workspace in cloudnsure Deactivate account',
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.blue,
),
),
],
),
),
),
SizedBox(height: 20),
],
),
),
);
}
}
+46
View File
@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
class AboutScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "About Us")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'About Us',
style: AppStyle.txtGilroyBold18Bluegray900,
),
const SizedBox(height: 20),
Text(
'Create a new project if you have access, if you don\'t have access, then contact the admin.',
textAlign: TextAlign.center,
style: AppStyle.txtGilroyBold16BlueA700,
),
],
),
),
);
}
}
@@ -0,0 +1,57 @@
import 'dart:typed_data';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:dio/dio.dart';
import '../../resources/api_constants.dart';
class ApiServiceProfileManagement {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
Future<void> createFile(
Uint8List fileBytes, String fileName, String token) async {
try {
String apiUrl = "$baseUrl/api/upload";
final mimeType = 'image/jpeg'; // You can set the appropriate MIME type
FormData formData = FormData.fromMap({
'imageFile': MultipartFile.fromBytes(
fileBytes,
filename: fileName,
contentType: MediaType.parse(mimeType),
),
});
Dio dio = Dio(); // Create a new Dio instance
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.post(apiUrl, data: formData);
if (response.statusCode == 200) {
// Handle successful response
print('File uploaded successfully');
} else {
print('Failed to upload file with status: ${response.statusCode}');
}
} catch (error) {
print('Error occurred during form submission: $error');
}
}
String lookupMimeType(String filePath) {
final ext = filePath.split('.').last;
switch (ext) {
case 'jpg':
case 'jpeg':
return 'image/jpeg';
case 'png':
return 'image/png';
case 'pdf':
return 'application/pdf';
// Add more cases for other file types as needed
default:
return 'application/octet-stream'; // Default MIME type
}
}
}
@@ -0,0 +1,318 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import 'package:http/http.dart' as http;
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../Login Screen/login_screen.dart';
import '../LogoutService/Logoutservice.dart';
class ResetPasswordScreen extends StatelessWidget {
final String userEmail;
final Map<String, dynamic> userData;
ResetPasswordScreen({required this.userEmail,required this.userData});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:
CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Reset Password")),
body: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
"You're signed in as $userEmail",
style: AppStyle.txtGilroyMedium16Bluegray800
),
const SizedBox(height: 20),
ResetPasswordForm(userData: userData,userEmail: userEmail),
const SizedBox(height: 20),
GestureDetector(
onTap: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => const LoginScreen()),
(route) => false, // Remove all routes from the stack
);
},
child: Text(
'Wrong account? Log in instead.',
style: AppStyle.txtGreenSemiBold16,
),
),
],
),
),
);
}
}
class ResetPasswordForm extends StatefulWidget {
final String userEmail;
final Map<String, dynamic> userData;
const ResetPasswordForm({super.key, required this.userEmail,required this.userData});
@override
_ResetPasswordFormState createState() => _ResetPasswordFormState();
}
class _ResetPasswordFormState extends State<ResetPasswordForm> {
final TextEditingController oldPasswordController = TextEditingController();
final TextEditingController newPasswordController = TextEditingController();
final TextEditingController reEnterNewPasswordController =
TextEditingController();
var responseMessage;
var isVisible=false;
bool issuccess = false;
bool isOldPasswordVisible = false;
bool isNewPasswordVisible = false;
bool isReEnterNewPasswordVisible = false;
bool _isPasswordValid1 = true;
void _validatePassword1(String password) {
setState(() {
_isPasswordValid1 = password.isNotEmpty;
});
}
bool _isPasswordValid2 = true;
void _validatePassword2(String password) {
setState(() {
_isPasswordValid2 = password.isNotEmpty;
});
}
bool _isPasswordValid3 = true;
void _validatePassword3(String password) {
setState(() {
_isPasswordValid3 = password.isNotEmpty&&password==newPasswordController.text;
});
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
isVisible?Text(responseMessage,style: TextStyle(
color: issuccess?Colors.green:Colors.red, // Set the text color to red
)):const Text(''),
Padding(
padding: getPadding(top: 19),
child: Text("Enter Old Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
controller: oldPasswordController,
hintText: "Enter Old Password",
margin: getMargin(top: 6),
errorText:
_isPasswordValid1 ? null : 'Please enter your old password',
padding: TextFormFieldPadding.PaddingT12,
textInputAction: TextInputAction.done,
onChanged: _validatePassword1,
validator: (value) {
if (value!.isEmpty) {
return 'Please enter your old password';
}
return null; // Return null to indicate no error
},
textInputType:TextInputType.visiblePassword,
suffix: IconButton(
icon: Icon(
isOldPasswordVisible ? Icons.visibility : Icons.visibility_off,
),
onPressed: () {
setState(() {
isOldPasswordVisible = !isOldPasswordVisible;
});
},
),
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText: !isOldPasswordVisible),
Padding(
padding: getPadding(top: 19),
child: Text("Enter New Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
controller: newPasswordController,
hintText: "Enter New Password",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputAction: TextInputAction.done,
suffix: IconButton(
icon: Icon(
isNewPasswordVisible ? Icons.visibility : Icons.visibility_off,
),
onPressed: () {
setState(() {
isNewPasswordVisible = !isNewPasswordVisible;
});
},
),
errorText:
_isPasswordValid2 ? null : 'Please enter your new password',
onChanged: _validatePassword2,
validator: (value) {
if (value!.isEmpty) {
return 'Please enter your new password';
}
return null;
},
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText:!isNewPasswordVisible,),
Padding(
padding: getPadding(top: 19),
child: Text("Re-Enter New Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
controller: reEnterNewPasswordController,
hintText: "Re-Enter New Password",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
onChanged: _validatePassword3,
validator: (value) {
if (value!.isEmpty) {
return 'Please re-enter your new password';
}
if (value != newPasswordController.text) {
return 'Passwords do not match';
}
return null;
},
suffix: IconButton(
icon: Icon(
isReEnterNewPasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
isReEnterNewPasswordVisible = !isReEnterNewPasswordVisible;
});
},
),
errorText:
_isPasswordValid3 ? null : 'Please re-enter your new password',
textInputAction: TextInputAction.done,
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText:!isReEnterNewPasswordVisible,),
CustomButton(
height: getVerticalSize(50),
text: "Continue",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
if (oldPasswordController.text.isEmpty ||
newPasswordController.text.isEmpty ||
reEnterNewPasswordController.text.isEmpty) {
print(oldPasswordController.text);
print(newPasswordController.text);
print(reEnterNewPasswordController.text);
} else {
Map<String, dynamic> passwordData = {
"userId":widget.userData['userId'],
"oldPassword": oldPasswordController.text,
"newPassword": newPasswordController.text,
"confirmPassword": reEnterNewPasswordController.text,
};
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/reset_password';
try {
final response = await http.post(Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
body: json.encode(passwordData));
if(response.statusCode==401){
LogoutService.logout();
}
if (response.statusCode <= 209) {
setState(() {
isVisible=true;
issuccess=true;
responseMessage = "Password Changes Successfully";
});
print("success");
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
(route) => false,
);
} else {
setState(() {
isVisible=true;
responseMessage = "Incorrect Password";
});
print(response.statusCode);
}
} catch (e) {
throw Exception('Failed to Update: $e');
}
}
},
),
],
);
}
@override
void dispose() {
oldPasswordController.dispose();
newPasswordController.dispose();
reEnterNewPasswordController.dispose();
super.dispose();
}
}
@@ -0,0 +1,102 @@
import 'package:fade_shimmer/fade_shimmer.dart';
import 'package:flutter/material.dart';
Widget _creditsloadingTile(BuildContext context) {
List<Widget> socialLinks = List.generate(
6,
(index) => Container(
child: const FadeShimmer(
radius: 16.18,
height: 48,
width: 48,
fadeTheme: FadeTheme.light,
),
padding: const EdgeInsets.all(2),
),
);
return Container(
width: MediaQuery.of(context).size.width - 10,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.blueGrey.shade100.withOpacity(0.1618),
borderRadius: const BorderRadius.all(Radius.circular(16.18))),
margin: const EdgeInsets.symmetric(vertical: 3, horizontal: 6.18),
child: Wrap(
direction: Axis.vertical,
children: [
Container(
width: MediaQuery.of(context).size.width - 48,
padding: const EdgeInsets.all(6.18),
child: Wrap(
alignment: WrapAlignment.spaceBetween,
children: [
Wrap(direction: Axis.vertical, children: [
Container(
child: const FadeShimmer(
radius: 16.18,
height: 27,
width: 96,
fadeTheme: FadeTheme.light,
),
padding: const EdgeInsets.all(2),
),
Container(
child: const FadeShimmer(
radius: 16.18,
height: 20,
width: 72,
fadeTheme: FadeTheme.light,
),
padding: const EdgeInsets.all(2),
),
]),
Container(
child: const FadeShimmer(
radius: 16.18,
height: 64,
width: 64,
fadeTheme: FadeTheme.light,
),
),
],
),
),
Container(
child: const FadeShimmer(
radius: 16.18,
height: 16,
width: 96,
fadeTheme: FadeTheme.light,
),
padding: const EdgeInsets.all(2),
),
Container(
height: 72,
width: MediaQuery.of(context).size.width - 48,
padding: const EdgeInsets.all(0),
color: Colors.transparent,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (_, index) => socialLinks[index],
separatorBuilder: (_, b) => const SizedBox(
width: 16.18,
),
itemCount: socialLinks.length),
)
],
),
);
}
Widget creditsLoadingList(int items, BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListView.builder(
padding: const EdgeInsets.all(0),
itemBuilder: (_, index) => Padding(
padding: const EdgeInsets.all(5),
child: _creditsloadingTile(context)),
itemCount: items,
),
);
}
Binary file not shown.
@@ -0,0 +1,263 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import 'SignUpService.dart';
class CreateAccountScreen extends StatefulWidget {
CreateAccountScreen({Key? key}) : super(key: key);
@override
_CreateAccountScreenState createState() => _CreateAccountScreenState();
}
class _CreateAccountScreenState extends State<CreateAccountScreen> {
final SignUpApiService userService = SignUpApiService();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
late BuildContext _context; // Store the current context
late var account_id; // Store the account_id
bool _isEmailValid = true;
void _validateEmail(String email) {
setState(() {
_isEmailValid =
RegExp(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$').hasMatch(email);
});
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
_context = context; // Store the context
return Scaffold(
appBar: AppBar(title: const Text('Create Account')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Text("Company Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['companyName'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Company Name';
}
return null;
},
hintText: "enter Company Name",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Email",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['email'] = value,
onChanged: _validateEmail,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Email';
}else if(!_isEmailValid){
return 'Please enter a valid email';
}
return null;
},
hintText: "enter Email",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Mobile Number",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
textInputType: TextInputType.phone,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))
],
onsaved: (value) => formData['mobile'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Mob No';
}
return null;
},
hintText: "enter Mobile Number",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
),
Padding(
padding: getPadding(top: 19),
child: Text("Workspace",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['workspace'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Workspace';
}
return null;
},
hintText: "enter Workspace",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Gst Number",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['gstNumber'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Gst Number';
}
return null;
},
hintText: "enter Gst Number",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("pancard",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['pancard'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Pancard';
}
return null;
},
hintText: "enter pancard",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Working",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['working'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Working';
}
return null;
},
hintText: "enter Working",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: CustomButton(
height: getVerticalSize(50),
width: getHorizontalSize(396),
text: "SUBMIT",
margin: getMargin(top: 25),
onTap: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
{
try {
print('form data is $formData');
final response =
await userService.createAccount(formData);
account_id = response['account_id'].toString();
print(
'after create account account id is $account_id');
// ignore: use_build_context_synchronously
Navigator.pop(
_context, account_id); // Pop with account_id
// Navigator.pop(context);
} catch (e) {
// ignore: use_build_context_synchronously
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Account Creation Failed: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}
},
),
),
],
),
),
),
),
);
}
}
+328
View File
@@ -0,0 +1,328 @@
import 'package:flutter/material.dart';
import 'SignUpService.dart';
class CreateUserScreen extends StatefulWidget {
CreateUserScreen({Key? key}) : super(key: key);
@override
_CreateUserScreenState createState() => _CreateUserScreenState();
}
class _CreateUserScreenState extends State<CreateUserScreen> {
int _currentStep = 0;
// Create a global key for each step
final GlobalKey<StepCreateAccountState> createAccountKey =
GlobalKey<StepCreateAccountState>();
final GlobalKey<StepGetEmailVerificationState> emailVerificationKey =
GlobalKey<StepGetEmailVerificationState>();
final GlobalKey<StepGetRegistrationState> registrationKey =
GlobalKey<StepGetRegistrationState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sign Up - Step ${_currentStep + 1}'),
),
body: Column(
children: [
// Display the current step
Expanded(
child: _buildStep(_currentStep),
),
// Navigation buttons
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (_currentStep > 0)
ElevatedButton(
onPressed: () {
setState(() {
_currentStep--;
});
},
child: const Text('Previous'),
),
if (_currentStep < 2)
ElevatedButton(
onPressed: () {
_proceedToNextStep();
},
child: const Text('Next'),
),
],
),
],
),
);
}
// Function to build the appropriate step based on the current step index
Widget _buildStep(int stepIndex) {
switch (stepIndex) {
case 0:
return StepCreateAccount(
key: createAccountKey,
onNext: () {
_proceedToNextStep();
},
);
case 1:
return StepGetEmailVerification(
key: emailVerificationKey,
onNext: () {
_proceedToNextStep();
},
);
case 2:
return StepGetRegistration(
key: registrationKey,
onNext: () {
_proceedToNextStep();
},
);
default:
return Container(); // Return an empty container by default
}
}
// Function to proceed to the next step
void _proceedToNextStep() {
if (_currentStep < 2) {
setState(() {
_currentStep++;
});
}
}
}
// Define your individual step widgets here
class StepCreateAccount extends StatefulWidget {
final Function onNext;
const StepCreateAccount({Key? key, required this.onNext}) : super(key: key);
@override
StepCreateAccountState createState() => StepCreateAccountState();
}
class StepCreateAccountState extends State<StepCreateAccount> {
// Add your state variables for this step here
String? accountId;
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
final SignUpApiService userService = SignUpApiService();
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Column(
children: [
const Text('Step 1: Create Account'),
TextFormField(
decoration: const InputDecoration(labelText: 'Company Name'),
onSaved: (value) => formData['companyName'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Company Name';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Email'),
onSaved: (value) => formData['email'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Email';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Mobile No'),
onSaved: (value) => formData['mobile'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Mob No';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Workspace'),
onSaved: (value) => formData['workspace'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Workspace';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Gst Number'),
onSaved: (value) => formData['gstNumber'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Gst Number';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'pancard'),
onSaved: (value) => formData['pancard'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Pancard';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Working'),
onSaved: (value) => formData['working'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Working';
}
return null;
},
),
const SizedBox(height: 16),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
{
try {
print('form data is $formData');
final response =
await userService.createAccount(formData);
accountId = response['account_id'].toString();
print('after create account account id is $accountId');
// ignore: use_build_context_synchronously
// Navigator.pop(
// _context, accountId); // Pop with account_id
// Navigator.pop(context);
} catch (e) {
// ignore: use_build_context_synchronously
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Account Creation Failed: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}
},
child: const SizedBox(
width: double.infinity,
height: 50,
child: Center(
child: Text(
'SUBMIT',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
if (accountId != null) Text('Selected Account ID: $accountId'),
],
),
);
}
}
class StepGetEmailVerification extends StatefulWidget {
final Function onNext;
const StepGetEmailVerification({Key? key, required this.onNext})
: super(key: key);
@override
StepGetEmailVerificationState createState() =>
StepGetEmailVerificationState();
}
class StepGetEmailVerificationState extends State<StepGetEmailVerification> {
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Text('Step 2: Get Email Verification'),
);
}
}
class StepGetRegistration extends StatefulWidget {
final Function onNext;
const StepGetRegistration({Key? key, required this.onNext}) : super(key: key);
@override
StepGetRegistrationState createState() => StepGetRegistrationState();
}
class StepGetRegistrationState extends State<StepGetRegistration> {
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Text('Step 3: Get Registration'),
);
}
}
// Example of a dialog to create an account
class CreateAccountDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Create Account'),
content: Text('Account created successfully!'),
actions: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pop('12345'); // Pass the created account ID
},
child: Text('OK'),
),
],
);
}
}
@@ -0,0 +1,359 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../Login Screen/login_screen.dart';
import 'CreateAccount.dart';
import 'SignUpService.dart';
class RegistrationDetailsScreen extends StatefulWidget {
var email;
RegistrationDetailsScreen({required this.email});
@override
_RegistrationDetailsScreenState createState() =>
_RegistrationDetailsScreenState();
}
class _RegistrationDetailsScreenState extends State<RegistrationDetailsScreen> {
final SignUpApiService userService = SignUpApiService();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
late BuildContext _context; // Store the current context
var account_id = null; // Initialize with null
var selectedAccount; // Use nullable type
var newPassword = ''; // Store the value of the confirm password field
var confirmPassword = ''; // Store the value of the confirm password field
// Validate that the passwords match
String? _validatePasswordMatch(String value) {
if (value != newPassword) {
print('value is $value and new is $newPassword');
return 'Passwords do not match';
}
return null;
}
bool _newpasswordVisible = false;
bool _confirmpasswordVisible = false;
bool _isPasswordValid = true;
void _validatePassword(String password) {
setState(() {
_isPasswordValid = password.isNotEmpty;
});
}
bool _isEmailValid = true;
void _validateEmail(String email) {
setState(() {
_isEmailValid =
RegExp(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$').hasMatch(email);
});
}
void showSuccessMessage(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
duration: const Duration(seconds: 2),
backgroundColor: Colors.green,
),
);
}
void showErrorMessage(String error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(error),
duration: const Duration(seconds: 2),
backgroundColor: Colors.red,
),
);
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
_context = context; // Store the context
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(54),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleft,
margin: getMargin(left: 16, top: 13, bottom: 17),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Registration")),
//AppBar(title: const Text('Registration')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Container(
height: 500,
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Text("First Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['first_name'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter First Name';
}
return null;
},
hintText: "enter First Name",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Last Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['last_name'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Last Name';
}
return null;
},
hintText: "enter Last Name",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Mobile Number",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
textInputType: TextInputType.phone,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))
],
onsaved: (value) => formData['mob_no'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Mobile Number';
}
return null;
},
hintText: "enter Mobile Number",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
),
Padding(
padding: getPadding(top: 19),
child: Text("New Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "New Password",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputAction: TextInputAction.done,
textInputType:TextInputType.visiblePassword,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Password';
}else if(!_isPasswordValid){
return 'Please enter a valid password';
}
return null;
},
suffix: IconButton(
icon: Icon(
_newpasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_newpasswordVisible = !_newpasswordVisible;
});
},
),
onsaved: (value) => formData['new_password'] = value,
onChanged: (value) {
setState(() {
newPassword = value!;
});
_validatePassword;
},
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText: !_newpasswordVisible),
Padding(
padding: getPadding(top: 19),
child: Text("Confirm Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Confirm Password",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputAction: TextInputAction.done,
textInputType:TextInputType.visiblePassword,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Password';
}
return _validatePasswordMatch(confirmPassword);
},
onsaved: (value) => formData['confirm_password'] = value,
onChanged: (value) {
setState(() {
confirmPassword = value!; // Update confirmPassword
});
},
suffix: IconButton(
icon: Icon(
_confirmpasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_confirmpasswordVisible = !_confirmpasswordVisible;
});
},
),
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText: !_confirmpasswordVisible,),
Row(
children: [
const Expanded(
child: Text('Add Account'),
),
IconButton(
onPressed: () async {
final accountId = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CreateAccountScreen(),
),
);
if (accountId != null) {
setState(() {
selectedAccount = accountId;
formData['account_id'] = accountId;
account_id =
accountId; // Update the account_id here
});
}
},
icon: const Icon(Icons.add),
),
],
),
if (account_id != null)
Container(
margin:
const EdgeInsets.symmetric(vertical: 5), // Add margin
child: CustomButton(
height: getVerticalSize(50),
width: getHorizontalSize(396),
text: "SUBMIT",
margin: getMargin(top: 25),
onTap: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
print('formdata is $formData');
formData['usrGrpId'] = 46;
formData['account_id'] = account_id;
formData['email'] = widget.email;
{
final token = await TokenManager.getToken();
try {
print(formData);
await userService
.createuser(token!, formData)
.then((_) => {
const LoginScreen(),
});
await Future.delayed(
const Duration(seconds: 5));
showSuccessMessage('User created successfully');
// ignore: use_build_context_synchronously
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const LoginScreen()));
// moveToNextStep();
} catch (e) {
showErrorMessage('Failed to create User: $e');
}
}
}
},
),
),
],
),
),
),
),
),
);
}
}
@@ -0,0 +1,113 @@
import 'package:dio/dio.dart';
import '../../resources/api_constants.dart';
class SignUpApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
// get all account
Future<List<Map<String, dynamic>>> getallAccount(String token) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/users/sysaccount/sysaccount');
final responseData = response.data;
print('response data is ... $responseData');
if (responseData is List) {
// If the response is a list, cast it to the expected type
final entities = responseData.cast<Map<String, dynamic>>();
return entities;
} else if (responseData is Map<String, dynamic>) {
// If the response is a single object, wrap it in a list
return [responseData];
} else {
// Handle other unexpected response types here
throw Exception('Unexpected response type');
}
} catch (e) {
throw Exception('Failed to Account: $e');
}
}
// Create account
Future<Map<String, dynamic>> createAccount(
Map<String, dynamic> entity) async {
try {
// dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio
.post('$baseUrl/token/users/sysaccount/savesysaccount', data: entity);
print(' created account is $response');
return response.data;
} catch (e) {
throw Exception('Failed To Create Account: $e');
}
}
// SEND EMAIL FOR OTP
Future<void> sendEmail(Map<String, dynamic> entity) async {
try {
print("in post api...$entity");
// dio.options.headers['Authorization'] = 'Bearer $token';
await dio.post('$baseUrl/token/user/send_email', data: entity);
print(entity);
} catch (e) {
throw Exception('Failed to Send Email: $e');
}
}
// RESEND EMAIL FOR OTP
Future<void> resendEmail(String email) async {
try {
// dio.options.headers['Authorization'] = 'Bearer $token';
await dio.post('$baseUrl/token/user/resend_otp?email=$email');
} catch (e) {
throw Exception('Failed to ReSend Email: $e');
}
}
// OTP VEFICATION
Future<void> otpverification(String email, String otp) async {
try {
// dio.options.headers['Authorization'] = 'Bearer $token';
await dio
.post('$baseUrl/token/user/otp_verification?email=$email&otp=$otp');
} catch (e) {
throw Exception('Failed to Verify Otp: $e');
}
}
Future<void> createuser(String token, Map<String, dynamic> entity) async {
try {
print("in post api...$entity");
dio.options.headers['Authorization'] = 'Bearer $token';
await dio.post('$baseUrl/token/addOneAppUser', data: entity);
print(entity);
} catch (e) {
throw Exception('Failed to create User: $e');
}
}
Future<void> updateUser(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
await dio.put('$baseUrl/api/updateAppUserDto/$entityId', data: entity);
print(entity);
} catch (e) {
throw Exception('Failed to update Backend: $e');
}
}
Future<void> deleteUser(String token, int entityId) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
await dio.delete('$baseUrl/api/delete_usr/$entityId');
} catch (e) {
throw Exception('Failed to delete User: $e');
}
}
}
+295
View File
@@ -0,0 +1,295 @@
// import 'package:flutter/material.dart';
//
// import 'package:flutter/services.dart';
//
// import 'RegistrationDetails.dart';
// import 'SignUpService.dart';
//
// enum RegistrationStep {
// SendOTP,
// VerifyOTP,
// EnterUserInfo,
// SelectAccount,
// }
//
// class SignUpUserScreen extends StatefulWidget {
// SignUpUserScreen({Key? key}) : super(key: key);
//
// @override
// _SignUpUserScreenState createState() => _SignUpUserScreenState();
// }
//
// class _SignUpUserScreenState extends State<SignUpUserScreen> {
// final SignUpApiService userService = SignUpApiService();
//
// final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
// final Map<String, dynamic> formData = {};
// final _formKey = GlobalKey<FormState>();
//
// var selectedAccount;
// var email;
// var otp;
// var confirmPassword;
//
// bool _passwordVisible = false;
// bool _isPasswordValid = true;
// void _validatePassword(String password) {
// setState(() {
// _isPasswordValid = password.isNotEmpty;
// });
// }
//
// RegistrationStep currentStep = RegistrationStep.SendOTP;
//
// void moveToNextStep() {
// setState(() {
// if (currentStep == RegistrationStep.SendOTP) {
// currentStep = RegistrationStep.VerifyOTP;
// } else if (currentStep == RegistrationStep.VerifyOTP) {
// currentStep = RegistrationStep.EnterUserInfo;
// } else if (currentStep == RegistrationStep.EnterUserInfo) {
// currentStep = RegistrationStep.SelectAccount;
// }
// });
// }
//
// void showSuccessMessage(String message) {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(message),
// duration: const Duration(seconds: 2),
// backgroundColor: Colors.green,
// ),
// );
// }
//
// void showErrorMessage(String error) {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(error),
// duration: const Duration(seconds: 2),
// backgroundColor: Colors.red,
// ),
// );
// }
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// key: _scaffoldKey,
// appBar: AppBar(
// title: const Text('Create User'),
// ),
// body: Builder(
// builder: (BuildContext context) {
// return SingleChildScrollView(
// child: Padding(
// padding: const EdgeInsets.all(16),
// child: Form(
// key: _formKey,
// child: SizedBox(
// height: MediaQuery.of(context).size.height *
// 0.5, // Use 50% of the screen height
// child: ListView.builder(
// itemCount: 1,
// itemBuilder: (BuildContext context, int index) {
// if (currentStep == RegistrationStep.SendOTP) {
// return Column(
// children: [
// const SizedBox(height: 16),
// TextFormField(
// decoration:
// const InputDecoration(labelText: 'Email'),
// keyboardType: TextInputType.emailAddress,
// onSaved: (value) => email = value,
// validator: (value) {
// if (value == null || value.isEmpty) {
// return 'Please enter Email';
// }
// return null;
// },
// ),
// const SizedBox(height: 16),
// Container(
// margin: const EdgeInsets.symmetric(vertical: 5),
// child: ElevatedButton(
// onPressed: () async {
// if (_formKey.currentState!.validate()) {
// _formKey.currentState!.save();
//
// formData['usrGrpId'] = 46;
// formData['email'] = email;
// try {
// print('send email data is $formData');
//
// await userService.sendEmail(formData);
//
// await Future.delayed(
// const Duration(seconds: 2));
//
// moveToNextStep();
// } catch (e) {
// showErrorMessage(
// 'Failed to send OTP: $e');
// }
// }
// },
// child: const SizedBox(
// width: double.infinity,
// height: 50,
// child: Center(
// child: Text(
// 'Send OTP',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ),
// ),
// ],
// );
// } else if (currentStep == RegistrationStep.VerifyOTP) {
// return Column(
// children: [
// const SizedBox(height: 16),
// TextFormField(
// decoration:
// const InputDecoration(labelText: 'Email'),
// initialValue: email,
// readOnly: true,
// ),
// const SizedBox(height: 16),
// Row(
// children: [
// Container(
// height: 100,
// width: 250,
// padding: const EdgeInsets.symmetric(
// horizontal: 16),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
// border: Border.all(color: Colors.grey),
// ),
// child: TextFormField(
// decoration:
// const InputDecoration(labelText: 'OTP'),
// onChanged: (value) {
// otp = value;
// },
// onSaved: (value) => otp = value,
// validator: (value) {
// if (value == null || value.isEmpty) {
// return 'Please enter OTP';
// }
// return null;
// },
// ),
// ),
// ElevatedButton(
// onPressed: () async {
// try {
// await userService.resendEmail(email);
//
// await Future.delayed(
// const Duration(seconds: 5));
// showSuccessMessage('OTP RESEND');
// } catch (e) {
// showErrorMessage(
// 'Failed to resend OTP: $e');
// }
// },
// child: const SizedBox(
// width: 100,
// height: 50,
// child: Center(
// child: Text(
// 'Resend OTP',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ),
// ],
// ),
// const SizedBox(height: 16),
// ElevatedButton(
// onPressed: () async {
// try {
// print('email is $email and otp is $otp');
// await userService.otpverification(email, otp);
//
// moveToNextStep();
// showSuccessMessage(
// 'Email verified successfully');
// } catch (e) {
// showErrorMessage('Failed to verify OTP: $e');
// }
// },
// child: const SizedBox(
// width: double.infinity,
// height: 50,
// child: Center(
// child: Text(
// 'VERIFY EMAIL',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ),
// ],
// );
// } else if (currentStep ==
// RegistrationStep.EnterUserInfo) {
// return Column(
// children: [
// // Other widgets for user information entry
// ElevatedButton(
// onPressed: () async {
// // Navigate to the RegistrationDetailsScreen when the button is pressed
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) =>
// RegistrationDetailsScreen(email: email),
// ),
// );
// },
// child: const SizedBox(
// width: double.infinity,
// height: 50,
// child: Center(
// child: Text(
// 'Go to Registration Details',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ),
// ],
// );
// } else {
// return Container(); // Return an empty container if none of the conditions match
// }
// },
// ),
// ),
// ),
// ),
// );
// },
// ),
// );
// }
// }
@@ -0,0 +1,138 @@
import 'package:flutter/material.dart';
class StepGetEmailVerification extends StatefulWidget {
final LabeledGlobalKey<FormState> emailPasswordFormKey;
// final Function updateSignUpDetails;
// final String email;
final Function proceedToNextStep;
const StepGetEmailVerification(
{Key? key,
// required this.updateSignUpDetails,
// required this.email,
required this.emailPasswordFormKey,
required this.proceedToNextStep})
: super(key: key);
@override
_StepGetEmailVerificationState createState() =>
_StepGetEmailVerificationState();
}
class _StepGetEmailVerificationState extends State<StepGetEmailVerification> {
String email = "";
String emailErrorMessage = "";
@override
void initState() {
super.initState();
// email = widget.email;
}
@override
void dispose() {
// widget.emailPasswordFormKey.currentState?.validate();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Form(
key: widget.emailPasswordFormKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
// initialValue: email,
// validator: _validateNewPassword,
autofocus: mounted,
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "email",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
keyboardType: TextInputType.name,
textInputAction: TextInputAction.next,
),
),
if (emailErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
width: double.infinity,
child: Text(
"\t\t\t\t$emailErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// Email CODE END HERE
],
));
}
// void errorMessageSetter(String fieldName, String message) {
// setState(() {
// switch (fieldName) {
// case 'NEW-PASSWORD':
// new_passwordErrorMessage = message;
// break;
// case 'CONFIRM-PASSWORD':
// confirm_passwordErrorMessage = message;
// break;
// }
// });
// }
// String? _validateNewPassword(String? value) {
// if (value == null || value.isEmpty) {
// errorMessageSetter('NEW-PASSWORD', 'password cannot be empty');
// } else {
// errorMessageSetter('NEW-PASSWORD', "");
// widget.updateSignUpDetails('new_password', value);
// }
// return null;
// }
// String? _validateConfirmpassword(String? value) {
// if (value == null || value.isEmpty) {
// errorMessageSetter(
// 'CONFIRM-PASSWORD', 'you must provide a valid confirm-password');
// } else {
// errorMessageSetter('CONFIRM-PASSWORD', "");
// widget.updateSignUpDetails('confirm_password', value);
// }
// return null;
// }
}
@@ -0,0 +1,393 @@
import 'package:flutter/material.dart';
class StepGetRegistration extends StatefulWidget {
final LabeledGlobalKey<FormState> bankAccountFormKey;
// final Function updateSignUpDetails;
final Function showConfirmSignUpButton;
final Function registrationDetails;
final Function finalStepProccessing;
const StepGetRegistration(
{Key? key,
// required this.updateSignUpDetails,
required this.registrationDetails,
required this.bankAccountFormKey,
required this.showConfirmSignUpButton,
required this.finalStepProccessing})
: super(key: key);
@override
_StepGetRegistrationState createState() => _StepGetRegistrationState();
}
class _StepGetRegistrationState extends State<StepGetRegistration> {
String firstname = "";
String firstnameErrorMessage = "";
String lastName = "";
String lastNameErrorMessage = "";
String mobNo = "";
String mobNoErrorMessage = "";
String password = "";
String passwordErrorMessage = "";
String confirmPassword = "";
String confirmPasswordErrorMessage = "";
@override
void initState() {
super.initState();
Map<String, String> signUpDetails = widget.registrationDetails();
if (mounted) {
setState(() {
firstname = signUpDetails['first_name']!;
lastName = signUpDetails['last_name']!;
mobNo = signUpDetails['mob_no']!;
password = signUpDetails['new_password']!;
confirmPassword = signUpDetails['confirm_password']!;
});
}
}
@override
void dispose() {
// widget.bankAccountFormKey.currentState?.validate();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Form(
key: widget.bankAccountFormKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: firstname,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "first name",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (firstnameErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$firstnameErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// first name code end here
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: lastName,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "last name",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (lastNameErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$lastNameErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// last name code
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: mobNo,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "mob no",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (mobNoErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$mobNoErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// mob no code end
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: password,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "password",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (passwordErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$passwordErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// new password code end
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: confirmPassword,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "confirmPassword",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (confirmPasswordErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$confirmPasswordErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// confirm password code end here
],
));
}
// void errorMessageSetter(String fieldName, String message) {
// setState(() {
// switch (fieldName) {
// case 'EMAIL-Id':
// emailErrorMessage = message;
// break;
// }
// });
// }
// String? _validateEmailId(String? value) {
// if (value == null || value.isEmpty) {
// errorMessageSetter('EMAIL-ID', 'you must provide a valid email-id');
// } else if (!validEmailFormat.hasMatch(value)) {
// errorMessageSetter('EMAIL-ID', 'format of your email address is invalid');
// } else {
// errorMessageSetter('EMAIL-ID', "");
// widget.updateSignUpDetails('email', value);
// }
// return null;
// }
void _toggleSignUpButtonVisibility(String value) {
widget.registrationDetails('confirmPassword', value);
if (value.isNotEmpty) {
widget.showConfirmSignUpButton(true);
} else {
widget.showConfirmSignUpButton(false);
}
}
}
@@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'sign_up_steps.dart';
class SignUpScreen extends StatefulWidget {
const SignUpScreen({Key? key}) : super(key: key);
@override
_SignUpScreenState createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(
body: SingleChildScrollView(
padding: const EdgeInsets.all(45),
child: Column(
children: <Widget>[
const SizedBox(
height: 16,
),
SizedBox(
height: 30,
child: Image.asset('/images/hadwin_system/cldnsure.png'),
),
const SizedBox(
height: 30,
),
const SignUpSteps(), // GO TO SIGN UP FORM
const SizedBox(
height: 27,
),
SizedBox(
width: double.infinity,
height: 16,
child: Center(
child: InkWell(
child: const Text(
'Already have an account? Sign in',
style:
TextStyle(fontSize: 14, color: Color(0xFF929BAB)),
),
onTap: () {
Navigator.pop(context);
},
),
),
),
const SizedBox(
height: 3,
)
],
),
),
),
onWillPop: () => Future.value(false));
}
}
@@ -0,0 +1,398 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pinput/pinput.dart';
import '../../Utils/color_constants.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_image_view.dart';
import '../../widgets/custom_text_form_field.dart';
import 'RegistrationDetails.dart';
import 'SignUpService.dart';
enum RegistrationStep {
SendOTP,
VerifyOTP,
EnterUserInfo,
SelectAccount,
}
class SignUpUserScreenNew extends StatefulWidget {
SignUpUserScreenNew({Key? key}) : super(key: key);
@override
_SignUpUserScreenState createState() => _SignUpUserScreenState();
}
class _SignUpUserScreenState extends State<SignUpUserScreenNew> {
final SignUpApiService userService = SignUpApiService();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
var selectedAccount;
TextEditingController emailcontroller = TextEditingController();
var email;
var otp;
var confirmPassword;
bool _passwordVisible = false;
bool _isPasswordValid = true;
void _validatePassword(String password) {
setState(() {
_isPasswordValid = password.isNotEmpty;
});
}
RegistrationStep currentStep = RegistrationStep.SendOTP;
void moveToNextStep() {
setState(() {
if (currentStep == RegistrationStep.SendOTP) {
currentStep = RegistrationStep.VerifyOTP;
} else if (currentStep == RegistrationStep.VerifyOTP) {
currentStep = RegistrationStep.EnterUserInfo;
} else if (currentStep == RegistrationStep.EnterUserInfo) {
currentStep = RegistrationStep.SelectAccount;
}
});
}
void showSuccessMessage(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
duration: const Duration(seconds: 2),
backgroundColor: Colors.green,
),
);
}
void showErrorMessage(String error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(error),
duration: const Duration(seconds: 2),
backgroundColor: Colors.red,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: CustomAppBar(
height: getVerticalSize(54),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleft,
margin: getMargin(left: 16, top: 13, bottom: 17),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Create User")),
body: Builder(
builder: (BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: SizedBox(
height: MediaQuery.of(context).size.height *
0.5, // Use 50% of the screen height
child: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
if(currentStep == RegistrationStep.SendOTP) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Email",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
controller: emailcontroller,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Email';
}
return null;
},
hintText: "Enter Your Email",
margin: getMargin(top: 7),
textInputType: TextInputType.emailAddress),
CustomButton(
height: getVerticalSize(50),
width: getHorizontalSize(396),
text: "Send OTP",
margin: getMargin(top: 25),
onTap: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
formData['usrGrpId'] = 46;
formData['email'] = emailcontroller.text;
try {
print('send email data is $formData');
await userService.sendEmail(formData);
await Future.delayed(
const Duration(seconds: 2));
moveToNextStep();
} catch (e) {
showErrorMessage(
'Failed to send OTP: $e');
}
}
},
),
Align(
alignment: Alignment.center,
child: Padding(
padding: getPadding(top: 28, bottom: 5),
child: RichText(
text: TextSpan(children: [
TextSpan(
text: "",
style: TextStyle(
color: ColorConstant.fromHex(
"#ff12282a"),
fontSize: getFontSize(16),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w400)),
TextSpan(
text: " ",
style: TextStyle(
color: ColorConstant.fromHex(
"#ff12282a"),
fontSize: getFontSize(16),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w700)),
TextSpan(
text: "",
style: TextStyle(
color: ColorConstant.fromHex(
"#ff0061ff"),
fontSize: getFontSize(16),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w700,
decoration:
TextDecoration.underline))
]),
textAlign: TextAlign.left)))
]);
}
else if(currentStep == RegistrationStep.VerifyOTP) {
return Container(
width: double.maxFinite,
padding: getPadding(
left: 16,
top: 76,
right: 16,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
CustomImageView(
svgPath: ImageConstant.imgMobile,
height: getVerticalSize(
82,
),
width: getHorizontalSize(
51,
),
),
Padding(
padding: getPadding(
top: 29,
),
child: Text(
"Email Verification",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold24,
),
),
Container(
width: getHorizontalSize(
302,
),
margin: getMargin(
left: 46,
top: 19,
right: 46,
),
child: Text(
"A mail with a 6-digit verification code was just sent to ${emailcontroller.text}",
maxLines: null,
textAlign: TextAlign.center,
style: AppStyle.txtGilroyMedium16,
),
),
Pinput(
length: 6,
showCursor: true,
defaultPinTheme: PinTheme(
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: ColorConstant.blue50,
),
),
textStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
onCompleted: (value) {
setState(() {
otp = value;
});
},
),
CustomButton(
height: getVerticalSize(
50,
),
text: "Next",
margin: getMargin(
top: 40,
),
onTap: () async {
try {
print('email is $email and otp is $otp');
await userService.otpverification(emailcontroller.text, otp);
moveToNextStep();
showSuccessMessage(
'Email verified successfully');
} catch (e) {
showErrorMessage('Failed to verify OTP: $e');
}
},
),
GestureDetector(
onTap: () async {
try {
await userService.resendEmail(email);
await Future.delayed(
const Duration(seconds: 5));
showSuccessMessage('OTP RESEND');
} catch (e) {
showErrorMessage(
'Failed to resend OTP: $e');
}
},
child: Padding(
padding: getPadding(top: 3),
child: Text("Forgot Password?",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium14BlueA700)),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: getPadding(
top: 18,
bottom: 5,
),
child: Row(
children: [
Padding(
padding: getPadding(
top: 2,
),
child: Text(
"Didnt get the code?",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16,
),
),
Padding(
padding: getPadding(
left: 12,
bottom: 1,
),
child: Text(
"Resend",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold16BlueA700,
),
),
],
),
),
),
],
),
);
}
else if (currentStep ==
RegistrationStep.EnterUserInfo) {
return Column(
children: [
CustomButton(
height: getVerticalSize(
50,
),
text: "Go to Registration Details",
margin: getMargin(
top: 40,
),
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
RegistrationDetailsScreen(email: emailcontroller.text),
),
);
},
),
],
);
}
else{
return Container();
}
},
),
),
),
),
);
},
),
);
}
}
@@ -0,0 +1,548 @@
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import '../../hadwin_components.dart';
import '../../utilities/slide_right_route.dart';
import '../Login Screen/login_screen.dart';
import 'StepGetEmailVerification.dart';
import 'StepGetRegistration.dart';
import 'step_createAccount.dart';
class SignUpSteps extends StatefulWidget {
const SignUpSteps({Key? key}) : super(key: key);
@override
_SignUpStepsState createState() => _SignUpStepsState();
}
class _SignUpStepsState extends State<SignUpSteps> {
late PageController _signUpStepController;
final createAccountFormKey = LabeledGlobalKey<FormState>("reateAccountForm");
final emailVerificationFormKey =
LabeledGlobalKey<FormState>("emailVerificationForm");
final signUpFormKey = LabeledGlobalKey<FormState>("signUpForm");
Map<String, String> accountDetails = {
'companyName': '',
'email': '',
'mobile': '',
'workspace': '',
'gstNumber': '',
'pancard': '',
};
Map<String, String> registrationDetails = {
'first_name': '',
'last_name': '',
'mob_no': '',
'new_password': '',
'confirm_password': '',
};
Map<String, String> accountsDetails() => accountDetails;
Map<String, String> registraionDetails() => registrationDetails;
String? email;
int _currentStep = 0;
List<bool> stepHasError = [false, false, false];
List<bool> stepCompletedSuccessfully = [false, false, false];
late List<Widget> signUpStepContent;
bool confirmSignUpButton = false;
@override
void initState() {
_signUpStepController = PageController();
signUpStepContent = [
StepCreateAccount(
registrationDetails: accountsDetails,
// updateSignUpDetails: updateSignUpDetails,
nameAddressFormKey: createAccountFormKey,
proceedToNextStep: _proceedToNextStep,
),
StepGetEmailVerification(
// updateSignUpDetails: updateSignUpDetails,
emailPasswordFormKey: emailVerificationFormKey,
// registrationDetails: registraionDetails,
proceedToNextStep: _proceedToNextStep,
),
StepGetRegistration(
// updateSignUpDetails: updateSignUpDetails,
bankAccountFormKey: signUpFormKey,
registrationDetails: registraionDetails,
showConfirmSignUpButton: showConfirmSignUpButton,
finalStepProccessing: _finalStepProccessing,
)
];
super.initState();
}
@override
void dispose() {
_signUpStepController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
child: Column(
children: [
SizedBox(
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [0, 1, 2]
.map((e) => Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
children: [
GestureDetector(
onTap: () => changeStepOnTap(e),
child: CircleAvatar(
backgroundColor: stepHasError[e]
? Colors.red.shade600
: !stepCompletedSuccessfully[e]
? const Color(0xffF5F7FA)
: Colors.green.shade600,
foregroundColor: !stepCompletedSuccessfully[e]
? const Color(0xFF0070BA)
: Colors.white,
radius: 18,
child: stepHasError[e]
? const Icon(
FluentIcons.warning_16_filled,
color: Colors.white,
)
: stepCompletedSuccessfully[e]
? const Icon(
FluentIcons.checkmark_16_regular)
: _currentStep == e
? const Icon(
FluentIcons.edit_16_filled)
: Text("${e + 1}")),
),
if (e < 2)
Container(
height: 10,
width: 70,
color: stepCompletedSuccessfully[e]
? Colors.green.shade600
: Colors.transparent,
),
],
))
.toList(),
),
),
const SizedBox(
height: 50,
),
SizedBox(
width: double.infinity,
height: _currentStep == 2 ? 230 : 300,
child: PageView(
clipBehavior: Clip.none,
controller: _signUpStepController,
physics: const NeverScrollableScrollPhysics(),
children: signUpStepContent,
),
),
if (_currentStep == 2)
Padding(
padding:
const EdgeInsets.symmetric(vertical: 3.6, horizontal: 10),
child: RichText(
text: TextSpan(
text: 'By signing up you are agreeing to the ',
style: const TextStyle(
fontSize: 14, color: Color(0xFF929BAB)),
children: <InlineSpan>[
TextSpan(
text: 'Terms & Conditions',
style: const TextStyle(
fontSize: 14, color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = () {
FocusManager.instance.primaryFocus?.unfocus();
Future.delayed(
const Duration(milliseconds: 300),
() => Navigator.push(
context,
SlideRightRoute(
page: const HadWinMarkdownViewer(
screenName: "Terms & Conditons",
urlRequested:
'https://raw.githubusercontent.com/brownboycodes/HADWIN/master/docs/TERMS_AND_CONDITIONS.md',
))));
}),
const TextSpan(
text: ' and our ',
style:
TextStyle(fontSize: 14, color: Color(0xFF929BAB)),
),
TextSpan(
text: 'End User License Agreement',
style: const TextStyle(
fontSize: 14, color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = () {
FocusManager.instance.primaryFocus?.unfocus();
Future.delayed(
const Duration(milliseconds: 300),
() => Navigator.push(
context,
SlideRightRoute(
page: const HadWinMarkdownViewer(
screenName:
"End User License Agreement",
urlRequested:
'https://raw.githubusercontent.com/brownboycodes/HADWIN/master/docs/END_USER_LICENSE_AGREEMENT.md',
))));
})
]))),
confirmSignUpButton
? Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
width: double.infinity,
height: 64,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.blueGrey.shade100,
offset: const Offset(0, 4),
blurRadius: 5.0)
],
gradient: const RadialGradient(
colors: [Color(0xff0070BA), Color(0xff1546A0)],
radius: 8.4,
center: Alignment(-0.24, -0.36)),
borderRadius: BorderRadius.circular(20),
),
child: ElevatedButton(
onPressed: _finalStepProccessing,
style: ElevatedButton.styleFrom(
// OLD: primary: Colors.transparent, // removed in Flutter 3.27 - by Azmat
backgroundColor: Colors.transparent, // renamed primary - by Azmat
shadowColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
),
child: const Text(
'Create Your Account',
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w600),
)),
)
: Row(
children: [
if (_currentStep > 0 && confirmSignUpButton == false)
Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(20),
),
child: TextButton(
onPressed: _goBackToPreviousStep,
style: TextButton.styleFrom(
// OLD: primary: Colors.transparent, // removed in Flutter 3.27 - by Azmat
foregroundColor: Colors.transparent, // renamed primary for TextButton - by Azmat
shadowColor: Colors.transparent,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
),
child: const Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 3.2,
children: [
Icon(
FluentIcons.arrow_left_16_filled,
color: Colors.blue,
size: 18,
),
Text(
'Back',
style: TextStyle(
color: Colors.blue, fontSize: 16),
),
])),
),
const Spacer(),
if (_currentStep < signUpStepContent.length - 1)
Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(20),
),
child: TextButton(
onPressed: _proceedToNextStep,
style: TextButton.styleFrom(
// OLD: primary: Colors.transparent, // removed in Flutter 3.27 - by Azmat
foregroundColor: Colors.transparent, // renamed primary for TextButton - by Azmat
shadowColor: Colors.transparent,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
),
child: const Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 3.2,
children: [
Text(
'Next',
style: TextStyle(
color: Colors.blue, fontSize: 16),
),
Icon(
FluentIcons.arrow_right_16_filled,
color: Colors.blue,
size: 18,
)
])),
),
],
),
],
));
}
void _finalStepProccessing() {
FocusManager.instance.primaryFocus?.unfocus();
_performErrorCheck(_currentStep + 1);
if (stepHasError[_currentStep] == false && mounted) {
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Text('Processing'),
backgroundColor: Colors.blue,
// onVisible: _tryRegistering,
),
)
.closed
.then((value) => _tryRegistering());
}
}
//? FUNCTION TO GO BACK TO PREVIOUS STEP OF THE CURRENT STEP
void _goBackToPreviousStep() {
FocusManager.instance.primaryFocus?.unfocus();
_performErrorCheck(_currentStep - 1);
if (_currentStep > 0) {
_signUpStepController.animateToPage(_currentStep - 1,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOutCubic);
setState(() {
_currentStep--;
});
}
}
//? FUNCTION TO MOVE TO THE NEXT STEP FROM THE CURRENT STEP
void _proceedToNextStep() {
FocusManager.instance.primaryFocus?.unfocus();
_performErrorCheck(_currentStep + 1);
print(stepHasError[_currentStep]);
print(_currentStep);
if (stepHasError[_currentStep] == false) {
if (_currentStep < signUpStepContent.length - 1) {
_signUpStepController.animateToPage(_currentStep + 1,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOutCubic);
setState(() {
_currentStep++;
});
}
}
}
//? FUNCTION TO UPDATE SIGN UP DETAILS
// void updateSignUpDetails(String key, String value) {
// setState(() {
// signUpDetails[key] = value;
// });
// }
//? FUNCTION TO TOGGLE VISIBILITY OF SIGN UP BUTTON
void showConfirmSignUpButton(bool value) {
if (value != confirmSignUpButton) {
setState(() {
confirmSignUpButton = value;
});
}
}
//? FUNCTION TO CHECK FOR ERRORS IN ANY STEPS PRIOR FROM THE ONE REQUESTED
void _performErrorCheck(int requestedIndex) {
if (_currentStep < requestedIndex) {
for (var i = 0; i < requestedIndex; i++) {
bool errorStatus = false;
switch (i) {
case 0:
createAccountFormKey.currentState?.validate();
if (accountDetails["companyName"]!.isEmpty ||
accountDetails['email']!.isEmpty ||
accountDetails['mobile']!.isEmpty ||
accountDetails['workspace']!.isEmpty ||
accountDetails['gstNumber']!.isEmpty ||
accountDetails['pancard']!.isEmpty ||
accountDetails['working']!.isEmpty) {
errorStatus = true;
}
break;
case 1:
emailVerificationFormKey.currentState?.validate();
if (stepCompletedSuccessfully[1]) {
errorStatus = false;
} else if (stepCompletedSuccessfully[0] && _currentStep == 1) {
// emailPasswordFormKey.currentState?.validate();
if (email!.isEmpty) {
errorStatus = true;
}
} else {
errorStatus = true;
}
break;
case 2:
signUpFormKey.currentState?.validate();
if (email!.isEmpty) {
errorStatus = true;
}
break;
}
setState(() {
stepHasError[i] = errorStatus;
stepCompletedSuccessfully[i] = !stepHasError[i];
});
if (errorStatus) {
break;
}
}
} else {
for (var i = _currentStep; i >= 0; i--) {
bool errorStatus = false;
switch (i) {
case 0:
createAccountFormKey.currentState?.validate();
if (accountDetails["companyName"]!.isEmpty ||
accountDetails['email']!.isEmpty ||
accountDetails['mobile']!.isEmpty ||
accountDetails['workspace']!.isEmpty ||
accountDetails['gstNumber']!.isEmpty ||
accountDetails['pancard']!.isEmpty ||
accountDetails['working']!.isEmpty) {
errorStatus = true;
}
break;
case 1:
emailVerificationFormKey.currentState?.validate();
if (stepCompletedSuccessfully[1]) {
errorStatus = false;
} else if (stepCompletedSuccessfully[0] && _currentStep == 1) {
// emailPasswordFormKey.currentState?.validate();
if (email!.isEmpty) {
errorStatus = true;
}
} else {
errorStatus = true;
}
break;
case 2:
signUpFormKey.currentState?.validate();
if (registrationDetails["first_name"]!.isEmpty ||
registrationDetails["last_name"]!.isEmpty ||
registrationDetails["mob_no"]!.isEmpty ||
registrationDetails["new_password"]!.isEmpty ||
registrationDetails["confirm_password"]!.isEmpty) {
errorStatus = true;
}
break;
}
setState(() {
stepHasError[i] = errorStatus;
stepCompletedSuccessfully[i] = !stepHasError[i];
});
if (errorStatus) {
break;
}
}
}
}
void _tryRegistering() {
sendData(urlPath: '/token/addOneAppUser', data: registrationDetails)
.then((response) {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
if (response.keys.join().toLowerCase().contains("error")) {
showErrorAlert(context, response);
} else {
print('Account succesfully created');
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(
content: Text("Account Created Successfully"),
backgroundColor: Colors.green))
.closed
.then((value) => Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => const LoginScreen()),
(route) => false));
// Navigator.of(context).pushAndRemoveUntil(
// MaterialPageRoute(
// builder: (context) => ChooseUsername(
// userAuthKey: response['authorization_token'],
// userData: response['user'],
// )),
// (route) => false);
}
});
}
//? FUNCTION TO CHANGE STEP ON TAPPING THE OVERHEAD STEP NUMBERS
void changeStepOnTap(int requestedIndex) {
FocusManager.instance.primaryFocus?.unfocus();
if (requestedIndex < _currentStep) {
_signUpStepController.animateToPage(requestedIndex,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOutCubic);
_performErrorCheck(requestedIndex);
setState(() {
_currentStep = requestedIndex;
});
} else if (requestedIndex > _currentStep &&
requestedIndex != _currentStep) {
_performErrorCheck(requestedIndex);
if (!stepHasError.sublist(0, requestedIndex).contains(true)) {
if (_currentStep < signUpStepContent.length - 1) {
_signUpStepController.animateToPage(requestedIndex,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOutCubic);
setState(() {
_currentStep = requestedIndex;
});
}
} else {
int stepWithError =
stepHasError.sublist(0, requestedIndex).indexOf(true);
_signUpStepController.animateToPage(stepWithError,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOutCubic);
setState(() {
_currentStep = stepWithError;
});
}
}
}
}
@@ -0,0 +1,555 @@
import 'package:flutter/material.dart';
class StepCreateAccount extends StatefulWidget {
final LabeledGlobalKey<FormState> nameAddressFormKey;
// final Function updateSignUpDetails;
final Function registrationDetails;
final Function proceedToNextStep;
const StepCreateAccount(
{Key? key,
// required this.updateSignUpDetails,
required this.nameAddressFormKey,
required this.registrationDetails,
required this.proceedToNextStep})
: super(key: key);
@override
_StepCreateAccountState createState() => _StepCreateAccountState();
}
class _StepCreateAccountState extends State<StepCreateAccount> {
String companyName = "";
String companyNameErrorMessage = "";
String email = "";
String emailErrorMessage = "";
RegExp validEmailFormat = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+");
String mobNo = "";
String mobNoErrorMessage = "";
String workspace = "";
String workspaceErrorMessage = "";
String gstNumber = "";
String gstNumberErrorMessage = "";
String pancard = "";
String pancardErrorMessage = "";
String working = "";
String workingErrorMessage = "";
@override
void initState() {
super.initState();
Map<String, String> signUpDetails = widget.registrationDetails();
if (mounted) {
setState(() {
companyName = signUpDetails['companyName'].toString();
email = signUpDetails['email'].toString();
mobNo = signUpDetails['mobile'].toString();
workspace = signUpDetails['workspace'].toString();
gstNumber = signUpDetails['gstNumber'].toString();
pancard = signUpDetails['pancard'].toString();
working = signUpDetails['working'].toString();
});
}
}
@override
void dispose() {
// widget.nameAddressFormKey.currentState?.validate();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: widget.nameAddressFormKey,
child: Column(
children: [
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
// initialValue: companyName,
validator: _validatecompanyName,
autofocus: mounted,
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(
left: 15, bottom: 11, top: 11, right: 15),
hintText: "Company_Name",
hintStyle:
TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style:
const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
keyboardType: TextInputType.name,
textInputAction: TextInputAction.next,
),
),
if (companyNameErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
width: double.infinity,
child: Text(
"\t\t\t\t$companyNameErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// COMPANY NAME CODE END HERE
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
// initialValue: email,
// validator: _validatelastName,
autofocus: mounted,
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(
left: 15, bottom: 11, top: 11, right: 15),
hintText: "email",
hintStyle:
TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style:
const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
keyboardType: TextInputType.name,
textInputAction: TextInputAction.next,
),
),
if (emailErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
width: double.infinity,
child: Text(
"\t\t\t\t$emailErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// input field for email name ends here
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
// initialValue: mobNo,
// validator: _validatemobno,
autofocus: mounted,
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(
left: 15, bottom: 11, top: 11, right: 15),
hintText: "mob_no",
hintStyle:
TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style:
const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
keyboardType: TextInputType.name,
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) => widget.proceedToNextStep(),
),
),
if (mobNoErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
width: double.infinity,
child: Text(
"\t\t\t\t$mobNoErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// input field for Mob No ends here
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
// initialValue: workspace,
// validator: _validatelastName,
autofocus: mounted,
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(
left: 15, bottom: 11, top: 11, right: 15),
hintText: "workspace",
hintStyle:
TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style:
const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
keyboardType: TextInputType.name,
textInputAction: TextInputAction.next,
),
),
if (workspaceErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
width: double.infinity,
child: Text(
"\t\t\t\t$workspaceErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// workspace code end
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
// initialValue: gstNumber,
// validator: _validatelastName,
autofocus: mounted,
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(
left: 15, bottom: 11, top: 11, right: 15),
hintText: "gst number",
hintStyle:
TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style:
const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
keyboardType: TextInputType.name,
textInputAction: TextInputAction.next,
),
),
if (gstNumberErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
width: double.infinity,
child: Text(
"\t\t\t\t$gstNumberErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// gst number code end here
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
// initialValue: pancard,
// validator: _validatelastName,
autofocus: mounted,
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(
left: 15, bottom: 11, top: 11, right: 15),
hintText: "pancard",
hintStyle:
TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style:
const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
keyboardType: TextInputType.name,
textInputAction: TextInputAction.next,
),
),
if (pancardErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
width: double.infinity,
child: Text(
"\t\t\t\t$pancardErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// pancard end here
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
// initialValue: working,
// validator: _validatelastName,
autofocus: mounted,
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(
left: 15, bottom: 11, top: 11, right: 15),
hintText: "working",
hintStyle:
TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style:
const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
keyboardType: TextInputType.name,
textInputAction: TextInputAction.next,
),
),
if (workingErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
width: double.infinity,
child: Text(
"\t\t\t\t$workingErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
],
)),
),
);
}
void errorMessageSetter(String fieldName, String message) {
setState(() {
switch (fieldName) {
case 'COMPANY_NAME':
companyNameErrorMessage = message;
break;
// case 'LAST-NAME':
// last_nameErrorMessage = message;
// break;
// case 'MOB-NO':
// mob_noErrorMessage = message;
// break;
}
});
}
String? _validatecompanyName(String? value) {
if (value == null || value.isEmpty) {
errorMessageSetter('COMPANY_NAME', 'you must provide your Company name');
} else if (value.length > 100) {
errorMessageSetter(
'COMPANY_NAME', 'name cannot contain more than 100 characters');
} else {
errorMessageSetter('COMPANY_NAME', "");
// widget.updateSignUpDetails('first_name', value);
}
return null;
}
// String? _validatelastName(String? value) {
// if (value == null || value.isEmpty) {
// errorMessageSetter('LAST-NAME', 'you must provide your last name');
// } else if (value.length > 100) {
// errorMessageSetter(
// 'LAST-NAME', 'name cannot contain more than 100 characters');
// } else {
// errorMessageSetter('LAST-NAME', "");
// widget.updateSignUpDetails('last_name', value);
// }
// return null;
// }
// String? _validatemobno(String? value) {
// if (value == null || value.isEmpty) {
// errorMessageSetter('MOB-NO', 'you must provide your MOB-NO');
// } else if (value.length > 100) {
// errorMessageSetter(
// 'MOB-NO', 'name cannot contain more than 100 characters');
// } else {
// errorMessageSetter('MOB-NO', "");
// widget.updateSignUpDetails('mob_no', value);
// }
// return null;
// }
// String? _validateAddress(String? value) {
// if (value == null || value.isEmpty) {
// errorMessageSetter(
// 'RESIDENTIAL-ADDRESS', 'you must provide your residential address');
// } else if (value.length > 300) {
// errorMessageSetter('RESIDENTIAL-ADDRESS',
// 'address cannot contain more than 300 characters');
// } else {
// errorMessageSetter('RESIDENTIAL-ADDRESS', "");
// widget.updateSignUpDetails('address', value);
// }
// return null;
// }
}
@@ -0,0 +1,84 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../Login Screen/login_screen.dart';
import '../main_app_screen/tabbed_layout_component.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
var isLogin = false;
Map<String, dynamic> userData = {};
Future<void> checkifLogin() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool? isLoggedIn = prefs.getBool('isLoggedIn');
var userdatastr = prefs.getString('userData');
if (kDebugMode) {
print('userData....$userdatastr');
}
if (isLoggedIn != null && isLoggedIn) {
setState(() {
isLogin = true;
});
}
if (userdatastr != null) {
try{
userData = json.decode(userdatastr);
if (kDebugMode) {
print(userData['token']);
}
}catch(e){
if (kDebugMode) {
print("error is ..................$e");
}
}
} else {
setState(() {
isLogin = false;
});
}
}
@override
void initState() {
checkifLogin().then((value) async => {
Future.delayed(const Duration(seconds: 2), () {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => isLogin
? TabbedLayoutComponent(): const LoginScreen()
),);
})
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Center(
child: SvgPicture.asset(
'assets/images/cloudnsuresp.svg',
width: 100,
),
),
),
),
);
}
}
+480
View File
@@ -0,0 +1,480 @@
import 'package:flutter/material.dart';
import '../Utils/color_constants.dart';
import '../Utils/size_utils.dart';
class AppDecoration {
static BoxDecoration get fillBlue5001 => BoxDecoration(
color: ColorConstant.blue5001,
);
static BoxDecoration get outlineGray5002 => BoxDecoration(
color: ColorConstant.gray5002,
border: Border.all(
color: ColorConstant.gray5002,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get outlineBlueA70001 => BoxDecoration(
border: Border.all(
color: ColorConstant.blueA70001,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get outlineGray60026 => BoxDecoration(
color: ColorConstant.whiteA700,
boxShadow: [
BoxShadow(
color: ColorConstant.gray60026,
spreadRadius: getHorizontalSize(
2,
),
blurRadius: getHorizontalSize(
2,
),
offset: Offset(
0,
2.41,
),
),
],
);
static BoxDecoration get txtFillBluegray100 => BoxDecoration(
color: ColorConstant.blueGray100,
);
static BoxDecoration get fillBlueA700 => BoxDecoration(
color: ColorConstant.blueA700,
);
static BoxDecoration get fillBluegray50 => BoxDecoration(
color: ColorConstant.blueGray50,
);
static BoxDecoration get outlineBlueA7002 => BoxDecoration(
color: ColorConstant.whiteA700,
border: Border.all(
color: ColorConstant.blueA700,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get outlineBlueA7001 => BoxDecoration(
color: ColorConstant.whiteA700,
border: Border.all(
color: ColorConstant.blueA700,
width: getHorizontalSize(
1,
),
),
boxShadow: [
BoxShadow(
color: ColorConstant.gray60019,
spreadRadius: getHorizontalSize(
2,
),
blurRadius: getHorizontalSize(
2,
),
offset: Offset(
0,
12,
),
),
],
);
static BoxDecoration get outlineGray70011 => BoxDecoration(
color: ColorConstant.whiteA700,
boxShadow: [
BoxShadow(
color: ColorConstant.gray70011,
spreadRadius: getHorizontalSize(
2,
),
blurRadius: getHorizontalSize(
2,
),
offset: Offset(
0,
0,
),
),
],
);
static BoxDecoration get outlineGray600191 => BoxDecoration();
static BoxDecoration get txtOutlineBlueA700 => BoxDecoration(
border: Border.all(
color: ColorConstant.blueA700,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get outlineBlue50 => BoxDecoration(
color: ColorConstant.whiteA700,
border: Border.all(
color: ColorConstant.blue50,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get txtFillBlueA700 => BoxDecoration(
color: ColorConstant.blueA700,
);
static BoxDecoration get outlineBlack90019 => BoxDecoration(
color: ColorConstant.blueA700,
boxShadow: [
BoxShadow(
color: ColorConstant.black90019,
spreadRadius: getHorizontalSize(
2,
),
blurRadius: getHorizontalSize(
2,
),
offset: Offset(
0,
2,
),
),
],
);
static BoxDecoration get outlineBluegray100 => BoxDecoration(
color: ColorConstant.gray50,
border: Border(
bottom: BorderSide(
color: ColorConstant.blueGray100,
width: getHorizontalSize(
1,
),
),
),
);
static BoxDecoration get fillGray50 => BoxDecoration(
color: ColorConstant.gray50,
);
static BoxDecoration get outlineBluegray10001 => BoxDecoration(
color: ColorConstant.whiteA700,
border: Border.all(
color: ColorConstant.blueGray10001,
width: getHorizontalSize(
1,
),
),
boxShadow: [
BoxShadow(
color: ColorConstant.black90033,
spreadRadius: getHorizontalSize(
2,
),
blurRadius: getHorizontalSize(
2,
),
offset: Offset(
0,
1,
),
),
],
);
static BoxDecoration get fillBlack900b2 => BoxDecoration(
color: ColorConstant.black900B2,
);
static BoxDecoration get outlineBlack90033 => BoxDecoration(
border: Border.all(
color: ColorConstant.black90033,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get outlineBlack90011 => BoxDecoration(
color: ColorConstant.whiteA700,
boxShadow: [
BoxShadow(
color: ColorConstant.black90011,
spreadRadius: getHorizontalSize(
2,
),
blurRadius: getHorizontalSize(
2,
),
offset: Offset(
0,
0,
),
),
],
);
static BoxDecoration get outlineGray30001 => BoxDecoration(
border: Border.all(
color: ColorConstant.gray30001,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get outlineBlue200 => BoxDecoration(
border: Border.all(
color: ColorConstant.blue200,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get outlineGray60019 => BoxDecoration(
color: ColorConstant.whiteA700,
boxShadow: [
BoxShadow(
color: ColorConstant.gray60019,
spreadRadius: getHorizontalSize(
2,
),
blurRadius: getHorizontalSize(
2,
),
offset: Offset(
0,
12,
),
),
],
);
static BoxDecoration get outlineGray700261 => BoxDecoration(
color: ColorConstant.whiteA700,
boxShadow: [
BoxShadow(
color: ColorConstant.gray70026,
spreadRadius: getHorizontalSize(
2,
),
blurRadius: getHorizontalSize(
2,
),
offset: Offset(
0,
0,
),
),
],
);
static BoxDecoration get fillWhiteA700 => BoxDecoration(
color: ColorConstant.whiteA700,
);
static BoxDecoration get outlineBlueA700 => BoxDecoration(
color: ColorConstant.gray50,
border: Border.all(
color: ColorConstant.blueA700,
width: getHorizontalSize(
2,
),
strokeAlign: strokeAlignOutside,
),
);
static BoxDecoration get fillBlue900 => BoxDecoration(
color: ColorConstant.blue900,
);
static BoxDecoration get outlineBluegray1002 => BoxDecoration(
color: ColorConstant.whiteA700,
border: Border(
top: BorderSide(
color: ColorConstant.blueGray100,
width: getHorizontalSize(
1,
),
),
bottom: BorderSide(
color: ColorConstant.blueGray100,
width: getHorizontalSize(
1,
),
),
),
);
static BoxDecoration get fillRed100 => BoxDecoration(
color: ColorConstant.red100,
);
static BoxDecoration get outlineBluegray1001 => BoxDecoration(
color: ColorConstant.whiteA700,
border: Border.all(
color: ColorConstant.blueGray100,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get outlineYellow9003f => BoxDecoration(
color: ColorConstant.whiteA700,
border: Border.all(
color: ColorConstant.yellow9003f,
width: getHorizontalSize(
1,
),
strokeAlign: strokeAlignOutside,
),
);
static BoxDecoration get fillBlue50 => BoxDecoration(
color: ColorConstant.blue50,
);
static BoxDecoration get outlineGray70026 => BoxDecoration(
color: ColorConstant.whiteA70099,
boxShadow: [
BoxShadow(
color: ColorConstant.gray70026,
spreadRadius: getHorizontalSize(
2,
),
blurRadius: getHorizontalSize(
2,
),
offset: Offset(
0,
0,
),
),
],
);
static BoxDecoration get txtOutlineBlack9000c => BoxDecoration(
color: ColorConstant.gray100,
border: Border.all(
color: ColorConstant.black9000c,
width: getHorizontalSize(
1,
),
),
);
static BoxDecoration get fillRed700 => BoxDecoration(
color: ColorConstant.red700,
);
static BoxDecoration get fillGray5003 => BoxDecoration(
color: ColorConstant.gray5003,
);
static BoxDecoration get fillGray200 => BoxDecoration(
color: ColorConstant.gray200,
);
static BoxDecoration get outlineBluegray50 => BoxDecoration(
color: ColorConstant.whiteA700,
border: Border.all(
color: ColorConstant.blueGray50,
width: getHorizontalSize(
1,
),
),
);
}
class BorderRadiusStyle {
static BorderRadius customBorderTL50 = BorderRadius.only(
topLeft: Radius.circular(
getHorizontalSize(
50,
),
),
bottomLeft: Radius.circular(
getHorizontalSize(
50,
),
),
);
static BorderRadius customBorderTL10 = BorderRadius.only(
topLeft: Radius.circular(
getHorizontalSize(
10,
),
),
topRight: Radius.circular(
getHorizontalSize(
10,
),
),
);
static BorderRadius circleBorder9 = BorderRadius.circular(
getHorizontalSize(
9,
),
);
static BorderRadius circleBorder22 = BorderRadius.circular(
getHorizontalSize(
22,
),
);
static BorderRadius roundedBorder16 = BorderRadius.circular(
getHorizontalSize(
16,
),
);
static BorderRadius circleBorder12 = BorderRadius.circular(
getHorizontalSize(
12,
),
);
static BorderRadius roundedBorder6 = BorderRadius.circular(
getHorizontalSize(
6,
),
);
static BorderRadius circleBorder25 = BorderRadius.circular(
getHorizontalSize(
25,
),
);
static BorderRadius roundedBorder3 = BorderRadius.circular(
getHorizontalSize(
3,
),
);
static BorderRadius circleBorder30 = BorderRadius.circular(
getHorizontalSize(
30,
),
);
static BorderRadius circleBorder76 = BorderRadius.circular(
getHorizontalSize(
76,
),
);
static BorderRadius txtRoundedBorder6 = BorderRadius.circular(
getHorizontalSize(
6,
),
);
static BorderRadius circleBorder61 = BorderRadius.circular(
getHorizontalSize(
61,
),
);
}
// Comment/Uncomment the below code based on your Flutter SDK version.
// For Flutter SDK Version 3.7.2 or greater.
double get strokeAlignInside => BorderSide.strokeAlignInside;
double get strokeAlignCenter => BorderSide.strokeAlignCenter;
double get strokeAlignOutside => BorderSide.strokeAlignOutside;
// For Flutter SDK Version 3.7.1 or less.
// StrokeAlign get strokeAlignInside => StrokeAlign.inside;
//
// StrokeAlign get strokeAlignCenter => StrokeAlign.center;
//
// StrokeAlign get strokeAlignOutside => StrokeAlign.outside;
File diff suppressed because it is too large Load Diff
+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';
// }
}
+46
View File
@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import '../custom_image_view.dart';
// ignore: must_be_immutable
class AppbarImage extends StatelessWidget {
AppbarImage(
{required this.height,
required this.width,
this.imagePath,
this.svgPath,
this.margin,
this.onTap});
double height;
double width;
String? imagePath;
String? svgPath;
EdgeInsetsGeometry? margin;
Function? onTap;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
onTap?.call();
},
child: Padding(
padding: margin ?? EdgeInsets.zero,
child: CustomImageView(
svgPath: svgPath,
imagePath: imagePath,
height: height,
width: width,
fit: BoxFit.contain,
),
),
);
}
}
+36
View File
@@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
import '../../Utils/color_constants.dart';
import '../../theme/app_style.dart';
// ignore: must_be_immutable
class AppbarTitle extends StatelessWidget {
AppbarTitle({required this.text, this.margin, this.onTap});
String text;
EdgeInsetsGeometry? margin;
Function? onTap;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
onTap?.call();
},
child: Padding(
padding: margin ?? EdgeInsets.zero,
child: Text(
text,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold24.copyWith(
color: ColorConstant.blueGray900,
),
),
),
);
}
}
+56
View File
@@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import '../../Utils/size_utils.dart';
// ignore: must_be_immutable
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget{
CustomAppBar(
{required this.height,
this.leadingWidth,
this.leading,
this.title,
this.bottom,
this.flexibleSpace,
this.centerTitle,
this.actions});
double height;
double? leadingWidth;
Widget? leading;
Widget? title;
PreferredSize? flexibleSpace;
TabBar? bottom;
bool? centerTitle;
List<Widget>? actions;
@override
Widget build(BuildContext context) {
return AppBar(
elevation: 0,
toolbarHeight: height,
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
leadingWidth: leadingWidth ?? 0,
leading: leading,
title: title,
bottom: bottom,
flexibleSpace: flexibleSpace,
titleSpacing: 0,
centerTitle: centerTitle ?? false,
actions: actions,
);
}
@override
Size get preferredSize => Size(
size.width,
height,
);
}
+132
View File
@@ -0,0 +1,132 @@
import 'package:flutter/material.dart';
import '../Utils/color_constants.dart';
import '../Utils/image_constant.dart';
import '../Utils/size_utils.dart';
import 'custom_image_view.dart';
class CustomBottomBar extends StatefulWidget {
CustomBottomBar({this.onChanged});
Function(BottomBarEnum)? onChanged;
@override
_CustomBottomBarState createState() => _CustomBottomBarState();
}
class _CustomBottomBarState extends State<CustomBottomBar> {
int selectedIndex = 0;
List<BottomMenuModel> bottomMenuList = [
BottomMenuModel(
icon: ImageConstant.imgFire,
type: BottomBarEnum.Fire,
),
BottomMenuModel(
icon: ImageConstant.imgSearchWhiteA70020x20,
type: BottomBarEnum.Searchwhitea70020x20,
),
BottomMenuModel(
icon: ImageConstant.imgMenu,
type: BottomBarEnum.Menu,
),
BottomMenuModel(
icon: ImageConstant.imgOverflowmenuWhiteA700,
type: BottomBarEnum.Overflowmenuwhitea700,
)
];
@override
Widget build(BuildContext context) {
return Container(
margin: getMargin(
left: 16,
right: 16,
),
decoration: BoxDecoration(
color: ColorConstant.blueA700,
borderRadius: BorderRadius.circular(
getHorizontalSize(
14,
),
),
),
child: BottomNavigationBar(
backgroundColor: Colors.transparent,
showSelectedLabels: false,
showUnselectedLabels: false,
elevation: 0,
currentIndex: selectedIndex,
type: BottomNavigationBarType.fixed,
items: List.generate(bottomMenuList.length, (index) {
return BottomNavigationBarItem(
icon: CustomImageView(
svgPath: bottomMenuList[index].icon,
height: getSize(
24,
),
width: getSize(
24,
),
color: ColorConstant.whiteA700,
),
activeIcon: CustomImageView(
svgPath: bottomMenuList[index].icon,
height: getSize(
24,
),
width: getSize(
24,
),
color: ColorConstant.whiteA700,
),
label: '',
);
}),
onTap: (index) {
selectedIndex = index;
widget.onChanged?.call(bottomMenuList[index].type);
setState(() {});
},
),
);
}
}
enum BottomBarEnum {
Fire,
Searchwhitea70020x20,
Menu,
Overflowmenuwhitea700,
}
class BottomMenuModel {
BottomMenuModel({required this.icon, required this.type});
String icon;
BottomBarEnum type;
}
class DefaultWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Please replace the respective Widget here',
style: TextStyle(
fontSize: 18,
),
),
],
),
),
);
}
}
+352
View File
@@ -0,0 +1,352 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import '../Utils/color_constants.dart';
import '../Utils/size_utils.dart';
class CustomButton extends StatelessWidget {
CustomButton(
{this.shape,
this.padding,
this.variant,
this.fontStyle,
this.alignment,
this.margin,
this.onTap,
this.width,
this.height,
this.text,
this.prefixWidget,
this.suffixWidget});
ButtonShape? shape;
ButtonPadding? padding;
ButtonVariant? variant;
ButtonFontStyle? fontStyle;
Alignment? alignment;
EdgeInsetsGeometry? margin;
VoidCallback? onTap;
double? width;
double? height;
String? text;
Widget? prefixWidget;
Widget? suffixWidget;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment!,
child: _buildButtonWidget(),
)
: _buildButtonWidget();
}
_buildButtonWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: TextButton(
onPressed: onTap,
style: _buildTextButtonStyle(),
child: _buildButtonWithOrWithoutIcon(),
),
);
}
_buildButtonWithOrWithoutIcon() {
if (prefixWidget != null || suffixWidget != null) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
prefixWidget ?? SizedBox(),
Text(
text ?? "",
textAlign: TextAlign.center,
style: _setFontStyle(),
),
suffixWidget ?? SizedBox(),
],
);
} else {
return Text(
text ?? "",
textAlign: TextAlign.center,
style: _setFontStyle(),
);
}
}
_buildTextButtonStyle() {
return TextButton.styleFrom(
fixedSize: Size(
width ?? double.maxFinite,
height ?? getVerticalSize(40),
),
padding: _setPadding(),
backgroundColor: _setColor(),
side: _setTextButtonBorder(),
shape: RoundedRectangleBorder(
borderRadius: _setBorderRadius(),
),
);
}
_setPadding() {
switch (padding) {
case ButtonPadding.PaddingT14:
return getPadding(
top: 14,
right: 14,
bottom: 14,
);
case ButtonPadding.PaddingT7:
return getPadding(
top: 7,
right: 7,
bottom: 7,
);
case ButtonPadding.PaddingAll7:
return getPadding(
all: 7,
);
case ButtonPadding.PaddingAll3:
return getPadding(
all: 3,
);
default:
return getPadding(
all: 14,
);
}
}
_setColor() {
switch (variant) {
case ButtonVariant.FillBlue50:
return ColorConstant.blue50;
case ButtonVariant.FillDeeporangeA10033:
return ColorConstant.deepOrangeA10033;
case ButtonVariant.FillGray10001:
return ColorConstant.gray10001;
case ButtonVariant.FillLightblue100:
return ColorConstant.lightBlue100;
case ButtonVariant.FillRed200:
return ColorConstant.red200;
case ButtonVariant.FillGreenA100:
return ColorConstant.greenA100;
case ButtonVariant.FillBlueA200:
return ColorConstant.blueA200;
case ButtonVariant.FillBluegray50:
return ColorConstant.blueGray50;
case ButtonVariant.OutlineBlueA700:
return null;
default:
return ColorConstant.blueA700;
}
}
_setTextButtonBorder() {
switch (variant) {
case ButtonVariant.OutlineBlueA700:
return BorderSide(
color: ColorConstant.blueA700,
width: getHorizontalSize(
1.00,
),
);
case ButtonVariant.FillBlueA700:
case ButtonVariant.FillBlue50:
case ButtonVariant.FillDeeporangeA10033:
case ButtonVariant.FillGray10001:
case ButtonVariant.FillLightblue100:
case ButtonVariant.FillRed200:
case ButtonVariant.FillGreenA100:
case ButtonVariant.FillBlueA200:
case ButtonVariant.FillBluegray50:
return null;
default:
return null;
}
}
_setBorderRadius() {
switch (shape) {
case ButtonShape.RoundedBorder2:
return BorderRadius.circular(
getHorizontalSize(
2.00,
),
);
case ButtonShape.RoundedBorder16:
return BorderRadius.circular(
getHorizontalSize(
16.00,
),
);
case ButtonShape.Square:
return BorderRadius.circular(0);
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
_setFontStyle() {
switch (fontStyle) {
case ButtonFontStyle.GilroyMedium14:
return TextStyle(
color: ColorConstant.blueA700,
fontSize: getFontSize(
14,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.GilroyMedium14WhiteA700:
return TextStyle(
color: ColorConstant.whiteA700,
fontSize: getFontSize(
14,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.GilroyMedium16Black900:
return TextStyle(
color: ColorConstant.black900,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.SFUIDisplayBold12:
return TextStyle(
color: ColorConstant.whiteA700,
fontSize: getFontSize(
12,
),
fontFamily: 'SF UI Display',
fontWeight: FontWeight.w700,
);
case ButtonFontStyle.GilroyMedium16BlueA700:
return TextStyle(
color: ColorConstant.blueA700,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.GilroyMedium12:
return TextStyle(
color: ColorConstant.deepOrange400,
fontSize: getFontSize(
12,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.GilroyMedium12Red700:
return TextStyle(
color: ColorConstant.red700,
fontSize: getFontSize(
12,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.InterSemiBold10:
return TextStyle(
color: ColorConstant.black90001,
fontSize: getFontSize(
10,
),
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
);
case ButtonFontStyle.RobotoMedium14:
return TextStyle(
color: ColorConstant.whiteA700,
fontSize: getFontSize(
14,
),
fontFamily: 'Roboto',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.InterRegular14:
return TextStyle(
color: ColorConstant.blueGray400,
fontSize: getFontSize(
14,
),
fontFamily: 'Inter',
fontWeight: FontWeight.w400,
);
default:
return TextStyle(
color: ColorConstant.whiteA700,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
}
}
}
enum ButtonShape {
Square,
RoundedBorder6,
RoundedBorder2,
RoundedBorder16,
}
enum ButtonPadding {
PaddingAll14,
PaddingT14,
PaddingT7,
PaddingAll7,
PaddingAll3,
}
enum ButtonVariant {
FillBlueA700,
OutlineBlueA700,
FillBlue50,
FillDeeporangeA10033,
FillGray10001,
FillLightblue100,
FillRed200,
FillGreenA100,
FillBlueA200,
FillBluegray50,
}
enum ButtonFontStyle {
GilroyMedium16,
GilroyMedium14,
GilroyMedium14WhiteA700,
GilroyMedium16Black900,
SFUIDisplayBold12,
GilroyMedium16BlueA700,
GilroyMedium12,
GilroyMedium12Red700,
InterSemiBold10,
RobotoMedium14,
InterRegular14,
}
+148
View File
@@ -0,0 +1,148 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import '../Utils/color_constants.dart';
import '../Utils/size_utils.dart';
class CustomCheckbox extends StatelessWidget {
CustomCheckbox(
{this.fontStyle,
this.alignment,
this.isRightCheck = false,
this.iconSize,
this.value,
this.onChange,
this.text,
this.width,
this.margin});
CheckboxFontStyle? fontStyle;
Alignment? alignment;
bool? isRightCheck;
double? iconSize;
bool? value;
Function(bool)? onChange;
String? text;
double? width;
EdgeInsetsGeometry? margin;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildCheckboxWidget(),
)
: _buildCheckboxWidget();
}
_buildCheckboxWidget() {
return InkWell(
onTap: () {
value = !(value!);
onChange!(value!);
},
child: Container(
width: width,
margin: margin ?? EdgeInsets.zero,
child: isRightCheck! ? getRightSideCheckbox() : getLeftSideCheckbox(),
),
);
}
Widget getRightSideCheckbox() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: EdgeInsets.only(
right: 8,
),
child: getTextWidget(),
),
getCheckboxWidget(),
],
);
}
Widget getLeftSideCheckbox() {
return Row(
children: [
getCheckboxWidget(),
Padding(
padding: EdgeInsets.only(
left: 8,
),
child: getTextWidget(),
),
],
);
}
Widget getTextWidget() {
return Text(
text ?? "",
textAlign: TextAlign.center,
style: _setFontStyle(),
);
}
Widget getCheckboxWidget() {
return SizedBox(
height: iconSize,
width: iconSize,
child: Checkbox(
value: value ?? false,
onChanged: (value) {
onChange!(value!);
},
checkColor: ColorConstant.whiteA700,
visualDensity: VisualDensity(
vertical: -4,
horizontal: -4,
),
),
);
}
_setFontStyle() {
switch (fontStyle) {
case CheckboxFontStyle.GilroyMedium16:
return TextStyle(
color: ColorConstant.blueGray900,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case CheckboxFontStyle.GilroyMedium14:
return TextStyle(
color: ColorConstant.blueGray300,
fontSize: getFontSize(
14,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
default:
return TextStyle(
color: ColorConstant.blueGray400,
fontSize: getFontSize(
14,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w400,
);
}
}
}
enum CheckboxFontStyle { GilroyRegular14, GilroyMedium16, GilroyMedium14 }
+199
View File
@@ -0,0 +1,199 @@
import 'package:flutter/material.dart';
import '../Utils/color_constants.dart';
import '../Utils/image_constant.dart';
import '../Utils/size_utils.dart';
class CustomDropDown extends StatelessWidget {
CustomDropDown(
{this.shape,
this.padding,
this.variant,
this.fontStyle,
this.alignment,
this.width,
this.margin,
this.focusNode,
this.icon,
this.hintText,
this.prefix,
this.prefixConstraints,
this.items,
this.onChanged,
this.validator});
DropDownShape? shape;
DropDownPadding? padding;
DropDownVariant? variant;
DropDownFontStyle? fontStyle;
Alignment? alignment;
double? width;
EdgeInsetsGeometry? margin;
FocusNode? focusNode;
Widget? icon;
String? hintText;
Widget? prefix;
BoxConstraints? prefixConstraints;
List<String>? items;
Function(String)? onChanged;
FormFieldValidator<String>? validator;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildDropDownWidget(),
)
: _buildDropDownWidget();
}
_buildDropDownWidget() {
return Container(
width: width ?? double.maxFinite,
margin: margin,
child: DropdownButtonFormField(
focusNode: focusNode,
icon: icon,
style: _setFontStyle(),
decoration: _buildDecoration(),
items: items?.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
overflow: TextOverflow.ellipsis,
),
);
}).toList(),
onChanged: (value) {
onChanged!(value.toString());
},
validator: validator,
),
);
}
_buildDecoration() {
return InputDecoration(
hintText: hintText ?? "",
hintStyle: _setFontStyle(),
border: _setBorderStyle(),
enabledBorder: _setBorderStyle(),
focusedBorder: _setBorderStyle(),
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
fillColor: _setFillColor(),
filled: _setFilled(),
isDense: true,
contentPadding: _setPadding(),
);
}
_setFontStyle() {
switch (fontStyle) {
case DropDownFontStyle.GilroyRegular16:
return TextStyle(
color: ColorConstant.blueGray200,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w400,
);
default:
return TextStyle(
color: ColorConstant.blueGray900,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w600,
);
}
}
_setOutlineBorderRadius() {
switch (shape) {
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
_setBorderStyle() {
switch (variant) {
case DropDownVariant.None:
return InputBorder.none;
default:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray100,
width: 1,
),
);
}
}
_setFillColor() {
switch (variant) {
default:
return ColorConstant.whiteA700;
}
}
_setFilled() {
switch (variant) {
case DropDownVariant.None:
return false;
default:
return true;
}
}
_setPadding() {
switch (padding) {
default:
return getPadding(
left: 10,
top: 10,
bottom: 10,
);
}
}
}
enum DropDownShape {
RoundedBorder6,
}
enum DropDownPadding {
PaddingT10,
}
enum DropDownVariant {
None,
OutlineBluegray100,
}
enum DropDownFontStyle {
GilroySemiBold16,
GilroyRegular16,
}
+162
View File
@@ -0,0 +1,162 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../Utils/color_constants.dart';
import '../Utils/size_utils.dart';
import 'custom_text_form_field.dart';
class CustomDropdownFormField extends StatelessWidget {
CustomDropdownFormField({
this.shape,
this.padding,
this.initialValue,
this.variant,
this.fontStyle,
this.alignment,
this.width,
this.margin,
this.items,
this.value,
this.hintText,
this.onChanged,
this.validator,
this.onSaved,
});
TextFormFieldShape? shape;
TextFormFieldPadding? padding;
String? initialValue;
TextFormFieldVariant? variant;
TextFormFieldFontStyle? fontStyle;
Alignment? alignment;
double? width;
EdgeInsetsGeometry? margin;
List<DropdownMenuItem<String>>? items;
String? value;
String? hintText;
void Function(String?)? onChanged;
FormFieldValidator<String>? validator;
void Function(String?)? onSaved;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildDropdownFormFieldWidget(),
)
: _buildDropdownFormFieldWidget();
}
_buildDropdownFormFieldWidget() {
return Container(
width: width ?? double.maxFinite,
margin: margin,
child: DropdownButtonFormField<String>(
value: value,
items: items,
onChanged: onChanged,
validator: validator,
onSaved: onSaved,
decoration: _buildDecoration(),
),
);
}
_buildDecoration() {
return InputDecoration(
hintText: hintText ?? "",
hintStyle: _setFontStyle(),
border: _setBorderStyle(),
enabledBorder: _setBorderStyle(),
focusedBorder: _setBorderStyle(),
fillColor: _setFillColor(),
filled: _setFilled(),
isDense: true,
contentPadding: _setPadding(),
);
}
_setFontStyle() {
switch (fontStyle) {
// Add cases for different font styles if needed
default:
return TextStyle(
color: ColorConstant.blueGray200,
fontSize: getFontSize(16),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
}
}
_setOutlineBorderRadius() {
switch (shape) {
case TextFormFieldShape.CircleBorder16:
return BorderRadius.circular(getHorizontalSize(16.00));
default:
return BorderRadius.circular(getHorizontalSize(6.00));
}
}
_setBorderStyle() {
switch (variant) {
case TextFormFieldVariant.FillBlue50:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide.none,
);
// Add cases for different variants if needed
default:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray100,
width: 1,
),
);
}
}
_setFillColor() {
switch (variant) {
case TextFormFieldVariant.FillBlue50:
return ColorConstant.blue50;
// Add cases for different variants if needed
default:
return ColorConstant.whiteA700;
}
}
_setFilled() {
switch (variant) {
case TextFormFieldVariant.FillBlue50:
return true;
// Add cases for different variants if needed
default:
return true;
}
}
_setPadding() {
switch (padding) {
case TextFormFieldPadding.PaddingAll11:
return getPadding(all: 11);
// Add cases for different paddings if needed
default:
return getPadding(all: 11);
}
}
}
+92
View File
@@ -0,0 +1,92 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import '../Utils/color_constants.dart';
import '../Utils/size_utils.dart';
class CustomFloatingButton extends StatelessWidget {
CustomFloatingButton(
{this.shape,
this.variant,
this.alignment,
this.margin,
this.onTap,
this.width,
this.height,
this.child});
FloatingButtonShape? shape;
FloatingButtonVariant? variant;
Alignment? alignment;
EdgeInsetsGeometry? margin;
VoidCallback? onTap;
double? width;
double? height;
Widget? child;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildFabWidget(),
)
: _buildFabWidget();
}
_buildFabWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: FloatingActionButton(
backgroundColor: _setColor(),
onPressed: onTap,
child: Container(
alignment: Alignment.center,
width: getSize(width ?? 0),
height: getSize(height ?? 0),
decoration: _buildDecoration(),
child: child,
),
),
);
}
_buildDecoration() {
return BoxDecoration(
color: _setColor(),
borderRadius: _setBorderRadius(),
);
}
_setColor() {
switch (variant) {
default:
return ColorConstant.blueA700;
}
}
_setBorderRadius() {
switch (shape) {
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
}
enum FloatingButtonShape {
RoundedBorder6,
}
enum FloatingButtonVariant {
FillBlueA700,
}
+260
View File
@@ -0,0 +1,260 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import '../Utils/color_constants.dart';
import '../Utils/size_utils.dart';
class CustomIconButton extends StatelessWidget {
CustomIconButton(
{this.shape,
this.padding,
this.variant,
this.alignment,
this.margin,
this.width,
this.height,
this.child,
this.onTap});
IconButtonShape? shape;
IconButtonPadding? padding;
IconButtonVariant? variant;
Alignment? alignment;
EdgeInsetsGeometry? margin;
double? width;
double? height;
Widget? child;
VoidCallback? onTap;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildIconButtonWidget(),
)
: _buildIconButtonWidget();
}
_buildIconButtonWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: IconButton(
visualDensity: VisualDensity(
vertical: -4,
horizontal: -4,
),
iconSize: getSize(height ?? 0),
padding: EdgeInsets.all(0),
icon: Container(
alignment: Alignment.center,
width: getSize(width ?? 0),
height: getSize(height ?? 0),
padding: _setPadding(),
decoration: _buildDecoration(),
child: child,
),
onPressed: onTap,
),
);
}
_buildDecoration() {
return BoxDecoration(
color: _setColor(),
border: _setBorder(),
borderRadius: _setBorderRadius(),
boxShadow: _setBoxShadow(),
);
}
_setPadding() {
switch (padding) {
case IconButtonPadding.PaddingAll4:
return getPadding(
all: 4,
);
case IconButtonPadding.PaddingAll16:
return getPadding(
all: 16,
);
case IconButtonPadding.PaddingAll8:
return getPadding(
all: 8,
);
default:
return getPadding(
all: 11,
);
}
}
_setColor() {
switch (variant) {
case IconButtonVariant.FillBlueA700:
return ColorConstant.blueA700;
case IconButtonVariant.OutlineGray80049:
return ColorConstant.whiteA700;
case IconButtonVariant.FillGray300:
return ColorConstant.gray300;
case IconButtonVariant.FillGray100:
return ColorConstant.gray100;
case IconButtonVariant.FillBlack90001:
return ColorConstant.black90001;
case IconButtonVariant.OutlineBluegray400:
return ColorConstant.whiteA700;
case IconButtonVariant.FillBlueA200:
return ColorConstant.blueA200;
case IconButtonVariant.OutlineBlueA700:
case IconButtonVariant.OutlineBlue50:
return null;
default:
return ColorConstant.blue50;
}
}
_setBorder() {
switch (variant) {
case IconButtonVariant.OutlineBlueA700:
return Border.all(
color: ColorConstant.blueA700,
width: getHorizontalSize(
1.00,
),
);
case IconButtonVariant.OutlineGray80049:
return Border.all(
color: ColorConstant.gray80049,
width: getHorizontalSize(
1.00,
),
);
case IconButtonVariant.OutlineBlue50:
return Border.all(
color: ColorConstant.blue50,
width: getHorizontalSize(
1.00,
),
);
case IconButtonVariant.OutlineBluegray400:
return Border.all(
color: ColorConstant.blueGray400,
width: getHorizontalSize(
1.00,
),
);
case IconButtonVariant.FillBlue50:
case IconButtonVariant.FillBlueA700:
case IconButtonVariant.FillGray300:
case IconButtonVariant.FillGray100:
case IconButtonVariant.FillBlack90001:
case IconButtonVariant.FillBlueA200:
return null;
default:
return null;
}
}
_setBorderRadius() {
switch (shape) {
case IconButtonShape.CircleBorder15:
return BorderRadius.circular(
getHorizontalSize(
15.00,
),
);
case IconButtonShape.RoundedBorder26:
return BorderRadius.circular(
getHorizontalSize(
26.00,
),
);
case IconButtonShape.CircleBorder10:
return BorderRadius.circular(
getHorizontalSize(
10.00,
),
);
case IconButtonShape.CircleBorder30:
return BorderRadius.circular(
getHorizontalSize(
30.00,
),
);
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
_setBoxShadow() {
switch (variant) {
case IconButtonVariant.OutlineBlueA700:
return [
BoxShadow(
color: ColorConstant.indigoA20033,
spreadRadius: getHorizontalSize(
2.00,
),
blurRadius: getHorizontalSize(
2.00,
),
offset: Offset(
0,
4,
),
),
];
case IconButtonVariant.FillBlue50:
case IconButtonVariant.FillBlueA700:
case IconButtonVariant.OutlineGray80049:
case IconButtonVariant.FillGray300:
case IconButtonVariant.FillGray100:
case IconButtonVariant.FillBlack90001:
case IconButtonVariant.OutlineBlue50:
case IconButtonVariant.OutlineBluegray400:
case IconButtonVariant.FillBlueA200:
return null;
default:
return null;
}
}
}
enum IconButtonShape {
RoundedBorder6,
CircleBorder15,
RoundedBorder26,
CircleBorder10,
CircleBorder30,
}
enum IconButtonPadding {
PaddingAll4,
PaddingAll16,
PaddingAll8,
PaddingAll11,
}
enum IconButtonVariant {
FillBlue50,
FillBlueA700,
OutlineBlueA700,
OutlineGray80049,
FillGray300,
FillGray100,
FillBlack90001,
OutlineBlue50,
OutlineBluegray400,
FillBlueA200,
}
+154
View File
@@ -0,0 +1,154 @@
// ignore_for_file: must_be_immutable
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CustomImageView extends StatelessWidget {
///[url] is required parameter for fetching network image
String? url;
///[imagePath] is required parameter for showing png,jpg,etc image
String? imagePath;
///[svgPath] is required parameter for showing svg image
String? svgPath;
///[file] is required parameter for fetching image file
File? file;
double? height;
double? width;
Color? color;
BoxFit? fit;
final String placeHolder;
Alignment? alignment;
VoidCallback? onTap;
EdgeInsetsGeometry? margin;
BorderRadius? radius;
BoxBorder? border;
///a [CustomImageView] it can be used for showing any type of images
/// it will shows the placeholder image if image is not found on network image
CustomImageView({
Key? key,
this.url,
this.imagePath,
this.svgPath,
this.file,
this.height,
this.width,
this.color,
this.fit,
this.alignment,
this.onTap,
this.radius,
this.margin,
this.border,
this.placeHolder = 'assets/images/image_not_found.png',
}) : super(key: key);
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment!,
child: _buildWidget(),
)
: _buildWidget();
}
Widget _buildWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: InkWell(
onTap: onTap,
child: _buildCircleImage(),
),
);
}
///build the image with border radius
_buildCircleImage() {
if (radius != null) {
return ClipRRect(
borderRadius: radius ?? BorderRadius.zero,
child: _buildImageWithBorder(),
);
} else {
return _buildImageWithBorder();
}
}
///build the image with border and border radius style
_buildImageWithBorder() {
if (border != null) {
return Container(
decoration: BoxDecoration(
border: border,
borderRadius: radius,
),
child: _buildImageView(),
);
} else {
return _buildImageView();
}
}
Widget _buildImageView() {
if (svgPath != null && svgPath!.isNotEmpty) {
return SizedBox(
height: height,
width: width,
child: SvgPicture.asset(
svgPath!,
height: height,
width: width,
fit: fit ?? BoxFit.contain,
color: color,
),
);
} else if (file != null && file!.path.isNotEmpty) {
return Image.file(
file!,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
color: color,
);
} else if (url != null && url!.isNotEmpty) {
return CachedNetworkImage(
height: height,
width: width,
fit: fit,
imageUrl: url!,
color: color,
placeholder: (context, url) => SizedBox(
height: 30,
width: 30,
child: LinearProgressIndicator(
color: Colors.grey.shade200,
backgroundColor: Colors.grey.shade100,
),
),
errorWidget: (context, url, error) => Image.asset(
placeHolder,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
),
);
} else if (imagePath != null && imagePath!.isNotEmpty) {
return Image.asset(
imagePath!,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
color: color,
);
}
return const SizedBox();
}
}
+260
View File
@@ -0,0 +1,260 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import '../Utils/color_constants.dart';
import '../Utils/size_utils.dart';
class CustomRadioButton extends StatelessWidget {
CustomRadioButton(
{this.shape,
this.padding,
this.variant,
this.fontStyle,
this.alignment,
this.onChange,
this.isRightCheck = false,
this.iconSize,
this.value,
this.groupValue,
this.text,
this.width,
this.margin});
RadioShape? shape;
RadioPadding? padding;
RadioVariant? variant;
RadioFontStyle? fontStyle;
Alignment? alignment;
Function(String)? onChange;
bool? isRightCheck;
double? iconSize;
String? value;
String? groupValue;
String? text;
double? width;
EdgeInsetsGeometry? margin;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildRadioButtonWidget(),
)
: _buildRadioButtonWidget();
}
_buildRadioButtonWidget() {
return InkWell(
onTap: () {
onChange!(value!);
},
child: Container(
width: width,
margin: margin ?? EdgeInsets.zero,
padding: _setPadding(),
decoration: _buildDecoration(),
child: isRightCheck! ? getRightSideRadio() : getLeftSideRadio(),
),
);
}
_buildDecoration() {
return BoxDecoration(
color: _setColor(),
border: _setBorder(),
borderRadius: _setBorderRadius(),
);
}
Widget getRightSideRadio() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: EdgeInsets.only(
right: 8,
),
child: getTextWidget(),
),
getRadioWidget(),
],
);
}
Widget getLeftSideRadio() {
return Row(
children: [
getRadioWidget(),
Padding(
padding: EdgeInsets.only(
left: 8,
),
child: getTextWidget(),
),
],
);
}
Widget getTextWidget() {
return Text(
text ?? "",
textAlign: TextAlign.center,
style: _setFontStyle(),
);
}
Widget getRadioWidget() {
return SizedBox(
height: iconSize,
width: iconSize,
child: Radio<String>(
value: value ?? "",
groupValue: groupValue,
activeColor: ColorConstant.whiteA700,
onChanged: (value) {
onChange!(value!);
},
visualDensity: VisualDensity(
vertical: -4,
horizontal: -4,
),
),
);
}
_setFontStyle() {
switch (fontStyle) {
case RadioFontStyle.GilroyMedium16:
return TextStyle(
color: ColorConstant.blueA700,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case RadioFontStyle.GilroyMedium18:
return TextStyle(
color: ColorConstant.blueGray300,
fontSize: getFontSize(
18,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case RadioFontStyle.GilroyRegular16:
return TextStyle(
color: ColorConstant.blueGray900,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w400,
);
default:
return TextStyle(
color: ColorConstant.blueGray400,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
}
}
_setPadding() {
switch (padding) {
case RadioPadding.PaddingAll11:
return getPadding(
all: 11,
);
case RadioPadding.PaddingT1:
return getPadding(
top: 1,
bottom: 1,
);
default:
return null;
}
}
_setColor() {
switch (variant) {
case RadioVariant.OutlineBluegray400:
return ColorConstant.whiteA700;
case RadioVariant.OutlineBlueA700:
return ColorConstant.whiteA700;
default:
return null;
}
}
_setBorder() {
switch (variant) {
case RadioVariant.OutlineBluegray400:
return Border.all(
color: ColorConstant.blueGray400,
width: getHorizontalSize(
1.00,
),
);
case RadioVariant.OutlineBlueA700:
return Border.all(
color: ColorConstant.blueA700,
width: getHorizontalSize(
1.00,
),
);
default:
return null;
}
}
_setBorderRadius() {
switch (shape) {
case RadioShape.RoundedBorder6:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
default:
return null;
}
}
}
enum RadioShape {
RoundedBorder6,
}
enum RadioPadding {
PaddingAll11,
PaddingT1,
}
enum RadioVariant {
OutlineBluegray400,
OutlineBlueA700,
}
enum RadioFontStyle {
GilroyMedium16Bluegray400,
GilroyMedium16,
GilroyMedium18,
GilroyRegular16,
}
+203
View File
@@ -0,0 +1,203 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import '../Utils/color_constants.dart';
import '../Utils/size_utils.dart';
class CustomSearchView extends StatelessWidget {
CustomSearchView(
{this.shape,
this.padding,
this.variant,
this.fontStyle,
this.alignment,
this.width,
this.margin,
this.controller,
this.focusNode,
this.hintText,
this.prefix,
this.prefixConstraints,
this.suffix,
this.suffixConstraints});
SearchViewShape? shape;
SearchViewPadding? padding;
SearchViewVariant? variant;
SearchViewFontStyle? fontStyle;
Alignment? alignment;
double? width;
EdgeInsetsGeometry? margin;
TextEditingController? controller;
FocusNode? focusNode;
String? hintText;
Widget? prefix;
BoxConstraints? prefixConstraints;
Widget? suffix;
BoxConstraints? suffixConstraints;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildSearchViewWidget(),
)
: _buildSearchViewWidget();
}
_buildSearchViewWidget() {
return Container(
width: width ?? double.maxFinite,
margin: margin,
child: TextFormField(
controller: controller,
focusNode: focusNode,
style: _setFontStyle(),
decoration: _buildDecoration(),
),
);
}
_buildDecoration() {
return InputDecoration(
hintText: hintText ?? "",
hintStyle: _setFontStyle(),
border: _setBorderStyle(),
enabledBorder: _setBorderStyle(),
focusedBorder: _setBorderStyle(),
disabledBorder: _setBorderStyle(),
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
suffixIconConstraints: suffixConstraints,
fillColor: _setFillColor(),
filled: _setFilled(),
isDense: true,
contentPadding: _setPadding(),
);
}
_setFontStyle() {
switch (fontStyle) {
case SearchViewFontStyle.GilroyMedium16Bluegray400:
return TextStyle(
color: ColorConstant.blueGray400,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
default:
return TextStyle(
color: ColorConstant.blueGray200,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
}
}
_setOutlineBorderRadius() {
switch (shape) {
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
_setBorderStyle() {
switch (variant) {
case SearchViewVariant.OutlineBluegray200:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray200,
width: 1,
),
);
case SearchViewVariant.None:
return InputBorder.none;
default:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray100,
width: 1,
),
);
}
}
_setFillColor() {
switch (variant) {
case SearchViewVariant.OutlineBluegray200:
return ColorConstant.whiteA700;
default:
return ColorConstant.whiteA700;
}
}
_setFilled() {
switch (variant) {
case SearchViewVariant.None:
return false;
default:
return true;
}
}
_setPadding() {
switch (padding) {
case SearchViewPadding.PaddingT11:
return getPadding(
top: 11,
right: 11,
bottom: 11,
);
default:
return getPadding(
top: 12,
bottom: 12,
);
}
}
}
enum SearchViewShape {
RoundedBorder6,
}
enum SearchViewPadding {
PaddingT11,
PaddingT12,
}
enum SearchViewVariant {
None,
OutlineBluegray100,
OutlineBluegray200,
}
enum SearchViewFontStyle {
GilroyMedium16,
GilroyMedium16Bluegray400,
}
+49
View File
@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:flutter_switch/flutter_switch.dart';
import '../Utils/color_constants.dart';
import '../Utils/size_utils.dart';
class CustomSwitch extends StatelessWidget {
CustomSwitch({this.alignment, this.margin, this.value, this.onChanged});
Alignment? alignment;
EdgeInsetsGeometry? margin;
bool? value;
Function(bool)? onChanged;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildSwitchWidget(),
)
: _buildSwitchWidget();
}
_buildSwitchWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: FlutterSwitch(
value: value ?? false,
height: getHorizontalSize(25),
width: getHorizontalSize(45),
toggleSize: 25,
borderRadius: getHorizontalSize(
12.00,
),
activeColor: ColorConstant.blueA700,
activeToggleColor: ColorConstant.gray50,
inactiveColor: ColorConstant.blueGray50,
inactiveToggleColor: ColorConstant.gray50,
onToggle: (value) {
onChanged!(value);
},
),
);
}
}
+220
View File
@@ -0,0 +1,220 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../Utils/color_constants.dart';
import '../Utils/image_constant.dart';
import '../Utils/size_utils.dart';
class CustomTextFormField extends StatelessWidget {
TextFormFieldShape? shape;
TextFormFieldPadding? padding;
void Function(String?)? onsaved;
void Function(String)? onChanged;
void Function()? onTap;
String? initialValue;
bool? readOnly;
List<TextInputFormatter>? inputFormatters;
TextFormFieldVariant? variant;
TextFormFieldFontStyle? fontStyle;
Alignment? alignment;
double? width;
EdgeInsetsGeometry? margin;
TextEditingController? controller;
FocusNode? focusNode;
String? errorText;
bool? isObscureText;
TextInputAction? textInputAction;
TextInputType? textInputType;
int? maxLines;
int? maxLength; // Added this line
String? hintText;
Widget? prefix;
BoxConstraints? prefixConstraints;
Widget? suffix;
BoxConstraints? suffixConstraints;
FormFieldValidator<String>? validator;
TextInputType? keyboardType; // Add this line
CustomTextFormField({
this.shape,
this.padding,
this.initialValue,
this.variant,
this.fontStyle,
this.readOnly,
this.alignment,
this.onChanged,
this.onTap,
this.width,
this.margin,
this.controller,
this.inputFormatters,
this.focusNode,
this.isObscureText = false,
this.textInputAction = TextInputAction.next,
this.textInputType,
this.maxLines,
this.maxLength, // Added this line
this.hintText,
this.prefix,
this.errorText,
this.onsaved,
this.prefixConstraints,
this.suffix,
this.suffixConstraints,
this.validator,
this.keyboardType, // Add this line
});
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildTextFormFieldWidget(),
)
: _buildTextFormFieldWidget();
}
_buildTextFormFieldWidget() {
return Container(
width: width ?? double.maxFinite,
margin: margin,
child: TextFormField(
readOnly: readOnly ?? false,
onSaved: onsaved,
onChanged: onChanged,
controller: controller,
onTap: onTap,
focusNode: focusNode,
style: _setFontStyle(),
obscureText: isObscureText!,
textInputAction: textInputAction,
keyboardType: textInputType,
maxLines: maxLines ?? 1,
maxLength: maxLength, // Added this line
decoration: _buildDecoration(),
validator: validator,
initialValue: initialValue,
inputFormatters: inputFormatters,
),
);
}
_buildDecoration() {
return InputDecoration(
hintText: hintText ?? "",
hintStyle: _setFontStyle(),
border: _setBorderStyle(),
enabledBorder: _setBorderStyle(),
focusedBorder: _setBorderStyle(),
disabledBorder: _setBorderStyle(),
prefixIcon: prefix,
errorText: errorText,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
suffixIconConstraints: suffixConstraints,
fillColor: _setFillColor(),
filled: _setFilled(),
isDense: true,
contentPadding: _setPadding(),
);
}
_setFontStyle() {
switch (fontStyle) {
// Existing cases...
case TextFormFieldFontStyle.RobotoMedium18:
return TextStyle(
color: ColorConstant.whiteA700,
fontSize: getFontSize(18),
fontFamily: 'Roboto',
fontWeight: FontWeight.w500,
);
default:
return TextStyle(
color: ColorConstant.blueGray200,
fontSize: getFontSize(16),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
}
}
_setOutlineBorderRadius() {
switch (shape) {
// Existing cases...
default:
return BorderRadius.circular(getHorizontalSize(6.00));
}
}
_setBorderStyle() {
switch (variant) {
// Existing cases...
default:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray100,
width: 1,
),
);
}
}
_setFillColor() {
switch (variant) {
// Existing cases...
default:
return ColorConstant.whiteA700;
}
}
_setFilled() {
switch (variant) {
// Existing cases...
default:
return true;
}
}
_setPadding() {
switch (padding) {
// Existing cases...
default:
return getPadding(all: 11);
}
}
}
enum TextFormFieldShape {
RoundedBorder6,
CircleBorder16,
}
enum TextFormFieldPadding {
PaddingAll11,
PaddingT12,
PaddingT16,
PaddingT20,
PaddingAll8,
PaddingT6,
PaddingT25,
}
enum TextFormFieldVariant {
None,
OutlineBluegray100,
FillBlue50,
OutlineBluegray400,
OutlineBlack9003f,
FillBlueA200,
}
enum TextFormFieldFontStyle {
GilroyMedium16,
GilroyMedium16BlueA700,
GilroyMedium16Bluegray400,
GilroySemiBold14,
RobotoMedium18,
}