feat: clean up UI

This commit is contained in:
veganbeef
2025-06-13 14:13:59 -07:00
parent 21ccdf3623
commit 7263cdef0e
7 changed files with 308 additions and 131 deletions

View File

@@ -0,0 +1,53 @@
import React from "react";
import type { Tab } from "~/components/Demo";
interface FooterProps {
activeTab: Tab;
setActiveTab: (tab: Tab) => void;
showWallet?: boolean;
}
export const Footer: React.FC<FooterProps> = ({ activeTab, setActiveTab, showWallet = false }) => (
<div className="fixed bottom-0 left-0 right-0 mx-4 mb-4 bg-gray-100 dark:bg-gray-800 border-[3px] border-double border-purple-500 px-2 py-2 rounded-lg z-50">
<div className="flex justify-around items-center h-14">
<button
onClick={() => setActiveTab('home')}
className={`flex flex-col items-center justify-center w-full h-full ${
activeTab === 'home' ? 'text-purple-500' : 'text-gray-500'
}`}
>
<span className="text-xl">🏠</span>
<span className="text-xs mt-1">Home</span>
</button>
<button
onClick={() => setActiveTab('actions')}
className={`flex flex-col items-center justify-center w-full h-full ${
activeTab === 'actions' ? 'text-purple-500' : 'text-gray-500'
}`}
>
<span className="text-xl"></span>
<span className="text-xs mt-1">Actions</span>
</button>
<button
onClick={() => setActiveTab('context')}
className={`flex flex-col items-center justify-center w-full h-full ${
activeTab === 'context' ? 'text-purple-500' : 'text-gray-500'
}`}
>
<span className="text-xl">📋</span>
<span className="text-xs mt-1">Context</span>
</button>
{showWallet && (
<button
onClick={() => setActiveTab('wallet')}
className={`flex flex-col items-center justify-center w-full h-full ${
activeTab === 'wallet' ? 'text-purple-500' : 'text-gray-500'
}`}
>
<span className="text-xl">👛</span>
<span className="text-xs mt-1">Wallet</span>
</button>
)}
</div>
</div>
);

View File

@@ -0,0 +1,82 @@
"use client";
import { useState } from "react";
import { APP_NAME } from "~/lib/constants";
import sdk from "@farcaster/frame-sdk";
import { useMiniApp } from "@neynar/react";
type HeaderProps = {
neynarUser: any;
};
export function Header({ neynarUser }: HeaderProps) {
const { context } = useMiniApp();
const [isUserDropdownOpen, setIsUserDropdownOpen] = useState(false);
const [hasClickedPfp, setHasClickedPfp] = useState(false);
return (
<div className="relative">
<div
className="mb-1 py-2 px-3 bg-gray-100 dark:bg-gray-800 rounded-lg flex items-center justify-between border-[3px] border-double border-purple-500"
>
<div className="text-lg font-light">
Welcome to {APP_NAME}!
</div>
{context?.user && (
<div
className="cursor-pointer"
onClick={() => {
setIsUserDropdownOpen(!isUserDropdownOpen);
setHasClickedPfp(true);
}}
>
{context.user.pfpUrl && (
<img
src={context.user.pfpUrl}
alt="Profile"
className="w-10 h-10 rounded-full border-2 border-purple-500"
/>
)}
</div>
)}
</div>
{context?.user && (
<>
{!hasClickedPfp && (
<div className="absolute right-0 -bottom-6 text-xs text-purple-500 flex items-center justify-end gap-1 pr-2">
<span className="text-[10px]"></span> Click PFP! <span className="text-[10px]"></span>
</div>
)}
{isUserDropdownOpen && (
<div className="absolute top-full right-0 z-50 w-fit mt-1 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700">
<div className="p-3 space-y-2">
<div className="text-right">
<h3
className="font-bold text-sm hover:underline cursor-pointer inline-block"
onClick={() => sdk.actions.viewProfile({ fid: context.user.fid })}
>
{context.user.displayName || context.user.username}
</h3>
<p className="text-xs text-gray-600 dark:text-gray-400">
@{context.user.username}
</p>
<p className="text-xs text-gray-500 dark:text-gray-500">
FID: {context.user.fid}
</p>
{neynarUser && (
<>
<p className="text-xs text-gray-500 dark:text-gray-500">
Neynar Score: {neynarUser.score}
</p>
</>
)}
</div>
</div>
</div>
)}
</>
)}
</div>
);
}