268 lines
9.2 KiB
Dart
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),
|
|
);
|
|
}
|
|
} |