feat: Phase 2 — 11 high-priority gaps implemented across home, auth, gamification, profile, and event detail

Phase 2 gaps completed:
- HOME-001: Hero slider pause-on-touch (GestureDetector wraps PageView)
- HOME-003: Calendar bottom sheet with TableCalendar (replaces custom dialog)
- AUTH-004: District dropdown on signup (14 Kerala districts)
- EVT-003: Mobile sticky "Book Now" bar + desktop CTA wired to CheckoutScreen
- ACH-001: Real achievements from dashboard API with fallback defaults
- GAM-002: 3-card EP row (Lifetime EP / Liquid EP / Reward Points)
- GAM-005: Horizontal tier roadmap Bronze→Silver→Gold→Platinum→Diamond
- CTR-001: Submission status chips (PENDING/APPROVED/REJECTED)
- CTR-002: +EP badge on approved submissions
- PROF-003: Gamification cards on profile screen with Consumer<GamificationProvider>
- UX-001: Shimmer skeleton loaders (shimmer ^3.0.0) replacing CircularProgressIndicator

Already complete (verified, no changes needed):
- HOME-002: Category shelves already built in _buildTypeSection()
- LDR-002: Podium visualization already built (_buildPodium / _buildDesktopPodium)
- BOOK-004: UPI handled natively by Razorpay SDK

Deferred: LOC-001/002 (needs Django haversine endpoint)
Skipped: AUTH-002 (OTP needs SMS provider decision)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-04 16:51:30 +05:30
parent 29e326b8fc
commit fe8af7cfe6
12 changed files with 715 additions and 250 deletions

View File

@@ -15,6 +15,7 @@ import '../core/auth/auth_guard.dart';
import '../core/utils/error_utils.dart';
import '../core/constants.dart';
import '../features/reviews/widgets/review_section.dart';
import 'checkout_screen.dart';
class LearnMoreScreen extends StatefulWidget {
final int eventId;
@@ -28,6 +29,18 @@ class LearnMoreScreen extends StatefulWidget {
class _LearnMoreScreenState extends State<LearnMoreScreen> {
final EventsService _service = EventsService();
void _navigateToCheckout() {
if (!AuthGuard.requireLogin(context, reason: 'Sign in to book this event.')) return;
if (_event == null) return;
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => CheckoutScreen(
eventId: _event!.id,
eventName: _event!.name,
eventImage: _event!.thumbImg,
),
));
}
bool _loading = true;
EventModel? _event;
String? _error;
@@ -388,9 +401,7 @@ class _LearnMoreScreenState extends State<LearnMoreScreen> {
right: 32,
bottom: 36,
child: ElevatedButton(
onPressed: () {
// TODO: implement booking action
},
onPressed: _navigateToCheckout,
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF1A56DB),
foregroundColor: Colors.white,
@@ -530,6 +541,42 @@ class _LearnMoreScreenState extends State<LearnMoreScreen> {
// ── MOBILE layout ─────────────────────────────────────────────────────
return Scaffold(
backgroundColor: theme.scaffoldBackgroundColor,
bottomNavigationBar: (_event != null && _event!.isBookable)
? Container(
decoration: BoxDecoration(
color: theme.scaffoldBackgroundColor,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
blurRadius: 12,
offset: const Offset(0, -4),
),
],
),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: SafeArea(
top: false,
child: SizedBox(
height: 52,
child: ElevatedButton(
onPressed: _navigateToCheckout,
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF1A56DB),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
),
elevation: 0,
),
child: const Text(
'Book Now',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700),
),
),
),
),
)
: null,
body: Stack(
children: [
// ── Scrollable content (carousel + card scroll together) ──