Files
Eventify-frontend/lib/features/share/share_rank_card.dart
Sicherhaven aefb381ed3 feat(share): update share rank caption and add URL
Share sheet now pre-fills:
"I'm a BRONZE Explorer on Eventify Plus! 7 EP earned.
Let's connect on the platform for more.

https://app.eventifyplus.com"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 14:16:33 +05:30

199 lines
6.8 KiB
Dart

import 'dart:io';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import '../../widgets/tier_avatar_ring.dart';
class ShareRankCard extends StatefulWidget {
final String username;
final String tier;
final int rank;
final int ep;
final int rewardPoints;
const ShareRankCard({
super.key,
required this.username,
required this.tier,
required this.rank,
required this.ep,
this.rewardPoints = 0,
});
@override
State<ShareRankCard> createState() => _ShareRankCardState();
}
class _ShareRankCardState extends State<ShareRankCard> {
final GlobalKey _boundaryKey = GlobalKey();
bool _sharing = false;
static const _tierGradients = {
'Bronze': [Color(0xFF92400E), Color(0xFFD97706)],
'Silver': [Color(0xFF475569), Color(0xFF94A3B8)],
'Gold': [Color(0xFF92400E), Color(0xFFFBBF24)],
'Platinum': [Color(0xFF4C1D95), Color(0xFF8B5CF6)],
'Diamond': [Color(0xFF1E3A8A), Color(0xFF60A5FA)],
};
List<Color> get _gradient {
return _tierGradients[widget.tier] ?? [const Color(0xFF0F172A), const Color(0xFF1E293B)];
}
Future<void> _share() async {
if (_sharing) return;
setState(() => _sharing = true);
try {
final boundary = _boundaryKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
final image = await boundary.toImage(pixelRatio: 3.0);
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
if (byteData == null) return;
final bytes = byteData.buffer.asUint8List();
final tempDir = await getTemporaryDirectory();
final file = File('${tempDir.path}/eventify_rank_${widget.username}.png');
await file.writeAsBytes(bytes);
await Share.shareXFiles(
[XFile(file.path)],
subject: 'My Eventify Rank',
text: 'I\'m a ${widget.tier.toUpperCase()} Explorer on Eventify Plus! ${widget.ep} EP earned. Let\'s connect on the platform for more.\n\nhttps://app.eventifyplus.com',
);
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Could not share rank card')),
);
}
} finally {
if (mounted) setState(() => _sharing = false);
}
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
RepaintBoundary(
key: _boundaryKey,
child: Container(
width: 320,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(0xFF0F172A), Color(0xFF1E293B)],
),
borderRadius: BorderRadius.circular(20),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Tier gradient header bar
Container(
height: 6,
decoration: BoxDecoration(
gradient: LinearGradient(colors: _gradient),
borderRadius: BorderRadius.circular(3),
),
),
const SizedBox(height: 20),
// Avatar
TierAvatarRing(username: widget.username, tier: widget.tier, size: 80),
const SizedBox(height: 12),
// Username
Text(
widget.username,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w800, color: Colors.white),
),
const SizedBox(height: 4),
// Tier badge
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration(
gradient: LinearGradient(colors: _gradient),
borderRadius: BorderRadius.circular(12),
),
child: Text(
widget.tier.isEmpty ? 'Contributor' : widget.tier,
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w700, color: Colors.white),
),
),
const SizedBox(height: 20),
// Stats row
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_stat('Rank', '#${widget.rank}'),
Container(width: 1, height: 40, color: Colors.white12),
_stat('EP', '${widget.ep}'),
Container(width: 1, height: 40, color: Colors.white12),
_stat('RP', '${widget.rewardPoints}'),
],
),
const SizedBox(height: 20),
// Branding
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(Icons.bolt, size: 14, color: Color(0xFF3B82F6)),
SizedBox(width: 4),
Text(
'EVENTIFY',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w900,
color: Color(0xFF3B82F6),
letterSpacing: 2,
),
),
],
),
],
),
),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: _sharing ? null : _share,
icon: _sharing
? const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
)
: const Icon(Icons.share, size: 18),
label: Text(_sharing ? 'Sharing...' : 'Share Rank Card'),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF1D4ED8),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
),
),
],
);
}
Widget _stat(String label, String value) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
value,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w800, color: Colors.white),
),
const SizedBox(height: 2),
Text(
label,
style: const TextStyle(fontSize: 11, color: Color(0xFF94A3B8)),
),
],
);
}
}