Loans diff --git a/apps/investor-tokenization/src/features/transparency/ProjectList.tsx b/apps/investor-tokenization/src/features/transparency/ProjectList.tsx index a58b26f..3e1cb52 100644 --- a/apps/investor-tokenization/src/features/transparency/ProjectList.tsx +++ b/apps/investor-tokenization/src/features/transparency/ProjectList.tsx @@ -38,7 +38,7 @@ export const ProjectList = ({ search = "", filter = "all" }: ProjectListProps) = queryFn: async () => { const result = await getEscrowByContractIds({ contractIds: escrowIds, - validateOnChain: true, + validateOnChain: false, }); const list = Array.isArray(result) ? result @@ -48,6 +48,7 @@ export const ProjectList = ({ search = "", filter = "all" }: ProjectListProps) = return list as GetEscrowsFromIndexerResponse[]; }, enabled: escrowIds.length > 0, + staleTime: 1000 * 60 * 10, }); const escrowsById = useMemo(() => { @@ -76,9 +77,7 @@ export const ProjectList = ({ search = "", filter = "all" }: ProjectListProps) = }); }, [search, filter, visibleCampaigns]); - const isLoading = isCampaignsLoading || isEscrowsLoading; - - if (!isLoading && filteredCampaigns.length === 0) { + if (!isCampaignsLoading && filteredCampaigns.length === 0) { return (
No campaigns available.
diff --git a/docs/plans/2026-03-13-update-roi-percentage.md b/docs/plans/2026-03-13-update-roi-percentage.md new file mode 100644 index 0000000..2b14878 --- /dev/null +++ b/docs/plans/2026-03-13-update-roi-percentage.md @@ -0,0 +1,398 @@ +# Update ROI Percentage — Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Allow backoffice admins to update the ROI percentage of a campaign's vault from the `/roi` page via an actions dropdown menu. + +**Architecture:** Add a dropdown-menu UI component, an API call function, a hook (following `useToggleVault` pattern), and a dialog (following `FundRoiDialog` pattern). Replace inline action buttons in the ROI table row with a dropdown menu that groups all actions. + +**Tech Stack:** React 19, Next.js 16, Radix UI (dropdown-menu), TanStack React Query, Soroban wallet signing, sonner toasts. + +--- + +### Task 1: Add DropdownMenu UI component + +**Files:** +- Create: `packages/ui/src/dropdown-menu.tsx` + +**Step 1: Install Radix dropdown-menu dependency** + +Run from repo root: +```bash +cd packages/ui && npm install @radix-ui/react-dropdown-menu +``` + +**Step 2: Create the component** + +Create `packages/ui/src/dropdown-menu.tsx` exporting Radix primitives styled consistently with the existing dialog/popover components. Follow the same pattern as `packages/ui/src/dialog.tsx` — thin wrappers around Radix with Tailwind classes. + +Exports needed: +- `DropdownMenu` (Root) +- `DropdownMenuTrigger` +- `DropdownMenuContent` +- `DropdownMenuItem` +- `DropdownMenuSeparator` + +**Step 3: Export from package index** + +Verify the package uses path-based exports (e.g., `@tokenization/ui/dropdown-menu`). Check `packages/ui/package.json` exports field and add entry if needed. + +**Step 4: Verify build** + +Run: `npx turbo run build --filter=@tokenization/ui` +Expected: BUILD SUCCESS + +**Step 5: Commit** + +```bash +git add packages/ui/src/dropdown-menu.tsx packages/ui/package.json +git commit -m "feat(ui): add DropdownMenu component" +``` + +--- + +### Task 2: Add API call function + +**Files:** +- Modify: `apps/backoffice-tokenization/src/features/campaigns/services/campaigns.api.ts` + +**Step 1: Add `updateRoiPorcentage` function** + +Add to the bottom of `campaigns.api.ts`: + +```typescript +export async function updateRoiPorcentage(params: { + contractId: string; + newRoiPorcentage: number; + callerPublicKey: string; +}): Promise<{ unsignedXdr: string }> { + const { data } = await httpClient.post<{ unsignedXdr: string }>( + "/vault/update-roi-porcentage", + params, + ); + return data; +} +``` + +This calls the existing backend endpoint `POST /vault/update-roi-porcentage` which accepts `{ contractId, newRoiPorcentage, callerPublicKey }` and returns `{ unsignedXdr }`. + +**Step 2: Commit** + +```bash +git add apps/backoffice-tokenization/src/features/campaigns/services/campaigns.api.ts +git commit -m "feat: add updateRoiPorcentage API call" +``` + +--- + +### Task 3: Add `useUpdateRoiPercentage` hook + +**Files:** +- Create: `apps/backoffice-tokenization/src/features/campaigns/hooks/useUpdateRoiPercentage.ts` + +**Step 1: Create the hook** + +Follow the exact pattern of `useToggleVault.ts`: + +```typescript +"use client"; + +import { useState } from "react"; +import { useWalletContext } from "@tokenization/tw-blocks-shared/src/wallet-kit/WalletProvider"; +import { signTransaction } from "@tokenization/tw-blocks-shared/src/wallet-kit/wallet-kit"; +import { submitAndExtractAddress } from "@/features/campaigns/services/soroban.service"; +import { updateRoiPorcentage } from "@/features/campaigns/services/campaigns.api"; + +interface UseUpdateRoiPercentageParams { + onSuccess?: () => void; +} + +export function useUpdateRoiPercentage({ onSuccess }: UseUpdateRoiPercentageParams = {}) { + const { walletAddress } = useWalletContext(); + const [isSubmitting, setIsSubmitting] = useState(false); + const [error, setError] = useState