tane/apps/app_seeds/lib/ui/currency_quick_picks.dart
vjrj cfa1053842 feat(offers): asking price on lots, published with sale offers (schema v11)
The data model always meant sale offers to carry an informational price
(data-model §2.8, sharing-model §4.4); with offer state collapsed onto
the Lot, the price lives there. Null amount on a sell lot = 'to be
agreed' — the NIP-99 event simply omits the price tag.

- schema v11: Lots.price_amount/price_currency, guarded migration,
  schema dump + generated schema_v11 for the round-trip test
- ShareableLot/VarietyLot carry the price (sell-only in shareableLots);
  addLot/updateLot persist it and clear it when the lot leaves sale
- OffersCubit.publishLots forwards it (outbox flush picks it up free)
- lot sheet: price + currency inputs revealed only on 'For sale', with
  the €/Ğ1/hours quick-picks extracted to a shared CurrencyQuickPicks
  widget (reused by the sale sheet)
- backup JSON round-trips the new columns
- i18n share.price/priceHint in en/es/pt/ast
2026-07-11 08:00:08 +02:00

44 lines
1.3 KiB
Dart

import 'package:flutter/material.dart';
import '../i18n/strings.g.dart';
/// One-tap currency chips bound to a free-text [controller]. Ğ1 sits quietly
/// among the familiar ones — offered, never imposed — and free text still
/// takes anything else (sharing-model §6). Shared by the sale sheet, the lot
/// price field and the hand-over sheet so every money-ish input feels the same.
class CurrencyQuickPicks extends StatelessWidget {
const CurrencyQuickPicks({
required this.controller,
required this.keyPrefix,
required this.onChanged,
super.key,
});
final TextEditingController controller;
/// Namespaces the chip [Key]s (e.g. `sale` → `sale.currencyChip.€`).
final String keyPrefix;
/// Fires after a chip toggles the controller text (for `setState`).
final VoidCallback onChanged;
@override
Widget build(BuildContext context) {
final t = context.t;
return Wrap(
spacing: 8,
children: [
for (final c in ['', 'Ğ1', t.sale.hours])
ChoiceChip(
key: Key('$keyPrefix.currencyChip.$c'),
label: Text(c),
selected: controller.text.trim() == c,
onSelected: (sel) {
controller.text = sel ? c : '';
onChanged();
},
),
],
);
}
}