feat: apply figma responsive home design
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 49s
@@ -7,6 +7,6 @@ Source: Figma file `uHDZkVHjAp7BXDKQKB0PM4`, responsive reference node `3761:109
|
|||||||
- `banner-576.png` — mobile/tablet banner crop from node `3726:13099`.
|
- `banner-576.png` — mobile/tablet banner crop from node `3726:13099`.
|
||||||
- `banner-440.png` — mobile banner crop from node `3726:14199`.
|
- `banner-440.png` — mobile banner crop from node `3726:14199`.
|
||||||
- `banner-375.png` — mobile banner crop from node `3726:14238`.
|
- `banner-375.png` — mobile banner crop from node `3726:14238`.
|
||||||
- `recommendation-1.png` ... `recommendation-5.png` — official recommendation cover exports from the 1920px frame card image nodes.
|
- `official-recommendation-1.png` ... `official-recommendation-5.png` — official recommendation cover exports from the 1920px frame card image nodes; used only as fallback/placeholder covers so real resource cards keep accurate API-provided imagery.
|
||||||
|
|
||||||
These files are visual UI assets only. They do not change backend data or API contracts.
|
These files are visual UI assets only. They do not change backend data or API contracts.
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 167 KiB |
17
src/App.tsx
@@ -1,3 +1,4 @@
|
|||||||
|
import { lazy, Suspense } from "react";
|
||||||
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
|
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
|
||||||
import { I18nProvider } from "./i18n";
|
import { I18nProvider } from "./i18n";
|
||||||
import { PublicLayout } from "./layouts/PublicLayout";
|
import { PublicLayout } from "./layouts/PublicLayout";
|
||||||
@@ -7,12 +8,17 @@ import { CategoryPage } from "./pages/CategoryPage";
|
|||||||
import { SearchPage } from "./pages/SearchPage";
|
import { SearchPage } from "./pages/SearchPage";
|
||||||
import { FavoritesPage } from "./pages/FavoritesPage";
|
import { FavoritesPage } from "./pages/FavoritesPage";
|
||||||
import { ResourceDetail } from "./pages/ResourceDetail";
|
import { ResourceDetail } from "./pages/ResourceDetail";
|
||||||
import { WalletPage } from "./pages/WalletPage";
|
|
||||||
import { AboutPage } from "./pages/AboutPage";
|
import { AboutPage } from "./pages/AboutPage";
|
||||||
import { adminUiPrefix } from "./adminPaths";
|
import { adminUiPrefix } from "./adminPaths";
|
||||||
import { AdminRouteTree } from "./adminRouteTree";
|
import { AdminRouteTree } from "./adminRouteTree";
|
||||||
import { AdminRouterModeProvider } from "./adminRouterMode";
|
import { AdminRouterModeProvider } from "./adminRouterMode";
|
||||||
|
|
||||||
|
const WalletPage = lazy(() =>
|
||||||
|
import("./pages/WalletPage").then((module) => ({
|
||||||
|
default: module.WalletPage,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
const adminEnabled = import.meta.env.VITE_DISABLE_ADMIN !== "true";
|
const adminEnabled = import.meta.env.VITE_DISABLE_ADMIN !== "true";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
@@ -28,7 +34,14 @@ export default function App() {
|
|||||||
<Route path="/search" element={<SearchPage />} />
|
<Route path="/search" element={<SearchPage />} />
|
||||||
<Route path="/favorites" element={<FavoritesPage />} />
|
<Route path="/favorites" element={<FavoritesPage />} />
|
||||||
<Route path="/resource/:id" element={<ResourceDetail />} />
|
<Route path="/resource/:id" element={<ResourceDetail />} />
|
||||||
<Route path="/wallet" element={<WalletPage />} />
|
<Route
|
||||||
|
path="/wallet"
|
||||||
|
element={
|
||||||
|
<Suspense fallback={null}>
|
||||||
|
<WalletPage />
|
||||||
|
</Suspense>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Route path="/about" element={<AboutPage />} />
|
<Route path="/about" element={<AboutPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
const FIGMA_ASSET_BASE = "/assets/ark-library/figma";
|
const FIGMA_ASSET_BASE = "/assets/ark-library/figma";
|
||||||
|
|
||||||
export const recommendationCoverFallbacks = [
|
export const officialRecommendationCoverFallbacks = [
|
||||||
`${FIGMA_ASSET_BASE}/recommendation-1.png`,
|
`${FIGMA_ASSET_BASE}/official-recommendation-1.png`,
|
||||||
`${FIGMA_ASSET_BASE}/recommendation-2.png`,
|
`${FIGMA_ASSET_BASE}/official-recommendation-2.png`,
|
||||||
`${FIGMA_ASSET_BASE}/recommendation-3.png`,
|
`${FIGMA_ASSET_BASE}/official-recommendation-3.png`,
|
||||||
`${FIGMA_ASSET_BASE}/recommendation-4.png`,
|
`${FIGMA_ASSET_BASE}/official-recommendation-4.png`,
|
||||||
`${FIGMA_ASSET_BASE}/recommendation-5.png`,
|
`${FIGMA_ASSET_BASE}/official-recommendation-5.png`,
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export function FigmaBanner() {
|
export function FigmaBanner() {
|
||||||
return (
|
return (
|
||||||
<picture className="block overflow-hidden border border-[#2a2a32] bg-black shadow-[0_24px_70px_rgba(0,0,0,0.18)] max-md:-mx-4 max-md:rounded-none max-md:border-x-0 md:rounded-xl">
|
<picture className="-mx-4 block overflow-hidden border border-[#2a2a32] bg-black shadow-[0_24px_70px_rgba(0,0,0,0.18)] min-[440px]:-mx-5 sm:-mx-6 md:mx-0 md:rounded-xl">
|
||||||
<source
|
<source
|
||||||
media="(max-width: 439px)"
|
media="(max-width: 439px)"
|
||||||
srcSet={`${FIGMA_ASSET_BASE}/banner-375.png`}
|
srcSet={`${FIGMA_ASSET_BASE}/banner-375.png`}
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import { assetUrl, postJSON } from "../api";
|
|||||||
import { useI18n } from "../i18n";
|
import { useI18n } from "../i18n";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { formatDateYmd } from "../utils/format";
|
import { formatDateYmd } from "../utils/format";
|
||||||
import { recommendationCoverFallbacks } from "./FigmaBanner";
|
import { officialRecommendationCoverFallbacks } from "./FigmaBanner";
|
||||||
|
|
||||||
function isPlaceholderAsset(path: string | undefined | null) {
|
function isPlaceholderAsset(path: string | undefined | null) {
|
||||||
return !path || path.includes("placeholder-cover");
|
return !path || path.includes("placeholder-cover");
|
||||||
}
|
}
|
||||||
|
|
||||||
const CARD_CLASS =
|
const CARD_CLASS =
|
||||||
"group flex w-[232px] shrink-0 flex-col overflow-hidden rounded-xl border border-ark-line bg-ark-panel transition hover:border-ark-gold/55 max-[439px]:w-[232px] min-[440px]:w-[230px] sm:w-[240px] lg:w-[246.4px]";
|
"group flex w-[232px] shrink-0 flex-col overflow-hidden rounded-xl border border-ark-line bg-ark-panel transition hover:border-ark-gold/55 max-[439px]:w-[232px] min-[440px]:w-[230px] sm:w-[240px] lg:w-[246.4px] min-[1100px]:max-xl:w-[273px] xl:w-[246.4px]";
|
||||||
|
|
||||||
export function RecommendedCard({
|
export function RecommendedCard({
|
||||||
r,
|
r,
|
||||||
@@ -25,8 +25,8 @@ export function RecommendedCard({
|
|||||||
const cover = useMemo(() => {
|
const cover = useMemo(() => {
|
||||||
const original = r.coverImage || r.previewUrl;
|
const original = r.coverImage || r.previewUrl;
|
||||||
if (isPlaceholderAsset(original)) {
|
if (isPlaceholderAsset(original)) {
|
||||||
return recommendationCoverFallbacks[
|
return officialRecommendationCoverFallbacks[
|
||||||
visualIndex % recommendationCoverFallbacks.length
|
visualIndex % officialRecommendationCoverFallbacks.length
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return assetUrl(original);
|
return assetUrl(original);
|
||||||
@@ -105,8 +105,8 @@ export function ComingSoonRecommendedCard({
|
|||||||
visualIndex?: number;
|
visualIndex?: number;
|
||||||
}) {
|
}) {
|
||||||
const cover =
|
const cover =
|
||||||
recommendationCoverFallbacks[
|
officialRecommendationCoverFallbacks[
|
||||||
visualIndex % recommendationCoverFallbacks.length
|
visualIndex % officialRecommendationCoverFallbacks.length
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export function PublicLayout() {
|
|||||||
return (
|
return (
|
||||||
<div className="min-h-full flex flex-col pb-20 md:pb-0">
|
<div className="min-h-full flex flex-col pb-20 md:pb-0">
|
||||||
<header className="sticky top-0 z-40 border-b border-ark-line bg-ark-nav/98 backdrop-blur-md">
|
<header className="sticky top-0 z-40 border-b border-ark-line bg-ark-nav/98 backdrop-blur-md">
|
||||||
<div className="mx-auto max-w-[1280px] px-4 py-[15px] md:px-8 xl:px-0">
|
<div className="mx-auto max-w-[1280px] px-4 py-[15px] min-[440px]:px-5 sm:px-6 md:px-9 xl:px-0">
|
||||||
{/* Single row (md+): logo | scrollable nav (左對齊,可橫向滑動) | 搜尋 + 語言 */}
|
{/* Single row (md+): logo | scrollable nav (左對齊,可橫向滑動) | 搜尋 + 語言 */}
|
||||||
<div className="flex h-10 items-center gap-2 lg:gap-4">
|
<div className="flex h-10 items-center gap-2 lg:gap-4">
|
||||||
<Link
|
<Link
|
||||||
@@ -85,13 +85,13 @@ export function PublicLayout() {
|
|||||||
className="flex min-w-0 shrink-0 items-center gap-2.5 rounded-sm text-xl font-bold tracking-wide text-ark-gold outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
|
className="flex min-w-0 shrink-0 items-center gap-2.5 rounded-sm text-xl font-bold tracking-wide text-ark-gold outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
|
||||||
>
|
>
|
||||||
<ArkLogoMark className="h-10 w-10 shrink-0" />
|
<ArkLogoMark className="h-10 w-10 shrink-0" />
|
||||||
<span className="max-w-[9rem] truncate text-ark-gold sm:inline md:max-w-[10rem] lg:max-w-none">
|
<span className="max-w-[7.125rem] truncate text-ark-gold sm:inline">
|
||||||
{t("brand")}
|
{t("brand")}
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<nav
|
<nav
|
||||||
className="header-nav-scroll hidden min-w-0 flex-1 items-center justify-center gap-4 overflow-x-auto overflow-y-hidden py-1 md:flex lg:gap-5"
|
className="header-nav-scroll hidden min-w-0 flex-1 items-center justify-center gap-4 overflow-x-auto overflow-y-hidden py-1 min-[1200px]:flex lg:gap-5"
|
||||||
aria-label={t("mainNav")}
|
aria-label={t("mainNav")}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
@@ -152,15 +152,15 @@ export function PublicLayout() {
|
|||||||
</Link>
|
</Link>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div className="flex shrink-0 items-center justify-end gap-2">
|
<div className="flex min-w-0 flex-1 items-center justify-end gap-2 min-[1200px]:flex-none">
|
||||||
<div className="hidden h-10 items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] py-2 pl-3 pr-3 shadow-inner md:flex lg:pr-4">
|
<div className="hidden h-10 min-w-0 flex-1 items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] py-2 pl-3 pr-3 shadow-inner md:flex min-[1200px]:w-44 min-[1200px]:flex-none lg:pr-4 xl:w-52">
|
||||||
<SearchIcon size={16} className="shrink-0 text-[#c6c7cf]" />
|
<SearchIcon size={16} className="shrink-0 text-[#c6c7cf]" />
|
||||||
<input
|
<input
|
||||||
value={q}
|
value={q}
|
||||||
onChange={(e) => setQ(e.target.value)}
|
onChange={(e) => setQ(e.target.value)}
|
||||||
onKeyDown={(e) => e.key === "Enter" && goSearch()}
|
onKeyDown={(e) => e.key === "Enter" && goSearch()}
|
||||||
placeholder={t("searchPlaceholder")}
|
placeholder={t("searchPlaceholder")}
|
||||||
className="w-24 rounded-md bg-transparent text-sm text-neutral-200 outline-none placeholder:text-[#777985] focus-visible:ring-2 focus-visible:ring-ark-gold/60 focus-visible:ring-offset-2 focus-visible:ring-offset-[#1a1b20] md:w-28 lg:w-44 xl:w-52"
|
className="min-w-0 flex-1 rounded-md bg-transparent text-sm text-neutral-200 outline-none placeholder:text-[#777985] focus-visible:ring-2 focus-visible:ring-ark-gold/60 focus-visible:ring-offset-2 focus-visible:ring-offset-[#1a1b20]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden h-10 items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] px-2 py-2 md:flex lg:px-3">
|
<div className="hidden h-10 items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] px-2 py-2 md:flex lg:px-3">
|
||||||
@@ -182,7 +182,7 @@ export function PublicLayout() {
|
|||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="md:hidden inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-ark-line bg-[#1a1b20] text-neutral-200 outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
|
className="inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-ark-line bg-[#1a1b20] text-neutral-200 outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg min-[1200px]:hidden"
|
||||||
onClick={() => setOpen((v) => !v)}
|
onClick={() => setOpen((v) => !v)}
|
||||||
aria-label="menu"
|
aria-label="menu"
|
||||||
>
|
>
|
||||||
@@ -193,7 +193,7 @@ export function PublicLayout() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{open ? (
|
{open ? (
|
||||||
<div className="md:hidden border-t border-ark-line bg-ark-nav px-4 py-3 grid gap-2">
|
<div className="grid gap-2 border-t border-ark-line bg-ark-nav px-4 py-3 min-[440px]:px-5 sm:px-6 md:px-9 min-[1200px]:hidden">
|
||||||
<div className="mb-1 flex items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] px-3 py-2">
|
<div className="mb-1 flex items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] px-3 py-2">
|
||||||
<SearchIcon size={16} className="shrink-0 text-[#c6c7cf]" />
|
<SearchIcon size={16} className="shrink-0 text-[#c6c7cf]" />
|
||||||
<input
|
<input
|
||||||
@@ -280,12 +280,12 @@ export function PublicLayout() {
|
|||||||
) : null}
|
) : null}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main className="mx-auto w-full max-w-[1280px] flex-1 px-4 py-6 md:px-8 md:py-10 xl:px-0">
|
<main className="mx-auto w-full max-w-[1280px] flex-1 px-4 py-6 min-[440px]:px-5 sm:px-6 md:px-9 md:py-10 xl:px-0">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer className="mt-auto border-t border-ark-line bg-ark-nav/90 mb-20 md:mb-0">
|
<footer className="mt-auto border-t border-ark-line bg-ark-nav/90 mb-20 md:mb-0">
|
||||||
<div className="mx-auto flex max-w-[1280px] flex-wrap gap-x-6 gap-y-2 px-4 py-6 text-sm text-neutral-400 md:px-8 xl:px-0">
|
<div className="mx-auto flex max-w-[1280px] flex-wrap gap-x-6 gap-y-2 px-4 py-6 text-sm text-neutral-400 min-[440px]:px-5 sm:px-6 md:px-9 xl:px-0">
|
||||||
<Link
|
<Link
|
||||||
to="/about"
|
to="/about"
|
||||||
className="rounded-sm outline-none hover:text-ark-gold2 focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
|
className="rounded-sm outline-none hover:text-ark-gold2 focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
|
||||||
|
|||||||
21
src/main.tsx
@@ -1,11 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { WagmiProvider } from "wagmi";
|
|
||||||
import { RainbowKitProvider, darkTheme } from "@rainbow-me/rainbowkit";
|
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import "@rainbow-me/rainbowkit/styles.css";
|
|
||||||
import { wagmiConfig } from "./wagmiConfig";
|
|
||||||
|
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
@@ -27,20 +23,9 @@ void (async () => {
|
|||||||
const { default: App } = await import("./App");
|
const { default: App } = await import("./App");
|
||||||
ReactDOM.createRoot(root).render(
|
ReactDOM.createRoot(root).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<WagmiProvider config={wagmiConfig}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<QueryClientProvider client={queryClient}>
|
<App />
|
||||||
<RainbowKitProvider
|
</QueryClientProvider>
|
||||||
theme={darkTheme({
|
|
||||||
accentColor: "#d4af37",
|
|
||||||
accentColorForeground: "#0a0a0a",
|
|
||||||
borderRadius: "medium",
|
|
||||||
})}
|
|
||||||
modalSize="wide"
|
|
||||||
>
|
|
||||||
<App />
|
|
||||||
</RainbowKitProvider>
|
|
||||||
</QueryClientProvider>
|
|
||||||
</WagmiProvider>
|
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
);
|
);
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export function Home() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-12 pb-10 md:space-y-14 md:pb-16">
|
<div className="space-y-[30px] pb-10 md:space-y-10 md:pb-16 xl:space-y-[34px]">
|
||||||
<section className="-mt-6 md:mt-0">
|
<section className="-mt-6 md:mt-0">
|
||||||
<FigmaBanner />
|
<FigmaBanner />
|
||||||
</section>
|
</section>
|
||||||
@@ -69,7 +69,7 @@ export function Home() {
|
|||||||
viewAllTo="/browse"
|
viewAllTo="/browse"
|
||||||
viewAllLabel={t("viewAll")}
|
viewAllLabel={t("viewAll")}
|
||||||
/>
|
/>
|
||||||
<div className="mt-7 grid grid-cols-3 gap-3 min-[440px]:gap-3.5 md:grid-cols-5 md:gap-3 xl:grid-cols-7 xl:gap-4">
|
<div className="mt-7 grid grid-cols-3 gap-3 min-[440px]:gap-3.5 md:grid-cols-5 md:gap-3 lg:grid-cols-6 xl:grid-cols-7 xl:gap-4">
|
||||||
{cats.map((c) => {
|
{cats.map((c) => {
|
||||||
const { line1, line2 } = categoryCardLines(c.name);
|
const { line1, line2 } = categoryCardLines(c.name);
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
|
import { RainbowKitProvider, darkTheme } from "@rainbow-me/rainbowkit";
|
||||||
|
import { WagmiProvider } from "wagmi";
|
||||||
|
import "@rainbow-me/rainbowkit/styles.css";
|
||||||
import { WalletLoginControls } from "../components/WalletLoginControls";
|
import { WalletLoginControls } from "../components/WalletLoginControls";
|
||||||
import { useI18n } from "../i18n";
|
import { useI18n } from "../i18n";
|
||||||
|
import { wagmiConfig } from "../wagmiConfig";
|
||||||
|
|
||||||
export function WalletPage() {
|
export function WalletPage() {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -16,7 +20,27 @@ export function WalletPage() {
|
|||||||
<li>{t("walletStepSign")}</li>
|
<li>{t("walletStepSign")}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div className="rounded-2xl border border-ark-line bg-ark-panel p-6 space-y-4">
|
<div className="rounded-2xl border border-ark-line bg-ark-panel p-6 space-y-4">
|
||||||
<WalletLoginControls />
|
{import.meta.env.VITE_WALLETCONNECT_PROJECT_ID ? (
|
||||||
|
<WagmiProvider config={wagmiConfig}>
|
||||||
|
<RainbowKitProvider
|
||||||
|
theme={darkTheme({
|
||||||
|
accentColor: "#d4af37",
|
||||||
|
accentColorForeground: "#0a0a0a",
|
||||||
|
borderRadius: "medium",
|
||||||
|
})}
|
||||||
|
modalSize="wide"
|
||||||
|
>
|
||||||
|
<WalletLoginControls />
|
||||||
|
</RainbowKitProvider>
|
||||||
|
</WagmiProvider>
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
className="text-sm text-amber-500/90 leading-relaxed"
|
||||||
|
title={t("walletMissingProjectId")}
|
||||||
|
>
|
||||||
|
{t("walletSetupNeeded")}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||