Skip to content

Commit 11555a4

Browse files
committed
feat: loading states for invoices
1 parent 5115e61 commit 11555a4

File tree

1 file changed

+41
-15
lines changed

1 file changed

+41
-15
lines changed

app/(app)/apps/invoices/components/invoice-generator.tsx

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "
55
import { fetchAsBase64 } from "@/lib/utils"
66
import { SettingsMap } from "@/models/settings"
77
import { Currency, User } from "@/prisma/client"
8-
import { FileDown, Save, TextSelect, X } from "lucide-react"
8+
import { FileDown, Loader2, Save, TextSelect, X } from "lucide-react"
99
import { useRouter } from "next/navigation"
1010
import { startTransition, useMemo, useReducer, useState } from "react"
1111
import {
@@ -83,6 +83,8 @@ export function InvoiceGenerator({
8383
const [isTemplateDialogOpen, setIsTemplateDialogOpen] = useState(false)
8484
const [newTemplateName, setNewTemplateName] = useState("")
8585
const [formData, dispatch] = useReducer(invoiceFormReducer, templates[0].formData)
86+
const [isPdfLoading, setIsPdfLoading] = useState(false)
87+
const [isSavingTransaction, setIsSavingTransaction] = useState(false)
8688

8789
const router = useRouter()
8890

@@ -97,12 +99,13 @@ export function InvoiceGenerator({
9799

98100
const handleGeneratePDF = async (e: React.FormEvent) => {
99101
e.preventDefault()
100-
101-
if (formData.businessLogo) {
102-
formData.businessLogo = await fetchAsBase64(formData.businessLogo)
103-
}
102+
setIsPdfLoading(true)
104103

105104
try {
105+
if (formData.businessLogo) {
106+
formData.businessLogo = await fetchAsBase64(formData.businessLogo)
107+
}
108+
106109
const pdfBuffer = await generateInvoicePDF(formData)
107110

108111
// Create a blob from the buffer
@@ -126,6 +129,8 @@ export function InvoiceGenerator({
126129
} catch (error) {
127130
console.error("Error generating PDF:", error)
128131
alert("Failed to generate PDF. Please try again.")
132+
} finally {
133+
setIsPdfLoading(false)
129134
}
130135
}
131136

@@ -179,12 +184,13 @@ export function InvoiceGenerator({
179184
// Accept optional event, prevent default only if present
180185
const handleSaveAsTransaction = async (e?: React.FormEvent) => {
181186
if (e) e.preventDefault()
182-
183-
if (formData.businessLogo) {
184-
formData.businessLogo = await fetchAsBase64(formData.businessLogo)
185-
}
187+
setIsSavingTransaction(true)
186188

187189
try {
190+
if (formData.businessLogo) {
191+
formData.businessLogo = await fetchAsBase64(formData.businessLogo)
192+
}
193+
188194
const result = await saveInvoiceAsTransactionAction(formData)
189195
if (result.success && result.data?.id) {
190196
console.log("SUCCESS! REDIRECTING TO TRANSACTION", result.data?.id)
@@ -197,6 +203,8 @@ export function InvoiceGenerator({
197203
} catch (error) {
198204
console.error("Error saving as transaction:", error)
199205
alert("Failed to save as transaction. Please try again.")
206+
} finally {
207+
setIsSavingTransaction(false)
200208
}
201209
}
202210

@@ -235,17 +243,35 @@ export function InvoiceGenerator({
235243

236244
{/* Generate PDF Button */}
237245
<div className="flex flex-col gap-4">
238-
<Button onClick={handleGeneratePDF}>
239-
<FileDown />
240-
Download PDF
246+
<Button onClick={handleGeneratePDF} disabled={isPdfLoading}>
247+
{isPdfLoading ? (
248+
<>
249+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
250+
Generating...
251+
</>
252+
) : (
253+
<>
254+
<FileDown className="mr-2" />
255+
Download PDF
256+
</>
257+
)}
241258
</Button>
242259
<Button variant="secondary" onClick={() => setIsTemplateDialogOpen(true)}>
243260
<TextSelect />
244261
Make a Template
245262
</Button>
246-
<Button variant="secondary" onClick={handleSaveAsTransaction}>
247-
<Save />
248-
Save as Transaction
263+
<Button variant="secondary" onClick={handleSaveAsTransaction} disabled={isSavingTransaction}>
264+
{isSavingTransaction ? (
265+
<>
266+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
267+
Saving...
268+
</>
269+
) : (
270+
<>
271+
<Save className="mr-2" />
272+
Save as Transaction
273+
</>
274+
)}
249275
</Button>
250276
</div>
251277
</div>

0 commit comments

Comments
 (0)