Skip to content
59 changes: 55 additions & 4 deletions lib/features/home/providers/home_order_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,71 @@ import 'package:mostro_mobile/shared/providers/order_repository_provider.dart';

final homeOrderTypeProvider = StateProvider((ref) => OrderType.sell);

// Filter state providers
final currencyFilterProvider = StateProvider<List<String>>((ref) => []);
final paymentMethodFilterProvider = StateProvider<List<String>>((ref) => []);
final ratingFilterProvider = StateProvider<({double min, double max})>((ref) => (min: 0.0, max: 5.0));
final premiumRangeFilterProvider = StateProvider<({double min, double max})>((ref) => (min: -10.0, max: 10.0));

final filteredOrdersProvider = Provider<List<NostrEvent>>((ref) {
final allOrdersAsync = ref.watch(orderEventsProvider);
final orderType = ref.watch(homeOrderTypeProvider);
final selectedCurrencies = ref.watch(currencyFilterProvider);
final selectedPaymentMethods = ref.watch(paymentMethodFilterProvider);
final ratingRange = ref.watch(ratingFilterProvider);
final premiumRange = ref.watch(premiumRangeFilterProvider);

return allOrdersAsync.maybeWhen(
data: (allOrders) {
allOrders
.sort((o1, o2) => o1.expirationDate.compareTo(o2.expirationDate));

final filtered = allOrders.reversed
var filtered = allOrders.reversed
.where((o) => o.orderType == orderType)
.where((o) => o.status == Status.pending)
.toList();
return filtered;
.where((o) => o.status == Status.pending);

// Apply currency filter
if (selectedCurrencies.isNotEmpty) {
filtered = filtered.where((o) =>
o.currency != null && selectedCurrencies.contains(o.currency!)
);
}

// Apply payment method filter
if (selectedPaymentMethods.isNotEmpty) {
final methodsLower = selectedPaymentMethods
.where((m) => m.trim().isNotEmpty)
.map((m) => m.toLowerCase())
.toSet();
filtered = filtered.where((o) {
final pms = o.paymentMethods;
if (pms.isEmpty) return false;
return pms.any((pm) {
final pmLower = pm.toLowerCase();
return methodsLower.any(pmLower.contains);
});
});
}

// Apply rating filter
if (ratingRange.min > 0.0 || ratingRange.max < 5.0) {
filtered = filtered.where((o) =>
o.rating != null &&
o.rating!.totalRating >= ratingRange.min &&
o.rating!.totalRating <= ratingRange.max
);
}

// Apply premium/discount filter
if (premiumRange.min > -10.0 || premiumRange.max < 10.0) {
filtered = filtered.where((o) {
if (o.premium == null || o.premium!.isEmpty) return false;
final premiumValue = double.tryParse(o.premium!) ?? 0.0;
return premiumValue >= premiumRange.min && premiumValue <= premiumRange.max;
});
}
Comment thread
Catrya marked this conversation as resolved.

return filtered.toList();
},
orElse: () => [],
);
Expand Down
88 changes: 55 additions & 33 deletions lib/features/home/screens/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:mostro_mobile/features/home/widgets/order_list_item.dart';
import 'package:mostro_mobile/shared/widgets/add_order_button.dart';
import 'package:mostro_mobile/shared/widgets/bottom_nav_bar.dart';
import 'package:mostro_mobile/shared/widgets/mostro_app_bar.dart';
import 'package:mostro_mobile/shared/widgets/order_filter.dart';
import 'package:mostro_mobile/shared/widgets/custom_drawer_overlay.dart';
import 'package:mostro_mobile/generated/l10n.dart';

Expand Down Expand Up @@ -196,7 +197,6 @@ class HomeScreen extends ConsumerWidget {
child: Align(
alignment: Alignment.centerLeft,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: AppTheme.backgroundInput,
borderRadius: BorderRadius.circular(30),
Expand All @@ -209,40 +209,62 @@ class HomeScreen extends ConsumerWidget {
),
],
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const HeroIcon(
HeroIcons.funnel,
style: HeroIconStyle.outline,
color: Colors.white70,
size: 18,
),
const SizedBox(width: 8),
Text(
S.of(context)!.filter,
style: const TextStyle(
color: Colors.white70,
fontSize: 13,
fontWeight: FontWeight.w500,
letterSpacing: 0.5,
),
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 8),
height: 16,
width: 1,
color: Colors.white.withValues(alpha: 0.2),
),
Text(
S.of(context)!.offersCount(filteredOrders.length.toString()),
style: const TextStyle(
color: Colors.grey,
fontSize: 12,
fontWeight: FontWeight.normal,
child: Material(
color: Colors.transparent,
borderRadius: BorderRadius.circular(30),
child: InkWell(
onTap: () {
showDialog<void>(
context: context,
builder: (BuildContext context) {
return const Dialog(
child: OrderFilter(),
);
},
);
},
borderRadius: BorderRadius.circular(30),
splashColor: AppTheme.activeColor.withValues(alpha: 0.3),
highlightColor: AppTheme.activeColor.withValues(alpha: 0.15),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const HeroIcon(
HeroIcons.funnel,
style: HeroIconStyle.outline,
color: Colors.white70,
size: 18,
),
const SizedBox(width: 8),
Text(
S.of(context)!.filter,
style: const TextStyle(
color: Colors.white70,
fontSize: 13,
fontWeight: FontWeight.w500,
letterSpacing: 0.5,
),
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 8),
height: 16,
width: 1,
color: Colors.white.withValues(alpha: 0.2),
),
Text(
S.of(context)!.offersCount(filteredOrders.length.toString()),
style: const TextStyle(
color: Colors.grey,
fontSize: 12,
fontWeight: FontWeight.normal,
),
),
],
),
),
],
),
),
),
),
Expand Down
11 changes: 11 additions & 0 deletions lib/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -796,9 +796,20 @@


