Skip to content

Commit

Permalink
Merge pull request #9 from jtgi/main
Browse files Browse the repository at this point in the history
misc layout fixes
  • Loading branch information
MrKevinOConnell authored Jun 25, 2024
2 parents f24992d + 2e9e3b1 commit a340aa5
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 157 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ yarn-error.log*

# local env files
.env*.local
.env

# vercel
.vercel
Expand Down
132 changes: 65 additions & 67 deletions src/app/[identifier]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
'use client'
"use client";
import Modal from "@/components/modal-component";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { useClipboard } from "@/hooks/useClipboard";
import { fetchCastAndFidData } from "@/lib/utils";
import { CopyCheckIcon, CopyIcon, UserIcon } from "lucide-react";
import Link from "next/link";

import { useEffect, useState } from "react";
Expand All @@ -12,12 +15,12 @@ interface ResponseProps {

const isNumeric = (str: string): boolean => {
return !isNaN(Number(str)) && !isNaN(parseFloat(str)) && !/^0x/.test(str);
}
};

const renderSkeletonHeader = () => (
<Card className="rounded-lg relative border-black md:p-8 text-xl min-w-40 flex flex-col items-center justify-center">
<Card className="rounded-lg relative border-black flex flex-col items-center justify-center">
<div className="w-full flex flex-col items-center animate-pulse">
<CardHeader className="text-center relative z-10 md:text-lg text-sm w-full">
<CardHeader className="text-center relative md:text-lg text-sm w-full">
<div className="h-6 bg-gray-300 rounded w-24 mb-2"></div>
</CardHeader>
<hr className="w-full border-t border-gray-300 my-2" />
Expand All @@ -28,16 +31,12 @@ const renderSkeletonHeader = () => (
</Card>
);

const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text).then(() => {
}).catch(err => {
});
};

export default function Page({ params }: ResponseProps) {
const identifier = decodeURIComponent(params.identifier);
const fid: number | null = isNumeric(identifier) ? Number(identifier) : null;
const hash = fid ? null : identifier;

const { copied, copy } = useClipboard();
const [data, setData] = useState<any>(null);
const [modalData, setModalData] = useState<any>(null);
const [modalTitle, setModalTitle] = useState<string>("");
Expand All @@ -47,14 +46,14 @@ export default function Page({ params }: ResponseProps) {

const fetchData = async () => {
setLoading(true);
const data = await fetchCastAndFidData(hash, fid) as any;
const data = (await fetchCastAndFidData(hash, fid)) as any;

const checkWarning = (message: any) => {
const expectedTypes = [
"USER_DATA_TYPE_PFP",
"USER_DATA_TYPE_DISPLAY",
"USER_DATA_TYPE_BIO",
"USER_DATA_TYPE_USERNAME"
"USER_DATA_TYPE_USERNAME",
];

if (message?.messages) {
Expand All @@ -65,7 +64,7 @@ export default function Page({ params }: ResponseProps) {
}
});

const missingTypes = expectedTypes.filter(type => !foundTypes.has(type));
const missingTypes = expectedTypes.filter((type) => !foundTypes.has(type));
return missingTypes;
}

Expand All @@ -83,14 +82,14 @@ export default function Page({ params }: ResponseProps) {
if (!username || username === expectedUsername) missingObjects.push("Username");

return missingObjects;
}
};

const warpcastAuthorMissing = checkWarning(data.apiData.warpcast?.author);
const neynarAuthorMissing = checkWarning(data.apiData.neynar?.author?.author);
const warpcastAuthorHubMissing = checkWarning(data.hubData?.[0]?.author);
const neynarAuthorHubMissing = checkWarning(data.hubData?.[1]?.author);
const warpcastCastMissing = [] as any
const neynarCastMissing = [] as any
const warpcastCastMissing = [] as any;
const neynarCastMissing = [] as any;

setData({
...data,
Expand All @@ -101,7 +100,7 @@ export default function Page({ params }: ResponseProps) {
warpcastCastMissing,
neynarCastMissing,
warpcastCastHubMissing: [],
neynarCastHubMissing: []
neynarCastHubMissing: [],
});

setLoading(false);
Expand All @@ -124,10 +123,14 @@ export default function Page({ params }: ResponseProps) {

const { warpcast, neynar } = data?.apiData ?? {};
const {
warpcastAuthorMissing, neynarAuthorMissing,
warpcastAuthorHubMissing, neynarAuthorHubMissing,
warpcastCastMissing, neynarCastMissing,
warpcastCastHubMissing, neynarCastHubMissing
warpcastAuthorMissing,
neynarAuthorMissing,
warpcastAuthorHubMissing,
neynarAuthorHubMissing,
warpcastCastMissing,
neynarCastMissing,
warpcastCastHubMissing,
neynarCastHubMissing,
} = data ?? {};

const hubs = data?.hubData ?? [];
Expand All @@ -138,65 +141,61 @@ export default function Page({ params }: ResponseProps) {
const { author: warpcastAuthor, cast: warpcastCast } = warpcast || {};
const { author: neynarAuthor, cast: neynarCast } = neynar || {};

const authorFid = warpcastCast?.author?.fid || neynarCast?.cast?.author?.fid
const authorFid = warpcastCast?.author?.fid || neynarCast?.cast?.author?.fid;

const renderHeader = (label: string, data: any | null, missingObjects: string[]) => {
if (!data) {
return null;
}

const renderHeader = (label: string, data: any, missingObjects: string[]) => {
let icon = '✅';
let icon = "✅";

if (data?.error) {
icon = '❌';
icon = "❌";
} else if (missingObjects.length > 0) {
icon = '⚠️';
icon = "⚠️";
}

return (
<button onClick={() => openModal(label, data, missingObjects)}>
<Card className="hover:bg-slate-100 rounded-lg relative border-black md:p-8 md:text-xl max-h-32 md:max-h-64 min-w-36 md:min-w-40 flex flex-col items-center justify-center">
<CardHeader className="text-center relative z-10 md:text-lg text-sm w-full">
{label}
</CardHeader>
<Card className="hover:bg-slate-100 rounded-lg relative border-black flex flex-col items-center justify-center">
<CardHeader className="text-center relative w-full">{label}</CardHeader>
<hr className="w-full border-t border-black my-2" />
<CardContent className="flex items-center justify-center md:text-6xl w-full text-4xl">
<CardContent className="flex items-center justify-center w-full text-4xl">
{icon}
</CardContent>
</Card>
</button>
);
};

const handleCopyClick = () => {
copyToClipboard(fid ? fid.toString() as any : hash);
setButtonClicked(true);
};

return (
<>
<Modal isOpen={isModalOpen} toggleModal={closeModal} response={modalData} title={modalTitle} />
<div className="flex flex-col w-full h-full items-center">
<div className="space-x-5 flex">
{ fid || hash ? (
<button
<div className="flex flex-col items-center">
<div className="gap-5 flex">
{fid || hash ? (
<Button
className="mb-10 min-h-10 px-4 py-2 bg-purple-500 text-white hover:bg-purple-700 rounded-lg"
onClick={() => copy(fid ? fid.toString() : hash || "")}
>
{copied ? <><CopyCheckIcon className="w-4 h-4 mr-2" /> Copied</>: <><CopyIcon className="w-4 h-4 mr-2" /> Copy {fid ? "User FID" : "Cast Hash"}</>}
</Button>
) : null}

{authorFid ? (
<Button asChild
className="mb-10 min-h-10 px-4 py-2 bg-purple-500 text-white hover:bg-purple-700 rounded-lg"
onClick={handleCopyClick}
>
{buttonClicked ? '✔️' : `Copy ${fid ? 'user FID' : 'cast hash'}`}
</button>
) : null
}

{ authorFid ? (
<Link href={`/${authorFid}`} >
<div className="min-h-10 px-4 py-2 items-center flex justify-center text-white bg-purple-500 text-white hover:bg-purple-700 text-md rounded-lg">
View Author Profile
</div>
</Link>
) : null
}
</div>

>
<Link href={`/${authorFid}`}>
<UserIcon className="w-4 h-4 mr-1" /> View Author Profile
</Link>
</Button>
) : null}
</div>


<div className="w-full flex md:flex-row flex-col justify-center items-center md:space-x-0 ">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{loading ? (
<>
{renderSkeletonHeader()}
Expand All @@ -206,19 +205,18 @@ export default function Page({ params }: ResponseProps) {
</>
) : (
<>
{warpcastAuthor && renderHeader('Warpcast API', warpcastAuthor, warpcastAuthorMissing)}
{warpcastCast && renderHeader('Warpcast API', warpcastCast, warpcastCastMissing)}
{nemesAuthor && renderHeader('Warpcast Hub (Hoyt)', nemesAuthor, warpcastAuthorHubMissing)}
{nemesCast && renderHeader('Warpcast Hub (Hoyt)', nemesCast, warpcastCastHubMissing)}
{neynarHubAuthor && renderHeader('Neynar Hub', neynarHubAuthor, neynarAuthorHubMissing)}
{neynarHubCast && renderHeader('Neynar Hub', neynarHubCast, neynarCastHubMissing)}
{neynarAuthor && renderHeader('Neynar API', neynarAuthor, neynarAuthorMissing)}
{neynarCast && renderHeader('Neynar API', neynarCast, neynarCastMissing)}
{renderHeader("Warpcast API", warpcastAuthor, warpcastAuthorMissing)}
{renderHeader("Warpcast API", warpcastCast, warpcastCastMissing)}
{renderHeader("Warpcast Hub (Hoyt)", nemesAuthor, warpcastAuthorHubMissing)}
{renderHeader("Warpcast Hub (Hoyt)", nemesCast, warpcastCastHubMissing)}
{renderHeader("Neynar Hub", neynarHubAuthor, neynarAuthorHubMissing)}
{renderHeader("Neynar Hub", neynarHubCast, neynarCastHubMissing)}
{renderHeader("Neynar API", neynarAuthor, neynarAuthorMissing)}
{renderHeader("Neynar API", neynarCast, neynarCastMissing)}
</>
)}
</div>
</div>
</>
);
}

74 changes: 39 additions & 35 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
'use client'
/* eslint-disable @next/next/no-img-element */
"use client";
import "./globals.css";
import Link from "next/link";
import Providers from "./providers";
import Search from "@/components/search";
import { usePathname } from 'next/navigation'
import { usePathname } from "next/navigation";
import { useEffect } from "react";
import { seo } from "@/constants";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { DownloadIcon } from "lucide-react";

export default function RootLayout({
children,
Expand All @@ -15,7 +18,7 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<head>
<head>
<meta property="og:title" content={seo.title} />
<meta property="og:description" content={seo.description} />
<meta property="og:image" content={seo.ogImage} />
Expand All @@ -26,39 +29,40 @@ export default function RootLayout({
<meta name="twitter:description" content={seo.description} />
<meta name="twitter:image" content={seo.ogImage} />
</head>
<body className="relative h-screen flex flex-col items-center justify-center min-h-screen">
<Providers>
<div className="absolute top-0 left-0 p-2">
<Link href="https://www.neynar.com" target="_blank">
<img className="w-16 md:w-32" src={"/neynar.png"} />
</Link>
</div>
<div className="absolute top-5 left-1/2 transform -translate-x-1/2 p-2">
<Link href="/" className="text-black font-bold">
<p className="text-md md:text-">Farcaster Explorer</p>
</Link>
</div>
<div className="w-full absolute top-10 justify-center mt-9 max-h-32 max-w-sm md:max-w-md">
<Search />
</div>
<div className="w-full px-4 md:px-8 mt-72 md:mb-64 flex flex-col ">
{children}
<div className="w-full flex justify-center items-center py-3 my-2">
<Link target="_blank" href="https://warpcast.com/~/add-cast-action?url=https://explorer.neynar.com/frames/actions/view-on-explorer" >

<body className="relative h-screen min-h-screen">
<div className="flex flex-col min-h-screen">
<Providers>
<div className="sticky top-0 z-10 w-full flex flex-col sm:flex-row justify-between bg-white p-4">
<div className="flex-1 min-w-32 mx-auto">
<Link className="block flex-shrink-0" href="https://www.neynar.com" target="_blank">
<img className="w-32" src={"/neynar.png"} />
</Link>
</div>

<Card className="w-full hover:bg-slate-100 rounded-lg max-w-md md:min-w-24 md:min-h-12 flex items-center justify-center">
<CardContent className="p-4 w-full font-bold flex flex-col justify-center items-center space-y-2">
Download cast action
</CardContent>
</Card>
</Link>
</div>
</div>
{//open in new page
}

</Providers>
<div className="flex flex-col items-center gap-2 sm:max-w-[350px] w-full">
<Link href="/" className="text-black font-bold">
<p className="text-md md:text-">Farcaster Explorer</p>
</Link>
<Search />
</div>
<div className="flex-1"></div>
</div>

<div className="flex-auto w-full p-4 md:p-8 bg-gray-50">{children}</div>

<div className="sticky bottom-0 p-4 text-center bg-white">
<Button asChild variant={"secondary"}>
<Link
target="_blank"
href="https://warpcast.com/~/add-cast-action?url=https://explorer.neynar.com/frames/actions/view-on-explorer"
>
<DownloadIcon className="w-4 h-4 mr-2" />
Install Cast Action
</Link>
</Button>
</div>
</Providers>
</div>
</body>
</html>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/cast-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function CastComponent({cast,warpcastUrl}: any) {
const avatarImg = cast.author.pfp_url ? cast.author.pfp_url : null
return (
<Link href={`/${warpcastUrl ? encodeURIComponent(warpcastUrl) :cast.hash}`}>
<Card className="w-full hover:bg-slate-100 rounded-lg max-w-md md:min-w-64">
<Card className="w-full hover:bg-slate-100 rounded-lg sm:max-w-md md:min-w-64 h-[150px]">
<CardHeader className="flex flex-row items-center space-x-2">
<Avatar >
<AvatarImage alt={`@${cast.author.username}`} src={avatarImg} />
Expand Down
Loading

0 comments on commit a340aa5

Please sign in to comment.