diff --git a/apps/explorer/public/apple-icon.png b/apps/explorer/public/apple-icon.png new file mode 100644 index 0000000..ed4cb2b Binary files /dev/null and b/apps/explorer/public/apple-icon.png differ diff --git a/apps/explorer/public/icon.svg b/apps/explorer/public/icon.svg new file mode 100644 index 0000000..4d16a55 --- /dev/null +++ b/apps/explorer/public/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/apps/explorer/public/social-media.png b/apps/explorer/public/social-media.png new file mode 100644 index 0000000..3ad2811 Binary files /dev/null and b/apps/explorer/public/social-media.png differ diff --git a/apps/explorer/src/app/[network]/[group]/page.tsx b/apps/explorer/src/app/[network]/[group]/page.tsx index 9c02a50..7542bef 100644 --- a/apps/explorer/src/app/[network]/[group]/page.tsx +++ b/apps/explorer/src/app/[network]/[group]/page.tsx @@ -15,8 +15,11 @@ export default function Group() { const [filteredCommitments, setFilteredCommitments] = useState([]) const [filteredProofs, setFilteredProofs] = useState([]) + const [loading, setLoading] = useState(false) + useEffect(() => { const fetchData = async () => { + setLoading(true) const subgraph = new SemaphoreSubgraph(network) const groupInfo = await subgraph.getGroup(groupId, { @@ -28,6 +31,7 @@ export default function Group() { setFilteredCommitments(groupInfo.members || []) setFilteredProofs(groupInfo.validatedProofs || []) + setLoading(false) } fetchData() @@ -59,7 +63,11 @@ export default function Group() { [group] ) - return ( + return loading ? ( +
+
+
+ ) : ( group && (
diff --git a/apps/explorer/src/app/[network]/page.tsx b/apps/explorer/src/app/[network]/page.tsx index 76564c9..beabffe 100644 --- a/apps/explorer/src/app/[network]/page.tsx +++ b/apps/explorer/src/app/[network]/page.tsx @@ -13,8 +13,11 @@ export default function Network() { const [allGroups, setAllGroups] = useState([]) const [filteredGroups, setFilteredGroups] = useState([]) + const [loading, setLoading] = useState(false) + useEffect(() => { const fetchData = async () => { + setLoading(true) const subgraph = new SemaphoreSubgraph(network) const groups = await subgraph.getGroups({ @@ -24,18 +27,26 @@ export default function Network() { setAllGroups(groups) setFilteredGroups(groups.slice()) + setLoading(false) } fetchData() }, []) - const filterGroups = useCallback((groupId: string) => { - const groups = allGroups.filter((group) => (!groupId ? true : group.id.includes(groupId))) + const filterGroups = useCallback( + (groupId: string) => { + const groups = allGroups.filter((group) => (!groupId ? true : group.id.includes(groupId))) - setFilteredGroups(groups) - }, []) + setFilteredGroups(groups) + }, + [allGroups] + ) - return ( + return loading ? ( +
+
+
+ ) : ( allGroups && (
diff --git a/apps/explorer/src/app/favicon.ico b/apps/explorer/src/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/apps/explorer/src/app/favicon.ico and /dev/null differ diff --git a/apps/explorer/src/app/globals.css b/apps/explorer/src/app/globals.css index bba55d9..ca782e8 100644 --- a/apps/explorer/src/app/globals.css +++ b/apps/explorer/src/app/globals.css @@ -25,3 +25,19 @@ body { text-wrap: balance; } } + +.loader { + width: 25px; + height: 25px; + border-radius: 50%; + border-top: 2px solid #3555df; + border-right: 2px solid transparent; + animation: spin 1s linear infinite; + z-index: 20; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} diff --git a/apps/explorer/src/app/layout.tsx b/apps/explorer/src/app/layout.tsx index 62d743b..bad2c17 100644 --- a/apps/explorer/src/app/layout.tsx +++ b/apps/explorer/src/app/layout.tsx @@ -16,7 +16,22 @@ const geistMono = localFont({ export const metadata: Metadata = { title: "Semaphore Explorer", - description: "Discover Semaphore groups, view members and zero-knowledge proofs." + description: "Discover Semaphore groups, view members and zero-knowledge proofs.", + icons: { icon: "/icon.svg", apple: "/apple-icon.png" }, + metadataBase: new URL("https://explorer.semaphore.pse.dev"), + openGraph: { + type: "website", + url: "https://explorer.semaphore.pse.dev", + title: "Semaphore Explorer", + description: "Discover Semaphore groups, view members and zero-knowledge proofs.", + siteName: "Semaphore Explorer", + images: [ + { + url: "https://explorer.semaphore.pse.dev/social-media.png" + } + ] + }, + twitter: { card: "summary_large_image", images: "https://explorer.semaphore.pse.dev/social-media.png" } } export default function RootLayout({