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>
66 lines
1.6 KiB
Dart
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,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|