diff --git a/.metadata b/.metadata
index 784ce129..90eabcff 100644
--- a/.metadata
+++ b/.metadata
@@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.
version:
- revision: "a14f74ff3a1cbd521163c5f03d68113d50af93d3"
+ revision: "80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819"
channel: "stable"
project_type: app
@@ -13,11 +13,26 @@ project_type: app
migration:
platforms:
- platform: root
- create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
- base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
+ create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ - platform: android
+ create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ - platform: ios
+ create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ - platform: linux
+ create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ - platform: macos
+ create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
- platform: web
- create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
- base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
+ create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ - platform: windows
+ create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+ base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
# User provided section
diff --git a/README.md b/README.md
index 451d649a..541bb3c5 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,9 @@
# get-flutter-fire
+CONTRIBUTOR: Vaishvi Jigneshkumar Parikh
+COLLEGE NAME: MIT World Peace University
+CONTACT DETAILS: 1032211203@mitwpu.edu.in
+
This codebase provides a boilerplate code utilizing the following three technologies:
1. Flutter 3.0 - For UX and uses Dart languange. See [https://flutter.dev/]
diff --git a/android/app/google-services.json b/android/app/google-services.json
new file mode 100644
index 00000000..dc9b9ab3
--- /dev/null
+++ b/android/app/google-services.json
@@ -0,0 +1,29 @@
+{
+ "project_info": {
+ "project_number": "projectnumber",
+ "project_id": "sharekhanproject",
+ "storage_bucket": "sharekhanproject.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "app_id",
+ "android_client_info": {
+ "package_name": "com.example.get_flutter_fire"
+ }
+ },
+ "oauth_client": [],
+ "api_key": [
+ {
+ "current_key": "MYKEY"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": []
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/example/get_flutter_fire/MainActivity.kt b/android/app/src/main/kotlin/com/example/get_flutter_fire/MainActivity.kt
new file mode 100644
index 00000000..018e286b
--- /dev/null
+++ b/android/app/src/main/kotlin/com/example/get_flutter_fire/MainActivity.kt
@@ -0,0 +1,5 @@
+package com.example.get_flutter_fire
+
+import io.flutter.embedding.android.FlutterActivity
+
+class MainActivity: FlutterActivity()
diff --git a/assets/lottie/tick.json b/assets/lottie/tick.json
new file mode 100644
index 00000000..2ba17b35
--- /dev/null
+++ b/assets/lottie/tick.json
@@ -0,0 +1 @@
+{"v":"5.4.2","fr":25,"ip":0,"op":50,"w":1080,"h":1080,"nm":"Tick","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[-214,-44,0],"ix":1},"s":{"a":0,"k":[71.036,71.036,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-392,-22],[-288,82],[-36,-170]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":60,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0],"y":[0.999]},"o":{"x":[0.112],"y":[0]},"n":["0_0p999_0p112_0"],"t":17,"s":[0],"e":[100]},{"t":35}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[46,70,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0_1_0p333_0","0_1_0p333_0","0p667_1_0p333_0"],"t":9,"s":[0,0,100],"e":[84.593,84.593,100]},{"t":17}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[540,540],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.598895203833,0.149973072725,0.83137254902,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[46,70],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":50,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[46,70,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.146,0.146,0.667],"y":[1,1,1]},"o":{"x":[0.21,0.21,0.333],"y":[0,0,0]},"n":["0p146_1_0p21_0","0p146_1_0p21_0","0p667_1_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"t":8}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[540,540],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.830080817727,0.501960754395,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[46,70],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":50,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/cors.json b/cors.json
new file mode 100644
index 00000000..a4859301
--- /dev/null
+++ b/cors.json
@@ -0,0 +1,14 @@
+[
+ {
+ "origin": [
+ "*"
+ ],
+ "method": [
+ "GET",
+ "POST",
+ "PUT",
+ "DELETE"
+ ],
+ "maxAgeSeconds": 3600
+ }
+]
\ No newline at end of file
diff --git a/firebase.json b/firebase.json
new file mode 100644
index 00000000..d6ea5ad1
--- /dev/null
+++ b/firebase.json
@@ -0,0 +1 @@
+// Added my firebase.json file
\ No newline at end of file
diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist
new file mode 100644
index 00000000..a940fe30
--- /dev/null
+++ b/ios/Runner/GoogleService-Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ API_KEY
+ API-KEY
+ GCM_SENDER_ID
+ SENDER-ID
+ PLIST_VERSION
+ 1
+ BUNDLE_ID
+ com.example.getflutterfire
+ PROJECT_ID
+ sharekhanproject
+ STORAGE_BUCKET
+ sharekhanproject.appspot.com
+ IS_ADS_ENABLED
+
+ IS_ANALYTICS_ENABLED
+
+ IS_APPINVITE_ENABLED
+
+ IS_GCM_ENABLED
+
+ IS_SIGNIN_ENABLED
+
+ GOOGLE_APP_ID
+ GOOGLE-APP-ID
+
+
\ No newline at end of file
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index fc7f1dd4..41297579 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -51,5 +51,12 @@
Allow access to microphone for video recording
NSPhotoLibraryUsageDescription
Allow access to photo library
+ NSPhotoLibraryUsageDescription
+ Need access to photo library to select profile picture
+ NSCameraUsageDescription
+ Need access to camera to take a profile picture
+ NSMicrophoneUsageDescription
+ Need access to microphone for recording
+
diff --git a/lib/app/modules/cart/controllers/cart_controller.dart b/lib/app/modules/cart/controllers/cart_controller.dart
index c938ec4c..71344eb7 100644
--- a/lib/app/modules/cart/controllers/cart_controller.dart
+++ b/lib/app/modules/cart/controllers/cart_controller.dart
@@ -1,9 +1,11 @@
import 'package:get/get.dart';
+import 'package:get_flutter_fire/models/product.dart';
+import '../../../../services/auth_service.dart';
class CartController extends GetxController {
- //TODO: Implement CartController
+ final RxList cartItems = [].obs;
+ final RxDouble totalPrice = 0.0.obs;
- final count = 0.obs;
@override
void onInit() {
super.onInit();
@@ -19,5 +21,51 @@ class CartController extends GetxController {
super.onClose();
}
- void increment() => count.value++;
+ void increment() => totalPrice.value++;
+
+ Future signInAnonymously() async {
+ await AuthService.to.signInAnonymously();
+ update();
+ }
+
+ Future convertAnonymousAccount(String email, String password) async {
+ await AuthService.to.convertAnonymousAccount(email, password);
+ }
+
+ Future addItemToCart(Product product) async {
+ if (AuthService.to.user == null) {
+ // If the user is not signed in, sign them in anonymously
+ await signInAnonymously();
+ }
+ cartItems.add(product);
+ totalPrice.value += product.price;
+ print("Product added to cart: ${product.name}");
+ update();
+ }
+
+ Future removeItemFromCart(Product product) async {
+ cartItems.remove(product);
+ totalPrice.value -= product.price;
+ print("Product removed from cart: ${product.name}");
+ update();
+ }
+
+ Future checkout() async {
+ if (AuthService.to.user == null) {
+ // If the user is not signed in, sign them in anonymously
+ await signInAnonymously();
+ }
+ // Proceed with the checkout process
+ print("Checkout process initiated");
+ update();
+ }
+
+ void calculateTotalPrice() {
+ totalPrice.value = cartItems.fold(0, (sum, item) => sum + item.price);
+ }
+
+ void clearCart() {
+ cartItems.clear();
+ calculateTotalPrice();
+ }
}
diff --git a/lib/app/modules/cart/views/cart_view.dart b/lib/app/modules/cart/views/cart_view.dart
index 3e048c79..468ce8fd 100644
--- a/lib/app/modules/cart/views/cart_view.dart
+++ b/lib/app/modules/cart/views/cart_view.dart
@@ -1,27 +1,102 @@
import 'package:flutter/material.dart';
-
import 'package:get/get.dart';
-import 'package:get_flutter_fire/app/routes/app_pages.dart';
-import '../../../widgets/screen_widget.dart';
-import '../../../../services/auth_service.dart';
import '../controllers/cart_controller.dart';
+import 'package:get_flutter_fire/models/product.dart'; // Ensure correct path
class CartView extends GetView {
const CartView({super.key});
+
@override
Widget build(BuildContext context) {
- return ScreenWidget(
+ return Scaffold(
appBar: AppBar(
- title: Text('${AuthService.to.userName} Cart'),
+ title: const Text('Cart'),
centerTitle: true,
),
- body: const Center(
- child: Text(
- 'CartView is working',
- style: TextStyle(fontSize: 20),
- ),
- ),
- screen: screen!,
+ body: Obx(() {
+ if (controller.cartItems.isEmpty) {
+ return const Center(
+ child: Text(
+ 'Your cart is empty',
+ style: TextStyle(fontSize: 20),
+ ),
+ );
+ }
+
+ return Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Expanded(
+ child: ListView.builder(
+ itemCount: controller.cartItems.length,
+ itemBuilder: (context, index) {
+ final item = controller.cartItems[index];
+ return Card(
+ child: ListTile(
+ title: Text(item.name),
+ subtitle:
+ Text('Price: \$${item.price.toStringAsFixed(2)}'),
+ trailing: IconButton(
+ icon: const Icon(Icons.remove_circle),
+ onPressed: () {
+ _confirmRemoveItem(context, item);
+ },
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ const SizedBox(height: 20),
+ Text(
+ 'Total: \$${controller.totalPrice.toStringAsFixed(2)}',
+ style:
+ const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
+ ),
+ const SizedBox(height: 20),
+ ElevatedButton(
+ onPressed: () {
+ if (controller.cartItems.isNotEmpty) {
+ Get.toNamed('/checkout');
+ } else {
+ Get.snackbar('Cart is empty',
+ 'Add items before proceeding to checkout');
+ }
+ },
+ child: const Text('Proceed to Checkout'),
+ ),
+ ],
+ ),
+ );
+ }),
+ );
+ }
+
+ void _confirmRemoveItem(BuildContext context, Product item) {
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: const Text('Remove Item'),
+ content: const Text(
+ 'Are you sure you want to remove this item from the cart?'),
+ actions: [
+ TextButton(
+ onPressed: () => Get.back(),
+ child: const Text('Cancel'),
+ ),
+ TextButton(
+ onPressed: () {
+ controller.removeItemFromCart(item);
+ Get.back();
+ },
+ child: const Text('Remove'),
+ ),
+ ],
+ );
+ },
);
}
}
diff --git a/lib/app/modules/checkout/bindings/checkout_binding.dart b/lib/app/modules/checkout/bindings/checkout_binding.dart
index 42202b56..719208ce 100644
--- a/lib/app/modules/checkout/bindings/checkout_binding.dart
+++ b/lib/app/modules/checkout/bindings/checkout_binding.dart
@@ -1,5 +1,4 @@
import 'package:get/get.dart';
-
import '../controllers/checkout_controller.dart';
class CheckoutBinding extends Bindings {
diff --git a/lib/app/modules/checkout/controllers/checkout_controller.dart b/lib/app/modules/checkout/controllers/checkout_controller.dart
index aa1265f6..bebeadd4 100644
--- a/lib/app/modules/checkout/controllers/checkout_controller.dart
+++ b/lib/app/modules/checkout/controllers/checkout_controller.dart
@@ -1,9 +1,10 @@
import 'package:get/get.dart';
+import '../../cart/controllers/cart_controller.dart';
class CheckoutController extends GetxController {
- //TODO: Implement CheckoutController
-
+ final cartController = Get.find();
final count = 0.obs;
+
@override
void onInit() {
super.onInit();
@@ -20,4 +21,19 @@ class CheckoutController extends GetxController {
}
void increment() => count.value++;
+
+ double get totalPrice => cartController.totalPrice.value;
+
+ void checkout() {
+ if (cartController.cartItems.isEmpty) {
+ print("Cart is empty. Add items before checking out.");
+ return;
+ }
+ // Placeholder for the payment process logic
+ print(
+ "Checkout initiated with total price: \$${totalPrice.toStringAsFixed(2)}");
+
+ // Clear the cart after successful checkout
+ cartController.clearCart();
+ }
}
diff --git a/lib/app/modules/checkout/views/checkout_view.dart b/lib/app/modules/checkout/views/checkout_view.dart
index b8b17072..d7c28b43 100644
--- a/lib/app/modules/checkout/views/checkout_view.dart
+++ b/lib/app/modules/checkout/views/checkout_view.dart
@@ -1,11 +1,10 @@
import 'package:flutter/material.dart';
-
import 'package:get/get.dart';
-
import '../controllers/checkout_controller.dart';
class CheckoutView extends GetView {
const CheckoutView({super.key});
+
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -13,10 +12,23 @@ class CheckoutView extends GetView {
title: const Text('CheckoutView'),
centerTitle: true,
),
- body: const Center(
- child: Text(
- 'CheckoutView is working',
- style: TextStyle(fontSize: 20),
+ body: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Total Price: \$${controller.totalPrice.toStringAsFixed(2)}',
+ style: const TextStyle(fontSize: 24),
+ ),
+ const SizedBox(height: 20),
+ ElevatedButton(
+ onPressed: () {
+ controller.checkout();
+ },
+ child: const Text('Checkout'),
+ ),
+ ],
),
),
);
diff --git a/lib/app/modules/dashboard/controllers/dashboard_controller.dart b/lib/app/modules/dashboard/controllers/dashboard_controller.dart
index 24d91a16..4a4e65d1 100644
--- a/lib/app/modules/dashboard/controllers/dashboard_controller.dart
+++ b/lib/app/modules/dashboard/controllers/dashboard_controller.dart
@@ -1,12 +1,17 @@
import 'dart:async';
-
import 'package:get/get.dart';
class DashboardController extends GetxController {
final now = DateTime.now().obs;
+
+ final RxList