payfrit-app/lib/screens/splash_screen.dart
John Mizerek 0a8c12c1d3 Enhance UI with Material Design 3 and fix cart quantity handling
UI Improvements:
- Menu items displayed as attractive cards with icons and better typography
- Restaurant selection upgraded to card-based layout with shadows
- Animated pulsing beacon scanner with gradient effect
- Enhanced item customization sheet with drag handle and pill-style pricing
- Category headers with highlighted background and borders
- Business and service point names now shown in app bar

Persistent Login:
- Created AuthStorage service for credential persistence using SharedPreferences
- Auto-restore authentication on app launch
- Seamless login flow: scan → browse → login on cart add
- Users stay logged in across app restarts

Cart Functionality Fixes:
- Fixed duplicate item handling: now properly increments quantity
- Prevented adding inactive items by skipping unselected modifiers
- Fixed self-referential items (item cannot be its own child)
- Added debug logging for cart state tracking
- Success messages now show accurate item counts

Technical Improvements:
- AppState tracks business/service point names for display
- Beacon scanner passes location names through navigation
- Quantity calculation checks existing cart items before adding
- Better null safety with firstOrNull pattern

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 09:40:23 -08:00

66 lines
1.6 KiB
Dart

import "dart:async";
import "package:flutter/material.dart";
import "package:provider/provider.dart";
import "../app/app_router.dart";
import "../app/app_state.dart";
import "../services/api.dart";
import "../services/auth_storage.dart";
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
Timer? _timer;
@override
void initState() {
super.initState();
_timer = Timer(const Duration(milliseconds: 2400), () async {
if (!mounted) return;
// Check for saved authentication credentials
final credentials = await AuthStorage.loadAuth();
if (credentials != null) {
// Restore authentication state
Api.setAuthToken(credentials.token);
final appState = context.read<AppState>();
appState.setUserId(credentials.userId);
}
if (!mounted) return;
// Always go to beacon scan first - allows browsing without login
Navigator.of(context).pushReplacementNamed(AppRoutes.beaconScan);
});
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return const Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Text(
"PAYFRIT",
style: TextStyle(
color: Colors.white,
fontSize: 38,
fontWeight: FontWeight.w800,
letterSpacing: 3,
),
),
),
);
}
}