2026-01-31 15:23:18 +05:30
|
|
|
// lib/main.dart
|
|
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
feat: Phase 1 critical gaps — gamification API, Razorpay checkout, Google OAuth, notifications
- Fix gamification endpoints to use Node.js server (app.eventifyplus.com)
- Replace 6 mock gamification methods with real API calls (dashboard, leaderboard, shop, redeem, submit)
- Add booking models, service, payment service (Razorpay), checkout provider
- Add 3-step CheckoutScreen with Razorpay native modal integration
- Add Google OAuth login (Flutter + Django backend)
- Add full notifications system (Django model + 3 endpoints + Flutter UI)
- Register CheckoutProvider, NotificationProvider in main.dart MultiProvider
- Wire notification bell in HomeScreen app bar
- Add razorpay_flutter ^1.3.7 and google_sign_in ^6.2.2 packages
2026-04-04 15:46:53 +05:30
|
|
|
import 'package:provider/provider.dart';
|
2026-01-31 15:23:18 +05:30
|
|
|
|
|
|
|
|
import 'screens/home_screen.dart';
|
|
|
|
|
import 'screens/home_desktop_screen.dart';
|
|
|
|
|
import 'screens/login_screen.dart';
|
|
|
|
|
import 'screens/desktop_login_screen.dart';
|
feat: Phase 1 critical gaps — gamification API, Razorpay checkout, Google OAuth, notifications
- Fix gamification endpoints to use Node.js server (app.eventifyplus.com)
- Replace 6 mock gamification methods with real API calls (dashboard, leaderboard, shop, redeem, submit)
- Add booking models, service, payment service (Razorpay), checkout provider
- Add 3-step CheckoutScreen with Razorpay native modal integration
- Add Google OAuth login (Flutter + Django backend)
- Add full notifications system (Django model + 3 endpoints + Flutter UI)
- Register CheckoutProvider, NotificationProvider in main.dart MultiProvider
- Wire notification bell in HomeScreen app bar
- Add razorpay_flutter ^1.3.7 and google_sign_in ^6.2.2 packages
2026-04-04 15:46:53 +05:30
|
|
|
import 'screens/responsive_layout.dart';
|
2026-01-31 15:23:18 +05:30
|
|
|
import 'core/theme_manager.dart';
|
feat: Phase 1 critical gaps — gamification API, Razorpay checkout, Google OAuth, notifications
- Fix gamification endpoints to use Node.js server (app.eventifyplus.com)
- Replace 6 mock gamification methods with real API calls (dashboard, leaderboard, shop, redeem, submit)
- Add booking models, service, payment service (Razorpay), checkout provider
- Add 3-step CheckoutScreen with Razorpay native modal integration
- Add Google OAuth login (Flutter + Django backend)
- Add full notifications system (Django model + 3 endpoints + Flutter UI)
- Register CheckoutProvider, NotificationProvider in main.dart MultiProvider
- Wire notification bell in HomeScreen app bar
- Add razorpay_flutter ^1.3.7 and google_sign_in ^6.2.2 packages
2026-04-04 15:46:53 +05:30
|
|
|
import 'core/analytics/posthog_service.dart';
|
|
|
|
|
import 'features/auth/providers/auth_provider.dart';
|
|
|
|
|
import 'features/gamification/providers/gamification_provider.dart';
|
|
|
|
|
import 'features/booking/providers/checkout_provider.dart';
|
|
|
|
|
import 'features/notifications/providers/notification_provider.dart';
|
2026-01-31 15:23:18 +05:30
|
|
|
|
|
|
|
|
void main() async {
|
|
|
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
|
await ThemeManager.init(); // load saved theme preference
|
feat: Phase 1 critical gaps — gamification API, Razorpay checkout, Google OAuth, notifications
- Fix gamification endpoints to use Node.js server (app.eventifyplus.com)
- Replace 6 mock gamification methods with real API calls (dashboard, leaderboard, shop, redeem, submit)
- Add booking models, service, payment service (Razorpay), checkout provider
- Add 3-step CheckoutScreen with Razorpay native modal integration
- Add Google OAuth login (Flutter + Django backend)
- Add full notifications system (Django model + 3 endpoints + Flutter UI)
- Register CheckoutProvider, NotificationProvider in main.dart MultiProvider
- Wire notification bell in HomeScreen app bar
- Add razorpay_flutter ^1.3.7 and google_sign_in ^6.2.2 packages
2026-04-04 15:46:53 +05:30
|
|
|
await PostHogService.instance.init();
|
2026-03-18 15:39:42 +05:30
|
|
|
|
|
|
|
|
// Increase image cache for smoother scrolling and faster re-renders
|
|
|
|
|
PaintingBinding.instance.imageCache.maximumSize = 500;
|
|
|
|
|
PaintingBinding.instance.imageCache.maximumSizeBytes = 200 * 1024 * 1024; // 200 MB
|
|
|
|
|
|
2026-01-31 15:23:18 +05:30
|
|
|
runApp(const MyApp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class MyApp extends StatelessWidget {
|
|
|
|
|
const MyApp({Key? key}) : super(key: key);
|
|
|
|
|
|
|
|
|
|
// Breakpoint used across app: >= => desktop/tablet UI, < => mobile UI
|
|
|
|
|
static const double desktopBreakpoint = 820;
|
|
|
|
|
|
|
|
|
|
// Optional: reuse your branded blue swatch if you prefer; simplified here.
|
|
|
|
|
static const MaterialColor primarySwatch = MaterialColor(
|
|
|
|
|
0xFF0B63D6,
|
|
|
|
|
<int, Color>{
|
|
|
|
|
50: Color(0xFFEAF4FF),
|
|
|
|
|
100: Color(0xFFD6EBFF),
|
|
|
|
|
200: Color(0xFFADD6FF),
|
|
|
|
|
300: Color(0xFF85C1FF),
|
|
|
|
|
400: Color(0xFF4FA6FF),
|
|
|
|
|
500: Color(0xFF0B63D6),
|
|
|
|
|
600: Color(0xFF0959C0),
|
|
|
|
|
700: Color(0xFF074EA6),
|
|
|
|
|
800: Color(0xFF05358D),
|
|
|
|
|
900: Color(0xFF04256E),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
2026-03-14 08:57:25 +05:30
|
|
|
static const String _fontFamily = 'Gilroy';
|
|
|
|
|
|
2026-01-31 15:23:18 +05:30
|
|
|
ThemeData _lightTheme() {
|
|
|
|
|
return ThemeData(
|
|
|
|
|
brightness: Brightness.light,
|
2026-03-14 08:57:25 +05:30
|
|
|
fontFamily: _fontFamily,
|
2026-01-31 15:23:18 +05:30
|
|
|
primarySwatch: primarySwatch,
|
|
|
|
|
scaffoldBackgroundColor: const Color(0xFFF7F5FB),
|
|
|
|
|
appBarTheme: const AppBarTheme(
|
|
|
|
|
backgroundColor: Colors.white,
|
|
|
|
|
foregroundColor: Colors.black87,
|
|
|
|
|
elevation: 0,
|
|
|
|
|
),
|
|
|
|
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
|
backgroundColor: const Color(0xFF0B63D6),
|
|
|
|
|
foregroundColor: Colors.white,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
cardColor: Colors.white,
|
|
|
|
|
useMaterial3: false,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ThemeData _darkTheme() {
|
|
|
|
|
return ThemeData(
|
|
|
|
|
brightness: Brightness.dark,
|
2026-03-14 08:57:25 +05:30
|
|
|
fontFamily: _fontFamily,
|
2026-01-31 15:23:18 +05:30
|
|
|
primarySwatch: primarySwatch,
|
|
|
|
|
scaffoldBackgroundColor: const Color(0xFF0B1220),
|
|
|
|
|
appBarTheme: const AppBarTheme(
|
|
|
|
|
backgroundColor: Color(0xFF0B1220),
|
|
|
|
|
foregroundColor: Colors.white,
|
|
|
|
|
elevation: 0,
|
|
|
|
|
),
|
|
|
|
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
|
|
|
|
style: ElevatedButton.styleFrom(backgroundColor: const Color(0xFF0B63D6)),
|
|
|
|
|
),
|
|
|
|
|
cardColor: const Color(0xFF0E1620),
|
2026-03-14 08:57:25 +05:30
|
|
|
textTheme: ThemeData.dark().textTheme.apply(fontFamily: _fontFamily),
|
2026-01-31 15:23:18 +05:30
|
|
|
useMaterial3: false,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
feat: Phase 1 critical gaps — gamification API, Razorpay checkout, Google OAuth, notifications
- Fix gamification endpoints to use Node.js server (app.eventifyplus.com)
- Replace 6 mock gamification methods with real API calls (dashboard, leaderboard, shop, redeem, submit)
- Add booking models, service, payment service (Razorpay), checkout provider
- Add 3-step CheckoutScreen with Razorpay native modal integration
- Add Google OAuth login (Flutter + Django backend)
- Add full notifications system (Django model + 3 endpoints + Flutter UI)
- Register CheckoutProvider, NotificationProvider in main.dart MultiProvider
- Wire notification bell in HomeScreen app bar
- Add razorpay_flutter ^1.3.7 and google_sign_in ^6.2.2 packages
2026-04-04 15:46:53 +05:30
|
|
|
return MultiProvider(
|
|
|
|
|
providers: [
|
|
|
|
|
ChangeNotifierProvider(create: (_) => AuthProvider()),
|
|
|
|
|
ChangeNotifierProvider(create: (_) => GamificationProvider()),
|
|
|
|
|
ChangeNotifierProvider(create: (_) => CheckoutProvider()),
|
|
|
|
|
ChangeNotifierProvider(create: (_) => NotificationProvider()),
|
|
|
|
|
],
|
|
|
|
|
child: ValueListenableBuilder<ThemeMode>(
|
|
|
|
|
valueListenable: ThemeManager.themeMode,
|
|
|
|
|
builder: (context, mode, _) {
|
|
|
|
|
return MaterialApp(
|
|
|
|
|
title: 'Event App',
|
|
|
|
|
debugShowCheckedModeBanner: false,
|
|
|
|
|
theme: _lightTheme(),
|
|
|
|
|
darkTheme: _darkTheme(),
|
|
|
|
|
themeMode: mode,
|
|
|
|
|
home: const StartupScreen(),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
2026-01-31 15:23:18 +05:30
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class StartupScreen extends StatefulWidget {
|
|
|
|
|
const StartupScreen({Key? key}) : super(key: key);
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<StartupScreen> createState() => _StartupScreenState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _StartupScreenState extends State<StartupScreen> {
|
|
|
|
|
bool? _loggedIn;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
super.initState();
|
|
|
|
|
_loadLoginState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> _loadLoginState() async {
|
2026-03-14 08:57:25 +05:30
|
|
|
try {
|
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
|
final hasEmail = prefs.getString('email') != null && prefs.getString('email')!.isNotEmpty;
|
|
|
|
|
setState(() => _loggedIn = hasEmail);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
// If SharedPreferences fails (common on web with plugin issues), default to not logged in
|
|
|
|
|
print('Error loading login state: $e');
|
|
|
|
|
if (mounted) {
|
|
|
|
|
setState(() => _loggedIn = false);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-31 15:23:18 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
// While we check local storage show a loader
|
|
|
|
|
if (_loggedIn == null) {
|
|
|
|
|
return const Scaffold(
|
|
|
|
|
body: Center(child: CircularProgressIndicator()),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Use LayoutBuilder so we can inspect the actual window width and choose the proper login/home variant.
|
|
|
|
|
return LayoutBuilder(builder: (context, constraints) {
|
|
|
|
|
final width = constraints.maxWidth;
|
|
|
|
|
final isDesktop = width >= MyApp.desktopBreakpoint;
|
|
|
|
|
|
|
|
|
|
// If the user is already logged in, show responsive home (mobile or desktop)
|
|
|
|
|
if (_loggedIn == true) {
|
|
|
|
|
return ResponsiveLayout(
|
|
|
|
|
mobile: HomeScreen(),
|
|
|
|
|
desktop: const HomeDesktopScreen(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Not logged in → show login appropriate for the window size
|
|
|
|
|
return isDesktop ? const DesktopLoginScreen() : const LoginScreen();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|