From 7725ea5ea3b2088496532d74ac412635e13ac064 Mon Sep 17 00:00:00 2001 From: Kris Urbas <605420+krzysu@users.noreply.github.com> Date: Tue, 7 Jan 2025 20:20:31 +0100 Subject: [PATCH] feat: edit wallet set dialog --- .github/copilot-instructions.md | 48 ++++++++++++++ .gitignore | 1 - .../TokenSelect/TokenSelectItem.tsx | 7 +- .../app/routes/api.updateWalletSet.tsx | 9 +++ .../components/EditWalletSetDialog.tsx | 64 +++++++++++++++++++ .../app/routes/wallets.$id/route.tsx | 6 +- 6 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 .github/copilot-instructions.md create mode 100644 packages/circle-demo-webapp/app/routes/api.updateWalletSet.tsx create mode 100644 packages/circle-demo-webapp/app/routes/wallets.$id/components/EditWalletSetDialog.tsx diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..0f40cb4 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,48 @@ +Role Definition + +You are an expert in JavaScript, TypeScript, React.js, Remix.js, ShadCN/UI, and Tailwind CSS. Your goal is to generate concise, high-quality code snippets and guidelines that follow the latest best practices and make efficient use of tokens. Ensure readability, maintainability, and component reusability. + +Include the following expertise: +• Modern JavaScript (ES6+): Standard functions, destructuring, template literals, modules, etc. +• TypeScript: Strong type inference, generics, and strict null checks. +• React.js: Functional components, hooks (useState, useEffect, useMemo, useCallback), and context API. +• Remix.js: Nested routes, loaders, actions, and forms. +• Tailwind CSS: Utility-first classes, responsive design, and support for dark theme. + +General Rules for All Languages: 1. Code Conciseness: +Write concise and meaningful code without unnecessary comments or verbose explanations. 2. Best Practices: +Adhere to modern conventions (e.g., const/let over var, avoiding any in TypeScript unless explicitly required). 3. Error Handling: +Always include robust error handling in examples (try/catch for async operations, proper useErrorBoundary in Remix.js). 4. Code Formatting: +• Use consistent formatting (2 spaces for indentation). +• Follow Prettier-like conventions for line length and trailing commas. +• Keep imports organized (external libraries first, then internal). + +TypeScript Rules: +• Use interface for defining object shapes and type for unions. +• Prefer unknown over any for stricter type safety. +• Leverage utility types (Partial, Required, Pick, Omit). +• Enable strict mode to catch nullish and undefined values early. + +React.js Rules: +• Always use functional components with hooks. +• Prefer useState for local state and useReducer for complex state management. +• Memoize expensive calculations using useMemo. +• Wrap event handlers in useCallback when passing down as props to prevent re-renders. + +Remix.js Rules: +• Avoid Remix-specific Loaders and Actions for data fetching and mutations. Instead, use a framework-agnostic solution like SWR, React Query, or native fetch to keep components reusable across different frameworks. +• Use native
components when possible, but implement form submission handling using reusable functions that abstract the request logic (e.g., handleSubmit functions that work with fetch or axios). +• Handle errors in a framework-independent way by using React’s ErrorBoundary or fallback components instead of Remix-specific CatchBoundary for broader compatibility. + +ShadCN/UI Rules: +• Use ShadCN UI pre-built components as the foundation for consistent, accessible UI. +• Avoid direct customization of core ShadCN components; instead, extend them via className props using Tailwind’s theme-aware utility classes (e.g., bg-background, text-primary). +• Leverage ShadCN’s slots and compound components (e.g., , ) to create modular, highly composable UI. +• Override default styles with Tailwind @apply in custom classes when necessary instead of inline classes for complex styling. +• Prefer using Tailwind tokens over hardcoded color values for better theme support. + +Tailwind CSS Rules: +• Use utility-first classes instead of custom CSS unless absolutely necessary. +• Avoid classes that directly define specific colors (like text-red-500, bg-blue-400). Instead, use theme-aware generic classes (like text-primary, bg-background) that reference your Tailwind theme for easy dark mode and theme switching. +• Leverage @apply for reusable style combinations in custom components. +• Use responsive design classes (sm:, md:, lg:) and variants (hover:, focus:, dark:) to add interactivity and dark mode support. diff --git a/.gitignore b/.gitignore index adb20af..2dc1482 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,3 @@ node_modules .vscode tmp .history -.github/copilot-instructions.md \ No newline at end of file diff --git a/packages/circle-demo-webapp/app/components/TokenSelect/TokenSelectItem.tsx b/packages/circle-demo-webapp/app/components/TokenSelect/TokenSelectItem.tsx index 6fb5e6e..275fdb8 100644 --- a/packages/circle-demo-webapp/app/components/TokenSelect/TokenSelectItem.tsx +++ b/packages/circle-demo-webapp/app/components/TokenSelect/TokenSelectItem.tsx @@ -17,11 +17,8 @@ export function TokenSelectItem({ balance }: TokenSelectItemProps) { variant="branded" className="flex-shrink-0" /> - -
-

- {balance.amount} {balance.token.symbol} -

+
+ {balance.amount} {balance.token.symbol}
); diff --git a/packages/circle-demo-webapp/app/routes/api.updateWalletSet.tsx b/packages/circle-demo-webapp/app/routes/api.updateWalletSet.tsx new file mode 100644 index 0000000..c3d5e6c --- /dev/null +++ b/packages/circle-demo-webapp/app/routes/api.updateWalletSet.tsx @@ -0,0 +1,9 @@ +import { UpdateWalletSetInput } from '@circle-fin/developer-controlled-wallets'; +import { ActionFunction } from '@remix-run/node'; + +import { sdk } from '~/lib/sdk'; + +export const action: ActionFunction = async ({ request }) => { + const res = await sdk.updateWalletSet((await request.json()) as UpdateWalletSetInput); + return Response.json(res.data); +}; diff --git a/packages/circle-demo-webapp/app/routes/wallets.$id/components/EditWalletSetDialog.tsx b/packages/circle-demo-webapp/app/routes/wallets.$id/components/EditWalletSetDialog.tsx new file mode 100644 index 0000000..c37492a --- /dev/null +++ b/packages/circle-demo-webapp/app/routes/wallets.$id/components/EditWalletSetDialog.tsx @@ -0,0 +1,64 @@ +import { useFetcher } from '@remix-run/react'; +import { FilePenLine, LoaderCircle } from 'lucide-react'; +import { useState } from 'react'; + +import { Button } from '~/components/ui/button'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '~/components/ui/dialog'; +import { Input } from '~/components/ui/input'; +import { WalletSet } from '~/lib/types'; + +interface EditWalletSetDialogProps { + walletSet: WalletSet; +} + +export function EditWalletSetDialog({ walletSet }: EditWalletSetDialogProps) { + const [open, setOpen] = useState(false); + const fetcher = useFetcher(); + + return ( + + + + + + + + Edit Wallet Set + Edit wallet set + + + { + setOpen(false); + }} + > +
+ + +
+ +
+
+
+ ); +} diff --git a/packages/circle-demo-webapp/app/routes/wallets.$id/route.tsx b/packages/circle-demo-webapp/app/routes/wallets.$id/route.tsx index bbf48e8..53842ba 100644 --- a/packages/circle-demo-webapp/app/routes/wallets.$id/route.tsx +++ b/packages/circle-demo-webapp/app/routes/wallets.$id/route.tsx @@ -8,6 +8,7 @@ import { sdk } from '~/lib/sdk'; import { TypeBlockchain, Wallet, WalletSet } from '~/lib/types'; import { isValidString } from '~/lib/utils'; +import { EditWalletSetDialog } from './components/EditWalletSetDialog'; import { NewWalletDialog } from './components/NewWalletDialog'; export async function loader({ params }: { params: { id: string } }) { @@ -62,7 +63,10 @@ function Header({ walletSet }: { walletSet: WalletSet }) { return (
-

Wallet Set

+
+

Wallet Set

+ +

Name: {walletSet.name}

ID: {walletSet.id}