test base project
This commit is contained in:
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
@@ -0,0 +1 @@
|
||||
class test {}
|
||||
@@ -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;
|
||||
// }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
}
|
||||
@@ -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 mustn’t.
|
||||
// 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,
|
||||
),
|
||||
);
|
||||
}
|
||||
BIN
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class ApiConstants {
|
||||
static const baseUrl = 'http://localhost:9292';
|
||||
}
|
||||
Vendored
BIN
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
BIN
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(),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
Vendored
BIN
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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
BIN
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),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
Vendored
BIN
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();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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(
|
||||
"Didn’t 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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];
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -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';
|
||||
// }
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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 }
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
Reference in New Issue
Block a user