Commit ba590246 authored by Sai Srinivas's avatar Sai Srinivas
Browse files

All testes clear and updated

parents 558ac0d8 cdbe1e86
This image diff could not be displayed because it is too large. You can view the blob instead.
......@@ -271,6 +271,7 @@ class HelpAndEnquiryProvider extends ChangeNotifier {
orderId,
otherReason,
images,
);
// Check if widget is still mounted before showing dialogs
......@@ -282,10 +283,7 @@ class HelpAndEnquiryProvider extends ChangeNotifier {
);
//Navigator.pop(context); // close bottom sheet or dialog if open
if (context.mounted) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HelpScreen(sessionId: sessionId, accId: accId))
);
Navigator.pop(context);
}
} else {
......
......@@ -257,33 +257,33 @@ class _BillDetailScreenState extends State<BillDetailScreen> {
child: Row(
children: [
// Pay Now Button (only if not paid)
if (!isPaid) ...[
Expanded(
child: ElevatedButton(
onPressed: () {
_showPayNowDialog(screenWidth, screenHeight);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.buttonColor,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(screenWidth * 0.03),
),
padding: EdgeInsets.symmetric(vertical: screenHeight * 0.018),
elevation: 0,
),
child: Text(
"Pay Now",
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
fontFamily: "Poppins",
fontWeight: FontWeight.w600,
),
),
),
),
SizedBox(width: screenWidth * 0.03),
],
// if (!isPaid) ...[
// Expanded(
// child: ElevatedButton(
// onPressed: () {
// _showPayNowDialog(screenWidth, screenHeight);
// },
// style: ElevatedButton.styleFrom(
// backgroundColor: AppColors.buttonColor,
// foregroundColor: Colors.white,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(screenWidth * 0.03),
// ),
// padding: EdgeInsets.symmetric(vertical: screenHeight * 0.018),
// elevation: 0,
// ),
// child: Text(
// "Pay Now",
// style: TextStyle(
// fontSize: getResponsiveTextSize(context, 14),
// fontFamily: "Poppins",
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// SizedBox(width: screenWidth * 0.03),
// ],
// Download Receipt Button
Expanded(
......@@ -315,7 +315,7 @@ class _BillDetailScreenState extends State<BillDetailScreen> {
label: Text(
provider.isDownloading
? "Downloading..."
: "Download Receipt",
: "Download Bill",
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
fontFamily: "Plus Jakarta Sans",
......
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:gen_rentals/Screens/HelpScreens/EnquiryScreen.dart';
import 'package:gen_rentals/Screens/HelpScreens/HelpScreen.dart';
......@@ -48,7 +51,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
}
}
// Handle back button press
// Handle back button press
Future<bool> _onWillPop() async {
DateTime now = DateTime.now();
if (currentBackPressTime == null ||
......@@ -61,9 +64,12 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
);
return false;
}
return true;
// Close the entire app immediately
exit(0);
}
// Responsive text size function
double getResponsiveTextSize(BuildContext context, double baseSize) {
final double width = MediaQuery.of(context).size.width;
......@@ -212,7 +218,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
// Header with profile
Container(
width: double.infinity,
height: screenHeight * 0.55,
height: screenHeight * 0.51,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
......@@ -228,7 +234,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
),
child: Column(
children: [
SizedBox(height: screenHeight * 0.06),
SizedBox(height: screenHeight * 0.09),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
......@@ -260,10 +266,11 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset(
'assets/images/gene_png.png',
'assets/images/dashboard_gen.png',
height: screenHeight * 0.25,
width: screenWidth * 0.6,
),
SizedBox(height: 5,),
Text(
"Welcome!",
style: TextStyle(
......@@ -288,8 +295,6 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
),
),
SizedBox(height: screenHeight * 0.01),
// Main content section
Container(
padding: EdgeInsets.symmetric(horizontal: getResponsivePadding(context)),
......@@ -387,7 +392,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
// Subscribed Orders
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: screenWidth * 0.005, vertical: screenHeight * 0.012),
padding: EdgeInsets.symmetric(horizontal: screenWidth * 0.0009, vertical: screenHeight * 0.012),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
......@@ -896,25 +901,26 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
bottomRight: Radius.circular(screenWidth * 0.05),
),
),
child: Row(
children: [
SizedBox(width: screenWidth * 0.03),
Icon(Icons.info_outline, color: Colors.red, size: getResponsiveIconSize(context, 15)),
SizedBox(width: screenWidth * 0.01),
Expanded(
child: Text(
product.pendingPaymentText ??
"Payment Pending. Please Pay before incurring fines.",
style: TextStyle(
fontFamily: "Poppins",
color: Colors.red,
fontSize: getResponsiveTextSize(context, 11),
fontWeight: FontWeight.w400,
child: Center(
child: Row(
children: [
SizedBox(width: screenWidth * 0.02),
Icon(Icons.info_outline, color: Colors.red, size: getResponsiveIconSize(context, 15)),
SizedBox(width: screenWidth * 0.01),
Expanded(
child: Text(
product.pendingPaymentText ??
"Payment Pending. Please Pay before incurring fines.",
style: TextStyle(
fontFamily: "Poppins",
color: Colors.black87,
fontSize: getResponsiveTextSize(context, 10),
fontWeight: FontWeight.w400,
),
),
),
),
SizedBox(width: screenWidth * 0.03),
],
],
),
),
),
],
......@@ -952,7 +958,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
width: getResponsiveIconSize(context, 40),
fit: BoxFit.contain,
errorBuilder: (context, error, stack) =>
Image.asset('assets/images/gene_png.png',
Image.asset('assets/images/dashboard_gen.png',
height: getResponsiveIconSize(context, 40),
width: getResponsiveIconSize(context, 40)),
),
......@@ -985,7 +991,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
],
),
// Gradient expiry badge
// Gradient expiry badge
if (product.expiringText != null && product.expiringText!.isNotEmpty)
Container(
padding: EdgeInsets.symmetric(
......@@ -1038,7 +1044,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
"• ",
style: TextStyle(
color: Colors.black,
fontSize: getResponsiveTextSize(context, 16)
fontSize: getResponsiveTextSize(context, 14)
),
),
Expanded(
......
......@@ -32,6 +32,9 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
List<File> _selectedImages = [];
String _selectedReason = 'Payment Issues';
// Success dialog state
bool _showSuccessDialog = false;
final List<Map<String, dynamic>> createNewTickets = [
{
'title': 'Payment \nIssues',
......@@ -130,200 +133,297 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
"Help?",
style: TextStyle(
fontSize: getResponsiveTextSize(context, 16),
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w600,
fontFamily: "Poppins",
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
],
),
),
body: SingleChildScrollView(
padding: EdgeInsets.all(getResponsivePadding(context)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
body: Stack(
children: [
SingleChildScrollView(
padding: EdgeInsets.all(getResponsivePadding(context)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SectionHeading(
title: 'Create New Ticket',
textStyle: TextStyle(
fontSize: getResponsiveTextSize(context, 16),
fontWeight: FontWeight.w500
),
),
Container(
padding: EdgeInsets.symmetric(
horizontal: getResponsivePadding(context) * 1.12,
vertical: getResponsiveButtonHeight(context) * 0.2,
),
decoration: BoxDecoration(
color: Color(0xFFE0F4FF),
borderRadius: BorderRadius.circular(screenWidth * 0.025),
),
child: Text(
"order #${widget.orderId}",
style: TextStyle(
fontSize: getResponsiveTextSize(context, 12),
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w400,
color: Colors.black87,
),
),
),
],
),
SizedBox(height: screenHeight * 0.015),
_fieldLabel("Reason"),
SizedBox(height: screenHeight * 0.008),
GestureDetector(
onTap: _showReasonBottomSheet,
child: Container(
width: screenWidth * 0.46, // 50% of screen width
padding: EdgeInsets.symmetric(
horizontal: getResponsivePadding(context),
vertical: screenHeight * 0.010,
),
decoration: BoxDecoration(
color: const Color(0xffFFF3D1),
borderRadius: BorderRadius.circular(screenWidth * 0.03),
),
child: Row(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
SectionHeading(
title: 'Create New Ticket',
textStyle: TextStyle(
fontFamily: "Poppins",
fontSize: getResponsiveTextSize(context, 16),
fontWeight: FontWeight.w500
),
),
Container(
padding: EdgeInsets.symmetric(
horizontal: getResponsivePadding(context) * 1.12,
vertical: getResponsiveButtonHeight(context) * 0.2,
),
decoration: BoxDecoration(
color: Color(0xFFE0F4FF),
borderRadius: BorderRadius.circular(screenWidth * 0.025),
),
child: Text(
_selectedReason,
"Order #${widget.orderId}",
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
fontStyle: FontStyle.normal,
fontSize: getResponsiveTextSize(context, 12),
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: Colors.black87,
),
overflow: TextOverflow.ellipsis,
),
),
SizedBox(width: screenWidth * 0.008),
SvgPicture.asset(
"assets/svg/edit_ic.svg",
height: getResponsiveIconSize(context, 22),
),
],
),
),
),
SizedBox(height: screenHeight * 0.02),
if (showOtherReasonField) ...[
_fieldLabel("Enter Reason"),
SizedBox(height: screenHeight * 0.008),
_textField(
controller: _otherReasonController,
hint: "Write your reason",
),
SizedBox(height: screenHeight * 0.02),
],
_fieldLabel("Tell us your issue?"),
SizedBox(height: screenHeight * 0.008),
_textField(
controller: _issueController,
hint: "Write your issue",
maxLines: 5,
),
SizedBox(height: screenHeight * 0.02),
_fieldLabel("Add Screenshot (optional)"),
SizedBox(height: screenHeight * 0.008),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
horizontal: getResponsivePadding(context),
vertical: screenHeight * 0.015,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(screenWidth * 0.03),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: getResponsiveIconSize(context, 60),
height: getResponsiveIconSize(context, 60),
SizedBox(height: screenHeight * 0.015),
_fieldLabel("Reason"),
SizedBox(height: screenHeight * 0.008),
GestureDetector(
onTap: _showReasonBottomSheet,
child: Container(
width: screenWidth * 0.46, // 50% of screen width
padding: EdgeInsets.symmetric(
horizontal: getResponsivePadding(context),
vertical: screenHeight * 0.010,
),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(screenWidth * 0.02),
color: const Color(0xffFFF3D1),
borderRadius: BorderRadius.circular(screenWidth * 0.03),
),
child: IconButton(
onPressed: _pickImage,
icon: Icon(
Icons.add,
size: getResponsiveIconSize(context, 24),
color: Colors.grey[600],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
_selectedReason,
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
fontStyle: FontStyle.normal,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: Colors.black87,
),
overflow: TextOverflow.ellipsis,
),
),
SizedBox(width: screenWidth * 0.008),
SvgPicture.asset(
"assets/svg/edit_ic.svg",
height: getResponsiveIconSize(context, 19),
),
],
),
),
SizedBox(height: screenHeight * 0.01),
if (_selectedImages.isNotEmpty)
GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isSmallScreen ? 3 : 4,
crossAxisSpacing: screenWidth * 0.02,
mainAxisSpacing: screenWidth * 0.02,
childAspectRatio: 1.0,
),
itemCount: _selectedImages.length,
itemBuilder: (context, index) {
return Stack(
children: [
ClipRRect(
),
SizedBox(height: screenHeight * 0.02),
if (showOtherReasonField) ...[
_fieldLabel("Enter Reason"),
SizedBox(height: screenHeight * 0.008),
_textField(
controller: _otherReasonController,
hint: "Write your reason",
),
SizedBox(height: screenHeight * 0.02),
],
_fieldLabel("Tell us your issue?"),
SizedBox(height: screenHeight * 0.008),
_textField(
controller: _issueController,
hint: "Write your issue",
maxLines: 5,
),
SizedBox(height: screenHeight * 0.02),
_fieldLabel("Add Screenshot (optional)"),
SizedBox(height: screenHeight * 0.008),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
horizontal: getResponsivePadding(context),
vertical: screenHeight * 0.015,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(screenWidth * 0.03),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Add file button
Container(
width: getResponsiveIconSize(context, 60),
height: getResponsiveIconSize(context, 60),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(screenWidth * 0.02),
child: Image.file(
_selectedImages[index],
fit: BoxFit.cover,
width: double.infinity,
height: double.infinity,
),
child: IconButton(
onPressed: _pickImage,
icon: Icon(
Icons.add,
size: getResponsiveIconSize(context, 24),
color: Colors.grey[600],
),
),
Positioned(
top: screenHeight * 0.005,
right: screenHeight * 0.005,
child: GestureDetector(
onTap: () => _removeImage(index),
child: Container(
padding: EdgeInsets.all(screenWidth * 0.01),
decoration: const BoxDecoration(
color: Colors.black54,
shape: BoxShape.circle,
),
child: Icon(
Icons.close,
size: getResponsiveIconSize(context, 14),
color: Colors.white,
),
),
SizedBox(width: screenWidth * 0.02),
// Attached images in horizontal scroll
if (_selectedImages.isNotEmpty)
Expanded(
child: SizedBox(
height: getResponsiveIconSize(context, 60),
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: _selectedImages.length,
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.only(right: screenWidth * 0.02),
width: getResponsiveIconSize(context, 60),
height: getResponsiveIconSize(context, 60),
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(screenWidth * 0.02),
child: Image.file(
_selectedImages[index],
fit: BoxFit.cover,
width: double.infinity,
height: double.infinity,
),
),
Positioned(
top: screenHeight * 0.005,
right: screenHeight * 0.005,
child: GestureDetector(
onTap: () => _removeImage(index),
child: Container(
padding: EdgeInsets.all(screenWidth * 0.01),
decoration: const BoxDecoration(
color: Colors.black54,
shape: BoxShape.circle,
),
child: Icon(
Icons.close,
size: getResponsiveIconSize(context, 14),
color: Colors.white,
),
),
),
),
],
),
);
},
),
),
),
],
);
},
),
],
),
],
),
SizedBox(height: screenHeight * 0.01),
],
),
),
SizedBox(height: screenHeight * 0.03),
],
),
SizedBox(height: screenHeight * 0.03),
),
// Success Dialog
if (_showSuccessDialog)
Container(
color: Colors.black54,
child: Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
"Submitted",
style: TextStyle(
fontSize: 18,
fontFamily: "Poppins",
fontWeight: FontWeight.w600,
color: Colors.black,
),
),
const SizedBox(height: 16),
],
),
Text(
"Thanks for reaching out!",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: AppColors.subtitleText,
),
),
const Text(
"Our team will review your ticket and reply to you soon.",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: Colors.black87,
),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
setState(() {
_showSuccessDialog = false;
});
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.buttonColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(28),
),
),
child: const Text(
"Close",
style: TextStyle(
fontFamily: "Poppins",
fontSize: 15,
fontWeight: FontWeight.w400,
),
),
),
),
],
),
),
),
),
],
),
bottomNavigationBar: Padding(
padding: const EdgeInsets.all(14.0),
padding: const EdgeInsets.all(15.0),
child: SizedBox(
width: double.infinity,
child: ElevatedButton(
......@@ -331,7 +431,7 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.buttonColor,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: getResponsiveButtonHeight(context) * 0.34),
padding: EdgeInsets.symmetric(vertical: getResponsiveButtonHeight(context) * 0.32),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(screenWidth * 0.07),
),
......@@ -349,8 +449,9 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
: Text(
'Submit',
style: TextStyle(
fontFamily: "Poppins",
fontSize: getResponsiveTextSize(context, 14),
fontWeight: FontWeight.w400,
fontWeight: FontWeight.w500,
),
),
),
......@@ -363,6 +464,7 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
Widget _fieldLabel(String text) => Text(
text,
style: TextStyle(
fontFamily: "Poppins",
fontSize: getResponsiveTextSize(context, 14),
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
......@@ -386,11 +488,13 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
style: TextStyle(
fontSize: getResponsiveTextSize(context, 14),
fontWeight: FontWeight.w400,
fontFamily: "Poppins",
color: Colors.black87,
),
decoration: InputDecoration(
hintText: hint,
hintStyle: TextStyle(
fontFamily: "Poppins",
fontSize: getResponsiveTextSize(context, 14),
fontWeight: FontWeight.w400,
color: Colors.grey[400],
......@@ -451,21 +555,45 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
reason = "Other";
}
// If user selected "Other Issues", use the custom reason text
final customReason = _selectedReason == 'Other Issues' ? otherReason : null;
debugPrint("Reason ========= $reason");
final helpProvider = Provider.of<HelpAndEnquiryProvider>(context, listen: false);
final helpProvider =
Provider.of<HelpAndEnquiryProvider>(context, listen: false);
// Show success dialog
setState(() {
_showSuccessDialog = true;
});
// Clear form
_issueController.clear();
_otherReasonController.clear();
setState(() {
_selectedImages.clear();
});
// Wait for 2 seconds to show the success dialog
await Future.delayed(Duration(seconds: 2));
if (!mounted) return;
// Close the dialog
setState(() {
_showSuccessDialog = false;
});
// Wait a brief moment for dialog to close, then call the API
await Future.delayed(Duration(milliseconds: 300));
if (!mounted) return;
// Now call the provider method which will handle navigation
await helpProvider.createTicket(
sessionId: widget.sessionId,
accId: widget.accId,
type: reason,
description: issue,
orderId: "1235",
otherReason: customReason.toString(),
orderId: widget.orderId,
otherReason: customReason?.toString() ?? "",
images: _selectedImages,
context: context,
);
......@@ -498,7 +626,7 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
"Select Your Reason",
style: TextStyle(
fontSize: getResponsiveTextSize(context, 16),
fontFamily: "Plus Jakarta Sans",
fontFamily: "Poppins",
fontWeight: FontWeight.w500,
color: Colors.black87,
),
......@@ -583,7 +711,7 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
fontSize: isSmallScreen ? 11 : 13, // Same font sizing logic
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
fontFamily: "Plus Jakarta Sans",
fontFamily: "Poppins",
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
......@@ -595,10 +723,11 @@ class _HelpTicketScreenState extends State<HelpTicketScreen> {
),
);
}
@override
void dispose() {
_issueController.dispose();
_otherReasonController.dispose();
super.dispose();
}
}
}
\ No newline at end of file
......@@ -28,6 +28,15 @@ class _EnquiryScreenState extends State<EnquiryScreen> {
final TextEditingController requirementController = TextEditingController();
final TextEditingController noteController = TextEditingController();
// Track field validation states for real-time validation
bool _nameValid = true;
bool _emailValid = true;
bool _phoneValid = true;
bool _requirementValid = true;
// Success dialog state
bool _showSuccessDialog = false;
@override
Widget build(BuildContext context) {
final enquiryProvider = Provider.of<HelpAndEnquiryProvider>(context);
......@@ -65,157 +74,293 @@ class _EnquiryScreenState extends State<EnquiryScreen> {
),
// Main Body
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_labelText("Name"),
_textField(
controller: nameController,
hint: "Enter Name",
fieldName: "Name",
),
const SizedBox(height: 16),
_labelText("Email Id"),
_textField(
controller: emailController,
hint: "Enter Email ID",
fieldName: "Email",
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.trim().isEmpty) {
return "Please enter your email";
}
if (!RegExp(r'^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$')
.hasMatch(value.trim())) {
return "Enter a valid email";
}
return null;
},
),
const SizedBox(height: 16),
_labelText("Phone No."),
_textField(
controller: phoneController,
hint: "Enter Phone Number",
fieldName: "Phone Number",
keyboardType: TextInputType.phone,
validator: (value) {
if (value == null || value.trim().isEmpty) {
return "Please enter your phone number";
}
if (value.trim().length < 10) {
return "Enter a valid phone number";
}
return null;
},
),
const SizedBox(height: 16),
body: Stack(
children: [
SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_labelText("Name"),
_textField(
controller: nameController,
hint: "Enter Name",
fieldName: "Name",
onChanged: (value) {
setState(() {
_nameValid = value.trim().isNotEmpty;
});
},
),
const SizedBox(height: 16),
_labelText("Requirement"),
_textField(
controller: requirementController,
hint: "Enter Requirement",
fieldName: "Requirement",
),
const SizedBox(height: 16),
_labelText("Note"),
_textField(
controller: noteController,
hint: "Write a short note",
fieldName: "Note",
maxLines: 5,
),
const SizedBox(height: 32),
// Submit button
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: enquiryProvider.isLoading
? null
: () async {
FocusScope.of(context).unfocus();
if (!_formKey.currentState!.validate()) return;
final success =
await enquiryProvider.submitEnquiry(
sessionId: widget.sessionId,
accId: widget.accId,
name: nameController.text.trim(),
email: emailController.text.trim(),
mobile: phoneController.text.trim(),
requirement: requirementController.text.trim(),
note: noteController.text.trim(),
);
if (!mounted) return;
if (success) {
CustomSnackBar.showSuccess(
context: context,
message: enquiryProvider.message ??
"Enquiry submitted successfully!",
);
_formKey.currentState!.reset();
nameController.clear();
emailController.clear();
phoneController.clear();
requirementController.clear();
noteController.clear();
Future.delayed(Duration(seconds: 1), () {
setState(() {
Navigator.pop(context);
});
_labelText("Email Id"),
_textField(
controller: emailController,
hint: "Enter Email ID",
fieldName: "Email",
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.trim().isEmpty) {
return "Please enter your email";
}
if (!RegExp(r'^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$')
.hasMatch(value.trim())) {
return "Enter a valid email";
}
return null;
},
onChanged: (value) {
setState(() {
_emailValid = value != null &&
value.trim().isNotEmpty &&
RegExp(r'^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$')
.hasMatch(value.trim());
});
},
),
const SizedBox(height: 16),
} else {
CustomSnackBar.showError(
context: context,
message: enquiryProvider.message ??
"Failed to submit enquiry!",
);
}
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.buttonColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(28),
),
elevation: 0,
_labelText("Phone No."),
_textField(
controller: phoneController,
hint: "Enter Phone Number",
fieldName: "Phone Number",
keyboardType: TextInputType.phone,
validator: (value) {
if (value == null || value.trim().isEmpty) {
return "Please enter your phone number";
}
if (value.trim().length < 10) {
return "Enter a valid phone number";
}
return null;
},
onChanged: (value) {
setState(() {
_phoneValid = value != null &&
value.trim().isNotEmpty &&
value.trim().length >= 10;
});
},
),
child: enquiryProvider.isLoading
? const SizedBox(
height: 22,
width: 22,
child: CircularProgressIndicator(
strokeWidth: 2.5,
color: Colors.white,
),
)
: const Text(
"Submit",
style: TextStyle(
fontFamily: "Poppins",
fontSize: 15,
fontWeight: FontWeight.w400,
const SizedBox(height: 16),
_labelText("Requirement"),
_textField(
controller: requirementController,
hint: "Enter Requirement",
fieldName: "Requirement",
onChanged: (value) {
setState(() {
_requirementValid = value.trim().isNotEmpty;
});
},
),
const SizedBox(height: 16),
_labelText("Note"),
_textField(
controller: noteController,
hint: "Write a short note",
fieldName: "Note",
maxLines: 5,
isOptional: true,
),
const SizedBox(height: 32),
// Submit button
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: enquiryProvider.isLoading
? null
: () async {
FocusScope.of(context).unfocus();
// Validate all fields
bool isValid = true;
if (nameController.text.trim().isEmpty) {
setState(() {
_nameValid = false;
});
isValid = false;
}
if (emailController.text.trim().isEmpty ||
!RegExp(r'^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$')
.hasMatch(emailController.text.trim())) {
setState(() {
_emailValid = false;
});
isValid = false;
}
if (phoneController.text.trim().isEmpty ||
phoneController.text.trim().length < 10) {
setState(() {
_phoneValid = false;
});
isValid = false;
}
if (requirementController.text.trim().isEmpty) {
setState(() {
_requirementValid = false;
});
isValid = false;
}
if (!isValid) return;
final success =
await enquiryProvider.submitEnquiry(
sessionId: widget.sessionId,
accId: widget.accId,
name: nameController.text.trim(),
email: emailController.text.trim(),
mobile: phoneController.text.trim(),
requirement: requirementController.text.trim(),
note: noteController.text.trim(),
);
if (!mounted) return;
if (success) {
// Show success dialog instead of snackbar
setState(() {
_showSuccessDialog = true;
});
// Clear form
_formKey.currentState!.reset();
nameController.clear();
emailController.clear();
phoneController.clear();
requirementController.clear();
noteController.clear();
// Reset validation states
setState(() {
_nameValid = true;
_emailValid = true;
_phoneValid = true;
_requirementValid = true;
});
} else {
CustomSnackBar.showError(
context: context,
message: enquiryProvider.message ??
"Failed to submit enquiry!",
);
}
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.buttonColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(28),
),
elevation: 0,
),
child: enquiryProvider.isLoading
? const SizedBox(
height: 22,
width: 22,
child: CircularProgressIndicator(
strokeWidth: 2.5,
color: Colors.white,
),
)
: const Text(
"Submit",
style: TextStyle(
fontFamily: "Poppins",
fontSize: 15,
fontWeight: FontWeight.w400,
),
),
),
),
),
],
),
],
),
),
),
// Success Dialog
if (_showSuccessDialog)
Container(
color: Colors.black54,
child: Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
"Submitted",
style: TextStyle(
fontSize: 18,
fontFamily: "Poppins",
fontWeight: FontWeight.w600,
color: Colors.black,
),
),
const SizedBox(height: 16),
const Text(
"Thanks for reaching out!\n\nWe've got your application.\nOur representative will call you soon.",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: Colors.black87,
),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
setState(() {
_showSuccessDialog = false;
});
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.buttonColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(28),
),
),
child: const Text(
"Close",
style: TextStyle(
fontFamily: "Poppins",
fontSize: 15,
fontWeight: FontWeight.w400,
),
),
),
),
],
),
),
),
),
],
),
),
);
......@@ -242,70 +387,106 @@ class _EnquiryScreenState extends State<EnquiryScreen> {
required String fieldName,
TextInputType keyboardType = TextInputType.text,
int maxLines = 1,
bool isOptional = false,
String? Function(String?)? validator,
Function(String)? onChanged,
}) {
return FormField<String>(
validator: validator ??
(value) {
if (controller.text.trim().isEmpty) {
return '$fieldName is required';
}
return null;
},
builder: (field) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
color: Color(0xffF6F6F8),
borderRadius: BorderRadius.circular(12),
// border: Border.all(
// color: field.hasError ? Colors.red : Colors.transparent,
// width: 1,
// ),
),
child: TextFormField(
controller: controller,
keyboardType: keyboardType,
maxLines: maxLines,
onChanged: (_) => field.didChange(controller.text),
style: TextStyle(
fontSize: 14,
fontFamily: "Poppins",
color: Colors.black,
fontWeight: FontWeight.w400,
),
decoration: InputDecoration(
hintText: hint,
hintStyle: TextStyle(
fontSize: 14,
fontFamily: "Poppins",
color: Colors.grey[400],
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
),
contentPadding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
border: InputBorder.none,
),
bool hasError = false;
String errorText = '';
// Determine validation state based on field type
if (fieldName == "Name" && !_nameValid) {
hasError = true;
errorText = "Name is required";
} else if (fieldName == "Email" && !_emailValid) {
hasError = true;
if (emailController.text.trim().isEmpty) {
errorText = "Please enter your email";
} else {
errorText = "Enter a valid email";
}
} else if (fieldName == "Phone Number" && !_phoneValid) {
hasError = true;
if (phoneController.text.trim().isEmpty) {
errorText = "Please enter your phone number";
} else {
errorText = "Enter a valid phone number";
}
} else if (fieldName == "Requirement" && !_requirementValid) {
hasError = true;
errorText = "Requirement is required";
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
color: Color(0xffF6F6F8),
borderRadius: BorderRadius.circular(12),
// border: Border.all(
// color: hasError ? Colors.red : Colors.transparent,
// width: 1,
// ),
),
child: TextFormField(
controller: controller,
keyboardType: keyboardType,
maxLines: maxLines,
onChanged: (value) {
if (onChanged != null) onChanged(value);
// Clear error when user starts typing
if (value.isNotEmpty) {
setState(() {
if (fieldName == "Name") _nameValid = true;
if (fieldName == "Email") {
_emailValid = value.trim().isNotEmpty &&
RegExp(r'^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$')
.hasMatch(value.trim());
}
if (fieldName == "Phone Number") {
_phoneValid = value.trim().isNotEmpty &&
value.trim().length >= 10;
}
if (fieldName == "Requirement") _requirementValid = true;
});
}
},
style: TextStyle(
fontSize: 14,
fontFamily: "Poppins",
color: Colors.black,
fontWeight: FontWeight.w400,
),
decoration: InputDecoration(
hintText: hint,
hintStyle: TextStyle(
fontSize: 14,
fontFamily: "Poppins",
color: Colors.grey[400],
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
),
contentPadding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
border: InputBorder.none,
),
if (field.hasError)
Padding(
padding: const EdgeInsets.only(top: 5, left: 4),
child: Text(
field.errorText ?? '',
style: const TextStyle(
fontFamily: "Poppins",
color: Colors.red,
fontSize: 12,
),
),
),
),
if (hasError)
Padding(
padding: const EdgeInsets.only(top: 5, left: 4),
child: Text(
errorText,
style: const TextStyle(
fontFamily: "Poppins",
color: Colors.red,
fontSize: 12,
),
],
);
},
),
),
],
);
}
......@@ -318,4 +499,4 @@ class _EnquiryScreenState extends State<EnquiryScreen> {
noteController.dispose();
super.dispose();
}
}
}
\ No newline at end of file
......@@ -135,17 +135,28 @@ class _HelpScreenState extends State<HelpScreen> {
_buildCreateNewTicketSection(),
const SizedBox(height: 12),
if (closedTickets.isEmpty && processingTickets.isEmpty)
Center(
child: SectionHeading(
title: 'No issues have been raised yet.',
textStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
padding: EdgeInsets.symmetric(horizontal: 2, vertical: 4),
),
),
// Processing Tickets Section
if (processingTickets.isNotEmpty)
SectionHeading(
title: 'Processing Tickets',
textStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
padding: EdgeInsets.symmetric(horizontal: 2, vertical: 4),
),
const SizedBox(height: 2),
if (processingTickets.isNotEmpty)
_buildProcessingTicketsSection(processingTickets),
const SizedBox(height: 10),
// Closed Tickets Section
if (closedTickets.isNotEmpty)
SectionHeading(
title: 'Closed Tickets',
textStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
......@@ -153,6 +164,7 @@ class _HelpScreenState extends State<HelpScreen> {
),
const SizedBox(height: 2),
if (closedTickets.isNotEmpty)
_buildClosedTicketsSection(closedTickets),
],
),
......
......@@ -127,7 +127,7 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
// Create New Ticket Section
SectionHeading(
title: 'Select the order you are having issues with',
textStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
textStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, fontFamily: "Poppins",),
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 2),
),
......@@ -280,7 +280,7 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
width: 42,
fit: BoxFit.contain,
errorBuilder: (context, error, stack) =>
Image.asset('assets/images/gene_png.png',
Image.asset('assets/images/dashboard_gen.png',
height: 40, width: 40),
),
),
......@@ -369,6 +369,7 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
visibleItems[i],
style: const TextStyle(
color: Colors.black,
fontFamily: "Poppins",
fontSize: 14,
fontWeight: FontWeight.w400,
),
......@@ -430,10 +431,7 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
}
}
void _showReasonBottomSheet(
Orders product,
) {
// Your existing bottom sheet implementation
void _showReasonBottomSheet(Orders product) {
showModalBottomSheet(
context: context,
backgroundColor: Colors.white,
......@@ -461,7 +459,7 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
),
),
),
SizedBox(height: 12,),
SizedBox(height: 12),
Text(
"Select Your Reason",
style: TextStyle(
......@@ -496,6 +494,7 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
orderId: product.orderid.toString(),
icon: icon,
color: color,
bottomSheetContext: context, // Pass the bottom sheet context
);
},
),
......@@ -513,25 +512,31 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
required String icon,
required String orderId,
required Color color,
required BuildContext bottomSheetContext, // Add this parameter
}) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HelpTicketScreen(
reason: title,
// Close the bottom sheet first
Navigator.pop(bottomSheetContext);
// Then navigate to HelpTicketScreen after a small delay
Future.delayed(Duration(milliseconds: 300), () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HelpTicketScreen(
reason: title,
sessionId: widget.sessionId,
accId: widget.accId,
orderId: orderId,
))
).then((_) {
final provider = Provider.of<HelpAndEnquiryProvider>(context, listen: false);
provider.fetchTicketList(
sessionId: widget.sessionId,
accId: widget.accId,
orderId: orderId,
))
).then((_) {
final provider = Provider.of<HelpAndEnquiryProvider>(context, listen: false);
provider.fetchTicketList(
sessionId: widget.sessionId,
accId: widget.accId,
);
);
});
});
},
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 1),
......@@ -565,6 +570,7 @@ class _OrderHelpScreenState extends State<OrderHelpScreen> {
title,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "Poppins",
color: AppColors.nearDarkText,
fontSize: 13,
height: 1,
......
......@@ -275,21 +275,32 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
),
);
},
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.network(
images[index],
width: 100,
height: 80,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return Container(
width: 100,
height: 80,
color: Colors.grey.shade200,
child: const Icon(Icons.broken_image, color: Colors.grey),
);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey, // Border color
width: 1, // Border width
style: BorderStyle.solid, // Optional: solid, none
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.network(
images[index],
width: 100,
height: 80,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return Container(
width: 100,
height: 80,
color: Colors.grey.shade200,
child: const Icon(Icons.broken_image, color: Colors.grey),
);
},
),
),
),
),
......
......@@ -90,8 +90,9 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
),
SizedBox(width: screenWidth * 0.025),
Text(
"Bill List",
"Bill Details",
style: TextStyle(
fontFamily: "Poppins",
fontSize: isSmallScreen ? 14 : 16,
fontWeight: FontWeight.w400,
color: Colors.black87,
......@@ -114,9 +115,9 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
child: _buildBody(provider, screenWidth, screenHeight),
),
bottomNavigationBar: Container(
height: screenHeight * 0.09, // Responsive height
height: screenHeight * 0.085, // Responsive height
padding: EdgeInsets.symmetric(
horizontal: screenWidth * 0.04,
horizontal: screenWidth * 0.048,
vertical: screenHeight * 0.012,
),
width: double.infinity,
......@@ -147,8 +148,9 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
child: Text(
"View Bill",
style: TextStyle(
fontFamily: "Poppins",
fontSize: isSmallScreen ? 13 : 14,
fontWeight: FontWeight.w400,
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
),
),
......@@ -492,76 +494,64 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
SizedBox(height: screenHeight * 0.015),
// Table-like layout for dates and price
Table(
columnWidths: const {
0: FlexColumnWidth(2),
1: FlexColumnWidth(1),
},
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TableRow(
children: [
TableCell(
child: Text(
product.dispatchDate != null
? "Dispatched On ${product.dispatchDate!}"
: "Dispatch date not available",
style: TextStyle(
fontSize: isSmallScreen ? 10 : 12,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: AppColors.subtitleText,
),
),
),
TableCell(
child: Align(
alignment: Alignment.centerRight,
child: Text(
"Plan",
style: TextStyle(
fontSize: isSmallScreen ? 10 : 12,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: Colors.black54,
),
),
),
Expanded(
flex: 8,
child: Text(
product.dispatchDate != null
? "Dispatched On ${product.dispatchDate!}"
: "Dispatch date not available",
style: TextStyle(
fontSize: isSmallScreen ? 10 : 12,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: AppColors.subtitleText,
),
],
),
),
TableRow(
children: [
TableCell(
child: Text(
product.receivedDate != null
? "Received On ${product.receivedDate!}"
: "Receive date not available",
style: TextStyle(
fontSize: isSmallScreen ? 10 : 12,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: Colors.grey,
),
),
Expanded(
child: Text(
"Plan",
style: TextStyle(
fontSize: isSmallScreen ? 10 : 12,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: Colors.black54,
),
TableCell(
child: Align(
alignment: Alignment.centerRight,
child: Text(
product.totalPrice != null
? "${product.totalPrice!}${product.per ?? 'mo'}"
: 'Price not available',
style: TextStyle(
fontSize: isSmallScreen ? 12 : 14,
fontFamily: "Poppins",
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
color: Colors.black87,
),
),
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 7,
child: Text(
product.receivedDate != null
? "Received On ${product.receivedDate!}"
: "Receive date not available",
style: TextStyle(
fontSize: isSmallScreen ? 10 : 12,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
color: Colors.grey,
),
],
),
),
Text(
product.totalPrice != null
? "₹${product.totalPrice!}${product.per ?? 'mo'}"
: 'Price not available',
style: TextStyle(
fontSize: isSmallScreen ? 12 : 14,
fontFamily: "Poppins",
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
color: Colors.black87,
),
),
],
),
......@@ -663,7 +653,7 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
showModalBottomSheet(
context: context,
backgroundColor: Colors.white,
isScrollControlled: true, // Add this to allow scrolling
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
......@@ -679,7 +669,7 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
vertical: screenHeight * 0.016,
),
constraints: BoxConstraints(
maxHeight: screenHeight * 0.7, // Limit maximum height
maxHeight: screenHeight * 0.7,
),
child: Column(
mainAxisSize: MainAxisSize.min,
......@@ -706,7 +696,7 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
),
),
SizedBox(height: screenHeight * 0.025),
Expanded( // Wrap GridView with Expanded
Expanded(
child: GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
......@@ -714,7 +704,7 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
crossAxisCount: 3,
crossAxisSpacing: screenWidth * 0.03,
mainAxisSpacing: screenWidth * 0.03,
childAspectRatio: 0.85, // Reduced from 0.99 to prevent overflow
childAspectRatio: 0.85,
),
itemCount: createNewTickets.length,
itemBuilder: (context, index) {
......@@ -731,6 +721,7 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
icon: icon,
color: color,
screenWidth: screenWidth,
bottomSheetContext: context, // Pass bottom sheet context
);
},
),
......@@ -751,24 +742,31 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
required String icon,
required Color color,
required double screenWidth,
required BuildContext bottomSheetContext, // Add this parameter
}) {
final isSmallScreen = screenWidth < 360;
final iconSize = screenWidth * 0.20; // Slightly reduced
final imageSize = screenWidth * 0.09; // Slightly reduced
final iconSize = screenWidth * 0.20;
final imageSize = screenWidth * 0.09;
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HelpTicketScreen(
reason: title,
sessionId: widget.sessionId,
accId: widget.accId,
orderId: orderId,
// Close the bottom sheet first
Navigator.pop(bottomSheetContext);
// Then navigate to HelpTicketScreen after a small delay for smooth transition
Future.delayed(Duration(milliseconds: 300), () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HelpTicketScreen(
reason: title,
sessionId: widget.sessionId,
accId: widget.accId,
orderId: orderId,
),
),
),
);
);
});
},
child: Container(
padding: EdgeInsets.symmetric(
......@@ -776,7 +774,7 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
vertical: screenWidth * 0.002
),
child: Column(
mainAxisSize: MainAxisSize.min, // Use min to prevent overflow
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Icon container
......@@ -798,9 +796,9 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
),
),
),
SizedBox(height: screenWidth * 0.015), // Reduced spacing
SizedBox(height: screenWidth * 0.015),
// Title
SizedBox( //
SizedBox(
width: iconSize,
child: Text(
title,
......@@ -808,7 +806,7 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
style: TextStyle(
color: AppColors.nearDarkText,
fontFamily: "Poppins",
fontSize: isSmallScreen ? 11 : 13, // Slightly smaller font
fontSize: isSmallScreen ? 11 : 13,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.w400,
),
......@@ -816,7 +814,7 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
overflow: TextOverflow.ellipsis,
),
),
SizedBox(height: screenWidth * 0.005), // Reduced spacing
SizedBox(height: screenWidth * 0.005),
],
),
),
......
......@@ -388,7 +388,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
style: TextStyle(
fontSize: 16,
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
fontWeight: FontWeight.w500,
color: AppColors.normalText,
),
),
......@@ -428,7 +428,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
style: TextStyle(
fontSize: 18,
fontFamily: "Poppins",
fontWeight: FontWeight.w500,
fontWeight: FontWeight.w600,
color: AppColors.normalText,
),
),
......@@ -536,13 +536,13 @@ class _ProfileScreenState extends State<ProfileScreen> {
),
const SizedBox(height: 6),
Text(title,
style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.w400, fontFamily: "Poppins", color: Colors.black87)),
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.w600, fontFamily: "Poppins", color: Colors.black87)),
const SizedBox(height: 2),
Text(value,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.w400, fontFamily: "Poppins", color: Colors.black54)),
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.w400, fontFamily: "Poppins", color: AppColors.subtitleText)),
],
);
}
......@@ -551,12 +551,12 @@ class _ProfileScreenState extends State<ProfileScreen> {
return Column(
children: [
Text(title,
style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.w400, fontFamily: "Poppins", color: Colors.black87)),
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.w600, fontFamily: "Poppins", color: Colors.black87)),
const SizedBox(height: 4),
Text(value,
style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.w400, fontFamily: "Poppins", color: Colors.black54)),
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.w400, fontFamily: "Poppins", color: AppColors.subtitleText)),
],
);
}
......
......@@ -61,6 +61,22 @@ class _BillPendingToastState extends State<BillPendingToast> {
: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkResponse(
onTap: () => Navigator.pop(context),
child: CircleAvatar(
radius: 16,
backgroundColor: Colors.black12,
child: Icon(
Icons.close,
size: 16,
),
),
)
],
),
// 🔴 Red Pending Icon
Container(
height: 60,
......@@ -209,17 +225,18 @@ class _BillPendingToastState extends State<BillPendingToast> {
),
)
: const Icon(Icons.download_rounded,
color: Colors.black),
color: Colors.white),
label: const Text(
"Download",
style: TextStyle(
fontSize: 14,
fontFamily: "Poppins",
fontWeight: FontWeight.w600,
color: Colors.black,
color: Colors.white,
),
),
style: OutlinedButton.styleFrom(
backgroundColor: Colors.blue,
side: const BorderSide(color: Colors.black26),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
......@@ -229,27 +246,27 @@ class _BillPendingToastState extends State<BillPendingToast> {
),
),
const SizedBox(width: 12),
Expanded(
child: ElevatedButton(
onPressed: widget.onPayNow,
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.amountText,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
padding: const EdgeInsets.symmetric(vertical: 14),
),
child: const Text(
"Pay Now",
style: TextStyle(
fontSize: 15,
fontFamily: "Poppins",
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
),
),
// Expanded(
// child: ElevatedButton(
// onPressed: widget.onPayNow,
// style: ElevatedButton.styleFrom(
// backgroundColor: AppColors.amountText,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(50),
// ),
// padding: const EdgeInsets.symmetric(vertical: 14),
// ),
// child: const Text(
// "Pay Now",
// style: TextStyle(
// fontSize: 15,
// fontFamily: "Poppins",
// fontWeight: FontWeight.w600,
// color: Colors.white,
// ),
// ),
// ),
// ),
],
),
],
......
......@@ -73,7 +73,23 @@ class _BillStatusToastState extends State<BillStatusToast> {
: Column(
mainAxisSize: MainAxisSize.min,
children: [
// ✅ Success Tick
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkResponse(
onTap: () => Navigator.pop(context),
child: CircleAvatar(
radius: 16,
backgroundColor: Colors.black12,
child: Icon(
Icons.close,
size: 16,
),
),
)
],
),
// Success Tick
Container(
height: 60,
width: 60,
......
......@@ -94,7 +94,7 @@ class _LoginScreenState extends State<LoginScreen> {
// Fixed background image
Positioned.fill(
child: Image.asset(
'assets/images/background.jpg',
'assets/images/login_background.png',
fit: BoxFit.cover,
),
),
......@@ -168,10 +168,10 @@ class _LoginScreenState extends State<LoginScreen> {
keyboardType: TextInputType.phone,
onChanged: _validatePhone,
maxLength: 10,
style: const TextStyle(color: Colors.black),
style: const TextStyle(color: Colors.black, fontFamily: "Poppins",fontSize: 14),
decoration: InputDecoration(
hintText: "Enter Mobile No.",
hintStyle: const TextStyle(color: Colors.grey,fontFamily: "Poppins",),
hintStyle: const TextStyle(color: Colors.grey,fontFamily: "Poppins", fontSize: 14),
filled: true,
fillColor: Colors.white,
counterText: "", // Remove character counter
......
......@@ -97,9 +97,15 @@ class _OtpScreenState extends State<OtpScreen> {
// Navigate to dashboard
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => DashboardScreen(
accId: rentalProvider.otpResponse!.accId!,
sessionId: rentalProvider.otpResponse!.sessionId!,)
PageRouteBuilder(
pageBuilder: (_, __, ___) => DashboardScreen(accId: rentalProvider.otpResponse!.accId!, sessionId: rentalProvider.otpResponse!.sessionId.toString(),),
transitionsBuilder: (_, animation, __, child) {
return FadeTransition(
opacity: animation,
child: child,
);
},
transitionDuration: const Duration(milliseconds: 800),
),
);
} else {
......@@ -243,7 +249,7 @@ class _OtpScreenState extends State<OtpScreen> {
// Background image
Positioned.fill(
child: Image.asset(
'assets/images/background.jpg',
'assets/images/login_background.png',
fit: BoxFit.cover,
),
),
......
......@@ -99,8 +99,8 @@ class CustomSnackBar {
style: const TextStyle(
color: Colors.white,
fontFamily: "Poppins",
fontWeight: FontWeight.w700,
fontSize: 15,
fontWeight: FontWeight.w500,
fontSize: 14,
letterSpacing: -0.2,
),
),
......@@ -111,7 +111,7 @@ class CustomSnackBar {
style: TextStyle(
fontFamily: "Poppins",
color: Colors.white.withOpacity(0.9),
fontSize: 14,
fontSize: 13,
height: 1.3,
fontWeight: FontWeight.w400,
),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment