claims and chatbot changes done
This commit is contained in:
parent
22b6b6750c
commit
6641314af0
11
.env
11
.env
@ -1,7 +1,6 @@
|
||||
API_URL=https://venbait.in/nhance/dev/employeeRest/
|
||||
#CHAT_BOT_URL=https://venbait.in/nhance/dev
|
||||
API_URL_Enrollment=https://venbait.in/enrollment/employeeRest/
|
||||
TICKET_API_URL=https://venbait.in/nhance/dev/api
|
||||
API_URL=https://app.nhanceindia.in/zenith/employeeRest/
|
||||
API_URL_Enrollment=https://app.nhanceindia.in/enrolment/employeeRest/
|
||||
TICKET_API_URL=https://app.nhanceindia.in/zenith/api
|
||||
ticketToken=3YTSia2mRoZ7A4zvBgkqbGPrCd6Ewp8IDOuyjXhVFsl1nxWNcQJ95MeUftKH
|
||||
BASE_HREF=/nhance/app/dev/
|
||||
ENV=development
|
||||
BASE_HREF=/app/
|
||||
ENV=production
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
API_URL=https://venbait.in/nhance/dev/employeeRest/
|
||||
#CHAT_BOT_URL=https://venbait.in/nhance/dev
|
||||
API_URL_Enrollment=https://venbait.in/enrollment/employeeRest/
|
||||
TICKET_API_URL=https://venbait.in/nhance/dev/api
|
||||
API_URL=https://app.nhanceindia.in/zenith/employeeRest/
|
||||
API_URL_Enrollment=https://app.nhanceindia.in/enrolment/employeeRest/
|
||||
TICKET_API_URL=https://app.nhanceindia.in/zenith/api
|
||||
ticketToken=3YTSia2mRoZ7A4zvBgkqbGPrCd6Ewp8IDOuyjXhVFsl1nxWNcQJ95MeUftKH
|
||||
BASE_HREF=/nhance/app/dev/
|
||||
ENV=development
|
||||
BASE_HREF=/app/
|
||||
ENV=production
|
||||
25
.metadata
25
.metadata
@ -4,7 +4,7 @@
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "300451adae589accbece3490f4396f10bdf15e6e"
|
||||
revision: "05db9689081f091050f01aed79f04dce0c750154"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
@ -13,26 +13,11 @@ project_type: app
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: android
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: ios
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: linux
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: macos
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
create_revision: 05db9689081f091050f01aed79f04dce0c750154
|
||||
base_revision: 05db9689081f091050f01aed79f04dce0c750154
|
||||
- platform: web
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: windows
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
create_revision: 05db9689081f091050f01aed79f04dce0c750154
|
||||
base_revision: 05db9689081f091050f01aed79f04dce0c750154
|
||||
|
||||
# User provided section
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ android {
|
||||
applicationId "nh.ind.nhance.benefits"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||
minSdkVersion 23
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
targetSdkVersion flutter.targetSdkVersion
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
||||
@ -21,6 +21,6 @@
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>12.0</string>
|
||||
<string>13.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@ -13,7 +13,6 @@ import 'package:nhance_app_pwa/pages/postEnrollment/botman_widget.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/chatbot.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/claimprocess.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/claims.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/claimtracklist.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/generalexclusionsdeductibles.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/help.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/home.dart';
|
||||
@ -21,8 +20,10 @@ import 'package:nhance_app_pwa/pages/postEnrollment/planclaimsform.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/policies.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/privacypolicy.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/profile.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/raisedTicketList.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/termsofuse.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/tickets.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/tickettracklist.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/wellness.dart';
|
||||
import 'package:nhance_app_pwa/pages/session/SetPinBiometric.dart';
|
||||
import 'package:nhance_app_pwa/pages/session/changePin.dart';
|
||||
@ -99,14 +100,33 @@ Future<void> main() async {
|
||||
|
||||
await dotenv.load(fileName: Environment.fileName);
|
||||
|
||||
runApp(MyApp());
|
||||
// ✅ Get prefs
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// ✅ Decide initialRoute
|
||||
String initialRoute = 'login';
|
||||
if (!kIsWeb) {
|
||||
if (prefs.containsKey('is_mpin_skipped')) {
|
||||
final isMpinSkipped = prefs.getString('is_mpin_skipped');
|
||||
if (isMpinSkipped == '0') {
|
||||
initialRoute = 'pinPage';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runApp(MyApp(initialRoute: initialRoute));
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
final String initialRoute;
|
||||
|
||||
const MyApp({super.key, required this.initialRoute});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
initialRoute: 'login',
|
||||
// initialRoute: 'login',
|
||||
initialRoute: initialRoute,
|
||||
debugShowCheckedModeBanner: false,
|
||||
routes: {
|
||||
'splash': (context) => SplashScreen(),
|
||||
@ -131,7 +151,7 @@ class MyApp extends StatelessWidget {
|
||||
'profile': (context) => profile(),
|
||||
'wellness': (context) => wellness(),
|
||||
'planclaimsform': (context) => planclaimsform(),
|
||||
'claimtracklist': (context) => claimtracklist(
|
||||
'tickettracklist': (context) => tickettracklist(
|
||||
ticketID: "",
|
||||
),
|
||||
'privacypolicy': (context) => privacypolicy(),
|
||||
@ -155,6 +175,7 @@ class MyApp extends StatelessWidget {
|
||||
'addOnsDetails': (context) => addOnsDetails(),
|
||||
'empReviewDetails': (context) => empReviewDetails(),
|
||||
'tickets': (context) => tickets(),
|
||||
'raisedTicketHistory': (context) => raisedTicketHistory(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -1875,7 +1875,7 @@ class _addOnsDetailsState extends State<addOnsDetails> {
|
||||
color: Colors.white,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 75,
|
||||
height: 80,
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 20, bottom: 20, left: 30, right: 30)
|
||||
@ -1889,13 +1889,13 @@ class _addOnsDetailsState extends State<addOnsDetails> {
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
width: 150,
|
||||
height: 150,
|
||||
width: 200,
|
||||
height: 200,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Image.network(
|
||||
clientLogo ?? '',
|
||||
width: 80, // Set the width here
|
||||
height: 80, // Set the height here
|
||||
// width: 200, // Set the width here
|
||||
// height: 200, // Set the height here
|
||||
loadingBuilder: (BuildContext context,
|
||||
Widget child,
|
||||
ImageChunkEvent? loadingProgress) {
|
||||
@ -1903,13 +1903,13 @@ class _addOnsDetailsState extends State<addOnsDetails> {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
value:
|
||||
loadingProgress.expectedTotalBytes !=
|
||||
null
|
||||
? loadingProgress
|
||||
.cumulativeBytesLoaded /
|
||||
loadingProgress
|
||||
.expectedTotalBytes!
|
||||
: null,
|
||||
loadingProgress.expectedTotalBytes !=
|
||||
null
|
||||
? loadingProgress
|
||||
.cumulativeBytesLoaded /
|
||||
loadingProgress
|
||||
.expectedTotalBytes!
|
||||
: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@ -680,7 +680,7 @@ class _empDetailsState extends State<empDetails> {
|
||||
color: Colors.white,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 75,
|
||||
height: 80,
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 20, bottom: 20, left: 30, right: 30)
|
||||
@ -694,13 +694,13 @@ class _empDetailsState extends State<empDetails> {
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
width: 150,
|
||||
height: 150,
|
||||
width: 200,
|
||||
height: 200,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Image.network(
|
||||
clientLogo ?? '',
|
||||
width: 80, // Set the width here
|
||||
height: 80, // Set the height here
|
||||
// width: 200, // Set the width here
|
||||
// height: 200, // Set the height here
|
||||
loadingBuilder: (BuildContext context,
|
||||
Widget child,
|
||||
ImageChunkEvent? loadingProgress) {
|
||||
|
||||
@ -1395,7 +1395,7 @@ class _empReviewDetailsState extends State<empReviewDetails> {
|
||||
color: Colors.white,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 75,
|
||||
height: 80,
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 20, bottom: 20, left: 30, right: 30)
|
||||
@ -1409,13 +1409,13 @@ class _empReviewDetailsState extends State<empReviewDetails> {
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
width: 150,
|
||||
height: 150,
|
||||
width: 200,
|
||||
height: 200,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Image.network(
|
||||
clientLogo ?? '',
|
||||
width: 80, // Set the width here
|
||||
height: 80, // Set the height here
|
||||
// width: 200, // Set the width here
|
||||
// height: 200, // Set the height here
|
||||
loadingBuilder: (BuildContext context,
|
||||
Widget child,
|
||||
ImageChunkEvent? loadingProgress) {
|
||||
@ -1423,13 +1423,13 @@ class _empReviewDetailsState extends State<empReviewDetails> {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
value:
|
||||
loadingProgress.expectedTotalBytes !=
|
||||
null
|
||||
? loadingProgress
|
||||
.cumulativeBytesLoaded /
|
||||
loadingProgress
|
||||
.expectedTotalBytes!
|
||||
: null,
|
||||
loadingProgress.expectedTotalBytes !=
|
||||
null
|
||||
? loadingProgress
|
||||
.cumulativeBytesLoaded /
|
||||
loadingProgress
|
||||
.expectedTotalBytes!
|
||||
: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@ -43,7 +43,7 @@ class _loginState extends State<login> {
|
||||
void initState() {
|
||||
countryController.text = "+91";
|
||||
super.initState();
|
||||
checkLoginPinOnMobile();
|
||||
// checkLoginPinOnMobile();
|
||||
}
|
||||
|
||||
Future<void> checkLoginPinOnMobile() async {
|
||||
|
||||
@ -1,83 +1,6 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:webview_flutter/webview_flutter.dart';
|
||||
//
|
||||
// class BotmanChatPage extends StatefulWidget {
|
||||
// const BotmanChatPage({super.key});
|
||||
//
|
||||
// @override
|
||||
// State<BotmanChatPage> createState() => _BotmanChatPageState();
|
||||
// }
|
||||
//
|
||||
// class _BotmanChatPageState extends State<BotmanChatPage> {
|
||||
// late final WebViewController _controller;
|
||||
//
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
//
|
||||
// _controller = WebViewController()
|
||||
// ..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
// ..loadHtmlString(_htmlContent);
|
||||
// }
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Scaffold(
|
||||
// appBar: AppBar(title: const Text('Ask ILA')),
|
||||
// body: WebViewWidget(controller: _controller),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// const String _htmlContent = '''
|
||||
// <!DOCTYPE html>
|
||||
// <html lang="en">
|
||||
// <head>
|
||||
// <meta charset="UTF-8" />
|
||||
// <meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
// <style>
|
||||
// html, body {
|
||||
// margin: 0;
|
||||
// padding: 0;
|
||||
// height: 100%;
|
||||
// }
|
||||
// #botmanWidgetRoot svg {
|
||||
// display: none !important;
|
||||
// }
|
||||
// </style>
|
||||
// <script>
|
||||
// const APIENDPOINT = 'https://venbait.in/nhance/chatbot';
|
||||
// const APIAPIENDPOINT = 'https://venbait.in/nhance/chatbot';
|
||||
//
|
||||
// window.botmanWidget = {
|
||||
// chatServer: APIENDPOINT + '/chat',
|
||||
// frameEndpoint: APIAPIENDPOINT + '/widget',
|
||||
// title: 'Ask ILA',
|
||||
// introMessage: 'Hai Suren',
|
||||
// bubbleBackground: '#007bff',
|
||||
// mainColor: '#007bff',
|
||||
// placeholderText: 'Type your message here...',
|
||||
// aboutText: 'Insurance Assistant ILA',
|
||||
// enableAttachments: false,
|
||||
// parameters: {
|
||||
// employee_id: '12288',
|
||||
// session_id: 'XYZ789',
|
||||
// origin: 'mobile',
|
||||
// emp_code: 'HTL-007',
|
||||
// client_id: 159,
|
||||
// client_branch_id: 125,
|
||||
// },
|
||||
// };
|
||||
// </script>
|
||||
// <script src="https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js"></script>
|
||||
// </head>
|
||||
// <body>
|
||||
// </body>
|
||||
// </html>
|
||||
// ''';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class ChatbotWebViewPage extends StatefulWidget {
|
||||
final String client_branch_id;
|
||||
@ -105,11 +28,42 @@ class _ChatbotWebViewPageState extends State<ChatbotWebViewPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
final url = Uri.parse(
|
||||
'https://venbait.in/nhance/dev/chatbot'
|
||||
'?employee_id=${widget.empPrimaryId}'
|
||||
'&emp_code=${widget.empCodeString}'
|
||||
'&origin=mob'
|
||||
'&name=${widget.empName}'
|
||||
'&client_id=${widget.client_id}'
|
||||
'&client_branch_id=${widget.client_branch_id}',
|
||||
);
|
||||
|
||||
_controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..loadRequest(
|
||||
Uri.parse('https://venbait.in/nhance/dev/chatbot?employee_id=${widget.empPrimaryId}&emp_code=${widget.empCodeString}&origin=mob&name=${widget.empName}&client_id=${widget.client_id}&client_branch_id=${widget.client_branch_id}'),
|
||||
);
|
||||
..setBackgroundColor(Colors.transparent)
|
||||
..setNavigationDelegate(
|
||||
NavigationDelegate(
|
||||
onNavigationRequest: (NavigationRequest request) {
|
||||
debugPrint("Clicked URL: ${request.url}");
|
||||
_launchInExternalBrowser(Uri.parse(request.url));
|
||||
return NavigationDecision.prevent; // prevent WebView navigation
|
||||
},
|
||||
onWebResourceError: (error) {
|
||||
debugPrint("WebView error: ${error.description}");
|
||||
},
|
||||
),
|
||||
)
|
||||
..loadRequest(url);
|
||||
}
|
||||
|
||||
/// Launch URL in external browser (Chrome or default)
|
||||
Future<void> _launchInExternalBrowser(Uri url) async {
|
||||
if (await canLaunchUrl(url)) {
|
||||
await launchUrl(url, mode: LaunchMode.externalApplication);
|
||||
} else {
|
||||
debugPrint("Could not launch $url");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -733,6 +733,7 @@ class _claimsState extends State<claims> {
|
||||
String policyEndDate = item['policy_end_date'];
|
||||
String policyNo = item['policy_no'];
|
||||
String clientPolicyId = item['client_policy_id'];
|
||||
String sumInsuredLabel = item['sum_insured_label'];
|
||||
List<dynamic> employeePolicy = item['EmployeePolicy'];
|
||||
|
||||
return GestureDetector(
|
||||
@ -835,7 +836,7 @@ class _claimsState extends State<claims> {
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'Cover Amount',
|
||||
sumInsuredLabel ?? '',
|
||||
textAlign: TextAlign.end,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
@ -1098,7 +1099,7 @@ class _claimsState extends State<claims> {
|
||||
DateTime date = DateTime.parse(timestamp);
|
||||
|
||||
// Format the DateTime object with date and time
|
||||
String formattedDate = DateFormat('d MMM, y HH:mm a').format(date);
|
||||
String formattedDate = DateFormat('d MMM y hh:mm a').format(date);
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../customAppBar/responsive.dart';
|
||||
|
||||
@ -37,6 +38,29 @@ class _ClaimHistoryPopupState extends State<ClaimHistoryPopup> {
|
||||
late Map<String, dynamic> stepMap;
|
||||
int _index = 4;
|
||||
bool isLoading = false;
|
||||
List<dynamic> claimFiles = [];
|
||||
// final List<Map<String, dynamic>> claimFiles = [
|
||||
// {
|
||||
// "claim_file_id": "23",
|
||||
// "claim_file_name": "1757420176_c2c92a7393b75677a5bb.png",
|
||||
// "url": "https://venbait.in/nhance/dev/downloadClaimFile/23"
|
||||
// },
|
||||
// {
|
||||
// "claim_file_id": "24",
|
||||
// "claim_file_name": "1757420176_7ff43ded77125ae390d0.png",
|
||||
// "url": "https://venbait.in/nhance/dev/downloadClaimFile/24"
|
||||
// },
|
||||
// {
|
||||
// "claim_file_id": "25",
|
||||
// "claim_file_name": "1757420176_193139b931f3bbf792f2.png",
|
||||
// "url": "https://venbait.in/nhance/dev/downloadClaimFile/25"
|
||||
// },
|
||||
// {
|
||||
// "claim_file_id": "26",
|
||||
// "claim_file_name": "1757420176_f66188d9ebf2580ed0f1.png",
|
||||
// "url": "https://venbait.in/nhance/dev/downloadClaimFile/26"
|
||||
// }
|
||||
// ];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -73,6 +97,11 @@ class _ClaimHistoryPopupState extends State<ClaimHistoryPopup> {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
print('Claims History List1');
|
||||
final claimsDocs = response['data']['claim_files'];
|
||||
print("TC1 - $claimsDocs");
|
||||
|
||||
claimFiles = List<Map<String, dynamic>>.from(claimsDocs);
|
||||
print('claimFiles $claimFiles');
|
||||
// final List<dynamic> ticketDataList = response['data']['ticket_data'];
|
||||
// final Map<String, dynamic> ticketDataMap =
|
||||
// response['data']['ticket_data'];
|
||||
@ -136,6 +165,18 @@ class _ClaimHistoryPopupState extends State<ClaimHistoryPopup> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _launchURL(String url) async {
|
||||
final Uri uri = Uri.parse(url); // Parse the URL properly
|
||||
print('_launchURL $uri');
|
||||
if (uri != null) {
|
||||
print('If $uri');
|
||||
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||
} else {
|
||||
print('else $uri');
|
||||
throw 'Could not launch $url';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// if (getClaimsHistoryList.isEmpty) {
|
||||
@ -428,6 +469,30 @@ class _ClaimHistoryPopupState extends State<ClaimHistoryPopup> {
|
||||
)),
|
||||
),
|
||||
),
|
||||
|
||||
Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
|
||||
child: claimFiles.isEmpty
|
||||
? const Center(child: Text("No files available"))
|
||||
: SizedBox( // ✅ Give ListView a fixed height
|
||||
height: 300,
|
||||
child: ListView.builder(
|
||||
itemCount: claimFiles.length,
|
||||
itemBuilder: (context, index) {
|
||||
final file = claimFiles[index];
|
||||
return Card(
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.insert_drive_file, color: Colors.blue),
|
||||
title: Text(file['claim_file_name']),
|
||||
trailing: const Icon(Icons.download, color: Colors.green),
|
||||
onTap: () => _launchURL(file['url']),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -83,9 +83,9 @@ class _HomeState extends State<Home> {
|
||||
if (kIsWeb) {
|
||||
openBotmanChat();
|
||||
|
||||
setupBackButtonHandler(() {
|
||||
if (!_dialogShown) _showBackConfirmationDialog();
|
||||
});
|
||||
// setupBackButtonHandler(() {
|
||||
// if (!_dialogShown) _showBackConfirmationDialog();
|
||||
// });
|
||||
|
||||
// Push a dummy state so back button triggers popstate instead of navigating
|
||||
// html.window.history.pushState(null, 'home', html.window.location.href);
|
||||
@ -922,7 +922,7 @@ class _HomeState extends State<Home> {
|
||||
String memberNames = getMemberNames(employeePolicy);
|
||||
|
||||
DateTime parsedDate = DateFormat('dd-MMM-yyyy').parse(policyEndDate);
|
||||
String formattedDate = DateFormat('d MMM, yyyy').format(parsedDate);
|
||||
String formattedDate = DateFormat('d MMM yyyy').format(parsedDate);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
|
||||
@ -1,17 +1,24 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
import 'package:nhance_app_pwa/customAppBar/customAppBar.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/claimtracklist.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/service/file_upload_service.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/service/multi_file_upload_widget.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../customAppBar/customFooter.dart';
|
||||
import '../../customAppBar/responsive.dart';
|
||||
import '../../customAppBar/tabs.dart';
|
||||
import '../../customAppBar/toastHelper.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
// import 'package:universal_html/html.dart' as html;
|
||||
|
||||
import '../../models/environment.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
|
||||
class planclaimsform extends StatefulWidget {
|
||||
const planclaimsform({Key? key}) : super(key: key);
|
||||
@ -46,6 +53,7 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
String? selectedServiceName;
|
||||
String? selectedPolicyNo;
|
||||
dynamic claimsDepartmentId;
|
||||
dynamic claimSubject;
|
||||
dynamic rawPolicyStartDate;
|
||||
dynamic rawPolicyEndDate;
|
||||
dynamic claimsPolicyNo;
|
||||
@ -55,6 +63,12 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
dynamic client_policy_id;
|
||||
dynamic selfDetails;
|
||||
List<Map<String, dynamic>> employeePolicyList = [];
|
||||
String? selectedFileNames;
|
||||
// html.File? uploadedFile;
|
||||
// List<html.File> uploadedFiles = [];
|
||||
List<PlatformFile> uploadedFiles = [];
|
||||
final fileService = FileUploadService();
|
||||
|
||||
|
||||
// Declare subjectController and bodyController as instance variables
|
||||
late TextEditingController subjectController;
|
||||
@ -100,6 +114,7 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
fileService.clearAll();
|
||||
subjectController = TextEditingController();
|
||||
messageController = TextEditingController();
|
||||
accidentDetailsController = TextEditingController();
|
||||
@ -118,6 +133,7 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
||||
// Dispose the controllers to avoid memory leaks
|
||||
subjectController.dispose();
|
||||
messageController.dispose();
|
||||
@ -151,6 +167,8 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
print('fromClaimsPage $fromClaimsPage');
|
||||
}
|
||||
if (fromClaimsPage == 0) {
|
||||
claimSubject = claimsDetails['claim_subject'];
|
||||
print('claimSubject $claimSubject');
|
||||
claimsDepartmentId = claimsDetails['ticket_type_id'];
|
||||
rawPolicyStartDate = claimsDetails['policy_start_date'];
|
||||
print('rawPolicyStartDate $rawPolicyStartDate');
|
||||
@ -163,6 +181,7 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
// print('employeePolicyList : $employeePolicyList');
|
||||
List<dynamic> empList = claimsDetails['EmployeePolicy'];
|
||||
setState(() {
|
||||
subjectController.text = claimSubject;
|
||||
employeePolicyList = empList.map((memberList) {
|
||||
return {
|
||||
'id': int.parse(memberList['id']),
|
||||
@ -303,7 +322,7 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
isLoading = true;
|
||||
});
|
||||
try {
|
||||
final response = await apiService.fetchDepartmentList();
|
||||
final response = await apiService.fetchDepartmentList(client_id!, empCodeString!);
|
||||
print(response);
|
||||
if (response['ticket_type'] != null) {
|
||||
print(response['ticket_type']);
|
||||
@ -364,6 +383,7 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
'id': index + 1, // Use index + 1 as a unique ID
|
||||
'policy_start_date' : policy['policy_start_date'],
|
||||
'claims_grace_date' : policy['claims_grace_date'],
|
||||
'claim_subject' : policy['claim_subject'],
|
||||
};
|
||||
}).toList();
|
||||
|
||||
@ -445,6 +465,8 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
print('Filtered matching policy_no: $filteredPoliciesList');
|
||||
|
||||
client_policy_id = filteredPoliciesList[0]['client_policy_id'];
|
||||
subjectController.text = filteredPoliciesList[0]['claim_subject'];
|
||||
|
||||
|
||||
if (filteredPoliciesList.isNotEmpty) {
|
||||
// Assuming you need to access the first matched policy
|
||||
@ -525,7 +547,7 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
// print('Help $filteredPoliciesList');
|
||||
try {
|
||||
print('Check One');
|
||||
Map<String, dynamic> formData = {
|
||||
Map<String, dynamic> fields = {
|
||||
// 'opener': 'user',
|
||||
'emp_id': emp_id,
|
||||
'client_policy_id': client_policy_id,
|
||||
@ -578,13 +600,13 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
// formData['emp_policy_id'] = selectedMemberId;
|
||||
// } else
|
||||
if (policyTypeCondition == 1) {
|
||||
formData['hospital_name'] = hospitalNameController.text;
|
||||
formData['doa'] = admitDateController.text;
|
||||
formData['dod'] = dischargeDateController.text;
|
||||
formData['claim_amount'] = claimAmountController.text;
|
||||
formData['policyholder_name'] = employeePolicyList[0]['name'];
|
||||
formData['member_name'] = selectedMemberName;
|
||||
formData['insured_emp_id'] = selectedMemberId;
|
||||
fields['hospital_name'] = hospitalNameController.text;
|
||||
fields['doa'] = admitDateController.text;
|
||||
fields['dod'] = dischargeDateController.text;
|
||||
fields['claim_amount'] = claimAmountController.text;
|
||||
fields['policyholder_name'] = employeePolicyList[0]['name'];
|
||||
fields['member_name'] = selectedMemberName;
|
||||
fields['insured_emp_id'] = selectedMemberId;
|
||||
} else {
|
||||
String formattedAccidentDate =
|
||||
DateFormat('yyyy-MM-dd').format(accidentDate!);
|
||||
@ -594,23 +616,73 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
DateFormat('yyyy-MM-dd').format(intimationDate!);
|
||||
// formData['accident_details'] = accidentDetailsController.text;
|
||||
// formData['accident_details'] = messageController.text;
|
||||
formData['date_of_accident'] = formattedAccidentDate;
|
||||
formData['dob'] = formattedBirthDate;
|
||||
formData['date_of_intimat'] = formattedIntimationDate;
|
||||
formData['date_of_death'] = formattedDeathDate;
|
||||
formData['si_amt'] = sumInsuredController.text;
|
||||
formData['policyholder_name'] = employeePolicyList[0]['name'];
|
||||
formData['member_name'] = selectedMemberName;
|
||||
formData['insured_emp_id'] = selectedMemberId;
|
||||
fields['date_of_accident'] = formattedAccidentDate;
|
||||
fields['dob'] = formattedBirthDate;
|
||||
fields['date_of_intimat'] = formattedIntimationDate;
|
||||
fields['date_of_death'] = formattedDeathDate;
|
||||
fields['si_amt'] = sumInsuredController.text;
|
||||
fields['policyholder_name'] = employeePolicyList[0]['name'];
|
||||
fields['member_name'] = selectedMemberName;
|
||||
fields['insured_emp_id'] = selectedMemberId;
|
||||
}
|
||||
|
||||
// Convert integer values to strings
|
||||
formData = formData.map((key, value) => MapEntry(key, value.toString()));
|
||||
// Multipart request
|
||||
|
||||
final response = await apiService.sendFormDataToApi(formData);
|
||||
// final request = http.MultipartRequest('POST', Uri.parse('${Environment.apiUrl}/initiateClaim'));
|
||||
// request.headers['Authorization'] = 'Bearer $_token';
|
||||
// final stringFields = fields.map((key, value) => MapEntry(key, value?.toString() ?? ''));
|
||||
// request.fields.addAll(stringFields);
|
||||
//
|
||||
// if (uploadedFile != null) {
|
||||
// final reader = html.FileReader();
|
||||
// reader.readAsArrayBuffer(uploadedFile!);
|
||||
// await reader.onLoad.first;
|
||||
//
|
||||
// final data = reader.result as Uint8List;
|
||||
//
|
||||
// request.files.add(http.MultipartFile.fromBytes(
|
||||
// 'claim_docs',
|
||||
// data,
|
||||
// filename: uploadedFile!.name,
|
||||
// ));
|
||||
// }
|
||||
|
||||
if (response['status'] == true) {
|
||||
ToastHelper.showSuccessToast(context, response['message']);
|
||||
final request = http.MultipartRequest('POST', Uri.parse('${Environment.apiUrl}/initiateClaim'));
|
||||
request.headers['Authorization'] = 'Bearer $_token';
|
||||
final stringFields = fields.map((key, value) => MapEntry(key, value?.toString() ?? ''));
|
||||
request.fields.addAll(stringFields);
|
||||
|
||||
// 🔥 Loop through multiple files
|
||||
// for (var file in uploadedFiles) {
|
||||
// final reader = html.FileReader();
|
||||
// reader.readAsArrayBuffer(file);
|
||||
// await reader.onLoad.first;
|
||||
// final data = reader.result as Uint8List;
|
||||
//
|
||||
// request.files.add(http.MultipartFile.fromBytes(
|
||||
// 'claim_docs[]', // 👈 if backend expects array
|
||||
// data,
|
||||
// filename: file.name,
|
||||
// ));
|
||||
// }
|
||||
uploadedFiles = FileUploadService().files;
|
||||
print("Files available globally: ${uploadedFiles.map((f) => f.name).toList()}");
|
||||
for (var file in uploadedFiles) {
|
||||
if (file.bytes != null) {
|
||||
request.files.add(http.MultipartFile.fromBytes(
|
||||
'claim_docs[]',
|
||||
file.bytes!,
|
||||
filename: file.name,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
final response = await request.send();
|
||||
final responseBody = await response.stream.bytesToString();
|
||||
|
||||
final decoded = jsonDecode(responseBody);
|
||||
if (decoded['status'] == true) {
|
||||
ToastHelper.showSuccessToast(context, decoded['message']);
|
||||
serviceId = null;
|
||||
departmentList.clear();
|
||||
setState(() {
|
||||
@ -618,14 +690,18 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
});
|
||||
Navigator.pushNamed(context, 'claims');
|
||||
print('Form data submitted successfully');
|
||||
fileService.clearAll();
|
||||
} else {
|
||||
print('Failed to submit form data: ${response['status']}');
|
||||
ToastHelper.showErrorToast(context, "Failed: ${decoded['message']}");
|
||||
}
|
||||
|
||||
|
||||
} catch (e) {
|
||||
print('Error submitting form data: $e');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> _pickDate(BuildContext context, String label) async {
|
||||
final DateTime? pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
@ -661,14 +737,15 @@ class _planclaimsformState extends State<planclaimsform> {
|
||||
setState(() {
|
||||
admitDate = pickedDateRange.start;
|
||||
dischargeDate = pickedDateRange.end;
|
||||
admitDateController.text = DateFormat('yyyy-MM-dd').format(admitDate!);
|
||||
admitDateController.text = DateFormat('dd-MM-yyyy').format(admitDate!);
|
||||
dischargeDateController.text =
|
||||
DateFormat('yyyy-MM-dd').format(dischargeDate!);
|
||||
DateFormat('dd-MM-yyyy').format(dischargeDate!);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Future<void> _pickFromToDate(BuildContext context) async {
|
||||
// final DateTimeRange? pickedDateRange = await showDateRangePicker(
|
||||
// context: context,
|
||||
@ -1026,10 +1103,10 @@ SizedBox(height: 15),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildTextField('Subject',
|
||||
subjectController),
|
||||
if (!isSubjectValid)
|
||||
Text('Please enter the Subject', style: TextStyle(color: Colors.red)),
|
||||
// buildTextField('Subject',
|
||||
// subjectController),
|
||||
// if (!isSubjectValid)
|
||||
// Text('Please enter the Subject', style: TextStyle(color: Colors.red)),
|
||||
SizedBox(height: 15),
|
||||
buildTextAreaField(
|
||||
'Message',
|
||||
@ -1157,7 +1234,28 @@ SizedBox(height: 15),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
SizedBox(height: 15),
|
||||
// ThemedUploadField(
|
||||
// hintText: "Upload Documents",
|
||||
// txtwidth: MediaQuery.of(context).size.width < 600
|
||||
// ? MediaQuery.of(context).size.width // Full width on mobile
|
||||
// : MediaQuery.of(context).size.width * 0.26, // 26% on desktop
|
||||
// txtheight: 45,
|
||||
// onFilesSelected: (files) {
|
||||
// print("Picked files: ${files.map((f) => f.name).toList()}");
|
||||
// setState(() {
|
||||
// uploadedFiles = files; // store all selected files
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const MultiFileUploadWidget(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -1270,7 +1368,8 @@ SizedBox(height: 15),
|
||||
"Profile",
|
||||
"Help",
|
||||
"Wellness",
|
||||
], // Initial index of the bottom navigation bar
|
||||
],
|
||||
initialIndex: 1,// Initial index of the bottom navigation bar
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -1336,7 +1435,7 @@ SizedBox(height: 15),
|
||||
),
|
||||
child: Text(
|
||||
selectedDate != null
|
||||
? DateFormat('yyyy-MM-dd').format(selectedDate)
|
||||
? DateFormat('dd-MM-yyyy').format(selectedDate)
|
||||
: 'Select $label',
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
|
||||
@ -92,7 +92,7 @@ class _policiesState extends State<policies> {
|
||||
String convertDateFormat(String date) {
|
||||
// Define input and output date formats
|
||||
DateFormat inputFormat = DateFormat('dd-MMM-yyyy');
|
||||
DateFormat outputFormat = DateFormat('d MMM, yyyy');
|
||||
DateFormat outputFormat = DateFormat('d MMM yyyy');
|
||||
|
||||
// Parse the input date string
|
||||
DateTime parsedDate = inputFormat.parse(date);
|
||||
@ -1034,7 +1034,7 @@ class _policiesState extends State<policies> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
buildExpandedColumn(
|
||||
context, 'Cover Amount', '₹ ${argumentsData['si_value']}'),
|
||||
context, argumentsData['sum_insured_label'], '₹ ${argumentsData['si_value']}'),
|
||||
buildExpandedColumn(context, 'Policy No', argumentsData['policy_no']),
|
||||
buildExpandedColumn(context, 'Policy Expiry',
|
||||
convertDateFormat(argumentsData['policy_end_date'])),
|
||||
@ -1058,7 +1058,7 @@ class _policiesState extends State<policies> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
buildExpandedColumn(
|
||||
context, 'Cover Amount', '₹ ${argumentsData['si_value']}'),
|
||||
context, argumentsData['sum_insured_label'], '₹ ${argumentsData['si_value']}'),
|
||||
buildExpandedColumn(context, 'Policy Expiry',
|
||||
convertDateFormat(argumentsData['policy_end_date'])),
|
||||
],
|
||||
|
||||
@ -115,7 +115,7 @@ class _profileState extends State<profile> {
|
||||
|
||||
String convertDate(String dateString) {
|
||||
DateTime date = DateTime.parse(dateString);
|
||||
DateFormat formatter = DateFormat('dd MMMM, yyyy');
|
||||
DateFormat formatter = DateFormat('dd MMM yyyy');
|
||||
return formatter.format(date);
|
||||
}
|
||||
|
||||
@ -169,15 +169,17 @@ class _profileState extends State<profile> {
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// Get the value of the mobile_number key
|
||||
|
||||
String? mobileNumber = prefs.getString('empMobileNo');
|
||||
String? mailID = prefs.getString('empEmailid');
|
||||
final isMpinSkipped = prefs.getString('is_mpin_skipped');
|
||||
|
||||
// bool? biometricStatus = prefs.getBool('biometricStatus') ?? false;
|
||||
// int? skipStatus = prefs.getInt('skipStatus') ?? 1;
|
||||
|
||||
// Clear all keys
|
||||
await prefs.clear();
|
||||
print('Local Storage Clear');
|
||||
print('Local Storage Clear');
|
||||
|
||||
// html.window.localStorage.clear();
|
||||
// Re-set the mobile_number key
|
||||
@ -192,10 +194,20 @@ class _profileState extends State<profile> {
|
||||
// await prefs.setBool('biometricStatus', biometricStatus!);
|
||||
// await prefs.setInt('skipStatus', skipStatus!);
|
||||
}
|
||||
await prefs.setString('is_mpin_skipped', isMpinSkipped!);
|
||||
print('isMpinSkipped $isMpinSkipped');
|
||||
if (isMpinSkipped != null && isMpinSkipped == '0') {
|
||||
Navigator.pushReplacementNamed(context, 'pinPage');
|
||||
} else {
|
||||
Navigator.pushReplacementNamed(context, 'login');
|
||||
}
|
||||
} else {
|
||||
ToastHelper.showSuccessToast(context, 'logout');
|
||||
// Navigate to login page
|
||||
Navigator.pushNamed(context, 'login');
|
||||
}
|
||||
ToastHelper.showSuccessToast(context, 'logout');
|
||||
// Navigate to login page
|
||||
Navigator.pushNamed(context, 'login');
|
||||
|
||||
|
||||
// } else {
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
// await prefs.clear();
|
||||
@ -594,6 +606,7 @@ class _profileState extends State<profile> {
|
||||
)
|
||||
])),
|
||||
SizedBox(height: 12),
|
||||
if(Responsive.isMobile(context))
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
|
||||
586
lib/pages/postEnrollment/raisedTicketList.dart
Normal file
586
lib/pages/postEnrollment/raisedTicketList.dart
Normal file
@ -0,0 +1,586 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
import 'package:nhance_app_pwa/customAppBar/customAppBar.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/service/svg_service.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/tickettracklist.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../customAppBar/customFooter.dart';
|
||||
import '../../customAppBar/responsive.dart';
|
||||
import '../../customAppBar/tabs.dart';
|
||||
import '../../customAppBar/toastHelper.dart';
|
||||
|
||||
class raisedTicketHistory extends StatefulWidget {
|
||||
const raisedTicketHistory({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<raisedTicketHistory> createState() => _raisedTicketHistoryState();
|
||||
}
|
||||
|
||||
class _raisedTicketHistoryState extends State<raisedTicketHistory> {
|
||||
bool isLoading = false;
|
||||
late ApiService apiService;
|
||||
int _currentIndex = 0;
|
||||
dynamic _token;
|
||||
dynamic decodedToken;
|
||||
dynamic empCodeString;
|
||||
dynamic empPrimaryId;
|
||||
dynamic client_id;
|
||||
dynamic empName;
|
||||
dynamic policyList;
|
||||
dynamic policyDataIsEmpty = 1;
|
||||
dynamic trackClaimsIsEmpty = 1;
|
||||
dynamic policyHeading;
|
||||
dynamic policyName;
|
||||
dynamic EmployeePolicy;
|
||||
List<Map<String, String>> employeeDetails = [];
|
||||
dynamic argumentsData;
|
||||
dynamic empMobileNo;
|
||||
List<dynamic> reversedClaimsList = [];
|
||||
List<dynamic> trackClaimsList = [];
|
||||
int trackClaimsActive = 1;
|
||||
int yourPlanActive = 0;
|
||||
int? serviceId;
|
||||
dynamic client_branch_id;
|
||||
dynamic mobileNo;
|
||||
List<dynamic> reversedTicketList = [];
|
||||
|
||||
List<dynamic> ticketList = [];
|
||||
|
||||
final Map<String, Color> statusColors = {
|
||||
'Open': Colors.green,
|
||||
'In Progress': Colors.blue,
|
||||
// 'Awaiting Reply': Colors.orange,
|
||||
'Resolved': Colors.yellow,
|
||||
'Closed': Colors.red,
|
||||
};
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
apiService = ApiService(context);
|
||||
_loadToken();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _loadToken() async {
|
||||
print('_loadToken');
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
final String? token = prefs.getString('_postToken');
|
||||
if (token != null && token.isNotEmpty) {
|
||||
setState(() {
|
||||
_token = token;
|
||||
});
|
||||
// Decode the JWT token received from the API response
|
||||
decodedToken = Jwt.parseJwt(token);
|
||||
print(decodedToken);
|
||||
mobileNo = decodedToken['mobile'];
|
||||
client_branch_id = decodedToken['client_branch_id'];
|
||||
empMobileNo = decodedToken['mobile'];
|
||||
empName = decodedToken['name'];
|
||||
empCodeString = prefs.getString('empCode');
|
||||
print(empCodeString); // Check if emp_code is correct
|
||||
empPrimaryId = prefs.getString('empPrimaryId');
|
||||
client_id = prefs.getString('client_id');
|
||||
print(client_id);
|
||||
getTicketList();
|
||||
} else {
|
||||
// Token is empty or null, handle accordingly (e.g., navigate to login screen)
|
||||
// For now, let's navigate to the login screen
|
||||
ToastHelper.showErrorToast(context, 'Session Out');
|
||||
Navigator.pushReplacementNamed(context, 'login');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getTicketList() async {
|
||||
if (client_id == null || empCodeString == null) {
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
print('check getTicketList 1');
|
||||
final response = await apiService.getTicketListByMobile(empMobileNo!);
|
||||
print('check getTicketList 2');
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
// if (response['success'] == true && response['data'] is List) {
|
||||
setState(() {
|
||||
ticketList = response['data'].toList();
|
||||
print("TC1 - $ticketList");
|
||||
reversedTicketList = List<Map<String, dynamic>>.from(ticketList);
|
||||
reversedTicketList = List<Map<String, dynamic>>.from(ticketList);
|
||||
print("TC2 - $ticketList");
|
||||
// ticketList = reversedTicketList.reversed.toList();
|
||||
ticketList = reversedTicketList.toList();
|
||||
print("TC3 - $ticketList");
|
||||
});
|
||||
// }
|
||||
// else if (response['status'] == "error" &&
|
||||
// response['message'] == "No tickets found") {
|
||||
// setState(() {
|
||||
// ticketList = [];
|
||||
// trackClaimsList = [];
|
||||
// trackClaimsClosedList = [];
|
||||
// });
|
||||
// ToastHelper.showErrorToast(context, 'No tickets found');
|
||||
// } else {
|
||||
// setState(() {
|
||||
// isLoading = false;
|
||||
// });
|
||||
// ToastHelper.showErrorToast(context, 'Something went wrong');
|
||||
// print('API request failed with status: ${response['status']}');
|
||||
// }
|
||||
} catch (e) {
|
||||
// ToastHelper.showErrorToast(context, 'Failed to load data');
|
||||
print('Error in getTicketList: $e');
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String formatDate(String timestamp) {
|
||||
// Convert the timestamp string to milliseconds
|
||||
int milliseconds = int.parse(timestamp) * 1000;
|
||||
|
||||
// Create a DateTime object from milliseconds
|
||||
DateTime date = DateTime.fromMillisecondsSinceEpoch(milliseconds);
|
||||
|
||||
// Format the DateTime object
|
||||
String formattedDate = DateFormat('d MMM, y').format(date);
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
Color getStatusColor(String? policyStatus) {
|
||||
if (policyStatus != null && statusColors.containsKey(policyStatus)) {
|
||||
return statusColors[policyStatus]!;
|
||||
} else {
|
||||
return Color(0xFF000000); // Default color for policyStatus text
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: CustomAppBar(),
|
||||
body: Stack(children: [
|
||||
SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: MediaQuery.of(context).size.width *
|
||||
0.2, // 30% of screen width as horizontal padding
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0.03, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Column(children: [
|
||||
Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'help');
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.chevron_left, // Replace with your desired icon
|
||||
color: Color(0xFF000000),
|
||||
size: 30,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
5), // Adjust space between icon and text
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Track Queries',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Manage your Queries',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
12, // Adjust the font size as needed
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// Add more rows as needed
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: generateClaimsTicketList(
|
||||
ticketList), // Replace 'yourDataList' with your actual data list
|
||||
),
|
||||
),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 40 : 70),
|
||||
]),
|
||||
)),
|
||||
if (isLoading)
|
||||
Container(
|
||||
color: Color(0x98FFFCE5), // Semi-transparent background
|
||||
child: Center(
|
||||
child: // Your GIF loader widget
|
||||
Image.asset(
|
||||
height: 60,
|
||||
width: 60,
|
||||
'assets/nhance-loader.gif'), // Adjust path to your GIF loader
|
||||
),
|
||||
),
|
||||
if (Responsive.isDesktop(context))
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Container(
|
||||
width: double.infinity, // Make the footer full width
|
||||
child: CustomFooter(),
|
||||
),
|
||||
),
|
||||
]),
|
||||
// floatingActionButton: Responsive.isDesktop(context)
|
||||
// ? null
|
||||
// : FloatingActionButton(
|
||||
// onPressed: () {
|
||||
// Navigator.pushNamed(context, 'chatbot');
|
||||
// },
|
||||
// child: Icon(Icons.chat),
|
||||
// ),
|
||||
floatingActionButtonLocation: Responsive.isDesktop(context)
|
||||
? null
|
||||
: FloatingActionButtonLocation.miniEndFloat,
|
||||
bottomNavigationBar: Responsive.isDesktop(context)
|
||||
? null
|
||||
: CustomBottomNavigationBar(
|
||||
onTabChanged: (index) {
|
||||
// Add your navigation logic here
|
||||
// For example:
|
||||
if (index == 0) {
|
||||
Navigator.pushNamed(context, 'home');
|
||||
} else if (index == 1) {
|
||||
Navigator.pushNamed(context, 'claims');
|
||||
} else if (index == 2) {
|
||||
Navigator.pushNamed(context, 'profile');
|
||||
} else if (index == 3) {
|
||||
Navigator.pushNamed(context, 'help');
|
||||
} else if (index == 4) {
|
||||
Navigator.pushNamed(context, 'wellness');
|
||||
}
|
||||
},
|
||||
icons: [
|
||||
Icons.home_outlined,
|
||||
Icons.sticky_note_2_outlined,
|
||||
Icons.person_outline_outlined,
|
||||
Icons.headset_mic_outlined,
|
||||
Icons.health_and_safety_outlined,
|
||||
],
|
||||
labels: [
|
||||
"Home",
|
||||
"Claim",
|
||||
"Profile",
|
||||
"Help",
|
||||
"Wellness",
|
||||
],
|
||||
initialIndex: 3, // Initial index of the bottom navigation bar
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> generateClaimsTicketList(List<dynamic> data) {
|
||||
return [
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: data.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var item = data[index];
|
||||
|
||||
// String claimsName = item['user_name'];
|
||||
String claimsticket = item['thz_id'] ?? '';
|
||||
String claimsSubject = item['subject'] ?? '';
|
||||
String claimsDate = item['created_at'] ?? '';
|
||||
String claimStatus = item['status'] ?? '';
|
||||
String claimsDepartmentName = item['ticket_type'] ?? '';
|
||||
// String claimsReplies = item['replies'];
|
||||
// List<dynamic> messageList = item['message_list'];
|
||||
print("item - $item");
|
||||
print('generateTrackList');
|
||||
print(claimsSubject);
|
||||
print(claimsDate);
|
||||
print(claimStatus);
|
||||
print(claimsDepartmentName);
|
||||
|
||||
final Map<String, Color> statusColors = {
|
||||
'Received': Colors.amber,
|
||||
'Rejected': Colors.red,
|
||||
'Cancelled': Colors.red,
|
||||
'Returned': Colors.deepOrange,
|
||||
'Closed': Colors.grey,
|
||||
'Approved': Colors.green,
|
||||
'Settled': Colors.lightBlueAccent,
|
||||
'Under Process': Colors.brown,
|
||||
};
|
||||
|
||||
// Determine the color based on the claimStatus
|
||||
Color statusColor;
|
||||
if (claimStatus != null) {
|
||||
statusColor = statusColors[claimStatus!] ?? Color(0xFF979797);
|
||||
} else {
|
||||
statusColor = Color(0xFF979797); // Default color if status is null
|
||||
}
|
||||
|
||||
final truncatedSubject = Responsive.isDesktop(context)
|
||||
? (claimsSubject.length > 30
|
||||
? '${claimsSubject.substring(0, 30)}...'
|
||||
: claimsSubject)
|
||||
: (claimsSubject.length > 15
|
||||
? '${claimsSubject.substring(0, 10)}...'
|
||||
: claimsSubject);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
print("Navigating with thz_id: ${item['thz_id']}");
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
tickettracklist(ticketID: item['thz_id']),
|
||||
),
|
||||
);
|
||||
|
||||
// Navigator.pushNamed(
|
||||
// context,
|
||||
// 'claimtracklist',
|
||||
// arguments: item['thz_id'],
|
||||
// );
|
||||
},
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: Color(0xFFD9D9D9), // Set the border color here
|
||||
width: 1.0, // Set the border width here
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
8.0), // Set the border radius here
|
||||
),
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors
|
||||
.white, // Set background color for the container
|
||||
),
|
||||
padding: EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 7,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.string(
|
||||
SvgService.getSvg('tickets'),
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
10), // Adjust space between icon and text
|
||||
Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'$claimsDepartmentName' ?? '',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(
|
||||
context)
|
||||
? 16
|
||||
: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
Responsive.isDesktop(context)
|
||||
? ' (Ticket Id #$claimsticket)'
|
||||
: ' (Tkt #$claimsticket)' ??
|
||||
'',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(
|
||||
context)
|
||||
? 14
|
||||
: 10,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Container(
|
||||
alignment: Alignment
|
||||
.centerLeft, // Set a fixed width or adjust based on your layout
|
||||
child: Tooltip(
|
||||
message: claimsSubject,
|
||||
child: Text(
|
||||
truncatedSubject,
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 14
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF777777),
|
||||
),
|
||||
),
|
||||
))
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 5,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
// Adjust space between icon and text
|
||||
Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
width: 100,
|
||||
decoration: BoxDecoration(
|
||||
// color: statusColor,
|
||||
color: getStatusColor(claimStatus),
|
||||
borderRadius: BorderRadius.circular(
|
||||
50), // Border radius set to 50
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: Text(
|
||||
claimStatus,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(
|
||||
context)
|
||||
? 12
|
||||
: 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
|
||||
color: Colors
|
||||
.white, // Text color against the background
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
formatDateWithTime(claimsDate),
|
||||
textAlign: TextAlign.right,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 14
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF777777),
|
||||
), // Ensure text automatically wraps
|
||||
),
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
])),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
String formatDateWithTime(String timestamp) {
|
||||
// Parse the timestamp string to DateTime
|
||||
DateTime date = DateTime.parse(timestamp);
|
||||
|
||||
// Format the DateTime object with date and time
|
||||
String formattedDate = DateFormat('d MMM y hh:mm a').format(date);
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
}
|
||||
@ -97,7 +97,7 @@ class ApiService {
|
||||
await _initializeToken();
|
||||
}
|
||||
final url = Uri.parse(
|
||||
'${Environment.apiUrlTicket}/get_ticket_data?emp_id=$empPrimaryId');
|
||||
'${Environment.apiUrl}/get_ticket_data?emp_id=$empPrimaryId');
|
||||
final headers = {
|
||||
'Authorization': 'Bearer $_token' ?? '',
|
||||
};
|
||||
@ -152,12 +152,12 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchDepartmentList() async {
|
||||
Future<Map<String, dynamic>> fetchDepartmentList(String clientId, String empCode) async {
|
||||
print(_token);
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
}
|
||||
final url = Uri.parse('${Environment.apiUrlTicket}/get_ticket_type');
|
||||
final url = Uri.parse('${Environment.apiUrl}/get_ticket_type?client_id=$clientId&emp_code=$empCode');
|
||||
final headers = {
|
||||
'Authorization': 'Bearer $_token' ?? '',
|
||||
};
|
||||
@ -165,7 +165,7 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> sendFormDataToApi(
|
||||
Future<Map<String, dynamic>> sendTicketFormDataToApi(
|
||||
Map<String, dynamic> formData) async {
|
||||
print(_token);
|
||||
if (_token == null) {
|
||||
@ -182,6 +182,23 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> sendClaimsFormDataToApi(
|
||||
Map<String, dynamic> formData) async {
|
||||
print(_token);
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
}
|
||||
final url = Uri.parse('${Environment.apiUrl}/initiateClaim');
|
||||
// Convert formData to Map<String, String>
|
||||
Map<String, String> stringFormData =
|
||||
formData.map((key, value) => MapEntry(key, value.toString()));
|
||||
final response = await _makePostRequest(url, stringFormData, {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Authorization': 'Bearer $_token' ?? '',
|
||||
});
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> sendClaimsMessageToApi(
|
||||
Map<String, dynamic> formData) async {
|
||||
print("sendClaimsMessageToApi");
|
||||
|
||||
46
lib/pages/postEnrollment/service/file_upload_service.dart
Normal file
46
lib/pages/postEnrollment/service/file_upload_service.dart
Normal file
@ -0,0 +1,46 @@
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
|
||||
class FileUploadService {
|
||||
FileUploadService._();
|
||||
static final FileUploadService _instance = FileUploadService._();
|
||||
factory FileUploadService() => _instance;
|
||||
|
||||
final List<PlatformFile> _files = [];
|
||||
|
||||
List<PlatformFile> get files => List.unmodifiable(_files);
|
||||
|
||||
// Allowed extensions
|
||||
static const allowedExtensions = ['pdf', 'png', 'jpg', 'jpeg','heic'];
|
||||
|
||||
Future<String?> pickFiles({int maxFileSizeInMB = 3}) async {
|
||||
final result = await FilePicker.platform.pickFiles(
|
||||
allowMultiple: true,
|
||||
withData: true,
|
||||
type: FileType.custom,
|
||||
allowedExtensions: allowedExtensions,
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
for (final file in result.files) {
|
||||
final ext = file.extension?.toLowerCase() ?? '';
|
||||
final sizeInMB = (file.size / (1024 * 1024));
|
||||
|
||||
if (!allowedExtensions.contains(ext)) {
|
||||
return "Unsupported file format: ${file.name}";
|
||||
}
|
||||
if (sizeInMB > maxFileSizeInMB) {
|
||||
return "File too large (${file.name}). Max $maxFileSizeInMB MB allowed.";
|
||||
}
|
||||
}
|
||||
|
||||
_files.addAll(result.files);
|
||||
}
|
||||
return null; // success
|
||||
}
|
||||
|
||||
void removeFileAt(int index) {
|
||||
if (index >= 0 && index < _files.length) _files.removeAt(index);
|
||||
}
|
||||
|
||||
void clearAll() => _files.clear();
|
||||
}
|
||||
137
lib/pages/postEnrollment/service/multi_file_upload_widget.dart
Normal file
137
lib/pages/postEnrollment/service/multi_file_upload_widget.dart
Normal file
@ -0,0 +1,137 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:nhance_app_pwa/customAppBar/responsive.dart';
|
||||
import 'file_upload_service.dart';
|
||||
|
||||
class MultiFileUploadWidget extends StatefulWidget {
|
||||
const MultiFileUploadWidget({super.key});
|
||||
|
||||
@override
|
||||
State<MultiFileUploadWidget> createState() => _MultiFileUploadWidgetState();
|
||||
}
|
||||
|
||||
class _MultiFileUploadWidgetState extends State<MultiFileUploadWidget> {
|
||||
final fileService = FileUploadService();
|
||||
String? errorMessage;
|
||||
|
||||
void _pickFiles() async {
|
||||
final error = await fileService.pickFiles(maxFileSizeInMB: 10); // 5 MB limit
|
||||
if (error != null) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
errorMessage = error;
|
||||
});
|
||||
|
||||
// also show alert dialog for big error messages
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (ctx) => AlertDialog(
|
||||
// title: const Text("File Upload Error"),
|
||||
// content: Text(error),
|
||||
// actions: [
|
||||
// TextButton(
|
||||
// onPressed: () => Navigator.pop(ctx),
|
||||
// child: const Text("OK"),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
}
|
||||
} else {
|
||||
setState(() {
|
||||
errorMessage = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _removeFile(int index) {
|
||||
fileService.removeFileAt(index);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final files = fileService.files;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (Responsive.isMobile(context)) ...[
|
||||
OutlinedButton.icon(
|
||||
onPressed: _pickFiles,
|
||||
icon: const Icon(Icons.file_upload_outlined,
|
||||
color: Color(0xFFE26728), size: 24),
|
||||
label: const Text(
|
||||
"Upload Documents",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: const BorderSide(color: Color(0xFFE26728)),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
const Text(
|
||||
"Supports only PDF, PNG, JPG, JPEG,HEIC formats (max 10 MB each)",
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
),
|
||||
] else ...[
|
||||
Row(
|
||||
children: [
|
||||
OutlinedButton.icon(
|
||||
onPressed: _pickFiles,
|
||||
icon: const Icon(Icons.file_upload_outlined,
|
||||
color: Color(0xFFE26728), size: 24),
|
||||
label: const Text(
|
||||
"Upload Documents",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: const BorderSide(color: Color(0xFFE26728)),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const Expanded(
|
||||
child: Text(
|
||||
"Supports only PDF, PNG, JPG, JPEG,HEIC formats (max 10 MB each)",
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
if (errorMessage != null) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
errorMessage!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
|
||||
const SizedBox(height: 8),
|
||||
...files.asMap().entries.map((entry) {
|
||||
final index = entry.key;
|
||||
final file = entry.value;
|
||||
|
||||
return ListTile(
|
||||
dense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(file.name, style: const TextStyle(fontSize: 14)),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.close, color: Colors.red),
|
||||
onPressed: () => _removeFile(index),
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,6 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
import 'package:nhance_app_pwa/customAppBar/customAppBar.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/claimtracklist.dart';
|
||||
import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../customAppBar/customFooter.dart';
|
||||
@ -238,7 +237,7 @@ class _ticketsState extends State<tickets> {
|
||||
// Convert integer values to strings
|
||||
formData = formData.map((key, value) => MapEntry(key, value.toString()));
|
||||
|
||||
final response = await apiService.sendFormDataToApi(formData);
|
||||
final response = await apiService.sendTicketFormDataToApi(formData);
|
||||
|
||||
if (response['status'] == 'success') {
|
||||
ToastHelper.showSuccessToast(context, response['message']);
|
||||
@ -252,7 +251,7 @@ class _ticketsState extends State<tickets> {
|
||||
// Navigator.pushNamed(context, 'help');
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
'help',
|
||||
'raisedTicketHistory',
|
||||
arguments: {'ticketTabSelected': 0},
|
||||
);
|
||||
print('Form data submitted successfully');
|
||||
|
||||
@ -14,15 +14,15 @@ import '../../customAppBar/responsive.dart';
|
||||
import '../../customAppBar/tabs.dart';
|
||||
import '../../customAppBar/toastHelper.dart';
|
||||
|
||||
class claimtracklist extends StatefulWidget {
|
||||
class tickettracklist extends StatefulWidget {
|
||||
final String ticketID;
|
||||
const claimtracklist({Key? key, required this.ticketID}) : super(key: key);
|
||||
const tickettracklist({Key? key, required this.ticketID}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<claimtracklist> createState() => _claimtracklistformState();
|
||||
State<tickettracklist> createState() => _tickettracklistState();
|
||||
}
|
||||
|
||||
class _claimtracklistformState extends State<claimtracklist> {
|
||||
class _tickettracklistState extends State<tickettracklist> {
|
||||
late ApiService apiService;
|
||||
late String ticketID;
|
||||
dynamic _token;
|
||||
@ -308,14 +308,10 @@ class _claimtracklistformState extends State<claimtracklist> {
|
||||
flex: 1,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// Navigator.pushNamed(
|
||||
// context, 'claims');
|
||||
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
'help',
|
||||
arguments: {
|
||||
'ticketTabSelected': 0
|
||||
},
|
||||
'raisedTicketHistory',
|
||||
);
|
||||
},
|
||||
child: Icon(
|
||||
@ -713,11 +709,11 @@ class _claimtracklistformState extends State<claimtracklist> {
|
||||
}
|
||||
|
||||
String formatDateWithTime(String timestamp) {
|
||||
// Parse the input string to DateTime
|
||||
DateTime date = DateFormat("yyyy-MM-dd HH:mm:ss").parse(timestamp);
|
||||
// Parse the timestamp string to DateTime
|
||||
DateTime date = DateTime.parse(timestamp);
|
||||
|
||||
// Format to your desired output
|
||||
String formattedDate = DateFormat("dd, MMM yy h:mm a").format(date);
|
||||
// Format the DateTime object with date and time
|
||||
String formattedDate = DateFormat('d MMM y hh:mm a').format(date);
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
@ -6,9 +6,13 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <file_selector_linux/file_selector_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
file_selector_linux
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import file_picker
|
||||
import file_selector_macos
|
||||
import firebase_app_check
|
||||
import firebase_auth
|
||||
import firebase_core
|
||||
@ -21,13 +23,15 @@ import video_player_avfoundation
|
||||
import webview_flutter_wkwebview
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||
FLTFirebaseAppCheckPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAppCheckPlugin"))
|
||||
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
|
||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
|
||||
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
|
||||
FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin"))
|
||||
FLALocalAuthPlugin.register(with: registry.registrar(forPlugin: "FLALocalAuthPlugin"))
|
||||
LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin"))
|
||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
|
||||
@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
#version: 1.0.24+24
|
||||
version: 1.0.12+13
|
||||
version: 1.0.13+14
|
||||
|
||||
environment:
|
||||
sdk: '>=3.3.3 <4.0.0'
|
||||
@ -61,6 +61,9 @@ dependencies:
|
||||
webview_flutter: ^4.13.0
|
||||
webview_flutter_android: ^4.7.0
|
||||
flutter_inappwebview: ^6.1.5
|
||||
file_picker: ^10.3.2
|
||||
file_selector: ^1.0.3
|
||||
universal_html: ^2.2.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
(function() {
|
||||
var botmanCDN = document.createElement("script");
|
||||
botmanCDN.src = "https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js";
|
||||
botmanCDN.defer = true;
|
||||
document.head.appendChild(botmanCDN);
|
||||
|
||||
botmanCDN.onload = function() {
|
||||
var botmanWidget = {
|
||||
// chatServer: 'https://appstage.nhanceindia.in/arena/crm/chat',
|
||||
// frameEndpoint: 'https://appstage.nhanceindia.in/arena/crm/widget',
|
||||
// chatServer: 'https://app.nhanceindia.in/zenith/chat ',
|
||||
//frameEndpoint: 'https://app.nhanceindia.in/zenith/widget',
|
||||
chatServer: 'https://venbait.in/nhance/dev/chat',
|
||||
frameEndpoint: 'https://venbait.in/nhance/dev/widget',
|
||||
title: "Ask ILA",
|
||||
introMessage: "",
|
||||
bubbleBackground: "#007bff",
|
||||
mainColor: "#007bff",
|
||||
placeholderText: "Type your message here...",
|
||||
aboutText: "Insurance Assistant ILA",
|
||||
enableAttachments: false,
|
||||
parameters: {
|
||||
employee_id: localStorage.getItem('empPrimaryId') || '',
|
||||
session_id: generateSessionId(15),
|
||||
origin: "mobile",
|
||||
emp_code: localStorage.getItem('empCode') || '',
|
||||
client_id: localStorage.getItem('client_id') || '',
|
||||
client_branch_id: localStorage.getItem('empClientBranchId') || ''
|
||||
}
|
||||
};
|
||||
|
||||
function generateSessionId(length = 15) {
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let sessionId = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
sessionId += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||
}
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
function openBotmanChat() {
|
||||
var checkBotman = setInterval(function () {
|
||||
if (typeof botmanChatWidget !== "undefined" && botmanChatWidget.open) {
|
||||
clearInterval(checkBotman);
|
||||
botmanChatWidget.open();
|
||||
setTimeout(function () {
|
||||
botmanChatWidget.sayAsBot('Hi ' + (localStorage.getItem('gpaEmpName') || '') +
|
||||
', This is ILA, your Insurance Assistant. Please choose an option.');
|
||||
}, 2000);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
window.openBotmanChat = openBotmanChat;
|
||||
};
|
||||
})();
|
||||
@ -171,8 +171,9 @@ body.show-botman #botmanWidgetRoot {
|
||||
introMessage: "",
|
||||
bubbleBackground: "#179a9f",
|
||||
mainColor: "#179a9f",
|
||||
bubbleAvatarUrl:"https://botman.io/img/logo.png",
|
||||
placeholderText: "Type your message here...",
|
||||
aboutText: "Insurance Assistant ILA",
|
||||
aboutText: "Press Enter to send the message",
|
||||
enableAttachments: false,
|
||||
parameters: getUpdatedParameters()
|
||||
};
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <file_selector_windows/file_selector_windows.h>
|
||||
#include <firebase_auth/firebase_auth_plugin_c_api.h>
|
||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
|
||||
@ -13,6 +14,8 @@
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
FileSelectorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||
FirebaseAuthPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi"));
|
||||
FirebaseCorePluginCApiRegisterWithRegistrar(
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
file_selector_windows
|
||||
firebase_auth
|
||||
firebase_core
|
||||
flutter_inappwebview_windows
|
||||
|
||||
Loading…
Reference in New Issue
Block a user