second commit

This commit is contained in:
2026-07-29 11:41:53 +05:30
parent fcccf22bac
commit d72522e737
211 changed files with 19260 additions and 0 deletions

27
lib/app/app.dart Normal file
View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../core/constants/app_constants.dart';
import '../core/router/app_router.dart';
import '../core/theme/app_theme.dart';
class NearlePosApp extends ConsumerWidget {
const NearlePosApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return MaterialApp.router(
title: AppConstants.appName,
debugShowCheckedModeBanner: false,
theme: AppTheme.light,
routerConfig: ref.watch(routerProvider),
builder: (context, child) {
// A POS runs on fixed hardware; ignore OS font scaling so the dense
// billing panel can never overflow.
return MediaQuery.withNoTextScaling(
child: child ?? const SizedBox.shrink(),
);
},
);
}
}

91
lib/app/providers.dart Normal file
View File

@@ -0,0 +1,91 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../core/services/receipt_service.dart';
import '../core/services/sound_service.dart';
import '../data/datasources/local_store.dart';
import '../data/repositories/customer_repository_impl.dart';
import '../data/repositories/product_repository_impl.dart';
import '../data/datasources/remote_catalogue_source.dart';
import '../data/repositories/sync_repository_impl.dart';
import '../data/repositories/transaction_repository_impl.dart';
import '../domain/repositories/customer_repository.dart';
import '../domain/repositories/product_repository.dart';
import '../domain/repositories/sync_repository.dart';
import '../domain/repositories/transaction_repository.dart';
import '../domain/usecases/checkout_sale.dart';
/// Root data source. Overridden in tests with an in-memory double.
final localStoreProvider = Provider<LocalStore>((ref) => LocalStore.instance);
// ---------------------------------------------------------- Repositories
final productRepositoryProvider = Provider<ProductRepository>(
(ref) => ProductRepositoryImpl(ref.watch(localStoreProvider)),
);
final customerRepositoryProvider = Provider<CustomerRepository>(
(ref) => CustomerRepositoryImpl(ref.watch(localStoreProvider)),
);
final transactionRepositoryProvider = Provider<TransactionRepository>(
(ref) => TransactionRepositoryImpl(ref.watch(localStoreProvider)),
);
/// Simulated back-office endpoints. Held as singletons so the offline toggle
/// in Settings affects every call.
final remoteCatalogueProvider =
Provider<RemoteCatalogueSource>((ref) => RemoteCatalogueSource());
final remoteReportSinkProvider =
Provider<RemoteReportSink>((ref) => RemoteReportSink());
final syncRepositoryProvider = Provider<SyncRepository>(
(ref) => SyncRepositoryImpl(
ref.watch(localStoreProvider),
ref.watch(remoteCatalogueProvider),
ref.watch(remoteReportSinkProvider),
),
);
// ------------------------------------------------------------- Use cases
final checkoutSaleProvider = Provider<CheckoutSale>(
(ref) => CheckoutSale(
productRepository: ref.watch(productRepositoryProvider),
customerRepository: ref.watch(customerRepositoryProvider),
transactionRepository: ref.watch(transactionRepositoryProvider),
),
);
// -------------------------------------------------------------- Services
final soundServiceProvider =
Provider<SoundService>((ref) => SoundService.instance);
final receiptServiceProvider =
Provider<ReceiptService>((ref) => ReceiptService.instance);
// --------------------------------------------------------------- Session
class CashierSession {
const CashierSession({
required this.name,
required this.role,
required this.terminalId,
});
final String name;
final String role;
final String terminalId;
}
final cashierSessionProvider = StateProvider<CashierSession>(
(ref) => const CashierSession(
name: 'Suriya',
role: 'ADMIN',
terminalId: 'TERM-01',
),
);
/// Ticks once a minute to drive the header clock without rebuilding on every
/// frame.
final clockProvider = StreamProvider<DateTime>((ref) async* {
yield DateTime.now();
yield* Stream.periodic(const Duration(seconds: 20), (_) => DateTime.now());
});