validation changes

This commit is contained in:
venbaittech 2025-11-03 11:51:39 +05:30
parent 872b4e4649
commit 7ff6c82a9c
11 changed files with 117 additions and 40 deletions

File diff suppressed because one or more lines are too long

View File

@ -5,12 +5,13 @@ class Env {
); );
static const String apiUrl = String.fromEnvironment( static const String apiUrl = String.fromEnvironment(
'API_URL', 'API_URL',
// defaultValue: 'https://partner.nhanceindia.in/partner_api/api/',
defaultValue: 'https://venbait.in/nhance/partner/dev/api/', defaultValue: 'https://venbait.in/nhance/partner/dev/api/',
); );
static const String baseUrl = String.fromEnvironment( // static const String baseUrl = String.fromEnvironment(
'BASE_URL', // 'BASE_URL',
defaultValue: '/nhance/partner/app', // defaultValue: '/nhance/partner/app',
); // );
static const String App_Signature = String.fromEnvironment( static const String App_Signature = String.fromEnvironment(
'App_Signature', 'App_Signature',
defaultValue: 'nhance-partner-2025-signature-35468846JRhH551HK', defaultValue: 'nhance-partner-2025-signature-35468846JRhH551HK',

View File

@ -340,13 +340,15 @@ class ApiService {
final url; final url;
if (role == 'staff') { if (role == 'staff') {
url = Uri.parse( // url = Uri.parse(
'https://venbait.in/nhance/partner/dev/api/staff/changeStaffStatus', // 'https://venbait.in/nhance/partner/dev/api/staff/changeStaffStatus',
); // );
url = Uri.parse('${Env.apiUrl}staff/changeStaffStatus');
} else { } else {
url = Uri.parse( // url = Uri.parse(
'https://venbait.in/nhance/partner/dev/api/agent/changeAgentStatus', // 'https://venbait.in/nhance/partner/dev/api/agent/changeAgentStatus',
); // );
url = Uri.parse('${Env.apiUrl}/api/agent/changeAgentStatus');
} }
// final token = await getToken(); // Fetch token // final token = await getToken(); // Fetch token

View File

@ -117,4 +117,25 @@ class Validators {
} }
return null; return null;
} }
static String? nonReqemail(String? value, String label) {
// Skip validation if empty
if (value == null || value.trim().isEmpty) return null;
final emailRegex = r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$';
if (!RegExp(emailRegex).hasMatch(value.trim())) {
return "Invalid $label";
}
return null;
}
static String? nonReqphone(String? value, String label) {
// Skip validation if empty
if (value == null || value.trim().isEmpty) return null;
if (!RegExp(r'^[0-9]{10}$').hasMatch(value.trim())) {
return "Enter a valid 10-digit phone number";
}
return null;
}
} }

View File

