This commit is contained in:
suvodip ghosh
2025-04-22 13:46:38 +00:00
parent 10a2c0c2c3
commit 5a32c1a7d2
18 changed files with 2026 additions and 58 deletions

187
src/lib/InvoicePDF.jsx Normal file
View File

@@ -0,0 +1,187 @@
import React from 'react';
import { Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'column',
backgroundColor: '#FFFFFF',
padding: 40
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 20,
borderBottomWidth: 2,
borderBottomColor: '#6d9e37',
paddingBottom: 10
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#6d9e37'
},
section: {
marginBottom: 20
},
row: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 5
},
label: {
fontSize: 12,
fontWeight: 'bold'
},
value: {
fontSize: 12
},
divider: {
borderBottomWidth: 1,
borderBottomColor: '#EEEEEE',
marginVertical: 10
},
tableHeader: {
flexDirection: 'row',
backgroundColor: '#F5F5F5',
padding: 5,
marginBottom: 5
},
tableRow: {
flexDirection: 'row',
padding: 5,
borderBottomWidth: 1,
borderBottomColor: '#EEEEEE'
},
col1: {
width: '40%'
},
col2: {
width: '30%',
textAlign: 'right'
},
col3: {
width: '30%',
textAlign: 'right'
},
total: {
flexDirection: 'row',
justifyContent: 'flex-end',
marginTop: 10
},
totalText: {
fontSize: 14,
fontWeight: 'bold'
},
footer: {
position: 'absolute',
bottom: 30,
left: 40,
right: 40,
textAlign: 'center',
fontSize: 10,
color: '#999999'
},
status: {
padding: 3,
borderRadius: 3,
fontSize: 10,
fontWeight: 'bold'
}
});
const InvoicePDF = ({ data }) => {
const statusColor = data.status === 'completed' ? '#10B981' : '#EF4444';
return (
<Document>
<Page size="A4" style={styles.page}>
{/* Header */}
<View style={styles.header}>
<View>
<Text style={styles.title}>INVOICE</Text>
<Text style={styles.label}>Invoice #: {data.billing_id}</Text>
<Text style={styles.label}>Date: {new Date(data.created_at).toLocaleDateString()}</Text>
</View>
<View>
<Text style={styles.label}>Your Company</Text>
<Text style={styles.value}>123 Business Street</Text>
<Text style={styles.value}>City, Country</Text>
<Text style={styles.value}>contact@yourcompany.com</Text>
</View>
</View>
{/* Bill To */}
<View style={styles.section}>
<View style={styles.row}>
<View>
<Text style={styles.label}>BILL TO:</Text>
<Text style={styles.value}>{data.user}</Text>
</View>
<View>
<Text style={styles.label}>STATUS:</Text>
<Text style={[styles.value, { color: statusColor }]}>
{data.status.toUpperCase()}
</Text>
</View>
</View>
</View>
<View style={styles.divider} />
{/* Items Table */}
<View style={styles.section}>
<View style={styles.tableHeader}>
<Text style={styles.col1}>DESCRIPTION</Text>
<Text style={styles.col2}>TENURE</Text>
<Text style={styles.col3}>AMOUNT</Text>
</View>
<View style={styles.tableRow}>
<Text style={styles.col1}>{data.service}</Text>
<Text style={styles.col2}>{data.tenure}</Text>
<Text style={styles.col3}>
{new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(parseFloat(data.amount))}
</Text>
</View>
</View>
<View style={styles.divider} />
{/* Total */}
<View style={styles.total}>
<View style={{width: '30%'}}>
<View style={styles.row}>
<Text style={styles.label}>SUBTOTAL:</Text>
<Text style={styles.value}>
{new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(parseFloat(data.amount))}
</Text>
</View>
<View style={styles.row}>
<Text style={styles.label}>TOTAL:</Text>
<Text style={styles.totalText}>
{new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(parseFloat(data.amount))}
</Text>
</View>
</View>
</View>
{/* Footer */}
<View style={styles.footer}>
<Text>Thank you for your business!</Text>
<Text>Please make payments payable to Your Company</Text>
</View>
</Page>
</Document>
);
};
export default InvoicePDF;