Skip to content

Commit

Permalink
component becomes controlled
Browse files Browse the repository at this point in the history
  • Loading branch information
iSouvikKhan committed Aug 15, 2024
1 parent 7616617 commit 137f225
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 176 deletions.
2 changes: 0 additions & 2 deletions src/actions/payoutMethods/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,6 @@ const deleteSolanaHandler = async (
};
};



export const addUpi = createSafeAction(upiIdInsertSchema, addUpiHandler);

export const addSolanaAddress = createSafeAction(
Expand Down
8 changes: 4 additions & 4 deletions src/actions/payoutMethods/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { z } from 'zod';
export const payoutMethodSchema = z.object({
upiId: z
.string()
.refine((value) => /^[0-9A-Za-z._-]{2,256}@[A-Za-z]{2,64}$/.test(value), {
.refine((value) => (/^[0-9A-Za-z._-]{2,256}@[A-Za-z]{2,64}$/).test(value), {
message: 'Enter a valid UPI address',
})
.optional(),
solanaAddress: z
.string()
.refine((value) => /^[A-Za-z0-9]{44}$/.test(value), {
.refine((value) => (/^[A-Za-z0-9]{44}$/).test(value), {
message: 'Enter a valid Solana address',
})
.optional(),
Expand All @@ -18,13 +18,13 @@ export const payoutMethodSchema = z.object({
export const upiIdInsertSchema = z.object({
upiId: z
.string()
.refine((value) => /^[0-9A_Za-z._-]{2,256}@[A_Za-z]{2,64}$/.test(value), {
.refine((value) => (/^[0-9A_Za-z._-]{2,256}@[A_Za-z]{2,64}$/).test(value), {
message: 'Invalid UPI address',
}),
});

export const solanaAddressInsertSchema = z.object({
solanaAddress: z.string().refine((value) => /^[A-Za-z0-9]{44}$/.test(value), {
solanaAddress: z.string().refine((value) => (/^[A-Za-z0-9]{44}$/).test(value), {
message: 'Invalid Solana address',
}),
});
Expand Down
16 changes: 13 additions & 3 deletions src/actions/payoutMethods/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { z } from 'zod';
import { payoutMethodDeleteSchema, solanaAddressInsertSchema, upiIdInsertSchema } from './schema';
import {
payoutMethodDeleteSchema,
solanaAddressInsertSchema,
upiIdInsertSchema,
} from './schema';
import { ActionState } from '@/lib/create-safe-action';
import { SolanaAddress, UpiId } from '@prisma/client';
import { Delete } from '@/lib/utils';
Expand All @@ -8,7 +12,13 @@ export type InputTypeCreateUpi = z.infer<typeof upiIdInsertSchema>;
export type ReturnTypeCreateUpi = ActionState<InputTypeCreateUpi, UpiId>;

export type InputTypeCreateSolana = z.infer<typeof solanaAddressInsertSchema>;
export type ReturnTypeCreateSolana = ActionState<InputTypeCreateSolana, SolanaAddress>;
export type ReturnTypeCreateSolana = ActionState<
InputTypeCreateSolana,
SolanaAddress
>;

export type DeleteTypePayoutMethod = z.infer<typeof payoutMethodDeleteSchema>;
export type ReturnTypePayoutMethodDelete = ActionState<DeleteTypePayoutMethod, Delete>;
export type ReturnTypePayoutMethodDelete = ActionState<
DeleteTypePayoutMethod,
Delete
>;
272 changes: 149 additions & 123 deletions src/app/payout-methods/page.tsx
Original file line number Diff line number Diff line change
@@ -1,141 +1,167 @@
"use client"
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import NewPayoutDialog from "@/components/NewPayoutDialog";
import { Trash } from "lucide-react"
import { deleteSolanaAddress, deleteUpiId, getPayoutMethods } from "@/actions/payoutMethods";
import { SolanaAddress, UpiId } from "@prisma/client";
import { useAction } from "@/hooks/useAction";
import { toast } from "sonner";
'use client';
import { useEffect, useState } from 'react';
import { Button } from '@/components/ui/button';
import NewPayoutDialog from '@/components/NewPayoutDialog';
import { Trash } from 'lucide-react';
import {
deleteSolanaAddress,
deleteUpiId,
getPayoutMethods,
} from '@/actions/payoutMethods';
import { SolanaAddress, UpiId } from '@prisma/client';
import { useAction } from '@/hooks/useAction';
import { toast } from 'sonner';

export default function Page() {
const [isDialogBoxOpen, setIsDialogBoxOpen] = useState<boolean>(false);
const [btnClicked, setBtnClicked] = useState<string>('');

const [isDialogBoxOpen, setIsDialogBoxOpen] = useState<boolean>(false)
const [btnClicked, setBtnClicked] = useState<string>("")
const openDialog = (e: any) => {
setIsDialogBoxOpen(true);
setBtnClicked(e.target.id);
};

const openDialog = (e: any) => {
setIsDialogBoxOpen(true)
setBtnClicked(e.target.id)
}

const closeDialog = () => setIsDialogBoxOpen(false)
const closeDialog = () => setIsDialogBoxOpen(false);

const [upiAddresses, setUpiAddresses] = useState<UpiId[] | undefined>([])
const [solanaAddresses, setSolanaAddresses] = useState<SolanaAddress[] | undefined>([])
const [upiAddresses, setUpiAddresses] = useState<UpiId[] | undefined>([]);
const [solanaAddresses, setSolanaAddresses] = useState<
SolanaAddress[] | undefined
>([]);

const fetchPayoutMethods = async () => {
const result = await getPayoutMethods()
if (result) {
setUpiAddresses(result.upiIds)
setSolanaAddresses(result.solanaAddresses)
}
const fetchPayoutMethods = async () => {
const result = await getPayoutMethods();
if (result) {
setUpiAddresses(result.upiIds);
setSolanaAddresses(result.solanaAddresses);
}
};

const { execute: executeDeleteUPI } = useAction(deleteUpiId, {
onSuccess: () => {
toast.success("UPI Address deleted successfully")
},
onError: () => {
toast.error("Failed to delete UPI id")
}
})
const { execute: executeDeleteUPI } = useAction(deleteUpiId, {
onSuccess: () => {
toast.success('UPI Address deleted successfully');
},
onError: () => {
toast.error('Failed to delete UPI id');
},
});

const { execute: executeDeleteSolana } = useAction(deleteSolanaAddress, {
onSuccess: () => {
toast.success("Solana Address deleted successfully")
},
onError: () => {
toast.error("Failed to delete Solana address")
}
})
const { execute: executeDeleteSolana } = useAction(deleteSolanaAddress, {
onSuccess: () => {
toast.success('Solana Address deleted successfully');
},
onError: () => {
toast.error('Failed to delete Solana address');
},
});

const handleUpiDelete = (id: number) => {
executeDeleteUPI({ id: id })
fetchPayoutMethods()
}
const handleUpiDelete = (id: number) => {
executeDeleteUPI({ id });
fetchPayoutMethods();
};

const handleSolanaDelete = (id: number) => {
executeDeleteSolana({ id: id })
fetchPayoutMethods()
}
const handleSolanaDelete = (id: number) => {
executeDeleteSolana({ id });
fetchPayoutMethods();
};

useEffect(() => {
fetchPayoutMethods()
}, [])
useEffect(() => {
fetchPayoutMethods();
}, []);

useEffect(() => {
fetchPayoutMethods()
}, [isDialogBoxOpen])
useEffect(() => {
fetchPayoutMethods();
}, [isDialogBoxOpen]);

return (
<div className="h-max pb-4 transition-colors duration-500 md:p-8">
<div className="mb-6 flex flex-col items-start justify-center sm:px-8 px-4 pt-3">
<div className="text-3xl text-black transition-colors duration-500 dark:text-white">
<h1 className="text-black dark:text-white">Payout Methods</h1>
</div>
<div className="py-8 sm:px-0 px-2">
<div>
<div className="w-[90vw] flex justify-between">
<p className="font-semibold py-2">UPI Addresses</p>
<Button
id="UPI"
size="sm"
className="light:text-black sticky rounded-md bg-black hover:bg-[#242424] p-3 text-white transition-colors duration-500 dark:bg-white dark:text-black hover:dark:bg-white"
onClick={(e) => openDialog(e)}
>
Add UPI address
</Button>
<NewPayoutDialog onClose={closeDialog} isOpen={isDialogBoxOpen} title={btnClicked} />
</div>
<div className="flex flex-col sm:w-3/6 w-[90vw]">
{
upiAddresses?.length !== 0 ? (
upiAddresses?.map((upi, index) => (
<div key={index} className="w-full flex items-center justify-between py-2">
<p className="sm:w-full w-1/2 overflow-hidden text-ellipsis whitespace-nowrap" >{upi.value}</p>
<Button className="mx-3" size="iconSM" variant={"outline"}><Trash className="w-4 h-4" onClick={() => handleUpiDelete(upi.id)} /></Button>
</div>
))
) :
<div className="flex flex-col items-start">
<p className="py-3">No addresses added yet!</p>
</div>
}
</div>
</div>
return (
<div className="h-max pb-4 transition-colors duration-500 md:p-8">
<div className="mb-6 flex flex-col items-start justify-center px-4 pt-3 sm:px-8">
<div className="text-3xl text-black transition-colors duration-500 dark:text-white">
<h1 className="text-black dark:text-white">Payout Methods</h1>
</div>
<div className="px-2 py-8 sm:px-0">
<div>
<div className="flex w-[90vw] justify-between">
<p className="py-2 font-semibold">UPI Addresses</p>
<Button
id="UPI"
size="sm"
className="light:text-black sticky rounded-md bg-black p-3 text-white transition-colors duration-500 hover:bg-[#242424] dark:bg-white dark:text-black hover:dark:bg-white"
onClick={(e) => openDialog(e)}
>
Add UPI address
</Button>
<NewPayoutDialog
onClose={closeDialog}
isOpen={isDialogBoxOpen}
title={btnClicked}
/>
</div>
<div className="flex w-[90vw] flex-col sm:w-3/6">
{upiAddresses?.length !== 0 ? (
upiAddresses?.map((upi, index) => (
<div
key={index}
className="flex w-full items-center justify-between py-2"
>
<p className="w-1/2 overflow-hidden text-ellipsis whitespace-nowrap sm:w-full">
{upi.value}
</p>
<Button className="mx-3" size="iconSM" variant={'outline'}>
<Trash
className="h-4 w-4"
onClick={() => handleUpiDelete(upi.id)}
/>
</Button>
</div>
))
) : (
<div className="flex flex-col items-start">
<p className="py-3">No addresses added yet!</p>
</div>
<div className="py-4 sm:px-0 px-2">
<div>
<div className="w-[90vw] flex justify-between">
<p className="font-semibold py-2">Solana Addresses</p>
<Button
id="Solana"
size="sm"
className="light:text-black sticky rounded-md bg-black hover:bg-[#242424] p-3 text-white transition-colors duration-500 dark:bg-white dark:text-black hover:dark:bg-white"
onClick={(e) => openDialog(e)}
>
Add SOL address
</Button>
</div>
<div className="flex flex-col sm:w-3/6 w-[90vw]">
{
solanaAddresses?.length !== 0 ? (
solanaAddresses?.map((sol, index) => (
<div key={index} className="flex items-center justify-between py-2">
<p className="sm:w-full w-1/2 overflow-hidden text-ellipsis whitespace-nowrap" >{sol.value}</p>
<Button className="mx-3" size="iconSM" variant={"outline"}><Trash className="w-4 h-4" onClick={() => handleSolanaDelete(sol.id)} /></Button>
</div>
))
) :
<div className="flex flex-col items-start">
<p className="py-3">No addresses added yet!</p>
</div>
}
</div>
</div>
)}
</div>
</div>
</div>
<div className="px-2 py-4 sm:px-0">
<div>
<div className="flex w-[90vw] justify-between">
<p className="py-2 font-semibold">Solana Addresses</p>
<Button
id="Solana"
size="sm"
className="light:text-black sticky rounded-md bg-black p-3 text-white transition-colors duration-500 hover:bg-[#242424] dark:bg-white dark:text-black hover:dark:bg-white"
onClick={(e) => openDialog(e)}
>
Add SOL address
</Button>
</div>
<div className="flex w-[90vw] flex-col sm:w-3/6">
{solanaAddresses?.length !== 0 ? (
solanaAddresses?.map((sol, index) => (
<div
key={index}
className="flex items-center justify-between py-2"
>
<p className="w-1/2 overflow-hidden text-ellipsis whitespace-nowrap sm:w-full">
{sol.value}
</p>
<Button className="mx-3" size="iconSM" variant={'outline'}>
<Trash
className="h-4 w-4"
onClick={() => handleSolanaDelete(sol.id)}
/>
</Button>
</div>
))
) : (
<div className="flex flex-col items-start">
<p className="py-3">No addresses added yet!</p>
</div>

)}
</div>
</div>
</div>
);
}
</div>
</div>
);
}
19 changes: 11 additions & 8 deletions src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,11 @@ export function Sidebar({
<Link
key={content.id}
href={navigateToContent(content.id) || '#'}
className={`flex cursor-pointer border-b p-2 hover:bg-gray-200 ${isActiveContent
? 'bg-gray-300 text-black dark:bg-gray-700 dark:text-white dark:hover:bg-gray-500'
: 'bg-gray-50 text-black dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700'
}`}
className={`flex cursor-pointer border-b p-2 hover:bg-gray-200 ${
isActiveContent
? 'bg-gray-300 text-black dark:bg-gray-700 dark:text-white dark:hover:bg-gray-500'
: 'bg-gray-50 text-black dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700'
}`}
>
<div className="flex w-full justify-between">
<div className="flex">
Expand Down Expand Up @@ -189,12 +190,14 @@ export function ToggleButton({
className={`block h-0.5 w-6 rounded-sm bg-black transition-all duration-300 ease-out dark:bg-white ${!sidebarOpen ? 'translate-y-1 rotate-45' : '-translate-y-0.5'}`}
></span>
<span
className={`my-0.5 block h-0.5 w-6 rounded-sm bg-black transition-all duration-300 ease-out dark:bg-white ${!sidebarOpen ? 'opacity-0' : 'opacity-100'
}`}
className={`my-0.5 block h-0.5 w-6 rounded-sm bg-black transition-all duration-300 ease-out dark:bg-white ${
!sidebarOpen ? 'opacity-0' : 'opacity-100'
}`}
></span>
<span
className={`block h-0.5 w-6 rounded-sm bg-black transition-all duration-300 ease-out dark:bg-white ${!sidebarOpen ? '-translate-y-1 -rotate-45' : 'translate-y-0.5'
}`}
className={`block h-0.5 w-6 rounded-sm bg-black transition-all duration-300 ease-out dark:bg-white ${
!sidebarOpen ? '-translate-y-1 -rotate-45' : 'translate-y-0.5'
}`}
></span>
</button>
);
Expand Down
Loading

0 comments on commit 137f225

Please sign in to comment.