diff --git a/src/app/dashboard/invoices/[id]/page.tsx b/src/app/dashboard/invoices/[id]/page.tsx
index bbffb55..3064583 100644
--- a/src/app/dashboard/invoices/[id]/page.tsx
+++ b/src/app/dashboard/invoices/[id]/page.tsx
@@ -3,7 +3,7 @@
import { DollarSign, Edit, Loader2, Trash2 } from "lucide-react";
import Link from "next/link";
import { notFound, useParams, useRouter } from "next/navigation";
-import { useState } from "react";
+import { useState, useEffect } from "react";
import { toast } from "sonner";
import { StatusBadge, type StatusType } from "~/components/data/status-badge";
import { PageHeader } from "~/components/layout/page-header";
@@ -505,7 +505,24 @@ function InvoiceViewContent({ invoiceId }: { invoiceId: string }) {
export default function InvoiceViewPage() {
const params = useParams();
+ const router = useRouter();
const id = params.id as string;
+ // Handle /invoices/new route - redirect to dedicated new page
+ useEffect(() => {
+ if (id === "new") {
+ router.replace("/dashboard/invoices/new");
+ }
+ }, [id, router]);
+
+ // Don't render anything if we're redirecting
+ if (id === "new") {
+ return (
+
+
+
+ );
+ }
+
return ;
}
diff --git a/src/app/dashboard/invoices/new/page.tsx b/src/app/dashboard/invoices/new/page.tsx
new file mode 100644
index 0000000..e9eca4f
--- /dev/null
+++ b/src/app/dashboard/invoices/new/page.tsx
@@ -0,0 +1,7 @@
+"use client";
+
+import InvoiceForm from "~/components/forms/invoice-form";
+
+export default function NewInvoicePage() {
+ return ;
+}
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 42c99ea..ed46c35 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -16,7 +16,7 @@ const buttonVariants = cva(
destructive:
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
- "border border-border/40 bg-background/60 shadow-sm backdrop-blur-sm hover:bg-accent/50 hover:text-foreground-foreground hover:border-border/60 transition-colors duration-150",
+ "border border-border/40 bg-background/60 shadow-sm hover:bg-accent/50 hover:text-foreground-foreground hover:border-border/60 transition-colors duration-150",
secondary:
"bg-secondary text-muted-foreground-foreground shadow-xs hover:bg-secondary/80",
ghost:
diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx
index 6aacab1..4669c8a 100644
--- a/src/components/ui/input.tsx
+++ b/src/components/ui/input.tsx
@@ -8,7 +8,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
type={type}
data-slot="input"
className={cn(
- "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground bg-background/50 text-foreground border-border/40 flex h-10 w-full min-w-0 border px-3 py-2 text-sm shadow-sm backdrop-blur-sm transition-all duration-200 outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground bg-background/50 text-foreground border-border/40 flex h-10 w-full min-w-0 border px-3 py-2 text-sm shadow-sm transition-all duration-200 outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
"focus-visible:border-ring focus-visible:bg-background/80 focus-visible:ring-ring/20 focus-visible:ring-[3px]",
"hover:border-border/60 hover:bg-background/60",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
diff --git a/src/lib/email-templates/invoice-email.ts b/src/lib/email-templates/invoice-email.ts
index e3c5255..7fa1257 100644
--- a/src/lib/email-templates/invoice-email.ts
+++ b/src/lib/email-templates/invoice-email.ts
@@ -106,9 +106,9 @@ export function generateInvoiceEmailTemplate({
}
body {
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
line-height: 1.6;
- color: #1f2937;
+ color: #0f0f0f;
background-color: #f9fafb;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
@@ -118,14 +118,14 @@ export function generateInvoiceEmailTemplate({
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
- border-radius: 12px;
+ border-radius: 0;
overflow: hidden;
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
}
.header {
- background: linear-gradient(135deg, #16a34a 0%, #15803d 100%);
+ background: #0f0f0f;
padding: 32px 24px;
text-align: center;
color: white;
@@ -135,15 +135,15 @@ export function generateInvoiceEmailTemplate({
font-size: 28px;
font-weight: bold;
margin-bottom: 8px;
- letter-spacing: -0.5px;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ letter-spacing: 0.5px;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
}
.header-subtitle {
font-size: 16px;
- opacity: 0.9;
+ opacity: 0.8;
font-weight: normal;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
}
.content {
@@ -154,21 +154,21 @@ export function generateInvoiceEmailTemplate({
font-size: 16px;
font-weight: bold;
margin-bottom: 24px;
- color: #374151;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ color: #0f0f0f;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
}
.message {
font-size: 15px;
line-height: 1.7;
margin-bottom: 32px;
- color: #4b5563;
+ color: #374151;
}
.invoice-card {
- background-color: #f8fafc;
- border: 1px solid #e2e8f0;
- border-radius: 12px;
+ background-color: #f9fafb;
+ border: 1px solid #e5e7eb;
+ border-radius: 0;
padding: 16px;
margin: 24px 0;
}
@@ -180,9 +180,9 @@ export function generateInvoiceEmailTemplate({
.invoice-number {
font-size: 24px;
font-weight: bold;
- color: #16a34a;
+ color: #0f0f0f;
margin-bottom: 8px;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
}
.invoice-date {
@@ -243,9 +243,9 @@ export function generateInvoiceEmailTemplate({
.business-name {
font-size: 16px;
font-weight: bold;
- color: #1f2937;
+ color: #0f0f0f;
margin-bottom: 8px;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
}
.business-details {
@@ -268,8 +268,8 @@ export function generateInvoiceEmailTemplate({
text-align: center;
margin: 32px 0;
padding: 24px;
- background-color: #f8fafc;
- border-radius: 8px;
+ background-color: #f9fafb;
+ border-radius: 0;
}
.cta-text {
@@ -279,9 +279,9 @@ export function generateInvoiceEmailTemplate({
}
.attachment-notice {
- background-color: #f0fdf4;
- border: 1px solid #bbf7d0;
- border-radius: 8px;
+ background-color: #f9fafb;
+ border: 1px solid #e5e7eb;
+ border-radius: 0;
padding: 16px;
margin: 20px 0;
display: flex;
@@ -292,16 +292,16 @@ export function generateInvoiceEmailTemplate({
.attachment-icon {
width: 20px;
height: 20px;
- background-color: #16a34a;
- border-radius: 50%;
+ background-color: #374151;
+ border-radius: 0;
flex-shrink: 0;
}
.attachment-text {
font-size: 14px;
- color: #166534;
+ color: #374151;
font-weight: bold;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
}
.signature {
@@ -313,9 +313,9 @@ export function generateInvoiceEmailTemplate({
.signature-name {
font-size: 16px;
font-weight: bold;
- color: #1f2937;
+ color: #0f0f0f;
margin-bottom: 4px;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
}
.signature-email {
@@ -333,18 +333,19 @@ export function generateInvoiceEmailTemplate({
.footer-brand {
font-size: 18px;
font-weight: bold;
- color: #16a34a;
+ color: #0f0f0f;
margin: 0 auto 8px;
display: block;
text-align: center;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
+ letter-spacing: 0.5px;
}
.footer-text {
font-size: 12px;
- color: #9ca3af;
+ color: #6b7280;
line-height: 1.5;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
+ font-family: ui-monospace, 'Geist Mono', 'Courier New', monospace;
}
/* Email client specific fixes */
@@ -370,8 +371,8 @@ export function generateInvoiceEmailTemplate({
/* Apple Mail attachment preview fix */
.attachment-notice {
- border: 2px dashed #bbf7d0 !important;
- background-color: #f0fdf4 !important;
+ border: 1px solid #e5e7eb !important;
+ background-color: #f9fafb !important;
}
@media (max-width: 600px) {
@@ -414,7 +415,7 @@ export function generateInvoiceEmailTemplate({
${getTimeOfDayGreeting()},
I hope this email finds you well. Please find attached invoice #${invoice.invoiceNumber}
for the services provided. The invoice details are summarized below for your reference.
- ${customMessage ? `${customMessage}
` : ""}
+ ${customMessage ? `${customMessage}
` : ""}
${customContent ? `${customContent}
` : ""}
@@ -451,7 +452,7 @@ export function generateInvoiceEmailTemplate({
| Total |
- ${formatCurrency(total)} |
+ ${formatCurrency(total)} |
diff --git a/src/lib/email-templates/password-reset-email.ts b/src/lib/email-templates/password-reset-email.ts
index d9b25d9..02fd491 100644
--- a/src/lib/email-templates/password-reset-email.ts
+++ b/src/lib/email-templates/password-reset-email.ts
@@ -27,10 +27,10 @@ export function generatePasswordResetEmailTemplate({
Password Reset - beenvoice