Adding base project of flutter-hybrid

This commit is contained in:
Azmat-7860
2026-09-12 11:22:07 +05:30
commit 45850796dc
471 changed files with 27188 additions and 0 deletions
BIN
View File
Binary file not shown.
@@ -0,0 +1,106 @@
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
import 'dart:typed_data';
import 'dart:convert';
import '../../resources/api_constants.dart';
import '../LogoutService/Logoutservice.dart';
class ApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
Future<List<Map<String, dynamic>>> getEntities(String token) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/Bookmarks/Bookmarks');
if (response.statusCode == 401) {
LogoutService.logout();
}
final entities = (response.data as List).cast<Map<String, dynamic>>();
return entities;
} catch (e) {
throw Exception('Failed to get all entities: $e');
}
}
Future<void> createEntity(
String token, Map<String, dynamic> fData, dynamic selectedFile) async {
try {
String apiUrl = "$baseUrl/Bookmarks/Bookmarks";
final Uint8List fileBytes = selectedFile.bytes!;
final mimeType = lookupMimeType(selectedFile.name!);
FormData formData = FormData.fromMap({
'file': MultipartFile.fromBytes(
fileBytes,
filename: selectedFile.name!,
contentType: MediaType.parse(mimeType!),
),
'data': jsonEncode(
fData), // Convert the map to JSON and include it as a parameter
});
Dio dio = Dio(); // Create a new Dio instance
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.post(apiUrl, data: formData);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode == 200) {
// Handle successful response
print('File uploaded successfully');
} else {
print('Failed to upload file with status: ${response.statusCode}');
}
} catch (error) {
print('Error occurred during form submission: $error');
}
}
String lookupMimeType(String filePath) {
final ext = filePath.split('.').last;
switch (ext) {
case 'jpg':
case 'jpeg':
return 'image/jpeg';
case 'png':
return 'image/png';
case 'pdf':
return 'application/pdf';
// Add more cases for other file types as needed
default:
return 'application/octet-stream'; // Default MIME type
}
}
Future<void> updateEntity(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response =
await dio.put('$baseUrl/Bookmarks/Bookmarks/$entityId', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to update entity: $e');
}
}
Future<void> deleteEntity(String token, int entityId) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio.delete('$baseUrl/Bookmarks/Bookmarks/$entityId');
if (response.statusCode == 401) {
LogoutService.logout();
}
} catch (e) {
throw Exception('Failed to delete entity: $e');
}
}
}
@@ -0,0 +1,111 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../providers/token_manager.dart';
import 'Bookmarks_api_service.dart';
class CreateEntityScreen extends StatefulWidget {
const CreateEntityScreen({super.key});
@override
_CreateEntityScreenState createState() => _CreateEntityScreenState();
}
class _CreateEntityScreenState extends State<CreateEntityScreen> {
final ApiService apiService = ApiService();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
var selectedFileupload_Field;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Create Bookmarks')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration:
const InputDecoration(labelText: 'bookmark_firstletter'),
onSaved: (value) => formData['bookmark_firstletter'] = value,
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'bookmark_link'),
onSaved: (value) => formData['bookmark_link'] = value,
),
const SizedBox(height: 16),
TextFormField(
decoration:
const InputDecoration(labelText: 'fileupload_field'),
onSaved: (value) => formData['fileupload_field'] = value,
),
const SizedBox(height: 16),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
final token = await TokenManager.getToken();
try {
print("token is : $token");
print(formData);
await apiService.createEntity(
token!, formData, selectedFileupload_Field);
Navigator.pop(context);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to create entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
},
child: Container(
width: double.infinity,
height: 50,
child: const Center(
child: Text(
'SUBMIT',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
],
),
),
),
),
);
}
}
@@ -0,0 +1,562 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_decoration.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import 'Bookmarks_api_service.dart';
import 'package:url_launcher/url_launcher.dart';
class bookmarks_entity_list_screen extends StatefulWidget {
static const String routeName = '/entity-list';
@override
_bookmarks_entity_list_screenState createState() =>
_bookmarks_entity_list_screenState();
}
class _bookmarks_entity_list_screenState
extends State<bookmarks_entity_list_screen> {
final ApiService apiService = ApiService();
List<Map<String, dynamic>> entities = [];
bool showCardView = true; // Add this variable to control the view mode
@override
void initState() {
super.initState();
fetchEntities();
}
Future<void> fetchEntities() async {
try {
final token = await TokenManager.getToken();
if (token != null) {
final fetchedEntities = await apiService.getEntities(token);
setState(() {
entities = fetchedEntities;
});
}
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to fetch entities: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
Future<void> deleteEntity(Map<String, dynamic> entity) async {
try {
final token = await TokenManager.getToken();
await apiService.deleteEntity(token!, entity['id']);
setState(() {
entities.remove(entity);
});
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to delete entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Bookmarks")),
body: entities.isEmpty
? const Center(
child: Text('No BookMarks found.'),
)
: Container(
width: double.maxFinite,
padding: getPadding(left: 16, top: 16, right: 16, bottom: 16),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: getPadding(top: 22),
child: entities.length != 0
? ListView.separated(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
separatorBuilder: (context, index) {
return SizedBox(height: getVerticalSize(24));
},
itemCount: entities.length,
itemBuilder: (context, index) {
Map<String, dynamic> entity = entities[index];
return Container(
width: double.maxFinite,
child: Container(
padding: getPadding(
left: 16,
top: 5,
right: 5,
bottom: 17,
),
decoration: AppDecoration.outlineGray70011
.copyWith(
borderRadius: BorderRadiusStyle
.roundedBorder6,
color: Colors.grey[100]),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Padding(
padding: getPadding(
//right: 13,
),
child: Row(
children: [
Container(
width: MediaQuery.of(context)
.size
.width *
0.30,
// getHorizontalSize(
// 147,
// ),
margin: getMargin(
left: 8,
top: 3,
bottom: 1,
),
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
entity['bookmark_firstletter'] ??
'No bookmark_firstletter provided',
overflow: TextOverflow
.ellipsis,
textAlign:
TextAlign.left,
style: AppStyle
.txtGreenSemiBold16,
),
],
),
),
Spacer(),
// PopupMenuButton<String>(
// icon: Icon(Icons.more_vert,color: Colors.black,size: 16,),
// itemBuilder: (BuildContext context) {
// return [
// PopupMenuItem<String>(
// value: 'edit',
// child: Row(
// children: [
// Icon(
// Icons.edit,
// size: 16, // Adjust the icon size as needed
// ),
// SizedBox(width: 8),
// Text(
// 'Edit',
// style: AppStyle.txtGilroySemiBold16, // Adjust the text size as needed
// ),
// ],
// ),
// ),
// PopupMenuItem<String>(
// value: 'delete',
// child: Row(
// children: [
// Icon(
// Icons.delete,
// size: 16, // Adjust the icon size as needed
// ),
// SizedBox(width: 8),
// Text(
// 'Delete',
// style: AppStyle.txtGilroySemiBold16, // Adjust the text size as needed
// ),
// ],
// ),
// ),
// ];
// },
// onSelected: (String value) {
// if (value == 'edit') {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => UpdateDatabseScreen(
// projectId: widget.projectId,
// entity: entity,
// ),
// ),
// ).then((_) {
// fetchEntities();
// });
// } else if (value == 'delete') {
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return AlertDialog(
// title: const Text('Confirm Deletion'),
// content: const Text('Are you sure you want to delete?'),
// actions: [
// TextButton(
// child: const Text('Cancel'),
// onPressed: () {
// Navigator.of(context).pop();
// },
// ),
// TextButton(
// child: const Text('Delete'),
// onPressed: () {
// Navigator.of(context).pop();
// deleteEntity(entity, context).then((value) => {
// fetchEntities()
// });
// },
// ),
// ],
// );
// },
// );
// }
// },
// ),
],
),
),
Padding(
padding: getPadding(
top: 10,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
'BookMark Link',
overflow:
TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800,
),
GestureDetector(
onTap: () {
_launchURL(entity[
'bookmark_link']);
},
child: Text(
entity['bookmark_link'] ??
'No bookmark_link provided',
overflow:
TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Green600,
),
)
],
),
),
],
),
),
);
})
: Container(
height: MediaQuery.of(context).size.height,
child: const Center(
child: Text("No Databases available"),
)),
)
]))
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => const CreateEntityScreen(),
// ),
// ).then((_) {
// fetchEntities();
// });
// },
// child: const Icon(Icons.add),
// ),
);
}
// Function to build list items
Widget _buildListItem(Map<String, dynamic> entity) {
return showCardView ? _buildCardView(entity) : _buildNormalView(entity);
}
// Function to build card view for a list item
Widget _buildCardView(Map<String, dynamic> entity) {
return Card(
elevation: 2,
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: _buildNormalView(entity));
}
// Function to build normal view for a list item
// Widget _buildNormalView(Map<String, dynamic> entity) {
// return ListTile(
// title: Text(entity['id'].toString()),
// subtitle: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
//
// Text(entity['bookmark_firstletter'] ?? 'No bookmark_firstletter provided'),
// const SizedBox(height: 4),
// Text(entity['bookmark_link'] ?? 'No bookmark_link provided'),
// const SizedBox(height: 4),
// Text(entity['fileupload_field'] ?? 'No fileupload_field provided'),
// const SizedBox(height: 4), // Added address text
// ],
//
// ),
// trailing: _buildPopupMenu(entity),
// onTap: () {
// _showAdditionalFieldsDialog(context, entity);
// },
// );
// }
Widget _buildNormalView(Map<String, dynamic> entity) {
return ListTile(
title: Text(entity['id'].toString()),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(entity['bookmark_firstletter'] ??
'No bookmark_firstletter provided'),
const SizedBox(height: 4),
GestureDetector(
onTap: () {
_launchURL(entity['bookmark_link']);
},
child: Text(
entity['bookmark_link'] ?? 'No bookmark_link provided',
style: TextStyle(
color:
Colors.blue, // Change the color to make it look like a link
decoration: TextDecoration.underline, // Underline the link
),
),
),
const SizedBox(height: 4),
Text(entity['fileupload_field'] ?? 'No fileupload_field provided'),
const SizedBox(height: 4),
// Added address text
],
),
// trailing: _buildPopupMenu(entity),
// onTap: () {
// _showAdditionalFieldsDialog(context, entity);
// },
);
}
// Function to launch a URL in the browser
Future<void> _launchURL(String? url) async {
if (url != null) {
try {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to launch URL: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}
// // Function to build popup menu for a list item
// Widget _buildPopupMenu(Map<String, dynamic> entity) {
// return PopupMenuButton<String>(
// itemBuilder: (BuildContext context) {
// return [
// const PopupMenuItem<String>(
// value: 'edit',
// child: Row(
// children: [
// Icon(Icons.edit),
// SizedBox(width: 8),
// Text('Edit'),
// ],
// ),
// ),
// const PopupMenuItem<String>(
// value: 'delete',
// child: Row(
// children: [
// Icon(Icons.delete),
// SizedBox(width: 8),
// Text('Delete'),
// ],
// ),
// ),
// ];
// },
// onSelected: (String value) {
// if (value == 'edit') {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => UpdateEntityScreen(entity: entity),
// ),
// ).then((_) {
// fetchEntities();
// });
// } else if (value == 'delete') {
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return AlertDialog(
// title: const Text('Confirm Deletion'),
// content:
// const Text('Are you sure you want to delete this entity?'),
// actions: [
// TextButton(
// child: const Text('Cancel'),
// onPressed: () {
// Navigator.of(context).pop();
// },
// ),
// TextButton(
// child: const Text('Delete'),
// onPressed: () {
// Navigator.of(context).pop();
// deleteEntity(entity);
// },
// ),
// ],
// );
// },
// );
// }
// },
// );
// }
// Function to show additional fields in a dialog
void _showAdditionalFieldsDialog(
BuildContext context,
Map<String, dynamic> entity,
) {
final dateFormat =
DateFormat('yyyy-MM-dd HH:mm:ss'); // Define your desired date format
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Additional Fields'),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Created At: ${_formatTimestamp(entity['createdAt'], dateFormat)}'),
Text('Created By: ${entity['createdBy'] ?? 'N/A'}'),
Text('Updated By: ${entity['updatedBy'] ?? 'N/A'}'),
Text(
'Updated At: ${_formatTimestamp(entity['updatedAt'], dateFormat)}'),
Text('Account ID: ${entity['accountId'] ?? 'N/A'}'),
],
),
actions: [
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
String _formatTimestamp(dynamic timestamp, DateFormat dateFormat) {
if (timestamp is int) {
// If it's an integer, assume it's a Unix timestamp in milliseconds
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
return dateFormat.format(dateTime);
} else if (timestamp is String) {
// If it's a string, assume it's already formatted as a date
return timestamp;
} else {
// Handle other cases here if needed
return 'N/A';
}
}
}
@@ -0,0 +1,140 @@
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter/services.dart';
import '../../providers/token_manager.dart';
import 'Bookmarks_api_service.dart';
class UpdateEntityScreen extends StatefulWidget {
final Map<String, dynamic> entity;
UpdateEntityScreen({required this.entity});
@override
_UpdateEntityScreenState createState() => _UpdateEntityScreenState();
}
class _UpdateEntityScreenState extends State<UpdateEntityScreen> {
final ApiService apiService = ApiService();
final _formKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Update Bookmarks')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
initialValue: widget.entity['bookmark_firstletter'],
decoration:
const InputDecoration(labelText: 'bookmark_firstletter'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a bookmark_firstletter';
}
return null;
},
onSaved: (value) {
widget.entity['bookmark_firstletter'] = value;
},
),
const SizedBox(height: 16),
TextFormField(
initialValue: widget.entity['bookmark_link'],
decoration: const InputDecoration(labelText: 'bookmark_link'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a bookmark_link';
}
return null;
},
onSaved: (value) {
widget.entity['bookmark_link'] = value;
},
),
const SizedBox(height: 16),
TextFormField(
initialValue: widget.entity['fileupload_field'],
decoration:
const InputDecoration(labelText: 'fileupload_field'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a fileupload_field';
}
return null;
},
onSaved: (value) {
widget.entity['fileupload_field'] = value;
},
),
const SizedBox(height: 16),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
final token = await TokenManager.getToken();
try {
await apiService.updateEntity(
token!,
widget.entity[
'id'], // Assuming 'id' is the key in your entity map
widget.entity);
Navigator.pop(context);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to update entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
},
child: Container(
width: double.infinity,
height: 50,
child: const Center(
child: Text(
'UPDATE',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
],
),
),
),
),
);
}
}
Binary file not shown.
@@ -0,0 +1,293 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'dart:convert';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../LogoutService/Logoutservice.dart';
class RaisedTicketScreen extends StatefulWidget {
final Map<String, dynamic> userData;
const RaisedTicketScreen({Key? key, required this.userData})
: super(key: key);
@override
_RaisedTicketScreenState createState() => _RaisedTicketScreenState();
}
class _RaisedTicketScreenState extends State<RaisedTicketScreen> {
List<Map<String, dynamic>> tickets = [];
@override
void initState() {
super.initState();
fetchTickets();
}
Future<void> fetchTickets() async {
int userid = widget.userData['userId'];
String baseUrl = ApiConstants.baseUrl;
final token = await TokenManager.getToken();
String apiUrl = '$baseUrl/gettickets/$userid';
final response = await http.get(Uri.parse(apiUrl), headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
});
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body);
setState(() {
tickets = data.cast<Map<String, dynamic>>();
});
} else {
print('Failed to fetch data');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
actions: [
GestureDetector(
child: Icon(
Icons.add,
color: Colors.black,
size: 20,
),
onTap: () {
Navigator.of(context)
.push(
MaterialPageRoute(
builder: (context) => TicketFormScreen(
userData: widget.userData,
)),
)
.then((value) => {fetchTickets()});
},
),
const SizedBox(
width: 20,
)
],
centerTitle: true,
title: AppbarTitle(text: "Raised Tickets")),
body: ListView.builder(
itemCount: tickets.length,
itemBuilder: (context, index) {
final ticket = tickets[index];
return ListTile(
title: Text(
'Ticket ID: ${ticket['ticketid']}',
style: const TextStyle(fontSize: 12),
),
subtitle: Text('Ticket Name: ${ticket['ticketname']}',
style: const TextStyle(fontSize: 10)),
// Add more fields as needed
);
},
),
);
}
}
class TicketFormScreen extends StatefulWidget {
final Map<String, dynamic> userData;
const TicketFormScreen({Key? key, required this.userData}) : super(key: key);
@override
_TicketFormScreenState createState() => _TicketFormScreenState();
}
class _TicketFormScreenState extends State<TicketFormScreen> {
final TextEditingController titleController = TextEditingController();
final TextEditingController descriptionController = TextEditingController();
TextEditingController projectNameController = TextEditingController();
var screenshot;
Future<void> submitTicket(File file) async {
print(widget.userData);
String title = titleController.text;
String description = descriptionController.text;
String baseUrl = ApiConstants.baseUrl;
final token = await TokenManager.getToken();
String apiUrl = '$baseUrl/service_request/raise_ticket';
// Create a multipart request
var request = http.MultipartRequest('POST', Uri.parse(apiUrl));
request.headers['Authorization'] = 'Bearer $token';
// Add text fields to the request
request.fields['title'] = title;
request.fields['description'] = description;
request.fields['userid'] = widget.userData['userId'].toString();
request.fields['username'] = widget.userData['fullname'];
// Add file to the request
if (file != null) {
request.files.add(
await http.MultipartFile.fromPath('file', file.path),
);
}
try {
// Send the request
final response = await request.send();
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode == 200) {
Fluttertoast.showToast(
msg: 'Ticket submitted successfully',
backgroundColor: Colors.green,
);
print('Ticket submitted successfully');
Navigator.pop(context);
} else {
Fluttertoast.showToast(
msg: 'Failed to submit ticket.',
backgroundColor: Colors.red,
);
print('Failed to submit ticket. Status code: ${response.statusCode}');
}
} catch (e) {
// Handle exceptions
print('Error: $e');
}
}
Future<void> _pickImage() async {
final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
screenshot = File(pickedFile.path);
} else {
print('No image selected.');
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Raise a Ticket")),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Title",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Title",
controller: titleController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Description",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Description",
controller: descriptionController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Project Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Project Name",
controller: projectNameController,
margin: getMargin(top: 6))
])), // Adjusted the spacing
Row(
children: <Widget>[
Text('Pick Screenshot of issue'),
IconButton(
onPressed: () {
_pickImage(); // Call the function to pick an image
},
icon: Icon(Icons.file_copy),
),
SizedBox(width: 8.0),
// Display the selected screenshot file name
Text(screenshot != null ? screenshot.path.split('/').last : ''),
],
),
CustomButton(
height: getVerticalSize(50),
text: "Submit",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
submitTicket(screenshot);
},
),
],
),
),
);
}
}
@@ -0,0 +1,975 @@
import 'package:flutter/material.dart';
import 'dart:convert';
// class ReportEditor extends StatefulWidget {
// @override
// _ReportEditorState createState() => _ReportEditorState();
// }
//
// class _ReportEditorState extends State<ReportEditor> {
// List<Map<String, dynamic>> droppedFields = [];
// GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
// TextEditingController keyController = TextEditingController();
// TextEditingController valueController = TextEditingController();
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// key: _scaffoldKey,
// appBar: AppBar(title: Text('Report Editor')),
// body: Row(
// children: <Widget>[
// Container(
// width: 200,
// padding: EdgeInsets.all(10),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// Text('Drag and Drop Fields:'),
// Draggable<String>(
// data: 'Title',
// child: DragField(text: 'Title'),
// feedback: DragField(text: 'Title'),
// ),
// Draggable<String>(
// data: 'Phone Number',
// child: DragField(text: 'Phone Number'),
// feedback: DragField(text: 'Phone Number'),
// ),
// Draggable<String>(
// data: 'Date',
// child: DragField(text: 'Date'),
// feedback: DragField(text: 'Date'),
// ),
// ],
// ),
// ),
// Expanded(
// child: SingleChildScrollView(
// child: Container(
// color: Colors.white,
// child: Stack(
// children: [
// Container(
// margin: EdgeInsets.all(10),
// width: 793, // A4 width
// height: 1122, // A4 height
// decoration: BoxDecoration(
// border: Border.all(
// color: Colors.black,
// width: 1.0,
// ),
// ),
// ),
// Align(
// alignment: Alignment.bottomRight,
// child: Text('Scale Bar Report Editor'),
// ),
// ...droppedFields.asMap().entries.map((entry) {
// final index = entry.key;
// final field = entry.value;
// return DraggableField(
// key: Key(index.toString()),
// field: field,
// onDrag: (Offset position) {
// setState(() {
// droppedFields[index]['left'] = position.dx;
// droppedFields[index]['top'] = position.dy;
// });
// },
// onEdit: (String key, String value) {
// setState(() {
// droppedFields[index]['key'] = key;
// droppedFields[index]['value'] = value;
// });
// },
//
// );
// }).toList(),
// DraggableTarget(
// onAccept: (String field) {
// final RenderBox renderBox = context.findRenderObject() as RenderBox;
// final offset = renderBox.localToGlobal(Offset.zero);
// print(offset.dx);
// setState(() {
// droppedFields.add({
// 'type': field,
// 'left': offset.dx, // Set left coordinate
// 'top': offset.dy, // Set top coordinate
// 'key': field,
// 'value': '',
// 'isEditing': true, // Set the newly dropped field to be in edit mode
// });
// });
// },
// ),
//
// ],
// ),
// ),
// ),
// ),
// ],
// ),
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// _submitReport();
// },
// child: Icon(Icons.save),
// ),
// );
// }
//
// void _submitReport() {
// final reportJson = jsonEncode(droppedFields);
// print(reportJson);
//
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text('Report JSON created and printed!'),
// ),
// );
// }
// }
//
// class DragField extends StatelessWidget {
// final String text;
//
// DragField({required this.text});
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 120,
// padding: EdgeInsets.all(8),
// margin: EdgeInsets.symmetric(vertical: 5),
// decoration: BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.circular(5),
// ),
// child: Text(
// text,
// style: TextStyle(color: Colors.white),
// ),
// );
// }
// }
//
// class DraggableField extends StatefulWidget {
// final Map<String, dynamic> field;
// final Function(Offset) onDrag;
// final Function(String, String) onEdit;
//
// DraggableField({
// required Key key,
// required this.field,
// required this.onDrag,
// required this.onEdit,
// }) : super(key: key);
//
// @override
// _DraggableFieldState createState() => _DraggableFieldState();
// }
//
// class _DraggableFieldState extends State<DraggableField> {
// Offset position = Offset(0, 0);
//
// @override
// void initState() {
// super.initState();
// final left = widget.field['left'] as double;
// final top = widget.field['top'] as double;
// position = Offset(left, top);
// }
//
// @override
// Widget build(BuildContext context) {
// return Positioned(
// left: position.dx,
// top: position.dy,
// child: GestureDetector(
// onLongPress: () {
// widget.onEdit(widget.field['key'], widget.field['value']);
// setState(() {
// // Set the field to be in edit mode when long-pressed
// widget.field['isEditing'] = true;
// });
// },
// child: Draggable<String>(
// data: widget.field['type'],
// child: widget.field['isEditing']
// ? EditableField(
// key: widget.key as Key,
// keyText: widget.field['key'],
// valueText: widget.field['value'],
// onEdit: widget.onEdit,
// )
// : DragField(text: widget.field['type']),
// feedback: DragField(text: widget.field['type']),
// onDragEnd: (details) {
// setState(() {
// position = details.offset;
// widget.onDrag(details.offset);
// });
// },
// ),
// ),
// );
// }
// }
//
// class EditableField extends StatefulWidget {
// final String keyText;
// final String valueText;
// final Function(String, String) onEdit;
//
// EditableField({
// required Key key,
// required this.keyText,
// required this.valueText,
// required this.onEdit,
// }) : super(key: key);
//
// @override
// _EditableFieldState createState() => _EditableFieldState();
// }
//
// class _EditableFieldState extends State<EditableField> {
// TextEditingController keyController = TextEditingController();
// TextEditingController valueController = TextEditingController();
//
// @override
// void initState() {
// super.initState();
// keyController.text = widget.keyText;
// valueController.text = widget.valueText;
// }
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 120,
// padding: EdgeInsets.all(8),
// margin: EdgeInsets.symmetric(vertical: 5),
// decoration: BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.circular(5),
// ),
// child: Column(
// children: [
// TextFormField(
// controller: keyController,
// decoration: InputDecoration(labelText: 'Key'),
// onChanged: (value) {
// widget.onEdit(value, valueController.text);
// },
// ),
// TextFormField(
// controller: valueController,
// decoration: InputDecoration(labelText: 'Value'),
// onChanged: (value) {
// widget.onEdit(keyController.text, value);
// },
// ),
// ],
// ),
// );
// }
// }
//
// class DraggableTarget extends StatelessWidget {
// final Function(String) onAccept;
//
// DraggableTarget({required this.onAccept});
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 793,
// height: 1122,
// child: DragTarget<String>(
// builder: (context, candidateData, rejectedData) {
// return Center(
// child: Text('Drop Here', style: TextStyle(fontSize: 24)),
// );
// },
// onAccept: (String field) {
// onAccept(field);
// },
// ));
// }
// }
// import 'package:flutter/material.dart';
//
// class ReportEditor extends StatefulWidget {
// @override
// _ReportEditorState createState() => _ReportEditorState();
// }
//
// class _ReportEditorState extends State<ReportEditor> {
// List<Map<String, dynamic>> droppedFields = [];
// GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
// TextEditingController keyController = TextEditingController();
// TextEditingController valueController = TextEditingController();
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// key: _scaffoldKey,
// appBar: AppBar(title: Text('Report Editor')),
// body: Row(
// children: <Widget>[
// Container(
// width: 200,
// padding: EdgeInsets.all(10),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// Text('Drag and Drop Fields:'),
// Draggable<String>(
// data: 'Title',
// child: DragField(text: 'Title'),
// feedback: DragField(text: 'Title'),
// ),
// Draggable<String>(
// data: 'Phone Number',
// child: DragField(text: 'Phone Number'),
// feedback: DragField(text: 'Phone Number'),
// ),
// Draggable<String>(
// data: 'Date',
// child: DragField(text: 'Date'),
// feedback: DragField(text: 'Date'),
// ),
// ],
// ),
// ),
// Expanded(
// child: SingleChildScrollView(
// child: Container(
// color: Colors.white,
// child: Stack(
// children: [
// Container(
// margin: EdgeInsets.all(10),
// width: 793, // A4 width
// height: 1122, // A4 height
// decoration: BoxDecoration(
// border: Border.all(
// color: Colors.black,
// width: 1.0,
// ),
// ),
// ),
// Align(
// alignment: Alignment.bottomRight,
// child: Text('Scale Bar Report Editor'),
// ),
// ...droppedFields.asMap().entries.map((entry) {
// final index = entry.key;
// final field = entry.value;
// return DraggableField(
// key: Key(index.toString()),
// field: field,
// onDrag: (Offset position) {
// setState(() {
// droppedFields[index]['left'] = position.dx;
// droppedFields[index]['top'] = position.dy;
// });
// },
// onEdit: (String key, String value) {
// setState(() {
// droppedFields[index]['key'] = key;
// droppedFields[index]['value'] = value;
// });
// },
// onDelete: () {
// setState(() {
// droppedFields.removeAt(index);
// });
// },
// );
// }).toList(),
// DraggableTarget(
// onAccept: (String field) {
// final RenderBox renderBox = context.findRenderObject() as RenderBox;
// final offset = renderBox.localToGlobal(Offset.zero);
// setState(() {
// droppedFields.add({
// 'type': field,
// 'left': offset.dx, // Set left coordinate
// 'top': offset.dy, // Set top coordinate
// 'key': field,
// 'value': '',
// 'isEditing': true, // Set the newly dropped field to be in edit mode
// });
// });
// },
// ),
// ],
// ),
// ),
// ),
// ),
// ],
// ),
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// _submitReport();
// },
// child: Icon(Icons.save),
// ),
// );
// }
//
// void _submitReport() {
// final reportJson = jsonEncode(droppedFields);
// print(reportJson);
//
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text('Report JSON created and printed!'),
// ),
// );
// }
// }
//
//
// class DragField extends StatelessWidget {
// final String text;
//
// DragField({required this.text});
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 120,
// padding: EdgeInsets.all(8),
// margin: EdgeInsets.symmetric(vertical: 5),
// decoration: BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.circular(5),
// ),
// child: Text(
// text,
// style: TextStyle(color: Colors.white),
// ),
// );
// }
// }
//
// class DraggableField extends StatefulWidget {
// final Map<String, dynamic> field;
// final Function(Offset) onDrag;
// final Function(String, String) onEdit;
// final Function onDelete;
//
// DraggableField({
// required Key key,
// required this.field,
// required this.onDrag,
// required this.onEdit,
// required this.onDelete,
// }) : super(key: key);
//
// @override
// _DraggableFieldState createState() => _DraggableFieldState();
// }
//
// class _DraggableFieldState extends State<DraggableField> {
// Offset position = Offset(0, 0);
// bool isEditing = false;
//
// @override
// void initState() {
// super.initState();
// final left = widget.field['left'] as double;
// final top = widget.field['top'] as double;
// position = Offset(left, top);
// }
//
// @override
// Widget build(BuildContext context) {
// return Positioned(
// left: position.dx,
// top: position.dy,
// child: GestureDetector(
// onLongPress: () {
// widget.onEdit(widget.field['key'], widget.field['value']);
// setState(() {
// isEditing = true;
// });
// },
// child: Draggable<String>(
// data: widget.field['type'],
// child: isEditing
// ? EditableField(
// key: widget.key as Key,
// keyText: widget.field['key'],
// valueText: widget.field['value'],
// onEdit: widget.onEdit,
// )
// : Stack(
// children: [
// DragField(text: widget.field['type']),
// Positioned(
// top: -10,
// right: -10,
// child: IconButton(
// icon: Icon(Icons.delete),
// onPressed: () {
// widget.onDelete();
// },
// ),
// ),
// ],
// ),
// feedback: DragField(text: widget.field['type']),
// onDragEnd: (details) {
// setState(() {
// position = details.offset;
// widget.onDrag(details.offset);
// });
// },
// ),
// ),
// );
// }
// }
//
// class EditableField extends StatefulWidget {
// final String keyText;
// final String valueText;
// final Function(String, String) onEdit;
//
// EditableField({
// required Key key,
// required this.keyText,
// required this.valueText,
// required this.onEdit,
// }) : super(key: key);
//
// @override
// _EditableFieldState createState() => _EditableFieldState();
// }
//
// class _EditableFieldState extends State<EditableField> {
// TextEditingController keyController = TextEditingController();
// TextEditingController valueController = TextEditingController();
//
// @override
// void initState() {
// super.initState();
// keyController.text = widget.keyText;
// valueController.text = widget.valueText;
// }
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 120,
// padding: EdgeInsets.all(8),
// margin: EdgeInsets.symmetric(vertical: 5),
// decoration: BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.circular(5),
// ),
// child: Column(
// children: [
// TextFormField(
// controller: keyController,
// decoration: InputDecoration(labelText: 'Key'),
// onChanged: (value) {
// widget.onEdit(value, valueController.text);
// },
// ),
// TextFormField(
// controller: valueController,
// decoration: InputDecoration(labelText: 'Value'),
// onChanged: (value) {
// widget.onEdit(keyController.text, value);
// },
// ),
// ],
// ),
// );
// }
// }
//
// class DraggableTarget extends StatelessWidget {
// final Function(String) onAccept;
//
// DraggableTarget({required this.onAccept});
//
// @override
// Widget build(BuildContext context) {
// return Container(
// width: 793,
// height: 1122,
// child: DragTarget<String>(
// builder: (context, candidateData, rejectedData) {
// return Center(
// child: Text('Drop Here', style: TextStyle(fontSize: 24)),
// );
// },
// onAccept: (String field) {
// onAccept(field);
// },
// ),
// );
// }
// }
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pdfLib;
import 'dart:io';
import 'dart:typed_data';
class ReportEditor extends StatefulWidget {
@override
_ReportEditorState createState() => _ReportEditorState();
}
class _ReportEditorState extends State<ReportEditor> {
List<Map<String, dynamic>> droppedFields = [];
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
TextEditingController keyController = TextEditingController();
TextEditingController valueController = TextEditingController();
Future<Uint8List> generatePdf() async {
final pdf = pdfLib.Document();
for (final field in droppedFields) {
final left = field['left'] as double;
final top = field['top'] as double;
final type = field['type'];
final key = field['key'];
final value = field['value'];
final widget = pdfLib.Container(
child: pdfLib.Text('$type: $key - $value'),
decoration: const pdfLib.BoxDecoration(
border: pdfLib.Border(),
),
padding: pdfLib.EdgeInsets.all(5),
);
pdf.addPage(
pdfLib.Page(
build: (context) {
return pdfLib.Positioned(
left: left,
top: top,
child: widget,
);
},
),
);
}
return pdf.save();
}
Future<void> savePdf() async {
final pdfBytes = await generatePdf();
final dir = await getApplicationDocumentsDirectory();
final pdfFile = File('${dir.path}/report.pdf');
await pdfFile.writeAsBytes(pdfBytes);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('PDF saved to ${pdfFile.path}'),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(title: Text('Report Editor')),
body: Row(
children: <Widget>[
Container(
width: 200,
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Drag and Drop Fields:'),
Draggable<String>(
data: 'Title',
child: DragField(text: 'Title'),
feedback: DragField(text: 'Title'),
),
Draggable<String>(
data: 'Phone Number',
child: DragField(text: 'Phone Number'),
feedback: DragField(text: 'Phone Number'),
),
Draggable<String>(
data: 'Date',
child: DragField(text: 'Date'),
feedback: DragField(text: 'Date'),
),
],
),
),
Expanded(
child: SingleChildScrollView(
child: Container(
color: Colors.white,
child: Stack(
children: [
Container(
margin: EdgeInsets.all(10),
width: 793, // A4 width
height: 1122, // A4 height
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1.0,
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Text('Scale Bar Report Editor'),
),
...droppedFields.asMap().entries.map((entry) {
final index = entry.key;
final field = entry.value;
return DraggableField(
key: Key(index.toString()),
field: field,
onDrag: (Offset position) {
setState(() {
droppedFields[index]['left'] = position.dx;
droppedFields[index]['top'] = position.dy;
});
},
onEdit: (String key, String value) {
setState(() {
droppedFields[index]['key'] = key;
droppedFields[index]['value'] = value;
});
},
);
}).toList(),
DraggableTarget(
onAccept: (String field) {
final RenderBox renderBox =
context.findRenderObject() as RenderBox;
final offset = renderBox.localToGlobal(Offset.zero);
setState(() {
droppedFields.add({
'type': field,
'left': offset.dx,
'top': offset.dy,
'key': field,
'value': '',
'isEditing': true,
});
});
},
),
],
),
),
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: savePdf,
child: Icon(Icons.save),
),
);
}
}
class DragField extends StatelessWidget {
final String text;
DragField({required this.text});
@override
Widget build(BuildContext context) {
return Container(
width: 120,
padding: EdgeInsets.all(8),
margin: EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(5),
),
child: Text(
text,
style: TextStyle(color: Colors.white),
),
);
}
}
class DraggableField extends StatefulWidget {
final Map<String, dynamic> field;
final Function(Offset) onDrag;
final Function(String, String) onEdit;
DraggableField({
required Key key,
required this.field,
required this.onDrag,
required this.onEdit,
}) : super(key: key);
@override
_DraggableFieldState createState() => _DraggableFieldState();
}
class _DraggableFieldState extends State<DraggableField> {
Offset position = Offset(0, 0);
@override
void initState() {
super.initState();
final left = widget.field['left'] as double;
final top = widget.field['top'] as double;
position = Offset(left, top);
}
@override
Widget build(BuildContext context) {
return Positioned(
left: position.dx,
top: position.dy,
child: GestureDetector(
onLongPress: () {
widget.onEdit(widget.field['key'], widget.field['value']);
setState(() {
widget.field['isEditing'] = true;
});
},
child: Draggable<String>(
data: widget.field['type'],
child: widget.field['isEditing']
? EditableField(
key: widget.key as Key,
keyText: widget.field['key'],
valueText: widget.field['value'],
onEdit: widget.onEdit,
)
: DragField(text: widget.field['type']),
feedback: DragField(text: widget.field['type']),
onDragEnd: (details) {
setState(() {
position = details.offset;
widget.onDrag(details.offset);
});
},
),
),
);
}
}
class EditableField extends StatefulWidget {
final String keyText;
final String valueText;
final Function(String, String) onEdit;
EditableField({
required Key key,
required this.keyText,
required this.valueText,
required this.onEdit,
}) : super(key: key);
@override
_EditableFieldState createState() => _EditableFieldState();
}
class _EditableFieldState extends State<EditableField> {
TextEditingController keyController = TextEditingController();
TextEditingController valueController = TextEditingController();
@override
void initState() {
super.initState();
keyController.text = widget.keyText;
valueController.text = widget.valueText;
}
@override
Widget build(BuildContext context) {
return Container(
width: 120,
padding: EdgeInsets.all(8),
margin: EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(5),
),
child: Column(
children: [
TextFormField(
controller: keyController,
decoration: InputDecoration(labelText: 'Key'),
onChanged: (value) {
widget.onEdit(value, valueController.text);
},
),
TextFormField(
controller: valueController,
decoration: InputDecoration(labelText: 'Value'),
onChanged: (value) {
widget.onEdit(keyController.text, value);
},
),
],
),
);
}
}
class DraggableTarget extends StatelessWidget {
final Function(String) onAccept;
DraggableTarget({required this.onAccept});
@override
Widget build(BuildContext context) {
return Container(
width: 793,
height: 1122,
child: DragTarget<String>(
builder: (context, candidateData, rejectedData) {
return Center(
child: Text('Drop Here', style: TextStyle(fontSize: 24)),
);
},
onAccept: (String field) {
onAccept(field);
},
),
);
}
}
void main() {
runApp(MaterialApp(
home: ReportEditor(),
));
}
Binary file not shown.
@@ -0,0 +1,342 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../Utils/color_constants.dart';
import '../../providers/token_manager.dart';
import '../../utilities/make_api_request.dart';
import '../main_app_screen/tabbed_layout_component.dart';
class LoginFormComponent extends StatefulWidget {
const LoginFormComponent({Key? key}) : super(key: key);
@override
LoginFormComponentState createState() {
return LoginFormComponentState();
}
}
class LoginFormComponentState extends State<LoginFormComponent> {
final _formKey = GlobalKey<FormState>();
String errorMessage1 = "";
String errorMessage2 = "";
String userInput = "";
String password = "";
bool isPasswordVisible = false;
bool stayLoggedIn = false;
void errorMessageSetter(int fieldNumber, String message) {
setState(() {
if (fieldNumber == 1) {
errorMessage1 = message;
} else {
errorMessage2 = message;
}
});
}
void tryLoggingIn() async {
final dataReceived = await sendData(
urlPath: "/token/session",
data: {"email": userInput, "password": password},
);
if (dataReceived.containsValue('ERROR')) {
var error = dataReceived['operationMessage'].toString();
// ignore: use_build_context_synchronously
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Text(error),
backgroundColor: Colors.redAccent,
))
.closed;
} else {
var token = dataReceived['item']['token'];
var user = dataReceived['item'];
await TokenManager.setToken(token);
if (stayLoggedIn) {
await _saveLoggedInUserData(token, user);
}
// ignore: use_build_context_synchronously
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(
content: Text("Login Successful"),
backgroundColor: Colors.green,
))
.closed
.then(
(value) => Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => TabbedLayoutComponent(),
),
(route) => false,
),
);
print('after login');
}
}
Future<bool> _saveLoggedInUserData(
String loggedInUserAuthKey, Map<String, dynamic> user) async {
try {
var userId = user['userId'].toString();
var firstName = user['firstName'].toString();
final prefs = await SharedPreferences.getInstance();
await prefs.setString('userData', json.encode(user));
await prefs.setBool('isLoggedIn', true);
await prefs.setString('token', loggedInUserAuthKey);
print('userId ....$userId');
print('firstName ....$firstName');
if (mounted) {
debugPrint("user data saved");
}
return true;
} catch (e) {
return false;
}
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Color(0xFFF5F7FA),
),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100,
),
],
),
child: TextFormField(
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
errorMessageSetter(
1, 'You must provide an email or username');
} else {
errorMessageSetter(1, "");
setState(() {
userInput = value;
});
}
return null;
},
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "Username or email address",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (errorMessage1 != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$errorMessage1",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
Container(
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
color: Colors.white,
boxShadow: [
const BoxShadow(
spreadRadius: 0.618,
blurRadius: 6.18,
offset: Offset(-4, -4),
color: Color(0xFFF5F7FA),
),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100,
),
],
),
child: TextFormField(
textInputAction: TextInputAction.done,
onFieldSubmitted: (value) => _validateLoginDetails(),
validator: (value) {
if (value == null || value.isEmpty) {
errorMessageSetter(2, 'Password cannot be empty');
} else {
errorMessageSetter(2, "");
setState(() {
password = value;
});
}
return null;
},
obscureText: !isPasswordVisible,
enableSuggestions: false,
autocorrect: false,
decoration: InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: const EdgeInsets.only(
left: 15, bottom: 11, top: 11, right: 15),
hintText: "Password",
hintStyle:
const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
suffixIcon: IconButton(
icon: Icon(
isPasswordVisible ? Icons.visibility : Icons.visibility_off,
),
onPressed: () {
setState(() {
isPasswordVisible = !isPasswordVisible;
});
},
),
),
),
),
if (errorMessage2 != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$errorMessage2",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
CheckboxListTile(
activeColor: ColorConstant.blue700,
title: const Text('Stay Logged In'),
value: stayLoggedIn,
onChanged: (value) {
setState(() {
stayLoggedIn = value!;
});
},
),
Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
width: double.infinity,
height: 64,
child: ElevatedButton(
onPressed: _validateLoginDetails,
style: ElevatedButton.styleFrom(
backgroundColor: ColorConstant.blue700,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: const Text(
'Log in',
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w600,
),
),
),
),
// Container(
// margin: const EdgeInsets.symmetric(vertical: 16.0),
// width: double.infinity,
// height: 64,
// decoration: BoxDecoration(
// boxShadow: [
// BoxShadow(
// color: Colors.blueGrey.shade100,
// offset: const Offset(0, 4),
// blurRadius: 5.0,
// ),
// ],
// gradient: const RadialGradient(
// colors: [Color(0xff0070BA), Color(0xff1546A0)],
// radius: 8.4,
// center: Alignment(-0.24, -0.36),
// ),
// borderRadius: BorderRadius.circular(20),
// ),
// child: ElevatedButton(
// onPressed: _validateLoginDetails,
// style: ElevatedButton.styleFrom(
// primary: Colors.transparent,
// shadowColor: Colors.transparent,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(20),
// ),
// ),
// child: const Text(
// 'Log in',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
],
),
);
}
void _validateLoginDetails() {
FocusManager.instance.primaryFocus?.unfocus();
if (_formKey.currentState!.validate()) {
if (errorMessage1 != "" || errorMessage2 != "") {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please provide all required details'),
backgroundColor: Colors.red,
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
onVisible: tryLoggingIn,
content: const Text('Processing...'),
backgroundColor: Colors.blue,
),
);
}
}
}
}
+586
View File
@@ -0,0 +1,586 @@
// import 'dart:convert';
// import 'package:flutter/material.dart';
// import 'package:authsec_flutter/hadwin_components.dart';
// import 'package:shared_preferences/shared_preferences.dart';
// import '../../Utils/color_constants.dart';
// import '../../Utils/image_constant.dart';
// import '../../Utils/size_utils.dart';
// import '../../providers/token_manager.dart';
// import '../../theme/app_style.dart';
// import '../../widgets/app_bar/appbar_title.dart';
// import '../../widgets/app_bar/custom_app_bar.dart';
// import '../../widgets/custom_button.dart';
// import '../../widgets/custom_image_view.dart';
// import '../../widgets/custom_text_form_field.dart';
// import '../forgot_password/forgotPasswordScreen.dart';
// import '../main_app_screen/newlanding_page.dart';
// import '../sign_up_screen/sign_up_step_1.dart';
//
//
//
// class LoginScreen extends StatefulWidget {
// const LoginScreen({Key? key}) : super(key: key);
//
// @override
// _LoginScreenState createState() => _LoginScreenState();
// }
//
// class _LoginScreenState extends State<LoginScreen> {
// TextEditingController inputFieldController = TextEditingController();
// TextEditingController inputFieldOneController = TextEditingController();
//
// String errorMessage1 = "";
// String errorMessage2 = "";
// bool isPasswordVisible = false;
// bool stayLoggedIn = false;
//
// @override
// initState(){
// super.initState();
// }
//
// GlobalKey<FormState> _formKey = GlobalKey<FormState>();
//
// void errorMessageSetter(int fieldNumber, String message) {
// setState(() {
// if (fieldNumber == 1) {
// errorMessage1 = message;
// } else {
// errorMessage2 = message;
// }
// });
// }
//
// void tryLoggingIn() async {
// final dataReceived = await sendData(
// urlPath: "/token/session",
// data: {"email": inputFieldController.text, "password": inputFieldOneController.text},
// );
//
// if (dataReceived.containsValue('ERROR')) {
// var error = dataReceived['operationMessage'].toString();
// // ignore: use_build_context_synchronously
// ScaffoldMessenger.of(context)
// .showSnackBar(SnackBar(
// content: Text(error),
// backgroundColor: Colors.redAccent,
// ))
// .closed;
// } else {
// var token = dataReceived['item']['token'];
// var user = dataReceived['item'];
// await TokenManager.setToken(token);
//
// if (stayLoggedIn) {
// await _saveLoggedInUserData(token, user);
// }
// // ignore: use_build_context_synchronously
// ScaffoldMessenger.of(context)
// .showSnackBar(const SnackBar(
// content: Text("Login Successful"),
// backgroundColor: Colors.green,
// ))
// .closed
// .then(
// (value) => Navigator.of(context).pushAndRemoveUntil(
// MaterialPageRoute(
// builder: (context) => TabbedLayoutComponentb(),
// ),
// (route) => false,
// ),
// );
//
// print('after login');
// }
// }
//
// Future<bool> _saveLoggedInUserData(
// String loggedInUserAuthKey, Map<String, dynamic> user) async {
// try {
// var userId = user['userId'].toString();
// var firstName = user['firstName'].toString();
//
// final prefs = await SharedPreferences.getInstance();
// await prefs.setString('userData', json.encode(user));
// await prefs.setBool('isLoggedIn', true);
// await prefs.setString('token', loggedInUserAuthKey);
//
// print('userId ....$userId');
// print('firstName ....$firstName');
//
// if (mounted) {
// debugPrint("user data saved");
// }
//
// return true;
// } catch (e) {
// return false;
// }
// }
//
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// backgroundColor: ColorConstant.gray50,
// appBar: CustomAppBar(
// height: getVerticalSize(54),
// leadingWidth: 40,
// centerTitle: true,
// title: AppbarTitle(text: "Login")),
// body: SingleChildScrollView(
// child: Form(
// key: _formKey,
// child: Container(
// width: double.maxFinite,
// padding:
// getPadding(left: 16, top: 22, right: 16, bottom: 22),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Padding(
// padding: getPadding(top: 19),
// child: Text("Email",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle.txtGilroyMedium16Bluegray900),),
//
// CustomTextFormField(
// focusNode: FocusNode(),
// controller: inputFieldController,
// hintText: "Enter Your Email",
// padding: TextFormFieldPadding.PaddingT12,
//
// margin: getMargin(top: 7),
// textInputType: TextInputType.emailAddress),
// Padding(
// padding: getPadding(top: 19),
// child: Text("Password",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style:
// AppStyle.txtGilroyMedium16Bluegray900)),
// CustomTextFormField(
// focusNode: FocusNode(),
// controller: inputFieldOneController,
// hintText: "Enter Password",
// margin: getMargin(top: 6),
// padding: TextFormFieldPadding.PaddingT12,
// textInputAction: TextInputAction.done,
// textInputType:TextInputType.visiblePassword,
// suffix: IconButton(
// icon: Icon(
// isPasswordVisible ? Icons.visibility_off : Icons.visibility,
// size: 12,
// ),
// onPressed: () {
// setState(() {
// isPasswordVisible = !isPasswordVisible;
// });
// },
// ),
// suffixConstraints: BoxConstraints(
// maxHeight: getVerticalSize(44)),
// isObscureText: !isPasswordVisible),
// Padding(
// padding: getPadding(top: 17),
// child: Row(children: [
// Checkbox(value: stayLoggedIn,
// activeColor: ColorConstant.blueA700,
// onChanged: (value) {
// setState(() {
// stayLoggedIn = value!;
// });
// },),
// Padding(
// padding:
// getPadding(left: 8, top: 1, bottom: 1),
// child: Text("Remember me",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle.txtGilroyMedium14)),
// Spacer(),
// GestureDetector(
// onTap: getLoginHelp,
// child: Padding(
// padding: getPadding(top: 3),
// child: Text("Forgot Password?",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style:
// AppStyle.txtGilroyMedium14BlueA700)),
// )
// ])),
// CustomButton(
// height: getVerticalSize(50),
// width: getHorizontalSize(396),
// text: "Log in",
// margin: getMargin(top: 25),
// onTap: (){
// if(inputFieldOneController.text==''||inputFieldController.text==''){
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('Please provide all required details'),
// backgroundColor: Colors.red,
// ),
// );
// }else{
// _validateLoginDetails();
// }
// },
// ),
// Padding(
// padding: getPadding(top: 26),
// child: Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Padding(
// padding: getPadding(top: 10, bottom: 7),
// child: Divider(
// height: getVerticalSize(1),
// thickness: getVerticalSize(1),
// color: ColorConstant.blueGray200)),
// Text("Or continue with",
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle
// .txtGilroyRegular16Bluegray200),
// Padding(
// padding: getPadding(top: 10, bottom: 7),
// child: Divider(
// height: getVerticalSize(1),
// thickness: getVerticalSize(1),
// color: ColorConstant.blueGray200))
// ])),
// CustomButton(
// height: getVerticalSize(50),
// text: "Sign Up",
// margin: getMargin(top: 28),
// variant: ButtonVariant.OutlineBlueA700,
// padding: ButtonPadding.PaddingT14,
// fontStyle: ButtonFontStyle.GilroyMedium16BlueA700,
// onTap:goToSignUpScreen ,
// // prefixWidget: Container(
// // margin: getMargin(right: 8),
// // child: CustomImageView(
// // svgPath: ImageConstant.imgGoogle))
// ),
// CustomButton(
// height: getVerticalSize(50),
// text: "Sign in with Google",
// margin: getMargin(top: 28),
// variant: ButtonVariant.OutlineBlueA700,
// padding: ButtonPadding.PaddingT14,
// fontStyle: ButtonFontStyle.GilroyMedium16BlueA700,
// prefixWidget: Container(
// margin: getMargin(right: 8),
// child: CustomImageView(
// svgPath: ImageConstant.imgGoogle))),
// CustomButton(
// height: getVerticalSize(50),
// text: "Sign in with Facebook",
// margin: getMargin(top: 17),
// variant: ButtonVariant.OutlineBlueA700,
// padding: ButtonPadding.PaddingT14,
// fontStyle: ButtonFontStyle.GilroyMedium16BlueA700,
// prefixWidget: Container(
// padding:
// getPadding(left: 9, top: 4, right: 3),
// margin: getMargin(right: 8),
// decoration: BoxDecoration(
// color: ColorConstant.blue700,
// borderRadius: BorderRadius.circular(
// getHorizontalSize(3))),
// child: CustomImageView(
// svgPath: ImageConstant.imgFacebook))),
// CustomButton(
// height: getVerticalSize(50),
// text: "Sign in with Linkedin",
// margin: getMargin(top: 17),
// variant: ButtonVariant.OutlineBlueA700,
// padding: ButtonPadding.PaddingT14,
// fontStyle: ButtonFontStyle.GilroyMedium16BlueA700,
// prefixWidget: Container(
// margin: getMargin(right: 8),
// child: CustomImageView(
// svgPath: ImageConstant.imgLinkedin11))),
// Align(
// alignment: Alignment.center,
// child: Padding(
// padding: getPadding(top: 28, bottom: 5),
// child: RichText(
// text: TextSpan(children: [
// TextSpan(
// text: "",
// style: TextStyle(
// color: ColorConstant.fromHex(
// "#ff12282a"),
// fontSize: getFontSize(16),
// fontFamily: 'Gilroy',
// fontWeight: FontWeight.w400)),
// TextSpan(
// text: " ",
// style: TextStyle(
// color: ColorConstant.fromHex(
// "#ff12282a"),
// fontSize: getFontSize(16),
// fontFamily: 'Gilroy',
// fontWeight: FontWeight.w700)),
// TextSpan(
// text: "",
// style: TextStyle(
// color: ColorConstant.fromHex(
// "#ff0061ff"),
// fontSize: getFontSize(16),
// fontFamily: 'Gilroy',
// fontWeight: FontWeight.w700,
// decoration:
// TextDecoration.underline))
// ]),
// textAlign: TextAlign.left)))
// ]))),
// ),
// );
// }
//
// // onTapArrowleft6(BuildContext context) {
// // Navigator.pop(context);
// // }
//
// void _validateLoginDetails() {
// FocusManager.instance.primaryFocus?.unfocus();
// if (_formKey.currentState!.validate()) {
// if (errorMessage1 != "" || errorMessage2 != "") {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('Please provide all required details'),
// backgroundColor: Colors.red,
// ),
// );
// } else {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// onVisible: tryLoggingIn,
// content: const Text('Processing...'),
// backgroundColor: Colors.blue,
// ),
// );
// }
// }
// }
//
// void getLoginHelp() {
// //ForgotPasswordPage
// Navigator.push(
// context, MaterialPageRoute(builder: (context) => ForgotPasswordPage()));
// // Navigator.push(
// // context,
// // SlideRightRoute(
// // page: const HadWinMarkdownViewer(
// // screenName: 'Login Help',
// // urlRequested:
// // 'https://raw.githubusercontent.com/brownboycodes/HADWIN/master/docs/HADWIN_WIKI.md')));
// }
//
// void goToSignUpScreen() {
// // Navigator.push(context,
// // MaterialPageRoute(builder: (context) => SignUpUserScreen()))
// // .then((value) => const LoginScreen());
//
// Navigator.push(context,
// MaterialPageRoute(builder: (context) => SignUpUserScreenNew()))
// .then((value) => const LoginScreen());
//
//
// }
//
// }
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import '../../Utils/color_constants.dart';
import '../../utilities/hadwin_markdown_viewer.dart';
import '../../utilities/slide_right_route.dart';
import '../sign_up_screen/SignUpUser.dart';
import '../sign_up_screen/sign_up_step_1.dart';
import 'form_component.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
@override
Widget build(BuildContext context) {
Widget helpInfoContainer = SizedBox(
width: double.infinity,
height: 36,
child: Center(
child: InkWell(
onTap: getLoginHelp,
child: const Text(
'Having trouble logging in?',
style: TextStyle(fontSize: 14, color: Color(0xFF929BAB)),
), // FOR LOGIN HELP
),
),
);
Widget signUpContainer = const SizedBox(
width: double.infinity,
height: 36,
child: Center(
child: InkWell(
//onTap: goToSignUpScreen,
child: Text(
'Or Continue with',
style: TextStyle(fontSize: 14, color: Color(0xFF929BAB)),
), // FOR SIGN UP
),
),
);
List<Widget> loginScreenContents = <Widget>[
_spacing(30),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: SvgPicture.asset(
'assets/images/cloudnsuresp.svg',
width: 300,
),
),
_spacing(30),
const LoginFormComponent(), // ON LOGIN SCREEN
_spacing(10),
signUpContainer,
_spacing(10),
Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
width: double.infinity,
height: 64,
child: ElevatedButton(
onPressed: goToSignUpScreen,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(color: ColorConstant.blue700, width: 2.0),
),
),
child: Text(
'Sign Up',
style: TextStyle(
fontSize: 16,
color: ColorConstant.blue700,
fontWeight: FontWeight.w600,
),
),
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
width: double.infinity,
height: 64,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(color: ColorConstant.blue700, width: 2.0),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
'assets/images/img_google.svg',
),
const SizedBox(
width: 10,
),
Text(
'Sign in with Google',
style: TextStyle(
fontSize: 16,
color: Colors.grey, //ColorConstant.blue700,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
width: double.infinity,
height: 64,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(color: ColorConstant.blue700, width: 2.0),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
'assets/images/img_linkedin_1_1.svg',
),
const SizedBox(
width: 10,
),
Text(
'Sign in with LinkedIn',
style: TextStyle(
fontSize: 16,
color: Colors.grey, //ColorConstant.blue700,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
];
return Scaffold(
body: SingleChildScrollView(
padding: const EdgeInsets.all(45),
child: Column(
children: loginScreenContents,
),
),
);
}
void getLoginHelp() {
Navigator.push(
context,
SlideRightRoute(
page: const HadWinMarkdownViewer(
screenName: 'Login Help',
urlRequested:
'https://raw.githubusercontent.com/brownboycodes/HADWIN/master/docs/HADWIN_WIKI.md')));
}
void goToSignUpScreen() {
Navigator.push(context,
MaterialPageRoute(builder: (context) => SignUpUserScreenNew()))
.then((value) => const LoginScreen());
}
SizedBox _spacing(double height) => SizedBox(
height: height,
);
}
@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../main.dart';
import '../Login Screen/login_screen.dart';
class LogoutService {
static Future<void> logout() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('userData');
await prefs.remove('isLoggedIn');
const storage = FlutterSecureStorage();
await storage.delete(key: 'token');
navigatorKey.currentState!.pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => LoginScreen()),
(route) => false, // Remove all routes from the stack
);
}
}
@@ -0,0 +1,75 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
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';
Future<void> scanBarcode() async {
final result = await FlutterBarcodeScanner.scanBarcode(
'#ff6666', // Background color
'Cancel', // Cancel button text
true, // Show flash icon
ScanMode.BARCODE, // Scan mode (you can change to QR code if needed)
);
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,75 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
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';
Future<void> scanQRcode() async {
final result = await FlutterBarcodeScanner.scanBarcode(
'#ff6666', // Background color
'Cancel', // Cancel button text
true, // Show flash icon
ScanMode.QR, // Scan mode (you can change to QR code if needed)
);
if (!mounted) return;
setState(() {
scannedqr_code_scanner = result;
});
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('QR Code')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Center(
child: Column(
children: [
const Text(
'Scanned QRcode:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Text(
scannedqr_code_scanner,
style: const TextStyle(fontSize: 16),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: () {
scanQRcode(); // Trigger barcode scanning
},
icon: const Icon(Icons.camera_alt), // Camera icon
label: const Text('Scan QRcode'),
),
const SizedBox(height: 16),
],
),
),
),
),
),
);
}
}
+127
View File
@@ -0,0 +1,127 @@
import 'package:flutter/material.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../SysParameters/SystemParameterScreen.dart';
class SetupScreen extends StatelessWidget {
const SetupScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Setup Screen")),
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildSetupBlock(context, 'User Maintenance', SysParameter()),
buildSetupBlock(context, 'User Group Maintenance', SysParameter()),
buildSetupBlock(context, 'Menu Maintenance', SysParameter()),
buildSetupBlock(context, 'Menu Access', SysParameter()),
buildSetupBlock(context, 'System Parameter', SysParameter()),
buildSetupBlock(context, 'Access Type', SysParameter()),
// buildSetupBlock(context, 'Report', ReportPage()),
buildSetupBlock(context, 'Dashboard', SysParameter()),
],
),
),
),
);
}
Widget buildSetupBlock(BuildContext context, String title, Widget screen) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => screen),
);
},
child: Card(
color: Colors.white,
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 40, 20, 40),
child: Column(
children: [
// Container(
// height: getSize(
// 55,
// ),
// width: getSize(
// 55,
// ),
// margin: getMargin(
// top: 2,
// ),
// child: Stack(
// alignment: Alignment.center,
// children: [
// Align(
// alignment: Alignment.center,
// child: Container(
// height: getSize(
// 55,
// ),
// width: getSize(
// 55,
// ),
// child: CircularProgressIndicator(
// value: 0.5,
// backgroundColor: ColorConstant.gray30099,
// color: ColorConstant.blueA700,
// ),
// ),
// ),
// Align(
// alignment: Alignment.center,
// child: Text(
// myProjectcount.toString(),
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle.txtGilroyBold18,
// ),
// ),
// ],
// ),
// ),
// Text(
// myProjectcount.toString(),
// style: const TextStyle(
// color: Colors.black,
// fontSize: 12,
// ),
// ),
const SizedBox(height: 3,),
Text(
title,
style: const TextStyle(
color: Colors.black,
fontSize: 10,
),
),
],
),
),
),
);
}
}
Binary file not shown.
@@ -0,0 +1,77 @@
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
import '../../resources/api_constants.dart';
import '../LogoutService/Logoutservice.dart';
class SystemParameterApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
Future<Map<String, dynamic>> getsystemparameters(String token, int id) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/sysparam/getSysParams/$id');
if (response.statusCode == 401) {
LogoutService.logout();
}
final entities = (response.data);
return entities;
} catch (e) {
throw Exception('Failed to get all projects: $e');
}
}
Future<void> updateParameter(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio
.put('$baseUrl/sysparam/updateSysParams/$entityId', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to update projects: $e');
}
}
Future<Map<String, dynamic>> createFile(
Uint8List fileBytes, String fileName, String token) async {
try {
String apiUrl = "$baseUrl/api/logos/upload?ref=test";
final mimeType = 'image/jpeg'; // You can set the appropriate MIME type
FormData formData = FormData.fromMap({
'file': MultipartFile.fromBytes(
fileBytes,
filename: fileName,
contentType: MediaType.parse(mimeType),
),
});
Dio dio = Dio(); // Create a new Dio instance
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.post(apiUrl, data: formData);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode == 200) {
print('File uploaded successfully');
return response.data; // Return the response data on success
} else {
print('Failed to upload file with status: ${response.statusCode}');
// You might want to handle this error case more explicitly
throw Exception('Failed to upload file');
}
} catch (error) {
print('Error occurred during form submission: $error');
// You might want to handle this error case more explicitly
throw Exception('Error during file upload: $error');
}
}
}
@@ -0,0 +1,533 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import 'SystemParameterApiService.dart';
class SysParameter extends StatefulWidget {
final int sysparameter=1;
// const SysParameter({Key? key, required this.sysparameter}) : super(key: key);
@override
_SysParameterState createState() => _SysParameterState();
}
class _SysParameterState extends State<SysParameter> {
TextEditingController schedulerTimerController = TextEditingController();
TextEditingController leaseTaxCodeController = TextEditingController();
TextEditingController vesselConfirmationController = TextEditingController();
TextEditingController rowToDisplayController = TextEditingController();
TextEditingController linkToDisplayController = TextEditingController();
TextEditingController rowToAddController = TextEditingController();
TextEditingController lovRowToDisplayController = TextEditingController();
TextEditingController lovLinkToDisplayController = TextEditingController();
TextEditingController oidServerNameController = TextEditingController();
TextEditingController oidBaseController = TextEditingController();
TextEditingController oidAdminUserController = TextEditingController();
TextEditingController oidServerPortController = TextEditingController();
TextEditingController userDefaultGroupController = TextEditingController();
TextEditingController defaultDepartmentController = TextEditingController();
TextEditingController defaultPositionController = TextEditingController();
TextEditingController singleChargeController = TextEditingController();
TextEditingController firstDayOfWeekController = TextEditingController();
TextEditingController hourPerShiftController = TextEditingController();
TextEditingController cnBillingFrequencyController = TextEditingController();
TextEditingController billingDepartmentCodeController = TextEditingController();
TextEditingController basePriceListController = TextEditingController();
TextEditingController nonContainerServiceController = TextEditingController();
TextEditingController ediMaeSchedulerController = TextEditingController();
TextEditingController ediSchedulerController = TextEditingController();
TextEditingController lastController = TextEditingController();
TextEditingController companynameController = TextEditingController();
bool isRegistrationAllow=false;
Map<String,dynamic> formData = {};
var logoname;
var logopath;
SystemParameterApiService apiService = SystemParameterApiService();
String? uploadimageurl;
Uint8List? _imageBytes; // Uint8List to store the image data
String? _imageFileName;
late Map<String,dynamic> sysparameter;
@override
void initState() {
_loadParameters();
}
Future<void> _loadParameters() async {
final token = await TokenManager.getToken();
try {
final projectData = await apiService.getsystemparameters(token!,widget.sysparameter);
setState(() {
sysparameter = projectData;
lastController.text = "('SYSADMIN','ITSUPPORTMSC')";
schedulerTimerController.text = sysparameter['schedulerTime'].toString()??'';
isRegistrationAllow = sysparameter['regitrationAllowed']??false;
leaseTaxCodeController.text = sysparameter['leaseTaxCode'].toString()??'';
vesselConfirmationController.text = sysparameter['vesselConfProcessLimit'].toString()??'';
rowToDisplayController.text = sysparameter['rowToDisplay'].toString()??'';
linkToDisplayController.text = sysparameter['linkToDisplay'].toString()??'';
rowToAddController.text = sysparameter['rowToAdd'].toString()??'';
lovRowToDisplayController.text = sysparameter['lovRowToDisplay'].toString()??'';
lovLinkToDisplayController.text = sysparameter['lovLinkToDisplay'].toString()??'';
oidServerNameController.text = sysparameter['oidserverName'].toString()??'';
oidBaseController.text = sysparameter['oidBase'].toString()??'';
oidAdminUserController.text = sysparameter['oidAdminUser'].toString()??'';
oidServerPortController.text = sysparameter['oidServerPort'].toString()??'';
userDefaultGroupController.text = sysparameter['userDefaultGroup'].toString()??'';
defaultDepartmentController.text = sysparameter['defaultDepartment'].toString()??'';
defaultPositionController.text = sysparameter['defaultPosition'].toString()??'';
singleChargeController.text = sysparameter['singleCharge'].toString()??'';
firstDayOfWeekController.text = sysparameter['firstDayOftheWeek'].toString()??'';
hourPerShiftController.text = sysparameter['hourPerShift'].toString()??'';
cnBillingFrequencyController.text = sysparameter['cnBillingFrequency'].toString()??'';
billingDepartmentCodeController.text = sysparameter['billingDepartmentCode'].toString()??'';
basePriceListController.text = sysparameter['basePriceList'].toString()??'';
nonContainerServiceController.text = sysparameter['nonContainerServiceOrder'].toString()??'';
ediMaeSchedulerController.text = sysparameter['ediMaeSchedulerONOFF'].toString()??'';
ediSchedulerController.text = sysparameter['ediSchedulerONOFF'].toString()??'';
lastController.text = "('SYSADMIN','ITSUPPORTMSC')"??'';
companynameController.text = sysparameter['company_Display_Name'].toString()??'';
print(sysparameter['schedulerTime']);
});
} catch (e) {
print('Failed to load projects: $e');
}
}
Future<void> _uploadImageFile() async {
final imagePicker = ImagePicker();
try {
final pickedImage =
await imagePicker.pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
final imageBytes = await pickedImage.readAsBytes();
setState(() {
_imageBytes = imageBytes;
_imageFileName = pickedImage.name; // Store the file name
});
}
_submitImage();
} catch (e) {
print(e);
}
}
Future<void> _submitImage() async {
if (_imageBytes == null) {
// Show an error message if no image is selected
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Please select an image.'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
return;
}
if (_imageFileName == null) {
// Handle the case where _imageFileName is null (no file name provided)
print('File name is missing.');
return;
}
try {
final token = await TokenManager.getToken();
Map<String,dynamic> fileuploadeddata = await apiService.createFile(_imageBytes!, _imageFileName!, token!);
logoname = fileuploadeddata['image_name'];
logopath = fileuploadeddata['image_path'];
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to upload image: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "System Parameter")),
body: Material(child:SingleChildScrollView( // Wrap the form in a SingleChildScrollView
scrollDirection: Axis.vertical, // Allow vertical scrolling
child:Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildFieldWithTooltip(
fieldName: 'Scheduler Timer',
controller: schedulerTimerController,
tooltip: 'Tooltip for Scheduler Timer',
),
_buildFieldWithTooltip(
fieldName: 'Lease Tax Code',
controller: leaseTaxCodeController,
tooltip: 'Tooltip for Lease Tax Code',
),
_buildFieldWithTooltip(
fieldName: 'Vessel Confirmation Process Limit',
controller: vesselConfirmationController,
tooltip: 'Tooltip for Vessel Confirmation Process Limit',
),
_buildFieldWithTooltip(
fieldName: 'Row To Display',
controller: rowToDisplayController,
tooltip: 'Tooltip for Row To Display',
),
_buildFieldWithTooltip(
fieldName: 'Link To Display',
controller: linkToDisplayController,
tooltip: 'Tooltip for Link To Display',
),
_buildFieldWithTooltip(
fieldName: 'Row To Add',
controller: rowToAddController,
tooltip: 'Tooltip for Row To Add',
),
_buildFieldWithTooltip(
fieldName: 'LOV Row To Display',
controller: lovRowToDisplayController,
tooltip: 'Tooltip for LOV Row To Display',
),
_buildFieldWithTooltip(
fieldName: 'LOV Link To Display',
controller: lovLinkToDisplayController,
tooltip: 'Tooltip for LOV Link To Display',
),
_buildFieldWithTooltip(
fieldName: 'OID Server Name',
controller: oidServerNameController,
tooltip: 'Tooltip for OID Server Name',
),
_buildFieldWithTooltip(
fieldName: 'OID Base',
controller: oidBaseController,
tooltip: 'Tooltip for OID Base',
),
_buildFieldWithTooltip(
fieldName: 'OID Admin User',
controller: oidAdminUserController,
tooltip: 'Tooltip for OID Admin User',
),
_buildFieldWithTooltip(
fieldName: 'OID Server Port',
controller: oidServerPortController,
tooltip: 'Tooltip for OID Server Port',
),
_buildFieldWithTooltip(
fieldName: 'User Default Group',
controller: userDefaultGroupController,
tooltip: 'Tooltip for User Default Group',
),
_buildFieldWithTooltip(
fieldName: 'Default Department',
controller: defaultDepartmentController,
tooltip: 'Tooltip for Default Department',
),
_buildFieldWithTooltip(
fieldName: 'Default Position',
controller: defaultPositionController,
tooltip: 'Tooltip for Default Position',
),
_buildFieldWithTooltip(
fieldName: 'Single Charge',
controller: singleChargeController,
tooltip: 'Tooltip for Single Charge',
),
_buildFieldWithTooltip(
fieldName: 'First Day of The Week',
controller: firstDayOfWeekController,
tooltip: 'Tooltip for First Day of The Week',
),
_buildFieldWithTooltip(
fieldName: 'Hour per Shift',
controller: hourPerShiftController,
tooltip: 'Tooltip for Hour per Shift',
),
_buildFieldWithTooltip(
fieldName: 'CN Billing Frequency',
controller: cnBillingFrequencyController,
tooltip: 'Tooltip for CN Billing Frequency',
),
_buildFieldWithTooltip(
fieldName: 'Billing Department Code',
controller: billingDepartmentCodeController,
tooltip: 'Tooltip for Billing Department Code',
),
_buildFieldWithTooltip(
fieldName: 'Base Price List',
controller: basePriceListController,
tooltip: 'Tooltip for Base Price List',
),
_buildFieldWithTooltip(
fieldName: 'Non-Container Service Order Auto-Approval Department Code',
controller: nonContainerServiceController,
tooltip: 'Tooltip for Non-Container Service Order Auto-Approval Department Code',
),
_buildFieldWithTooltip(
fieldName: 'EDI MAE Scheduler ON/OFF',
controller: ediMaeSchedulerController,
tooltip: 'Tooltip for EDI MAE Scheduler ON/OFF',
),
_buildFieldWithTooltip(
fieldName: 'EDI Scheduler ON/OFF',
controller: ediSchedulerController,
tooltip: 'Tooltip for EDI Scheduler ON/OFF',
),
_buildFieldWithTooltip(
fieldName: 'Company Name',
controller: companynameController,
tooltip: 'Company Name',
),
Text("Is Registration Allowed?",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
Row(
children: [
Radio(
value: true,
groupValue: isRegistrationAllow,
onChanged: (value) {
setState(() {
isRegistrationAllow = value as bool;
});
},
),
Text("Yes",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
Radio(
value: false,
groupValue: isRegistrationAllow,
onChanged: (value) {
setState(() {
isRegistrationAllow = value as bool;
});
},
),
Text("No",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
],
),
ElevatedButton(
onPressed: () {
_uploadImageFile();
},
style: ButtonStyle(
backgroundColor: _imageBytes==null?MaterialStateProperty.all<Color>(Colors.red):MaterialStateProperty.all<Color>(Colors.green), // Change to the desired color
),
child: _imageBytes == null
? Text("Pick a Company Logo",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800)
: Text("Company Logo uploaded Successful",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
),
Tooltip(
message: 'Allow customer code for MSC taulia CSV generation',
child: Column(
children: [
Text("i",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
CustomTextFormField(
focusNode: FocusNode(),
controller:lastController,
margin: getMargin(top: 7),
textInputType:
TextInputType.text),
],
)
// TextFormField(
// controller: lastController,
// decoration: const InputDecoration(
// labelText: 'i',
// ),
// ),
),
CustomButton(
height: getVerticalSize(50),
text: "Save",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
formData['regitrationAllowed'] = isRegistrationAllow;
formData['schedulerTime']=schedulerTimerController.text;
formData['leaseTaxCode']=leaseTaxCodeController.text;
formData['vesselConfProcessLimit']=vesselConfirmationController.text;
formData['rowToDisplay']=rowToDisplayController.text;
formData['linkToDisplay']=linkToDisplayController.text;
formData['rowToAdd']=rowToAddController.text;
formData['lovRowToDisplay']=lovRowToDisplayController.text;
formData['lovLinkToDisplay']=lovLinkToDisplayController.text;
formData['oidserverName']=oidServerNameController.text;
formData['oidBase']=oidBaseController.text;
formData['oidAdminUser']=oidAdminUserController.text;
formData['oidServerPort']=oidServerPortController.text;
formData['userDefaultGroup']=userDefaultGroupController.text;
formData['defaultDepartment']=defaultDepartmentController.text;
formData['defaultPosition']=defaultPositionController.text;
formData['singleCharge']=singleChargeController.text;
formData['firstDayOftheWeek']=firstDayOfWeekController.text;
formData['hourPerShift']=hourPerShiftController.text;
formData['cnBillingFrequency']=cnBillingFrequencyController.text;
formData['billingDepartmentCode']=billingDepartmentCodeController.text;
formData['basePriceList']=basePriceListController.text;
formData['nonContainerServiceOrder']=nonContainerServiceController.text;
formData['ediMaeSchedulerONOFF']=ediMaeSchedulerController.text;
formData['ediSchedulerONOFF']=ediSchedulerController.text;
//formData['']=lastController.text;
formData['upload_Logo_name']=logoname;
formData['upload_Logo_path']=logopath;
formData['company_Display_Name']=companynameController.text;
final token = await TokenManager.getToken();
try {
print("token is : $token");
print(formData);
if (formData != null) {
// Create new project
apiService.updateParameter(token!, widget.sysparameter, formData);
}
Navigator.pop(context);
// Add navigation or any other logic after successful create/update
} catch (e) {
print('error is $e');
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text(
'Failed to ${widget.sysparameter == null ? 'create' : 'update'} project: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
},
),
],
),
),
)));
}
Widget _buildFieldWithTooltip({
required String fieldName,
required TextEditingController controller,
required String tooltip,
}) {
return Tooltip(
message: tooltip,
child:
Padding(
padding: getPadding(top: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("$fieldName",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray800),
CustomTextFormField(
focusNode: FocusNode(),
controller:controller,
hintText: "Enter Your $fieldName",
margin: getMargin(top: 7),
textInputType:
TextInputType.text)
])),
// TextFormField(
// controller: controller,
// decoration: InputDecoration(
// labelText: fieldName,
// ),
// ),
);
}
}
@@ -0,0 +1,279 @@
import 'package:flutter/material.dart';
import '../../providers/token_manager.dart';
import 'dynamic_form_service.dart';
class EditForm extends StatefulWidget {
final Map<String, dynamic> formData;
EditForm({required this.formData});
@override
_EditFormState createState() => _EditFormState();
}
class _EditFormState extends State<EditForm> {
TextEditingController formNameController = TextEditingController();
TextEditingController formDescController = TextEditingController();
TextEditingController relatedToController = TextEditingController();
TextEditingController pageEventController = TextEditingController();
TextEditingController buttonCaptionController = TextEditingController();
final DynamicForApiService apiService = DynamicForApiService();
List<dynamic> components = []; // List to store table data
List<dynamic> relatedToFixedDropdown = ['Menu', 'Related To',];
List<dynamic> pageEventFixedDropdown = ['OnClick', 'OnBlur',];
List<dynamic> typeFixedDropdown = ['text', 'dropdown','date','checkbox','textarea','togglebutton'];
List<dynamic> mappingFixedDropdown = ['TEXTFIELD1', 'TEXTFIELD2','TEXTFIELD3','TEXTFIELD4','TEXTFIELD5','TEXTFIELD6','TEXTFIELD7','TEXTFIELD8','TEXTFIELD9','TEXTFIELD10','TEXTFIELD11','TEXTFIELD12','TEXTFIELD13','TEXTFIELD14','TEXTFIELD15','TEXTFIELD16','TEXTFIELD17','TEXTFIELD18','TEXTFIELD19','TEXTFIELD20','TEXTFIELD21','TEXTFIELD22','TEXTFIELD23',
'TEXTFIELD24','TEXTFIELD25','TEXTFIELD26','LONGTEXT1','LONGTEXT2','LONGTEXT3','LONGTEXT4',];
List<dynamic> truefalseFixedDropdown = ['true', 'false',];
@override
void initState() {
super.initState();
// Initialize text controllers with the data from the selected row
formNameController.text = widget.formData['form_name'] ?? '';
formDescController.text = widget.formData['form_desc'] ?? '';
relatedToController.text = widget.formData['related_to'] ?? '';
pageEventController.text = widget.formData['page_event'] ?? '';
buttonCaptionController.text = widget.formData['button_caption'] ?? '';
// Initialize the components data, or you can load it from formData['components'].
// For this example, we'll use an empty list.
components = widget.formData['components'] ?? [];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Form'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
controller: formNameController,
decoration: InputDecoration(labelText: 'Form Name'),
),
TextFormField(
controller: formDescController,
decoration: InputDecoration(labelText: 'Form Description'),
),
DropdownButtonFormField<String>(
value: relatedToController.text,
decoration:
const InputDecoration(labelText: 'Select Related To'),
items: [
...relatedToFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
relatedToController.text = value!;
});
},
),
DropdownButtonFormField<String>(
value: pageEventController.text,
decoration:
const InputDecoration(labelText: 'Select Page Event'),
items: [
...pageEventFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
pageEventController.text = value!;
});
},
),
TextFormField(
controller: buttonCaptionController,
decoration: InputDecoration(labelText: 'Button Caption'),
),
const Text('Components Details'),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: const <DataColumn>[
DataColumn(label: Text('Label')),
DataColumn(label: Text('Type')),
DataColumn(label: Text('Mapping')),
DataColumn(label: Text('Mandatory')),
DataColumn(label: Text('Readonly')),
DataColumn(label: Text('Drop Values')),
DataColumn(label: Text('SP')),
DataColumn(label: Text('Actions'), numeric: false), // Add Actions column
],
rows: components.asMap().entries.map((entry) {
final index = entry.key;
final component = entry.value;
return DataRow(
cells: <DataCell>[
DataCell(TextField(
controller: TextEditingController(text: component['label'] ?? ''),
onChanged: (value){
component['label']=value;
},
)),
DataCell(
DropdownButtonFormField<String>(
value: component['type'],
decoration:
const InputDecoration(labelText: 'Select Type'),
items: [
...typeFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
component['type'] = value;
});
},
),
),
DataCell(
DropdownButtonFormField<String>(
value: component['mapping'],
decoration:
const InputDecoration(labelText: 'Select Mapping'),
items: [
...mappingFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
component['mapping'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['mandatory'] ?? ''),
onChanged: (value){
component['mandatory']=value;
},
)),
DataCell(
DropdownButtonFormField<String>(
value: component['readonly'],
decoration:
const InputDecoration(labelText: 'Select Read Only'),
items: [
...truefalseFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
component['readonly'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['drop_values'] ?? ''),
onChanged: (value){
component['drop_values']=value;
},
)),
DataCell(TextField(
controller: TextEditingController(text: component['sp'] ?? ''),
onChanged: (value){
component['sp']=value;
},
)),
DataCell(
ElevatedButton(
onPressed: () {
setState(() {
components.removeAt(index);
});
},
child: Text('Delete'),
),
),
],
);
}).toList(),
),
),
ElevatedButton(
onPressed: () {
// Add a new row to the components table
components.add({
'label': '',
'type': null,
'mapping': null,
'mandatory': '',
'readonly': null,
'drop_values': '',
'sp': '',
});
setState(() {}); // Refresh the UI to show the new row
},
child: Text('Add Row'),
),
ElevatedButton(
onPressed: () async {
// Save the updated data back to the original data list
widget.formData['form_name'] = formNameController.text;
widget.formData['form_desc'] = formDescController.text;
widget.formData['related_to'] = relatedToController.text;
widget.formData['page_event'] = pageEventController.text;
widget.formData['button_caption'] = buttonCaptionController.text;
widget.formData['components'] = components;
final token = await TokenManager.getToken();
apiService.updateDynamicForm(token!, widget.formData['form_id'], widget.formData);
Navigator.of(context).pop();
},
child: Text('Update'),
),
],
),
),
),
);
}
}
@@ -0,0 +1,333 @@
import 'package:flutter/material.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_dropdown_field.dart';
import '../../widgets/custom_text_form_field.dart';
import 'dynamic_form_service.dart';
class CreateForm extends StatefulWidget {
@override
_CreateFormState createState() => _CreateFormState();
}
class _CreateFormState extends State<CreateForm> {
TextEditingController formNameController = TextEditingController();
TextEditingController formDescController = TextEditingController();
TextEditingController relatedToController = TextEditingController();
TextEditingController pageEventController = TextEditingController();
TextEditingController buttonCaptionController = TextEditingController();
final DynamicForApiService apiService = DynamicForApiService();
List<Map<String, dynamic>> components = [];
List<dynamic> relatedToFixedDropdown = ['Menu', 'Related To',];
List<dynamic> pageEventFixedDropdown = ['OnClick', 'OnBlur',];
List<dynamic> typeFixedDropdown = ['text', 'dropdown','date','checkbox','textarea','togglebutton'];
List<dynamic> mappingFixedDropdown = ['TEXTFIELD1', 'TEXTFIELD2','TEXTFIELD3','TEXTFIELD4','TEXTFIELD5','TEXTFIELD6','TEXTFIELD7','TEXTFIELD8','TEXTFIELD9','TEXTFIELD10','TEXTFIELD11','TEXTFIELD12','TEXTFIELD13','TEXTFIELD14','TEXTFIELD15','TEXTFIELD16','TEXTFIELD17','TEXTFIELD18','TEXTFIELD19','TEXTFIELD20','TEXTFIELD21','TEXTFIELD22','TEXTFIELD23',
'TEXTFIELD24','TEXTFIELD25','TEXTFIELD26','LONGTEXT1','LONGTEXT2','LONGTEXT3','LONGTEXT4',];
List<dynamic> truefalseFixedDropdown = ['true', 'false',];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleft,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Create Dynamic Form"),),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Form Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Form Name",
controller: formNameController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Form Description",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Form Description",
controller: formDescController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Select Related To",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900,
),
CustomDropdownFormField(
items: [
...relatedToFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item, style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
relatedToController.text = value!;
});
},
)
],
),
),
Padding(
padding: getPadding(top: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Select Page Event",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900,
),
CustomDropdownFormField(
items: [
...pageEventFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
pageEventController.text = value!;
});
},
)
],
),
),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Button Caption",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Button Caption",
controller: buttonCaptionController,
margin: getMargin(top: 6))
])),
const Text('Components Details'),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: const <DataColumn>[
DataColumn(label: Text('Label')),
DataColumn(label: Text('Type')),
DataColumn(label: Text('Mapping')),
DataColumn(label: Text('Mandatory')),
DataColumn(label: Text('Readonly')),
DataColumn(label: Text('Drop Values')),
DataColumn(label: Text('SP')),
],
rows: components.asMap().entries.map((entry) {
final index = entry.key;
final component = entry.value;
bool? isReadonly = false;
return DataRow(
cells: <DataCell>[
DataCell(TextField(
controller: TextEditingController(text: component['label'] ?? ''),
onChanged: (value) {
component['label'] = value;
},
)),
DataCell(
DropdownButtonFormField<String>(
decoration:
const InputDecoration(labelText: 'Select Type'),
items: [
...typeFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
component['type'] = value;
});
},
),
),
DataCell(
DropdownButtonFormField<String>(
decoration:
const InputDecoration(labelText: 'Select Mapping'),
items: [
...mappingFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
component['mapping'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['mandatory'] ?? ''),
onChanged: (value) {
component['mandatory'] = value;
},
)),
DataCell(
DropdownButtonFormField<String>(
decoration:
const InputDecoration(labelText: 'Select Read Only'),
items: [
...truefalseFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
component['readonly'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['drop_values'] ?? ''),
onChanged: (value) {
component['drop_values'] = value;
},
)),
DataCell(TextField(
controller: TextEditingController(text: component['sp'] ?? ''),
onChanged: (value) {
component['sp'] = value;
},
)),
],
);
}).toList(),
),
),
CustomButton(
height: getVerticalSize(50),
text: "Add Row",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
components.add({
'label': '',
'type': '',
'mapping': '',
'mandatory': '',
'readonly': '',
'drop_values': '',
'sp': '',
});
setState(() {});
},
),
CustomButton(
height: getVerticalSize(50),
text: "Create Dynamic Form",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
final dynamicFormData = {
'form_name': formNameController.text,
'form_desc': formDescController.text,
'related_to': relatedToController.text,
'page_event': pageEventController.text,
'button_caption': buttonCaptionController.text,
'components': components,
};
final token = await TokenManager.getToken();
apiService.createDynamicForm(token!, dynamicFormData);
Navigator.of(context).pop();
},
),
],
),
),
),
);
}
}
@@ -0,0 +1,100 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../../resources/api_constants.dart';
import '../LogoutService/Logoutservice.dart';
class DynamicForApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
//api/dynamic_form_build
Future<void> BuildForms(String token, int id) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response =
await dio.get('$baseUrl/api/dynamic_form_build?form_id=$id');
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode! <= 209) {
Fluttertoast.showToast(
msg: 'Build success',
backgroundColor: Colors.red,
);
} else {
Fluttertoast.showToast(
msg: 'Unable to build',
backgroundColor: Colors.red,
);
throw Exception('Unexpected response type');
}
} catch (e) {
throw Exception('Failed to Build form: $e');
}
}
Future<List<Map<String, dynamic>>> getallDynamicForms(
String token,
) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/api/form_setup');
if (response.statusCode == 401) {
LogoutService.logout();
}
final responseData = response.data['items'];
if (responseData is List) {
final entities = responseData.cast<Map<String, dynamic>>();
return entities;
} else if (responseData is Map<String, dynamic>) {
return [responseData];
} else {
throw Exception('Unexpected response type');
}
} catch (e) {
throw Exception('Failed to get modules by projectId: $e');
}
}
Future<void> createDynamicForm(
String token, Map<String, dynamic> entity) async {
try {
print("in post api...$entity");
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio.post('$baseUrl/api/form_setup', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to create Dynamic form: $e');
}
}
Future<void> updateDynamicForm(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response =
await dio.put('$baseUrl/api/form_setup/$entityId', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to update Dynamic form: $e');
}
}
Future<void> deleteDynamicForm(String token, int entityId) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio.delete('$baseUrl/api/form_setup/$entityId');
if (response.statusCode == 401) {
LogoutService.logout();
}
} catch (e) {
throw Exception('Failed to delete Dynamic form: $e');
}
}
}
@@ -0,0 +1,224 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import '../../Utils/color_constants.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import 'UpdatedynamicForm.dart';
import 'create_dynamicform.dart';
import 'dynamic_form_service.dart';
class DynamicForm extends StatefulWidget {
@override
_DynamicFormState createState() => _DynamicFormState();
}
class _DynamicFormState extends State<DynamicForm> {
final DynamicForApiService apiService = DynamicForApiService();
late List<Map<String, dynamic>> allData = [];
bool isLoading = false;
@override
void initState() {
super.initState();
_loadDynamicForms();
}
Future<void> _loadDynamicForms() async {
final token = await TokenManager.getToken();
try {
final alData = await apiService.getallDynamicForms(token!);
setState(() {
allData = alData;
print('allData fetched...');
});
isLoading = true;
} catch (e) {
isLoading = true;
print('Failed to load allData: $e');
}
}
Future<void> deleteEntity(Map<String, dynamic> entity) async {
try {
final token = await TokenManager.getToken();
await apiService.deleteDynamicForm(token!, entity['form_id']);
setState(() {
allData.remove(entity);
});
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to delete entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
actions: [
GestureDetector(
child: Icon(
Icons.add,
color: Colors.black,
size: 20,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CreateForm(),
),
).then((value) => {_loadDynamicForms()});
},
),
const SizedBox(
width: 20,
)
],
centerTitle: true,
title: AppbarTitle(text: "Dynamic Form")),
body: isLoading == false
? const Center(child: CircularProgressIndicator())
: allData.isEmpty
? const Center(
child: Text('No Services available.'),
)
: Scrollable(
viewportBuilder:
(BuildContext context, ViewportOffset position) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: [
DataColumn(label: Text('Form Name')),
DataColumn(label: Text('Form Description')),
DataColumn(label: Text('Related To')),
DataColumn(label: Text('Page Event')),
DataColumn(label: Text('Button Caption')),
DataColumn(label: Text('Build')),
DataColumn(label: Text('Actions')),
],
rows: allData.map((module) {
return DataRow(
cells: [
DataCell(
Text('${module['form_name'] ?? 'N/A'}')),
DataCell(
Text('${module['form_desc'] ?? 'N/A'}')),
DataCell(
Text('${module['related_to'] ?? 'N/A'}')),
DataCell(
Text('${module['page_event'] ?? 'N/A'}')),
DataCell(Text(
'${module['button_caption'] ?? 'N/A'}')),
DataCell(Row(
children: [
ElevatedButton(
onPressed: () async {
print(module);
final token =
await TokenManager.getToken();
apiService.BuildForms(
token!, module['form_id']);
},
child: Text("build"),
style: ElevatedButton.styleFrom(
backgroundColor: ColorConstant.blue700,
),
)
],
)),
DataCell(Row(
children: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
EditForm(formData: module),
),
).then(
(value) => {_loadDynamicForms()});
},
icon: Icon(Icons.edit),
),
IconButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
'Confirm Deletion'),
content: const Text(
'Are you sure you want to delete this Module?'),
actions: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Delete'),
onPressed: () {
Navigator.of(context).pop();
deleteEntity(module);
},
),
],
);
},
);
},
icon: Icon(Icons.delete),
),
],
)),
],
);
}).toList(),
),
),
);
},
),
);
}
}
@@ -0,0 +1,130 @@
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import '../../Utils/color_constants.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../Login Screen/login_screen.dart';
class ForgotPasswordPage extends StatefulWidget {
@override
_ForgotPasswordPageState createState() => _ForgotPasswordPageState();
}
class _ForgotPasswordPageState extends State<ForgotPasswordPage> {
final TextEditingController emailController = TextEditingController();
String message = '';
bool isLoading = false; // Added to track loading state
Future<void> sendForgotPasswordRequest() async {
setState(() {
isLoading = true; // Show loading indicator when sending request
});
final email = emailController.text;
final token = await TokenManager.getToken();
const String baseUrl = ApiConstants.baseUrl;
final response = await http.post(
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
Uri.parse('$baseUrl/api/resources/forgotpassword?email=$email'),
);
if (response.statusCode == 200) {
setState(() {
message = 'An email with a reset link has been sent to $email.';
});
// Delay for 3 seconds and then navigate to the login page
Future.delayed(Duration(seconds: 3), () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => LoginScreen()));
});
} else {
setState(() {
message = 'Failed to send the reset link. Please try again.';
});
}
setState(() {
isLoading = false; // Hide loading indicator when the request is complete
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Forgot Password")),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Email",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Email",
controller: emailController,
margin: getMargin(top: 6))
])),
CustomButton(
height: getVerticalSize(50),
text: "Send me an access link",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
sendForgotPasswordRequest();
},
),
isLoading
? CircularProgressIndicator(
color: ColorConstant.blue700,
) // Show loading indicator when isLoading is true
: Text(message, style: AppStyle.txtGilroyMedium16Bluegray900),
if (message.contains('An email with a reset link'))
InkWell(
child: Text('Click here to return to login',
style: AppStyle.txtGilroyMedium16Bluegray900),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const LoginScreen()));
},
),
],
),
),
);
}
}
@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
class CustomizedFooter extends StatelessWidget {
final IconData homeIcon;
final IconData squareIcon;
final IconData addIcon;
final List<String> labels;
final List<Function()> onTapActions;
CustomizedFooter({
required this.homeIcon,
required this.squareIcon,
required this.addIcon,
required this.labels,
required this.onTapActions,
});
@override
Widget build(BuildContext context) {
assert(labels.length == 3 && onTapActions.length == 3);
return Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3),
),
],
),
child: BottomNavigationBar(
onTap: (index) {
onTapActions[index]();
},
items: [
BottomNavigationBarItem(
icon: Icon(homeIcon),
label: labels[0],
),
BottomNavigationBarItem(
icon: Icon(squareIcon),
label: labels[1],
),
BottomNavigationBarItem(
icon: Icon(addIcon),
label: labels[2],
),
],
),
);
}
}
@@ -0,0 +1,339 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg_provider/flutter_svg_provider.dart' as fs;
import '../../Utils/color_constants.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_style.dart';
import '../LogoutService/Logoutservice.dart';
import 'package:http/http.dart' as http;
class Listgroup524ItemWidget extends StatefulWidget {
final Map<String, dynamic> userData;
Listgroup524ItemWidget({required this.userData});
@override
State<Listgroup524ItemWidget> createState() => _Listgroup524ItemWidgetState();
}
class _Listgroup524ItemWidgetState extends State<Listgroup524ItemWidget> {
int myProjectcount = 0;
int sharedWithMeCount = 0;
int allprojectCount = 0;
@override
void initState() {
super.initState();
fetchData();
}
Future<void> fetchData() async {
print("working");
final token = await TokenManager.getToken();
print(token);
String baseUrl = ApiConstants.baseUrl;
var myProjectcountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_myproject'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
var sharedWithMeCountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_sharedwithme'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
var allProjectsCountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_allproject'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
if (myProjectcountres.statusCode == 401) {
LogoutService.logout();
}
print(myProjectcountres.statusCode);
if (myProjectcountres.statusCode <= 209 &&
sharedWithMeCountres.statusCode <= 209) {
final myProjectData = jsonDecode(myProjectcountres.body);
final sharedData = jsonDecode(sharedWithMeCountres.body);
final allData = jsonDecode(allProjectsCountres.body);
setState(() {
myProjectcount = myProjectData;
sharedWithMeCount = sharedData;
allprojectCount = allData;
});
} else {
// Handle errors
print('Failed to fetch data');
}
}
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "myproject"), // Get all projects
// ),
// );
},
child: Card(
color: Colors.white,
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Column(
children: [
Container(
height: getSize(
55,
),
width: getSize(
55,
),
margin: getMargin(
top: 2,
),
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.center,
child: Container(
height: getSize(
55,
),
width: getSize(
55,
),
child: CircularProgressIndicator(
value: 0.5,
backgroundColor: ColorConstant.gray30099,
color: ColorConstant.blueA700,
),
),
),
Align(
alignment: Alignment.center,
child: Text(
myProjectcount.toString(),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyBold18,
),
),
],
),
),
// Text(
// myProjectcount.toString(),
// style: const TextStyle(
// color: Colors.black,
// fontSize: 12,
// ),
// ),
const SizedBox(
height: 3,
),
const Text(
'My Projects',
style: TextStyle(
color: Colors.black,
fontSize: 10,
),
),
],
),
),
),
),
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "sharedproject"), // Get all projects
// ),
// );
},
child: Card(
color: Colors.white,
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Column(
children: [
Container(
height: getSize(
55,
),
width: getSize(
55,
),
margin: getMargin(
top: 2,
),
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.center,
child: Container(
height: getSize(
55,
),
width: getSize(
55,
),
child: CircularProgressIndicator(
value: 0.5,
backgroundColor: ColorConstant.gray30099,
color: ColorConstant.blueA700,
),
),
),
Align(
alignment: Alignment.center,
child: Text(
sharedWithMeCount.toString(),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyBold18,
),
),
],
),
),
// Text(
// myProjectcount.toString(),
// style: const TextStyle(
// color: Colors.black,
// fontSize: 12,
// ),
// ),
const SizedBox(
height: 3,
),
const Text(
'Shared with me',
style: TextStyle(
color: Colors.black,
fontSize: 10,
),
),
],
),
),
),
),
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "allproject"), // Get all projects
// ),
// );
},
child: Card(
color: Colors.white,
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Column(
children: [
Container(
height: getSize(
55,
),
width: getSize(
55,
),
margin: getMargin(
top: 2,
),
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.center,
child: Container(
height: getSize(
55,
),
width: getSize(
55,
),
child: CircularProgressIndicator(
value: 0.5,
backgroundColor: ColorConstant.gray30099,
color: ColorConstant.blueA700,
),
),
),
Align(
alignment: Alignment.center,
child: Text(
allprojectCount.toString(),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyBold18,
),
),
],
),
),
// Text(
// myProjectcount.toString(),
// style: const TextStyle(
// color: Colors.black,
// fontSize: 12,
// ),
// ),
const SizedBox(
height: 3,
),
const Text(
'All Projects',
style: TextStyle(
color: Colors.black,
fontSize: 10,
),
),
],
),
),
),
),
],
),
),
);
}
}
@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
// ignore: must_be_immutable
class ListtextItemWidget extends StatelessWidget {
ListtextItemWidget();
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Lorem ipsum",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold16,
),
Padding(
padding: getPadding(
top: 10,
),
child: Text(
"Lorem ipsum",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyRegular14,
),
),
],
),
Padding(
padding: getPadding(
top: 11,
bottom: 13,
),
child: Text(
"7.5",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold18,
),
),
],
);
}
}
@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
class LocalSplashScreenComponent extends StatelessWidget {
const LocalSplashScreenComponent({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff2f73b9),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/hadwin_system/hadwin-splash-screen-logo.png',
height: 128.0,
),
],
),
);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,88 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
class NotificationItem extends StatelessWidget {
final Map<String, dynamic> notification;
const NotificationItem({required this.notification});
@override
Widget build(BuildContext context) {
final notificationText = notification['notification'] as String;
final time = notification['time'] as String;
final timeDifference = calculateTimeDifference(time);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
// Text(
// notificationText,
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.left,
// style: AppStyle.txtGilroySemiBold16,
// ),
Padding(
padding: getPadding(
top: 10,
),
child: Text(
notificationText,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyRegular14,
),
),
],
),
Padding(
padding: getPadding(
top: 11,
bottom: 13,
),
child: Text(
timeDifference,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold18,
),
),
],
);
ListTile(
title: Text(notificationText),
subtitle: Text(timeDifference),
);
}
String calculateTimeDifference(String time) {
final currentTime = DateTime.now();
final notificationTime = DateTime.parse(time);
final difference = currentTime.difference(notificationTime);
if (difference.inDays >= 365) {
final years = (difference.inDays / 365).floor();
return '${years} ${years == 1 ? 'year' : 'years'} ago';
} else if (difference.inDays >= 30) {
final months = (difference.inDays / 30).floor();
return '${months} ${months == 1 ? 'month' : 'months'} ago';
} else if (difference.inDays > 0) {
return '${difference.inDays} ${difference.inDays == 1 ? 'day' : 'days'} ago';
} else if (difference.inHours > 0) {
return '${difference.inHours} ${difference.inHours == 1 ? 'hour' : 'hours'} ago';
} else {
return 'Just now';
}
}
}
@@ -0,0 +1,993 @@
import 'package:intl/intl.dart';
import '../../Entity/gaurav/Gauravtest1/Gauravtest1_entity_list_screen.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(
'Gauravtest1',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
gauravtest1_entity_list_screen(), //go to get all entity
),
);
// Add your logic for menu 2 here
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'gtest',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => gauravtest1_entity_list_screen(),
),
);
},
),
PopupMenuItem<String>(
//value: 'Option 1',
child: Text(
'LogOut',
style: AppStyle.txtGilroySemiBold16,
),
onTap: () {
_logoutUser();
},
),
],
),
],
),
backgroundColor: const Color(0xfffefefe),
extendBodyBehindAppBar: true,
//bottomNavigationBar: AppFooter(),
body: screens.isEmpty
? const Text("Loading...")
: ListView.builder(
itemCount: screens.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) => screens[index],
),
),
);
}
Future<void> _logoutUser() async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
// Remove 'userData' and 'isLoggedIn' from SharedPreferences
await prefs.remove('userData');
await prefs.remove('isLoggedIn');
String logouturl = "${ApiConstants.baseUrl}/token/logout";
var response = await http.get(Uri.parse(logouturl));
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode <= 209) {
// ignore: use_build_context_synchronously
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => const LoginScreen()),
(route) => false, // Remove all routes from the stack
);
} else {
const Text('failed to logout');
}
} catch (error) {
print('Error occurred during logout: $error');
}
}
Widget googleNavBar() {
return Container(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6.18, vertical: 1),
child: GNav(
haptic: false,
gap: 6,
activeColor: const Color(0xFF0070BA),
iconSize: 24,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 11),
duration: const Duration(milliseconds: 300),
color: const Color(0xFF243656),
tabs: [
GButton(
icon: FluentIcons.home_32_regular,
iconSize: 36,
text: 'Home',
onPressed: () {
print('home');
},
),
GButton(
icon: FluentIcons.people_32_regular,
iconSize: 36,
text: 'Contacts',
onPressed: () {
print('contacts');
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => AllContactsScreen(
// setTab: setTab,
// ),
// ),
// );
},
),
GButton(
icon: Icons.wallet,
text: 'Wallet',
iconSize: 34,
onPressed: () {
print('wallet');
},
),
],
selectedIndex: _currentTab,
onTabChange: _onTabChange,
),
),
);
}
void _onTabChange(int index) {
if (_currentTab == 1 || _currentTab == 2) {
FocusManager.instance.primaryFocus?.unfocus();
}
Provider.of<TabNavigationProvider>(context, listen: false)
.updateTabs(_currentTab);
setState(() {
_currentTab = index;
});
}
Future<bool> _onBackPress() {
if (_currentTab == 0) {
return Future.value(true);
} else {
int lastTab =
Provider.of<TabNavigationProvider>(context, listen: false).lastTab;
Provider.of<TabNavigationProvider>(context, listen: false)
.removeLastTab();
setTab(lastTab);
}
return Future.value(false);
}
}
class StaticChartsScreen extends StatefulWidget {
final Map<String, dynamic> userData;
const StaticChartsScreen({required this.userData, Key? key})
: super(key: key);
@override
_StaticChartsScreenState createState() => _StaticChartsScreenState();
}
class _StaticChartsScreenState extends State<StaticChartsScreen> {
int myProjectcount = 0;
int sharedWithMeCount = 0;
int allprojectCount = 0;
@override
void initState() {
super.initState();
fetchData();
}
Future<void> fetchData() async {
print("working");
final token = await TokenManager.getToken();
print(token);
String baseUrl = ApiConstants.baseUrl;
var myProjectcountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_myproject'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
var sharedWithMeCountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_sharedwithme'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
var allProjectsCountres = await http.get(
Uri.parse('$baseUrl/workspace/secworkspaceuser/count_allproject'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type':
'application/json', // You may need to adjust the content type as needed
},
);
if (myProjectcountres.statusCode == 401) {
LogoutService.logout();
}
print(myProjectcountres.statusCode);
if (myProjectcountres.statusCode <= 209 &&
sharedWithMeCountres.statusCode <= 209) {
final myProjectData = jsonDecode(myProjectcountres.body);
final sharedData = jsonDecode(sharedWithMeCountres.body);
final allData = jsonDecode(allProjectsCountres.body);
setState(() {
myProjectcount = myProjectData;
sharedWithMeCount = sharedData;
allprojectCount = allData;
});
} else {
// Handle errors
print('Failed to fetch data');
}
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "myproject"), // Get all projects
// ),
// );
print('test1');
},
child: Card(
color: Colors.white,
elevation: 5.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
myProjectcount.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 12,
),
),
const Text(
'Test1',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
],
),
),
),
),
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "sharedproject"), // Get all projects
// ),
// );
print('test2');
},
child: Card(
color: Colors.white,
elevation: 5.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
sharedWithMeCount.toString(),
style: const TextStyle(
fontSize: 12,
),
),
const Text(
'Test2',
style: TextStyle(
fontSize: 12,
),
),
],
),
),
),
),
GestureDetector(
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => ProjectListScreen(
// userData: widget.userData,
// type: "allproject"), // Get all projects
// ),
// );
print('test3');
},
child: Card(
color: Colors.white,
elevation: 5.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
allprojectCount.toString(),
style: const TextStyle(
fontSize: 12,
),
),
const Text(
'Test3',
style: TextStyle(
fontSize: 12,
),
),
],
),
),
),
),
],
);
}
}
class HomeDashboardScreen extends StatelessWidget {
final Map<String, dynamic> userData;
const HomeDashboardScreen({super.key, required this.userData});
@override
Widget build(BuildContext context) {
var firstName = userData['firstName'].toString();
return Container(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Card(
clipBehavior: Clip.antiAlias,
elevation: 0,
margin: getMargin(top: 5),
color: ColorConstant.whiteA70099,
shape: RoundedRectangleBorder(
borderRadius: BorderRadiusStyle.roundedBorder6),
child: Container(
height: getVerticalSize(224),
width:
MediaQuery.of(context).size.width, //getHorizontalSize(396),
// padding: getPadding(
// left: 16, top: 17, right: 16, bottom: 17),
decoration: AppDecoration.outlineGray70026
.copyWith(borderRadius: BorderRadiusStyle.roundedBorder6),
child: Stack(alignment: Alignment.centerRight, children: [
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: getPadding(left: 1),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("08",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding:
getPadding(top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness: getVerticalSize(1),
color:
ColorConstant.blueGray400,
indent: getHorizontalSize(9))))
]),
Padding(
padding: getPadding(top: 28),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text("06",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding: getPadding(
top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness:
getVerticalSize(1),
color: ColorConstant
.blueGray400,
indent:
getHorizontalSize(9))))
])),
Padding(
padding: getPadding(top: 28),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text("04",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding: getPadding(
top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness:
getVerticalSize(1),
color: ColorConstant
.blueGray400,
indent:
getHorizontalSize(9))))
])),
Padding(
padding: getPadding(top: 28),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text("02",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding: getPadding(
top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness:
getVerticalSize(1),
color: ColorConstant
.blueGray400,
indent:
getHorizontalSize(10))))
])),
Padding(
padding: getPadding(top: 28),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text("00",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10),
Expanded(
child: Padding(
padding: getPadding(
top: 6, bottom: 5),
child: Divider(
height: getVerticalSize(1),
thickness:
getVerticalSize(1),
color: ColorConstant
.blueGray400,
indent:
getHorizontalSize(9))))
]))
]))),
Align(
alignment: Alignment.centerRight,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
buildContainer(
height: 97,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(top: 45),
text: "08/21"),
buildContainer(
height: 138,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 23, top: 19),
text: "08/22"),
buildContainer(
height: 160,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 21, top: 5),
text: "08/23"),
buildContainer(
height: 83,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 21, top: 53),
text: "08/24"),
buildContainer(
height: 64,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 20, top: 65),
text: "08/25"),
buildContainer(
height: 126,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 21, top: 26),
text: "08/26"),
buildContainer(
height: 83,
width: MediaQuery.of(context).size.width * 0.016,
margin: const EdgeInsets.only(left: 22, top: 53),
text: "08/27"),
],
),
)
]))),
));
// );
}
Widget buildContainer(
{required double height,
required double width,
required EdgeInsets margin,
required String text}) {
return Container(
width: getHorizontalSize(width),
margin: margin,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: getVerticalSize(height),
decoration: BoxDecoration(
color: ColorConstant.blueA700,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(getHorizontalSize(4)),
topRight: Radius.circular(getHorizontalSize(4)),
),
),
),
Padding(
padding: getPadding(top: 9),
child: Text(
text,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium10,
),
),
],
),
);
}
}
class NotificationItem extends StatelessWidget {
final Map<String, dynamic> notification;
const NotificationItem({required this.notification});
@override
Widget build(BuildContext context) {
final notificationText = notification['notification'] as String;
final time = notification['time'] as String;
final timeDifference = calculateTimeDifference(time);
return ListTile(
title: Text(
notificationText,
style: TextStyle(fontSize: 12, color: Colors.grey[800]),
),
subtitle: Text(timeDifference),
);
}
String calculateTimeDifference(String time) {
final currentTime = DateTime.now();
final formatter = DateFormat('yyyy/MM/dd HH:mm:ss');
final notificationTime = formatter.parse(time);
final difference = currentTime.difference(notificationTime);
if (difference.inDays >= 365) {
final years = (difference.inDays / 365).floor();
return '${years} ${years == 1 ? 'year' : 'years'} ago';
} else if (difference.inDays >= 30) {
final months = (difference.inDays / 30).floor();
return '${months} ${months == 1 ? 'month' : 'months'} ago';
} else if (difference.inDays > 0) {
return '${difference.inDays} ${difference.inDays == 1 ? 'day' : 'days'} ago';
} else if (difference.inHours > 0) {
return '${difference.inHours} ${difference.inHours == 1 ? 'hour' : 'hours'} ago';
} else {
return 'Just now';
}
}
}
@@ -0,0 +1,524 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../Login Screen/login_screen.dart';
import '../LogoutService/Logoutservice.dart';
import 'apiserviceprofilemanagement.dart';
import 'package:http/http.dart' as http;
import 'changepassword.dart';
class ProfileSettingsScreen extends StatefulWidget {
final Map<String, dynamic> userData;
ProfileSettingsScreen({required this.userData});
@override
_ProfileSettingsScreenState createState() => _ProfileSettingsScreenState();
}
class _ProfileSettingsScreenState extends State<ProfileSettingsScreen> {
ApiServiceProfileManagement apiService = ApiServiceProfileManagement();
String? fetchedimageurl =
'http://43.205.154.152:30165/assets/images/profile-icon.png';
Uint8List? _imageBytes; // Uint8List to store the image data
String? _imageFileName;
final _formKey = GlobalKey<FormState>();
TextEditingController fullNameController = TextEditingController();
TextEditingController pronounsController = TextEditingController();
TextEditingController roleController = TextEditingController();
TextEditingController departmentController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController aboutMeController = TextEditingController();
@override
void initState() {
super.initState();
//fetchProfileImageData();
fetchUserProfileData();
}
Future<void> _uploadImageFile() async {
final imagePicker = ImagePicker();
try {
final pickedImage =
await imagePicker.pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
final imageBytes = await pickedImage.readAsBytes();
setState(() {
_imageBytes = imageBytes;
_imageFileName = pickedImage.name; // Store the file name
});
}
} catch (e) {
print(e);
}
}
//api/user-profile
Future<void> fetchUserProfileData() async {
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/user-profile';
try {
final response = await http.get(
Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
},
);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode >= 200 && response.statusCode <= 209) {
final Map<String, dynamic> jsonData = json.decode(response.body);
setState(() {
fullNameController.text =
jsonData['fullName'] != null ? jsonData['fullName'] : '';
pronounsController.text =
jsonData['pronouns'] != null ? jsonData['pronouns'] : '';
roleController.text =
jsonData['role'] != null ? jsonData['role'] : '';
departmentController.text =
jsonData['department'] != null ? jsonData['department'] : '';
emailController.text =
jsonData['email'] != null ? jsonData['email'] : '';
aboutMeController.text =
jsonData['about'] != null ? jsonData['about'] : '';
});
} else {
throw Exception('Failed to load data: ${response.statusCode}');
}
} catch (e) {
throw Exception('Failed to load data: $e');
}
}
Future<void> fetchProfileImageData() async {
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/retrieve-image';
try {
final response = await http.get(
Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
},
);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode >= 200 && response.statusCode <= 209) {
final Map<String, dynamic> jsonData = json.decode(response.body);
final trustedImageUrl = Uri.dataFromString(jsonData['image'],
mimeType: 'image/*', encoding: Encoding.getByName('utf-8'))
.toString();
fetchedimageurl = trustedImageUrl;
} else {
throw Exception('Failed to load data: ${response.statusCode}');
}
} catch (e) {
throw Exception('Failed to load data: $e');
}
}
Future<void> _submitImage() async {
if (_imageBytes == null) {
// Show an error message if no image is selected
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Please select an image.'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
return;
}
if (_imageFileName == null) {
// Handle the case where _imageFileName is null (no file name provided)
print('File name is missing.');
return;
}
try {
final token = await TokenManager.getToken();
await apiService.createFile(_imageBytes!, _imageFileName!, token!);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to upload image: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
Future<void> _updateProfile() async {
if (_formKey.currentState!.validate()) {
// Create a JSON object with the form data
final profileData = {
'fullName': fullNameController.text,
'pronouns': pronounsController.text,
'role': roleController.text,
'department': departmentController.text,
'email': emailController.text,
'aboutMe': aboutMeController.text,
};
//api/user-profile
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/user-profile';
try {
final response = await http.put(Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
body: json.encode(profileData));
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode <= 209) {
print("success");
Navigator.of(context).pop();
} else {
print(response.statusCode);
}
} catch (e) {
throw Exception('Failed to Update: $e');
}
}
}
Future<void> _logoutUser() async {
try {
String logouturl = "${ApiConstants.baseUrl}/token/logout";
var response = await http.get(Uri.parse(logouturl));
if (response.statusCode <= 209) {
// ignore: use_build_context_synchronously
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
(route) => false, // Remove all routes from the stack
);
} else {
const Text('failed to logout');
}
} catch (error) {
print('Error occurred during logout: $error');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "My Profile Settings")),
body: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
// Section: Show Profile Photo
Center(
child: Column(
children: [
CircleAvatar(
radius: 70, // Adjust as needed
backgroundImage: NetworkImage(
"$fetchedimageurl"), // Replace with your API URL
),
SizedBox(height: 10),
CustomButton(
height: getVerticalSize(50),
text: _imageBytes == null
? "Pick a Profile Photo"
: 'Upload Success',
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
if (_imageBytes != null) {
_submitImage();
} else {
_uploadImageFile();
}
},
),
],
),
),
SizedBox(height: 20),
// Section: Profile Form
Text(
'Your Profile Information',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Form(
key: _formKey,
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Your Full Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
controller: fullNameController,
hintText: "Enter Full Name",
validator: (value) {
if (value!.isEmpty) {
return 'Please enter your full name';
}
return null;
},
onChanged: (value) {
fullNameController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Pronouns",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Pronouns",
controller: pronounsController,
onChanged: (value) {
pronounsController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Role",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Role",
controller: roleController,
onChanged: (value) {
roleController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Department or Team",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Department or Team",
controller: departmentController,
onChanged: (value) {
departmentController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Email",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Email",
controller: emailController,
validator: (value) {
if (value!.isEmpty || !value!.contains('@')) {
return 'Please enter a valid email address';
}
return null;
},
onChanged: (value) {
emailController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("About Me",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "About Me",
controller: aboutMeController,
maxLines: 3,
onChanged: (value) {
aboutMeController.text = value;
},
margin: getMargin(top: 6))
])),
CustomButton(
height: getVerticalSize(50),
text: "Update Profile",
margin: getMargin(top: 24, bottom: 5),
onTap: _updateProfile,
),
],
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResetPasswordScreen(
userData: widget.userData,
userEmail: emailController.text,
), //go to get all entity
),
);
},
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
"Password:Change Password for your account Change password",
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.blue,
),
),
],
),
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () {
print("change password");
},
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'Security:Logout of all sessions except this current browser Logout other sessions',
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.blue,
),
),
],
),
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () {
_logoutUser();
},
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'Deactivation:Remove access to all organizations and workspace in cloudnsure Deactivate account',
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.blue,
),
),
],
),
),
),
SizedBox(height: 20),
],
),
),
);
}
}
+46
View File
@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
class AboutScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "About Us")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'About Us',
style: AppStyle.txtGilroyBold18Bluegray900,
),
const SizedBox(height: 20),
Text(
'Create a new project if you have access, if you don\'t have access, then contact the admin.',
textAlign: TextAlign.center,
style: AppStyle.txtGilroyBold16BlueA700,
),
],
),
),
);
}
}
@@ -0,0 +1,57 @@
import 'dart:typed_data';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:dio/dio.dart';
import '../../resources/api_constants.dart';
class ApiServiceProfileManagement {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
Future<void> createFile(
Uint8List fileBytes, String fileName, String token) async {
try {
String apiUrl = "$baseUrl/api/upload";
final mimeType = 'image/jpeg'; // You can set the appropriate MIME type
FormData formData = FormData.fromMap({
'imageFile': MultipartFile.fromBytes(
fileBytes,
filename: fileName,
contentType: MediaType.parse(mimeType),
),
});
Dio dio = Dio(); // Create a new Dio instance
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.post(apiUrl, data: formData);
if (response.statusCode == 200) {
// Handle successful response
print('File uploaded successfully');
} else {
print('Failed to upload file with status: ${response.statusCode}');
}
} catch (error) {
print('Error occurred during form submission: $error');
}
}
String lookupMimeType(String filePath) {
final ext = filePath.split('.').last;
switch (ext) {
case 'jpg':
case 'jpeg':
return 'image/jpeg';
case 'png':
return 'image/png';
case 'pdf':
return 'application/pdf';
// Add more cases for other file types as needed
default:
return 'application/octet-stream'; // Default MIME type
}
}
}
@@ -0,0 +1,318 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import 'package:http/http.dart' as http;
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../Login Screen/login_screen.dart';
import '../LogoutService/Logoutservice.dart';
class ResetPasswordScreen extends StatelessWidget {
final String userEmail;
final Map<String, dynamic> userData;
ResetPasswordScreen({required this.userEmail,required this.userData});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:
CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Reset Password")),
body: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
"You're signed in as $userEmail",
style: AppStyle.txtGilroyMedium16Bluegray800
),
const SizedBox(height: 20),
ResetPasswordForm(userData: userData,userEmail: userEmail),
const SizedBox(height: 20),
GestureDetector(
onTap: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => const LoginScreen()),
(route) => false, // Remove all routes from the stack
);
},
child: Text(
'Wrong account? Log in instead.',
style: AppStyle.txtGreenSemiBold16,
),
),
],
),
),
);
}
}
class ResetPasswordForm extends StatefulWidget {
final String userEmail;
final Map<String, dynamic> userData;
const ResetPasswordForm({super.key, required this.userEmail,required this.userData});
@override
_ResetPasswordFormState createState() => _ResetPasswordFormState();
}
class _ResetPasswordFormState extends State<ResetPasswordForm> {
final TextEditingController oldPasswordController = TextEditingController();
final TextEditingController newPasswordController = TextEditingController();
final TextEditingController reEnterNewPasswordController =
TextEditingController();
var responseMessage;
var isVisible=false;
bool issuccess = false;
bool isOldPasswordVisible = false;
bool isNewPasswordVisible = false;
bool isReEnterNewPasswordVisible = false;
bool _isPasswordValid1 = true;
void _validatePassword1(String password) {
setState(() {
_isPasswordValid1 = password.isNotEmpty;
});
}
bool _isPasswordValid2 = true;
void _validatePassword2(String password) {
setState(() {
_isPasswordValid2 = password.isNotEmpty;
});
}
bool _isPasswordValid3 = true;
void _validatePassword3(String password) {
setState(() {
_isPasswordValid3 = password.isNotEmpty&&password==newPasswordController.text;
});
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
isVisible?Text(responseMessage,style: TextStyle(
color: issuccess?Colors.green:Colors.red, // Set the text color to red
)):const Text(''),
Padding(
padding: getPadding(top: 19),
child: Text("Enter Old Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
controller: oldPasswordController,
hintText: "Enter Old Password",
margin: getMargin(top: 6),
errorText:
_isPasswordValid1 ? null : 'Please enter your old password',
padding: TextFormFieldPadding.PaddingT12,
textInputAction: TextInputAction.done,
onChanged: _validatePassword1,
validator: (value) {
if (value!.isEmpty) {
return 'Please enter your old password';
}
return null; // Return null to indicate no error
},
textInputType:TextInputType.visiblePassword,
suffix: IconButton(
icon: Icon(
isOldPasswordVisible ? Icons.visibility : Icons.visibility_off,
),
onPressed: () {
setState(() {
isOldPasswordVisible = !isOldPasswordVisible;
});
},
),
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText: !isOldPasswordVisible),
Padding(
padding: getPadding(top: 19),
child: Text("Enter New Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
controller: newPasswordController,
hintText: "Enter New Password",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputAction: TextInputAction.done,
suffix: IconButton(
icon: Icon(
isNewPasswordVisible ? Icons.visibility : Icons.visibility_off,
),
onPressed: () {
setState(() {
isNewPasswordVisible = !isNewPasswordVisible;
});
},
),
errorText:
_isPasswordValid2 ? null : 'Please enter your new password',
onChanged: _validatePassword2,
validator: (value) {
if (value!.isEmpty) {
return 'Please enter your new password';
}
return null;
},
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText:!isNewPasswordVisible,),
Padding(
padding: getPadding(top: 19),
child: Text("Re-Enter New Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
controller: reEnterNewPasswordController,
hintText: "Re-Enter New Password",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
onChanged: _validatePassword3,
validator: (value) {
if (value!.isEmpty) {
return 'Please re-enter your new password';
}
if (value != newPasswordController.text) {
return 'Passwords do not match';
}
return null;
},
suffix: IconButton(
icon: Icon(
isReEnterNewPasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
isReEnterNewPasswordVisible = !isReEnterNewPasswordVisible;
});
},
),
errorText:
_isPasswordValid3 ? null : 'Please re-enter your new password',
textInputAction: TextInputAction.done,
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText:!isReEnterNewPasswordVisible,),
CustomButton(
height: getVerticalSize(50),
text: "Continue",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
if (oldPasswordController.text.isEmpty ||
newPasswordController.text.isEmpty ||
reEnterNewPasswordController.text.isEmpty) {
print(oldPasswordController.text);
print(newPasswordController.text);
print(reEnterNewPasswordController.text);
} else {
Map<String, dynamic> passwordData = {
"userId":widget.userData['userId'],
"oldPassword": oldPasswordController.text,
"newPassword": newPasswordController.text,
"confirmPassword": reEnterNewPasswordController.text,
};
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/reset_password';
try {
final response = await http.post(Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
body: json.encode(passwordData));
if(response.statusCode==401){
LogoutService.logout();
}
if (response.statusCode <= 209) {
setState(() {
isVisible=true;
issuccess=true;
responseMessage = "Password Changes Successfully";
});
print("success");
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
(route) => false,
);
} else {
setState(() {
isVisible=true;
responseMessage = "Incorrect Password";
});
print(response.statusCode);
}
} catch (e) {
throw Exception('Failed to Update: $e');
}
}
},
),
],
);
}
@override
void dispose() {
oldPasswordController.dispose();
newPasswordController.dispose();
reEnterNewPasswordController.dispose();
super.dispose();
}
}
@@ -0,0 +1,102 @@
import 'package:fade_shimmer/fade_shimmer.dart';
import 'package:flutter/material.dart';
Widget _creditsloadingTile(BuildContext context) {
List<Widget> socialLinks = List.generate(
6,
(index) => Container(
child: const FadeShimmer(
radius: 16.18,
height: 48,
width: 48,
fadeTheme: FadeTheme.light,
),
padding: const EdgeInsets.all(2),
),
);
return Container(
width: MediaQuery.of(context).size.width - 10,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.blueGrey.shade100.withOpacity(0.1618),
borderRadius: const BorderRadius.all(Radius.circular(16.18))),
margin: const EdgeInsets.symmetric(vertical: 3, horizontal: 6.18),
child: Wrap(
direction: Axis.vertical,
children: [
Container(
width: MediaQuery.of(context).size.width - 48,
padding: const EdgeInsets.all(6.18),
child: Wrap(
alignment: WrapAlignment.spaceBetween,
children: [
Wrap(direction: Axis.vertical, children: [
Container(
child: const FadeShimmer(
radius: 16.18,
height: 27,
width: 96,
fadeTheme: FadeTheme.light,
),
padding: const EdgeInsets.all(2),
),
Container(
child: const FadeShimmer(
radius: 16.18,
height: 20,
width: 72,
fadeTheme: FadeTheme.light,
),
padding: const EdgeInsets.all(2),
),
]),
Container(
child: const FadeShimmer(
radius: 16.18,
height: 64,
width: 64,
fadeTheme: FadeTheme.light,
),
),
],
),
),
Container(
child: const FadeShimmer(
radius: 16.18,
height: 16,
width: 96,
fadeTheme: FadeTheme.light,
),
padding: const EdgeInsets.all(2),
),
Container(
height: 72,
width: MediaQuery.of(context).size.width - 48,
padding: const EdgeInsets.all(0),
color: Colors.transparent,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (_, index) => socialLinks[index],
separatorBuilder: (_, b) => const SizedBox(
width: 16.18,
),
itemCount: socialLinks.length),
)
],
),
);
}
Widget creditsLoadingList(int items, BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListView.builder(
padding: const EdgeInsets.all(0),
itemBuilder: (_, index) => Padding(
padding: const EdgeInsets.all(5),
child: _creditsloadingTile(context)),
itemCount: items,
),
);
}
Binary file not shown.
@@ -0,0 +1,263 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import 'SignUpService.dart';
class CreateAccountScreen extends StatefulWidget {
CreateAccountScreen({Key? key}) : super(key: key);
@override
_CreateAccountScreenState createState() => _CreateAccountScreenState();
}
class _CreateAccountScreenState extends State<CreateAccountScreen> {
final SignUpApiService userService = SignUpApiService();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
late BuildContext _context; // Store the current context
late var account_id; // Store the account_id
bool _isEmailValid = true;
void _validateEmail(String email) {
setState(() {
_isEmailValid =
RegExp(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$').hasMatch(email);
});
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
_context = context; // Store the context
return Scaffold(
appBar: AppBar(title: const Text('Create Account')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Text("Company Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['companyName'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Company Name';
}
return null;
},
hintText: "enter Company Name",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Email",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['email'] = value,
onChanged: _validateEmail,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Email';
}else if(!_isEmailValid){
return 'Please enter a valid email';
}
return null;
},
hintText: "enter Email",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Mobile Number",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
textInputType: TextInputType.phone,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))
],
onsaved: (value) => formData['mobile'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Mob No';
}
return null;
},
hintText: "enter Mobile Number",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
),
Padding(
padding: getPadding(top: 19),
child: Text("Workspace",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['workspace'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Workspace';
}
return null;
},
hintText: "enter Workspace",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Gst Number",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['gstNumber'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Gst Number';
}
return null;
},
hintText: "enter Gst Number",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("pancard",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['pancard'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Pancard';
}
return null;
},
hintText: "enter pancard",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Working",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['working'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Working';
}
return null;
},
hintText: "enter Working",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: CustomButton(
height: getVerticalSize(50),
width: getHorizontalSize(396),
text: "SUBMIT",
margin: getMargin(top: 25),
onTap: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
{
try {
print('form data is $formData');
final response =
await userService.createAccount(formData);
account_id = response['account_id'].toString();
print(
'after create account account id is $account_id');
// ignore: use_build_context_synchronously
Navigator.pop(
_context, account_id); // Pop with account_id
// Navigator.pop(context);
} catch (e) {
// ignore: use_build_context_synchronously
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Account Creation Failed: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}
},
),
),
],
),
),
),
),
);
}
}
+328
View File
@@ -0,0 +1,328 @@
import 'package:flutter/material.dart';
import 'SignUpService.dart';
class CreateUserScreen extends StatefulWidget {
CreateUserScreen({Key? key}) : super(key: key);
@override
_CreateUserScreenState createState() => _CreateUserScreenState();
}
class _CreateUserScreenState extends State<CreateUserScreen> {
int _currentStep = 0;
// Create a global key for each step
final GlobalKey<StepCreateAccountState> createAccountKey =
GlobalKey<StepCreateAccountState>();
final GlobalKey<StepGetEmailVerificationState> emailVerificationKey =
GlobalKey<StepGetEmailVerificationState>();
final GlobalKey<StepGetRegistrationState> registrationKey =
GlobalKey<StepGetRegistrationState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sign Up - Step ${_currentStep + 1}'),
),
body: Column(
children: [
// Display the current step
Expanded(
child: _buildStep(_currentStep),
),
// Navigation buttons
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (_currentStep > 0)
ElevatedButton(
onPressed: () {
setState(() {
_currentStep--;
});
},
child: const Text('Previous'),
),
if (_currentStep < 2)
ElevatedButton(
onPressed: () {
_proceedToNextStep();
},
child: const Text('Next'),
),
],
),
],
),
);
}
// Function to build the appropriate step based on the current step index
Widget _buildStep(int stepIndex) {
switch (stepIndex) {
case 0:
return StepCreateAccount(
key: createAccountKey,
onNext: () {
_proceedToNextStep();
},
);
case 1:
return StepGetEmailVerification(
key: emailVerificationKey,
onNext: () {
_proceedToNextStep();
},
);
case 2:
return StepGetRegistration(
key: registrationKey,
onNext: () {
_proceedToNextStep();
},
);
default:
return Container(); // Return an empty container by default
}
}
// Function to proceed to the next step
void _proceedToNextStep() {
if (_currentStep < 2) {
setState(() {
_currentStep++;
});
}
}
}
// Define your individual step widgets here
class StepCreateAccount extends StatefulWidget {
final Function onNext;
const StepCreateAccount({Key? key, required this.onNext}) : super(key: key);
@override
StepCreateAccountState createState() => StepCreateAccountState();
}
class StepCreateAccountState extends State<StepCreateAccount> {
// Add your state variables for this step here
String? accountId;
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
final SignUpApiService userService = SignUpApiService();
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Column(
children: [
const Text('Step 1: Create Account'),
TextFormField(
decoration: const InputDecoration(labelText: 'Company Name'),
onSaved: (value) => formData['companyName'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Company Name';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Email'),
onSaved: (value) => formData['email'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Email';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Mobile No'),
onSaved: (value) => formData['mobile'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Mob No';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Workspace'),
onSaved: (value) => formData['workspace'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Workspace';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Gst Number'),
onSaved: (value) => formData['gstNumber'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Gst Number';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'pancard'),
onSaved: (value) => formData['pancard'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Pancard';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(labelText: 'Working'),
onSaved: (value) => formData['working'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Working';
}
return null;
},
),
const SizedBox(height: 16),
Container(
margin: const EdgeInsets.symmetric(vertical: 5), // Add margin
child: ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
{
try {
print('form data is $formData');
final response =
await userService.createAccount(formData);
accountId = response['account_id'].toString();
print('after create account account id is $accountId');
// ignore: use_build_context_synchronously
// Navigator.pop(
// _context, accountId); // Pop with account_id
// Navigator.pop(context);
} catch (e) {
// ignore: use_build_context_synchronously
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Account Creation Failed: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}
},
child: const SizedBox(
width: double.infinity,
height: 50,
child: Center(
child: Text(
'SUBMIT',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
if (accountId != null) Text('Selected Account ID: $accountId'),
],
),
);
}
}
class StepGetEmailVerification extends StatefulWidget {
final Function onNext;
const StepGetEmailVerification({Key? key, required this.onNext})
: super(key: key);
@override
StepGetEmailVerificationState createState() =>
StepGetEmailVerificationState();
}
class StepGetEmailVerificationState extends State<StepGetEmailVerification> {
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Text('Step 2: Get Email Verification'),
);
}
}
class StepGetRegistration extends StatefulWidget {
final Function onNext;
const StepGetRegistration({Key? key, required this.onNext}) : super(key: key);
@override
StepGetRegistrationState createState() => StepGetRegistrationState();
}
class StepGetRegistrationState extends State<StepGetRegistration> {
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Text('Step 3: Get Registration'),
);
}
}
// Example of a dialog to create an account
class CreateAccountDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Create Account'),
content: Text('Account created successfully!'),
actions: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pop('12345'); // Pass the created account ID
},
child: Text('OK'),
),
],
);
}
}
@@ -0,0 +1,359 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../Login Screen/login_screen.dart';
import 'CreateAccount.dart';
import 'SignUpService.dart';
class RegistrationDetailsScreen extends StatefulWidget {
var email;
RegistrationDetailsScreen({required this.email});
@override
_RegistrationDetailsScreenState createState() =>
_RegistrationDetailsScreenState();
}
class _RegistrationDetailsScreenState extends State<RegistrationDetailsScreen> {
final SignUpApiService userService = SignUpApiService();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
late BuildContext _context; // Store the current context
var account_id = null; // Initialize with null
var selectedAccount; // Use nullable type
var newPassword = ''; // Store the value of the confirm password field
var confirmPassword = ''; // Store the value of the confirm password field
// Validate that the passwords match
String? _validatePasswordMatch(String value) {
if (value != newPassword) {
print('value is $value and new is $newPassword');
return 'Passwords do not match';
}
return null;
}
bool _newpasswordVisible = false;
bool _confirmpasswordVisible = false;
bool _isPasswordValid = true;
void _validatePassword(String password) {
setState(() {
_isPasswordValid = password.isNotEmpty;
});
}
bool _isEmailValid = true;
void _validateEmail(String email) {
setState(() {
_isEmailValid =
RegExp(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$').hasMatch(email);
});
}
void showSuccessMessage(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
duration: const Duration(seconds: 2),
backgroundColor: Colors.green,
),
);
}
void showErrorMessage(String error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(error),
duration: const Duration(seconds: 2),
backgroundColor: Colors.red,
),
);
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
_context = context; // Store the context
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(54),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleft,
margin: getMargin(left: 16, top: 13, bottom: 17),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Registration")),
//AppBar(title: const Text('Registration')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Container(
height: 500,
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Text("First Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['first_name'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter First Name';
}
return null;
},
hintText: "enter First Name",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Last Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
onsaved: (value) => formData['last_name'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Last Name';
}
return null;
},
hintText: "enter Last Name",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputType: TextInputType.text
),
Padding(
padding: getPadding(top: 19),
child: Text("Mobile Number",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
textInputType: TextInputType.phone,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))
],
onsaved: (value) => formData['mob_no'] = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Mobile Number';
}
return null;
},
hintText: "enter Mobile Number",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
),
Padding(
padding: getPadding(top: 19),
child: Text("New Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "New Password",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputAction: TextInputAction.done,
textInputType:TextInputType.visiblePassword,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Password';
}else if(!_isPasswordValid){
return 'Please enter a valid password';
}
return null;
},
suffix: IconButton(
icon: Icon(
_newpasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_newpasswordVisible = !_newpasswordVisible;
});
},
),
onsaved: (value) => formData['new_password'] = value,
onChanged: (value) {
setState(() {
newPassword = value!;
});
_validatePassword;
},
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText: !_newpasswordVisible),
Padding(
padding: getPadding(top: 19),
child: Text("Confirm Password",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium16Bluegray900)),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Confirm Password",
margin: getMargin(top: 6),
padding: TextFormFieldPadding.PaddingT12,
textInputAction: TextInputAction.done,
textInputType:TextInputType.visiblePassword,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Password';
}
return _validatePasswordMatch(confirmPassword);
},
onsaved: (value) => formData['confirm_password'] = value,
onChanged: (value) {
setState(() {
confirmPassword = value!; // Update confirmPassword
});
},
suffix: IconButton(
icon: Icon(
_confirmpasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_confirmpasswordVisible = !_confirmpasswordVisible;
});
},
),
suffixConstraints: BoxConstraints(
maxHeight: getVerticalSize(44)),
isObscureText: !_confirmpasswordVisible,),
Row(
children: [
const Expanded(
child: Text('Add Account'),
),
IconButton(
onPressed: () async {
final accountId = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CreateAccountScreen(),
),
);
if (accountId != null) {
setState(() {
selectedAccount = accountId;
formData['account_id'] = accountId;
account_id =
accountId; // Update the account_id here
});
}
},
icon: const Icon(Icons.add),
),
],
),
if (account_id != null)
Container(
margin:
const EdgeInsets.symmetric(vertical: 5), // Add margin
child: CustomButton(
height: getVerticalSize(50),
width: getHorizontalSize(396),
text: "SUBMIT",
margin: getMargin(top: 25),
onTap: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
print('formdata is $formData');
formData['usrGrpId'] = 46;
formData['account_id'] = account_id;
formData['email'] = widget.email;
{
final token = await TokenManager.getToken();
try {
print(formData);
await userService
.createuser(token!, formData)
.then((_) => {
const LoginScreen(),
});
await Future.delayed(
const Duration(seconds: 5));
showSuccessMessage('User created successfully');
// ignore: use_build_context_synchronously
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const LoginScreen()));
// moveToNextStep();
} catch (e) {
showErrorMessage('Failed to create User: $e');
}
}
}
},
),
),
],
),
),
),
),
),
);
}
}
@@ -0,0 +1,113 @@
import 'package:dio/dio.dart';
import '../../resources/api_constants.dart';
class SignUpApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
// get all account
Future<List<Map<String, dynamic>>> getallAccount(String token) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/users/sysaccount/sysaccount');
final responseData = response.data;
print('response data is ... $responseData');
if (responseData is List) {
// If the response is a list, cast it to the expected type
final entities = responseData.cast<Map<String, dynamic>>();
return entities;
} else if (responseData is Map<String, dynamic>) {
// If the response is a single object, wrap it in a list
return [responseData];
} else {
// Handle other unexpected response types here
throw Exception('Unexpected response type');
}
} catch (e) {
throw Exception('Failed to Account: $e');
}
}
// Create account
Future<Map<String, dynamic>> createAccount(
Map<String, dynamic> entity) async {
try {
// dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio
.post('$baseUrl/token/users/sysaccount/savesysaccount', data: entity);
print(' created account is $response');
return response.data;
} catch (e) {
throw Exception('Failed To Create Account: $e');
}
}
// SEND EMAIL FOR OTP
Future<void> sendEmail(Map<String, dynamic> entity) async {
try {
print("in post api...$entity");
// dio.options.headers['Authorization'] = 'Bearer $token';
await dio.post('$baseUrl/token/user/send_email', data: entity);
print(entity);
} catch (e) {
throw Exception('Failed to Send Email: $e');
}
}
// RESEND EMAIL FOR OTP
Future<void> resendEmail(String email) async {
try {
// dio.options.headers['Authorization'] = 'Bearer $token';
await dio.post('$baseUrl/token/user/resend_otp?email=$email');
} catch (e) {
throw Exception('Failed to ReSend Email: $e');
}
}
// OTP VEFICATION
Future<void> otpverification(String email, String otp) async {
try {
// dio.options.headers['Authorization'] = 'Bearer $token';
await dio
.post('$baseUrl/token/user/otp_verification?email=$email&otp=$otp');
} catch (e) {
throw Exception('Failed to Verify Otp: $e');
}
}
Future<void> createuser(String token, Map<String, dynamic> entity) async {
try {
print("in post api...$entity");
dio.options.headers['Authorization'] = 'Bearer $token';
await dio.post('$baseUrl/token/addOneAppUser', data: entity);
print(entity);
} catch (e) {
throw Exception('Failed to create User: $e');
}
}
Future<void> updateUser(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
await dio.put('$baseUrl/api/updateAppUserDto/$entityId', data: entity);
print(entity);
} catch (e) {
throw Exception('Failed to update Backend: $e');
}
}
Future<void> deleteUser(String token, int entityId) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
await dio.delete('$baseUrl/api/delete_usr/$entityId');
} catch (e) {
throw Exception('Failed to delete User: $e');
}
}
}
+295
View File
@@ -0,0 +1,295 @@
// import 'package:flutter/material.dart';
//
// import 'package:flutter/services.dart';
//
// import 'RegistrationDetails.dart';
// import 'SignUpService.dart';
//
// enum RegistrationStep {
// SendOTP,
// VerifyOTP,
// EnterUserInfo,
// SelectAccount,
// }
//
// class SignUpUserScreen extends StatefulWidget {
// SignUpUserScreen({Key? key}) : super(key: key);
//
// @override
// _SignUpUserScreenState createState() => _SignUpUserScreenState();
// }
//
// class _SignUpUserScreenState extends State<SignUpUserScreen> {
// final SignUpApiService userService = SignUpApiService();
//
// final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
// final Map<String, dynamic> formData = {};
// final _formKey = GlobalKey<FormState>();
//
// var selectedAccount;
// var email;
// var otp;
// var confirmPassword;
//
// bool _passwordVisible = false;
// bool _isPasswordValid = true;
// void _validatePassword(String password) {
// setState(() {
// _isPasswordValid = password.isNotEmpty;
// });
// }
//
// RegistrationStep currentStep = RegistrationStep.SendOTP;
//
// void moveToNextStep() {
// setState(() {
// if (currentStep == RegistrationStep.SendOTP) {
// currentStep = RegistrationStep.VerifyOTP;
// } else if (currentStep == RegistrationStep.VerifyOTP) {
// currentStep = RegistrationStep.EnterUserInfo;
// } else if (currentStep == RegistrationStep.EnterUserInfo) {
// currentStep = RegistrationStep.SelectAccount;
// }
// });
// }
//
// void showSuccessMessage(String message) {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(message),
// duration: const Duration(seconds: 2),
// backgroundColor: Colors.green,
// ),
// );
// }
//
// void showErrorMessage(String error) {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(error),
// duration: const Duration(seconds: 2),
// backgroundColor: Colors.red,
// ),
// );
// }
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// key: _scaffoldKey,
// appBar: AppBar(
// title: const Text('Create User'),
// ),
// body: Builder(
// builder: (BuildContext context) {
// return SingleChildScrollView(
// child: Padding(
// padding: const EdgeInsets.all(16),
// child: Form(
// key: _formKey,
// child: SizedBox(
// height: MediaQuery.of(context).size.height *
// 0.5, // Use 50% of the screen height
// child: ListView.builder(
// itemCount: 1,
// itemBuilder: (BuildContext context, int index) {
// if (currentStep == RegistrationStep.SendOTP) {
// return Column(
// children: [
// const SizedBox(height: 16),
// TextFormField(
// decoration:
// const InputDecoration(labelText: 'Email'),
// keyboardType: TextInputType.emailAddress,
// onSaved: (value) => email = value,
// validator: (value) {
// if (value == null || value.isEmpty) {
// return 'Please enter Email';
// }
// return null;
// },
// ),
// const SizedBox(height: 16),
// Container(
// margin: const EdgeInsets.symmetric(vertical: 5),
// child: ElevatedButton(
// onPressed: () async {
// if (_formKey.currentState!.validate()) {
// _formKey.currentState!.save();
//
// formData['usrGrpId'] = 46;
// formData['email'] = email;
// try {
// print('send email data is $formData');
//
// await userService.sendEmail(formData);
//
// await Future.delayed(
// const Duration(seconds: 2));
//
// moveToNextStep();
// } catch (e) {
// showErrorMessage(
// 'Failed to send OTP: $e');
// }
// }
// },
// child: const SizedBox(
// width: double.infinity,
// height: 50,
// child: Center(
// child: Text(
// 'Send OTP',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ),
// ),
// ],
// );
// } else if (currentStep == RegistrationStep.VerifyOTP) {
// return Column(
// children: [
// const SizedBox(height: 16),
// TextFormField(
// decoration:
// const InputDecoration(labelText: 'Email'),
// initialValue: email,
// readOnly: true,
// ),
// const SizedBox(height: 16),
// Row(
// children: [
// Container(
// height: 100,
// width: 250,
// padding: const EdgeInsets.symmetric(
// horizontal: 16),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
// border: Border.all(color: Colors.grey),
// ),
// child: TextFormField(
// decoration:
// const InputDecoration(labelText: 'OTP'),
// onChanged: (value) {
// otp = value;
// },
// onSaved: (value) => otp = value,
// validator: (value) {
// if (value == null || value.isEmpty) {
// return 'Please enter OTP';
// }
// return null;
// },
// ),
// ),
// ElevatedButton(
// onPressed: () async {
// try {
// await userService.resendEmail(email);
//
// await Future.delayed(
// const Duration(seconds: 5));
// showSuccessMessage('OTP RESEND');
// } catch (e) {
// showErrorMessage(
// 'Failed to resend OTP: $e');
// }
// },
// child: const SizedBox(
// width: 100,
// height: 50,
// child: Center(
// child: Text(
// 'Resend OTP',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ),
// ],
// ),
// const SizedBox(height: 16),
// ElevatedButton(
// onPressed: () async {
// try {
// print('email is $email and otp is $otp');
// await userService.otpverification(email, otp);
//
// moveToNextStep();
// showSuccessMessage(
// 'Email verified successfully');
// } catch (e) {
// showErrorMessage('Failed to verify OTP: $e');
// }
// },
// child: const SizedBox(
// width: double.infinity,
// height: 50,
// child: Center(
// child: Text(
// 'VERIFY EMAIL',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ),
// ],
// );
// } else if (currentStep ==
// RegistrationStep.EnterUserInfo) {
// return Column(
// children: [
// // Other widgets for user information entry
// ElevatedButton(
// onPressed: () async {
// // Navigate to the RegistrationDetailsScreen when the button is pressed
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) =>
// RegistrationDetailsScreen(email: email),
// ),
// );
// },
// child: const SizedBox(
// width: double.infinity,
// height: 50,
// child: Center(
// child: Text(
// 'Go to Registration Details',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ),
// ],
// );
// } else {
// return Container(); // Return an empty container if none of the conditions match
// }
// },
// ),
// ),
// ),
// ),
// );
// },
// ),
// );
// }
// }
@@ -0,0 +1,138 @@
import 'package:flutter/material.dart';
class StepGetEmailVerification extends StatefulWidget {
final LabeledGlobalKey<FormState> emailPasswordFormKey;
// final Function updateSignUpDetails;
// final String email;
final Function proceedToNextStep;
const StepGetEmailVerification(
{Key? key,
// required this.updateSignUpDetails,
// required this.email,
required this.emailPasswordFormKey,
required this.proceedToNextStep})
: super(key: key);
@override
_StepGetEmailVerificationState createState() =>
_StepGetEmailVerificationState();
}
class _StepGetEmailVerificationState extends State<StepGetEmailVerification> {
String email = "";
String emailErrorMessage = "";
@override
void initState() {
super.initState();
// email = widget.email;
}
@override
void dispose() {
// widget.emailPasswordFormKey.currentState?.validate();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Form(
key: widget.emailPasswordFormKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
// initialValue: email,
// validator: _validateNewPassword,
autofocus: mounted,
autocorrect: false,
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "email",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
keyboardType: TextInputType.name,
textInputAction: TextInputAction.next,
),
),
if (emailErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
width: double.infinity,
child: Text(
"\t\t\t\t$emailErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// Email CODE END HERE
],
));
}
// void errorMessageSetter(String fieldName, String message) {
// setState(() {
// switch (fieldName) {
// case 'NEW-PASSWORD':
// new_passwordErrorMessage = message;
// break;
// case 'CONFIRM-PASSWORD':
// confirm_passwordErrorMessage = message;
// break;
// }
// });
// }
// String? _validateNewPassword(String? value) {
// if (value == null || value.isEmpty) {
// errorMessageSetter('NEW-PASSWORD', 'password cannot be empty');
// } else {
// errorMessageSetter('NEW-PASSWORD', "");
// widget.updateSignUpDetails('new_password', value);
// }
// return null;
// }
// String? _validateConfirmpassword(String? value) {
// if (value == null || value.isEmpty) {
// errorMessageSetter(
// 'CONFIRM-PASSWORD', 'you must provide a valid confirm-password');
// } else {
// errorMessageSetter('CONFIRM-PASSWORD', "");
// widget.updateSignUpDetails('confirm_password', value);
// }
// return null;
// }
}
@@ -0,0 +1,393 @@
import 'package:flutter/material.dart';
class StepGetRegistration extends StatefulWidget {
final LabeledGlobalKey<FormState> bankAccountFormKey;
// final Function updateSignUpDetails;
final Function showConfirmSignUpButton;
final Function registrationDetails;
final Function finalStepProccessing;
const StepGetRegistration(
{Key? key,
// required this.updateSignUpDetails,
required this.registrationDetails,
required this.bankAccountFormKey,
required this.showConfirmSignUpButton,
required this.finalStepProccessing})
: super(key: key);
@override
_StepGetRegistrationState createState() => _StepGetRegistrationState();
}
class _StepGetRegistrationState extends State<StepGetRegistration> {
String firstname = "";
String firstnameErrorMessage = "";
String lastName = "";
String lastNameErrorMessage = "";
String mobNo = "";
String mobNoErrorMessage = "";
String password = "";
String passwordErrorMessage = "";
String confirmPassword = "";
String confirmPasswordErrorMessage = "";
@override
void initState() {
super.initState();
Map<String, String> signUpDetails = widget.registrationDetails();
if (mounted) {
setState(() {
firstname = signUpDetails['first_name']!;
lastName = signUpDetails['last_name']!;
mobNo = signUpDetails['mob_no']!;
password = signUpDetails['new_password']!;
confirmPassword = signUpDetails['confirm_password']!;
});
}
}
@override
void dispose() {
// widget.bankAccountFormKey.currentState?.validate();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Form(
key: widget.bankAccountFormKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: firstname,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "first name",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (firstnameErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$firstnameErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// first name code end here
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: lastName,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "last name",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (lastNameErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$lastNameErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// last name code
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: mobNo,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "mob no",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (mobNoErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$mobNoErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// mob no code end
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: password,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "password",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (passwordErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$passwordErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// new password code end
Container(
width: double.infinity,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(width: 1.0, color: const Color(0xFFF5F7FA)),
borderRadius: BorderRadius.circular(20),
boxShadow: [
const BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: Offset(-4, -4),
color: Colors.white38),
BoxShadow(
blurRadius: 6.18,
spreadRadius: 0.618,
offset: const Offset(4, 4),
color: Colors.blueGrey.shade100)
]),
child: TextFormField(
initialValue: confirmPassword,
onChanged: _toggleSignUpButtonVisibility,
// validator: _validateEmailId,
autofocus: mounted,
autocorrect: false,
onFieldSubmitted: (value) {
if (value.isNotEmpty) {
widget.finalStepProccessing();
}
},
decoration: const InputDecoration(
fillColor: Colors.white,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15, bottom: 11, top: 11, right: 15),
hintText: "confirmPassword",
hintStyle: TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
style: const TextStyle(fontSize: 16, color: Color(0xFF929BAB)),
),
),
if (confirmPasswordErrorMessage != '')
Container(
margin: const EdgeInsets.all(2),
padding: const EdgeInsets.all(2),
child: Text(
"\t\t\t\t$confirmPasswordErrorMessage",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
),
// confirm password code end here
],
));
}
// void errorMessageSetter(String fieldName, String message) {
// setState(() {
// switch (fieldName) {
// case 'EMAIL-Id':
// emailErrorMessage = message;
// break;
// }
// });
// }
// String? _validateEmailId(String? value) {
// if (value == null || value.isEmpty) {
// errorMessageSetter('EMAIL-ID', 'you must provide a valid email-id');
// } else if (!validEmailFormat.hasMatch(value)) {
// errorMessageSetter('EMAIL-ID', 'format of your email address is invalid');
// } else {
// errorMessageSetter('EMAIL-ID', "");
// widget.updateSignUpDetails('email', value);
// }
// return null;
// }
void _toggleSignUpButtonVisibility(String value) {
widget.registrationDetails('confirmPassword', value);
if (value.isNotEmpty) {
widget.showConfirmSignUpButton(true);
} else {
widget.showConfirmSignUpButton(false);
}
}
}
@@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'sign_up_steps.dart';
class SignUpScreen extends StatefulWidget {
const SignUpScreen({Key? key}) : super(key: key);
@override
_SignUpScreenState createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(
body: SingleChildScrollView(
padding: const EdgeInsets.all(45),
child: Column(
children: <Widget>[
const SizedBox(
height: 16,
),
SizedBox(
height: 30,
child: Image.asset('/images/hadwin_system/cldnsure.png'),
),
const SizedBox(
height: 30,
),
const SignUpSteps(), // GO TO SIGN UP FORM
const SizedBox(
height: 27,
),
SizedBox(
width: double.infinity,
height: 16,
child: Center(
child: InkWell(
child: const Text(
'Already have an account? Sign in',
style:
TextStyle(fontSize: 14, color: Color(0xFF929BAB)),
),
onTap: () {
Navigator.pop(context);
},
),
),
),
const SizedBox(
height: 3,
)
],
),
),
),
onWillPop: () => Future.value(false));
}
}
@@ -0,0 +1,398 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pinput/pinput.dart';
import '../../Utils/color_constants.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_image_view.dart';
import '../../widgets/custom_text_form_field.dart';
import 'RegistrationDetails.dart';
import 'SignUpService.dart';
enum RegistrationStep {
SendOTP,
VerifyOTP,
EnterUserInfo,
SelectAccount,
}
class SignUpUserScreenNew extends StatefulWidget {
SignUpUserScreenNew({Key? key}) : super(key: key);
@override
_SignUpUserScreenState createState() => _SignUpUserScreenState();
}
class _SignUpUserScreenState extends State<SignUpUserScreenNew> {
final SignUpApiService userService = SignUpApiService();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final Map<String, dynamic> formData = {};
final _formKey = GlobalKey<FormState>();
var selectedAccount;
TextEditingController emailcontroller = TextEditingController();
var email;
var otp;
var confirmPassword;
bool _passwordVisible = false;
bool _isPasswordValid = true;
void _validatePassword(String password) {
setState(() {
_isPasswordValid = password.isNotEmpty;
});
}
RegistrationStep currentStep = RegistrationStep.SendOTP;
void moveToNextStep() {
setState(() {
if (currentStep == RegistrationStep.SendOTP) {
currentStep = RegistrationStep.VerifyOTP;
} else if (currentStep == RegistrationStep.VerifyOTP) {
currentStep = RegistrationStep.EnterUserInfo;
} else if (currentStep == RegistrationStep.EnterUserInfo) {
currentStep = RegistrationStep.SelectAccount;
}
});
}
void showSuccessMessage(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
duration: const Duration(seconds: 2),
backgroundColor: Colors.green,
),
);
}
void showErrorMessage(String error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(error),
duration: const Duration(seconds: 2),
backgroundColor: Colors.red,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: CustomAppBar(
height: getVerticalSize(54),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleft,
margin: getMargin(left: 16, top: 13, bottom: 17),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Create User")),
body: Builder(
builder: (BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _formKey,
child: SizedBox(
height: MediaQuery.of(context).size.height *
0.5, // Use 50% of the screen height
child: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
if(currentStep == RegistrationStep.SendOTP) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Email",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
controller: emailcontroller,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter Email';
}
return null;
},
hintText: "Enter Your Email",
margin: getMargin(top: 7),
textInputType: TextInputType.emailAddress),
CustomButton(
height: getVerticalSize(50),
width: getHorizontalSize(396),
text: "Send OTP",
margin: getMargin(top: 25),
onTap: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
formData['usrGrpId'] = 46;
formData['email'] = emailcontroller.text;
try {
print('send email data is $formData');
await userService.sendEmail(formData);
await Future.delayed(
const Duration(seconds: 2));
moveToNextStep();
} catch (e) {
showErrorMessage(
'Failed to send OTP: $e');
}
}
},
),
Align(
alignment: Alignment.center,
child: Padding(
padding: getPadding(top: 28, bottom: 5),
child: RichText(
text: TextSpan(children: [
TextSpan(
text: "",
style: TextStyle(
color: ColorConstant.fromHex(
"#ff12282a"),
fontSize: getFontSize(16),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w400)),
TextSpan(
text: " ",
style: TextStyle(
color: ColorConstant.fromHex(
"#ff12282a"),
fontSize: getFontSize(16),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w700)),
TextSpan(
text: "",
style: TextStyle(
color: ColorConstant.fromHex(
"#ff0061ff"),
fontSize: getFontSize(16),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w700,
decoration:
TextDecoration.underline))
]),
textAlign: TextAlign.left)))
]);
}
else if(currentStep == RegistrationStep.VerifyOTP) {
return Container(
width: double.maxFinite,
padding: getPadding(
left: 16,
top: 76,
right: 16,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
CustomImageView(
svgPath: ImageConstant.imgMobile,
height: getVerticalSize(
82,
),
width: getHorizontalSize(
51,
),
),
Padding(
padding: getPadding(
top: 29,
),
child: Text(
"Email Verification",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold24,
),
),
Container(
width: getHorizontalSize(
302,
),
margin: getMargin(
left: 46,
top: 19,
right: 46,
),
child: Text(
"A mail with a 6-digit verification code was just sent to ${emailcontroller.text}",
maxLines: null,
textAlign: TextAlign.center,
style: AppStyle.txtGilroyMedium16,
),
),
Pinput(
length: 6,
showCursor: true,
defaultPinTheme: PinTheme(
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: ColorConstant.blue50,
),
),
textStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
onCompleted: (value) {
setState(() {
otp = value;
});
},
),
CustomButton(
height: getVerticalSize(
50,
),
text: "Next",
margin: getMargin(
top: 40,
),
onTap: () async {
try {
print('email is $email and otp is $otp');
await userService.otpverification(emailcontroller.text, otp);
moveToNextStep();
showSuccessMessage(
'Email verified successfully');
} catch (e) {
showErrorMessage('Failed to verify OTP: $e');
}
},
),
GestureDetector(
onTap: () async {
try {
await userService.resendEmail(email);
await Future.delayed(
const Duration(seconds: 5));
showSuccessMessage('OTP RESEND');
} catch (e) {
showErrorMessage(
'Failed to resend OTP: $e');
}
},
child: Padding(
padding: getPadding(top: 3),
child: Text("Forgot Password?",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style:
AppStyle.txtGilroyMedium14BlueA700)),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: getPadding(
top: 18,
bottom: 5,
),
child: Row(
children: [
Padding(
padding: getPadding(
top: 2,
),
child: Text(
"Didnt get the code?",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16,
),
),
Padding(
padding: getPadding(
left: 12,
bottom: 1,
),
child: Text(
"Resend",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold16BlueA700,
),
),
],
),
),
),
],
),
);
}
else if (currentStep ==
RegistrationStep.EnterUserInfo) {
return Column(
children: [
CustomButton(
height: getVerticalSize(
50,
),
text: "Go to Registration Details",
margin: getMargin(
top: 40,
),
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
RegistrationDetailsScreen(email: emailcontroller.text),
),
);
},
),
],
);
}
else{
return Container();
}
},
),
),
),
),
);
},
),
);
}
}
@@ -0,0 +1,545 @@
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(
primary: Colors.transparent,
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(
primary: Colors.transparent,
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(
primary: Colors.transparent,
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,
),
),
),
),
);
}
}