refactor: implement device payment verification with useActionState hook 🔨

This commit is contained in:
2025-07-06 23:06:51 +05:00
parent 837cc35ad3
commit 1a11f1a06c
2 changed files with 131 additions and 50 deletions

View File

@ -6,9 +6,9 @@ import {
Loader2,
Wallet,
} from "lucide-react";
import { useState } from "react";
import { useActionState, useEffect, useState } from "react";
import { toast } from "sonner";
import { verifyPayment } from "@/actions/payment";
import { type VerifyDevicePaymentState, verifyDevicePayment } from "@/actions/payment";
import {
Table,
TableBody,
@ -21,13 +21,32 @@ import type { Payment } from "@/lib/backend-types";
import type { User } from "@/lib/types/user";
import { Button } from "./ui/button";
const initialState: VerifyDevicePaymentState = {
message: "",
success: false,
fieldErrors: {},
};
export default function DevicesToPay({
payment,
user,
}: { payment?: Payment; user?: User }) {
const [verifyingWalletPayment, setVerifyingWalletPayment] = useState(false);
const [verifyingTransferPayment, setVerifyingTransferPayment] = useState(false);
const [state, formAction, isPending] = useActionState(verifyDevicePayment, initialState);
// Handle toast notifications based on state changes
useEffect(() => {
if (state.success && state.message) {
toast.success("Payment successful!", {
closeButton: true,
description: state.message,
});
} else if (!state.success && state.message && state.message !== initialState.message) {
toast.error("Payment Verification Failed", {
closeButton: true,
description: state.message,
});
}
}, [state]);
const devices = payment?.devices;
if (devices?.length === 0) {
@ -81,53 +100,37 @@ export default function DevicesToPay({
) : (
<div className="flex flex-col gap-2">
{isWalletPayVisible && (
<Button
disabled={verifyingWalletPayment || verifyingTransferPayment}
onClick={async () => {
setVerifyingWalletPayment(true);
await verifyPayment({
method: "WALLET",
id: payment?.id ?? "",
});
setVerifyingWalletPayment(false);
}}
variant={"secondary"}
size={"lg"}
>
{verifyingWalletPayment ? "Processing payment..." : "Pay with wallet"}
<Wallet />
</Button>
<form action={formAction}>
<input type="hidden" name="paymentId" value={payment?.id ?? ""} />
<input type="hidden" name="method" value="WALLET" />
<Button
disabled={isPending}
type="submit"
variant={"secondary"}
size={"lg"}
>
{isPending ? "Processing payment..." : "Pay with wallet"}
<Wallet />
</Button>
</form>
)}
<Button
disabled={verifyingTransferPayment || verifyingWalletPayment}
onClick={async () => {
setVerifyingTransferPayment(true);
try {
await verifyPayment({
id: payment?.id ?? "",
method: "TRANSFER"
});
toast.success("Payment verification successful!");
} catch (error: unknown) {
if (error instanceof Error) {
toast.error(error.message);
} else {
toast.error("Payment verification failed.");
}
} finally {
setVerifyingTransferPayment(false);
}
}}
size={"lg"}
className="mb-4"
>
{verifyingTransferPayment ? "Processing payment..." : "I have paid"}
{verifyingTransferPayment ? (
<Loader2 className="animate-spin" />
) : (
<BadgeDollarSign />
)}
</Button>
<form action={formAction}>
<input type="hidden" name="paymentId" value={payment?.id ?? ""} />
<input type="hidden" name="method" value="TRANSFER" />
<Button
disabled={isPending}
type="submit"
size={"lg"}
className="mb-4"
>
{isPending ? "Processing payment..." : "I have paid"}
{isPending ? (
<Loader2 className="animate-spin" />
) : (
<BadgeDollarSign />
)}
</Button>
</form>
</div>
)}
</div>