From a602d61d2b7b1752d9a335b192bfab6270bb09b9 Mon Sep 17 00:00:00 2001 From: risadmin_prod Date: Fri, 28 Mar 2025 09:08:07 +0000 Subject: [PATCH] build_app --- .../Builders/Services/BuilderService.java | 3 + .../basic1/Controllers/TestfController.java | 195 ++++ .../java/com/realnet/basic1/Entity/Testf.java | 85 ++ .../basic1/Repository/TestfRepository.java | 54 + .../realnet/basic1/Services/TestfService.java | 214 ++++ .../authsec_mysql/mysql/wf_table/wf_table.sql | 2 + .../Testf/TestfView/Testf_api_service.dart | 132 +++ .../TestfView/Testf_create_entity_screen.dart | 720 ++++++++++++ .../TestfView/Testf_entity_list_screen.dart | 1020 +++++++++++++++++ .../TestfView/Testf_update_entity_screen.dart | 589 ++++++++++ .../Testf/Testf_Repo/Testf_repo_screen.dart | 92 ++ .../Testf_view_model_screen.dart | 131 +++ .../lib/commans/widgets/custome_drawer.dart | 156 +-- 13 files changed, 3325 insertions(+), 68 deletions(-) create mode 100644 testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Controllers/TestfController.java create mode 100644 testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Entity/Testf.java create mode 100644 testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Repository/TestfRepository.java create mode 100644 testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Services/TestfService.java create mode 100755 testflutter20-db-d/authsec_mysql/mysql/wf_table/wf_table.sql create mode 100644 testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_api_service.dart create mode 100644 testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_create_entity_screen.dart create mode 100644 testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_entity_list_screen.dart create mode 100644 testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_update_entity_screen.dart create mode 100644 testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/Testf_Repo/Testf_repo_screen.dart create mode 100644 testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/Testf_viewModel/Testf_view_model_screen.dart diff --git a/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/Builders/Services/BuilderService.java b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/Builders/Services/BuilderService.java index 11edc5f..c5c1912 100644 --- a/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/Builders/Services/BuilderService.java +++ b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/Builders/Services/BuilderService.java @@ -69,6 +69,9 @@ public class BuilderService { executeDump(true); // ADD OTHER SERVICE +addCustomMenu( "Testf", "Transcations"); + + System.out.println("dashboard and menu inserted..."); diff --git a/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Controllers/TestfController.java b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Controllers/TestfController.java new file mode 100644 index 0000000..239f28a --- /dev/null +++ b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Controllers/TestfController.java @@ -0,0 +1,195 @@ +package com.realnet.basic1.Controllers; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.springframework.web.bind.annotation.CrossOrigin; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.realnet.config.EmailService; +import com.realnet.users.entity1.AppUser; +import com.realnet.users.service1.AppUserServiceImpl; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.data.domain.*; +import com.realnet.fnd.response.EntityResponse; +import org.springframework.http.*; +import org.springframework.beans.factory.annotation.*; +import com.realnet.basic1.Entity.Testf; +import com.realnet.basic1.Services.TestfService ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@RequestMapping(value = "/Testf") + @CrossOrigin("*") +@RestController +public class TestfController { + @Autowired + private TestfService Service; + +@Value("${projectPath}") + private String projectPath; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @PostMapping("/Testf") + public Testf Savedata(@RequestBody Testf data) { + Testf save = Service.Savedata(data) ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + System.out.println("data saved..." + save); + + return save; + } +@PutMapping("/Testf/{id}") + public Testf update(@RequestBody Testf data,@PathVariable Integer id ) { + Testf update = Service.update(data,id); + System.out.println("data update..." + update); + return update; + } +// get all with pagination + @GetMapping("/Testf/getall/page") + public Page getall(@RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "size", required = false) Integer size) { + Pageable paging = PageRequest.of(page, size); + Page get = Service.getAllWithPagination(paging); + + return get; + + } + @GetMapping("/Testf") + public List getdetails() { + List get = Service.getdetails(); + return get; +} +// get all without authentication + + @GetMapping("/token/Testf") + public List getallwioutsec() { + List get = Service.getdetails(); + return get; +} +@GetMapping("/Testf/{id}") + public Testf getdetailsbyId(@PathVariable Integer id ) { + Testf get = Service.getdetailsbyId(id); + return get; + } +@DeleteMapping("/Testf/{id}") + public ResponseEntity delete_by_id(@PathVariable Integer id ) { + Service.delete_by_id(id); + return new ResponseEntity<>(new EntityResponse("Deleted"), HttpStatus.OK); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} \ No newline at end of file diff --git a/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Entity/Testf.java b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Entity/Testf.java new file mode 100644 index 0000000..e1f3424 --- /dev/null +++ b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Entity/Testf.java @@ -0,0 +1,85 @@ +package com.realnet.basic1.Entity; + import lombok.*; +import com.realnet.WhoColumn.Entity.Extension; + import javax.persistence.*; + import java.time.LocalDateTime; + import java.util.*; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @Entity + @Data + public class Testf extends Extension { + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + +private String name; + +private int numbers; + + private String phones; + + +@Column(length = 2000) +private String paragraphs; + +private String passwordss; +@Transient +private String confirmpasswordss; + +@Column(length = 2000) +private String textareas; + +private String dates; + +private String datetimes; + +private String emails; + +private boolean toggless; + +private String urls; + +private int decimals; + +private String recaptchas; + +private int percentages; + +private String documentss; + + +} diff --git a/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Repository/TestfRepository.java b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Repository/TestfRepository.java new file mode 100644 index 0000000..66b5a5c --- /dev/null +++ b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Repository/TestfRepository.java @@ -0,0 +1,54 @@ +package com.realnet.basic1.Repository; + + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import org.springframework.stereotype.Repository; +import java.util.*; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +import com.realnet.basic1.Entity.Testf; + +@Repository +public interface TestfRepository extends JpaRepository { + +@Query(value = "select * from testf where created_by=?1", nativeQuery = true) + List findAll(Long creayedBy); + +@Query(value = "select * from testf where created_by=?1", nativeQuery = true) + Page findAll(Pageable page, Long creayedBy); +} \ No newline at end of file diff --git a/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Services/TestfService.java b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Services/TestfService.java new file mode 100644 index 0000000..c4ae8f8 --- /dev/null +++ b/testflutter20-back-b/authsec_springboot/backend/src/main/java/com/realnet/basic1/Services/TestfService.java @@ -0,0 +1,214 @@ +package com.realnet.basic1.Services; +import com.realnet.basic1.Repository.TestfRepository; +import com.realnet.basic1.Entity.Testf +;import java.util.*; + +import org.springframework.beans.factory.annotation.Autowired; +import com.realnet.SequenceGenerator.Service.SequenceService; +import com.realnet.Notification.Entity.NotificationService; +import org.springframework.data.domain.Page; +import com.realnet.realm.Entity.Realm; +import com.realnet.realm.Services.RealmService; +import org.springframework.data.domain.Pageable; +import org.springframework.http.*;import com.realnet.users.service1.AppUserServiceImpl; +import com.realnet.users.entity1.AppUser; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + import org.springframework.stereotype.Service; + +@Service + public class TestfService { +@Autowired +private TestfRepository Repository; + @Autowired + private AppUserServiceImpl userService; +@Autowired + private RealmService realmService; + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Autowired + private SequenceService documentsssequenceService; + +public Testf Savedata(Testf data) { + + + + + + + + + + + + + + + + + + + + + + + + + + + + +data.setDocumentss (documentsssequenceService.GenerateSequence("s")); + + data.setUpdatedBy(getUser().getUserId()); + data.setCreatedBy(getUser().getUserId()); + data.setAccountId(getUser().getAccount().getAccount_id()); +Testf save = Repository.save(data); + return save; + } + + +// get all with pagination + public Page getAllWithPagination(Pageable page) { + return Repository.findAll(page, getUser().getUserId()); + } +public List getdetails() { + List realm = realmService.findByUserId(getUser().getUserId()); +List all = Repository.findAll(getUser().getUserId()); + + return all ; } + + +public Testf getdetailsbyId(Integer id) { + return Repository.findById(id).get(); + } + + + public void delete_by_id(Integer id) { + Repository.deleteById(id); +} + + +public Testf update(Testf data,Integer id) { + Testf old = Repository.findById(id).get(); +old.setName(data.getName()); + +old.setNumbers(data.getNumbers()); + +old.setPhones(data.getPhones()); + +old.setParagraphs(data.getParagraphs()); + +old.setPasswordss(data.getPasswordss()); + +old.setTextareas(data.getTextareas()); + +old.setDates(data.getDates()); + +old.setDatetimes(data.getDatetimes()); + +old.setEmails(data.getEmails()); + +old.setToggless (data.isToggless()); + +old.setUrls(data.getUrls()); + +old.setDecimals(data.getDecimals()); + +old.setRecaptchas(data.getRecaptchas()); + +old.setPercentages(data.getPercentages()); + +old.setDocumentss(data.getDocumentss()); + +final Testf test = Repository.save(old); + data.setUpdatedBy(getUser().getUserId()); + return test;} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + public AppUser getUser() { + AppUser user = userService.getLoggedInUser(); + return user; + + }} diff --git a/testflutter20-db-d/authsec_mysql/mysql/wf_table/wf_table.sql b/testflutter20-db-d/authsec_mysql/mysql/wf_table/wf_table.sql new file mode 100755 index 0000000..b240ce6 --- /dev/null +++ b/testflutter20-db-d/authsec_mysql/mysql/wf_table/wf_table.sql @@ -0,0 +1,2 @@ +CREATE TABLE db.Testf(id BIGINT NOT NULL AUTO_INCREMENT, percentages int, datetimes VARCHAR(400), dates Date, toggless VARCHAR(400), passwordss VARCHAR(400), textareas VARCHAR(400), urls VARCHAR(400), decimals int, name VARCHAR(400), numbers int, phones VARCHAR(400), documentss VARCHAR(400), recaptchas VARCHAR(400), emails VARCHAR(400), paragraphs VARCHAR(400), PRIMARY KEY (id)); + diff --git a/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_api_service.dart b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_api_service.dart new file mode 100644 index 0000000..f07007b --- /dev/null +++ b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_api_service.dart @@ -0,0 +1,132 @@ +import 'dart:typed_data'; +import 'package:dio/dio.dart'; +import 'package:http_parser/http_parser.dart'; +import '../../../../resources/api_constants.dart'; +import '../../../../data/network/base_network_service.dart'; +import '../../../../data/network/network_api_service.dart'; + +class testfApiService { + final String baseUrl = ApiConstants.baseUrl; + + final BaseNetworkService _helper = NetworkApiService(); + + + + Future>> getEntities() async { + + try { + final response = await _helper.getGetApiResponse('$baseUrl/Testf/Testf'); + final entities = (response as List).cast>(); + return entities; + } catch (e) { + throw Exception('Failed to get all entities: $e'); + } + } +Future>> getAllWithPagination( + int page, int size) async { + try { + final response = + await _helper.getGetApiResponse('$baseUrl/Testf/Testf/getall/page?page=$page&size=$size'); + final entities = + (response['content'] as List).cast>(); + return entities; + } catch (e) { + throw Exception('Failed to get all without pagination: $e'); + } + } + Future> createEntity( + Map entity) async { + try { + print("in post api$entity"); + final response = + await _helper.getPostApiResponse('$baseUrl/Testf/Testf', entity); + + print(entity); + + // Assuming the response is a Map + Map responseData = response; + + return responseData; + } catch (e) { + throw Exception('Failed to create entity: $e'); + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Future updateEntity( int entityId, Map entity) async { + try { + await _helper.getPutApiResponse('$baseUrl/Testf/Testf/$entityId', + entity); print(entity); + + } catch (e) { + throw Exception('Failed to update entity: $e'); + } + } + + Future deleteEntity( int entityId) async { + try { + await _helper.getDeleteApiResponse('$baseUrl/Testf/Testf/$entityId'); + } catch (e) { + throw Exception('Failed to delete entity: $e'); + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} \ No newline at end of file diff --git a/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_create_entity_screen.dart b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_create_entity_screen.dart new file mode 100644 index 0000000..1254bbd --- /dev/null +++ b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_create_entity_screen.dart @@ -0,0 +1,720 @@ +// ignore_for_file: use_build_context_synchronously +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:provider/provider.dart'; +import '../Testf_viewModel/Testf_view_model_screen.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_text_form_field.dart'; +import '../../../../widgets/custom_dropdown_field.dart'; +import 'dart:math'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'package:barcode_widget/barcode_widget.dart'; +import 'package:intl/intl.dart'; + +import 'package:autocomplete_textfield/autocomplete_textfield.dart'; +import 'package:http/http.dart' as http; +import 'package:flutter/services.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import '../../../../Reuseable/reusable_date_picker_field.dart'; +import '../../../../Reuseable/reusable_date_time_picker_field.dart' +;import 'package:multi_select_flutter/multi_select_flutter.dart'; +import 'package:just_audio/just_audio.dart'; +import 'package:video_player/video_player.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:lottie/lottie.dart'; +import '../../../../utils/toast_messages/toast_message_util.dart'; +import 'dart:io'; +import '../../../../Reuseable/reusable_text_field.dart'; +import '../../../../Reuseable/reusable_dropdown_field.dart'; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +class testfCreateEntityScreen extends StatefulWidget { + const testfCreateEntityScreen({super.key}); + + @override + _testfCreateEntityScreenState createState() => _testfCreateEntityScreenState(); +} + +class _testfCreateEntityScreenState extends State { + +final Map formData = {}; + final _formKey = GlobalKey(); + final TextEditingController nameController = TextEditingController(); + + + final TextEditingController numbersController = TextEditingController(); + + + final TextEditingController phonesController = TextEditingController(); + + + final TextEditingController paragraphsController = TextEditingController(); + + + + bool _passwordVisiblepasswordss = false; + bool _isPasswordValidpasswordss = true; + bool _doPasswordsMatchpasswordss = true; + + String _passwordpasswordss = ''; // To store the first password + + void _validatePasswordpasswordss(String password) { + setState(() { + _isPasswordValidpasswordss = password.isNotEmpty; + _passwordpasswordss = password; // Store the password for later comparison + _doPasswordsMatchpasswordss = true; // Reset match flag on new input + }); + } + + void _validateConfirmPasswordpasswordss(String confirmPassword) { + setState(() { + _doPasswordsMatchpasswordss = confirmPassword == _passwordpasswordss; + }); + } + + final TextEditingController textareasController = TextEditingController(); + + +TextEditingController dates = TextEditingController(); + + DateTime selectedDatedates = DateTime.now(); + Future _selectDatedates(BuildContext context) async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: selectedDatedates, + firstDate: DateTime(2000), + lastDate: DateTime(2101), + ); + if (picked != null && picked != selectedDatedates) { + setState(() { + selectedDatedates = picked; + }); + } + } + + + final TextEditingController datetimesController = TextEditingController(); + + + bool _isemailsEmailValid = true; + void _validateemailsEmail(String email) { + setState(() { + _isemailsEmailValid = RegExp(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$').hasMatch(email); + }); + } + + +bool _isSwitchedtoggless = false; +bool toggless = false; + +void _toggleSwitchtoggless(bool value) { + setState(() { + _isSwitchedtoggless = value; + }); +} + + bool _isUrlValidurls = true; + void _validateUrlurls(String url) { + setState(() { + _isUrlValidurls = Uri.parse(url).isAbsolute; + }); + } + + + final TextEditingController decimalsController = TextEditingController(); + + +late String recaptchascaptcha; + TextEditingController _recaptchasController = TextEditingController(); + final GlobalKey _recaptchasscaffoldKey = GlobalKey(); +void generaterecaptchasCaptcha() { + final random = Random(); + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'; + recaptchascaptcha = String.fromCharCodes(Iterable.generate( + 6, (_) => chars.codeUnitAt(random.nextInt(chars.length)))); + } + + void verifyrecaptchasCaptcha() { + print("Verifying captcha"); + if (_recaptchasController.text.isEmpty) { + print("recaptchas is empty"); + recaptchasSnackbar('Please enter CAPTCHA', success: false); + } else if (_recaptchasController.text != recaptchascaptcha) { + print("captcha is not matching"); + recaptchasSnackbar('CAPTCHA verification failed', success: false); + } else { + print("captcha is verified"); + recaptchasSnackbar('CAPTCHA Verified', success: true); + // Navigate to another screen after verification + // Example navigation to a new screen + // Navigator.push( + // context, + // MaterialPageRoute(builder: (context) => NextScreen()), + // ); + } + } + + void recaptchasSnackbar(String message, {required bool success}) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(message), + backgroundColor: success ? Colors.green : Colors.red, + ), + ); + } + + + final TextEditingController percentagesController = TextEditingController(); + + + + + @override + void initState() { + super.initState(); + final provider = Provider.of(context, listen: false); + + + + + + + + + + + + + + + + + + + + + + + + + generaterecaptchasCaptcha(); + + + + + +} + + + + @override + Widget build(BuildContext context) { + final provider = Provider.of(context, listen: false); + 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: "Create Testf"), + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16), + child: Form( + key: _formKey, + child: Column( + children: [ + ReusableTextField( + controller: nameController, + + onSaved:(value) => formData['name'] = value , + label:"Enter Name", + // ValidationProperties +), + + SizedBox(height: 16), + + +ReusableTextField( + controller: numbersController, + + onSaved:(value) => formData['numbers'] = value , + label: "Enter Numbers", + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow((RegExp(r'[0-9]'))), + ], + // ValidationProperties +), + +SizedBox(height: 16), + +ReusableTextField( + onSaved:(value) => formData['phones'] = value , + label: "Enter Phones", + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, +LengthLimitingTextInputFormatter( + 10), // Limit input to 10 digits + ], + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter Phones'; + } + if (value.length != 10) { + return 'Phone number must be exactly 10 digits'; + } + return null; + }, + ), + +ReusableTextField( + controller: paragraphsController, + + onSaved:(value) => formData['paragraphs'] = value , + label: "Enter Paragraphs", + maxLines: 5, + + ), + +TextFormField( + obscureText: !_passwordVisiblepasswordss, + decoration: InputDecoration( + labelText: 'Passwordss', + suffixIcon: IconButton( + icon: Icon( + _passwordVisiblepasswordss + ? Icons.visibility + : Icons.visibility_off, + ), + onPressed: () { + setState(() { + _passwordVisiblepasswordss = !_passwordVisiblepasswordss; + }); + }, + ), + errorText: + _isPasswordValidpasswordss ? null : 'Please enter a password', + border: OutlineInputBorder(), + ), + onSaved: (value) => formData['passwordss'] = value, + onChanged: _validatePasswordpasswordss, + ), + const SizedBox(height: 16), + TextFormField( + obscureText: !_passwordVisiblepasswordss, + decoration: InputDecoration( + labelText: 'Confirm Passwordss', + suffixIcon: IconButton( + icon: Icon( + _passwordVisiblepasswordss + ? Icons.visibility + : Icons.visibility_off, + ), + onPressed: () { + setState(() { + _passwordVisiblepasswordss = !_passwordVisiblepasswordss; + }); + }, + ), + errorText: + _doPasswordsMatchpasswordss ? null : 'Passwords do not match', + border: OutlineInputBorder(), + ), + onChanged: _validateConfirmPasswordpasswordss, + ), + +ReusableTextField( + controller: textareasController, + + onSaved:(value) => formData['textareas'] = value , + label: "Enter Textareas", + maxLines: 5, +// ValidationProperties +), + + + SizedBox(height: 16), + + +ReusableDatePickerField( + label:' Dates', controller: dates +, + onSaved: (value) => formData['dates'] = value,), +const SizedBox(height: 16), + + +ReusableTextField( + controller: datetimesController, + + onSaved:(value) => formData['datetimes'] = value , + label:"Enter Datetimes", + // ValidationProperties +), + + SizedBox(height: 16), + + + +Padding( + padding: getPadding(top: 19), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Emails", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900), + CustomTextFormField( + hintText: "Enter Emails", + errorText: _isemailsEmailValid ? null : 'Please enter a valid email', + +onsaved: (value) => formData['emails'] = value, + onChanged: (value) { + _validateemailsEmail(value); + }, + margin: getMargin(top: 6)) + ])), + + Switch( + value: _isSwitchedtoggless, + onChanged: _toggleSwitchtoggless, + activeColor: Colors.white, + activeTrackColor: Colors.green, + inactiveThumbColor: Colors.white, + inactiveTrackColor: Colors.red, + ), + + +Padding( + padding: getPadding(top: 19), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Urls", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900), + CustomTextFormField( + hintText: "Enter Urls", + errorText: _isUrlValidurls ? null : 'Please enter a valid URL', + keyboardType: TextInputType.url, + + + onsaved: (value) => formData['urls'] = value, + onChanged: _validateUrlurls, + + margin: getMargin(top: 6)) + ])), +SizedBox(height: 16), + +ReusableTextField( + controller: decimalsController, + + onSaved:(value) => formData['decimals'] = value , + label: "Enter Decimals", + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow((RegExp(r'[0-9]'))), + ], + // ValidationProperties +), + +SizedBox(height: 16), + +Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'Enter the following CAPTCHA:', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + SizedBox(height: 16), + Container( + decoration: BoxDecoration( + color: Colors.grey[300], + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + spreadRadius: 2, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + recaptchascaptcha, + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: Colors.blue, + letterSpacing: 4, + fontFamily: 'Roboto', + decoration: TextDecoration.none, + ), + ), + IconButton( + icon: Icon(Icons.refresh), + onPressed: () { + setState(() { + generaterecaptchasCaptcha(); + }); + }, + ), + ], + ), + ), + SizedBox(height: 24), + TextFormField( + controller: _recaptchasController, + decoration: InputDecoration( + labelText: 'Enter CAPTCHA', + border: OutlineInputBorder(), + ), + ), + SizedBox(height: 24), + ElevatedButton( + onPressed: verifyrecaptchasCaptcha, + child: Text('Verify CAPTCHA'), + ), + ], + ), + ), + +ReusableTextField( + controller: percentagesController, + + onSaved:(value) => formData['percentages'] = value , + label: "Enter Percentages", + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow((RegExp(r'[0-9]'))), + ], + // ValidationProperties +), + +SizedBox(height: 16), + + + + const SizedBox(width: 8), + CustomButton( + height: getVerticalSize(50), + text: "Submit", + margin: getMargin(top: 24, bottom: 5), + onTap: () async { + if (_formKey.currentState!.validate()) { + _formKey.currentState!.save(); + + + + + + + + + + + + + + + + + + +formData['toggless'] = toggless; + + + + + + + + + + + + + + try { + print(formData); + Map createdEntity = await provider.createEntity(formData); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Navigator.pop(context); + } catch (e) { + // ignore: use_build_context_synchronously + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Error'), + content: Text('Failed to create Testf: $e'), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + } + }, + ), + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ], + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_entity_list_screen.dart b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_entity_list_screen.dart new file mode 100644 index 0000000..12ff74b --- /dev/null +++ b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_entity_list_screen.dart @@ -0,0 +1,1020 @@ +// ignore_for_file: use_build_context_synchronously +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'Testf_create_entity_screen.dart'; +import 'Testf_update_entity_screen.dart'; +import '../Testf_viewModel/Testf_view_model_screen.dart'; +import 'package:flutter/services.dart'; +import 'package:speech_to_text/speech_to_text.dart' as stt; +import '../../../../theme/app_style.dart'; +import '../../../../utils/size_utils.dart'; +import '../../../../widgets/custom_icon_button.dart'; +import '../../../../utils/image_constant.dart'; +import '../../../../widgets/app_bar/appbar_image.dart'; +import '../../../../widgets/app_bar/appbar_title.dart'; +import '../../../../widgets/app_bar/custom_app_bar.dart'; +import '../../../../theme/app_decoration.dart'; +import 'package:multi_select_flutter/multi_select_flutter.dart'; +import '../../../../Reuseable/reusable_text_field.dart'; +import 'package:provider/provider.dart'; +import 'package:fluttertoast/fluttertoast.dart'; + +class testf_entity_list_screen extends StatefulWidget { + static const String routeName = '/entity-list'; + + @override + _testf_entity_list_screenState createState() => _testf_entity_list_screenState(); +} + +class _testf_entity_list_screenState extends State { + List> entities = []; + List> filteredEntities = []; + List> serachEntities = []; + + bool showCardView = true; // Add this variable to control the view mode + TextEditingController searchController = TextEditingController(); + late stt.SpeechToText _speech; + + bool isLoading = false; // Add this variable to track loading state + int currentPage = 0; + int pageSize = 10; // Adjust this based on your backend API + + final ScrollController _scrollController = ScrollController(); + @override + void initState() { + _speech = stt.SpeechToText(); + super.initState(); + fetchEntities(); + _scrollController.addListener(_scrollListener); + fetchwithoutpaging(); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Future fetchwithoutpaging() async { + try { + final provider = + Provider.of(context, listen: false); + final fetchedEntities = await provider.getEntities(); + print('withoutpaging data is $fetchedEntities'); + setState(() { + serachEntities = fetchedEntities; // Update only filteredEntities + }); + print('Testf entity is .. $serachEntities'); + } catch (e) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Error'), + content: Text('Failed to fetch Testf: $e'), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + } +Future fetchEntities() async { + try { + setState(() { + isLoading = true; + }); + + + + final provider = + Provider.of(context, listen: false); + final fetchedEntities = + await provider.getAllWithPagination(currentPage, pageSize); + print('pagination data is $fetchedEntities'); + setState(() { + entities.addAll(fetchedEntities); // Add new data to the existing list + filteredEntities = entities.toList(); // Update only filteredEntities + currentPage++; + }); + + print(' entity is .. $filteredEntities'); + } catch (e) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Error'), + content: Text('Failed to fetch Testf data: $e'), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } finally { + setState(() { + isLoading = false; + }); + } + } + + void _scrollListener() { + if (_scrollController.position.pixels == + _scrollController.position.maxScrollExtent) { + fetchEntities(); + } + } + + Future deleteEntity(Map entity) async { + try { + final provider = + Provider.of(context, listen: false); + + await provider.deleteEntity(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(); + }, + ), + ], + ); + }, + ); + } + } + + void _searchEntities(String keyword) { + setState(() { + filteredEntities = serachEntities + .where((entity) => + + + + entity['name'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['numbers'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['phones'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['paragraphs'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['passwordss'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['textareas'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['dates'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['datetimes'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['emails'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + entity['toggless'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['urls'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['decimals'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + + + entity['percentages'].toString().toLowerCase().contains(keyword.toLowerCase()) || + + + + + + entity['documentss'].toString().toLowerCase().contains(keyword.toLowerCase()) + + + ).toList(); + }); + } + + void _startListening() async { + if (!_speech.isListening) { + bool available = await _speech.initialize( + onStatus: (status) { + print('Speech recognition status: $status'); + }, + onError: (error) { + print('Speech recognition error: $error'); + }, + ); + + if (available) { + _speech.listen( + onResult: (result) { + if (result.finalResult) { + searchController.text = result.recognizedWords; + _searchEntities(result.recognizedWords); + } + }, + ); + } + } + } + + void _stopListening() { + if (_speech.isListening) { + _speech.stop(); + } + } + + @override + void dispose() { + _speech.cancel(); + super.dispose(); + } + +onTapArrowleft1(BuildContext context) { + Navigator.pop(context); + } + @override + Widget build(BuildContext context) { + return SafeArea( + child: 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: () { + onTapArrowleft1(context); + }), + centerTitle: true, + title: AppbarTitle(text: " Testf"), + actions: [ + Row( + children: [ + Switch( + activeColor: Colors.greenAccent, + inactiveThumbColor: Colors.white, + value: showCardView, + onChanged: (value) { + setState(() { + showCardView = value; + }); + }, + ), + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ], + ), ], + ), + body: RefreshIndicator( + onRefresh: () async { + currentPage = 1; + entities.clear(); + await fetchEntities(); + }, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: TextField( + controller: searchController, + onChanged: (value) { + _searchEntities(value); + }, + decoration: InputDecoration( + hintText: 'Search...', + contentPadding: const EdgeInsets.symmetric(horizontal: 16.0), + filled: true, + fillColor: Colors.grey[200], + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10.0), + borderSide: BorderSide.none, + ), + suffixIcon: IconButton( + icon: const Icon(Icons.mic), + onPressed: () { + _startListening(); + }, + ), + ), + ), + ), + Expanded( + child: ListView.builder( + itemCount: filteredEntities.length + (isLoading ? 1 : 0), + itemBuilder: (BuildContext context, int index) { + if (index < filteredEntities.length) { + final entity = filteredEntities[index]; + return _buildListItem(entity); + } else { + // Display the loading indicator at the bottom when new data is loading + return const Padding( + padding: EdgeInsets.all(8.0), + child: Center( + child: CircularProgressIndicator(), + ), + ); + } + }, + controller: _scrollController, + ), + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ChangeNotifierProvider( + create: (context) => TestfViewModelScreen(), + child: testfCreateEntityScreen(), + ), + ), + ).then((_) { + fetchEntities(); + }); + }, + child: const Icon(Icons.add), + ), + )); + } + + Widget _buildListItem(Map entity) { + return showCardView ? _buildCardView(entity) : _buildNormalView(entity); + } + + + // Function to build card view for a list item + Widget _buildCardView(Map 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 + + // Function to build normal view for a list item + + Widget _buildNormalView(Map entity) { + final values = entity.values.elementAt(21) ?? 'Authsec'; + + return SizedBox( + 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, + margin: getMargin( + left: 8, + top: 3, + bottom: 1, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + entity['id'].toString(), + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGreenSemiBold16, + ), + ], + ), + ), + const Spacer(), + PopupMenuButton( + icon: const Icon( + Icons.more_vert, + color: Colors.black, + size: 16, + ), + itemBuilder: (BuildContext context) { + return [ + PopupMenuItem( + value: 'edit', + child: Row( + children: [ + const Icon( + Icons.edit, + size: 16, // Adjust the icon size as needed + ), + const SizedBox(width: 8), + Text( + 'Edit', + style: AppStyle + .txtGilroySemiBold16, // Adjust the text size as needed + ), + ], + ), + ), + PopupMenuItem( + value: 'delete', + child: Row( + children: [ + const Icon( + Icons.delete, + size: 16, // Adjust the icon size as needed + ), + const 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) => ChangeNotifierProvider( + create: (context) => TestfViewModelScreen(), + child: testfUpdateEntityScreen(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) + .then((value) => {fetchEntities()}); + }, + ), + ], + ); + }, + ); + } + }, + ), + ], + ), + ), + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Name : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['name'].toString() ?? 'No Name Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Numbers : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['numbers'].toString() ?? 'No Numbers Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Phones : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['phones'].toString() ?? 'No Phones Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Paragraphs : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['paragraphs'].toString() ?? 'No Paragraphs Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Passwordss : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['passwordss'].toString() ?? 'No Passwordss Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Textareas : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['textareas'].toString() ?? 'No Textareas Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Dates : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['dates'].toString() ?? 'No Dates Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Datetimes : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['datetimes'].toString() ?? 'No Datetimes Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Emails : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['emails'].toString() ?? 'No Emails Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "toggless : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['toggless'].toString() ?? 'No toggless Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Urls : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['urls'].toString() ?? 'No Urls Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Decimals : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['decimals'].toString() ?? 'No Decimals Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Percentages : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['percentages'].toString() ?? 'No Percentages Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + Padding( + padding: getPadding( + top: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "documentss : ", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16, + ), + Text( + entity['documentss'].toString() ?? 'No documentss Available', + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle.txtGilroyMedium16Bluegray900, + ), + ], + ), + ), + + + ], + ), + ), + ); + } + + Widget _buildLeadingIcon(String title) { + return CircleAvatar( + backgroundColor: Colors.blue, + child: Text( + title.isNotEmpty ? title[0].toUpperCase() : 'NA', + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), + ); + } + + void _showAdditionalFieldsDialog( + BuildContext context, + Map entity, + ) { + final dateFormat = DateFormat('yyyy-MM-dd HH:mm:ss'); + + 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) { + final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp); + return dateFormat.format(dateTime); + } else if (timestamp is String) { + return timestamp; + } else { + return 'N/A'; + } + } +} + \ No newline at end of file diff --git a/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_update_entity_screen.dart b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_update_entity_screen.dart new file mode 100644 index 0000000..d2b00bd --- /dev/null +++ b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/TestfView/Testf_update_entity_screen.dart @@ -0,0 +1,589 @@ +// ignore_for_file: use_build_context_synchronously +import 'dart:convert'; +import 'package:provider/provider.dart'; +import '../Testf_viewModel/Testf_view_model_screen.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 'package:barcode_widget/barcode_widget.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import '../../../../widgets/custom_button.dart'; +import '../../../../widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; +import 'package:autocomplete_textfield/autocomplete_textfield.dart'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'package:intl/intl.dart'; + +import 'dart:math'; +import '../../../../Reuseable/reusable_text_field.dart'; +import '../../../../Reuseable/reusable_date_picker_field.dart'; +import '../../../../Reuseable/reusable_date_time_picker_field.dart'; +import '../../../../Reuseable/reusable_dropdown_field.dart'; +import 'package:flutter/services.dart'; +class testfUpdateEntityScreen extends StatefulWidget { + final Map entity; + + + testfUpdateEntityScreen({required this.entity}); + + @override + _testfUpdateEntityScreenState createState() => _testfUpdateEntityScreenState(); +} + +class _testfUpdateEntityScreenState extends State { + final _formKey = GlobalKey(); + + + + + + + + + + + bool _passwordVisiblepasswordss = false; + bool _isPasswordValidpasswordss = true; + bool _doPasswordsMatchpasswordss = true; + + String _passwordpasswordss = ''; // To store the first password + + void _validatePasswordpasswordss(String password) { + setState(() { + _isPasswordValidpasswordss = password.isNotEmpty; + _passwordpasswordss = password; // Store the password for later comparison + _doPasswordsMatchpasswordss = true; // Reset match flag on new input + }); + } + + void _validateConfirmPasswordpasswordss(String confirmPassword) { + setState(() { + _doPasswordsMatchpasswordss = confirmPassword == _passwordpasswordss; + }); + } + + + +TextEditingController dates = TextEditingController(); +DateTime selectedDatedates = DateTime.now(); + +Future _selectDatedates(BuildContext context) async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: selectedDatedates, + firstDate: DateTime(2000), + lastDate: DateTime(2101), + ); + print(picked); + if (picked != null && picked != selectedDatedates) { + setState(() { + selectedDatedates = picked; + }); + } +} + + + +bool _isemailsEmailValid = true; + +void _validateemailsEmail(String email) { + setState(() { + _isemailsEmailValid = RegExp(r'^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$').hasMatch(email); + }); +} + + bool istoggless = false; + +bool _isUrlValidurls = true; + +void _validateUrlurls(String url) { + setState(() { + _isUrlValidurls= Uri.parse(url).isAbsolute; + }); +} + + + + + + + + + + + @override + void initState() { + super.initState(); + final provider = Provider.of(context, listen: false); + + + + + + + + + + + + + + + + + + +istoggless = widget.entity['toggless'] ?? false; // Set initial value + + + + + + + + + + + +} + + + @override + Widget build(BuildContext context) { + final provider = Provider.of(context, listen: false); + 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: "Update Testf"), actions: [ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ], +), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16), + child: Form( + key: _formKey, + child: Column( + children: [ + + ReusableTextField( + + label: "Please Enter Name", + initialValue: widget.entity['name'] ?? '', + + // ValidationProperties + onSaved: (value) => widget.entity['name'] = value, +), + + SizedBox(height: 16), + + + ReusableTextField( + initialValue: widget.entity['numbers'].toString(), + onSaved: (value) => widget.entity['numbers']= value, + label: "Enter Numbers", + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow((RegExp(r'[0-9]'))), + ], + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter a number'; + } + return null; + }, + ), + +ReusableTextField( + initialValue: widget.entity['phones'], + onSaved: (value) => widget.entity['phones'] = value, + label: "Enter Phones", + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + LengthLimitingTextInputFormatter( + 10), // Limit input to 10 digits + ], + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter Phones'; + } + if (value.length != 10) { + return 'Phone number must be exactly 10 digits'; + } + return null; + }, + ), + + // }), + ReusableTextField( + initialValue: widget.entity['paragraphs'], + onSaved: (value) => widget.entity['paragraphs']= value, + label: "Enter Paragraphs", + maxLines: 5, + ), + +TextFormField( + initialValue: widget.entity['passwordss'], + + obscureText: !_passwordVisiblepasswordss, + decoration: InputDecoration( + labelText: 'Passwordss', + suffixIcon: IconButton( + icon: Icon( + _passwordVisiblepasswordss + ? Icons.visibility + : Icons.visibility_off, + ), + onPressed: () { + setState(() { + _passwordVisiblepasswordss = !_passwordVisiblepasswordss; + }); + }, + ), + errorText: + _isPasswordValidpasswordss ? null : 'Please enter a password', + border: OutlineInputBorder(), + ), + onSaved: (value) => widget.entity['passwordss'] = value, + onChanged: _validatePasswordpasswordss, + ), + const SizedBox(height: 16), + TextFormField( + obscureText: !_passwordVisiblepasswordss, + decoration: InputDecoration( + labelText: 'Confirm Passwordss', + suffixIcon: IconButton( + icon: Icon( + _passwordVisiblepasswordss + ? Icons.visibility + : Icons.visibility_off, + ), + onPressed: () { + setState(() { + _passwordVisiblepasswordss = !_passwordVisiblepasswordss; + }); + }, + ), + errorText: + _doPasswordsMatchpasswordss ? null : 'Passwords do not match', + border: OutlineInputBorder(), + ), + onChanged: _validateConfirmPasswordpasswordss, + ), + + + + + + ReusableTextField( + initialValue: widget.entity['textareas'], + onSaved: (value) => widget.entity['textareas']= value, + label: "Enter Textareas", + maxLines: 5, + ), + + ReusableDatePickerField(label: 'Dates', controller: dates, initialDate: widget.entity['dates'], + onSaved: (value) => widget.entity['dates'] = value,), + + + + ReusableTextField( + + label: "Please Enter Datetimes", + initialValue: widget.entity['datetimes'] ?? '', + + // ValidationProperties + onSaved: (value) => widget.entity['datetimes'] = value, +), + + SizedBox(height: 16), + + + Padding( + padding: getPadding(top: 19), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Emails", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle + .txtGilroyMedium16Bluegray900), + CustomTextFormField( + hintText: "Enter Emails", + initialValue: widget.entity['emails'], + keyboardType: TextInputType.url, + errorText: _isemailsEmailValid ? null : 'Please enter a valid URL', + onChanged: _validateemailsEmail, + + + + // ValidationProperties + + onsaved: (value) { + widget.entity['emails'] = value; + }, + margin: getMargin(top: 6)) + ])), + +SizedBox(height: 16), + +Row( + children: [ + Switch( + value: istoggless, + onChanged: (newValue) { + setState(() { + istoggless = newValue; + }); + }, + activeColor: Colors.white, + activeTrackColor: Colors.green, + inactiveThumbColor: Colors.white, + inactiveTrackColor: Colors.red, + ), + const SizedBox(width: 8), + const Text('toggless'), + ], +), + + Padding( + padding: getPadding(top: 19), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Urls", + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.left, + style: AppStyle + .txtGilroyMedium16Bluegray900), + CustomTextFormField( + hintText: "Enter Urls", + initialValue: widget.entity['urls'], + keyboardType: TextInputType.url, + errorText: _isUrlValidurls ? null : 'Please enter a valid URL', + onChanged: _validateUrlurls, + + + + // ValidationProperties + + onsaved: (value) { + widget.entity['urls'] = value; + }, + margin: getMargin(top: 6)) + ])), + +SizedBox(height: 16), + + ReusableTextField( + initialValue: widget.entity['decimals'].toString(), + onSaved: (value) => widget.entity['decimals']= value, + label: "Enter Decimals", + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow((RegExp(r'[0-9]'))), + ], + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter a number'; + } + return null; + }, + ), + + + ReusableTextField( + + label: "Please Enter recaptchas", + initialValue: widget.entity['recaptchas'] ?? '', + + // ValidationProperties + onSaved: (value) => widget.entity['recaptchas'] = value, +), + + SizedBox(height: 16), + + + ReusableTextField( + initialValue: widget.entity['percentages'].toString(), + onSaved: (value) => widget.entity['percentages']= value, + label: "Enter Percentages", + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow((RegExp(r'[0-9]'))), + ], + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter a number'; + } + return null; + }, + ), + + + ReusableTextField( + + label: "Please Enter documentss", + initialValue: widget.entity['documentss'] ?? '', + + // ValidationProperties + onSaved: (value) => widget.entity['documentss'] = value, +), + + SizedBox(height: 16), + + + + CustomButton( + height: getVerticalSize(50), + text: "Update", + margin: getMargin(top: 24, bottom: 5), + onTap: () async { + if (_formKey.currentState!.validate()) { + _formKey.currentState!.save(); + + + + + + + + + + + + + + + + + + +widget.entity['toggless'] = istoggless; + + + + + + + + + + + + + try { + await provider.updateEntity( + widget.entity[ + 'id'], // Assuming 'id' is the key in your entity map + widget.entity); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Navigator.pop(context); + } catch (e) { + // ignore: use_build_context_synchronously + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Error'), + content: + Text('Failed to update Testf: $e'), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + } + }, + ), + ], + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/Testf_Repo/Testf_repo_screen.dart b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/Testf_Repo/Testf_repo_screen.dart new file mode 100644 index 0000000..cee2e11 --- /dev/null +++ b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/Testf_Repo/Testf_repo_screen.dart @@ -0,0 +1,92 @@ +import 'package:dio/dio.dart'; +import '../../../../data/network/base_network_service.dart'; +import '../../../../data/network/network_api_service.dart'; +import '../../../../resources/api_constants.dart'; + +class TestfRepoScreen { + final String baseUrl = ApiConstants.baseUrl; + final BaseNetworkService _helper = NetworkApiService(); + + Future getEntities() async { + try { + final response = + await _helper.getGetApiResponse('$baseUrl/Testf/Testf'); + return response; + } catch (e) { + throw Exception('Failed to get all entities: $e'); + } + } + + Future getAllWithPagination(int page, int size) async { + try { + final response = await _helper.getGetApiResponse( + '$baseUrl/Testf/Testf/getall/page?page=$page&size=$size'); + return response; + } catch (e) { + throw Exception('Failed to get all without pagination: $e'); + } + } + + Future createEntity(Map entity) async { + try { + print("in post api$entity"); + final response = await _helper.getPostApiResponse( + '$baseUrl/Testf/Testf', entity); + + print(entity); + + return response; + } catch (e) { + throw Exception('Failed to create entity: $e'); + } + } + + Future updateEntity(int entityId, Map entity) async { + try { + await _helper.getPutApiResponse( + '$baseUrl/Testf/Testf/$entityId', entity); + print(entity); + } catch (e) { + throw Exception('Failed to update entity: $e'); + } + } + + Future deleteEntity(int entityId) async { + try { + await _helper + .getDeleteApiResponse('$baseUrl/Testf/Testf/$entityId'); + } catch (e) { + throw Exception('Failed to delete entity: $e'); + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/Testf_viewModel/Testf_view_model_screen.dart b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/Testf_viewModel/Testf_view_model_screen.dart new file mode 100644 index 0000000..99ecef4 --- /dev/null +++ b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/Entity/basic1/Testf/Testf_viewModel/Testf_view_model_screen.dart @@ -0,0 +1,131 @@ +import 'dart:typed_data'; +import 'package:dio/dio.dart'; +import 'package:http_parser/http_parser.dart'; +import '../../../../utils/toast_messages/toast_message_util.dart'; +import 'package:flutter/material.dart'; +import '../Testf_Repo/Testf_repo_screen.dart'; + +class TestfViewModelScreen extends ChangeNotifier{ + final TestfRepoScreen repo = TestfRepoScreen(); + + Future>> getEntities() async { + try { + final response = await repo.getEntities(); + final entities = (response as List).cast>(); + return entities; + } catch (e) { + throw Exception('Failed to get all entities: $e'); + } + } + + + Future>> getAllWithPagination( + int page, int size) async { + try { + final response = + await repo.getAllWithPagination(page, size); // ✅ Use await + + print('res - $response'); + + // ✅ Ensure response is a Map + if (response is! Map) { + throw Exception('Unexpected response format: $response'); + } + + // ✅ Extract 'content' and ensure it's a list + final entities = (response['content'] as List) + .cast>() // ✅ Ensure list of maps + .toList(); + return entities; + } catch (e) { + print(e); + throw Exception('Failed to get all without pagination :- $e'); + } + } + + + Future> createEntity(Map entity) async { + try { + print("in post api - $entity"); + // Wait for API response + final responseData = + await repo.createEntity(entity) as Map; + print('after value - $responseData'); + ToastMessageUtil.showToast( + message: "Added Successfully", toastType: ToastType.success); + + return responseData; // Return the data AFTER it is received + } catch (error) { + print("error--$error"); + ToastMessageUtil.showToast( + message: "Got Error", toastType: ToastType.error); + + throw Exception( + 'Failed to Create Entity: $error'); // Properly rethrow the error + } + } + Future updateEntity(int entityId, Map entity) async { + try { + repo.updateEntity(entityId, entity).then((value) { + ToastMessageUtil.showToast( + message: "Updated Successfully", toastType: ToastType.success); + }).onError( + (error, stackTrace) { + print("error--$error"); + ToastMessageUtil.showToast( + message: "Got Error", toastType: ToastType.error); + }, + ); + print(entity); + } catch (e) { + throw Exception('Failed to update entity: $e'); + } + } + + Future deleteEntity(int entityId) async { + try { + repo.deleteEntity(entityId).then((value) { + ToastMessageUtil.showToast( + message: "Deleted Successfully", toastType: ToastType.success); + }).onError( + (error, stackTrace) { + print("error--$error"); + ToastMessageUtil.showToast( + message: "Got Error", toastType: ToastType.error); + }, + ); + } catch (e) { + throw Exception('Failed to delete entity: $e'); + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} \ No newline at end of file diff --git a/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/commans/widgets/custome_drawer.dart b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/commans/widgets/custome_drawer.dart index 73fb148..9ba8dff 100644 --- a/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/commans/widgets/custome_drawer.dart +++ b/testflutter20-front-f/authsec_flutterNewUi/base_project/lib/commans/widgets/custome_drawer.dart @@ -1,3 +1,6 @@ +import '../../Entity/basic1/Testf/TestfView/Testf_entity_list_screen.dart'; +import '../../Entity/basic1/Testf/Testf_viewModel/Testf_view_model_screen.dart'; + import 'package:base_project/utils/image_constant.dart'; import 'package:base_project/commans/widgets/custome_drawe_item.dart'; import 'package:base_project/resources/app_colors.dart'; @@ -9,79 +12,96 @@ import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; class MyCustomDrawer extends StatelessWidget { - const MyCustomDrawer({super.key}); +const MyCustomDrawer({super.key}); - @override - Widget build(BuildContext context) { - final email = UserManager().email; - final userName = UserManager().userName; - final provider = Provider.of(context, listen: false); - return Drawer( - child: ListView( - padding: EdgeInsets.zero, - children: [ - UserAccountsDrawerHeader( - decoration: const BoxDecoration( - color: AppColors.primary, - ), - currentAccountPicture: CircleAvatar( - radius: 60, - backgroundColor: AppColors.primary.withOpacity(0.3), - backgroundImage: provider.profileImageBytes != null - ? MemoryImage(provider.profileImageBytes!) - : null, - child: provider.profileImageBytes != null - ? null // Use backgroundImage for the actual image, so child should be null - : SvgPicture.asset( - ImageConstant.userProfileImg, // Placeholder SVG asset +@override +Widget build(BuildContext context) { +final email = UserManager().email; +final userName = UserManager().userName; +final provider = Provider.of(context, listen: false); +return Drawer( +child: ListView( +padding: EdgeInsets.zero, +children: [ +UserAccountsDrawerHeader( +decoration: const BoxDecoration( +color: AppColors.primary, +), +currentAccountPicture: CircleAvatar( +radius: 60, +backgroundColor: AppColors.primary.withOpacity(0.3), +backgroundImage: provider.profileImageBytes != null +? MemoryImage(provider.profileImageBytes!) +: null, +child: provider.profileImageBytes != null +? null // Use backgroundImage for the actual image, so child should be null +: SvgPicture.asset( +ImageConstant.userProfileImg, // Placeholder SVG asset // AppImages.userProfileImg, // Placeholder SVG asset - width: 60, // Adjust to fit the CircleAvatar - height: 60, - ), - ), - accountName: Text("Hello, $userName"), - accountEmail: Text(email.toString()), - ), - DrawerItem( - color: AppColors.primary, - icon: Icons.person, - title: 'Profile', - onTap: () { - Navigator.pushNamed(context, RouteNames.profileView); - }, - ), - DrawerItem( - color: AppColors.primary, - icon: Icons.system_security_update, - title: 'System Parameters', - onTap: () { +width: 60, // Adjust to fit the CircleAvatar +height: 60, +), +), +accountName: Text("Hello, $userName"), +accountEmail: Text(email.toString()), +), +DrawerItem( +color: AppColors.primary, +icon: Icons.person, +title: 'Profile', +onTap: () { +Navigator.pushNamed(context, RouteNames.profileView); +}, +), +DrawerItem( +color: AppColors.primary, +icon: Icons.system_security_update, +title: 'System Parameters', +onTap: () { // Add navigation or other logic here - Navigator.pushNamed(context, RouteNames.systemParamsView); - }, - ), - DrawerItem( - color: AppColors.primary, - icon: Icons.password, - title: 'change password', - onTap: () { - Navigator.pushNamed(context, RouteNames.changePasswordView); - }, - ), +Navigator.pushNamed(context, RouteNames.systemParamsView); +}, +), +DrawerItem( +color: AppColors.primary, +icon: Icons.password, +title: 'change password', +onTap: () { +Navigator.pushNamed(context, RouteNames.changePasswordView); +}, +), // NEW MENU - - DrawerItem( - icon: Icons.logout, - color: Colors.red, - title: 'Logout', - onTap: () async { - await UserManager().clearUser(); - Navigator.pushReplacementNamed(context, RouteNames.splashView); - }, +DrawerItem( + color: AppColors.primary, + icon: Icons.chat_bubble, + title: 'Testf', + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ChangeNotifierProvider( + create: (context) => TestfViewModelScreen(), + child: testf_entity_list_screen(), + ), + ), + ); + }, ), - ], - ), - ); - } + + +DrawerItem( +icon: Icons.logout, +color: Colors.red, +title: 'Logout', +onTap: () async { +await UserManager().clearUser(); +Navigator.pushReplacementNamed(context, RouteNames.splashView); +}, +), +], +), +); } +} \ No newline at end of file