cyberhybridhub/lib/widgets/google_sign_in_button.dart
2026-05-20 10:22:58 -05:00

140 lines
3.7 KiB
Dart

import 'package:flutter/material.dart';
import '../services/auth_service.dart';
import '../theme/app_theme.dart';
class GoogleSignInButton extends StatefulWidget {
const GoogleSignInButton({
super.key,
this.label = 'Continue with Google',
this.compact = false,
this.onSignedIn,
this.onError,
});
final String label;
final bool compact;
final VoidCallback? onSignedIn;
final void Function(Object error)? onError;
@override
State<GoogleSignInButton> createState() => _GoogleSignInButtonState();
}
class _GoogleSignInButtonState extends State<GoogleSignInButton> {
bool _isLoading = false;
Future<void> _signIn() async {
setState(() => _isLoading = true);
try {
await AuthService.instance.signInWithGoogle();
widget.onSignedIn?.call();
} catch (error) {
widget.onError?.call(error);
} finally {
if (mounted) {
setState(() => _isLoading = false);
}
}
}
@override
Widget build(BuildContext context) {
final double verticalPadding = widget.compact ? 14 : 16;
return SizedBox(
width: double.infinity,
child: FilledButton(
onPressed: _isLoading ? null : _signIn,
style: FilledButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: const Color(0xFF1F2937),
disabledBackgroundColor: Colors.white.withValues(alpha: 0.7),
padding: EdgeInsets.symmetric(vertical: verticalPadding),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 0,
),
child: _isLoading
? const SizedBox(
width: 22,
height: 22,
child: CircularProgressIndicator(
strokeWidth: 2.5,
color: AppColors.background,
),
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const _GoogleLogo(size: 22),
const SizedBox(width: 12),
Flexible(
child: Text(
widget.label,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Color(0xFF1F2937),
),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
],
),
),
);
}
}
class _GoogleLogo extends StatelessWidget {
const _GoogleLogo({required this.size});
final double size;
@override
Widget build(BuildContext context) {
return SizedBox(
width: size,
height: size,
child: CustomPaint(painter: _GoogleLogoPainter()),
);
}
}
class _GoogleLogoPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final double w = size.width;
final double h = size.height;
final Offset center = Offset(w / 2, h / 2);
final double r = w * 0.42;
void arc(Color color, double start, double sweep) {
final Paint paint = Paint()
..color = color
..style = PaintingStyle.stroke
..strokeWidth = w * 0.18
..strokeCap = StrokeCap.round;
canvas.drawArc(
Rect.fromCircle(center: center, radius: r),
start,
sweep,
false,
paint,
);
}
arc(const Color(0xFF4285F4), -0.4, 1.6);
arc(const Color(0xFFEA4335), 1.2, 1.3);
arc(const Color(0xFFFBBC05), 2.5, 1.3);
arc(const Color(0xFF34A853), 3.8, 1.3);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}