Files
Casha/lib/shared/widgets/pro_subscription_card.dart
T
2026-08-06 21:35:22 +03:00

265 lines
8.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../core/l10n/locale_provider.dart';
import '../../core/services/haptic_service.dart';
import '../providers/premium_provider.dart';
class ProSubscriptionCard extends StatefulWidget {
const ProSubscriptionCard({super.key});
@override
State<ProSubscriptionCard> createState() =>
_ProSubscriptionCardState();
}
class _ProSubscriptionCardState extends State<ProSubscriptionCard>
with SingleTickerProviderStateMixin {
late final AnimationController _shimmerController;
static const _gradientColors = [
Color(0xFF5B4DCC),
Color(0xFF7C6DED),
Color(0xFF9D8FF5),
];
@override
void initState() {
super.initState();
_shimmerController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 2800),
)..repeat();
}
@override
void dispose() {
_shimmerController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (context, ref, _) {
final s = ref.watch(stringsProvider);
final isPremium = ref.watch(isPremiumProvider);
return ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
children: [
Container(
padding: const EdgeInsets.fromLTRB(20, 22, 20, 18),
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: _gradientColors,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.18),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.white.withOpacity(0.25),
width: 1,
),
),
child: Icon(
isPremium
? Icons.verified_rounded
: Icons.workspace_premium_rounded,
color: Colors.white,
size: 26,
),
),
const SizedBox(width: 14),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
s.proTitle,
style: Theme.of(context)
.textTheme
.titleLarge
?.copyWith(
fontWeight: FontWeight.w800,
color: Colors.white,
letterSpacing: -0.3,
),
),
const SizedBox(height: 3),
Text(
isPremium ? s.proActive : s.proSubtitle,
style: isPremium
? Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(
color: Colors.white.withOpacity(0.95),
fontWeight: FontWeight.w600,
)
: Theme.of(context)
.textTheme
.bodySmall
?.copyWith(
color: Colors.white.withOpacity(0.75),
),
),
],
),
),
if (isPremium)
Container(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: Colors.white.withOpacity(0.3),
width: 1,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.check_circle_rounded,
color: Colors.white.withOpacity(0.95),
size: 14,
),
const SizedBox(width: 4),
Text(
'Pro',
style: TextStyle(
color: Colors.white.withOpacity(0.95),
fontSize: 11,
fontWeight: FontWeight.w700,
),
),
],
),
),
],
),
const SizedBox(height: 18),
SizedBox(
width: double.infinity,
child: _GlassButton(
label: s.proAboutPro,
icon: Icons.arrow_forward_rounded,
onTap: () {
HapticService.light();
context.push('/pro');
},
),
),
],
),
),
Positioned.fill(
child: IgnorePointer(
child: AnimatedBuilder(
animation: _shimmerController,
builder: (context, _) {
final t = _shimmerController.value;
final startX = -1.5;
final endX = 2.5;
final x = startX + (endX - startX) * t;
return ShaderMask(
blendMode: BlendMode.srcOver,
shaderCallback: (Rect bounds) {
return LinearGradient(
begin: Alignment(x, 0),
end: Alignment(x + 0.5, 0),
colors: [
Colors.white.withOpacity(0),
Colors.white.withOpacity(0.12),
Colors.white.withOpacity(0),
],
stops: const [0.0, 0.5, 1.0],
).createShader(bounds);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: Colors.white.withOpacity(0.15),
width: 1,
),
),
),
);
},
),
),
),
],
),
);
},
);
}
}
class _GlassButton extends StatelessWidget {
final String label;
final IconData icon;
final VoidCallback onTap;
const _GlassButton({
required this.label,
required this.icon,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return Material(
color: Colors.white.withOpacity(0.15),
borderRadius: BorderRadius.circular(12),
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(12),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.white.withOpacity(0.25),
width: 1,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
label,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontSize: 14,
),
),
const SizedBox(width: 6),
Icon(icon, color: Colors.white, size: 18),
],
),
),
),
);
}
}