Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/lite/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="preconnect" href="https://cdn.morpho.org" />
<link rel="preconnect" href="https://app.family.co" />
<link rel="preconnect" href="https://static.cloudflareinsights.com" />
<link rel="preload" href="/src/index.css" as="style" />
<link href="/src/index.css" rel="stylesheet" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>%VITE_APP_TITLE%</title>
Expand Down
3 changes: 1 addition & 2 deletions apps/lite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"@tanstack/react-query-persist-client": "^5.66.0",
"blo": "^1.2.0",
"connectkit": "^1.8.2",
"core-js": "3.42.0",
"gql.tada": "^1.8.10",
"humanize-duration": "^3.32.1",
"lucide-react": "^0.475.0",
Expand All @@ -37,7 +36,6 @@
"react-router": "^7.4.0",
"recharts": "^2.15.1",
"sonner": "^2.0.0",
"tailwind-merge": "^3.0.1",
"tailwindcss-animate": "^1.0.7",
"urql": "^4.2.2",
"viem": "~2.29.1",
Expand All @@ -46,6 +44,7 @@
"devDependencies": {
"@fleek-platform/cli": "^3.8.2",
"@tailwindcss/vite": "^4.0.6",
"@types/humanize-duration": "^3.27.4",
"@vitejs/plugin-react": "^4.3.4",
"tailwindcss": "^4.0.6",
"terser": "^5.39.0",
Expand Down
3 changes: 3 additions & 0 deletions apps/lite/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
User-agent: *
Allow: /

17 changes: 10 additions & 7 deletions apps/lite/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AddressScreeningModal } from "@morpho-org/uikit/components/address-screening-modal";
import { SafeLinkModal } from "@morpho-org/uikit/components/safe-link-modal";
import { TooltipProvider } from "@morpho-org/uikit/components/shadcn/tooltip";
import { AddressScreeningProvider } from "@morpho-org/uikit/hooks/use-address-screening";
import { SafeLinksProvider } from "@morpho-org/uikit/hooks/use-safe-links";
import { cyrb64Hash } from "@morpho-org/uikit/lib/cyrb64";
Expand Down Expand Up @@ -59,13 +60,15 @@ function App({ children, wagmiConfig = defaultWagmiConfig }: { children: ReactNo
}}
>
<UrqlProvider value={urqlClient}>
<AddressScreeningProvider>
<SafeLinksProvider>
{children}
<SafeLinkModal />
</SafeLinksProvider>
<AddressScreeningModal />
</AddressScreeningProvider>
<TooltipProvider>
Copy link
Author

@fscgustavo fscgustavo Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following Radix UI best practices, wrapping the entire application in a single is efficient because it allows all tooltip components to share a common configuration (like delay duration). This avoids redundant provider instances, keeps the component tree cleaner and with less code to compile.

https://www.radix-ui.com/primitives/docs/components/tooltip#provider

If a specific tooltip ever needs unique timing or behavior, we can still nest a separate provider locally for that case, but the global one handles the default case for the whole app.

