Skip to content
Draft
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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import { Suspense } from "react";

import SearchContracts from "./components/SearchContracts";
import SearchCollectionsLayout from "~/components/dashboard/SearchCollectionsLayout";
import SearchContracts from "~/components/SearchContracts";

export default function CollectionSearch({
params,
}: {
params: { search: string };
}) {
return (
<div className="container mx-auto px-4 py-12 sm:px-6 lg:px-8">
<div className="mb-8">
<h1 className="text-3xl font-bold">Search Results</h1>
<p className="text-muted-foreground">
Explore the contracts that match your search query.
</p>
</div>
<SearchCollectionsLayout search={params.search}>
<Suspense>
<SearchContracts search={params.search} />
</Suspense>
</div>
</SearchCollectionsLayout>
);
}
34 changes: 34 additions & 0 deletions ark-indexer-marketplace-admin/src/app/(dashboard)/indexer/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Suspense } from "react";
import type { NextPage } from "next";

import BlocksOverview from "~/components/dashboard/BlockOverview";
import BlocksOverviewSkeleton from "~/components/dashboard/BlockOverviewSkeleton";
import CreateIndexerTaskForm from "~/components/dashboard/CreateIndexerTaskForm";
import IndexerBlocksList from "~/components/dashboard/IndexerBlocksList";
import IndexerTasksList from "~/components/dashboard/IndexerTasksList";
import { TaskFormProvider } from "~/components/dashboard/TaskFormProvider";

const IndexerPage: NextPage = () => {
return (
<TaskFormProvider>
<div className="flex space-x-12">
<div className="flex-1 p-6">
<Suspense fallback={<BlocksOverviewSkeleton />}>
<BlocksOverview />
</Suspense>
<Suspense fallback={null}>
<IndexerTasksList />
</Suspense>
<Suspense fallback={null}>
<IndexerBlocksList />
</Suspense>
</div>
<div className="sticky top-0 h-screen border-l p-6">
<CreateIndexerTaskForm />
</div>
</div>
</TaskFormProvider>
);
};

export default IndexerPage;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { headers } from "next/headers";

import CollectionSearch from "~/components/CollectionSearch";
import Header from "~/components/dashboard/Header";
import { NetworkProvider } from "~/components/dashboard/NetworkProvider";
import { ThemeProvider } from "~/components/ThemeProvider";
Expand Down
56 changes: 28 additions & 28 deletions ark-indexer-marketplace-admin/src/app/(dashboard)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { Suspense } from "react";
import type { NextPage } from "next";

import BlocksOverview from "~/components/dashboard/BlockOverview";
import BlocksOverviewSkeleton from "~/components/dashboard/BlockOverviewSkeleton";
import CreateIndexerTaskForm from "~/components/dashboard/CreateIndexerTaskForm";
import IndexerBlocksList from "~/components/dashboard/IndexerBlocksList";
import IndexerTasksList from "~/components/dashboard/IndexerTasksList";
import { TaskFormProvider } from "~/components/dashboard/TaskFormProvider";
import CollectionSearch from "~/components/CollectionSearch";
import ContractGridItem from "~/components/dashboard/ContractGridItem";
import { api } from "~/trpc/server";
import SearchContracts from "../../components/SearchContracts";

export default async function DashboardPage({
params,
}: {
params: { search: string };
}) {
const contracts = await api.contract.getContracts.query();

const DashboardPage: NextPage = () => {
return (
<TaskFormProvider>
<div className="flex space-x-12">
<div className="flex-1 p-6">
<Suspense fallback={<BlocksOverviewSkeleton />}>
<BlocksOverview />
</Suspense>
<Suspense fallback={null}>
<IndexerTasksList />
</Suspense>
<Suspense fallback={null}>
<IndexerBlocksList />
</Suspense>
</div>
<div className="sticky top-0 h-screen border-l p-6">
<CreateIndexerTaskForm />
</div>
<div className="container mx-auto px-4 py-12 sm:px-6 lg:px-8">
<div className="mb-8 flex flex-col gap-2">
<h1 className="text-3xl font-bold">Contracts</h1>
<p className="text-muted-foreground">
Explore the contracts that match your search query.
</p>
<CollectionSearch />
</div>
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6">
{contracts.map((contract) => (
<ContractGridItem
key={contract.contract_address}
contract={contract}
/>
))}
</div>
</TaskFormProvider>
</div>
);
};

export default DashboardPage;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { useRouter } from "next/navigation";

import { Input } from "./ui/input";

export default function CollectionSearch() {
const [text, setText] = useState<string>("");
export default function CollectionSearch(props: { search?: string }) {
const [text, setText] = useState<string>(props.search ?? "");
const router = useRouter();

return (
Expand All @@ -21,7 +21,7 @@ export default function CollectionSearch() {
}
}}
type="search"
placeholder="Search collection..."
placeholder="Type collection name..."
className="md:w-[100px] lg:w-[300px]"
value={text}
/>
Expand Down
18 changes: 18 additions & 0 deletions ark-indexer-marketplace-admin/src/components/SearchContracts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"use client";

import ContractGridItem from "~/components/dashboard/ContractGridItem";
import { api } from "~/trpc/react";

export default function SearchContracts(props: { search: string }) {
const [contracts] = api.contract.searchContracts.useSuspenseQuery({
contractName: props.search,
});

return (
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6">
{contracts.map((contract) => (
<ContractGridItem key={contract.contract_address} contract={contract} />
))}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Link from "next/link";

import type { Contract } from "~/types";

interface ContractGridItemProps {
contract: Contract;
}

export default function ContractGridItem(props: ContractGridItemProps) {
const { contract } = props;
return (
<div key={contract.contract_address} className="space-y-3">
<Link
href={`/collections/${contract.contract_address}`}
className="relative block overflow-hidden rounded-md"
prefetch={false}
>
{contract.contract_image ? (
<div className="border bg-card">
<img
src={contract.contract_image}
alt={contract.contract_name ?? ""}
width={400}
height={300}
className="aspect-square h-auto w-auto object-cover transition-all hover:scale-105"
/>
</div>
) : (
<div className="h-[202px] w-full border bg-card object-cover transition-opacity group-hover:opacity-80" />
)}

<div className="absolute inset-0 flex items-end bg-gradient-to-t from-black/70 to-transparent p-4">
<div>
<h3 className="text-lg font-semibold text-white">
{contract.contract_name}
</h3>
<p className="w-full overflow-hidden text-ellipsis whitespace-nowrap text-sm text-white/80"></p>
<div className="mt-2">
{contract.is_spam && (
<div className="mr-2 inline-flex items-center rounded-md bg-red-500 px-2 py-1 text-xs font-medium text-primary-foreground shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50">
SPAM
</div>
)}

{contract.is_verified && (
<div className="inline-flex items-center rounded-md bg-primary px-2 py-1 text-xs font-medium text-primary-foreground shadow transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50">
VERIFIED
</div>
)}
</div>
</div>
</div>
</Link>
</div>
);
}
22 changes: 0 additions & 22 deletions ark-indexer-marketplace-admin/src/components/dashboard/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export default function DashboardHeader({ user }: DashboardHeaderProps) {
<Logo className="h-8 w-auto" />
<DashboardNav />
<div className="flex-grow" />
<CollectionSearch />
<NetworkSelector />
<DropdownMenu>
<DropdownMenuTrigger asChild>
Expand Down Expand Up @@ -63,34 +62,13 @@ export default function DashboardHeader({ user }: DashboardHeaderProps) {
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<Link href="/dashboard">
<DropdownMenuItem className="cursor-pointer">
Dashboard
</DropdownMenuItem>
</Link>
<Link href="/metadata">
<DropdownMenuItem className="cursor-pointer">
Metadata
</DropdownMenuItem>
</Link>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<div className="flex items-center justify-between px-2 py-[6px]">
<span className="text-sm">Theme</span>
<ThemeSelect />
</div>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<Link href="/home" target="_blank">
<DropdownMenuItem className="flex cursor-pointer justify-between">
ArkProject.dev
</DropdownMenuItem>
</Link>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem
className="cursor-pointer"
onClick={(event) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function NetworkSelector() {
<SelectValue placeholder="Network" />
</SelectTrigger>
<SelectContent>
<SelectItem value="production-mainnet">Production Mainnet</SelectItem>
<SelectItem value="production-mainnet">Mainnet</SelectItem>
{/* <SelectItem value="production-sepolia">Production Sepolia</SelectItem>
<SelectItem value="staging-mainnet">Staging Mainnet</SelectItem>
<SelectItem value="staging-sepolia">Staging Sepolia</SelectItem> */}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import CollectionSearch from "~/components/CollectionSearch";

export default function SearchCollectionsLayout({
children,
search,
}: {
search?: string;
children: React.ReactNode;
}) {
return (
<div className="container mx-auto px-4 py-12 sm:px-6 lg:px-8">
<div className="mb-8 flex flex-col gap-2">
<h1 className="text-3xl font-bold">Contracts</h1>
<p className="text-muted-foreground">
Explore the contracts that match your search query.
</p>
<CollectionSearch search={search} />
</div>
{children}
</div>
);
}
13 changes: 12 additions & 1 deletion ark-indexer-marketplace-admin/src/lib/queries/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,22 @@ export async function fetchContract(contractAddress: string, chainId: string) {
return res.rows.length > 0 ? res.rows[0] : undefined;
}

export async function getDefaultContracts(chainId: string) {
const res = await pool.query<Contract>(
`SELECT contract_address, chain_id, updated_timestamp, contract_type, contract_name, contract_symbol, contract_image, metadata_ok, is_spam, is_nsfw, deployed_timestamp, is_verified, save_images, is_refreshing
FROM contract
WHERE contract_type = 'ERC721' AND is_spam = false AND chain_id = $1 AND contract_name != '' ORDER BY contract_name ASC LIMIT 50`,
[chainId],
);

return res.rows;
}

export async function searchContracts(contractName: string, chainId: string) {
const res = await pool.query<Contract>(
`SELECT contract_address, chain_id, updated_timestamp, contract_type, contract_name, contract_symbol, contract_image, metadata_ok, is_spam, is_nsfw, deployed_timestamp, is_verified, save_images, is_refreshing
FROM contract
WHERE contract_type = 'ERC721' AND contract_name ILIKE $1 AND chain_id = $2 ORDER BY contract_image ASC LIMIT 50`,
WHERE contract_type = 'ERC721' AND contract_name ILIKE $1 AND chain_id = $2 ORDER BY contract_image ASC, contract_name ASC LIMIT 50`,
["%" + contractName + "%", chainId],
);

Expand Down
Loading