From 58f13f0a63f9091a87f2cfd77bd5711ded2c8919 Mon Sep 17 00:00:00 2001
From: Aimen Sahnoun
Date: Fri, 30 May 2025 15:07:36 +0400
Subject: [PATCH 01/18] feat: Add Direct Payment page and component for instant
payouts
---
src/app/{direct-payment => payouts}/page.tsx | 11 +++++------
.../{direct-payment.tsx => direct-payout.tsx} | 4 ++--
src/components/header.tsx | 4 ++--
3 files changed, 9 insertions(+), 10 deletions(-)
rename src/app/{direct-payment => payouts}/page.tsx (78%)
rename src/components/{direct-payment.tsx => direct-payout.tsx} (99%)
diff --git a/src/app/direct-payment/page.tsx b/src/app/payouts/page.tsx
similarity index 78%
rename from src/app/direct-payment/page.tsx
rename to src/app/payouts/page.tsx
index ba4ea16b..402b1f51 100644
--- a/src/app/direct-payment/page.tsx
+++ b/src/app/payouts/page.tsx
@@ -1,5 +1,5 @@
import { BackgroundWrapper } from "@/components/background-wrapper";
-import { DirectPayment } from "@/components/direct-payment";
+import { DirectPayment } from "@/components/direct-payout";
import { Footer } from "@/components/footer";
import { Header } from "@/components/header";
import { getCurrentSession } from "@/server/auth";
@@ -7,8 +7,9 @@ import type { Metadata } from "next";
import { redirect } from "next/navigation";
export const metadata: Metadata = {
- title: "Direct Payment | Easy Invoice",
- description: "Send payments directly without creating a request first",
+ title: "Payouts | Easy Invoice",
+ description:
+ "Make a single or batch payouts without having to create a request first",
};
export default async function DirectPaymentPage() {
@@ -26,9 +27,7 @@ export default async function DirectPaymentPage() {
>
-
- Direct Payment
-
+ Payouts
Send payments quickly without having to create a request first.
diff --git a/src/components/direct-payment.tsx b/src/components/direct-payout.tsx
similarity index 99%
rename from src/components/direct-payment.tsx
rename to src/components/direct-payout.tsx
index bc277ec3..9db9784b 100644
--- a/src/components/direct-payment.tsx
+++ b/src/components/direct-payout.tsx
@@ -190,10 +190,10 @@ export function DirectPayment() {
- Direct Payment
+ Direct Payout
- Send payments instantly without creating a request first
+ Make a single payout instantly without creating a request first
diff --git a/src/components/header.tsx b/src/components/header.tsx
index 89cc4737..6252dbfd 100644
--- a/src/components/header.tsx
+++ b/src/components/header.tsx
@@ -36,10 +36,10 @@ export function Header({ user }: { user?: User | undefined }) {
Dashboard
- Direct Payment
+ Payouts
Date: Fri, 30 May 2025 15:18:27 +0400
Subject: [PATCH 02/18] feat: Introduce PayoutTabs component for managing
single and batch payouts
---
src/app/payouts/page.tsx | 4 ++--
src/components/batch-payout.tsx | 3 +++
src/components/payout-tabs.tsx | 27 +++++++++++++++++++++++++++
3 files changed, 32 insertions(+), 2 deletions(-)
create mode 100644 src/components/batch-payout.tsx
create mode 100644 src/components/payout-tabs.tsx
diff --git a/src/app/payouts/page.tsx b/src/app/payouts/page.tsx
index 402b1f51..dffd7d44 100644
--- a/src/app/payouts/page.tsx
+++ b/src/app/payouts/page.tsx
@@ -1,7 +1,7 @@
import { BackgroundWrapper } from "@/components/background-wrapper";
-import { DirectPayment } from "@/components/direct-payout";
import { Footer } from "@/components/footer";
import { Header } from "@/components/header";
+import { PayoutTabs } from "@/components/payout-tabs";
import { getCurrentSession } from "@/server/auth";
import type { Metadata } from "next";
import { redirect } from "next/navigation";
@@ -32,7 +32,7 @@ export default async function DirectPaymentPage() {
Send payments quickly without having to create a request first.
-
+
diff --git a/src/components/batch-payout.tsx b/src/components/batch-payout.tsx
new file mode 100644
index 00000000..03df00ab
--- /dev/null
+++ b/src/components/batch-payout.tsx
@@ -0,0 +1,3 @@
+export function BatchPayout() {
+ return Batch Payout
;
+}
diff --git a/src/components/payout-tabs.tsx b/src/components/payout-tabs.tsx
new file mode 100644
index 00000000..b2f379c2
--- /dev/null
+++ b/src/components/payout-tabs.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+import { BatchPayout } from "@/components/batch-payout";
+import { DirectPayment } from "@/components/direct-payout";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
+import { useState } from "react";
+
+export function PayoutTabs() {
+ const [activeTab, setActiveTab] = useState("single");
+
+ return (
+
+
+ Single Payout
+ Batch Payout
+
+
+
+
+
+
+
+
+
+
+ );
+}
From 95a14af1d08305815e0710257f53d6c1c6c7a5da Mon Sep 17 00:00:00 2001
From: Aimen Sahnoun
Date: Fri, 30 May 2025 15:37:39 +0400
Subject: [PATCH 03/18] refactor: Replace INVOICE_CURRENCIES with
EXTENDED_INVOICE_CURRENCIES and update related logic in invoice form
---
src/components/invoice-form.tsx | 4 ++--
src/lib/constants/currencies.ts | 22 +++++++++++++++-------
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/src/components/invoice-form.tsx b/src/components/invoice-form.tsx
index 6906c61a..39b900e1 100644
--- a/src/components/invoice-form.tsx
+++ b/src/components/invoice-form.tsx
@@ -21,7 +21,7 @@ import {
import { Textarea } from "@/components/ui/textarea";
import { PaymentDetailsStatus as PaymentDetailsStatusEnum } from "@/lib/constants/bank-account";
import {
- INVOICE_CURRENCIES,
+ EXTENDED_INVOICE_CURRENCIES,
type InvoiceCurrency,
MAINNET_CURRENCIES,
type MainnetCurrency,
@@ -831,7 +831,7 @@ export function InvoiceForm({
- {INVOICE_CURRENCIES.map((currency) => (
+ {EXTENDED_INVOICE_CURRENCIES.map((currency) => (
{formatCurrencyLabel(currency)}
{currency === "fUSDC-sepolia" && (
diff --git a/src/lib/constants/currencies.ts b/src/lib/constants/currencies.ts
index 3b355354..0bcdd744 100644
--- a/src/lib/constants/currencies.ts
+++ b/src/lib/constants/currencies.ts
@@ -24,31 +24,39 @@ export const INVOICE_CURRENCIES = [
"FAU-sepolia",
"fUSDC-sepolia",
"fUSDT-sepolia",
- ...MAINNET_CURRENCIES,
] as const;
-export type InvoiceCurrency = (typeof INVOICE_CURRENCIES)[number];
-export const PAYMENT_CURRENCIES: Partial<{
- [K in InvoiceCurrency]: readonly string[];
-}> = {
+export const PAYMENT_CURRENCIES = {
USD: ["ETH-sepolia-sepolia", "FAU-sepolia"] as const,
"ETH-sepolia-sepolia": ["ETH-sepolia-sepolia"] as const,
"FAU-sepolia": ["FAU-sepolia"] as const,
"fUSDC-sepolia": ["fUSDC-sepolia"] as const,
"fUSDT-sepolia": ["fUSDT-sepolia"] as const,
+};
+
+export const EXTENDED_INVOICE_CURRENCIES = [
+ ...INVOICE_CURRENCIES,
+ ...MAINNET_CURRENCIES,
+] as const;
+export type InvoiceCurrency = (typeof EXTENDED_INVOICE_CURRENCIES)[number];
+
+export const EXTENDED_PAYMENT_CURRENCIES: Partial<{
+ [K in InvoiceCurrency]: readonly string[];
+}> = {
+ ...PAYMENT_CURRENCIES,
...Object.fromEntries(
MAINNET_CURRENCIES.map((currency) => [currency, [currency]]),
),
} as const;
export type PaymentCurrency = NonNullable<
- (typeof PAYMENT_CURRENCIES)[InvoiceCurrency]
+ (typeof EXTENDED_PAYMENT_CURRENCIES)[InvoiceCurrency]
>[number];
export function getPaymentCurrenciesForInvoice(
invoiceCurrency: InvoiceCurrency,
): PaymentCurrency[] {
- return [...(PAYMENT_CURRENCIES[invoiceCurrency] || [])];
+ return [...(EXTENDED_PAYMENT_CURRENCIES[invoiceCurrency] || [])];
}
export function formatCurrencyLabel(currency: string): string {
From 3f002851b4921bee3365dabf5ddf9838781087ef Mon Sep 17 00:00:00 2001
From: Aimen Sahnoun
Date: Fri, 30 May 2025 15:42:25 +0400
Subject: [PATCH 04/18] refactor: Update currency types to use
ExtendedInvoiceCurrency and adjust invoice schema accordingly
---
src/components/invoice-form.tsx | 4 ++--
src/lib/constants/currencies.ts | 8 ++++++--
src/lib/schemas/invoice.ts | 4 ++--
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/components/invoice-form.tsx b/src/components/invoice-form.tsx
index 39b900e1..98768c7c 100644
--- a/src/components/invoice-form.tsx
+++ b/src/components/invoice-form.tsx
@@ -22,7 +22,7 @@ import { Textarea } from "@/components/ui/textarea";
import { PaymentDetailsStatus as PaymentDetailsStatusEnum } from "@/lib/constants/bank-account";
import {
EXTENDED_INVOICE_CURRENCIES,
- type InvoiceCurrency,
+ type ExtendedInvoiceCurrency,
MAINNET_CURRENCIES,
type MainnetCurrency,
formatCurrencyLabel,
@@ -818,7 +818,7 @@ export function InvoiceForm({