1)product manual api integration

2)order management implementation
This commit is contained in:
saritabirare 2024-09-16 16:48:52 +05:30
parent 174d7afa99
commit 545637e035
24 changed files with 1528 additions and 392 deletions

View File

@ -1,4 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<application <application
android:label="cheminova" android:label="cheminova"

BIN
assets/images/cart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,47 @@
import 'package:cheminova/controller/product_mannual_service.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/product_mannual_model.dart'; // Your model import
// Your service import
class ProductManualController extends GetxController {
var productManualList = <ProductManualModel>[].obs;
// Service to fetch data
final ProductMannualService productMannualService = ProductMannualService();
// Loading state
var isLoading = false.obs;
// Method to fetch product manuals from the service
void fetchProductManuals() async {
try {
// Set loading to true
isLoading.value = true;
SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('token');
var manuals = await productMannualService.getProductManuals(token!);
// If data is returned, update the list
if (manuals != null) {
productManualList.value = manuals;
} else {
productManualList.value = []; // If no data, set an empty list
}
} catch (e) {
// Handle error here, for example logging or showing an error message
print("Error fetching product manuals: $e");
} finally {
// Set loading to false
isLoading.value = false;
}
}
@override
void onInit() {
// Fetch product manuals when the controller is initialized
fetchProductManuals();
super.onInit();
}
}

View File

@ -0,0 +1,36 @@
import '../models/product_mannual_model.dart';
import '../utils/common_api_service.dart'; // Replace with your actual common API service import
class ProductMannualService {
Future<List<ProductManualModel>?> getProductManuals(String token) async {
try {
String url = "/api/productmanual/getall"; // Base URL to fetch product manuals
final response = await commonApiService<List<ProductManualModel>>(
method: "GET",
url: url,
additionalHeaders: { // Pass the token here
'Authorization': 'Bearer $token',
},
fromJson: (json) {
if (json['productManuals'] != null) {
// Map the list of product manuals from the response
final List<ProductManualModel> productManuals = (json['productManuals'] as List)
.map((manualJson) => ProductManualModel.fromJson(manualJson as Map<String, dynamic>))
.toList();
return productManuals;
} else {
return [];
}
},
);
return response;
} catch (e) {
print(e.toString());
return null;
}
}
}

View File

@ -0,0 +1,120 @@
class ProductManualModel {
final String id;
final String title;
final ProductManualDetails productManual;
final String createdAt;
final String updatedAt;
ProductManualModel({
required this.id,
required this.title,
required this.productManual,
required this.createdAt,
required this.updatedAt,
});
// Factory method to create a ProductManualModel from JSON
factory ProductManualModel.fromJson(Map<String, dynamic> json) {
return ProductManualModel(
id: json['_id'] ?? '',
title: json['title'] ?? '',
productManual: ProductManualDetails.fromJson(json['product_manual']),
createdAt: json['createdAt'],
updatedAt: json['updatedAt'],
);
}
// Method to convert a ProductManualModel to JSON
Map<String, dynamic> toJson() {
return {
'_id': id,
'title': title,
'product_manual': productManual.toJson(),
'createdAt': createdAt,
'updatedAt': updatedAt,
};
}
// Override toString for better debugging
@override
String toString() {
return 'ProductManualModel(id: $id, title: $title, productManual: $productManual, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
class ProductManualDetails {
final String publicId;
final String url;
final String filename;
ProductManualDetails({
required this.publicId,
required this.url,
required this.filename,
});
// Factory method to create ProductManualDetails from JSON
factory ProductManualDetails.fromJson(Map<String, dynamic> json) {
return ProductManualDetails(
publicId: json['public_id'] ?? '',
url: json['url'] ?? '',
filename: json['filename'] ?? '',
);
}
// Method to convert ProductManualDetails to JSON
Map<String, dynamic> toJson() {
return {
'public_id': publicId,
'url': url,
'filename': filename,
};
}
// Override toString for better debugging
@override
String toString() {
return 'ProductManualDetails(publicId: $publicId, url: $url, filename: $filename)';
}
}
// Model for handling the entire response
class ProductManualResponse {
final bool success;
final List<ProductManualModel> productManuals;
final int total;
ProductManualResponse({
required this.success,
required this.productManuals,
required this.total,
});
// Factory method to create ProductManualResponse from JSON
factory ProductManualResponse.fromJson(Map<String, dynamic> json) {
var productList = (json['productManuals'] as List)
.map((manual) => ProductManualModel.fromJson(manual))
.toList();
return ProductManualResponse(
success: json['success'] ?? false,
productManuals: productList,
total: json['total'] ?? 0,
);
}
// Method to convert ProductManualResponse to JSON
Map<String, dynamic> toJson() {
return {
'success': success,
'productManuals': productManuals.map((manual) => manual.toJson()).toList(),
'total': total,
};
}
// Override toString for better debugging
@override
String toString() {
return 'ProductManualResponse(success: $success, total: $total, productManuals: $productManuals)';
}
}

View File

@ -9,6 +9,7 @@ class Product {
final Brand brand; final Brand brand;
final int price; final int price;
int quantity; int quantity;
bool selected;
final int gst; final int gst;
final int hsnCode; final int hsnCode;
final String description; final String description;
@ -24,6 +25,7 @@ class Product {
required this.brand, required this.brand,
required this.price, required this.price,
this.quantity =1, this.quantity =1,
this.selected=false,
required this.gst, required this.gst,
required this.hsnCode, required this.hsnCode,
required this.description, required this.description,

View File

@ -138,7 +138,7 @@ class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
hintText: "Current Password", hintText: "Current Password",
labelText: "Current Password", labelText: "Current Password",
controller: authController.currentpassController, controller: authController.currentpassController,
obscureText: true, obscureText: false,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
), ),
@ -146,7 +146,7 @@ class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
InputField( InputField(
hintText: "New Password", hintText: "New Password",
labelText: "New Password", labelText: "New Password",
obscureText: true, obscureText: false,
controller: authController.newpassController, controller: authController.newpassController,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
), ),
@ -154,7 +154,7 @@ class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
InputField( InputField(
hintText: "Confirm Password", hintText: "Confirm Password",
labelText: "Confirm Password", labelText: "Confirm Password",
obscureText: true, obscureText: false,
controller: authController.confirmpassController, controller: authController.confirmpassController,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
), ),

View File

@ -1,5 +1,6 @@
import 'package:cheminova/screens/authentication/controller/auth_service.dart'; import 'package:cheminova/screens/authentication/controller/auth_service.dart';
import 'package:cheminova/screens/home_screen.dart'; import 'package:cheminova/screens/home_screen.dart';
import 'package:cheminova/utils/show_snackbar.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -25,8 +26,12 @@ class AuthController extends GetxController {
isLoading.value = false; isLoading.value = false;
update(); update();
if (response != null) { if (response != null) {
showSnackbar("Your Successfully logged In!");
Get.offAll(() => const HomeScreen()); Get.offAll(() => const HomeScreen());
} }
else if(response == null){
showSnackbar("Please Enter Valid Email or Password");
}
} }
Future<void> forgotpass() async{ Future<void> forgotpass() async{
@ -39,7 +44,7 @@ class AuthController extends GetxController {
isLoading.value = false; isLoading.value = false;
update(); update();
if(response != null){ if(response != null){
showSnackbar("Email sent successfully");
} }
} }

View File

@ -1,13 +1,12 @@
import 'dart:ui';
import 'package:cheminova/screens/authentication/controller/auth_controller.dart';
import 'package:cheminova/screens/authentication/forget_password_screen.dart';
import 'package:cheminova/screens/authentication/verify_phone_screen.dart';
import 'package:cheminova/widgets/custom_button.dart';
import 'package:cheminova/widgets/input_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../widgets/comman_text_from_filed.dart';
import '../../widgets/custom_button.dart';
import 'controller/auth_controller.dart';
import 'forget_password_screen.dart';
// Make sure you import HomeScreen
class LoginScreen extends StatefulWidget { class LoginScreen extends StatefulWidget {
const LoginScreen({super.key}); const LoginScreen({super.key});
@ -19,6 +18,8 @@ class LoginScreen extends StatefulWidget {
class _LoginScreenState extends State<LoginScreen> { class _LoginScreenState extends State<LoginScreen> {
final formKey = GlobalKey<FormState>(); final formKey = GlobalKey<FormState>();
final authController = Get.put(AuthController()); final authController = Get.put(AuthController());
final String emailPattern = r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$';
final String passwordPattern = r'^.{6,}$'; // At least 6 characters
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -30,9 +31,7 @@ class _LoginScreenState extends State<LoginScreen> {
decoration: const BoxDecoration( decoration: const BoxDecoration(
image: DecorationImage( image: DecorationImage(
fit: BoxFit.cover, fit: BoxFit.cover,
image: AssetImage( image: AssetImage('assets/images/image_1.png'),
'assets/images/image_1.png',
),
), ),
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(50.0), bottomLeft: Radius.circular(50.0),
@ -45,6 +44,8 @@ class _LoginScreenState extends State<LoginScreen> {
), ),
), ),
SingleChildScrollView( SingleChildScrollView(
child: Form(
key: formKey,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
@ -130,17 +131,37 @@ class _LoginScreenState extends State<LoginScreen> {
), ),
), ),
), ),
InputField( CommonTextFormField(
hintText: "Email",
labelText: "Email",
controller: authController.emailController, controller: authController.emailController,
keyboardType: TextInputType.emailAddress, keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email id';
}
if (!RegExp(emailPattern).hasMatch(value)) {
return 'Please Enter valid email';
}
return null;
},
title: 'Email',
label: "Email",
), ),
InputField( const SizedBox(height: 15),
hintText: "Password", CommonTextFormField(
labelText: "Password",
controller: authController.passwordController, controller: authController.passwordController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
}
if (!RegExp(passwordPattern).hasMatch(value)) {
return 'Please Enter valid password';
}
return null;
},
obscureText: true, obscureText: true,
title: 'Password',
maxLines: 1,
label: "Password",
), ),
const SizedBox(height: 30), const SizedBox(height: 30),
GestureDetector( GestureDetector(
@ -161,7 +182,12 @@ class _LoginScreenState extends State<LoginScreen> {
Obx( Obx(
() => CustomButton( () => CustomButton(
text: "Login", text: "Login",
onPressed: () => authController.login(), onPressed: () {
if (formKey.currentState!.validate()) {
// Perform login action
authController.login();
}
},
isLoading: authController.isLoading.value, isLoading: authController.isLoading.value,
), ),
), ),
@ -172,6 +198,7 @@ class _LoginScreenState extends State<LoginScreen> {
], ],
), ),
), ),
),
], ],
), ),
); );

View File

@ -16,7 +16,8 @@ import '../../models/product_model1.dart';
class OrderConfermationScreen extends StatefulWidget { class OrderConfermationScreen extends StatefulWidget {
Product? productModel; Product? productModel;
PlacedOrderModel? placedOrder; PlacedOrderModel? placedOrder;
OrderConfermationScreen({super.key,this.productModel,this.placedOrder}); List<Product>? selectedProducts;
OrderConfermationScreen({super.key,this.productModel,this.placedOrder,this.selectedProducts});
@override @override
State<OrderConfermationScreen> createState() => State<OrderConfermationScreen> createState() =>
@ -143,10 +144,10 @@ class _OrderConfermationScreenState extends State<OrderConfermationScreen> {
padding: EdgeInsets.all(Get.width * 0.02), padding: EdgeInsets.all(Get.width * 0.02),
child: ListView.builder( child: ListView.builder(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemCount: _cartController.cartList.length, itemCount: _cartController.selectedProducts.length,
itemBuilder: (context, index) => itemBuilder: (context, index) =>
ProductCard( ProductCard(
productModel:_cartController.cartList[index], productModel:_cartController.selectedProducts[index],
isCheckout: true, isCheckout: true,
), ),
), ),

View File

@ -1,10 +1,9 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cheminova/controller/get_order_placed_controller.dart'; import 'package:cheminova/controller/get_order_placed_controller.dart';
import 'package:cheminova/models/oder_place_model.dart'; import 'package:cheminova/models/oder_place_model.dart';
import 'package:cheminova/models/order_item_model.dart'; import 'package:cheminova/models/order_item_model.dart';
import 'package:cheminova/models/place_order_list_model.dart'; import 'package:cheminova/models/place_order_list_model.dart';
import 'package:cheminova/models/product_model.dart';
import 'package:cheminova/screens/order_management/order_fullfilment_screen.dart';
import 'package:cheminova/widgets/product_card.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
@ -49,7 +48,7 @@ Future<void> adduni()async {
final List<PlacedOrderList> uniqueOrders = []; final List<PlacedOrderList> uniqueOrders = [];
for (var order in _getPlacedOrderController.placedOrders) { for (var order in _getPlacedOrderController.placedOrders) {
if (uniqueOrderIds.add(order.id)) { if (uniqueOrderIds.add(order.uniqueId)) {
uniqueOrders.add(order); uniqueOrders.add(order);
} }
} }
@ -158,7 +157,7 @@ Future<void> adduni()async {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
Text(widget.placedOrderList!.id), Text(widget.placedOrderList!.uniqueId),
], ],
), ),
), ),
@ -283,6 +282,7 @@ Future<void> adduni()async {
), ),
SizedBox( SizedBox(
width: Get.width, width: Get.width,
height: Get.height*0.06,
child: Padding( child: Padding(
padding: padding:
const EdgeInsets.fromLTRB(8, 8, 8, 0), const EdgeInsets.fromLTRB(8, 8, 8, 0),
@ -295,7 +295,8 @@ Future<void> adduni()async {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
Text("${widget.placedOrderList!.shipTo}") AutoSizeText("${widget.placedOrderList!.shipTo}",maxLines: 4,
overflow:TextOverflow.ellipsis,)
], ],
), ),
), ),

View File

@ -177,7 +177,7 @@ class _OrderManagementScreenState extends State<OrderManagementScreen> {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Text("Order ID: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)), Text("Order ID: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)),
Text("${order.id}") Text("${order.uniqueId}")
], ],
), ),
), ),

View File

@ -1,5 +1,4 @@
import 'package:cheminova/models/oder_place_model.dart';
import 'package:cheminova/models/product_model.dart';
import 'package:cheminova/screens/order/checkout_screen.dart'; import 'package:cheminova/screens/order/checkout_screen.dart';
import 'package:cheminova/widgets/my_drawer.dart'; import 'package:cheminova/widgets/my_drawer.dart';
import 'package:cheminova/widgets/product_card.dart'; import 'package:cheminova/widgets/product_card.dart';
@ -9,11 +8,13 @@ import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../controller/cart_controller.dart'; import '../../controller/cart_controller.dart';
import '../../models/oder_place_model.dart';
import '../../models/product_model1.dart'; import '../../models/product_model1.dart';
class CartScreen extends StatefulWidget { class CartScreen extends StatefulWidget {
Product? productModel; Product? productModel;
PlacedOrderModel? placedOrder; PlacedOrderModel? placedOrder;
CartScreen({super.key, this.productModel, this.placedOrder}); CartScreen({super.key, this.productModel, this.placedOrder});
@override @override
@ -23,12 +24,33 @@ class CartScreen extends StatefulWidget {
class _CartScreenState extends State<CartScreen> { class _CartScreenState extends State<CartScreen> {
final CartController _cartController = Get.find<CartController>(); final CartController _cartController = Get.find<CartController>();
// @override bool _selectAll = true; // Default to true to select all products
@override
void initState() { void initState() {
super.initState(); super.initState();
if (widget.productModel != null) { if (widget.productModel != null) {
_cartController.addToCart(widget.productModel!); _cartController.addToCart(widget.productModel!);
} }
// Ensure all products are pre-selected by default
_cartController.initializeSelections();
_checkIfAllSelected(); // Check if all products are selected by default
}
void _toggleSelectAll(bool? value) {
setState(() {
_selectAll = value ?? false;
_cartController.selectAllProducts(_selectAll);
});
}
void _checkIfAllSelected() {
// This function checks if all items are selected or not and updates _selectAll
setState(() {
_selectAll = _cartController.cartList.every(
(product) => _cartController.selectedProducts.contains(product),
);
});
} }
@override @override
@ -62,8 +84,8 @@ class _CartScreenState extends State<CartScreen> {
), ),
), ),
], ],
title: Center( title: const Center(
child: const Text( child: Text(
"Cart", "Cart",
), ),
), ),
@ -77,7 +99,31 @@ class _CartScreenState extends State<CartScreen> {
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
SafeArea( SafeArea(
child: Obx(() {
if (_cartController.cartList.isEmpty) {
return Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/cart.png',
width: Get.width * 0.5,
height: Get.width * 0.5,
),
const SizedBox(height: 20),
Text(
'Your Cart is empty',
style: GoogleFonts.roboto(
fontSize: 24,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
],
),
);
}
return Column(
children: [ children: [
SizedBox( SizedBox(
height: Get.height * 0.02, height: Get.height * 0.02,
@ -94,97 +140,111 @@ class _CartScreenState extends State<CartScreen> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
// "Select All" Checkbox
Row(
children: [
Checkbox(
value: _selectAll,
onChanged: _toggleSelectAll,
),
Text(
"Select All",
style: GoogleFonts.roboto(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
],
),
SizedBox( SizedBox(
height: Get.height * 0.6, height: Get.height * 0.6,
child: Obx(() { child: ListView.builder(
return ListView.builder(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemCount: _cartController.cartList.length, itemCount: _cartController.cartList.length,
itemBuilder: (context, index) => ProductCard( itemBuilder: (context, index) {
productModel: _cartController.cartList[index], return Row(
children: [
Checkbox(
value: _cartController.selectedProducts.contains(
_cartController.cartList[index]),
onChanged: (value) {
_cartController.toggleProductSelection(
_cartController.cartList[index],
value!,
);
_checkIfAllSelected(); // Check if all are selected after each toggle
},
),
Expanded(
child: ProductCard(
productModel:
_cartController.cartList[index],
isInCart: true, isInCart: true,
placedOrder: widget.placedOrder, placedOrder: widget.placedOrder,
), ),
),
],
); );
}), },
), ),
const SizedBox(
height: 10,
), ),
Obx(() { const SizedBox(height: 10),
return Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
"Subtotal ", "Subtotal ",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 15, fontSize: 15,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.bold fontWeight: FontWeight.bold,
), ),
), ),
Text("${_cartController.subtotal.value}"), Obx(() =>
Text("${_cartController.subtotal.value}")),
], ],
); ),
Row(
}),
// const SizedBox(
// height: 16,
// ),
Obx(() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
"GST ", "GST ",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 15, fontSize: 15,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.bold fontWeight: FontWeight.bold,
), ),
), ),
Text("${_cartController.gstTotal.value}"), Obx(() =>
Text("${_cartController.gstTotal.value}")),
], ],
); ),
Row(
}),
Obx(() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
"Total Amount ", "Total Amount ",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 15, fontSize: 15,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.bold fontWeight: FontWeight.bold,
), ),
), ),
Text("${_cartController.grandTotal.value}"), Obx(() => Text(
"${_cartController.grandTotal.value}")),
], ],
); ),
}),
], ],
), ),
), ),
), ),
SizedBox( SizedBox(height: Get.height * 0.020),
height: Get.height * 0.025,
),
SizedBox( SizedBox(
width: Get.width * 0.9, width: Get.width * 0.9,
height: Get.height * 0.06, height: Get.height * 0.06,
child: ElevatedButton( child: ElevatedButton(
onPressed: () => Get.to(() => CheckoutScreen( onPressed: () => Get.to(() => CheckoutScreen(
selectedProducts: _cartController.selectedProducts,
productModel:widget.productModel
)), )),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, foregroundColor: Colors.white,
@ -203,10 +263,277 @@ class _CartScreenState extends State<CartScreen> {
), ),
), ),
], ],
), );
}),
), ),
], ],
), ),
); );
} }
} }
// import 'package:cheminova/models/oder_place_model.dart';
// import 'package:cheminova/models/product_model.dart';
// import 'package:cheminova/screens/order/checkout_screen.dart';
// import 'package:cheminova/widgets/my_drawer.dart';
// import 'package:cheminova/widgets/product_card.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter_svg/svg.dart';
// import 'package:get/get.dart';
// import 'package:google_fonts/google_fonts.dart';
//
// import '../../controller/cart_controller.dart';
// import '../../models/product_model1.dart';
//
// class CartScreen extends StatefulWidget {
// Product? productModel;
// PlacedOrderModel? placedOrder;
//
// CartScreen({super.key, this.productModel, this.placedOrder});
//
// @override
// State<CartScreen> createState() => _CartScreenState();
// }
//
// class _CartScreenState extends State<CartScreen> {
// final CartController _cartController = Get.find<CartController>();
//
// bool _selectAll = false; // State to track "Select All" checkbox
//
// @override
// void initState() {
// super.initState();
// if (widget.productModel != null) {
// _cartController.addToCart(widget.productModel!);
// }
// }
//
// void _toggleSelectAll(bool? value) {
// setState(() {
// _selectAll = value ?? false;
// _cartController.cartList.forEach((product) {
// _cartController.toggleProductSelection(product, _selectAll);
// });
// });
// }
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// extendBodyBehindAppBar: true,
// appBar: AppBar(
// backgroundColor: Colors.transparent,
// elevation: 0,
// leading: Builder(
// builder: (context) {
// return GestureDetector(
// onTap: () => Scaffold.of(context).openDrawer(),
// child: Padding(
// padding: const EdgeInsets.all(16.0),
// child: SvgPicture.asset(
// 'assets/svg/menu.svg',
// ),
// ),
// );
// },
// ),
// actions: [
// GestureDetector(
// onTap: () => Get.back(),
// child: Padding(
// padding: const EdgeInsets.all(8.0),
// child: SvgPicture.asset(
// 'assets/svg/back_arrow.svg',
// ),
// ),
// ),
// ],
// title: Center(
// child: const Text(
// "Cart",
// ),
// ),
// ),
// drawer: const MyDrawer(),
// body: Stack(
// fit: StackFit.expand,
// children: [
// Image.asset(
// 'assets/images/image_1.png',
// fit: BoxFit.cover,
// ),
// SafeArea(
// child: Obx(() {
// if (_cartController.cartList.isEmpty) {
// return Center(
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Image.asset(
// 'assets/images/cart.png',
// width: Get.width * 0.5,
// height: Get.width * 0.5,
// ),
// const SizedBox(height: 20),
// Text(
// 'Your Cart is empty',
// style: GoogleFonts.roboto(
// fontSize: 24,
// fontWeight: FontWeight.w500,
// color: Colors.white,
// ),
// ),
// ],
// ),
// );
// }
// return Column(
// children: [
// SizedBox(
// height: Get.height * 0.02,
// ),
// Card(
// margin: const EdgeInsets.symmetric(horizontal: 18),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(19),
// side: const BorderSide(color: Color(0xFFFDFDFD)),
// ),
// color: const Color(0xFFB4D1E5).withOpacity(0.9),
// child: Padding(
// padding: const EdgeInsets.all(12.0),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: [
// // "Select All" Checkbox
// Row(
// children: [
// Checkbox(
// value: _selectAll,
// onChanged: _toggleSelectAll,
// ),
// Text(
// "Select All",
// style: GoogleFonts.roboto(
// fontSize: 16,
// fontWeight: FontWeight.w500,
// ),
// ),
// ],
// ),
// SizedBox(
// height: Get.height * 0.6,
// child: ListView.builder(
// padding: EdgeInsets.zero,
// itemCount: _cartController.cartList.length,
// itemBuilder: (context, index) {
// return Row(
// children: [
// Checkbox(
// value: _cartController
// .cartList[index].selected,
// onChanged: (value) {
// setState(() {
//
// });
// _cartController.toggleProductSelection(
// _cartController.cartList[index],
// value!);
// },
// ),
// Expanded(
// child: ProductCard(
// productModel:
// _cartController.cartList[index],
// isInCart: true,
// placedOrder: widget.placedOrder,
// ),
// ),
// ],
// );
// },
// ),
// ),
// const SizedBox(height: 10),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text(
// "Subtotal ",
// style: GoogleFonts.roboto(
// fontSize: 15,
// color: Colors.black,
// fontWeight: FontWeight.bold,
// ),
// ),
// Obx(() => Text("${_cartController.subtotal.value}")),
// ],
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text(
// "GST ",
// style: GoogleFonts.roboto(
// fontSize: 15,
// color: Colors.black,
// fontWeight: FontWeight.bold,
// ),
// ),
// Obx(() => Text("${_cartController.gstTotal.value}")),
// ],
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text(
// "Total Amount ",
// style: GoogleFonts.roboto(
// fontSize: 15,
// color: Colors.black,
// fontWeight: FontWeight.bold,
// ),
// ),
// Obx(() => Text("${_cartController.grandTotal.value}")),
// ],
// ),
// ],
// ),
// ),
// ),
// SizedBox(height: Get.height * 0.020),
// SizedBox(
// width: Get.width * 0.9,
// height: Get.height * 0.06,
// child: ElevatedButton(
// onPressed: () => Get.to(() => CheckoutScreen(
// productModel: widget.productModel,
// )),
// style: ElevatedButton.styleFrom(
// foregroundColor: Colors.white,
// backgroundColor: const Color(0xFF00784C),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(10),
// ),
// ),
// child: Text(
// "Proceed to Checkout",
// style: GoogleFonts.roboto(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ],
// );
// }),
// ),
// ],
// ),
// );
// }
// }

View File

@ -0,0 +1,26 @@
import 'package:cheminova/models/product_mannual_model.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
class ViewPdfScreen extends StatefulWidget {
final ProductManualModel productManualModel;
const ViewPdfScreen({super.key, required this.productManualModel});
@override
State<ViewPdfScreen> createState() => _ViewPdfScreenState();
}
class _ViewPdfScreenState extends State<ViewPdfScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SfPdfViewer.network(
widget.productManualModel.productManual.url,
),
),
);
}
}

View File

@ -0,0 +1,134 @@
import 'package:cheminova/controller/product_mannual_controller.dart';
import 'package:cheminova/models/product_mannual_model.dart';
import 'package:cheminova/screens/product/pdf_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart';
import '../../widgets/custom_button.dart';
class ProductsManualScreen extends StatefulWidget {
const ProductsManualScreen({super.key});
@override
_ProductsManualScreenState createState() => _ProductsManualScreenState();
}
class _ProductsManualScreenState extends State<ProductsManualScreen> {
final ProductManualController _productManualController = Get.put(ProductManualController());
@override
void initState() {
super.initState();
_productManualController.fetchProductManuals(); // Fetch product manual list from API
}
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: _buildAppBar(),
body: Stack(
alignment: Alignment.topCenter,
children: [
_buildBackgroundImage(),
Center(
child: SingleChildScrollView(
child: _buildCardContent(),
),
),
],
),
);
}
// Extract AppBar to its own method
AppBar _buildAppBar() {
return AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: GestureDetector(
onTap: () => Get.back(),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: SvgPicture.asset('assets/svg/menu.svg'),
),
),
actions: [
GestureDetector(
onTap: () => Get.back(),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SvgPicture.asset('assets/svg/back_arrow.svg'),
),
),
],
);
}
// Extract background image widget
Widget _buildBackgroundImage() {
return Container(
height: 900,
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/images/image_1.png'),
),
),
child: SizedBox(
width: Get.width,
height: Get.height * 0.7,
),
);
}
// Build the card content
Widget _buildCardContent() {
return Obx(() {
if (_productManualController.isLoading.value) {
return const CircularProgressIndicator(); // Loading state
}
if (_productManualController.productManualList.isEmpty) {
return const Text("No product manuals available"); // Empty state
}
return Card(
margin: const EdgeInsets.symmetric(horizontal: 24),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(19),
side: const BorderSide(color: Color(0xFFFDFDFD)),
),
color: const Color(0xFFB4D1E5).withOpacity(0.9),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: _buildProductButtons(),
),
),
);
});
}
// Method to create a list of CustomButtons for products dynamically from API data
List<Widget> _buildProductButtons() {
return _productManualController.productManualList.map((productManual) {
return CustomButton(
text: productManual.title ?? "No Title", // Dynamically fetch product name
onPressed: () => _navigateToPdfScreen(productManual),
);
}).toList();
}
// Method to handle navigation to PDF screen
void _navigateToPdfScreen(ProductManualModel productManual) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ViewPdfScreen(
productManualModel: productManual,
),
),
);
}
}

View File

@ -1,22 +1,31 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class InputField extends StatelessWidget { class InputField extends StatefulWidget {
final String hintText; final String hintText;
final String labelText; final String labelText;
final TextEditingController controller; final TextEditingController controller;
final bool obscureText; final bool obscureText;
final TextInputType? keyboardType; final TextInputType? keyboardType;
final String? Function(String?)? validator;// Add this line for validation
const InputField({ InputField({
super.key, super.key,
required this.hintText, required this.hintText,
required this.labelText, required this.labelText,
required this.controller, required this.controller,
this.obscureText = false, this.obscureText = false,
this.keyboardType = TextInputType.text, this.keyboardType = TextInputType.text,
this.validator, // Add this
}); });
@override
State<InputField> createState() => _InputFieldState();
}
class _InputFieldState extends State<InputField> {
bool _isObscured = true;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
@ -24,15 +33,16 @@ class InputField extends StatelessWidget {
width: Get.width * 0.9, width: Get.width * 0.9,
padding: const EdgeInsets.fromLTRB(6, 10, 10, 0), padding: const EdgeInsets.fromLTRB(6, 10, 10, 0),
child: TextFormField( child: TextFormField(
controller: controller, controller: widget.controller,
obscureText: obscureText, obscureText: widget.obscureText && _isObscured,
keyboardType: keyboardType, keyboardType: widget.keyboardType,
decoration: InputDecoration( decoration: InputDecoration(
labelText: labelText, labelText: widget.labelText,
hintText: hintText, hintText: widget.hintText,
labelStyle: const TextStyle( labelStyle: const TextStyle(
color: Color(0xFF000000), color: Color(0xFF000000),
), ),
enabledBorder: const OutlineInputBorder( enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey), borderSide: BorderSide(color: Colors.grey),
borderRadius: BorderRadius.all(Radius.circular(8)), borderRadius: BorderRadius.all(Radius.circular(8)),
@ -45,7 +55,21 @@ class InputField extends StatelessWidget {
const EdgeInsets.symmetric(vertical: 10, horizontal: 16), const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
fillColor: Colors.white, fillColor: Colors.white,
filled: true, filled: true,
// suffixIcon: widget.obscureText
// ? IconButton(
// icon: Icon(
// _isObscured ? Icons.visibility : Icons.visibility_off,
// color: Colors.grey,
// ),
// onPressed: () {
// setState(() {
// _isObscured = !_isObscured;
// });
// },
// )
// : null,
), ),
validator: widget.validator, // Add this for validation
), ),
); );
} }

View File

@ -9,7 +9,6 @@ import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../models/product_model1.dart'; import '../models/product_model1.dart';
import '../utils/show_snackbar.dart'; import '../utils/show_snackbar.dart';
class ProductCard extends StatefulWidget { class ProductCard extends StatefulWidget {
@ -69,7 +68,7 @@ class _ProductCardState extends State<ProductCard> {
borderRadius: BorderRadius.circular(15.0), borderRadius: BorderRadius.circular(15.0),
child: Container( child: Container(
height: Get.height * 0.15, height: Get.height * 0.15,
width: Get.width * 0.30, width: Get.width * 0.31,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage("assets/images/product.png"), image: AssetImage("assets/images/product.png"),
@ -79,10 +78,10 @@ class _ProductCardState extends State<ProductCard> {
), ),
), ),
), ),
const SizedBox( Expanded(
width: 10, child: Padding(
), padding: const EdgeInsets.symmetric(horizontal: 3.0),
Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
@ -106,24 +105,22 @@ class _ProductCardState extends State<ProductCard> {
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
), ),
), ),
showQuantity if (showQuantity)
? Text( Text(
"Quantity: ${currentQuantity}", "Quantity: ${currentQuantity}",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 15, fontSize: 15,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
), ),
) ),
: const SizedBox(), if (!widget.isCheckout)
widget.isCheckout widget.isInCart
? const SizedBox()
: widget.isInCart
? Row( ? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Container( Container(
height: 40, height: Get.height * 0.04,
width: 100, width: Get.width * 0.21,
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFF004791), color: const Color(0xFF004791),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
@ -167,8 +164,8 @@ class _ProductCardState extends State<ProductCard> {
), ),
), ),
SizedBox( SizedBox(
height: 24, height: 22,
width: 24, width: 22,
child: ElevatedButton( child: ElevatedButton(
onPressed: () { onPressed: () {
_cartController.increaseQuantity(widget.productModel!); _cartController.increaseQuantity(widget.productModel!);
@ -198,7 +195,7 @@ class _ProductCardState extends State<ProductCard> {
), ),
), ),
SizedBox( SizedBox(
width: 20.0, width: 2.0,
), ),
IconButton( IconButton(
onPressed: () { onPressed: () {
@ -212,7 +209,7 @@ class _ProductCardState extends State<ProductCard> {
Icons.delete_outline_rounded, Icons.delete_outline_rounded,
color: Colors.red, color: Colors.red,
), ),
) ),
], ],
) )
: ElevatedButton( : ElevatedButton(
@ -222,9 +219,6 @@ class _ProductCardState extends State<ProductCard> {
} else { } else {
_cartController.addToCart(widget.productModel!); _cartController.addToCart(widget.productModel!);
showSnackbar("Product successfully added to your cart"); showSnackbar("Product successfully added to your cart");
// setState(() {
// currentQuantity = widget.productModel!.quantity;
// });
} }
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
@ -244,7 +238,9 @@ class _ProductCardState extends State<ProductCard> {
), ),
), ),
], ],
) ),
),
),
], ],
), ),
), ),

View File

@ -6,6 +6,14 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { 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) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
} }

View File

@ -3,6 +3,8 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
url_launcher_linux
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@ -5,10 +5,18 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import device_info_plus
import file_selector_macos
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import syncfusion_pdfviewer_macos
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SyncfusionFlutterPdfViewerPlugin.register(with: registry.registrar(forPlugin: "SyncfusionFlutterPdfViewerPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
} }

View File

@ -17,6 +17,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.11.0" version: "2.11.0"
auto_size_text:
dependency: "direct main"
description:
name: auto_size_text
sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -49,6 +57,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.18.0" version: "1.18.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
url: "https://pub.dev"
source: hosted
version: "0.3.4+2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -57,6 +81,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.3" version: "3.0.3"
csc_picker:
dependency: "direct main"
description:
name: csc_picker
sha256: "7e5d6023a81f53b89a7fb0369953fd4dc676f7ea20e9a0c0707973a5f0aedf14"
url: "https://pub.dev"
source: hosted
version: "0.2.7"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -65,6 +97,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.8" version: "1.0.8"
device_info_plus:
dependency: transitive
description:
name: device_info_plus
sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
url: "https://pub.dev"
source: hosted
version: "10.1.2"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba"
url: "https://pub.dev"
source: hosted
version: "7.0.1"
dio: dio:
dependency: "direct main" dependency: "direct main"
description: description:
@ -105,6 +153,46 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.0.0" version: "7.0.0"
file_selector_linux:
dependency: transitive
description:
name: file_selector_linux
sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492"
url: "https://pub.dev"
source: hosted
version: "0.9.2+1"
file_selector_macos:
dependency: transitive
description:
name: file_selector_macos
sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385
url: "https://pub.dev"
source: hosted
version: "0.9.4"
file_selector_platform_interface:
dependency: transitive
description:
name: file_selector_platform_interface
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
url: "https://pub.dev"
source: hosted
version: "2.6.2"
file_selector_windows:
dependency: transitive
description:
name: file_selector_windows
sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69"
url: "https://pub.dev"
source: hosted
version: "0.9.3+2"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -118,6 +206,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.0.2"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda"
url: "https://pub.dev"
source: hosted
version: "2.0.22"
flutter_svg: flutter_svg:
dependency: "direct main" dependency: "direct main"
description: description:
@ -160,6 +256,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.1" version: "6.2.1"
hive:
dependency: transitive
description:
name: hive
sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
hive_flutter:
dependency: "direct main"
description:
name: hive_flutter
sha256: dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc
url: "https://pub.dev"
source: hosted
version: "1.1.0"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
@ -176,6 +288,70 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.0.2"
image_picker:
dependency: "direct main"
description:
name: image_picker
sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
sha256: "8c5abf0dcc24fe6e8e0b4a5c0b51a5cf30cefdf6407a3213dae61edc75a70f56"
url: "https://pub.dev"
source: hosted
version: "0.8.12+12"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: "6703696ad49f5c3c8356d576d7ace84d1faf459afb07accbb0fae780753ff447"
url: "https://pub.dev"
source: hosted
version: "0.8.12"
image_picker_linux:
dependency: transitive
description:
name: image_picker_linux
sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
image_picker_macos:
dependency: transitive
description:
name: image_picker_macos
sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80"
url: "https://pub.dev"
source: hosted
version: "2.10.0"
image_picker_windows:
dependency: transitive
description:
name: image_picker_windows
sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
intl: intl:
dependency: "direct main" dependency: "direct main"
description: description:
@ -184,6 +360,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.19.0" version: "0.19.0"
js:
dependency: transitive
description:
name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
url: "https://pub.dev"
source: hosted
version: "0.7.1"
leak_tracker: leak_tracker:
dependency: transitive dependency: transitive
description: description:
@ -248,6 +432,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.12.0" version: "1.12.0"
mime:
dependency: transitive
description:
name: mime
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
url: "https://pub.dev"
source: hosted
version: "1.0.6"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -413,6 +605,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.10.0" version: "1.10.0"
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -437,6 +637,70 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
syncfusion_flutter_core:
dependency: transitive
description:
name: syncfusion_flutter_core
sha256: "6e67726b85812afc7105725a23620b876ab7f6b04b8410e211330ffb8c2cdbe8"
url: "https://pub.dev"
source: hosted
version: "26.2.14"
syncfusion_flutter_pdf:
dependency: transitive
description:
name: syncfusion_flutter_pdf
sha256: "59a1173dc34a1fac0a41aff7a2bb6f3c1578f1bfd749ea8b24379018434ba5a5"
url: "https://pub.dev"
source: hosted
version: "26.2.14"
syncfusion_flutter_pdfviewer:
dependency: "direct main"
description:
name: syncfusion_flutter_pdfviewer
sha256: b54ffe621a0e2155cfc913ee55efcd160e2dc8d21c2b9185f4a9996e0ccc9424
url: "https://pub.dev"
source: hosted
version: "26.2.14"
syncfusion_flutter_signaturepad:
dependency: transitive
description:
name: syncfusion_flutter_signaturepad
sha256: "5f8955d4ee64f342b389928111ebfad041e75003415eedee802f3af1d4ce7036"
url: "https://pub.dev"
source: hosted
version: "26.2.14"
syncfusion_pdfviewer_macos:
dependency: transitive
description:
name: syncfusion_pdfviewer_macos
sha256: "1eec60fe44cc357072a0b872e4b0a82edef741463fda2b3a95a6973d7a615ec1"
url: "https://pub.dev"
source: hosted
version: "26.2.14"
syncfusion_pdfviewer_platform_interface:
dependency: transitive
description:
name: syncfusion_pdfviewer_platform_interface
sha256: e128a2875226dc1d922ac0366d0804aa0ee7a52be23799cc6d84d78fd32ce092
url: "https://pub.dev"
source: hosted
version: "26.2.14"
syncfusion_pdfviewer_web:
dependency: transitive
description:
name: syncfusion_pdfviewer_web
sha256: "5625c2e658e5d680ea240ea5f5daedf6a0acd563cec026a38b8cb5643783ce4f"
url: "https://pub.dev"
source: hosted
version: "26.2.14"
syncfusion_pdfviewer_windows:
dependency: transitive
description:
name: syncfusion_pdfviewer_windows
sha256: f6c56fea4b77ada9d7ddab6ed67a4a25317a2efd1007309e8938c01f1d952b20
url: "https://pub.dev"
source: hosted
version: "26.2.14"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@ -461,6 +725,78 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.2" version: "1.3.2"
url_launcher:
dependency: transitive
description:
name: url_launcher
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: f0c73347dfcfa5b3db8bc06e1502668265d39c08f310c29bff4e28eea9699f79
url: "https://pub.dev"
source: hosted
version: "6.3.9"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
url: "https://pub.dev"
source: hosted
version: "6.3.1"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
url: "https://pub.dev"
source: hosted
version: "3.2.0"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
url: "https://pub.dev"
source: hosted
version: "2.3.3"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
uuid:
dependency: transitive
description:
name: uuid
sha256: f33d6bb662f0e4f79dcd7ada2e6170f3b3a2530c28fc41f49a411ddedd576a77
url: "https://pub.dev"
source: hosted
version: "4.5.0"
vector_graphics: vector_graphics:
dependency: transitive dependency: transitive
description: description:
@ -509,6 +845,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
win32:
dependency: transitive
description:
name: win32
sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a"
url: "https://pub.dev"
source: hosted
version: "5.5.4"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6"
url: "https://pub.dev"
source: hosted
version: "1.1.4"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:

View File

@ -44,6 +44,11 @@ dependencies:
logger: ^2.4.0 logger: ^2.4.0
get_storage: ^2.1.1 get_storage: ^2.1.1
intl: ^0.19.0 intl: ^0.19.0
hive_flutter: ^1.1.0
syncfusion_flutter_pdfviewer: ^26.2.14
image_picker: ^1.1.2
csc_picker: ^0.2.7
auto_size_text: ^3.0.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@ -6,6 +6,15 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <file_selector_windows/file_selector_windows.h>
#include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View File

@ -3,6 +3,9 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
file_selector_windows
syncfusion_pdfviewer_windows
url_launcher_windows
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST