Skip to content

Commit

Permalink
feat: NewWalletForm
Browse files Browse the repository at this point in the history
  • Loading branch information
krzysu committed Jan 27, 2025
1 parent bf2747a commit 3c0f5d5
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { NewWalletForm, NewWalletFormInput } from '@circle-libs/circle-react-elements';
import { Plus } from 'lucide-react';
import { useState } from 'react';
import { SubmitHandler } from 'react-hook-form';

import { Button } from '~/components/ui/button';
import {
Expand All @@ -10,8 +12,7 @@ import {
DialogTitle,
DialogTrigger,
} from '~/components/ui/dialog';

import { NewWalletForm } from './NewWalletForm';
import { useCreateWallet } from '~/hooks/useCreateWallet';

interface NewWalletDialogProps {
walletSetId: string;
Expand All @@ -20,6 +21,30 @@ interface NewWalletDialogProps {

export function NewWalletDialog({ walletSetId, onSuccess }: NewWalletDialogProps) {
const [open, setOpen] = useState(false);
const { createWallet, isLoading, error } = useCreateWallet();

const onSubmit: SubmitHandler<NewWalletFormInput> = async ({
walletSetId,
name,
blockchain,
description,
}) => {
const success = await createWallet({
walletSetId,
name,
blockchain,
description,
});

if (!success) {
return;
}

setOpen(false);
if (typeof onSuccess === 'function') {
onSuccess();
}
};

return (
<Dialog open={open} onOpenChange={setOpen}>
Expand All @@ -39,12 +64,9 @@ export function NewWalletDialog({ walletSetId, onSuccess }: NewWalletDialogProps

<NewWalletForm
walletSetId={walletSetId}
onSuccess={() => {
setOpen(false);
if (typeof onSuccess === 'function') {
onSuccess();
}
}}
isSubmitting={isLoading}
onSubmit={onSubmit}
serverError={error}
/>
</DialogContent>
</Dialog>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';

import { NewWalletForm } from './NewWalletForm';

const meta = {
title: 'NewWalletForm',
component: NewWalletForm,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
} satisfies Meta<typeof NewWalletForm>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
walletSetId: 'f270e785-0a7b-578d-a43c-bd514fcc4d49',
isSubmitting: false,
onSubmit: fn(),
serverError: undefined,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { LoaderCircle, Plus } from 'lucide-react';
import { SubmitHandler, useForm } from 'react-hook-form';
import { z } from 'zod';

import { FormErrorText } from '../FormErrorText';
import { TestChainSelect } from '../TestChainSelect';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Textarea } from '../ui/textarea';

const formSchema = z.object({
walletSetId: z.string(),
name: z.string().nonempty('Name must not be empty'),
description: z.string().optional(),
blockchain: z.string().nonempty('Blockchain must be selected'),
});

export type NewWalletFormInput = z.infer<typeof formSchema>;

export interface NewWalletFormProps {
walletSetId: string;
isSubmitting?: boolean;
onSubmit: SubmitHandler<NewWalletFormInput>;
serverError?: Error;
}

export function NewWalletForm({
walletSetId,
isSubmitting,
onSubmit,
serverError,
}: NewWalletFormProps) {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<NewWalletFormInput>({
resolver: zodResolver(formSchema),
defaultValues: {
walletSetId,
},
});

return (
<form onSubmit={(e) => void handleSubmit(onSubmit)(e)} className="space-y-8">
<div className="space-y-4">
<input type="hidden" {...register('walletSetId')} />

<div>
<Input
type="text"
placeholder="Enter wallet name"
error={errors.name}
{...register('name')}
/>
<FormErrorText message={errors.name?.message} />
</div>

<div>
<Textarea
placeholder="Enter description (optional)"
className="min-h-[100px]"
{...register('description')}
/>
<FormErrorText message={errors.description?.message} />
</div>

<div>
<TestChainSelect {...register('blockchain')} />
<FormErrorText message={errors.blockchain?.message} />
</div>
</div>

<Button type="submit" className="w-full" disabled={isSubmitting}>
{isSubmitting ? <LoaderCircle className="animate-spin" /> : <Plus />}
Create Wallet
</Button>

<FormErrorText message={serverError?.message} />
</form>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './NewWalletForm';
1 change: 1 addition & 0 deletions packages/circle-react-elements/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './components/ChainLabel';
export * from './components/ChainSelect';
export * from './components/ComplianceEngineText';
export * from './components/EditWalletForm';
export * from './components/NewWalletForm';
export * from './components/NewWalletSetForm';
export * from './components/SendTransactionForm';
export * from './components/TestChainSelect';
Expand Down

0 comments on commit 3c0f5d5

Please sign in to comment.