From a1616b161d5336e1688df49b849a18fd60ccd7c4 Mon Sep 17 00:00:00 2001 From: Sean O'Connor Date: Wed, 30 Jul 2025 21:28:59 -0400 Subject: [PATCH] Add flashy UI animations and enhance PDF invoice layout - Adds CSS animations for buttons, cards, icons, and text - Improves homepage with animated elements and interactive effects - Refines PDF export: better notes/totals layout, colors, and spacing - Updates styles for more engaging user experience --- src/app/page.tsx | 121 +++++++++---- src/lib/pdf-export.tsx | 94 ++++++---- src/styles/globals.css | 377 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 522 insertions(+), 70 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 15cccc5..40a66af 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -9,13 +9,13 @@ import { Check, Zap, Shield, - Globe, Sparkles, BarChart3, Clock, Rocket, Heart, ChevronRight, + Stars, } from "lucide-react"; export default function HomePage() { @@ -62,57 +62,93 @@ export default function HomePage() {
{/* Background decoration */}
-
-
-
+
+
+
+ + {/* Particle Effects */} +
+
+
+
+
+
+
+
+
+
+
+ + {/* Floating icons */} +
+ +
+
+ +
+
+ +
- - + + Free Forever -

+

Simple Invoicing for - Freelancers + + Freelancers +

-

+

Create professional invoices, manage clients, and track payments. Built for freelancers and small businesses— - completely free. + + completely free + + .

-
+
-
+
{[ "No credit card required", "Setup in 2 minutes", "Free forever", ].map((text, i) => ( -
- +
+ {text}
))} @@ -146,10 +182,10 @@ export default function HomePage() {
{/* Feature 1 */} - + -
- +
+

Quick Setup @@ -176,10 +212,10 @@ export default function HomePage() { {/* Feature 2 */} - + -
- +
+

Payment Tracking @@ -205,10 +241,10 @@ export default function HomePage() { {/* Feature 3 */} - + -
- +
+

Professional Features @@ -255,13 +291,15 @@ export default function HomePage() {

- +
- Forever Free + + Forever Free +
-
+
$0
@@ -280,8 +318,15 @@ export default function HomePage() { "Line item details", "Free forever", ].map((feature, i) => ( -
- +
+ {feature} @@ -292,9 +337,9 @@ export default function HomePage() { @@ -316,7 +361,9 @@ export default function HomePage() {

Why choose - BeenVoice + + BeenVoice +

@@ -381,10 +428,10 @@ export default function HomePage() {
diff --git a/src/lib/pdf-export.tsx b/src/lib/pdf-export.tsx index 8fd8cac..2cee19f 100644 --- a/src/lib/pdf-export.tsx +++ b/src/lib/pdf-export.tsx @@ -267,8 +267,8 @@ const styles = StyleSheet.create({ // Notes section (first page only) notesSection: { - marginTop: 20, - marginBottom: 20, + marginTop: 0, + marginBottom: 0, padding: 15, backgroundColor: "#f9fafb", borderRadius: 4, @@ -285,7 +285,7 @@ const styles = StyleSheet.create({ notesContent: { fontSize: 10, fontFamily: "Helvetica", - color: "#6b7280", + color: "#374151", lineHeight: 1.4, }, @@ -436,16 +436,25 @@ const styles = StyleSheet.create({ alignSelf: "flex-start", }, - // Totals section - totalsSection: { + // Bottom section with notes and totals + bottomSection: { marginTop: 20, flexDirection: "row", - justifyContent: "flex-end", + justifyContent: "space-between", + alignItems: "flex-start", + }, + + notesContainer: { + width: 240, + }, + + totalsContainer: { + width: 240, }, totalsBox: { - width: 250, - padding: 15, + width: "100%", + padding: 10, backgroundColor: "#f9fafb", border: "1px solid #e5e7eb", borderRadius: 4, @@ -454,26 +463,27 @@ const styles = StyleSheet.create({ totalRow: { flexDirection: "row", justifyContent: "space-between", - marginBottom: 6, + marginBottom: 4, + paddingVertical: 1, }, totalLabel: { - fontSize: 11, - color: "#6b7280", + fontSize: 12, + color: "#475569", + fontFamily: "Helvetica", }, totalAmount: { - fontSize: 10, + fontSize: 12, fontFamily: "Courier-Bold", - color: "#111827", + color: "#1e293b", }, finalTotalRow: { flexDirection: "row", justifyContent: "space-between", - marginTop: 8, - paddingTop: 8, - borderTop: "2px solid #10b981", + marginTop: 6, + paddingTop: 6, }, finalTotalLabel: { @@ -491,7 +501,7 @@ const styles = StyleSheet.create({ itemCount: { fontSize: 9, fontFamily: "Helvetica", - color: "#6b7280", + color: "#64748b", textAlign: "center", marginTop: 6, fontStyle: "italic", @@ -631,10 +641,10 @@ function calculateItemsForPage( if (hasNotes) { // Last page needs space for totals and notes - availableHeight -= 120; // Totals + notes space + availableHeight -= 100; // Totals + notes space (reduced) } else { // Regular page just needs totals space - availableHeight -= 80; // Totals space only + availableHeight -= 65; // Totals space only (reduced) } // Table header takes space @@ -683,10 +693,10 @@ function calculateItemsPerPage( if (hasNotes) { // Last page needs space for totals and notes - availableHeight -= 120; // Totals + notes space + availableHeight -= 100; // Totals + notes space (reduced) } else { // Regular page just needs totals space - availableHeight -= 80; // Totals space only + availableHeight -= 65; // Totals space only (reduced) } // Table header takes space @@ -892,9 +902,11 @@ const NotesSection: React.FC<{ invoice: InvoiceData }> = ({ invoice }) => { if (!invoice.notes) return null; return ( - - Notes: - {invoice.notes} + + + NOTES + {invoice.notes} + ); }; @@ -919,7 +931,7 @@ const Footer: React.FC = () => ( ); -// Totals section component +// Enhanced totals section component const TotalsSection: React.FC<{ invoice: InvoiceData; items: Array[0]>; @@ -928,8 +940,22 @@ const TotalsSection: React.FC<{ const taxAmount = (subtotal * invoice.taxRate) / 100; return ( - + + + INVOICE SUMMARY + + Subtotal: {formatCurrency(subtotal)} @@ -943,14 +969,14 @@ const TotalsSection: React.FC<{ )} - Total: + TOTAL: {formatCurrency(invoice.totalAmount)} - {items.length} item{items.length !== 1 ? "s" : ""} + {items.length} line item{items.length !== 1 ? "s" : ""} @@ -1020,11 +1046,13 @@ const InvoicePDF: React.FC<{ invoice: InvoiceData }> = ({ invoice }) => { )} - {/* Totals (only on last page) */} - {isLastPage && } - - {/* Notes (only on last page) */} - {isLastPage && } + {/* Bottom section with notes and totals (only on last page) */} + {isLastPage && ( + + {invoice.notes && } + + + )} {/* Footer */}