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

First commit after setup

parent a2b314a9
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:gen_rentals/Screens/authScreen/OTP_Screen.dart';
import 'package:provider/provider.dart';
import '../../Notifier/RentalContactProvider .dart';
import '../../Utility/AdvancedSnackbar.dart';
import '../../Utility/CustomSnackbar.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final TextEditingController _phoneController = TextEditingController();
bool _isValid = false;
bool _isDirty = false;
void _validatePhone(String value) {
setState(() {
_isDirty = true;
_isValid = RegExp(r'^[0-9]{10}$').hasMatch(value);
});
}
Future<void> _login(BuildContext context) async {
final rentalProvider =
Provider.of<RentalContactProvider>(context, listen: false);
final mob = _phoneController.text.trim();
await rentalProvider.fetchRentalContactData(
context,
"4d21382d9e1c4d6e0b7c426d53d89b6b7d48078877f185289092e6fa13bac4b11d417d37738b20b34151b8e638625b3ec013",
"5",
mob,
);
// ✅ Handle response
if (rentalProvider.rentalContact != null &&
rentalProvider.rentalContact!.error == 0) {
AnimatedSnackBar.success(
context: context,
title: "Login Success",
message: "${rentalProvider.rentalContact?.message} OTP: ${rentalProvider.rentalContact?.otp}" ?? "Login Success",
);
// Navigate to OTP screen
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),
),
);
} else {
CustomSnackBar.showWarning(
context: context,
message: rentalProvider.rentalContact?.message ??
rentalProvider.errorMessage ??
"Login failed",
title: "Login Status",
);
}
}
@override
Widget build(BuildContext context) {
final rentalProvider = Provider.of<RentalContactProvider>(context);
return Scaffold(
resizeToAvoidBottomInset: false, // prevents background image resize
body: Stack(
children: [
// 🏙️ Fixed background image
Positioned.fill(
child: Image.asset(
'assets/images/background.jpg',
fit: BoxFit.cover,
),
),
// 🌑 Dark overlay
Positioned.fill(
child: Container(color: Colors.black.withOpacity(0.4)),
),
// 📦 Foreground content with gradient
Align(
alignment: Alignment.bottomCenter,
child: AnimatedPadding(
duration: const Duration(milliseconds: 250),
curve: Curves.easeOut,
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Container(
width: double.infinity,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.transparent,
Colors.black54,
Colors.black87,
],
),
),
padding:
const EdgeInsets.symmetric(horizontal: 22, vertical: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 60),
const Text(
"Rental Power,\nManaged in a Tap",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 35,
fontWeight: FontWeight.w400,
height: 1.3,
),
),
const SizedBox(height: 34),
// 🏷️ Label above input
const Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.only(left: 12),
child: Text(
"Enter Registered Mobile No.",
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w400,
),
),
),
),
const SizedBox(height: 8),
// 📱 Mobile Input
TextField(
controller: _phoneController,
keyboardType: TextInputType.phone,
onChanged: _validatePhone,
style: const TextStyle(color: Colors.black),
decoration: InputDecoration(
hintText: "Enter Mobile No.",
hintStyle: const TextStyle(color: Colors.grey),
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.symmetric(
vertical: 16, horizontal: 20),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide(
color: Colors.white.withOpacity(0.5),
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide:
const BorderSide(color: Colors.blue, width: 2),
),
),
),
// ⚠️ Validation message
if (_isDirty && !_isValid)
const Padding(
padding: EdgeInsets.only(left: 12, top: 8),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"*Invalid number. Enter your registered number.",
style: TextStyle(
color: Colors.redAccent,
fontSize: 12,
),
),
),
),
const SizedBox(height: 20),
// 🔘 Continue Button
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: (!_isValid || rentalProvider.isLoading)
? null
: () => _login(context),
style: ElevatedButton.styleFrom(
backgroundColor: _isValid
? const Color(0xFF008CDE)
: const Color(0xFF266E99),
foregroundColor: Colors.white,
disabledBackgroundColor:
const Color(0xFF266E99),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
padding:
const EdgeInsets.symmetric(vertical: 16),
),
child: rentalProvider.isLoading
? const SizedBox(
height: 22,
width: 22,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
AlwaysStoppedAnimation<Color>(
Colors.white),
),
)
: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 22),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
"Continue",
style: TextStyle(
color: _isValid
? const Color(0xFFFFFFFF)
: const Color(0xFF03456C),
fontSize: 16,
),
),
SvgPicture.asset(
"assets/svg/continue_ic.svg",
color: _isValid
? const Color(0xFFFFFFFF)
: const Color(0xFF03456C),
height: 25,
width: 25,
),
],
),
),
),
),
const SizedBox(height: 40),
],
),
),
),
),
],
),
);
}
}
// forgot_password_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class ForgotPasswordScreen extends StatelessWidget {
const ForgotPasswordScreen({super.key});
@override
Widget build(BuildContext context) {
final emailController = TextEditingController();
return Scaffold(
backgroundColor: const Color(0xFFF5F8FC),
body: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.network(
"https://genrentals.in/assets/img/logo-black.svg",
height: 70,
),
const SizedBox(height: 20),
const Text(
"Forgot Password",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
const SizedBox(height: 20),
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 6,
offset: Offset(0, 2),
)
],
),
child: Column(
children: [
TextFormField(
controller: emailController,
decoration: InputDecoration(
labelText: "Email Address",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
),
),
),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
height: 45,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2563EB),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content:
Text("Password reset link sent to email")),
);
},
child: const Text(
"Confirm",
style: TextStyle(color: Colors.white),
),
),
)
],
),
),
],
),
),
),
);
}
}
This diff is collapsed.
/// base Url of api
const baseUrl = "https://erp.gengroup.in/ci/app/Inventory/";
/// tokens url
const addFcmTokenUrl = "${baseUrl}add_fcm_token";
/// payments and bills
const addPaymentUrl = "${baseUrl}add_payment";
const rentalPaymentDetailsUrl = "${baseUrl}rental_payment_details";
const balanceUrl = "${baseUrl}balance";
const billDetailsUrl = "${baseUrl}bill_details";
const billListUrl = "${baseUrl}bill_list";
const billProductUrl = "${baseUrl}bill_product";
/// info
const checkInOutSubmitUrl = "${baseUrl}check_in_out_submit";
const rentalContactUrl = "${baseUrl}rental_contact";
const getRentalAccInfoUrl = "${baseUrl}get_rental_acc_info";
/// order
const orderDetailsBillUrl = "${baseUrl}order_details_bill";
const orderDetailsMainUrl = "${baseUrl}order_details_main";
const orderDetailsProductUrl = "${baseUrl}order_details_product";
const orderListUrl = "${baseUrl}order_list";
const tagOrderUrl = "${baseUrl}tag_order";
/// tickets
const raiseTicketUrl = "${baseUrl}raise_ticket";
const ticketChatUrl = "${baseUrl}ticket_chat";
const ticketChatDisplayUrl = "${baseUrl}ticket_chat_display";
const ticketCUrl = "${baseUrl}ticket_c";
const ticketListUrl = "${baseUrl}ticket_list";
\ No newline at end of file
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:gen_rentals/Models/CommonResponse.dart';
import 'package:gen_rentals/Models/TicketChatDisplayResponse.dart';
import 'package:gen_rentals/Models/billListResponse.dart';
import 'package:gen_rentals/Models/billProductResponse.dart';
import 'package:gen_rentals/Models/orderDetailsBillResponse.dart';
import 'package:gen_rentals/Models/orderDetailsMainResponse.dart';
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/RentalPaymentDetailsResponse.dart';
import '../Models/rentalAccountResponse.dart';
import '../Models/rentalContactResponse.dart';
import 'api_URLs.dart';
import 'api_post_request.dart';
class ApiCalling {
/// Fetch rental contact by mobile number
static Future<RentalContactResponse?> fetchRentalContactApi(
String sessionId,
String empId,
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, {});
if (res != null) {
return RentalContactResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error: $e");
return null;
}
}
/// Fetch Rental Account Info
static Future<RentalAccountResponse?> fetchRentalAccountInfoApi(
String sessionId,
String empId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
};
final res = await post(data, getRentalAccInfoUrl, {});
if (res != null) {
return RentalAccountResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchRentalAccountInfo): $e");
return null;
}
}
/// Fetch Bill List
static Future<BillListResponse?> fetchBillListApi(
String sessionId,
String empId,
String accId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"acc_id": accId,
};
final res = await post(data, billListUrl, {});
if (res != null) {
return BillListResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchBillList): $e");
return null;
}
}
/// Fetch Bill Details
static Future<BillDetailsResponse?> fetchBillDetailsApi(
String sessionId,
String empId,
String billId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"bill_id": billId,
};
final res = await post(data, billDetailsUrl, {});
if (res != null) {
return BillDetailsResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchBillDetails): $e");
return null;
}
}
/// Fetch Bill Product
static Future<BillProductResponse?> fetchBillProductApi(
String sessionId,
String empId,
String accId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"acc_id": accId,
};
final res = await post(data, billProductUrl, {});
if (res != null) {
return BillProductResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchBillProduct): $e");
return null;
}
}
/// Fetch Order Detail Bill
static Future<OrderDetailsBillResponse?> fetchOrderDetailBillApi(
String sessionId,
String empId,
String orderId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"ord_id": orderId,
};
final res = await post(data, orderDetailsBillUrl, {});
if (res != null) {
return OrderDetailsBillResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchOrderDetailBill): $e");
return null;
}
}
/// Fetch Order List
static Future<OrderListResponse?> fetchOrderListApi(
String sessionId,
String empId,
String accId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"acc_id": accId,
};
final res = await post(data, orderListUrl, {});
if (res != null) {
return OrderListResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchOrderList): $e");
return null;
}
}
/// Fetch Order Details Product
static Future<OrderDetailsProductResponse?> fetchOrderDetailProductApi(
String sessionId,
String empId,
String orderId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"order_id": orderId,
};
final res = await post(data, orderDetailsProductUrl, {});
if (res != null) {
return OrderDetailsProductResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchOrderDetailProduct): $e");
return null;
}
}
/// Fetch Order Details Main
static Future<OrderDetailsMainResponse?> fetchOrderDetailMainApi(
String sessionId,
String empId,
String orderId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"ord_id": orderId,
};
final res = await post(data, orderDetailsMainUrl, {});
if (res != null) {
return OrderDetailsMainResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchOrderDetailMain): $e");
return null;
}
}
/// Fetch Rental Payment Details
static Future<RentalPaymentDetailsResponse?> fetchRentalPaymentDetailsApi(
String sessionId,
String empId,
String billId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"bill_id": billId,
};
final res = await post(data, rentalPaymentDetailsUrl, {});
if (res != null) {
return RentalPaymentDetailsResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchRentalPaymentDetails): $e");
return null;
}
}
/// Fetch Ticket List
static Future<TicketListResponse?> fetchTicketListApi(
String sessionId,
String empId,
String accId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"acc_id": accId,
};
final res = await post(data, ticketListUrl, {});
if (res != null) {
return TicketListResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchTicketList): $e");
return null;
}
}
/// Fetch Ticket Chat Display
static Future<TicketChatDisplayResponse?> fetchTicketChatDisplayApi(
String sessionId,
String empId,
String ticId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"tic_id": ticId,
};
final res = await post(data, ticketChatDisplayUrl, {});
if (res != null) {
return TicketChatDisplayResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchTicketChatDisplay): $e");
return null;
}
}
/// Fetch Tag Order
static Future<CommonResponse?> fetchTagOrderApi(
String sessionId,
String empId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
};
final res = await post(data, tagOrderUrl, {});
if (res != null) {
return CommonResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetchTagOrder): $e");
return null;
}
}
/// Fetch Raise Ticket
static Future<CommonResponse?> fetchRaiseTicketApi(
String sessionId,
String empId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
};
final res = await post(data, raiseTicketUrl, {});
if (res != null) {
return CommonResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (raise Ticket): $e");
return null;
}
}
/// Fetch CheckInOut Submit
static Future<CommonResponse?> fetchCheckInOutSubmitApi(
String sessionId,
String empId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
};
final res = await post(data, checkInOutSubmitUrl, {});
if (res != null) {
return CommonResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (CheckInOutSubmit): $e");
return null;
}
}
/// Fetch Balance
static Future<CommonResponse?> fetchBalanceApi(
String sessionId,
String empId,
String accId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"acc_id": accId,
};
final res = await post(data, balanceUrl, {});
if (res != null) {
return CommonResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetch Balance): $e");
return null;
}
}
/// Add Payment
static Future<CommonResponse?> fetchAddPaymentApi(
String sessionId,
String empId,
String amount,
String orderId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"amount": amount,
"order_id": orderId,
};
final res = await post(data, addPaymentUrl, {});
if (res != null) {
return CommonResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (AddPaymentApi): $e");
return null;
}
}
/// Add Fcm Token
static Future<CommonResponse?> fetchAddFcmTokenApi(
String sessionId,
String empId,
String amount,
String orderId,
) async {
try {
Map<String, String> data = {
"session_id": sessionId,
"emp_id": empId,
"amount": amount,
"order_id": orderId,
};
final res = await post(data, addFcmTokenUrl, {});
if (res != null) {
return CommonResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint("❌ API Error (fetch Add Payment Api): $e");
return null;
}
}
}
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
Future<http.Response?> post(
Map<String, dynamic> Body,
apiUrl,
Map<String, String> Headers,
) async {
http.Response? response;
try {
response = await http.post(Uri.parse(apiUrl), headers: Headers, body: Body);
return response;
} on Exception catch (e, s) {
print(e);
print(s);
}
return response;
}
Future<http.Response?> get(apiUrl, Map<String, String> Headers) async {
http.Response? response;
try {
response = await http.get(Uri.parse(apiUrl), headers: Headers);
return response;
} on Exception catch (e, s) {
print(e);
print(s);
}
return response;
}
Future<String?> postImage(
Map<String, String> body,
String urlLink,
Map<String, String> headers,
File image,
) async {
try {
var req = http.MultipartRequest('POST', Uri.parse(urlLink));
req.headers.addAll(headers);
req.files.add(
await http.MultipartFile.fromPath('check_in_pic', image.path),
);
req.fields.addAll(body);
var res = await req.send();
final resBody = await res.stream.bytesToString();
if (res.statusCode >= 200 && res.statusCode < 300) {
print("**** $resBody .... $res");
return resBody;
} else {
print("error: ${res.reasonPhrase}");
return null;
}
} catch (e) {
debugPrint(e.toString());
return null;
}
}
Future<String?> postImage2(
Map<String, String> body,
Map<String, String> headers,
String urlLink,
File image,
) async {
try {
var req = http.MultipartRequest('POST', Uri.parse(urlLink));
req.headers.addAll(headers);
req.files.add(
await http.MultipartFile.fromPath('check_out_pic', image.path),
);
req.fields.addAll(body);
var res = await req.send();
final resBody = await res.stream.bytesToString();
if (res.statusCode >= 200 && res.statusCode < 300) {
print("**** $resBody .... $res");
return resBody;
} else {
print("error: ${res.reasonPhrase}");
return null;
}
} catch (e) {
debugPrint(e.toString());
return null;
}
}
Future<String?> postImage3(
Map<String, String> body,
Map<String, String> headers,
String urlLink,
File image,
) async {
try {
var req = http.MultipartRequest('POST', Uri.parse(urlLink));
req.headers.addAll(headers);
req.files.add(
await http.MultipartFile.fromPath('payment_proof', image.path),
);
req.fields.addAll(body);
var res = await req.send();
final resBody = await res.stream.bytesToString();
if (res.statusCode >= 200 && res.statusCode < 300) {
print("**** $resBody .... $res");
return resBody;
} else {
print("error: ${res.reasonPhrase}");
return null;
}
} catch (e) {
debugPrint(e.toString());
return null;
}
}
Future<String?> postImage4(
Map<String, String> body,
Map<String, String> headers,
String urlLink,
File image,
) async {
try {
var req = http.MultipartRequest('POST', Uri.parse(urlLink));
req.headers.addAll(headers);
req.files.add(await http.MultipartFile.fromPath('fsr_file', image.path));
req.fields.addAll(body);
var res = await req.send();
final resBody = await res.stream.bytesToString();
if (res.statusCode >= 200 && res.statusCode < 300) {
print("**** $resBody .... ${res.statusCode}");
return resBody;
} else {
print("error: ${res.reasonPhrase}");
return null;
}
} catch (e) {
debugPrint(e.toString());
return null;
}
}
Future<String?> postImageNew(
Map<String, String> body,
Map<String, String> headers,
String urlLink,
File image,
reqField,
) async {
try {
var req = http.MultipartRequest('POST', Uri.parse(urlLink));
req.headers.addAll(headers ?? {});
req.files.add(await http.MultipartFile.fromPath(reqField, image.path));
req.fields.addAll(body ?? {});
var res = await req.send();
final resBody = await res.stream.bytesToString();
if (res.statusCode >= 200 && res.statusCode < 300) {
print("**** $resBody .... ${res.statusCode}");
return resBody;
} else {
print("error: ${res.reasonPhrase}");
return null;
}
} catch (e) {
debugPrint(e.toString());
return null;
}
}
//travel_image
//hotel_image
//other_image
Future<String?> PostMultipleImagesNew(
Map<String, String> body,
String urlLink,
Map<String, String> headers,
List<http.MultipartFile> newList,
List<http.MultipartFile> newList1,
List<http.MultipartFile> newList2,
) async {
try {
var req = http.MultipartRequest('POST', Uri.parse(urlLink));
req.headers.addAll(headers);
req.files.addAll(newList);
req.files.addAll(newList1);
req.files.addAll(newList2);
req.fields.addAll(body);
var res = await req.send();
final resBody = await res.stream.bytesToString();
if (res.statusCode >= 200 && res.statusCode < 300) {
print("**** $resBody .... $res");
return resBody;
} else {
print("error: ${res.reasonPhrase}");
return null;
}
} catch (e) {
debugPrint(e.toString());
return null;
}
}
Future<String?> PostMultipleImagesNew2(
Map<String, String> body,
String urlLink,
Map<String, String> headers,
List<http.MultipartFile> newList,
List<http.MultipartFile> newList1,
) async {
try {
var req = http.MultipartRequest('POST', Uri.parse(urlLink));
req.headers.addAll(headers);
req.files.addAll(newList);
req.files.addAll(newList1);
req.fields.addAll(body);
var res = await req.send();
final resBody = await res.stream.bytesToString();
if (res.statusCode >= 200 && res.statusCode < 300) {
print("**** $resBody .... $res");
return resBody;
} else {
print("error: ${res.reasonPhrase}");
return null;
}
} catch (e) {
debugPrint(e.toString());
return null;
}
}
Future<String?> PostMultipleImages(
Map<String, String> body,
String urlLink,
Map<String, String> headers,
List<http.MultipartFile> newList,
) async {
try {
var req = http.MultipartRequest('POST', Uri.parse(urlLink));
req.headers.addAll(headers);
req.files.addAll(newList);
req.fields.addAll(body);
var res = await req.send();
final resBody = await res.stream.bytesToString();
if (res.statusCode >= 200 && res.statusCode < 300) {
print("**** $resBody .... $res");
return resBody;
} else {
print("error: ${res.reasonPhrase}");
return null;
}
} catch (e) {
debugPrint(e.toString());
return null;
}
}
// utils/animated_snackbar.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class AnimatedSnackBar {
static void show({
required BuildContext context,
required String message,
String? title,
IconData? icon,
Color backgroundColor = const Color(0xFF324563),
Duration duration = const Duration(seconds: 4),
SnackBarAction? action,
bool showProgressBar = false,
bool enableHaptic = true,
Curve animationCurve = Curves.elasticOut,
}) {
if (enableHaptic) {
HapticFeedback.lightImpact();
}
final overlay = Overlay.of(context);
// Create a variable to hold the overlay entry
late OverlayEntry overlayEntry;
overlayEntry = OverlayEntry(
builder: (context) => Positioned(
top: MediaQuery.of(context).viewPadding.top + 10,
left: 16,
right: 16,
child: Material(
color: Colors.transparent,
child: _AnimatedSnackBarContent(
message: message,
title: title,
icon: icon,
backgroundColor: backgroundColor,
duration: duration,
action: action,
showProgressBar: showProgressBar,
animationCurve: animationCurve,
onClose: () {
if (overlayEntry.mounted) {
overlayEntry.remove();
}
},
),
),
),
);
overlay.insert(overlayEntry);
// Auto remove after duration
Future.delayed(duration, () {
if (overlayEntry.mounted) {
overlayEntry.remove();
}
});
}
// Quick methods for different types
static void success({
required BuildContext context,
required String message,
String title = "Success",
Color backgroundColor = const Color(0xFF059669),
SnackBarAction? action,
bool enableHaptic = true,
}) {
show(
context: context,
message: message,
title: title,
icon: Icons.check_circle_rounded,
backgroundColor: backgroundColor,
action: action,
enableHaptic: enableHaptic,
);
}
static void error({
required BuildContext context,
required String message,
String title = "Error",
Color backgroundColor = const Color(0xFFDC2626),
SnackBarAction? action,
bool enableHaptic = true,
}) {
show(
context: context,
message: message,
title: title,
icon: Icons.error_outline_rounded,
backgroundColor: backgroundColor,
action: action,
enableHaptic: enableHaptic,
);
}
static void warning({
required BuildContext context,
required String message,
String title = "Warning",
Color backgroundColor = const Color(0xFFD97706),
SnackBarAction? action,
bool enableHaptic = true,
}) {
show(
context: context,
message: message,
title: title,
icon: Icons.warning_amber_rounded,
backgroundColor: backgroundColor,
action: action,
enableHaptic: enableHaptic,
);
}
static void info({
required BuildContext context,
required String message,
String title = "Info",
Color backgroundColor = const Color(0xFF2563EB),
SnackBarAction? action,
bool enableHaptic = true,
}) {
show(
context: context,
message: message,
title: title,
icon: Icons.info_outline_rounded,
backgroundColor: backgroundColor,
action: action,
enableHaptic: enableHaptic,
);
}
}
class _AnimatedSnackBarContent extends StatefulWidget {
final String message;
final String? title;
final IconData? icon;
final Color backgroundColor;
final Duration duration;
final SnackBarAction? action;
final bool showProgressBar;
final Curve animationCurve;
final VoidCallback onClose;
const _AnimatedSnackBarContent({
required this.message,
required this.title,
required this.icon,
required this.backgroundColor,
required this.duration,
required this.action,
required this.showProgressBar,
required this.animationCurve,
required this.onClose,
});
@override
_AnimatedSnackBarContentState createState() => _AnimatedSnackBarContentState();
}
class _AnimatedSnackBarContentState extends State<_AnimatedSnackBarContent>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Offset> _slideAnimation;
late Animation<double> _scaleAnimation;
late Animation<double> _fadeAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 800),
vsync: this,
);
_slideAnimation = Tween<Offset>(
begin: const Offset(0, -2),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _controller,
curve: widget.animationCurve,
));
_scaleAnimation = Tween<double>(
begin: 0.5,
end: 1.0,
).animate(CurvedAnimation(
parent: _controller,
curve: widget.animationCurve,
));
_fadeAnimation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _close() {
_controller.reverse().then((_) {
widget.onClose();
});
}
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _fadeAnimation,
child: SlideTransition(
position: _slideAnimation,
child: ScaleTransition(
scale: _scaleAnimation,
child: Container(
padding: const EdgeInsets.all(18),
decoration: BoxDecoration(
color: widget.backgroundColor,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: widget.backgroundColor.withOpacity(0.4),
blurRadius: 25,
offset: const Offset(0, 10),
spreadRadius: 2,
),
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 8,
offset: const Offset(0, 4),
),
],
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
widget.backgroundColor,
Color.alphaBlend(Colors.white.withOpacity(0.15), widget.backgroundColor),
],
),
border: Border.all(
color: Colors.white.withOpacity(0.2),
width: 1,
),
),
child: Row(
children: [
// Animated Icon Container
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.15),
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: widget.backgroundColor.withOpacity(0.5),
blurRadius: 8,
spreadRadius: 1,
),
],
),
child: Icon(
widget.icon ?? Icons.notifications_none_rounded,
color: Colors.white,
size: 22,
),
),
const SizedBox(width: 16),
// Content Section
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (widget.title != null) ...[
Text(
widget.title!,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontSize: 16,
letterSpacing: -0.3,
height: 1.2,
),
),
const SizedBox(height: 4),
],
Text(
widget.message,
style: TextStyle(
color: Colors.white.withOpacity(0.9),
fontSize: 14,
height: 1.4,
fontWeight: FontWeight.w400,
),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
// Action Button
if (widget.action != null) ...[
const SizedBox(height: 8),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: Colors.white.withOpacity(0.3),
),
),
child: TextButton(
onPressed: () {
widget.action!.onPressed();
_close();
},
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 4,
),
minimumSize: Size.zero,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: Text(
widget.action!.label,
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
),
),
],
],
),
),
const SizedBox(width: 12),
// Close Button
GestureDetector(
onTap: _close,
child: Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
shape: BoxShape.circle,
),
child: Icon(
Icons.close_rounded,
color: Colors.white.withOpacity(0.7),
size: 18,
),
),
),
],
),
),
),
),
);
}
}
\ No newline at end of file
// utils/app_colors.dart
import 'dart:ui';
class AppColors {
// Primary colors from genrentals.in
static const Color primary = Color(0xFF2563EB);
static const Color secondary = Color(0xFF10B981);
static const Color accent = Color(0xFFF59E0B);
// Status colors
static const Color success = Color(0xFF10B981);
static const Color warning = Color(0xFFF59E0B);
static const Color error = Color(0xFFEF4444);
static const Color info = Color(0xFF3B82F6);
// Neutral colors
static const Color dark = Color(0xFF1F2937);
static const Color light = Color(0xFFF9FAFB);
static const Color gray = Color(0xFF6B7280);
// Background colors
static const Color backgroundLight = Color(0xFFFFFFFF);
static const Color backgroundDark = Color(0xFF111827);
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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