Initial commit of Flutter project

This commit is contained in:
2025-09-19 11:30:38 +05:30
parent 1f0ec17edc
commit 4a9ae0a3b3
28 changed files with 2033 additions and 594 deletions

View File

@@ -1,41 +1,103 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:glowwheels/constants/api.dart';
import 'package:glowwheels/models/order_model.dart';
import 'package:http/http.dart' as http;
import '../models/order_model.dart';
import '../models/serviceboy_model.dart';
class OrderProvider with ChangeNotifier {
final List<Order> _orders = [
Order(
customerName: "Ankit Ghosh",
mobileNumber: "8617015476",
serviceType: "Doorstep Service",
service: "Foam Wash",
price: "₹ 104",
time: "10:00 - 11:00 AM",
date: "2025-05-28",
carName: "Mahindra XUV 700",
status: "Confirmed",
imagePath: "assets/images/car.jpg",
),
Order(
customerName: "Ravi Kumar",
mobileNumber: "9876543210",
serviceType: "Workshop",
service: "Interior Cleaning",
price: "₹ 150",
time: "12:00 - 1:00 PM",
date: "2025-05-29",
carName: "Hyundai Creta",
status: "Pending",
imagePath: "assets/images/bike.png",
),
// Add more sample orders if needed
];
class OrdersProvider with ChangeNotifier {
List<Order> _orders = [];
bool _isLoading = false;
bool _isRefreshing = false;
String? _errorMessage;
List<Order> get orders => _orders;
bool get isLoading => _isLoading;
bool get isRefreshing => _isRefreshing;
String? get errorMessage => _errorMessage;
void assignServiceBoy(int index, ServiceBoy boy) {
_orders[index].assignedBoy = boy;
Future<void> fetchOrders(String shopId, {bool refresh = false}) async {
final ordersUri = Uri.parse(ApiConstants.ordersByShop(shopId));
if (refresh) {
_isRefreshing = true;
} else {
_isLoading = true;
}
notifyListeners();
try {
final response = await http.get(ordersUri);
if (response.statusCode == 200) {
final data = json.decode(response.body);
if (data['success'] == true) {
final List<dynamic> ordersJson = data['orders'];
_orders = ordersJson.map((orderJson) => Order.fromJson(orderJson)).toList();
_errorMessage = null;
} else {
_errorMessage = 'Failed to fetch orders';
}
} else {
_errorMessage = 'Server error: ${response.statusCode}';
}
} catch (e) {
_errorMessage = 'An error occurred: $e';
}
_isLoading = false;
_isRefreshing = false;
notifyListeners();
}
Future<void> assignServiceBoyToOrder({
required String orderId,
required String serviceBoyId,
required String shopId,
}) async {
final assignUri = Uri.parse(ApiConstants.assignServiceBoy(orderId));
try {
final response = await http.put(
assignUri,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'serviceBoyId': serviceBoyId}),
);
if (response.statusCode == 200) {
print('Successfully assigned service boy');
} else {
print('Failed to assign service boy: ${response.statusCode}');
}
} catch (e) {
print('Error assigning service boy: $e');
}
}
Future<void> updateOrderStatus({
required String orderId,
required String status,
}) async {
final updateStatusUri = Uri.parse(ApiConstants.updateOrderStatusByAdmin(orderId));
try {
final response = await http.put(
updateStatusUri,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'status': status}),
);
if (response.statusCode == 200) {
final index = _orders.indexWhere((o) => o.id == orderId);
if (index != -1) {
_orders[index] = _orders[index].copyWith(status: status);
notifyListeners();
}
} else {
print('Failed to update status: ${response.statusCode}');
}
} catch (e) {
print('Error updating order status: $e');
}
}
}

View File

@@ -1,41 +1,152 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import '../models/serviceboy_model.dart';
class ServiceBoyProvider extends ChangeNotifier {
List<ServiceBoy> _serviceBoys = [
ServiceBoy(name: 'John Doe', phone: '9875643210'),
ServiceBoy(name: 'Amit Raj', phone: '9765432180'),
ServiceBoy(name: 'Manoj Sinha', phone: '9543219876'),
];
import 'package:glowwheels/constants/api.dart';
import 'package:http/http.dart' as http;
import 'package:glowwheels/models/serviceboy_model.dart';
class ServiceBoyProvider with ChangeNotifier {
List<ServiceBoy> _serviceBoys = [];
ServiceBoy? _selectedBoy;
bool _isLoading = false;
List<ServiceBoy> get serviceBoys => _serviceBoys;
ServiceBoy? get selectedBoy => _selectedBoy;
bool get isLoading => _isLoading;
// Add a new service boy
void addServiceBoy(ServiceBoy boy) {
_serviceBoys.add(boy);
/// Fetch service boys by shop ID
Future<void> fetchServiceBoys(String shopId) async {
_isLoading = true;
notifyListeners();
final serviceBoyListUri = Uri.parse(ApiConstants.serviceBoysByShop(shopId));
try {
final response = await http.get(serviceBoyListUri);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
final List<dynamic> boysJson = data['data']['serviceBoy'];
_serviceBoys = boysJson.map((json) => ServiceBoy.fromJson(json)).toList();
print('fetched service boys');
print (_serviceBoys);
notifyListeners();
} else {
print('Failed to fetch service boys: ${response.statusCode}');
}
} catch (e) {
print('Error fetching service boys: $e');
}
_isLoading = false;
notifyListeners();
}
// Edit an existing service boy
void editServiceBoy(int index, ServiceBoy updatedBoy) {
if (index >= 0 && index < _serviceBoys.length) {
_serviceBoys[index] = updatedBoy;
notifyListeners();
/// Fetch a single service boy by ID
Future<ServiceBoy?> fetchServiceBoyById(String serviceBoyId) async {
final serviceBoyUri = Uri.parse(ApiConstants.serviceBoyDetails(serviceBoyId));
try {
final response = await http.get(serviceBoyUri);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
final boyJson = data['data']; // Adjust if API wraps in `data`
final serviceBoy = ServiceBoy.fromJson(boyJson);
return serviceBoy;
} else {
print('Failed to fetch service boy: ${response.statusCode}');
}
} catch (e) {
print('Error fetching service boy: $e');
}
return null;
}
/// Add new service boy to shop
Future<void> addServiceBoy(String shopId, String name,String phone) async {
print('add api called');
print(name+'Phone '+phone.toString());
final addServiceBoyUri = Uri.parse(ApiConstants.addServiceBoy);
final body = jsonEncode({
'shopId': shopId,
'serviceBoy': [
{
'name': name,
'phone':phone,
}
]
});
try {
final response = await http.post(
addServiceBoyUri,
headers: {'Content-Type': 'application/json'},
body: body,
);
print('add service boy response '+response.statusCode.toString());
if (response.statusCode == 200) {
await fetchServiceBoys(shopId); // refresh list
} else {
print('Failed to add service boy: ${response.statusCode}');
}
} catch (e) {
print('Error adding service boy: $e');
}
}
// Delete a service boy
void deleteServiceBoy(int index) {
if (index >= 0 && index < _serviceBoys.length) {
_serviceBoys.removeAt(index);
notifyListeners();
/// Edit service boy phone
Future<void> editServiceBoy(
String serviceBoyId,
String updatedName,
String updatedPhone,
String shopId,
) async {
final serviceBoyUri = Uri.parse(ApiConstants.serviceBoyDetails(serviceBoyId));
// Build request body only with non-empty fields
final Map<String, dynamic> data = {};
if (updatedName.isNotEmpty) data['name'] = updatedName;
if (updatedPhone.isNotEmpty) data['phone'] = updatedPhone;
if (data.isEmpty) {
print('No fields to update.');
return;
}
try {
final response = await http.put(
serviceBoyUri,
headers: {'Content-Type': 'application/json'},
body: jsonEncode(data),
);
if (response.statusCode == 200) {
print('Service boy updated successfully');
await fetchServiceBoys(shopId); // Refresh list
} else {
print('Failed to update service boy: ${response.statusCode}');
print('Response body: ${response.body}');
}
} catch (e) {
print('Error updating service boy: $e');
}
}
// Assign a selected service boy (for dialogs)
/// Delete a service boy
Future<void> deleteServiceBoy(String serviceBoyId, String shopId) async {
final serviceBoyUri = Uri.parse(ApiConstants.serviceBoyDetails(serviceBoyId));
try {
final response = await http.delete(serviceBoyUri);
if (response.statusCode == 200) {
await fetchServiceBoys(shopId); // refresh list
} else {
print('Failed to delete service boy: ${response.statusCode}');
}
} catch (e) {
print('Error deleting service boy: $e');
}
}
// Select a service boy
void selectBoy(ServiceBoy boy) {
_selectedBoy = boy;
notifyListeners();

View File

@@ -0,0 +1,40 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:glowwheels/constants/api.dart';
import 'package:glowwheels/models/shop_profile_model.dart';
import 'package:http/http.dart' as http;
class ShopProfileProvider with ChangeNotifier {
ShopProfileModel? _shopProfile;
bool _isLoading = false;
String? _errorMessage;
ShopProfileModel? get shopProfile => _shopProfile;
bool get isLoading => _isLoading;
String? get errorMessage => _errorMessage;
Future<void> fetchShopProfile(String shopId) async {
_isLoading = true;
_errorMessage = null;
notifyListeners();
final shopUri = Uri.parse(ApiConstants.shopDetails(shopId));
try {
final response = await http.get(shopUri);
if (response.statusCode == 200) {
final data = json.decode(response.body);
_shopProfile = ShopProfileModel.fromJson(data);
} else {
_errorMessage = 'Failed to load shop profile. Status code: ${response.statusCode}';
}
} catch (e) {
_errorMessage = 'An error occurred: $e';
} finally {
_isLoading = false;
notifyListeners();
}
}
}

View File

@@ -1,52 +1,98 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:glowwheels/constants/api.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
import '../models/shop_model.dart';
class ShopProvider with ChangeNotifier {
ShopModel? _shop;
ShopModel? get shop => _shop;
String? _token;
final String _boxName = 'shopBox';
ShopModel? get shop => _shop;
String? get token => _token;
final String _shopBox = 'shopBox';
final String _tokenBox = 'tokenBox';
ShopProvider() {
_loadOrCreateDummyShop();
_loadShopAndTokenFromHive();
}
void _loadOrCreateDummyShop() async {
final box = await Hive.openBox<ShopModel>(_boxName);
if (box.isNotEmpty) {
_shop = box.getAt(0);
} else {
// Dummy data
_shop = ShopModel(
id: '1',
shopName: "Omkara Car Wash Center",
email: "omkara@gmail.com",
mobile: "8617019854",
image: "assets/images/shop_image.jpg",
address: "Bidhannagar, Kolkata, pin-700017",
void _loadShopAndTokenFromHive() async {
final shopBox = await Hive.openBox<ShopModel>(_shopBox);
_shop = shopBox.get('shop');
final tokenBox = await Hive.openBox<String>(_tokenBox);
_token = tokenBox.get('token');
notifyListeners();
}
String? getShopId(BuildContext context) {
return Provider.of<ShopProvider>(context, listen: false).shop?.user.id;
}
Future<bool> login(String email, String password) async {
final loginUri = Uri.parse(ApiConstants.loginUrl);
try {
final response = await http.post(
loginUri,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'email': email, 'password': password}),
);
await box.add(_shop!);
print('Response code: ${response.statusCode}');
print('Response body: ${response.body}');
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
final shopModel = ShopModel.fromJson(data);
final shopBox = await Hive.openBox<ShopModel>(_shopBox);
final tokenBox = await Hive.openBox<String>(_tokenBox);
await shopBox.put('shop', shopModel);
await tokenBox.put('token', shopModel.token);
_shop = shopModel;
_token = shopModel.token;
notifyListeners();
return true;
} else {
print('HTTP Error: ${response.statusCode}');
return false;
}
} catch (e) {
print('Login Exception: $e');
return false;
}
notifyListeners();
}
Future<void> setShop(ShopModel shop) async {
_shop = shop;
notifyListeners();
final box = await Hive.openBox<ShopModel>(_boxName);
await box.clear(); // Keep only one shop
await box.add(shop);
}
Future<void> logout() async {
_shop = null;
_token = null;
notifyListeners();
final box = await Hive.openBox<ShopModel>(_boxName);
await box.clear();
final shopBox = await Hive.openBox<ShopModel>(_shopBox);
await shopBox.clear();
final tokenBox = await Hive.openBox<String>(_tokenBox);
await tokenBox.clear();
}
void setShop(ShopModel shop) {
_shop = shop;
notifyListeners();
}
void setToken(String token) {
_token = token;
notifyListeners();
}
}