Amba-Emails/emails/ticket-pdf.tsx

323 lines
8.3 KiB
TypeScript

import React from 'react';
import {
Document,
Page,
Text,
View,
Image,
StyleSheet,
} from '@react-pdf/renderer';
interface TicketPDFProps {
userName?: string;
eventName?: string;
eventDate?: string;
eventTime?: string;
venue?: string;
ticketType?: string;
amount?: string;
qrCodeDataUrl?: string;
ticketNumber?: string;
purchaseDate?: string;
orderId?: string;
seatNumber?: string;
section?: string;
}
export const TicketPDF = ({
userName = 'Kirubel',
eventName = 'Summer Music Festival 2024',
eventDate = 'July 15, 2024',
eventTime = '7:00 PM',
venue = 'City Park Amphitheater',
ticketType = 'General Admission',
amount = '$75.00',
qrCodeDataUrl,
ticketNumber = 'EVT-12345',
purchaseDate = new Date().toLocaleDateString(),
orderId = 'ORD-12345',
seatNumber,
section,
}: TicketPDFProps) => {
return (
<Document>
<Page size="A4" style={styles.page}>
{/* Header */}
<View style={styles.header}>
<Text style={styles.headerTitle}>AMBA</Text>
<Text style={styles.headerSubtitle}>Event Ticket</Text>
</View>
{/* Ticket Number Badge */}
<View style={styles.ticketBadge}>
<Text style={styles.ticketBadgeText}>TICKET #{ticketNumber}</Text>
</View>
{/* Event Information Section */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Event Details</Text>
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Event Name:</Text>
<Text style={styles.infoValue}>{eventName}</Text>
</View>
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Date:</Text>
<Text style={styles.infoValue}>{eventDate}</Text>
</View>
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Time:</Text>
<Text style={styles.infoValue}>{eventTime}</Text>
</View>
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Venue:</Text>
<Text style={styles.infoValue}>{venue}</Text>
</View>
</View>
{/* Ticket Holder Information */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Ticket Holder</Text>
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Name:</Text>
<Text style={styles.infoValue}>{userName}</Text>
</View>
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Ticket Type:</Text>
<Text style={styles.infoValue}>{ticketType}</Text>
</View>
{seatNumber && (
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Seat:</Text>
<Text style={styles.infoValue}>{seatNumber}</Text>
</View>
)}
{section && (
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Section:</Text>
<Text style={styles.infoValue}>{section}</Text>
</View>
)}
</View>
{/* Payment Information */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Payment Information</Text>
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Amount Paid:</Text>
<Text style={styles.infoValue}>{amount}</Text>
</View>
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Order ID:</Text>
<Text style={styles.infoValue}>{orderId}</Text>
</View>
<View style={styles.infoRow}>
<Text style={styles.infoLabel}>Purchase Date:</Text>
<Text style={styles.infoValue}>{purchaseDate}</Text>
</View>
</View>
{/* QR Code Section */}
{qrCodeDataUrl && (
<View style={styles.qrSection}>
<Text style={styles.qrTitle}>Entry QR Code</Text>
<Text style={styles.qrInstructions}>
Present this QR code at the venue entrance for quick access
</Text>
<View style={styles.qrContainer}>
<Image
src={qrCodeDataUrl}
style={styles.qrCode}
/>
</View>
<Text style={styles.qrNote}>
Ticket Number: {ticketNumber}
</Text>
</View>
)}
{/* Footer */}
<View style={styles.footer}>
<Text style={styles.footerText}>
This ticket is non-transferable and non-refundable.
</Text>
<Text style={styles.footerText}>
Please arrive at least 30 minutes before the event start time.
</Text>
<Text style={styles.footerText}>
For support, contact: support@amba.app
</Text>
</View>
{/* Terms and Conditions */}
<View style={styles.termsSection}>
<Text style={styles.termsTitle}>Terms & Conditions</Text>
<Text style={styles.termsText}>
This ticket grants admission to the specified event only
</Text>
<Text style={styles.termsText}>
The ticket holder must present valid ID if requested
</Text>
<Text style={styles.termsText}>
The venue reserves the right to refuse entry
</Text>
<Text style={styles.termsText}>
Lost or stolen tickets cannot be replaced
</Text>
<Text style={styles.termsText}>
Recording devices may be prohibited
</Text>
</View>
</Page>
</Document>
);
};
const styles = StyleSheet.create({
page: {
padding: 40,
backgroundColor: '#ffffff',
fontFamily: 'Helvetica',
},
header: {
marginBottom: 30,
textAlign: 'center',
borderBottom: '2px solid #105D38',
paddingBottom: 20,
},
headerTitle: {
fontSize: 32,
fontWeight: 'bold',
color: '#105D38',
marginBottom: 5,
},
headerSubtitle: {
fontSize: 16,
color: '#666666',
textTransform: 'uppercase',
letterSpacing: 2,
},
ticketBadge: {
backgroundColor: '#105D38',
padding: 10,
borderRadius: 5,
marginBottom: 25,
textAlign: 'center',
},
ticketBadgeText: {
color: '#ffffff',
fontSize: 14,
fontWeight: 'bold',
textAlign: 'center',
},
section: {
marginBottom: 20,
padding: 15,
backgroundColor: '#f8fafc',
borderRadius: 5,
border: '1px solid #e2e8f0',
},
sectionTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#1e293b',
marginBottom: 12,
borderBottom: '1px solid #cbd5e1',
paddingBottom: 8,
},
infoRow: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 10,
paddingBottom: 8,
borderBottom: '1px solid #e2e8f0',
},
infoLabel: {
fontSize: 12,
color: '#FFB668',
fontWeight: '600',
flex: 1,
},
infoValue: {
fontSize: 12,
color: '#105D38',
fontWeight: 'normal',
flex: 2,
textAlign: 'right',
},
qrSection: {
marginTop: 30,
marginBottom: 20,
padding: 20,
backgroundColor: '#E6F4EC',
borderRadius: 5,
border: '2px solid #FFB668',
alignItems: 'center',
},
qrTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#105D38',
marginBottom: 8,
},
qrInstructions: {
fontSize: 11,
color: '#666666',
marginBottom: 15,
textAlign: 'center',
},
qrContainer: {
padding: 15,
backgroundColor: '#ffffff',
borderRadius: 5,
border: '2px solid #cbd5e1',
marginBottom: 10,
},
qrCode: {
width: 200,
height: 200,
},
qrNote: {
fontSize: 10,
color: '#666666',
marginTop: 10,
fontWeight: 'bold',
},
footer: {
marginTop: 20,
marginBottom: 15,
padding: 15,
backgroundColor: '#f8fafc',
borderRadius: 5,
border: '1px solid #e2e8f0',
},
footerText: {
fontSize: 9,
color: '#64748b',
marginBottom: 5,
textAlign: 'center',
lineHeight: 1.4,
},
termsSection: {
marginTop: 15,
padding: 15,
backgroundColor: '#fff7ed',
borderRadius: 5,
border: '1px solid #fed7aa',
},
termsTitle: {
fontSize: 14,
fontWeight: 'bold',
color: '#9a3412',
marginBottom: 10,
},
termsText: {
fontSize: 9,
color: '#7c2d12',
marginBottom: 5,
lineHeight: 1.4,
},
});
export default TicketPDF;