<AddressScreeningProvider>
<SafeLinksProvider>
{children}
<SafeLinkModal />
</SafeLinksProvider>
<AddressScreeningModal />
</AddressScreeningProvider>
</TooltipProvider>
</UrqlProvider>
</ConnectKitProvider>
</PersistQueryClientProvider>
Expand Down
79 changes: 41 additions & 38 deletions apps/lite/src/app/dashboard/borrow-subpage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { AccrualPosition } from "@morpho-org/blue-sdk";
import { restructure } from "@morpho-org/blue-sdk-viem";
import { metaMorphoFactoryAbi } from "@morpho-org/uikit/assets/abis/meta-morpho-factory";
import { morphoAbi } from "@morpho-org/uikit/assets/abis/morpho";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@morpho-org/uikit/components/shadcn/tabs";
import useContractEvents from "@morpho-org/uikit/hooks/use-contract-events/use-contract-events";
import {
marketHasDeadDeposit,
Expand All @@ -16,6 +17,7 @@ import { type Address, erc20Abi, type Chain, zeroAddress, type Hex } from "viem"
import { useAccount, useReadContract, useReadContracts } from "wagmi";

import { BorrowPositionTable, BorrowTable } from "@/components/borrow-table";
import { BoxTopRoundedCorners } from "@/components/box-top-rounded-corners";
import { CtaCard } from "@/components/cta-card";
import { useMarkets } from "@/hooks/use-markets";
import * as Merkl from "@/hooks/use-merkl-campaigns";
Expand Down Expand Up @@ -240,41 +242,42 @@ export function BorrowSubPage() {

return (
<div className="flex min-h-screen flex-col px-2.5 pt-16">
{status === "disconnected" ? (
<div className="bg-linear-to-b flex w-full flex-col from-transparent to-white/[0.03] px-8 pb-20 pt-8">
<CtaCard
className="md:w-7xl flex flex-col gap-4 md:mx-auto md:max-w-full md:flex-row md:items-center md:justify-between"
bigText="Provide collateral to borrow any asset"
littleText="Connect wallet to get started"
videoSrc={{
mov: "https://cdn.morpho.org/v2/assets/videos/borrow-animation.mov",
webm: "https://cdn.morpho.org/v2/assets/videos/borrow-animation.webm",
}}
/>
</div>
) : (
userMarkets.length > 0 && (
<div className="bg-linear-to-b lg:pt-22 flex h-fit w-full flex-col items-center from-transparent to-white/[0.03] pb-20">
<div className="text-primary-foreground w-full max-w-7xl px-2 lg:px-8">
<BorrowPositionTable
chain={chain}
markets={userMarkets}
tokens={tokens}
positions={positions}
borrowingRewards={borrowingRewards}
refetchPositions={refetchPositionsRaw}
/>
</div>
</div>
)
)}
{/*
Outer div ensures background color matches the end of the gradient from the div above,
allowing rounded corners to show correctly. Inner div defines rounded corners and table background.
*/}
<div className="flex grow flex-col bg-white/[0.03]">
<div className="bg-linear-to-b from-background to-primary flex h-full grow justify-center rounded-t-xl pb-16 pt-8">
<div className="text-primary-foreground w-full max-w-7xl px-2 lg:px-8">
<div className="bg-linear-to-b to-white/3 flex w-full flex-col from-transparent px-8 pb-20 pt-8">
<CtaCard
bigText="Provide collateral to borrow any asset"
littleText="Connect wallet to get started"
videoSrc={{
mov: "https://cdn.morpho.org/v2/assets/videos/borrow-animation.mov",
webm: "https://cdn.morpho.org/v2/assets/videos/borrow-animation.webm",
}}
/>
</div>
<BoxTopRoundedCorners>
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BoxTopRoundedCorners to standardize the layout structure and avoid repetition

<Tabs
defaultValue={userMarkets.length > 0 ? "user-positions" : "markets"}
className="w-full max-w-7xl px-2 lg:px-8"
>
<TabsList className="grid grid-cols-2 p-0">
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we are matching the strategy used on the main Morpho app. By placing the static Call-to-Action (CTA) cards at the top, we ensure immediate visual feedback for the user without blocking the render. The data-heavy, asynchronous content (tables for user positions and markets) is moved to the bottom within Tabs. This separation allows the core interface to load instantly while heavier data fetches happen in the background, significantly improving perceived performance and eliminating the layout shift that would occur if dynamic content pushed the static elements down after loading.

<TabsTrigger
className="disabled:cursor-not-allowed!"
value="user-positions"
disabled={userMarkets.length === 0}
>
Your positions
</TabsTrigger>
<TabsTrigger value="markets">Markets</TabsTrigger>
</TabsList>
<TabsContent value="user-positions" className="mt-4">
<BorrowPositionTable
chain={chain}
markets={userMarkets}
tokens={tokens}
positions={positions}
borrowingRewards={borrowingRewards}
refetchPositions={refetchPositionsRaw}
/>
</TabsContent>
<TabsContent value="markets" className="mt-4">
<BorrowTable
chain={chain}
markets={marketsArr}
Expand All @@ -283,9 +286,9 @@ export function BorrowSubPage() {
borrowingRewards={borrowingRewards}
refetchPositions={refetchPositionsRaw}
/>
</div>
</div>
</div>
</TabsContent>
</Tabs>
</BoxTopRoundedCorners>
</div>
);
}
76 changes: 42 additions & 34 deletions apps/lite/src/app/dashboard/earn-subpage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from "@morpho-org/blue-sdk";
import { metaMorphoAbi } from "@morpho-org/uikit/assets/abis/meta-morpho";
import { metaMorphoFactoryAbi } from "@morpho-org/uikit/assets/abis/meta-morpho-factory";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@morpho-org/uikit/components/shadcn/tabs";
import useContractEvents from "@morpho-org/uikit/hooks/use-contract-events/use-contract-events";
import {
getDeadDepositsBitmap,
Expand All @@ -23,6 +24,7 @@ import { useOutletContext } from "react-router";
import { type Address, type Chain, erc20Abi, zeroAddress } from "viem";
import { useAccount, useReadContract, useReadContracts } from "wagmi";

import { BoxTopRoundedCorners } from "@/components/box-top-rounded-corners";
import { CtaCard } from "@/components/cta-card";
import { EarnTable } from "@/components/earn-table";
import { useMarkets } from "@/hooks/use-markets";
Expand Down Expand Up @@ -270,21 +272,33 @@ export function EarnSubPage() {

return (
<div className="flex min-h-screen flex-col px-2.5 pt-16">
{status === "disconnected" ? (
<div className="bg-linear-to-b flex w-full flex-col from-transparent to-white/[0.03] px-8 pb-20 pt-8">
<CtaCard
className="md:w-7xl flex flex-col gap-4 md:mx-auto md:max-w-full md:flex-row md:items-center md:justify-between"
bigText="Earn on your terms"
littleText="Connect wallet to get started"
videoSrc={{
mov: "https://cdn.morpho.org/v2/assets/videos/earn-animation.mov",
webm: "https://cdn.morpho.org/v2/assets/videos/earn-animation.webm",
}}
/>
</div>
) : (
userRows.length > 0 && (
<div className="bg-linear-to-b lg:pt-22 flex h-fit w-full flex-col items-center from-transparent to-white/[0.03] pb-20">
<div className="bg-linear-to-b to-white/3 flex w-full flex-col from-transparent pb-20">
<CtaCard
bigText="Earn on your terms"
littleText="Connect wallet to get started"
videoSrc={{
mov: "https://cdn.morpho.org/v2/assets/videos/earn-animation.mov",
webm: "https://cdn.morpho.org/v2/assets/videos/earn-animation.webm",
}}
/>
</div>

<BoxTopRoundedCorners>
<Tabs
defaultValue={userRows.length > 0 ? "user-positions" : "vaults"}
className="w-full max-w-7xl px-2 lg:px-8"
>
<TabsList className="grid grid-cols-2 p-0">
<TabsTrigger
className="disabled:cursor-not-allowed!"
value="user-positions"
disabled={userRows.length === 0}
>
Your positions
</TabsTrigger>
<TabsTrigger value="vaults">Vaults</TabsTrigger>
</TabsList>
<TabsContent value="user-positions" className="mt-4">
<EarnTable
chain={chain}
rows={userRows}
Expand All @@ -293,25 +307,19 @@ export function EarnSubPage() {
lendingRewards={lendingRewards}
refetchPositions={refetchBalanceOf}
/>
</div>
)
)}
{/*
Outer div ensures background color matches the end of the gradient from the div above,
allowing rounded corners to show correctly. Inner div defines rounded corners and table background.
*/}
<div className="flex grow flex-col bg-white/[0.03]">
<div className="bg-linear-to-b from-background to-primary flex h-full grow justify-center rounded-t-xl pb-16 pt-8">
<EarnTable
chain={chain}
rows={rows}
depositsMode="totalAssets"
tokens={tokens}
lendingRewards={lendingRewards}
refetchPositions={refetchBalanceOf}
/>
</div>
</div>
</TabsContent>
<TabsContent value="vaults" className="mt-4">
<EarnTable
chain={chain}
rows={rows}
depositsMode="totalAssets"
tokens={tokens}
lendingRewards={lendingRewards}
refetchPositions={refetchBalanceOf}
/>
</TabsContent>
</Tabs>
</BoxTopRoundedCorners>
</div>
);
}
17 changes: 1 addition & 16 deletions apps/lite/src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { Button } from "@morpho-org/uikit/components/shadcn/button";
import { WalletMenu } from "@morpho-org/uikit/components/wallet-menu";
import { CORE_DEPLOYMENTS } from "@morpho-org/uikit/lib/deployments";
import { getChainSlug } from "@morpho-org/uikit/lib/utils";
import { ConnectKitButton } from "connectkit";
import { useCallback, useEffect, useMemo } from "react";
import { Link, Outlet, useLocation, useNavigate, useParams } from "react-router";
import { Toaster } from "sonner";
import { useChains } from "wagmi";

import { ConnectWalletButton } from "@/components/connect-wallet-button";
import { Footer } from "@/components/footer";
import { Header } from "@/components/header";
import { MorphoMenu } from "@/components/morpho-menu";
Expand All @@ -21,21 +21,6 @@ enum SubPage {
Borrow = "borrow",
}

function ConnectWalletButton() {
return (
<ConnectKitButton.Custom>
{({ show }) => {
return (
<Button variant="blue" size="lg" className="rounded-full px-4 font-light md:px-6" onClick={show}>
<span className="inline md:hidden">Connect</span>
<span className="hidden md:inline">Connect&nbsp;Wallet</span>
</Button>
);
}}
</ConnectKitButton.Custom>
);
}

export default function Page() {
const navigate = useNavigate();
const { chain: selectedChainSlug } = useParams();
Expand Down
Loading