Commit 23aaf199 authored by Sai Srinivas's avatar Sai Srinivas
Browse files

New Screen and Api added

parent eecc769f
import 'package:flutter/material.dart';
import 'package:gen_rentals/Utility/Reusablewidgets.dart';
import '../Utility/AppColors.dart';
import 'package:flutter_svg/flutter_svg.dart';
class PaymentSuccessfulScreen extends StatefulWidget {
const PaymentSuccessfulScreen({super.key});
@override
State<PaymentSuccessfulScreen> createState() => _PaymentSuccessfulScreenState();
}
class _PaymentSuccessfulScreenState extends State<PaymentSuccessfulScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.backgroundRegular,
body: SafeArea(
child: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 14),
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFFFFFFFF),
Color(0xFFFFFFFF),
AppColors.backgroundRegular,
AppColors.backgroundRegular,
AppColors.backgroundRegular
],
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 40),
// Success Icon
Container(
width: double.infinity,
height: 140,
color: Colors.white,
child: Image.asset(
'assets/images/success_pay_gif.gif',
height: 80,
width: 80,
),
),
const SizedBox(height: 24),
// Success Title
const Text(
"Payment Successful",
style: TextStyle(
fontFamily: "Poppins",
fontSize: 24,
fontWeight: FontWeight.w500,
color: AppColors.normalText,
),
),
const SizedBox(height: 8),
// Success Message
Text(
"Now enjoy a seamless,\nuninterrupted rental service.",
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "Poppins",
fontSize: 16,
fontWeight: FontWeight.w400,
color: AppColors.subtitleText,
height: 1.5,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 25),
const SectionHeading(title: "Payment Details"),
// Payment Details Section
_buildSection(
children: [
_buildDetailRow(title: "Date", value: "8th Oct, 2025"),
_buildDetailRow(title: "Payment Mode", value: "Credit Card **56"),
_buildDetailRow(
title: "Payment Status",
value: "Paid",
valueStyle: const TextStyle(
color: Color(0xFF4CAF50),
fontWeight: FontWeight.w600,
),
),
],
),
const SizedBox(height: 10),
const SectionHeading(title: "Bill Details"),
// Bill Details Section
_buildSection(
children: [
_buildDetailRow(title: "Total Amount", value: "₹421"),
_buildDetailRow(title: "Bill Cycle", value: "7th Sep, 2025 – 7th Oct, 2025"),
_buildDetailRow(title: "Bill Generated Date", value: "8th Oct, 2025"),
_buildDetailRow(title: "Payable Amount", value: "₹421"),
_buildDetailRow(title: "Paid Date/Due Date", value: "7th Oct, 2025"),
],
),
],
),
const SizedBox(height: 25),
// Back to Home Button
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
// Add navigation logic here
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.buttonColor,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
padding: const EdgeInsets.symmetric(vertical: 16),
),
child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 22),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Back to Home",
style: TextStyle(
color: Color(0xFFFFFFFF),
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
],
),
),
),
),
const SizedBox(height: 20),
],
),
),
),
),
);
}
Widget _buildSection({
required List<Widget> children,
}) {
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
decoration: BoxDecoration(
color: const Color(0xFFF8F9FA),
borderRadius: BorderRadius.circular(18),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: children,
),
);
}
Widget _buildDetailRow({
required String title,
required String value,
TextStyle? valueStyle,
}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: const TextStyle(
fontFamily: "Poppins",
fontSize: 14,
fontWeight: FontWeight.w400,
color: Color(0xFF777777),
),
),
Row(
children: [
if (value == "Paid")
SvgPicture.asset(
"assets/svg/success_ic.svg",
height: 18,
width: 18,
),
if (value == "Pending")
SvgPicture.asset(
"assets/svg/failed_ic.svg",
height: 18,
width: 18,
),
const SizedBox(width: 4),
Text(
value,
style: valueStyle ?? const TextStyle(
fontFamily: "Poppins",
fontSize: 14,
fontWeight: FontWeight.w400,
color: AppColors.normalText,
),
),
],
),
],
),
);
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -3,6 +3,10 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:gen_rentals/Screens/BillDetailListScreen.dart';
import 'package:gen_rentals/Screens/DashboardScreen.dart';
import 'package:gen_rentals/Screens/ProductsDetailScreen.dart';
import 'package:gen_rentals/Screens/TransactionsScreen.dart';
import '../Utility/CustomSnackbar.dart';
import 'authScreen/LoginScreen.dart';
......@@ -76,7 +80,7 @@ class _SplashScreenState extends State<SplashScreen> with SingleTickerProviderSt
Navigator.pushReplacement(
context,
PageRouteBuilder(
pageBuilder: (_, __, ___) => const LoginScreen(),
pageBuilder: (_, __, ___) => LoginScreen(),
transitionsBuilder: (_, animation, __, child) {
return FadeTransition(
opacity: animation,
......
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../Utility/AppColors.dart';
class TransactionsScreen extends StatefulWidget {
const TransactionsScreen({super.key});
@override
State<TransactionsScreen> createState() => _TransactionsScreenState();
}
class _TransactionsScreenState extends State<TransactionsScreen> {
// Dummy data for transactions
final List<Map<String, dynamic>> transactions = [
{
"type": "debit",
"title": "Payment for June Rent",
"date": "25 Dec 2025",
"amount": "₹5,390.00",
"ref": "₹1,12,300"
},
{
"type": "debit",
"title": "Payment for June Rent",
"date": "25 Dec 2025",
"amount": "₹2,512.00",
"ref": "₹26,300"
},
{
"type": "credit",
"title": "Refund of Deposit Amount",
"date": "25 Dec 2025",
"amount": "₹19,790.00",
"ref": "₹1,26,300"
},
{
"type": "debit",
"title": "Payment for June Rent",
"date": "25 Dec 2025",
"amount": "₹5,390.00",
"ref": "₹1,12,300"
},
{
"type": "debit",
"title": "Payment for June Rent",
"date": "25 Dec 2025",
"amount": "₹2,512.00",
"ref": "₹26,300"
},
{
"type": "credit",
"title": "Refund of Deposit Amount",
"date": "25 Dec 2025",
"amount": "₹19,790.00",
"ref": "₹1,26,300"
},
];
@override
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: Scaffold(
backgroundColor: AppColors.backgroundRegular,
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
titleSpacing: 0,
title: Row(
children: [
InkResponse(
onTap: () => Navigator.pop(context),
child: SvgPicture.asset(
"assets/svg/continue_left_ic.svg",
height: 25,
width: 25,
),
),
const SizedBox(width: 12),
const Text(
"Transactions",
style: TextStyle(
fontSize: 16,
fontFamily: "Poppins",
fontWeight: FontWeight.w500,
color: Colors.black,
),
),
],
),
),
// Main content
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Column(
children: [
SizedBox(height: 4,),
// Balance Card
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient: const LinearGradient(
colors: [
Color(0xFFE9FFEF),
Color(0xFFD6FFDF),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Column(
children: [
Text(
"₹12,596",
style: TextStyle(
fontFamily: "Poppins",
fontWeight: FontWeight.w500,
fontSize: 34,
color: AppColors.cardAmountText,
),
),
const SizedBox(height: 4),
Text(
"Balance Amount",
style: TextStyle(
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
fontSize: 14,
color: AppColors.cardAmountText,
),
),
const SizedBox(height: 10),
Container(
height: 1,
color: const Color(0xFF777777).withOpacity(0.3),
),
const SizedBox(height: 14),
// Credited / Debited info
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildAmountSummary(
icon: "assets/svg/cross_down_arrow.svg",
color: Colors.white,
amount: "₹26,300",
label: "Credited Amount",
),
_buildAmountSummary(
icon: "assets/svg/cross_up_arrow.svg",
color: Colors.white,
amount: "₹26,300",
label: "Debited Amount",
),
],
),
],
),
),
const SizedBox(height: 16),
// Transaction list
Column(
children: transactions.map((t) {
return _buildTransactionItem(
type: t["type"],
title: t["title"],
date: t["date"],
amount: t["amount"],
ref: t["ref"],
);
}).toList(),
),
],
),
),
),
);
}
Widget _buildAmountSummary({
required String icon,
required Color color,
required String amount,
required String label,
}) {
return Row(
children: [
// Icon and title row
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: color.withOpacity(0.9),
borderRadius: BorderRadius.circular(30),
),
child: Center( // Add this Center widget
child: SvgPicture.asset(
icon,
height: 20,
width: 20,
// Remove fit: BoxFit.none
),
),
),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
amount,
style: TextStyle(
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
fontSize: 14,
color: Colors.black,
),
),
Text(
label,
style: TextStyle(
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
fontSize: 12,
color: Colors.grey.shade600,
),
),
],
),
],
);
}
Widget _buildTransactionItem({
required String type,
required String title,
required String date,
required String amount,
required String ref,
}) {
final isCredit = type == "credit";
return Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 14),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(14),
// border: Border.all(color: Colors.grey.shade200, width: 1),
// boxShadow: [
// BoxShadow(
// color: Colors.black.withOpacity(0.02),
// blurRadius: 5,
// offset: const Offset(0, 1),
// ),
// ],
),
child: Row(
children: [
// Icon and title row
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: isCredit ? Colors.green.withOpacity(0.09) : Colors.red.withOpacity(0.09),
borderRadius: BorderRadius.circular(30),
),
child: Center( // Add this Center widget
child: SvgPicture.asset(
isCredit ? "assets/svg/cross_down_arrow.svg" : "assets/svg/cross_up_arrow.svg",
height: 20,
width: 20,
// Remove fit: BoxFit.none
),
),
),
// Container(
// padding: const EdgeInsets.all(8),
// decoration: BoxDecoration(
// color: isCredit
// ? const Color(0xFFE8F9EE)
// : const Color(0xFFFFEBEB),
// shape: BoxShape.circle,
// ),
// child: Icon(
// isCredit ? Icons.arrow_downward_rounded : Icons.arrow_upward_rounded,
// color: isCredit ? Colors.green : Colors.red,
// size: 20,
// ),
// ),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
fontSize: 14,
color: Colors.black,
),
),
const SizedBox(height: 4),
Text(
date,
style: TextStyle(
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
fontSize: 12,
color: Colors.grey.shade600,
),
),
],
),
),
const SizedBox(width: 12),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
amount,
style: TextStyle(
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
fontSize: 14,
color: Colors.black,
),
),
const SizedBox(height: 4),
Row(
children: [
Text(
ref,
style: TextStyle(
fontFamily: "Poppins",
fontWeight: FontWeight.w400,
fontSize: 12,
color: Colors.grey.shade600,
),
),
const SizedBox(width: 4),//
SvgPicture.asset(
"assets/svg/rupee_coin_ic.svg",
height: 14,
width: 14,
// Remove fit: BoxFit.none
),
],
),
],
),
],
),
);
}
}
......@@ -26,58 +26,47 @@ class _LoginScreenState extends State<LoginScreen> {
}
Future<void> _login(BuildContext context) async {
final rentalProvider =
Provider.of<RentalContactProvider>(context, listen: false);
final rentalProvider = Provider.of<RentalProvider>(context, listen: false);
final mob = _phoneController.text.trim();
await rentalProvider.fetchRentalContactData(
context,
"4d21382d9e1c4d6e0b7c426d53d89b6b7d48078877f185289092e6fa13bac4b11d417d37738b20b34151b8e638625b3ec013",
"5",
mob,
);
await rentalProvider.fetchRentalMobile(mob);
// ✅ Handle response
if (rentalProvider.rentalContact != null &&
rentalProvider.rentalContact!.error == 0) {
// ✅ Handle response - Check if error is "0" (string comparison)
if (rentalProvider.response != null && rentalProvider.response!.error == "0") {
AnimatedSnackBar.success(
context: context,
title: "Login Success",
message: "${rentalProvider.rentalContact?.message} OTP: ${rentalProvider.rentalContact?.otp}" ?? "Login Success",
title: "OTP Sent",
message: rentalProvider.response?.errorMsg ?? "OTP sent to your registered mobile number!",
);
// Navigate to OTP screen
// Navigate to OTP screen after a short delay
Future.delayed(const Duration(milliseconds: 1500), () {
if (mounted) {
Navigator.pushReplacement(
context,
PageRouteBuilder(
pageBuilder: (_, __, ___) => OtpScreen(
mob: mob,
otp: rentalProvider.rentalContact!.otp ?? 0,
),
transitionsBuilder: (_, animation, __, child) {
return FadeTransition(opacity: animation, child: child);
},
transitionDuration: const Duration(milliseconds: 600),
MaterialPageRoute(
builder: (context) => OtpScreen(mob: mob),
),
);
}
});
} else {
CustomSnackBar.showWarning(
context: context,
message: rentalProvider.rentalContact?.message ??
rentalProvider.errorMessage ??
"Login failed",
title: "Login Status",
title: "Login Failed",
message: rentalProvider.response?.errorMsg ??
"Mobile number not registered or invalid",
);
}
}
@override
Widget build(BuildContext context) {
final rentalProvider = Provider.of<RentalContactProvider>(context);
final rentalProvider = Provider.of<RentalProvider>(context);
return Scaffold(
resizeToAvoidBottomInset: false, // prevents background image resize
resizeToAvoidBottomInset: false,
body: Stack(
children: [
// 🏙️ Fixed background image
......@@ -115,8 +104,7 @@ class _LoginScreenState extends State<LoginScreen> {
],
),
),
padding:
const EdgeInsets.symmetric(horizontal: 22, vertical: 20),
padding: const EdgeInsets.symmetric(horizontal: 22, vertical: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
......@@ -155,12 +143,14 @@ class _LoginScreenState extends State<LoginScreen> {
controller: _phoneController,
keyboardType: TextInputType.phone,
onChanged: _validatePhone,
maxLength: 10,
style: const TextStyle(color: Colors.black),
decoration: InputDecoration(
hintText: "Enter Mobile No.",
hintStyle: const TextStyle(color: Colors.grey),
filled: true,
fillColor: Colors.white,
counterText: "", // Remove character counter
contentPadding: const EdgeInsets.symmetric(
vertical: 16, horizontal: 20),
enabledBorder: OutlineInputBorder(
......@@ -172,8 +162,7 @@ class _LoginScreenState extends State<LoginScreen> {
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide:
const BorderSide(color: Colors.blue, width: 2),
borderSide: const BorderSide(color: Colors.blue, width: 2),
),
),
),
......@@ -208,13 +197,11 @@ class _LoginScreenState extends State<LoginScreen> {
? const Color(0xFF008CDE)
: const Color(0xFF266E99),
foregroundColor: Colors.white,
disabledBackgroundColor:
const Color(0xFF266E99),
disabledBackgroundColor: const Color(0xFF266E99),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
padding:
const EdgeInsets.symmetric(vertical: 16),
padding: const EdgeInsets.symmetric(vertical: 16),
),
child: rentalProvider.isLoading
? const SizedBox(
......@@ -222,17 +209,14 @@ class _LoginScreenState extends State<LoginScreen> {
width: 22,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
AlwaysStoppedAnimation<Color>(
valueColor: AlwaysStoppedAnimation<Color>(
Colors.white),
),
)
: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 22),
padding: const EdgeInsets.symmetric(horizontal: 22),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Continue",
......
......@@ -7,13 +7,11 @@ import '../../Utility/AdvancedSnackbar.dart';
import '../../Utility/CustomSnackbar.dart';
class OtpScreen extends StatefulWidget {
final String mob; // ✅ phone number
final int otp; // ✅ backend OTP
final String mob; // phone number
const OtpScreen({
super.key,
required this.mob,
required this.otp,
});
@override
......@@ -28,12 +26,10 @@ class _OtpScreenState extends State<OtpScreen> {
bool _isVerifying = false;
bool _isResending = false;
int _secondsRemaining = 22;
int _currentOtp = 0; // ✅ Store current OTP in state
@override
void initState() {
super.initState();
_currentOtp = widget.otp; // ✅ Initialize with passed OTP
_startTimer();
}
......@@ -69,62 +65,80 @@ class _OtpScreenState extends State<OtpScreen> {
}
Future<void> _verifyOtp() async {
final rentalProvider = Provider.of<RentalProvider>(context, listen: false);
final enteredOtp = _controllers.map((c) => c.text).join();
setState(() => _isVerifying = true);
await Future.delayed(const Duration(milliseconds: 800));
// Compare with current OTP (not widget.otp)
if (enteredOtp == _currentOtp.toString()) {
// OTP verified successfully
try {
await rentalProvider.fetchMobileOtp(widget.mob, enteredOtp);
if (rentalProvider.otpResponse != null) {
if (rentalProvider.otpResponse?.error == "0") {
// ✅ OTP verified successfully
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(" OTP Verified Successfully!"),
backgroundColor: Colors.green,
),
);
// navigation:
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (_) => const DashboardScreen())
AnimatedSnackBar.success(
context: context,
title: "Success",
message: rentalProvider.otpResponse?.message ?? "OTP Verified Successfully!",
);
// Navigate to dashboard
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => const DashboardScreen()),
);
} else {
// ❌ Invalid OTP
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("❌ Invalid OTP. Please try again."),
backgroundColor: Colors.redAccent,
),
CustomSnackBar.showError(
context: context,
title: "Error",
message: rentalProvider.otpResponse?.errorMsg ??
rentalProvider.otpResponse?.message ??
"Invalid OTP. Please try again.",
);
}
} else {
// ❌ API Error
CustomSnackBar.showError(
context: context,
title: "Error",
message: rentalProvider.otpResponse?.message ?? "Failed to verify OTP. Please try again.",
);
}
} catch (e) {
// ❌ Network Error
CustomSnackBar.showError(
context: context,
title: "Network Error",
message: e.toString(),
);
} finally {
if (mounted) setState(() => _isVerifying = false);
}
}
/// Resend OTP Function
/// 🔁 Resend OTP Function
Future<void> _resendOtp(BuildContext context) async {
setState(() => _isResending = true);
try {
final rentalProvider =
Provider.of<RentalContactProvider>(context, listen: false);
final rentalProvider = Provider.of<RentalProvider>(context, listen: false);
await rentalProvider.fetchRentalContactData(
context,
"4d21382d9e1c4d6e0b7c426d53d89b6b7d48078877f185289092e6fa13bac4b11d417d37738b20b34151b8e638625b3ec013",
"5",
widget.mob,
);
// Call the mobile API again to get new OTP
await rentalProvider.fetchRentalMobile(widget.mob);
if (rentalProvider.rentalContact != null &&
rentalProvider.rentalContact!.error == 0) {
if (rentalProvider.response != null && rentalProvider.response?.error == "0") {
// ✅ Successfully resent OTP
AnimatedSnackBar.success(
context: context,
title: "OTP Sent",
message: rentalProvider.response?.message ?? "OTP has been sent to your mobile number.",
);
// Update current OTP with the new one from API response
final newOtp = rentalProvider.rentalContact!.otp!;
// Reset timer and clear fields
setState(() {
_currentOtp = newOtp; // Update current OTP
_secondsRemaining = 22;
});
......@@ -139,18 +153,13 @@ class _OtpScreenState extends State<OtpScreen> {
// Restart timer
_startTimer();
AnimatedSnackBar.success(
context: context,
title: "OTP Sent",
message: "${rentalProvider.rentalContact?.message} (OTP: $newOtp)",
);
} else {
// ❌ Failed to resend OTP
CustomSnackBar.showWarning(
context: context,
title: "Error",
message: rentalProvider.rentalContact?.message ??
rentalProvider.errorMessage ??
message: rentalProvider.response?.errorMsg ??
rentalProvider.response?.message ??
"Failed to resend OTP",
);
}
......@@ -330,8 +339,7 @@ class _OtpScreenState extends State<OtpScreen> {
? const Color(0xFF008CDE)
: const Color(0xFF266E99),
foregroundColor: Colors.white,
disabledBackgroundColor:
const Color(0xFF266E99),
disabledBackgroundColor: const Color(0xFF266E99),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
......@@ -347,11 +355,9 @@ class _OtpScreenState extends State<OtpScreen> {
),
)
: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 22),
padding: const EdgeInsets.symmetric(horizontal: 22),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Continue",
......
This diff is collapsed.
......@@ -30,3 +30,9 @@ const ticketChatUrl = "${baseUrl}ticket_chat";
const ticketChatDisplayUrl = "${baseUrl}ticket_chat_display";
const ticketCUrl = "${baseUrl}ticket_c";
const ticketListUrl = "${baseUrl}ticket_list";
/// dashboard and login
const fetchMobileUrl = "${baseUrl}fetch_mobile_number";
const fetchOtpUrl = "${baseUrl}login";
const dashboardUrl = "${baseUrl}ticket_list";
\ No newline at end of file
......@@ -10,9 +10,11 @@ import 'package:gen_rentals/Models/orderDetailsProductResponse.dart';
import 'package:gen_rentals/Models/orderListResponse.dart';
import 'package:gen_rentals/Models/ticketListResponse.dart';
import 'package:gen_rentals/Notifier/billDetailsResponse.dart';
import '../Models/DashboardResponse.dart';
import '../Models/RentalPaymentDetailsResponse.dart';
import '../Models/rentalAccountResponse.dart';
import '../Models/rentalContactResponse.dart';
import '../Notifier/RentalContactProvider .dart';
import 'api_URLs.dart';
import 'api_post_request.dart';
......@@ -21,22 +23,42 @@ class ApiCalling {
/// Fetch rental contact by mobile number
static Future<RentalContactResponse?> fetchRentalContactApi(
String sessionId,
String empId,
static Future<FetchMobileResponse?> fetchRentalMobileApi(
String mob,
) async {
debugPrint("############################### Api calling ");
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"mob": mob,
};
final res = await post(data, rentalContactUrl, {});
final res = await post(data, fetchMobileUrl, {});
if (res != null) {
return FetchMobileResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error: $e");
return null;
}
}
static Future<FetchMobileResponse?> fetchMobileOtpApi(
String mob,
String otp
) async {
debugPrint("############################### Api calling ");
try {
Map<String, String> data = {
"mob": mob,
"otp": otp,
};
final res = await post(data, fetchOtpUrl, {});
if (res != null) {
return RentalContactResponse.fromJson(jsonDecode(res.body));
return FetchMobileResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
......@@ -510,5 +532,33 @@ class ApiCalling {
}
}
/// Fetch Dashboard
static Future<DashboardResponse?> fetchDashboardApi(
String sessionId,
String empId,
String mob,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"mob": mob,
};
final res = await post(data, dashboardUrl, {});
if (res != null) {
return DashboardResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetch Balance): $e");
return null;
}
}
}
......@@ -7,6 +7,14 @@ class AppColors {
static const Color secondary = Color(0xFF10B981);
static const Color accent = Color(0xFFF59E0B);
// Text colors
static const Color amountText = Color(0xFF008CDE);
static const Color cardAmountText = Color(0xFF2D2D2D);
static const Color normalText = Color(0xFF2D2D2D);
static const Color subtitleText = Color(0xFF8E8E8E);
static const Color warningText = Color(0xFFF00000);
static const Color nearDarkText = Color(0xFF1E1E1E);
// Status colors
static const Color success = Color(0xFF10B981);
static const Color warning = Color(0xFFF59E0B);
......@@ -21,4 +29,8 @@ class AppColors {
// Background colors
static const Color backgroundLight = Color(0xFFFFFFFF);
static const Color backgroundDark = Color(0xFF111827);
static const Color backgroundRegular = Color(0xFFF2F2F2);
//Button
static const Color buttonColor = Color(0xFF008CDE);
}
\ No newline at end of file
import 'package:flutter/material.dart';
class SectionHeading extends StatelessWidget {
final String title;
final TextStyle? textStyle;
final EdgeInsetsGeometry padding;
const SectionHeading({
Key? key,
required this.title,
this.textStyle = const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, fontFamily: "Poppins"),
this.padding = const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: padding,
child: Text(
title,
style: textStyle ??
Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:gen_rentals/Notifier/DashboardProvider.dart';
import 'package:gen_rentals/Screens/SplashScreen.dart';
import 'package:provider/provider.dart';
import 'Notifier/RentalContactProvider .dart';
......@@ -24,10 +25,9 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<RentalContactProvider>(create: (_) => RentalContactProvider(),
),
ChangeNotifierProvider<ThemeProvider>(create: (_) => ThemeProvider(),
),
ChangeNotifierProvider<DashboardProvider>(create: (_) => DashboardProvider()),
ChangeNotifierProvider<RentalProvider>(create: (_) => RentalProvider(),),
ChangeNotifierProvider<ThemeProvider>(create: (_) => ThemeProvider(),),
],
child: Consumer<ThemeProvider>(
builder: (context, themeProvider, child) {
......
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