INFRA: Set Up Project.

This commit is contained in:
2025-11-28 11:10:49 +05:00
commit c798279f7d
609 changed files with 77436 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
import 'dart:async';
import 'dart:developer';
import 'package:customer/constant/constant.dart';
import 'package:customer/models/cart_product_model.dart';
import 'package:customer/themes/custom_dialog_box.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'database_helper.dart';
class CartProvider with ChangeNotifier {
final _cartStreamController = StreamController<List<CartProductModel>>.broadcast();
List<CartProductModel> _cartItems = [];
Stream<List<CartProductModel>> get cartStream => _cartStreamController.stream;
CartProvider() {
_initCart();
}
Future<void> _initCart() async {
_cartItems = await DatabaseHelper.instance.fetchCartProducts();
_cartStreamController.sink.add(_cartItems);
}
Future<void> addToCart(BuildContext context, CartProductModel product, int quantity) async {
_cartItems = await DatabaseHelper.instance.fetchCartProducts();
if ((_cartItems.where((item) => item.id == product.id)).isNotEmpty) {
var index = _cartItems.indexWhere((item) => item.id == product.id);
_cartItems[index].quantity = quantity;
if (product.extras != null || product.extras!.isNotEmpty) {
_cartItems[index].extras = product.extras;
_cartItems[index].extrasPrice = product.extrasPrice;
} else {
_cartItems[index].extras = [];
_cartItems[index].extrasPrice = "0";
}
await DatabaseHelper.instance.updateCartProduct(_cartItems[index]);
} else {
if (_cartItems.isEmpty || _cartItems.where((item) => item.vendorID == product.vendorID).isNotEmpty) {
product.quantity = quantity;
_cartItems.add(product);
cartItem.add(product);
await DatabaseHelper.instance.insertCartProduct(product);
log("===> insert");
} else {
showDialog(
context: context,
builder: (BuildContext context) {
return CustomDialogBox(
title: "Alert".tr,
descriptions: "Your cart already contains items from another restaurant. Would you like to replace them with items from this restaurant instead?".tr,
positiveString: "Add".tr,
negativeString: "Cancel".tr,
positiveClick: () async {
cartItem.clear();
_cartItems.clear();
DatabaseHelper.instance.deleteAllCartProducts();
addToCart(context, product, quantity);
Get.back();
},
negativeClick: () {
Get.back();
},
img: null,
);
},
);
}
}
_initCart();
}
Future<void> removeFromCart(CartProductModel product, int quantity) async {
_cartItems = await DatabaseHelper.instance.fetchCartProducts();
var index = _cartItems.indexWhere((item) => item.id == product.id);
if (index >= 0) {
_cartItems[index].quantity = quantity;
if (_cartItems[index].quantity == 0) {
await DatabaseHelper.instance.deleteCartProduct(product.id!);
_cartItems.removeAt(index);
cartItem.removeAt(index);
} else {
await DatabaseHelper.instance.updateCartProduct(_cartItems[index]);
}
}
_initCart();
}
Future<void> clearDatabase() async {
_cartItems.clear();
cartItem.clear();
_cartStreamController.sink.add(_cartItems);
}
}

View File

@@ -0,0 +1,106 @@
import 'dart:convert';
import 'dart:developer';
import 'package:customer/constant/constant.dart';
import 'package:customer/models/cart_product_model.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static final DatabaseHelper instance = DatabaseHelper._init();
static Database? _database;
DatabaseHelper._init();
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDB('cart.db');
return _database!;
}
Future<Database> _initDB(String filePath) async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, filePath);
return await openDatabase(
path,
version: 1,
onCreate: _createDB,
);
}
Future _createDB(Database db, int version) async {
// const idType = 'TEXT PRIMARY KEY';
const textType = 'TEXT NOT NULL';
const intType = 'INTEGER NOT NULL';
await db.execute('''
CREATE TABLE cart_products (
id $textType,
category_id $textType,
name $textType,
photo $textType,
price $textType,
discountPrice $textType,
vendorID $textType,
quantity $intType,
extras_price $textType,
extras $textType,
variant_info $textType NULL
)
''');
print('Table cart_products created'); // Debugging
}
Future<void> insertCartProduct(CartProductModel product) async {
log(product.toJson().toString());
final db = await instance.database;
await db.insert(
'cart_products',
product.toJson()
..['variant_info'] = jsonEncode(product.variantInfo)
..['extras'] = jsonEncode(product.extras),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<List<CartProductModel>> fetchCartProducts() async {
final db = await instance.database;
final maps = await db.query('cart_products');
return List.generate(maps.length, (i) {
return CartProductModel.fromJson(maps[i]);
});
}
Future<void> updateCartProduct(CartProductModel product) async {
log(product.toJson().toString());
final db = await instance.database;
await db.update(
'cart_products',
product.toJson()
..['variant_info'] = jsonEncode(product.variantInfo)
..['extras'] = jsonEncode(product.extras),
where: 'id = ?',
whereArgs: [product.id],
);
}
Future<void> deleteCartProduct(String id) async {
final db = await instance.database;
await db.delete(
'cart_products',
where: 'id = ?',
whereArgs: [id],
);
}
Future close() async {
final db = await instance.database;
db.close();
}
Future<void> deleteAllCartProducts() async {
final db = await database;
cartItem.clear();
await db.delete('cart_products');
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../lang/app_en.dart';
class LocalizationService extends Translations {
// Default locale
static const locale = Locale('en', 'US');
static final locales = [const Locale('en')];
// Keys and their translations
// Translations are separated maps in `lang` file
@override
Map<String, Map<String, String>> get keys => {'en_US': enUS};
// Gets locale from language, and updates the locale
void changeLocale(String lang) {
Get.updateLocale(Locale(lang));
}
}

View File

@@ -0,0 +1,109 @@
import 'dart:convert';
import 'dart:developer';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
Future<void> firebaseMessageBackgroundHandle(RemoteMessage message) async {
log("BackGround Message :: ${message.messageId}");
}
class NotificationService {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> initInfo() async {
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
var request = await FirebaseMessaging.instance.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
if (request.authorizationStatus == AuthorizationStatus.authorized ||
request.authorizationStatus == AuthorizationStatus.provisional) {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
var iosInitializationSettings = const DarwinInitializationSettings();
final InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: iosInitializationSettings);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onDidReceiveNotificationResponse: (payload) {});
setupInteractedMessage();
}
}
Future<void> setupInteractedMessage() async {
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
FirebaseMessaging.onBackgroundMessage(
(message) => firebaseMessageBackgroundHandle(message));
}
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
log("::::::::::::onMessage:::::::::::::::::");
if (message.notification != null) {
log(message.notification.toString());
display(message);
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
log("::::::::::::onMessageOpenedApp:::::::::::::::::");
if (message.notification != null) {
log(message.notification.toString());
}
});
log("::::::::::::Permission authorized:::::::::::::::::");
await FirebaseMessaging.instance.subscribeToTopic("customer");
}
static Future<String?>? getToken() async {
String? token = await FirebaseMessaging.instance.getToken();
return token;
}
void display(RemoteMessage message) async {
log('Got a message whilst in the foreground!');
log('Message data: ${message.notification!.body.toString()}');
try {
AndroidNotificationChannel channel = const AndroidNotificationChannel(
'0',
'goRide-customer',
description: 'Show QuickLAI Notification',
importance: Importance.max,
);
AndroidNotificationDetails notificationDetails =
AndroidNotificationDetails(channel.id, channel.name,
channelDescription: 'your channel Description',
importance: Importance.high,
priority: Priority.high,
ticker: 'ticker');
const DarwinNotificationDetails darwinNotificationDetails =
DarwinNotificationDetails(
presentAlert: true, presentBadge: true, presentSound: true);
NotificationDetails notificationDetailsBoth = NotificationDetails(
android: notificationDetails, iOS: darwinNotificationDetails);
await FlutterLocalNotificationsPlugin().show(
0,
message.notification!.title,
message.notification!.body,
notificationDetailsBoth,
payload: jsonEncode(message.data),
);
} on Exception catch (e) {
log(e.toString());
}
}
}

View File

@@ -0,0 +1,108 @@
import 'dart:convert';
import 'package:customer/constant/constant.dart';
import 'package:customer/models/notification_model.dart';
import 'package:customer/service/fire_store_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'package:googleapis_auth/auth_io.dart';
class SendNotification {
static final _scopes = ['https://www.googleapis.com/auth/firebase.messaging'];
static Future getCharacters() {
return http.get(Uri.parse(Constant.jsonNotificationFileURL.toString()));
}
static Future<String> getAccessToken() async {
Map<String, dynamic> jsonData = {};
await getCharacters().then((response) {
jsonData = json.decode(response.body);
});
final serviceAccountCredentials = ServiceAccountCredentials.fromJson(jsonData);
final client = await clientViaServiceAccount(serviceAccountCredentials, _scopes);
return client.credentials.accessToken.data;
}
static Future<bool> sendFcmMessage(String type, String token, Map<String, dynamic>? payload) async {
print(type);
try {
final String accessToken = await getAccessToken();
debugPrint("accessToken=======>");
debugPrint(accessToken);
NotificationModel? notificationModel = await FireStoreUtils.getNotificationContent(type);
final response = await http.post(
Uri.parse('https://fcm.googleapis.com/v1/projects/${Constant.senderId}/messages:send'),
headers: <String, String>{'Content-Type': 'application/json', 'Authorization': 'Bearer $accessToken'},
body: jsonEncode(<String, dynamic>{
'message': {
'token': token,
'notification': {'body': notificationModel?.message ?? '', 'title': notificationModel?.subject ?? ''},
'data': payload,
},
}),
);
debugPrint("Notification=======>");
debugPrint(response.statusCode.toString());
debugPrint(response.body);
return true;
} catch (e) {
debugPrint(e.toString());
return false;
}
}
static Future<bool> sendOneNotification({required String token, required String title, required String body, required Map<String, dynamic> payload}) async {
try {
final String accessToken = await getAccessToken();
debugPrint("accessToken=======>");
debugPrint(accessToken);
final response = await http.post(
Uri.parse('https://fcm.googleapis.com/v1/projects/${Constant.senderId}/messages:send'),
headers: <String, String>{'Content-Type': 'application/json', 'Authorization': 'Bearer $accessToken'},
body: jsonEncode(<String, dynamic>{
'message': {
'token': token,
'notification': {'body': body, 'title': title},
'data': payload,
},
}),
);
debugPrint("Notification=======>");
debugPrint(response.statusCode.toString());
debugPrint(response.body);
return true;
} catch (e) {
debugPrint(e.toString());
return false;
}
}
static Future<bool> sendChatFcmMessage(String title, String message, String token, Map<String, dynamic>? payload) async {
try {
final String accessToken = await getAccessToken();
final response = await http.post(
Uri.parse('https://fcm.googleapis.com/v1/projects/${Constant.senderId}/messages:send'),
headers: <String, String>{'Content-Type': 'application/json', 'Authorization': 'Bearer $accessToken'},
body: jsonEncode(<String, dynamic>{
'message': {
'token': token,
'notification': {'body': message, 'title': title},
'data': payload,
},
}),
);
debugPrint("Notification=======>");
debugPrint(response.statusCode.toString());
debugPrint(response.body);
return true;
} catch (e) {
print(e);
return false;
}
}
}