feat(block2): market screen — discover seeds near you (offers UI)
Wires the 'coming soon' market card to a real discovery screen (mockups 04/05): - MarketScreen: opens an OfferTransport lazily; local-first, so it degrades to a human 'set up sharing' prompt when no relay/area is set or the net is down. - Discovers offers by the saved coarse area, lists them with human reciprocity labels (gift/swap/for sale), 'near you' (never exact location), price only for sales. Config sheet to set area + community servers (no bundled public relays). - Threaded via TaneApp(social, socialSettings) — null keeps the card 'coming soon' (so Block 1 tests pass unchanged); main wires it live. - i18n en/es/pt (market.*), reuses share.* for type labels. 3 market widget tests + home tests green; app_seeds analyzes clean.
This commit is contained in:
parent
528b499209
commit
c696956ee2
8 changed files with 637 additions and 16 deletions
|
|
@ -11,7 +11,11 @@ import 'theme.dart';
|
|||
/// to action and "Open market" (Block 2) as a disabled outlined card. The
|
||||
/// hamburger opens [AppDrawer].
|
||||
class HomeScreen extends StatelessWidget {
|
||||
const HomeScreen({super.key});
|
||||
const HomeScreen({this.marketEnabled = false, super.key});
|
||||
|
||||
/// When the Block 2 social layer is wired, the market becomes a live
|
||||
/// destination; otherwise it stays a disabled "coming soon" card.
|
||||
final bool marketEnabled;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -77,10 +81,14 @@ class HomeScreen extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
_OutlinedMenuCard(
|
||||
key: const Key('home.market'),
|
||||
icon: Icons.storefront_outlined,
|
||||
label: t.home.openMarket,
|
||||
subtitle: t.home.openMarketSubtitle,
|
||||
tag: t.common.comingSoon,
|
||||
tag: marketEnabled ? null : t.common.comingSoon,
|
||||
onTap: marketEnabled
|
||||
? () => context.go('/market')
|
||||
: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
@ -151,17 +159,24 @@ class _OutlinedMenuCard extends StatelessWidget {
|
|||
required this.icon,
|
||||
required this.label,
|
||||
required this.subtitle,
|
||||
required this.tag,
|
||||
this.tag,
|
||||
this.onTap,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
final String label;
|
||||
final String subtitle;
|
||||
final String tag;
|
||||
|
||||
/// A small trailing tag (e.g. "coming soon"); omitted for live cards.
|
||||
final String? tag;
|
||||
|
||||
/// When set, the card is tappable; otherwise it reads as disabled.
|
||||
final VoidCallback? onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
final card = Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
|
|
@ -183,18 +198,31 @@ class _OutlinedMenuCard extends StatelessWidget {
|
|||
subtitleColor: seedMuted,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
tag.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFB3BDA8),
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w500,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
if (tag != null)
|
||||
Text(
|
||||
tag!.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFB3BDA8),
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w500,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
)
|
||||
else if (onTap != null)
|
||||
const Icon(Icons.chevron_right, color: seedMuted),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (onTap == null) return card;
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
child: card,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue