Files
CityCards_Customer_Flutter/lib/postcard/widgets/back_card_widget.dart
2026-02-10 13:58:58 +05:30

268 lines
9.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:html/parser.dart' as html_parser;
class BackCardWidget extends StatelessWidget {
final String message;
final String name;
final String address;
final String city;
final String state;
final String country;
final String pincode;
final double aspectRatio;
final double scale;
const BackCardWidget({
super.key,
this.message = '',
this.name = '',
this.address = '',
this.city = '',
this.state = '',
this.country = '',
this.pincode = '',
this.aspectRatio = 1.5,
this.scale = 1.08,
});
// Parse HTML message and extract font family and text
Map<String, String> _parseHtmlMessage(String htmlMessage) {
if (htmlMessage.isEmpty) {
return {'text': '', 'fontFamily': ''};
}
// Check if message contains HTML tags
if (!htmlMessage.contains('<span') && !htmlMessage.contains('style=')) {
// Plain text message - no font specified
return {'text': htmlMessage, 'fontFamily': ''};
}
try {
// Parse HTML
final document = html_parser.parse(htmlMessage);
final spanElement = document.querySelector('span');
if (spanElement != null) {
// Extract text content
final text = spanElement.text;
// Extract font-family from style attribute
final style = spanElement.attributes['style'] ?? '';
final fontFamilyMatch = RegExp(r'font-family:\s*([^;]+)').firstMatch(style);
final fontFamily = fontFamilyMatch?.group(1)?.trim() ?? '';
return {'text': text, 'fontFamily': fontFamily};
}
// Fallback: return plain text
return {'text': document.body?.text ?? htmlMessage, 'fontFamily': ''};
} catch (e) {
// If parsing fails, return original message
return {'text': htmlMessage, 'fontFamily': ''};
}
}
// Get TextStyle with any Google Font
TextStyle _getFontStyle(String fontFamily, double fontSize, double height) {
// If no font family specified, use default Caveat
if (fontFamily.isEmpty) {
return GoogleFonts.caveat(fontSize: fontSize, height: height);
}
try {
// Normalize font name: remove extra spaces, handle common variations
final normalizedFont = fontFamily
.trim()
.replaceAll(RegExp(r'\s+'), ' '); // Replace multiple spaces with single space
// Try to get the font from Google Fonts
// GoogleFonts.getFont() can load ANY Google Font dynamically
return GoogleFonts.getFont(
normalizedFont,
fontSize: fontSize,
height: height,
);
} catch (e) {
// If font not found in Google Fonts, fallback to default
debugPrint('⚠️ Font "$fontFamily" not found in Google Fonts. Using default Caveat font.');
return GoogleFonts.caveat(fontSize: fontSize, height: height);
}
}
@override
Widget build(BuildContext context) {
// Parse the message to extract text and font
final parsedMessage = _parseHtmlMessage(message);
final messageText = parsedMessage['text'] ?? '';
final fontFamily = parsedMessage['fontFamily'] ?? '';
return Transform.scale(
scale: scale,
child: Container(
key: const ValueKey('back'),
margin: EdgeInsets.symmetric(horizontal: 12.w),
decoration: BoxDecoration(
color: const Color(0xFFFAF9F6),
borderRadius: BorderRadius.circular(6),
border: Border.all(color: Colors.black.withOpacity(0.12)),
// boxShadow: [
// BoxShadow(
// color: Colors.black.withOpacity(0.08),
// blurRadius: 10,
// offset: const Offset(0, 4),
// ),
// ],
),
child: AspectRatio(
aspectRatio: aspectRatio,
child: Stack(
children: [
Row(
children: [
/// LEFT MESSAGE
Expanded(
flex: 55,
child: Padding(
padding: EdgeInsets.fromLTRB(22.w, 22.h, 18.w, 18.h),
child: SingleChildScrollView(
child: Text(
messageText,
style: _getFontStyle(fontFamily, 16.sp, 1.7),
),
),
),
),
/// DIVIDER
Container(
width: 1.5,
margin: EdgeInsets.symmetric(vertical: 28.h),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.black.withOpacity(0.05),
Colors.black.withOpacity(0.15),
Colors.black.withOpacity(0.05),
],
),
),
),
/// RIGHT ADDRESS
Expanded(
flex: 45,
child: Padding(
padding: EdgeInsets.fromLTRB(14.w, 4.h, 14.w, 14.h),
child: Column(
children: [
Align(
alignment: Alignment.topRight,
child: Image.asset(
'assets/images/postcard_stamp_logo.png',
height: 40.h,
),
),
Flexible(
child: Container(
padding: EdgeInsets.all(6.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
border: Border.all(
color: Colors.black.withOpacity(0.18),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
'ADDRESS',
style: GoogleFonts.montserrat(
fontSize: 7.sp,
fontWeight: FontWeight.w600,
color: Colors.black45,
),
),
),
SizedBox(height: 5.h),
if (name.isNotEmpty) ...[
_addressLine(name),
_divider(),
],
if (address.isNotEmpty) ...[
_addressLine(address),
_divider(),
],
if (city.isNotEmpty) ...[
_addressLine(city),
_divider(),
],
if (state.isNotEmpty) ...[
_addressLine(state),
_divider(),
],
if (country.isNotEmpty) ...[
_addressLine(country),
_divider(),
],
if (pincode.isNotEmpty) ...[
_addressLine(pincode),
_divider(),
],
],
),
),
),
],
),
),
),
],
),
/// BRAND
Positioned(
bottom: 0.h,
left: 0.h,
right: 0.h,
child: Center(
child: Text(
'CityCards.co',
style: GoogleFonts.montserrat(
fontSize: 12.sp,
color: const Color(0xffF95F62),
fontWeight: FontWeight.w500,
),
),
),
),
],
),
),
),
);
}
Widget _addressLine(String text) {
return Text(
text,
textAlign: TextAlign.center,
style: GoogleFonts.caveat(
fontSize: 12.sp,
height: 1.4,
),
);
}
Widget _divider() {
return Divider(
height: 1,
color: Colors.black.withOpacity(0.15),
);
}
}