Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Name Lookup Demo #217

Merged
merged 5 commits into from
Mar 27, 2024
Merged
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
15 changes: 14 additions & 1 deletion app/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,17 @@ label.label {

.card1::scrollbar {
@apply rounded-tr-xl overflow-hidden;
}
}

.load-width {
animation: load-width 1s ease-out forwards;
}

@keyframes load-width {
0% {
width: 0;
}
100% {
width: 90%;
}
}
115 changes: 72 additions & 43 deletions app/local/content/demos/namelookup/NameLookup.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use client';

import { formatAddress } from '@ens-tools/format';
import clsx from 'clsx';
import { FC, useState } from 'react';
import { BiLoaderAlt } from 'react-icons/bi';
import { useDebounce } from 'use-debounce';

import { Button } from '@/components/Button';

import { useProfile } from './logic/useProfile';
import { Chains } from './parts/chains';
import { Records } from './parts/records';
Expand All @@ -15,59 +17,86 @@ export const NameLookupDemo: FC = () => {

const { data, isLoading, error } = useProfile({ name });

const isValidName = !isLoading && data && data['status'] === undefined;
const isUnknownName =
!isLoading && ((data && data['status'] == 404) || !data);
const isOtherError = !isLoading && error && data['status'] !== 404;

return (
<div className="mx-auto flex gap-2 p-4 text-ens-light-text-primary dark:text-ens-dark-text-primary">
<div className="max-w-xs">
<div>Find user</div>
<div className="text-ens-light-text-primary dark:text-ens-dark-text-primary mx-auto space-y-2 p-4">
<div className="w-full">
<input
className="w-full rounded-md border border-ens-light-border pl-2 dark:border-ens-dark-border"
placeholder="luc.eth"
className="border-ens-light-border dark:border-ens-dark-border input w-full rounded-md border pl-2"
placeholder="Enter name or address..."
onChange={(event) => setTemporaryName(event.target.value)}
value={temporaryName}
/>
</div>
<div className="mt-2 flex h-fit flex-col gap-1.5 rounded-lg border border-ens-light-border p-4 dark:border-ens-dark-border">
{isLoading && <BiLoaderAlt className="animate-spin" />}
{!isLoading && (
<>
{error && <div>Error {JSON.stringify(error)}</div>}
{!data && (
<div>
<div>Unknown Name 🤷‍♀️</div>
<div>
Try <b>luc.eth</b>
</div>
<div className="border-ens-light-border dark:border-ens-dark-border not-prose mt-2 flex h-fit flex-col gap-1.5 rounded-lg border p-4">
{isLoading && (
<div className="bg-ens-light-background-secondary border-ens-light-border dark:border-ens-dark-border dark:bg-ens-dark-background-secondary h-4 rounded-lg border">
<div
className={clsx(
'bg-ens-light-blue-primary dark:bg-ens-dark-blue-primary h-full rounded-lg transition',
temporaryName == name && 'load-width'
)}
></div>
</div>
)}
<>
{isOtherError && <div>Error {JSON.stringify(error)}</div>}
{isUnknownName && (
<div>
<div>Unknown Name 🤷‍♀️</div>
<div className="flex gap-2">
Try{' '}
<ul>
{['luc.eth', 'irc.eth', 'domico.eth'].map(
(name) => (
<li>
<Button
variant="outline"
onClick={() => {
setTemporaryName(name);
}}
>
<b>{name}</b>
</Button>
</li>
)
)}
</ul>
</div>
)}
{data && (
<>
<div className="flex gap-2">
<div className="size-8 overflow-hidden rounded-full bg-ens-light-blue-100">
{data?.avatar && (
<img
src={data.avatar}
alt="Avatar"
className="aspect-square w-full rounded-full"
/>
)}
</div>
)}
{isValidName && (
<>
<div className="flex gap-2">
<div className="bg-ens-light-blue-100 size-10 overflow-hidden rounded-full">
{data?.avatar && (
<img
src={data.avatar}
alt="Avatar"
className="aspect-square w-full rounded-full"
/>
)}
</div>
<div className="flex flex-col justify-center">
<div className="font-bold leading-none">
{data.name}
</div>
<div className="flex flex-col justify-center">
<div className="font-bold leading-none">
{data.name}
</div>

<div className="text-xs leading-none">
{data?.address &&
formatAddress(data.address)}
</div>
<div className="text-xs leading-none">
{data?.address &&
formatAddress(data.address)}
</div>
</div>
<Records records={data?.records} />
<Chains chains={data?.chains} />
</>
)}
</>
)}
</div>
<Records records={data?.records} />
<Chains chains={data?.chains} />
</>
)}
</>
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion app/local/content/demos/namelookup/logic/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const rawFetchEnstateProfile = async (
name: string,
instance: string = ENSTATE_PUBLIC_INSTANCE
): Promise<ENStateProfile> => {
const request = await fetch(instance + '/n/' + name);
const request = await fetch(instance + '/u/' + name);

return request.json() as Promise<ENStateProfile>;
};
Expand Down
6 changes: 5 additions & 1 deletion app/local/content/demos/namelookup/logic/useProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ export type UseProfileParameters = {
// TODO: Naive approach, doesn't support extended character set
const isValidDomain = /^([\da-z-]{1,63}\.)+[\da-z-]{1,63}$/i;

const isValidAddress = /^0x[\da-f]{40}$/i;

export const useProfile = ({ name, instance }: UseProfileParameters) => {
const { data, error, isLoading, isValidating, mutate } = useSWR(
isValidDomain.test(name) ? ['enstate', name] : undefined,
isValidDomain.test(name) || isValidAddress.test(name)
? ['enstate', name]
: undefined,
swrFetchEnstateProfile(instance)
);

Expand Down
2 changes: 1 addition & 1 deletion app/local/content/demos/namelookup/parts/records.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const Records: FC<{ records?: Record<RecordType, string> }> = ({
.sort((a, b) => b.length - a.length)
.map((record) => (
<Fragment key={record}>
<div>
<div className="py-1">
{recordIcons[record] ? (
<div className="flex items-center gap-0.5">
<div className="flex size-4 items-center justify-center">
Expand Down
Loading