feat(plantare): UI — propose from chat, review & sign on the ledger
The viral loop, made usable end-to-end: - Propose sheet (plantare_propose_sheet.dart): from a chat with a peer (their key already in hand), pick your side, name the seed, choose what comes back (similar · non-GMO organic / work hours / other) and an optional return-by, then sign and send. Reached from the chat overflow menu; confirms "waiting for them to sign". - Plantares screen: incoming proposals show Accept & sign / Decline right on the tile; every bilateral row wears a handshake badge — awaiting signature, signed by both, or declined. Accept falls back to a gentle "offline" nudge if the proposal isn't in hand yet. - i18n: full en + es for the bilateral flow; other locales fall back to base per slang config. Wire-up only touches human copy (no jargon) and stays behind the optional PlantareService, so inventory-only builds are unaffected. Tests: propose sheet drives a real sign+send; the ledger renders the signed/awaiting badges. Fake SocialSession in your_people test gains the new transport getter. Widget tests targeted + timed. All green.
This commit is contained in:
parent
2e25e34d11
commit
f9c3dc018d
11 changed files with 2223 additions and 1459 deletions
|
|
@ -1809,6 +1809,75 @@ class Translations$plantare$en {
|
|||
|
||||
/// en: 'Commitments'
|
||||
String get sectionTitle => 'Commitments';
|
||||
|
||||
/// en: 'Propose a signed Plantaré'
|
||||
String get propose => 'Propose a signed Plantaré';
|
||||
|
||||
/// en: 'Both of you keep the same promise, signed by both — proof that this seed changed hands and will be grown out and returned.'
|
||||
String get proposeHelp => 'Both of you keep the same promise, signed by both — proof that this seed changed hands and will be grown out and returned.';
|
||||
|
||||
/// en: 'With {name}'
|
||||
String proposeTo({required Object name}) => 'With ${name}';
|
||||
|
||||
/// en: 'Proposal sent — waiting for them to sign'
|
||||
String get sent => 'Proposal sent — waiting for them to sign';
|
||||
|
||||
/// en: 'Which seed?'
|
||||
String get seedLabel => 'Which seed?';
|
||||
|
||||
/// en: 'The variety this promise is about'
|
||||
String get seedHint => 'The variety this promise is about';
|
||||
|
||||
/// en: 'What comes back?'
|
||||
String get returnKindLabel => 'What comes back?';
|
||||
|
||||
/// en: 'A similar amount of seed'
|
||||
String get returnSimilar => 'A similar amount of seed';
|
||||
|
||||
/// en: 'open-pollinated · non-GMO · organically grown'
|
||||
String get returnSimilarNote => 'open-pollinated · non-GMO · organically grown';
|
||||
|
||||
/// en: 'Some hours of work'
|
||||
String get returnWork => 'Some hours of work';
|
||||
|
||||
/// en: 'Something else'
|
||||
String get returnOther => 'Something else';
|
||||
|
||||
/// en: 'How many hours?'
|
||||
String get workHoursLabel => 'How many hours?';
|
||||
|
||||
/// en: 'Waiting for your reply'
|
||||
String get proposalsSection => 'Waiting for your reply';
|
||||
|
||||
/// en: '{name} proposes a Plantaré'
|
||||
String incomingFrom({required Object name}) => '${name} proposes a Plantaré';
|
||||
|
||||
/// en: 'Accept & sign'
|
||||
String get accept => 'Accept & sign';
|
||||
|
||||
/// en: 'Decline'
|
||||
String get declineAction => 'Decline';
|
||||
|
||||
/// en: 'Reason (optional)'
|
||||
String get declineReasonHint => 'Reason (optional)';
|
||||
|
||||
/// en: 'Signed — you both hold it now'
|
||||
String get acceptedToast => 'Signed — you both hold it now';
|
||||
|
||||
/// en: 'Declined'
|
||||
String get declinedToast => 'Declined';
|
||||
|
||||
/// en: 'Awaiting signature'
|
||||
String get badgeAwaiting => 'Awaiting signature';
|
||||
|
||||
/// en: 'Signed by both'
|
||||
String get badgeSigned => 'Signed by both';
|
||||
|
||||
/// en: 'Declined'
|
||||
String get badgeDeclined => 'Declined';
|
||||
|
||||
/// en: 'You're offline — it'll be sent when you reconnect'
|
||||
String get offline => 'You\'re offline — it\'ll be sent when you reconnect';
|
||||
}
|
||||
|
||||
// Path: handover
|
||||
|
|
@ -3020,6 +3089,31 @@ extension on Translations {
|
|||
'plantare.pickDate' => 'Pick a date',
|
||||
'plantare.clearDate' => 'Clear date',
|
||||
'plantare.sectionTitle' => 'Commitments',
|
||||
'plantare.propose' => 'Propose a signed Plantaré',
|
||||
'plantare.proposeHelp' => 'Both of you keep the same promise, signed by both — proof that this seed changed hands and will be grown out and returned.',
|
||||
'plantare.proposeTo' => ({required Object name}) => 'With ${name}',
|
||||
'plantare.sent' => 'Proposal sent — waiting for them to sign',
|
||||
'plantare.seedLabel' => 'Which seed?',
|
||||
'plantare.seedHint' => 'The variety this promise is about',
|
||||
'plantare.returnKindLabel' => 'What comes back?',
|
||||
'plantare.returnSimilar' => 'A similar amount of seed',
|
||||
'plantare.returnSimilarNote' => 'open-pollinated · non-GMO · organically grown',
|
||||
'plantare.returnWork' => 'Some hours of work',
|
||||
'plantare.returnOther' => 'Something else',
|
||||
'plantare.workHoursLabel' => 'How many hours?',
|
||||
'plantare.proposalsSection' => 'Waiting for your reply',
|
||||
'plantare.incomingFrom' => ({required Object name}) => '${name} proposes a Plantaré',
|
||||
'plantare.accept' => 'Accept & sign',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'plantare.declineAction' => 'Decline',
|
||||
'plantare.declineReasonHint' => 'Reason (optional)',
|
||||
'plantare.acceptedToast' => 'Signed — you both hold it now',
|
||||
'plantare.declinedToast' => 'Declined',
|
||||
'plantare.badgeAwaiting' => 'Awaiting signature',
|
||||
'plantare.badgeSigned' => 'Signed by both',
|
||||
'plantare.badgeDeclined' => 'Declined',
|
||||
'plantare.offline' => 'You\'re offline — it\'ll be sent when you reconnect',
|
||||
'handover.title' => 'Seeds changed hands',
|
||||
'handover.help' => 'A gift, a swap or a sale — note it down, with a return promise or without.',
|
||||
'handover.iGave' => 'I gave seeds',
|
||||
|
|
@ -3035,8 +3129,6 @@ extension on Translations {
|
|||
'sale.help' => 'Record seed you sold or bought — money, Ğ1, or any currency. A separate model from a gift or a Plantare. No commission is ever taken on seeds.',
|
||||
'sale.add' => 'Record a sale',
|
||||
'sale.empty' => 'No sales yet. Note here what you sell or buy.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'sale.iSold' => 'I sold',
|
||||
'sale.iBought' => 'I bought',
|
||||
'sale.direction' => 'Sold or bought?',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue