Files
Eventify-frontend/lib/widgets/eventify_bottom_sheet.dart

97 lines
2.6 KiB
Dart
Raw Permalink Normal View History

feat: Phase 3 — 26 medium-priority gaps implemented P3-A/K Profile: Eventify ID glassmorphic badge (tap-to-copy), DiceBear Notionists avatar via TierAvatarRing, district picker (14 pills) with 183-day cooldown lock, multipart photo upload to server P3-B Home: Top Events converted to PageView scroll-snap (viewportFraction 0.9 + PageScrollPhysics) P3-C Event detail: contributor widget (tier ring + name + navigation), related events horizontal row; added getEventsByCategory() to EventsService; added contributorId/Name/Tier fields to EventModel P3-D Kerala pincodes: 463-entry JSON (all 14 districts), registered as asset, async-loaded in SearchScreen replacing hardcoded 32 cities P3-E Checkout: promo code field + Apply/Remove button in Step 2, discountAmount subtracted from total, applyPromo()/resetPromo() methods in CheckoutProvider P3-F/G Gamification: reward cycle countdown + EP→RP progress bar (blue→ amber) in contribute + profile screens; TierAvatarRing in podium and all leaderboard rows; GlassCard current-user stats card at top of leaderboard tab P3-H New ContributorProfileScreen: tier ring, stats, submission grid with status chips; getDashboardForUser() in GamificationService; wired from leaderboard row taps P3-I Achievements: 11 default badges (up from 6), 6 new icon map entries; progress % labels already confirmed present P3-J Reviews: CustomPainter circular arc rating ring (amber, 84px) replaces large rating number in ReviewSummary P3-L Share rank card: RepaintBoundary → PNG capture → Share.shareXFiles; share button wired in profile header and leaderboard tab P3-M SafeArea audit: home bottom nav, contribute/achievements scroll padding, profile CustomScrollView top inset New files: tier_avatar_ring.dart, glass_card.dart, eventify_bottom_sheet.dart, contributor_profile_screen.dart, share_rank_card.dart, assets/data/kerala_pincodes.json New dep: path_provider ^2.1.0
2026-04-04 17:17:36 +05:30
import 'package:flutter/material.dart';
void showEventifyBottomSheet(
BuildContext context, {
required String title,
required Widget child,
double initialSize = 0.5,
double minSize = 0.3,
double maxSize = 0.9,
bool isDismissible = true,
}) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
isDismissible: isDismissible,
backgroundColor: Colors.transparent,
builder: (_) => DraggableScrollableSheet(
initialChildSize: initialSize,
minChildSize: minSize,
maxChildSize: maxSize,
expand: false,
builder: (_, scrollController) => _EventifyBottomSheetContent(
title: title,
child: child,
scrollController: scrollController,
),
),
);
}
class _EventifyBottomSheetContent extends StatelessWidget {
const _EventifyBottomSheetContent({
required this.title,
required this.child,
required this.scrollController,
});
final String title;
final Widget child;
final ScrollController scrollController;
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
color: Color(0xFF0F172A),
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 12),
Center(
child: Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: Colors.white24,
borderRadius: BorderRadius.circular(2),
),
),
),
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Expanded(
child: Text(
title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
),
IconButton(
icon: const Icon(Icons.close, color: Colors.white54),
onPressed: () => Navigator.pop(context),
),
],
),
),
const Divider(color: Colors.white12, height: 1),
Expanded(
child: SingleChildScrollView(
controller: scrollController,
child: child,
),
),
],
),
);
}
}