feat(shell): home menu + navigation drawer (mockups 02/03)

The app now opens on a main menu instead of straight into the list:
- HomeScreen (mockup 02): sprout logo over a faint seed-glyph watermark, with
  big "Your inventory" (→ /inventory) and "Open market" (Block 2, "coming soon")
  destinations.
- AppDrawer (mockup 03): Inventory is live; the social items (market, profile,
  chat, wishlist, following, settings) are shown disabled with a "coming soon"
  tag so the roadmap is visible. Drawer is available on home and inventory.
- Routing: / → home, /inventory → list, /variety/:id → detail.

Tests: home shows the menu + navigates; drawer opens + navigates. quick-add flow
updated to go home → inventory. 50 green; Linux runs.
This commit is contained in:
vjrj 2026-07-08 12:22:42 +02:00
parent 17073dd560
commit 02a9d5bf39
11 changed files with 472 additions and 8 deletions

View file

@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:tane/app.dart';
import 'package:tane/i18n/strings.g.dart';
import '../support/test_support.dart';
void main() {
Widget app(db) => TranslationProvider(
child: TaneApp(
repository: newTestRepository(db),
species: newTestSpeciesRepository(db),
),
);
testWidgets('home shows the menu and navigates to inventory', (tester) async {
LocaleSettings.setLocaleSync(AppLocale.en);
final db = newTestDatabase();
addTearDown(db.close);
await tester.pumpWidget(app(db));
await tester.pumpAndSettle();
expect(find.text('Your inventory'), findsOneWidget);
expect(find.text('Open market'), findsOneWidget);
expect(find.text('Coming soon'), findsOneWidget); // market is Block 2
await tester.tap(find.byKey(const Key('home.inventory')));
await tester.pumpAndSettle();
expect(find.text('No seeds yet. Tap + to add your first.'), findsOneWidget);
await disposeTree(tester);
});
testWidgets('drawer opens and its Inventory item navigates', (tester) async {
LocaleSettings.setLocaleSync(AppLocale.en);
final db = newTestDatabase();
addTearDown(db.close);
await tester.pumpWidget(app(db));
await tester.pumpAndSettle();
await tester.tap(find.byIcon(Icons.menu)); // hamburger
await tester.pumpAndSettle();
// Social destinations are shown but disabled.
expect(find.text('Your profile'), findsOneWidget);
await tester.tap(find.text('Inventory')); // active drawer item
await tester.pumpAndSettle();
expect(find.text('No seeds yet. Tap + to add your first.'), findsOneWidget);
await disposeTree(tester);
});
}

View file

@ -24,6 +24,10 @@ void main() {
);
await tester.pumpAndSettle();
// Home inventory.
await tester.tap(find.byKey(const Key('home.inventory')));
await tester.pumpAndSettle();
// Starts empty.
expect(
find.text('No seeds yet. Tap + to add your first.'),