@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:nhance_partner/presentation/layouts/responsive_layout.dart'; import 'package:nhance_partner/presentation/layouts/responsive_layout.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart'; import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
@ -770,10 +771,10 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
Widget buildEmail(BuildContext context) { Widget buildEmail(BuildContext context) {
return buildResponsiveField( return buildResponsiveField(
label: "Email *", label: "Email",
field: ThemedFormField( field: ThemedFormField(
controller: controllers['email']!, controller: controllers['email']!,
validator: (value) => Validators.email(value, "email"), validator: (value) => Validators.nonReqemail(value, "email"),
inputFormatters: [ inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_@.]')), FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_@.]')),
], ],
@ -786,10 +787,10 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
Widget buildPhNumber(BuildContext context) { Widget buildPhNumber(BuildContext context) {
return buildResponsiveField( return buildResponsiveField(
label: "Phone Number *", label: "Phone Number",
field: ThemedFormField( field: ThemedFormField(
controller: controllers['mobile']!, controller: controllers['mobile']!,
validator: (value) => Validators.phone(value, "phNumber"), validator: (value) => Validators.nonReqphone(value, "phone"),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[ 0-9]'))], inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[ 0-9]'))],
txtwidth: ResponsiveLayout.isMobile(context) txtwidth: ResponsiveLayout.isMobile(context)
? null ? null
@ -873,6 +874,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
filled: true, filled: true,
fillColor: Colors.white, fillColor: Colors.white,
hintText: "Search Vehicle Type...", hintText: "Search Vehicle Type...",
hintStyle: GoogleFonts.inter(fontSize: 12, color: Colors.black),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Colors.white, color: Colors.white,
@ -886,7 +888,18 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
), ),
), ),
), ),
// constraints: BoxConstraints(), // constraints: BoxConstraints(),
itemBuilder: (context, item, isDisabled, isSelected) {
return Container(
// color: isSelected ? Colors.blue.withOpacity(0.1) : null,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
child: Text(
item['vehicle_type'].toString(),
style: GoogleFonts.inter(fontSize: 13, color: Colors.black),
),
);
},
), ),
onChanged: (val) { onChanged: (val) {
@ -1043,6 +1056,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
filled: true, filled: true,
fillColor: Colors.white, fillColor: Colors.white,
hintText: "Search Partner...", hintText: "Search Partner...",
hintStyle: GoogleFonts.inter(fontSize: 12, color: Colors.black),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Colors.white, color: Colors.white,
@ -1056,7 +1070,33 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
), ),
), ),
), ),
// constraints: BoxConstraints(), // constraints: BoxConstraints(),
itemBuilder: (context, item, isDisabled, isSelected) {
return Container(
// color: isSelected ? Colors.blue.withOpacity(0.1) : null,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
item['name'].toString(),
style: GoogleFonts.inter(
fontSize: 13,
color: Colors.black,
),
),
Text(
item['agent_code'].toString(),
style: GoogleFonts.inter(
fontSize: 13,
color: Colors.grey,
),
),
],
),
);
},
), ),
onChanged: (val) { onChanged: (val) {

View File

@ -608,6 +608,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
await prefs.remove('enqAgentDataId'); await prefs.remove('enqAgentDataId');
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.tabEnquiry); context.go(AppRoutes.tabEnquiry);
// print('Export'); // print('Export');
}, },

View File

@ -802,6 +802,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
await prefs.remove('enqAgentDataId'); await prefs.remove('enqAgentDataId');
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.tabEnquiry); context.go(AppRoutes.tabEnquiry);
// print('Export'); // print('Export');
}, },

View File

@ -57,11 +57,10 @@ class _SplashScreenState extends State<SplashScreen> {
const SizedBox(height: 10), const SizedBox(height: 10),
// Environment Label (Optional) // Environment Label (Optional)
Text( // Text(
"Environment: ${Env.envName.toUpperCase()}", // "Environment: ${Env.envName.toUpperCase()}",
style: const TextStyle(fontSize: 14, color: Colors.grey), // style: const TextStyle(fontSize: 14, color: Colors.grey),
), // ),
const SizedBox(height: 30), const SizedBox(height: 30),
// Loading Indicator // Loading Indicator

View File

@ -262,7 +262,6 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
controller: widget.startController, controller: widget.startController,
onDateSelected: (date) { onDateSelected: (date) {
print("Picked Date: $date"); print("Picked Date: $date");
widget.startController.text = DateFormat('dd-MM-yyyy').format(date); widget.startController.text = DateFormat('dd-MM-yyyy').format(date);
// controllers['date']?.text = date as String; // controllers['date']?.text = date as String;
}, },
@ -526,7 +525,6 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
), ),
itemBuilder: (context, item, isDisabled, isSelected) { itemBuilder: (context, item, isDisabled, isSelected) {
// 4 parameters
return Container( return Container(
// color: isSelected ? Colors.blue.withOpacity(0.1) : null, // color: isSelected ? Colors.blue.withOpacity(0.1) : null,
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(

View File

@ -1,15 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as ref; // import 'package:http/http.dart' as ref;
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart'; import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import '../../core/routing/routes.dart'; import '../../core/routing/routes.dart';
import '../layouts/responsive_layout.dart'; import '../layouts/responsive_layout.dart';
import '../providers/manager_provider.dart';
import '../providers/userRoleProvider.dart'; import '../providers/userRoleProvider.dart';
class TopBar extends StatefulWidget implements PreferredSizeWidget { class TopBar extends ConsumerStatefulWidget implements PreferredSizeWidget {
final String title; final String title;
final bool isMobile; final bool isMobile;
final VoidCallback? onLogout; final VoidCallback? onLogout;
@ -28,13 +31,15 @@ class TopBar extends StatefulWidget implements PreferredSizeWidget {
}); });
@override @override
State<TopBar> createState() => _TopBarState(); ConsumerState<TopBar> createState() => _TopBarState();
// State<TopBar> createState() => _TopBarState();
@override @override
Size get preferredSize => const Size.fromHeight(kToolbarHeight); Size get preferredSize => const Size.fromHeight(kToolbarHeight);
} }
class _TopBarState extends State<TopBar> { // class _TopBarState extends State<TopBar>
class _TopBarState extends ConsumerState<TopBar> {
String? role; String? role;
@override @override
@ -109,6 +114,7 @@ class _TopBarState extends State<TopBar> {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
await prefs.remove('enqAgentDataId'); await prefs.remove('enqAgentDataId');
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.tabEnquiry); context.go(AppRoutes.tabEnquiry);
// print('Export'); // print('Export');
}, },
@ -145,10 +151,13 @@ class _TopBarState extends State<TopBar> {
child: Tooltip( child: Tooltip(
message: 'Notifications', message: 'Notifications',
child: IconButton( child: IconButton(
icon: const Icon(Icons.notifications_none, color: Colors.black87), icon: const Icon(
Icons.notifications_none,
color: Colors.black87,
),
onPressed: widget.onNotifications, onPressed: widget.onNotifications,
), ),
) ),
), ),
if (!widget.isMobile) ...[ if (!widget.isMobile) ...[
SizedBox(width: 10), SizedBox(width: 10),
@ -159,12 +168,16 @@ class _TopBarState extends State<TopBar> {
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.circular(50.0), borderRadius: BorderRadius.circular(50.0),
), ),
child : Tooltip( message: 'Profile', child: Tooltip(
child: GestureDetector( message: 'Profile',
onTapDown: (details) => widget.onProfile!(details), child: GestureDetector(
child: const Icon(Icons.person_outline, color: Colors.black87), onTapDown: (details) => widget.onProfile!(details),
child: const Icon(
Icons.person_outline,
color: Colors.black87,
),
),
), ),
)
), ),
// IconButton( // IconButton(
@ -180,13 +193,13 @@ class _TopBarState extends State<TopBar> {
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.circular(50.0), borderRadius: BorderRadius.circular(50.0),
), ),
child: Tooltip( child: Tooltip(
message: 'Logout', message: 'Logout',
child: IconButton( child: IconButton(
icon: const Icon(Icons.logout, color: Colors.black87), icon: const Icon(Icons.logout, color: Colors.black87),
onPressed: widget.onLogout, onPressed: widget.onLogout,
), ),
) ),
), ),
], ],
), ),

View File

@ -15,6 +15,7 @@
the `--base-href` argument provided to `flutter build`. the `--base-href` argument provided to `flutter build`.
--> -->
<!-- <base href="$FLUTTER_BASE_HREF">--> <!-- <base href="$FLUTTER_BASE_HREF">-->
<!-- <base href="/partner/">-->
<base href="/nhance/partner/app/"> <base href="/nhance/partner/app/">
<meta charset="UTF-8"> <meta charset="UTF-8">