"save": "Save",
"apply": "Apply",
"selectCurrency": "Select Currency",
"noCurrencySelected": "No currency selected",

"@_comment_filter_section": "Filter section strings",
"rating": "Rating",
"reputation": "Reputation",
"premiumRange": "Premium/Discount",
"discount": "Discount",
"premium": "Premium",
"clear": "Clear",
"min": "Min",
"max": "Max",

"@_comment_timeout_messages": "Timeout notification messages",
"orderTimeoutTaker": "You didn't respond in time. The order will be republished",
"orderTimeoutMaker": "Your counterpart didn't respond in time. The order will be republished",
Expand Down
11 changes: 11 additions & 0 deletions lib/l10n/intl_es.arb
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,17 @@
"add": "Agregar",

"save": "Guardar",
"apply": "Aplicar",

"@_comment_filter_section": "Strings de la sección de filtros",
"rating": "Calificación",
"reputation": "Reputación",
"premiumRange": "Prima/Descuento",
"discount": "Descuento",
"premium": "Prima",
"clear": "Limpiar",
"min": "Mín",
"max": "Máx",
"selectCurrency": "Seleccionar Moneda",
"noCurrencySelected": "Ninguna moneda seleccionada",

Expand Down
11 changes: 11 additions & 0 deletions lib/l10n/intl_it.arb
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,17 @@
"add": "Aggiungi",

"save": "Salva",
"apply": "Applica",

"@_comment_filter_section": "Stringhe della sezione filtri",
"rating": "Valutazione",
"reputation": "Reputazione",
"premiumRange": "Premio/Sconto",
"discount": "Sconto",
"premium": "Premio",
"clear": "Cancella",
"min": "Min",
"max": "Max",
"selectCurrency": "Seleziona Valuta",
"noCurrencySelected": "Nessuna valuta selezionata",

Expand Down
Loading