Improve snackbar styling and fix business switching
Snackbar Improvements: - All snackbars now have colored backgrounds (green/red/orange/blue) - Added icons to snackbar messages (check_circle, error, warning, info) - Floating behavior with bottom margin to avoid obscuring action buttons - Consistent styling across menu_browse, cart_view, and login screens App State Fixes: - Clear cartItemCount when switching businesses (setBusiness, setServicePoint, setBusinessAndServicePoint, clearAll) - Prevents stale cart count showing after switching restaurants 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
846461bf29
commit
924367c70e
8 changed files with 99 additions and 137 deletions
|
|
@ -1,5 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<foreground>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_launcher_foreground"
|
||||
android:inset="25%" />
|
||||
</foreground>
|
||||
</adaptive-icon>
|
||||
|
|
|
|||
|
|
@ -1,122 +1 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
{"images":[{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@3x.png","scale":"3x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"Icon-App-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"Icon-App-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}}
|
||||
|
|
@ -40,6 +40,7 @@ class AppState extends ChangeNotifier {
|
|||
|
||||
_cartOrderId = null;
|
||||
_cartOrderUuid = null;
|
||||
_cartItemCount = 0;
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
@ -49,6 +50,7 @@ class AppState extends ChangeNotifier {
|
|||
|
||||
_cartOrderId = null;
|
||||
_cartOrderUuid = null;
|
||||
_cartItemCount = 0;
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
@ -66,6 +68,7 @@ class AppState extends ChangeNotifier {
|
|||
|
||||
_cartOrderId = null;
|
||||
_cartOrderUuid = null;
|
||||
_cartItemCount = 0;
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
@ -122,6 +125,7 @@ class AppState extends ChangeNotifier {
|
|||
|
||||
_cartOrderId = null;
|
||||
_cartOrderUuid = null;
|
||||
_cartItemCount = 0;
|
||||
|
||||
_activeOrderId = null;
|
||||
_activeOrderStatusId = null;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../app/app_state.dart';
|
||||
|
|
@ -204,8 +204,16 @@ class _CartViewScreenState extends State<CartViewScreen> {
|
|||
if (paymentResult.error != 'Payment cancelled') {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(paymentResult.error ?? 'Payment failed'),
|
||||
content: Row(
|
||||
children: [
|
||||
Icon(Icons.error, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Expanded(child: Text(paymentResult.error ?? 'Payment failed')),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.red,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
margin: const EdgeInsets.only(bottom: 80, left: 16, right: 16),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -230,10 +238,17 @@ class _CartViewScreenState extends State<CartViewScreen> {
|
|||
// This works even after the cart screen is popped
|
||||
rootScaffoldMessengerKey.currentState?.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(update.message),
|
||||
content: Row(
|
||||
children: [
|
||||
Icon(Icons.notifications_active, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Expanded(child: Text(update.message)),
|
||||
],
|
||||
),
|
||||
backgroundColor: _getStatusColorStatic(update.statusId),
|
||||
duration: const Duration(seconds: 5),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
margin: const EdgeInsets.only(bottom: 80, left: 16, right: 16),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
@ -247,11 +262,21 @@ class _CartViewScreenState extends State<CartViewScreen> {
|
|||
// Show success message
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
content: const Row(
|
||||
children: [
|
||||
Icon(Icons.check_circle, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Payment successful! Order placed. You'll receive notifications as your order is prepared.",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.green,
|
||||
duration: const Duration(seconds: 5),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
margin: const EdgeInsets.only(bottom: 80, left: 16, right: 16),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
@ -263,8 +288,16 @@ class _CartViewScreenState extends State<CartViewScreen> {
|
|||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Error: ${e.toString()}'),
|
||||
content: Row(
|
||||
children: [
|
||||
const Icon(Icons.error, color: Colors.white),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: Text('Error: ${e.toString()}')),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.red,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
margin: const EdgeInsets.only(bottom: 80, left: 16, right: 16),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import "package:flutter/material.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:provider/provider.dart";
|
||||
|
||||
import "../app/app_router.dart";
|
||||
|
|
@ -185,7 +185,16 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||
onPressed: _isLoading ? null : () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text("Registration not yet implemented"),
|
||||
content: Row(
|
||||
children: [
|
||||
Icon(Icons.info, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Text("Registration not yet implemented"),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.blue,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
margin: EdgeInsets.only(bottom: 80, left: 16, right: 16),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -736,7 +736,18 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
|
||||
if (_businessId == null || _servicePointId == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("Missing required information")),
|
||||
const SnackBar(
|
||||
content: Row(
|
||||
children: [
|
||||
Icon(Icons.warning, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Text("Missing required information"),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
margin: EdgeInsets.only(bottom: 80, left: 16, right: 16),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -808,13 +819,35 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
: "Added ${item.name} with ${selectedModifierIds.length} customizations (${cart.itemCount} item${cart.itemCount == 1 ? '' : 's'})";
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(message)),
|
||||
SnackBar(
|
||||
content: Row(
|
||||
children: [
|
||||
const Icon(Icons.check_circle, color: Colors.white),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: Text(message)),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.green,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
margin: const EdgeInsets.only(bottom: 80, left: 16, right: 16),
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text("Error adding to cart: $e")),
|
||||
SnackBar(
|
||||
content: Row(
|
||||
children: [
|
||||
const Icon(Icons.error, color: Colors.white),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: Text("Error adding to cart: $e")),
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.red,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
margin: const EdgeInsets.only(bottom: 80, left: 16, right: 16),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,10 +122,10 @@ packages:
|
|||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_launcher_icons
|
||||
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
|
||||
sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.1"
|
||||
version: "0.14.4"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ dev_dependencies:
|
|||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^4.0.0
|
||||
flutter_launcher_icons: ^0.13.1
|
||||
flutter_launcher_icons: ^0.14.4
|
||||
|
||||
flutter_launcher_icons:
|
||||
android: true
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue