Code committed
This commit is contained in:
@@ -1,59 +1,68 @@
|
||||
plugins {
|
||||
id "com.android.application"
|
||||
id "kotlin-android"
|
||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
}
|
||||
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file("local.properties")
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader("UTF-8") { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
// Load key.properties for signing release builds
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = "1"
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = "1.0"
|
||||
}
|
||||
// Flutter versioning
|
||||
def flutterVersionCode = 12
|
||||
def flutterVersionName = "1.0.4"
|
||||
|
||||
android {
|
||||
namespace = "com.frontshop.userapp"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = flutter.ndkVersion
|
||||
compileSdk = 35
|
||||
ndkVersion = "26.1.10909125" // Optional; only if you use native code
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
defaultConfig {
|
||||
applicationId = "com.frontshop.userapp"
|
||||
minSdk = 23
|
||||
targetSdk = 35
|
||||
versionCode = flutterVersionCode
|
||||
versionName = flutterVersionName
|
||||
}
|
||||
|
||||
defaultConfig
|
||||
{
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId = "com.frontshop.userapp"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||
minSdk = flutter.minSdkVersion
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = flutterVersionCode.toInteger()
|
||||
versionName = flutterVersionName
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file(keystoreProperties['storeFile'])
|
||||
storePassword keystoreProperties['storePassword']
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig = signingConfigs.debug
|
||||
signingConfig = signingConfigs.release
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
coreLibraryDesugaringEnabled true
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
||||
|
||||
// ✅ PhonePe SDK - ensure this matches your maven URL from root `build.gradle`
|
||||
|
||||
}
|
||||
|
||||
@@ -2,24 +2,21 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.frontshop.userapp">
|
||||
|
||||
<!-- Permissions -->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.CALL_PHONE"/>
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
|
||||
<application
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
@@ -27,9 +24,12 @@
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
|
||||
<!-- Firebase notification channel -->
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
||||
android:value="high_importance_channel"/>
|
||||
|
||||
<!-- Main activity -->
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
@@ -39,33 +39,41 @@
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
|
||||
<!-- Flutter splash theme -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
android:resource="@style/NormalTheme"/>
|
||||
|
||||
<!-- PhonePe / Deeplink support -->
|
||||
|
||||
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data
|
||||
android:scheme="frontshop"
|
||||
android:host="payment-response"
|
||||
android:pathPrefix="/" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
<!-- Main launcher -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Razorpay Tokenizer -->
|
||||
<activity
|
||||
android:name="com.razorpay.RzpTokeniserSdkFlutter.TokeniserSdkActivity"
|
||||
android:theme="@style/Theme.AppCompat.NoActionBar"
|
||||
android:exported="false" />
|
||||
|
||||
|
||||
<meta-data android:name="com.google.android.geo.API_KEY"
|
||||
android:value="AIzaSyAi3_Dls63iGs7Nccgdm-4FkS0rhT03-4U"/>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<!-- Firebase Messaging -->
|
||||
<service
|
||||
android:name="io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingService"
|
||||
android:exported="true"
|
||||
@@ -74,32 +82,31 @@
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
<!-- Required to query activities that can process text, see:
|
||||
https://developer.android.com/training/package-visibility and
|
||||
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||
|
||||
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||
<!-- Firebase Maps API Key -->
|
||||
<meta-data android:name="com.google.android.geo.API_KEY"
|
||||
android:value="AIzaSyAi3_Dls63iGs7Nccgdm-4FkS0rhT03-4U"/>
|
||||
|
||||
<!-- Flutter embedding -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
|
||||
<!-- Queries for package visibility -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||
<data android:mimeType="text/plain"/>
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<!-- Provide required visibility configuration for API level 30 and above -->
|
||||
<queries>
|
||||
<!-- If your app checks for SMS support -->
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="sms" />
|
||||
</intent>
|
||||
<!-- If your app checks for call support -->
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="tel" />
|
||||
</intent>
|
||||
<!-- If your application checks for inAppBrowserView launch mode support -->
|
||||
<intent>
|
||||
<action android:name="android.support.customtabs.action.CustomTabsService" />
|
||||
</intent>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
package com.frontshop.userapp
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
class MainActivity: FlutterActivity()
|
||||
import io.flutter.embedding.android.FlutterFragmentActivity
|
||||
class MainActivity : FlutterFragmentActivity()
|
||||
@@ -2,14 +2,18 @@ allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
|
||||
// ✅ Required for PhonePe SDK
|
||||
maven {
|
||||
url "https://phonepe.mycloudrepo.io/public/repositories/phonepe-intentsdk-android"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = "../build"
|
||||
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(":app")
|
||||
}
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ pluginManagement {
|
||||
|
||||
plugins {
|
||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||
id "com.android.application" version "7.3.0" apply false
|
||||
id "com.android.application" version "8.6.0" apply false
|
||||
id "org.jetbrains.kotlin.android" version "1.9.10" apply false
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '12.0'
|
||||
# platform :ios, '13.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
@@ -45,5 +45,21 @@
|
||||
<true/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>tez</string>
|
||||
<string>phonepe</string>
|
||||
<string>paytmmp</string>
|
||||
<string>bhim</string>
|
||||
</array>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>frontshop</string> <!-- 👈 must match `appSchema` -->
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
class APIURL {
|
||||
static const BASE_URL = "http://210.89.44.183:3333/xam/";
|
||||
static const BASE_URL = "https://www.mv.frontshopemporium.in/xam/";
|
||||
static const String sendOtp = "${BASE_URL}auth/send-otp/customer";
|
||||
static const String verifyOtp = "${BASE_URL}auth/verify-otp/customer";
|
||||
static const String loginOtp = "${BASE_URL}auth/login/customer";
|
||||
static const String login = "${BASE_URL}auth/login/vendor";
|
||||
static const String customerRegister = "${BASE_URL}auth/register/customer";
|
||||
static const String getAllProduct = "${BASE_URL}products";
|
||||
static const String getAllProduct = "${BASE_URL}products?order=home";
|
||||
static const String getProductDetails = "${BASE_URL}products/";
|
||||
static const String getBanners = "${BASE_URL}banners";
|
||||
static const String customerLogOut = "${BASE_URL}auth/logout/customer";
|
||||
@@ -39,6 +39,8 @@ class APIURL {
|
||||
static const String getProduct = "${BASE_URL}products";
|
||||
static const String getCategoryByLevel = "${BASE_URL}categories/by-level/1";
|
||||
static const String getMe = "${BASE_URL}auth/me";
|
||||
static const String distanctByProduct = "${BASE_URL}distance/delivery-charges-by-distance";
|
||||
|
||||
|
||||
static const String createProduct = "${BASE_URL}products";
|
||||
|
||||
@@ -50,6 +52,7 @@ class APIURL {
|
||||
static const String updateStatus = "${BASE_URL}orders/items/";
|
||||
static const String checkAddress = "${BASE_URL}distance/by-address/";
|
||||
|
||||
|
||||
static const String productReview = "${BASE_URL}products/";
|
||||
|
||||
static const String upDateDeviceToken = "${BASE_URL}devices/register";
|
||||
|
||||
@@ -377,7 +377,7 @@ class AddtocartProvider extends ChangeNotifier {
|
||||
|
||||
////////////////////////////COD ////////////
|
||||
|
||||
Future<void> paymentCODOrder(
|
||||
Future<bool> paymentCODOrder(
|
||||
BuildContext context,
|
||||
double subtotal,
|
||||
int deliverCharge,
|
||||
@@ -386,30 +386,20 @@ class AddtocartProvider extends ChangeNotifier {
|
||||
) async {
|
||||
ispaymentLoader = true;
|
||||
notifyListeners();
|
||||
var data;
|
||||
if (couponId.isNotEmpty) {
|
||||
data = {
|
||||
"addressId": addressId,
|
||||
"paymentMethod": "COD",
|
||||
"paymentStatus": "PENDING",
|
||||
"orderStatus": "PENDING",
|
||||
"subtotal": subtotal,
|
||||
"deliveryCharge": deliverCharge,
|
||||
"transactionId": "phonepe_transaction_123",
|
||||
"couponId": couponId
|
||||
};
|
||||
} else {
|
||||
data = {
|
||||
"addressId": addressId,
|
||||
"paymentMethod": "COD",
|
||||
"paymentStatus": "PENDING",
|
||||
"orderStatus": "PENDING",
|
||||
"subtotal": subtotal,
|
||||
"deliveryCharge": deliverCharge,
|
||||
};
|
||||
}
|
||||
|
||||
print("kjfhxgkljfhg ${data}");
|
||||
var data = {
|
||||
"addressId": addressId,
|
||||
"paymentMethod": "COD",
|
||||
"paymentStatus": "PENDING",
|
||||
"orderStatus": "PENDING",
|
||||
"subtotal": subtotal,
|
||||
"deliveryCharge": deliverCharge,
|
||||
};
|
||||
|
||||
if (couponId.isNotEmpty) {
|
||||
data["couponId"] = couponId;
|
||||
data["transactionId"] = "phonepe_transaction_123";
|
||||
}
|
||||
|
||||
try {
|
||||
var result = await _homeRepo.paymentCODOrder(data);
|
||||
@@ -420,32 +410,33 @@ class AddtocartProvider extends ChangeNotifier {
|
||||
msg: "${error.message}",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white,
|
||||
fontSize: 14.0,
|
||||
);
|
||||
ispaymentLoader = false;
|
||||
notifyListeners();
|
||||
return false;
|
||||
},
|
||||
(response) {
|
||||
context.clearAndPush(routePath: MyRoutes.SUCCESSPAYMENT);
|
||||
|
||||
ispaymentLoader = false;
|
||||
notifyListeners();
|
||||
return true;
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
ispaymentLoader = false;
|
||||
notifyListeners();
|
||||
|
||||
Fluttertoast.showToast(
|
||||
msg: "${e}",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white,
|
||||
fontSize: 14.0,
|
||||
);
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:grocery_app/src/common_widget/name_text_field.dart';
|
||||
import 'package:grocery_app/src/common_widget/network_image.dart';
|
||||
import 'package:grocery_app/src/logic/provider/addTocart_provider.dart';
|
||||
import 'package:grocery_app/src/ui/payment/phonepe_payment.dart';
|
||||
import 'package:grocery_app/utils/constants/assets_constant.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../payment/razorpay_payment.dart';
|
||||
|
||||
class CardCheckoutScreen extends StatefulWidget {
|
||||
int deliveryCharge;
|
||||
// String currency;
|
||||
@@ -15,7 +19,7 @@ class CardCheckoutScreen extends StatefulWidget {
|
||||
// String name;
|
||||
// String phone;
|
||||
// String email;
|
||||
// String userId;
|
||||
String userId;
|
||||
String cartId;
|
||||
String addressId;
|
||||
// String remarks;
|
||||
@@ -30,7 +34,7 @@ class CardCheckoutScreen extends StatefulWidget {
|
||||
// required this.name,
|
||||
// required this.phone,
|
||||
// required this.email,
|
||||
// required this.userId,
|
||||
required this.userId,
|
||||
required this.cartId,
|
||||
required this.addressId,
|
||||
// required this.remarks,
|
||||
@@ -84,7 +88,7 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
|
||||
),
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
/* onTap: () {
|
||||
if (paymentProvider.selectedPaymentMethod == "Online") {
|
||||
print("dsjfkhkdfhgdkfghdfg");
|
||||
paymentProvider.orderPaymnet(
|
||||
@@ -93,7 +97,8 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
|
||||
widget.cartId,
|
||||
widget.addressId,
|
||||
widget.couponId!);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
paymentProvider.paymentCODOrder(
|
||||
context,
|
||||
widget.originalAmount,
|
||||
@@ -102,6 +107,68 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
|
||||
widget.addressId,
|
||||
);
|
||||
}
|
||||
},*/
|
||||
onTap: (){
|
||||
if(paymentProvider.selectedPaymentMethod!=null) {
|
||||
if (paymentProvider.selectedPaymentMethod ==
|
||||
"razorpay") {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
RazorpayPaymentScreen(
|
||||
amount: widget.originalAmount +
|
||||
widget.deliveryCharge,
|
||||
cartId: widget.cartId,
|
||||
addressId: widget.addressId,
|
||||
couponId: widget.couponId,
|
||||
userId: widget.userId,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (paymentProvider.selectedPaymentMethod ==
|
||||
"phonepe") {
|
||||
// Navigate to PhonePe screen (optional for now)
|
||||
// Replace this when you implement PhonePe
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
PhonePePaymentScreen(
|
||||
amount: widget.originalAmount +
|
||||
widget.deliveryCharge,
|
||||
cartId: widget.cartId,
|
||||
addressId: widget.addressId,
|
||||
//couponId: widget.couponId,
|
||||
userId: widget.userId,
|
||||
),
|
||||
),
|
||||
);
|
||||
/* ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text("PhonePe integration coming soon")),
|
||||
);*/
|
||||
} /*
|
||||
else {
|
||||
paymentProvider.paymentCODOrder(
|
||||
context,
|
||||
widget.originalAmount,
|
||||
widget.deliveryCharge,
|
||||
widget.couponId ?? "",
|
||||
widget.addressId,
|
||||
);
|
||||
}*/
|
||||
}else
|
||||
{
|
||||
Fluttertoast.showToast(
|
||||
msg: "Select Payment method",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
textColor: Colors.white,
|
||||
fontSize: 14.0,
|
||||
);
|
||||
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
@@ -173,16 +240,34 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
|
||||
),
|
||||
SizedBox(height: 0),
|
||||
|
||||
ListTile(
|
||||
/* ListTile(
|
||||
leading: Icon(Icons.payment, color: Colors.blue),
|
||||
title: Text("Online Payment"),
|
||||
trailing: paymentProvider.selectedPaymentMethod == "Online"
|
||||
? Icon(Icons.check_circle, color: Colors.green)
|
||||
: null,
|
||||
onTap: () {
|
||||
paymentProvider.selectPaymentMethod("Online");
|
||||
// paymentProvider.selectPaymentMethod("Online");
|
||||
// Navigator.pop(context);
|
||||
},
|
||||
),*/
|
||||
|
||||
RadioListTile<String>(
|
||||
value: "razorpay",
|
||||
groupValue: paymentProvider.selectedPaymentMethod,
|
||||
title: const Text("Razorpay Online Payment"),
|
||||
onChanged: (value) {
|
||||
paymentProvider.selectPaymentMethod(value!);
|
||||
},
|
||||
),
|
||||
|
||||
RadioListTile<String>(
|
||||
value: "phonepe",
|
||||
groupValue: paymentProvider.selectedPaymentMethod,
|
||||
title: const Text("PhonePe Online Payment"),
|
||||
onChanged: (value) {
|
||||
paymentProvider.selectPaymentMethod(value!);
|
||||
},
|
||||
),
|
||||
|
||||
// Cash on Delivery (COD) Option
|
||||
@@ -404,3 +489,4 @@ class _CardCheckoutScreenState extends State<CardCheckoutScreen> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:carousel_slider/carousel_slider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
@@ -15,6 +17,7 @@ import 'package:grocery_app/src/ui/widgets/elevated_button.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/constants/shared_pref_utils.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:skeletonizer/skeletonizer.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
@@ -1006,6 +1009,8 @@ class _MycartState extends State<Mycart> {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _showAddressBottomSheet(BuildContext context) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
@@ -1140,6 +1145,67 @@ class AddressBottomSheet extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _AddressBottomSheetState extends State<AddressBottomSheet> {
|
||||
Future<String?> fetchDeliveryMessage() async {
|
||||
const String url = 'https://www.mv.frontshopemporium.in/xam/distance/delivery-charges-by-distance';
|
||||
|
||||
try {
|
||||
final response = await http.get(Uri.parse(url), headers: {
|
||||
"Content-Type": "application/json",
|
||||
"authorization": "Bearer ${await SharedPrefUtils.getToken()}"
|
||||
});
|
||||
|
||||
print('continue response');
|
||||
print(response.statusCode);
|
||||
print(response.body);
|
||||
if (response.statusCode == 200) {
|
||||
|
||||
final Map<String, dynamic> data = json.decode(response.body);
|
||||
print(data);
|
||||
final List<dynamic> nonDeliverableProducts = data['nonDeliverableProducts'] ?? [];
|
||||
if (nonDeliverableProducts.isNotEmpty) {
|
||||
final String reason = nonDeliverableProducts[0]['reason'];
|
||||
print(reason);
|
||||
return reason;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
return 'Failed with status: ${response.statusCode}';
|
||||
}
|
||||
} catch (e) {
|
||||
return 'Error: $e';
|
||||
}
|
||||
}
|
||||
Future<String?> setDefaultAddress(String addressId) async {
|
||||
String url = 'https://www.mv.frontshopemporium.in/xam/user/addresses/${addressId}/set-default';
|
||||
|
||||
try {
|
||||
final response = await http.put(Uri.parse(url), headers: {
|
||||
"Content-Type": "application/json",
|
||||
"authorization": "Bearer ${await SharedPrefUtils.getToken()}"
|
||||
});
|
||||
|
||||
print('address response');
|
||||
print(response.statusCode);
|
||||
print(response.body);
|
||||
if (response.statusCode == 200) {
|
||||
|
||||
/* final Map<String, dynamic> data = json.decode(response.body);
|
||||
print(data);
|
||||
final List<dynamic> nonDeliverableProducts = data['nonDeliverableProducts'] ?? [];
|
||||
if (nonDeliverableProducts.isNotEmpty) {
|
||||
final String reason = nonDeliverableProducts[0]['reason'];
|
||||
return reason;
|
||||
} else {
|
||||
return 'No non-deliverable products found';
|
||||
}*/
|
||||
} else {
|
||||
return 'Failed with status: ${response.statusCode}';
|
||||
}
|
||||
} catch (e) {
|
||||
return 'Error: $e';
|
||||
}
|
||||
}
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
@@ -1186,8 +1252,8 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
|
||||
Consumer<AddtocartProvider>(
|
||||
builder: (context, paymentProvider, child) {
|
||||
return ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
if (paymentProvider.selectedAddress.isNotEmpty) {
|
||||
onPressed: () async{
|
||||
/* if (paymentProvider.selectedAddress.isNotEmpty) {
|
||||
if (paymentProvider.isDeliverable) {
|
||||
Navigator.pop(context);
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
@@ -1200,7 +1266,7 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
|
||||
// name: paymentProvider.selecteUserName,
|
||||
// phone: paymentProvider.selecteUserPhone,
|
||||
// email: paymentProvider.selecteEmail,
|
||||
// userId: paymentProvider.allitem.userId!,
|
||||
userId: paymentProvider.allitem.userId!,
|
||||
cartId: paymentProvider.allitem.id!,
|
||||
addressId: paymentProvider.selectedAddress,
|
||||
// remarks: paymentProvider.selecteUserName,
|
||||
@@ -1229,17 +1295,97 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
|
||||
textColor: Colors.white,
|
||||
fontSize: 14.0,
|
||||
);
|
||||
}
|
||||
}*/
|
||||
|
||||
// Call your API and get the message
|
||||
String? message = await fetchDeliveryMessage(); // Use the function from earlier
|
||||
|
||||
if (message != null && message.isNotEmpty) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text("Alert"),
|
||||
content: Text(message),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(); // Close the dialog
|
||||
},
|
||||
child: Text("OK"),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
Navigator.pop(context);
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CardCheckoutScreen(
|
||||
deliveryCharge: paymentProvider.getdeliverycharge,
|
||||
originalAmount: paymentProvider.grandPrice,
|
||||
userId: paymentProvider.allitem.userId!,
|
||||
cartId: paymentProvider.allitem.id!,
|
||||
addressId: paymentProvider.selectedAddress,
|
||||
couponId: paymentProvider.couponId,
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
/*
|
||||
|
||||
// Call your API and get the message
|
||||
await paymentProvider.paymentCODOrder(
|
||||
context,
|
||||
paymentProvider.grandPrice,
|
||||
paymentProvider.getdeliverycharge,
|
||||
paymentProvider.couponId ?? "",
|
||||
paymentProvider.selectedAddress,
|
||||
);
|
||||
|
||||
*/
|
||||
/* if (message != null && message.isNotEmpty) {
|
||||
Fluttertoast.showToast(
|
||||
msg: message,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white,
|
||||
fontSize: 14.0,
|
||||
);
|
||||
} else {*/
|
||||
/*
|
||||
Navigator.pop(context);
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CardCheckoutScreen(
|
||||
deliveryCharge: paymentProvider.getdeliverycharge,
|
||||
originalAmount: paymentProvider.grandPrice,
|
||||
userId: paymentProvider.allitem.userId!,
|
||||
cartId: paymentProvider.allitem.id!,
|
||||
addressId: paymentProvider.selectedAddress,
|
||||
couponId: paymentProvider.couponId,
|
||||
);
|
||||
},
|
||||
));
|
||||
// }
|
||||
|
||||
|
||||
},*/
|
||||
label: Text(
|
||||
"Continue",
|
||||
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: paymentProvider.isDeliverable
|
||||
backgroundColor:Colors.green,
|
||||
/*backgroundColor: paymentProvider.isDeliverable
|
||||
? Colors.green
|
||||
: Colors.grey,
|
||||
minimumSize: Size(double.infinity, 50),
|
||||
*/minimumSize: Size(double.infinity, 50),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
@@ -1278,12 +1424,13 @@ class _AddressBottomSheetState extends State<AddressBottomSheet> {
|
||||
activeColor: Colors.green,
|
||||
onChanged: (value) {
|
||||
addressProvider.checkAddress(context, value);
|
||||
|
||||
setDefaultAddress(address.id);
|
||||
addressProvider.selectAddress(
|
||||
value.toString(),
|
||||
address.phoneNumber,
|
||||
address.name,
|
||||
address.user!.email);
|
||||
|
||||
},
|
||||
),
|
||||
title: Text(
|
||||
|
||||
@@ -59,7 +59,7 @@ class _MyOrderScreenState extends State<MyOrderScreen> {
|
||||
width: 20,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
context.clearAndPush(routePath: MyRoutes.BOTTOMNAV);
|
||||
context.clearAndPush(routePath: MyRoutes.HOME);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
APPASSETS.back,
|
||||
|
||||
271
lib/src/ui/payment/phonepe_payment.dart
Normal file
271
lib/src/ui/payment/phonepe_payment.dart
Normal file
@@ -0,0 +1,271 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:phonepe_payment_sdk/phonepe_payment_sdk.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'dart:convert';
|
||||
import 'dart:async';
|
||||
import 'package:app_links/app_links.dart';
|
||||
import '../../../utils/constants/shared_pref_utils.dart';
|
||||
import '../../core/routes/routes.dart';
|
||||
import '../myOrder/my_order.dart';
|
||||
class PhonePePaymentScreen extends StatefulWidget {
|
||||
final double amount;
|
||||
final String cartId;
|
||||
final String addressId;
|
||||
final String userId;
|
||||
|
||||
const PhonePePaymentScreen({
|
||||
required this.amount,
|
||||
required this.cartId,
|
||||
required this.addressId,
|
||||
required this.userId,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<PhonePePaymentScreen> createState() => _PhonePePaymentScreenState();
|
||||
}
|
||||
|
||||
class _PhonePePaymentScreenState extends State<PhonePePaymentScreen> {
|
||||
String _statusMessage = "Initiating payment...";
|
||||
bool _isLoading = true;
|
||||
|
||||
final AppLinks _appLinks = AppLinks();
|
||||
StreamSubscription<Uri>? _linkSub;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_listenForRedirect();
|
||||
_initiateAndStartPayment();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_linkSub?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _listenForRedirect() {
|
||||
print("Listening for redirect...");
|
||||
_linkSub = _appLinks.uriLinkStream.listen((Uri uri) {
|
||||
print("Deep link received: $uri");
|
||||
final transactionId = uri.queryParameters['transactionId'];
|
||||
final status = uri.queryParameters['status'];
|
||||
|
||||
if (transactionId != null && status == "SUCCESS") {
|
||||
//_verifyPayment(transactionId);
|
||||
} else if (status == "CANCEL") {
|
||||
setState(() {
|
||||
_statusMessage = "Payment cancelled by user.";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false); // 👈 Return failure
|
||||
} else {
|
||||
setState(() {
|
||||
_statusMessage = "Payment failed or unknown status.";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false); // 👈 Return failure
|
||||
}
|
||||
}, onError: (err) {
|
||||
print("Deep link error: $err");
|
||||
setState(() {
|
||||
_statusMessage = "Error handling redirect: $err";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false); // 👈 Return failure
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _initiateAndStartPayment() async {
|
||||
try {
|
||||
final uri = Uri.parse("https://www.mv.frontshopemporium.in/xam/payment/phonepe/sdk/initiate");
|
||||
|
||||
print("Calling backend initiate API...");
|
||||
final response = await http.post(
|
||||
uri,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"authorization": "Bearer ${await SharedPrefUtils.getToken()}",
|
||||
},
|
||||
body: jsonEncode({
|
||||
"amount": widget.amount,
|
||||
"cartId": widget.cartId,
|
||||
"addressId": widget.addressId,
|
||||
}),
|
||||
);
|
||||
|
||||
print("Response code: ${response.statusCode}");
|
||||
print("Response body: ${response.body}");
|
||||
|
||||
if (response.statusCode != 200 && response.statusCode != 201) {
|
||||
setState(() {
|
||||
_statusMessage = "Failed to initiate payment.";
|
||||
_isLoading = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
final data = jsonDecode(response.body);
|
||||
final String? orderId = data['orderId'];
|
||||
final String? merchantId = data['merchantId'];
|
||||
final String? token = data['token'];
|
||||
|
||||
const String environment = "PRODUCTION";
|
||||
const String appSchema = "frontshop";
|
||||
final String flowId = 'FLWID_${Uuid().v4()}';
|
||||
|
||||
if (orderId == null || merchantId == null || token == null) {
|
||||
print("Invalid response from backend. Missing fields.");
|
||||
setState(() {
|
||||
_statusMessage = "Invalid response from backend.";
|
||||
_isLoading = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
print("Initializing SDK...");
|
||||
|
||||
PhonePePaymentSdk.init(environment, merchantId, flowId, true);
|
||||
|
||||
final payload = {
|
||||
"orderId": orderId,
|
||||
"merchantId": merchantId,
|
||||
"token": token,
|
||||
"paymentMode": {"type": "PAY_PAGE"},
|
||||
};
|
||||
String request = jsonEncode(payload);
|
||||
|
||||
print("Starting transaction with payload: $request");
|
||||
|
||||
final result = await PhonePePaymentSdk.startTransaction(request, appSchema);
|
||||
print("Transaction result: $result");
|
||||
|
||||
if (result != null) {
|
||||
final status = result['status']?.toString() ?? '';
|
||||
final error = result['error']?.toString() ?? '';
|
||||
|
||||
if (status == 'SUCCESS') {
|
||||
final txnId = data['merchantOrderId']?? '';
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("Payment Successful!")),
|
||||
);
|
||||
_verifyPayment(txnId);
|
||||
context.push(MyRoutes.MYORDER);
|
||||
} else if (status == 'CANCELLED') {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("Payment Cancelled by User")),
|
||||
);
|
||||
setState(() {
|
||||
_statusMessage = "Payment cancelled.";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text("Payment Failed: $error")),
|
||||
);
|
||||
setState(() {
|
||||
_statusMessage = "Payment failed.";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false);
|
||||
}
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("No response from PhonePe")),
|
||||
);
|
||||
setState(() {
|
||||
_statusMessage = "No response.";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
print("Error during payment: $e");
|
||||
setState(() {
|
||||
_statusMessage = "Error: ${e.toString()}";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false); // 👈 Exit with failure
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _verifyPayment(String transactionId) async {
|
||||
try {
|
||||
|
||||
|
||||
|
||||
final verifyUri = Uri.parse(
|
||||
"https://mv.frontshopemporium.in/xam/payment/phonepe/sdk/status/$transactionId",
|
||||
);
|
||||
|
||||
final response = await http.get(
|
||||
verifyUri,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"authorization": "Bearer ${await SharedPrefUtils.getToken()}",
|
||||
},
|
||||
);
|
||||
|
||||
print("Status check response: ${response.body}");
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final statusData = jsonDecode(response.body);
|
||||
final paymentStatus = statusData['status'];
|
||||
|
||||
if (paymentStatus == "SUCCESS") {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("Order Placed Successfully")),
|
||||
);
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => MyOrderScreen()),
|
||||
(route) => false,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
setState(() {
|
||||
_statusMessage = "Payment verification failed: $paymentStatus";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false); // ❌ Return failure
|
||||
}
|
||||
} else {
|
||||
setState(() {
|
||||
_statusMessage = "Failed to verify payment.";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false);
|
||||
}
|
||||
} catch (e) {
|
||||
print("Verification error: $e");
|
||||
setState(() {
|
||||
_statusMessage = "Verification error: ${e.toString()}";
|
||||
_isLoading = false;
|
||||
});
|
||||
Navigator.pop(context, false); // ❌ Return failure
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text("PhonePe Payment")),
|
||||
body: Center(
|
||||
child: _isLoading
|
||||
? const CircularProgressIndicator()
|
||||
: Text(
|
||||
_statusMessage,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,12 +7,16 @@
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <file_selector_linux/file_selector_plugin.h>
|
||||
#include <gtk/gtk_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) gtk_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
|
||||
gtk_plugin_register_with_registrar(gtk_registrar);
|
||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
file_selector_linux
|
||||
gtk
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import app_links
|
||||
import connectivity_plus
|
||||
import file_selector_macos
|
||||
import firebase_core
|
||||
@@ -15,10 +16,11 @@ import geolocator_apple
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
import shared_preferences_foundation
|
||||
import sqflite
|
||||
import sqflite_darwin
|
||||
import url_launcher_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
|
||||
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||
|
||||
494
pubspec.lock
494
pubspec.lock
File diff suppressed because it is too large
Load Diff
15
pubspec.yaml
15
pubspec.yaml
@@ -2,7 +2,7 @@ name: grocery_app
|
||||
description: "CustomerApp"
|
||||
|
||||
publish_to: 'none'
|
||||
version: 1.0.0+1
|
||||
version: 1.0.3+25
|
||||
|
||||
environment:
|
||||
sdk: '>=3.4.0 <4.0.0'
|
||||
@@ -24,16 +24,21 @@ dependencies:
|
||||
flutter_toggle_tab: ^1.4.1
|
||||
dotted_border: ^2.1.0
|
||||
go_router: ^14.2.0
|
||||
uuid: ^4.0.0
|
||||
phonepe_payment_sdk: ^3.0.0
|
||||
google_maps_flutter:
|
||||
geolocator:
|
||||
geocoding:
|
||||
flutter_google_places:
|
||||
google_api_headers:
|
||||
app_links: ^3.0.0
|
||||
google_places_flutter: ^2.1.0
|
||||
google_api_headers: ^4.4.1
|
||||
fluttertoast:
|
||||
flutter_rating_stars: ^1.1.0
|
||||
url_launcher: ^6.3.1
|
||||
skeletonizer: ^1.4.3
|
||||
art_sweetalert: ^0.0.5
|
||||
|
||||
|
||||
blur:
|
||||
flutter_rating_bar:
|
||||
change_app_package_name: ^1.5.0
|
||||
@@ -75,6 +80,10 @@ dependencies:
|
||||
image_picker: any
|
||||
shimmer: ^3.0.0
|
||||
flutter_inappwebview: ^6.0.0
|
||||
razorpay_flutter: ^1.3.7
|
||||
http: ^1.1.0
|
||||
|
||||
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// This is a basic Flutter widget test.
|
||||
//
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:grocery_app/main.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(const MyApplication());
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(find.text('1'), findsNothing);
|
||||
|
||||
// Tap the '+' icon and trigger a frame.
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that our counter has incremented.
|
||||
expect(find.text('0'), findsNothing);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
@@ -6,20 +6,26 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <app_links/app_links_plugin_c_api.h>
|
||||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||
#include <file_selector_windows/file_selector_windows.h>
|
||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
|
||||
#include <geolocator_windows/geolocator_windows.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
AppLinksPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
|
||||
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||
FileSelectorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||
FirebaseCorePluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
|
||||
FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi"));
|
||||
GeolocatorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("GeolocatorWindows"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
app_links
|
||||
connectivity_plus
|
||||
file_selector_windows
|
||||
firebase_core
|
||||
flutter_inappwebview_windows
|
||||
geolocator_windows
|
||||
permission_handler_windows
|
||||
url_launcher_windows
|
||||
|
||||
Reference in New Issue
Block a user