diff --git a/src/app/contacts/import/page.tsx b/src/app/contacts/import/page.tsx
index 989fc2e..a66008c 100644
--- a/src/app/contacts/import/page.tsx
+++ b/src/app/contacts/import/page.tsx
@@ -69,7 +69,7 @@ export default async function ImportContactsPage() {
diff --git a/src/app/contacts/new/page.tsx b/src/app/contacts/new/page.tsx
index 622962a..9f767e1 100644
--- a/src/app/contacts/new/page.tsx
+++ b/src/app/contacts/new/page.tsx
@@ -69,7 +69,7 @@ export default async function NewContactPage() {
diff --git a/src/app/contacts/page.tsx b/src/app/contacts/page.tsx
index 45b82c1..cfa5248 100644
--- a/src/app/contacts/page.tsx
+++ b/src/app/contacts/page.tsx
@@ -132,7 +132,7 @@ export default async function ContactsPage({ searchParams }: ContactsPageProps)
diff --git a/src/app/dao-members/page.tsx b/src/app/dao-members/page.tsx
new file mode 100644
index 0000000..3f690f7
--- /dev/null
+++ b/src/app/dao-members/page.tsx
@@ -0,0 +1,209 @@
+import { Metadata } from "next";
+import Link from "next/link";
+import { notFound } from "next/navigation";
+import { getUser } from "@/lib/auth";
+import { Button } from "@/components/ui/button";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { LogoutButton } from "@/components/auth/logout-button";
+import { Input } from "@/components/ui/input";
+import { prisma } from "@/lib/prisma";
+
+export const metadata: Metadata = {
+ title: "DAO Members - Stones Database",
+ description: "Track members of Moloch DAOs",
+};
+
+export default async function DAOMembersPage() {
+ const user = await getUser();
+
+ if (!user) {
+ notFound();
+ }
+
+ // Mock DAO data (this would be replaced with real data from the database)
+ const daos = [
+ {
+ id: "raid-guild",
+ name: "Raid Guild",
+ description: "A Decentralized Collective of Mercenaries Ready to Slay Your Web3 Product Demons",
+ imageUrl: "https://placekitten.com/206/206",
+ members: 178,
+ treasury: "2.5M $RAID",
+ },
+ {
+ id: "metacartel",
+ name: "MetaCartel",
+ description: "A DAO focused on funding early-stage decentralized applications",
+ imageUrl: "https://placekitten.com/207/207",
+ members: 82,
+ treasury: "436 ETH",
+ },
+ {
+ id: "daohaus",
+ name: "DAOhaus",
+ description: "The Shared Community DAO Infrastructure for Moloch DAOs",
+ imageUrl: "https://placekitten.com/208/208",
+ members: 120,
+ treasury: "320 ETH",
+ },
+ ];
+
+ return (
+
+
+
+
+
+ Stones Database
+
+
+
+
+
+
+
+
+
+
+ ← Back to Dashboard
+
+
+
DAO Members
+
Track members of Moloch DAOs
+
+
+
+
+
+
+
+
+
+
+ Search DAOs
+
+
+
+
+
+
+
+
+
+
+
+ {daos.map((dao) => (
+
+
+

+
+
{dao.name}
+
+
+
+ {dao.description}
+
+
+
Members
+
{dao.members}
+
+
+
Treasury
+
{dao.treasury}
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+ Add DAO
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index cb440ff..152aa02 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -127,11 +127,49 @@ export default async function DashboardPage() {
+
+
+
+
+ Data Collection Features
+
+
+
+
+
NFT Holders
+
Track holders of specific NFT collections
+
Automatically collect Ethereum addresses of NFT holders and resolve their ENS names.
+
+
+
+
+
+
+
Token Holders
+
Track holders of ERC20 tokens
+
Collect data on ERC20 token holders, including balance information and transaction history.
+
+
+
+
+
+
+
DAO Members
+
Track members of Moloch DAOs
+
Collect information on members of Moloch DAOs such as Raid Guild, DAOhaus, and Metacartel.
+
+
+
+
+
+
+
+
diff --git a/src/app/nft-holders/page.tsx b/src/app/nft-holders/page.tsx
new file mode 100644
index 0000000..9118556
--- /dev/null
+++ b/src/app/nft-holders/page.tsx
@@ -0,0 +1,186 @@
+import { Metadata } from "next";
+import Link from "next/link";
+import { notFound } from "next/navigation";
+import { getUser } from "@/lib/auth";
+import { Button } from "@/components/ui/button";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { LogoutButton } from "@/components/auth/logout-button";
+import { Input } from "@/components/ui/input";
+import { prisma } from "@/lib/prisma";
+
+export const metadata: Metadata = {
+ title: "NFT Holders - Stones Database",
+ description: "Track holders of specific NFT collections",
+};
+
+export default async function NFTHoldersPage() {
+ const user = await getUser();
+
+ if (!user) {
+ notFound();
+ }
+
+ // Get NFT collection information from the database (this would be replaced with real data)
+ const nftCollections = [
+ {
+ id: "nouns",
+ name: "Nouns",
+ description: "One Noun, every day, forever.",
+ imageUrl: "https://placekitten.com/200/200",
+ holders: 548,
+ },
+ {
+ id: "cryptopunks",
+ name: "CryptoPunks",
+ description: "10,000 unique collectible characters with proof of ownership on Ethereum.",
+ imageUrl: "https://placekitten.com/201/201",
+ holders: 3664,
+ },
+ {
+ id: "bayc",
+ name: "Bored Ape Yacht Club",
+ description: "A collection of 10,000 Bored Ape NFTs on Ethereum.",
+ imageUrl: "https://placekitten.com/202/202",
+ holders: 6425,
+ },
+ ];
+
+ return (
+
+
+
+
+
+ Stones Database
+
+
+
+
+
+
+
+
+
+
+ ← Back to Dashboard
+
+
+
NFT Holders
+
Track holders of specific NFT collections
+
+
+
+
+
+
+
+
+
+
+ Search NFT Collections
+
+
+
+
+
+
+
+
+
+
+
+ {nftCollections.map((collection) => (
+
+
+

+
+
+ {collection.name}
+
+
+ {collection.description}
+
+
+ {collection.holders} holders
+
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+ Add NFT Collection
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/token-holders/page.tsx b/src/app/token-holders/page.tsx
new file mode 100644
index 0000000..814624d
--- /dev/null
+++ b/src/app/token-holders/page.tsx
@@ -0,0 +1,209 @@
+import { Metadata } from "next";
+import Link from "next/link";
+import { notFound } from "next/navigation";
+import { getUser } from "@/lib/auth";
+import { Button } from "@/components/ui/button";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { LogoutButton } from "@/components/auth/logout-button";
+import { Input } from "@/components/ui/input";
+import { prisma } from "@/lib/prisma";
+
+export const metadata: Metadata = {
+ title: "Token Holders - Stones Database",
+ description: "Track holders of ERC20 tokens",
+};
+
+export default async function TokenHoldersPage() {
+ const user = await getUser();
+
+ if (!user) {
+ notFound();
+ }
+
+ // Mock token data (this would be replaced with real data from the database)
+ const tokens = [
+ {
+ id: "stones",
+ name: "Stones",
+ symbol: "STONES",
+ description: "The native token of the Stones ecosystem",
+ imageUrl: "https://placekitten.com/203/203",
+ holders: 1245,
+ marketCap: "$4.5M",
+ },
+ {
+ id: "eth",
+ name: "Ethereum",
+ symbol: "ETH",
+ description: "Native cryptocurrency of the Ethereum blockchain",
+ imageUrl: "https://placekitten.com/204/204",
+ holders: 52000000,
+ marketCap: "$367B",
+ },
+ {
+ id: "dai",
+ name: "Dai Stablecoin",
+ symbol: "DAI",
+ description: "Decentralized stablecoin pegged to the US Dollar",
+ imageUrl: "https://placekitten.com/205/205",
+ holders: 684000,
+ marketCap: "$5.2B",
+ },
+ ];
+
+ return (
+
+
+
+
+
+ Stones Database
+
+
+
+
+
+
+
+
+
+
+ ← Back to Dashboard
+
+
+
Token Holders
+
Track holders of ERC20 tokens
+
+
+
+
+
+
+
+
+
+
+ Search Tokens
+
+
+
+
+
+
+
+
+
+
+
+ {tokens.map((token) => (
+
+
+

+
+
{token.name}
+
{token.symbol}
+
+
+
+ {token.description}
+
+
+
Holders
+
{token.holders.toLocaleString()}
+
+
+
Market Cap
+
{token.marketCap}
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+ Add Token
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file