Files
meezi/mobile/meezi_app/lib/features/cart/cart_state.dart
T
soroush.asadi a85890f30a chore: Flutter mobile app, CI, and dev tooling
- mobile/: Flutter/Dart merchant mobile app skeleton
- .github/: GitHub Actions CI workflows
- .dockerignore: exclude host node_modules from build context
- .cursorrules: Cursor IDE project rules
- .claude/: Claude Code project settings and launch config

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-27 21:35:27 +03:30

106 lines
2.6 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/api/api_client.dart';
import '../public/public_api.dart';
class CartLine {
CartLine({
required this.menuItemId,
required this.name,
required this.unitPrice,
this.quantity = 1,
this.notes,
});
final String menuItemId;
final String name;
final int unitPrice;
int quantity;
final String? notes;
int get lineTotal => unitPrice * quantity;
Map<String, dynamic> toOrderJson() => {
'menuItemId': menuItemId,
'quantity': quantity,
if (notes != null && notes!.isNotEmpty) 'notes': notes,
};
}
class CartState {
CartState({
this.cafeSlug,
this.cafeName,
this.tableId,
this.tableNumber,
this.lines = const [],
});
final String? cafeSlug;
final String? cafeName;
final String? tableId;
final int? tableNumber;
final List<CartLine> lines;
int get itemCount => lines.fold(0, (sum, l) => sum + l.quantity);
int get subtotal => lines.fold(0, (sum, l) => sum + l.lineTotal);
CartState copyWith({
String? cafeSlug,
String? cafeName,
String? tableId,
int? tableNumber,
List<CartLine>? lines,
}) =>
CartState(
cafeSlug: cafeSlug ?? this.cafeSlug,
cafeName: cafeName ?? this.cafeName,
tableId: tableId ?? this.tableId,
tableNumber: tableNumber ?? this.tableNumber,
lines: lines ?? this.lines,
);
}
class CartNotifier extends StateNotifier<CartState> {
CartNotifier() : super(CartState());
void setContext({
required String slug,
required String cafeName,
String? tableId,
int? tableNumber,
}) {
state = CartState(
cafeSlug: slug,
cafeName: cafeName,
tableId: tableId,
tableNumber: tableNumber,
lines: state.lines,
);
}
void addItem(CartLine line) {
final existing = state.lines.where((l) => l.menuItemId == line.menuItemId).toList();
if (existing.isNotEmpty) {
existing.first.quantity += line.quantity;
state = state.copyWith(lines: [...state.lines]);
return;
}
state = state.copyWith(lines: [...state.lines, line]);
}
void removeItem(String menuItemId) {
state = state.copyWith(
lines: state.lines.where((l) => l.menuItemId != menuItemId).toList(),
);
}
void clear() => state = CartState();
}
final apiClientProvider = Provider<ApiClient>((ref) => ApiClient());
final publicApiProvider = Provider<PublicApi>((ref) => PublicApi(ref.watch(apiClientProvider)));
final cartProvider = StateNotifierProvider<CartNotifier, CartState>((ref) => CartNotifier());