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

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-04 15:46:53 +05:30
parent 847577c09d
commit 29e326b8fc
24 changed files with 1663 additions and 164 deletions

View File

@@ -1,15 +1,19 @@
// lib/screens/booking_screen.dart
import 'package:flutter/material.dart';
import 'checkout_screen.dart';
class BookingScreen extends StatefulWidget {
// Keep onBook in the constructor if you want to use it later, but we won't call it here.
final VoidCallback? onBook;
final String image;
final int? eventId;
final String? eventName;
const BookingScreen({
Key? key,
this.onBook,
this.image = 'assets/images/event1.jpg',
this.eventId,
this.eventName,
}) : super(key: key);
@override
@@ -39,11 +43,22 @@ Whether you're a longtime fan or hearing him live for the first time, this eveni
bool _booked = false;
void _performLocalBooking() {
// mark locally booked (do NOT call widget.onBook())
// If event data is available, navigate to real checkout
if (widget.eventId != null) {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => CheckoutScreen(
eventId: widget.eventId!,
eventName: widget.eventName ?? 'Event',
eventImage: widget.image,
),
));
return;
}
// Fallback: demo booking for events without IDs
if (!_booked) {
setState(() => _booked = true);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Tickets booked (demo)')),
const SnackBar(content: Text('Tickets booked (demo)')),
);
}
}