feat: product search screen with catalog add and success feedback

- Add product search screen (/products/search) as primary add flow;
  "Add" button on products list opens search, manual entry remains as fallback
- Add to shelf bottom sheet with AnimatedSwitcher success view (green checkmark)
  and SnackBar confirmation on the search screen via onAdded callback
- Manual add (AddProductScreen) shows SnackBar on success before popping back
- Extend AddProductScreen with optional nutrition fields (calories, protein,
  fat, carbs, fiber); auto-fills from catalog selection and auto-expands section
- Auto-upsert catalog product on backend when nutrition data is provided
  without a primary_product_id, linking the user product to the catalog
- Add fiber_per_100g field to CatalogProduct model and CreateRequest
- Add 16 new L10n keys across all 12 locales (addProduct, addManually,
  searchProducts, quantity, storageDays, addToShelf, nutritionOptional,
  calories, protein, fat, carbs, fiber, productAddedToShelf, etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
dbastrikin
2026-03-26 14:04:58 +02:00
parent 16d944c80e
commit 8d33a4eb30
40 changed files with 2167 additions and 74 deletions

View File

@@ -1029,6 +1029,126 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Processing...'**
String get processingProducts;
/// No description provided for @clearAllProducts.
///
/// In en, this message translates to:
/// **'Clear all'**
String get clearAllProducts;
/// No description provided for @clearAllConfirmTitle.
///
/// In en, this message translates to:
/// **'Clear all products?'**
String get clearAllConfirmTitle;
/// No description provided for @clearAllConfirmMessage.
///
/// In en, this message translates to:
/// **'All products will be permanently deleted.'**
String get clearAllConfirmMessage;
/// No description provided for @addManually.
///
/// In en, this message translates to:
/// **'Manually'**
String get addManually;
/// No description provided for @scan.
///
/// In en, this message translates to:
/// **'Scan'**
String get scan;
/// No description provided for @addProduct.
///
/// In en, this message translates to:
/// **'Add'**
String get addProduct;
/// No description provided for @searchProducts.
///
/// In en, this message translates to:
/// **'Search products'**
String get searchProducts;
/// No description provided for @searchProductsHint.
///
/// In en, this message translates to:
/// **'Type a product name to search or add manually'**
String get searchProductsHint;
/// No description provided for @noSearchResults.
///
/// In en, this message translates to:
/// **'No results for \"{query}\"'**
String noSearchResults(String query);
/// No description provided for @quantity.
///
/// In en, this message translates to:
/// **'Quantity'**
String get quantity;
/// No description provided for @storageDays.
///
/// In en, this message translates to:
/// **'Storage days'**
String get storageDays;
/// No description provided for @addToShelf.
///
/// In en, this message translates to:
/// **'Add to pantry'**
String get addToShelf;
/// No description provided for @errorGeneric.
///
/// In en, this message translates to:
/// **'Something went wrong'**
String get errorGeneric;
/// No description provided for @nutritionOptional.
///
/// In en, this message translates to:
/// **'Nutrition per 100g (optional)'**
String get nutritionOptional;
/// No description provided for @calories.
///
/// In en, this message translates to:
/// **'Calories'**
String get calories;
/// No description provided for @protein.
///
/// In en, this message translates to:
/// **'Protein'**
String get protein;
/// No description provided for @fat.
///
/// In en, this message translates to:
/// **'Fat'**
String get fat;
/// No description provided for @carbs.
///
/// In en, this message translates to:
/// **'Carbohydrates'**
String get carbs;
/// No description provided for @fiber.
///
/// In en, this message translates to:
/// **'Fiber'**
String get fiber;
/// No description provided for @productAddedToShelf.
///
/// In en, this message translates to:
/// **'Added to pantry'**
String get productAddedToShelf;
}
class _AppLocalizationsDelegate