Skip to content

Commit

Permalink
feat: profile loading skeleton (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
martines3000 authored Jun 6, 2024
1 parent fdc4a9d commit 9824882
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 47 deletions.
27 changes: 3 additions & 24 deletions packages/dapp/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Container } from '@/components/Container';
import { EndorseForm } from '@/components/EndorseForm';
import { Endorsee } from '@/components/Endorsee';
import { Endorsee, EndorseeSkeleton } from '@/components/Endorsee';
import { Button } from '@/components/ui/button';
import { Skeleton } from '@/components/ui/skeleton';
import { PlatformType, validateOrGetDefaultPlatform } from '@/utils';
import Link from 'next/link';
import { Suspense } from 'react';
Expand Down Expand Up @@ -33,17 +32,7 @@ export default async function Page({
endorsee={
<Suspense
key={JSON.stringify(searchParams)}
fallback={
<>
<div className="relative sm:mt-3">
<Skeleton className="h-[80px] w-[80px] rounded-full bg-primary-200" />
</div>
<div className="flex flex-col w-full sm:ml-4 gap-y-2 max-sm:items-center">
<Skeleton className="w-[160px] h-[32px] rounded-full bg-primary-200" />
<Skeleton className="w-[112px] h-[16px] rounded-full bg-primary-200" />
</div>
</>
}
fallback={<EndorseeSkeleton />}
>
<Endorsee
platform={PlatformType.ens}
Expand Down Expand Up @@ -72,17 +61,7 @@ export default async function Page({
endorsee={
<Suspense
key={JSON.stringify(searchParams)}
fallback={
<>
<div className="relative sm:mt-3">
<Skeleton className="h-[80px] w-[80px] rounded-full bg-primary-200" />
</div>
<div className="flex flex-col w-full sm:ml-4 gap-y-2 max-sm:items-center">
<Skeleton className="w-[160px] h-[32px] rounded-full bg-primary-200" />
<Skeleton className="w-[112px] h-[16px] rounded-full bg-primary-200" />
</div>
</>
}
fallback={<EndorseeSkeleton />}
>
<Endorsee
platform={platform}
Expand Down
43 changes: 34 additions & 9 deletions packages/dapp/src/app/profile/[slug]/Feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { PlatformType } from '@/utils';
import { Dashboard } from './Dashboard';
import { Explorer } from './Explorer';
import { SocialGraph } from './SocialGraph';
import { Skeleton } from '@/components/ui/skeleton';
import { Suspense } from 'react';

const TABS = [
{ value: 'dashboard', label: 'Dashboard' },
Expand Down Expand Up @@ -37,9 +39,9 @@ export const Feed = ({ account, platform, tab, network }: FeedProps) => {

return (
<div>
<div className="max-sm:flex max-sm:flex-col sm:h-10 sm:items-center justify-center rounded-md p-1 text-muted-foreground grid w-full grid-cols-3 bg-gray-100">
<div className="gap-1 max-sm:flex max-sm:flex-col sm:h-10 sm:items-center justify-center rounded-md p-1 text-muted-foreground grid w-full grid-cols-3 bg-gray-100">
<Link
className="inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm"
className="cursor-pointer inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm"
href={`?platform=${platform}&tab=dashboard`}
data-state={_tab === 'dashboard' ? 'active' : ''}
scroll={false}
Expand All @@ -48,27 +50,50 @@ export const Feed = ({ account, platform, tab, network }: FeedProps) => {
</Link>
<Link
href={`?platform=${platform}&tab=explorer`}
className="inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm"
className="cursor-pointer inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm"
data-state={_tab === 'explorer' ? 'active' : ''}
scroll={false}
>
Endorsement Explorer 🚧
</Link>
<Link
href={`?platform=${platform}&tab=graph`}
className="inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm"
className="cursor-pointer inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm"
data-state={_tab === 'graph' ? 'active' : ''}
scroll={false}
>
Social Graph 🚧
</Link>
</div>
<div className="mt-4 w-full">
{_tab === 'dashboard' && (
<Dashboard account={account} network={network} />
)}
{_tab === 'explorer' && <Explorer />}
{_tab === 'graph' && <SocialGraph />}
<Suspense
fallback={
<div className="mt-4 w-full">
<Skeleton className="w-full h-48 bg-gray-200 rounded-sm" />
</div>
}
>
{_tab === 'dashboard' && (
<Dashboard account={account} network={network} />
)}
{_tab === 'explorer' && <Explorer />}
{_tab === 'graph' && <SocialGraph />}
</Suspense>
</div>
</div>
);
};

export const FeedSkeleton = () => {
return (
<div>
<div className="gap-1 max-sm:flex max-sm:flex-col sm:h-10 sm:items-center justify-center rounded-md p-1 text-muted-foreground grid w-full grid-cols-3 bg-gray-100">
<Skeleton className="w-full h-[32px] bg-primary-200 rounded-sm" />
<Skeleton className="w-full h-[32px] bg-primary-200 rounded-sm" />
<Skeleton className="w-full h-[32px] bg-primary-200 rounded-sm" />
</div>
<div className="mt-4 w-full">
<Skeleton className="w-full h-48 bg-gray-200 rounded-sm" />
</div>
</div>
);
Expand Down
29 changes: 29 additions & 0 deletions packages/dapp/src/app/profile/[slug]/PageSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Container } from '@/components/Container';
import { ProfileAvatarSkeleton } from './ProfileAvatar';
import { Skeleton } from '@/components/ui/skeleton';
import { FeedSkeleton } from './Feed';

export const PageSkeleton = () => {
return (
<Container className="pt-16 max-w-[1440px] overflow-auto">
<div className="flex max-lg:flex-col w-full gap-4">
<div className="lg:w-[30%] min-w-[300px] w-full">
<div className="flex flex-col gap-y-2 text-center items-center">
<ProfileAvatarSkeleton size="5xl" />
<div className="text-3xl font-semibold">
<Skeleton className="w-[140px] h-9 bg-primary-200 rounded-3xl" />
</div>
<div className="flex gap-x-1 items-center text-md text-gray-600 font-medium">
<Skeleton className="w-[160px] h-8 bg-primary-200 rounded-3xl" />
<Skeleton className="w-[100px] h-8 bg-primary-200 rounded-3xl" />
</div>
<Skeleton className="mt-2 w-[260px] h-6 bg-primary-200 rounded-3xl" />
</div>
</div>
<div className="w-full">
<FeedSkeleton />
</div>
</div>
</Container>
);
};
62 changes: 51 additions & 11 deletions packages/dapp/src/app/profile/[slug]/ProfileAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ import { useState } from 'react';
import { Skeleton } from '@/components/ui/skeleton';
import { MemoizedImage } from '@/components/MemoizedImage';

type AvatarSize =
| 'xs'
| 'sm'
| 'md'
| 'lg'
| 'xl'
| '2xl'
| '3xl'
| '4xl'
| '5xl'
| '6xl';

type ProfileAvatarProps = {
avatar: string | null;
size?:
| 'xs'
| 'sm'
| 'md'
| 'lg'
| 'xl'
| '2xl'
| '3xl'
| '4xl'
| '5xl'
| '6xl';
size?: AvatarSize;
};

const AVATAR_SIZES = {
Expand Down Expand Up @@ -101,3 +103,41 @@ export const ProfileAvatar = ({ avatar, size = 'md' }: ProfileAvatarProps) => {
</div>
);
};

export const ProfileAvatarSkeleton = ({
size = 'md',
}: { size?: AvatarSize }) => {
return (
<div
className={cn(
'relative',
size === 'xs' && 'w-[14px] h-[14px]',
size === 'sm' && 'w-[24px] h-[24px]',
size === 'md' && 'w-[36px] h-[36px]',
size === 'lg' && 'w-[48px] h-[48px]',
size === 'xl' && 'w-[64px] h-[64px]',
size === '2xl' && 'w-[80px] h-[80px]',
size === '3xl' && 'w-[96px] h-[96px]',
size === '4xl' && 'w-[128px] h-[128px]',
size === '5xl' && 'w-[160px] h-[160px]',
size === '6xl' && 'w-[192px] h-[192px]'
)}
>
<Skeleton
className={cn(
'absolute rounded-full bg-primary-200',
size === 'xs' && 'w-[14px] h-[14px]',
size === 'sm' && 'w-[24px] h-[24px]',
size === 'md' && 'w-[36px] h-[36px]',
size === 'lg' && 'w-[48px] h-[48px]',
size === 'xl' && 'w-[64px] h-[64px]',
size === '2xl' && 'w-[80px] h-[80px]',
size === '3xl' && 'w-[96px] h-[96px]',
size === '4xl' && 'w-[128px] h-[128px]',
size === '5xl' && 'w-[160px] h-[160px]',
size === '6xl' && 'w-[192px] h-[192px]'
)}
/>
</div>
);
};
5 changes: 3 additions & 2 deletions packages/dapp/src/app/profile/[slug]/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PageSkeleton } from './PageSkeleton';

export default function Loading() {
// You can add any UI inside Loading, including a Skeleton.
return <div>Loading...</div>;
return <PageSkeleton />;
}
16 changes: 16 additions & 0 deletions packages/dapp/src/components/Endorsee/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { EndorseeBadge } from './EndorseeBadge';
import type { PlatformType } from '@/utils/platform';
import { getMinimalProfileInfoByPlatform } from '@/lib/airstack/getMinimalProfileInfoByPlatform';
import { SearchParamsStateSync } from './SearchParamsStateSync';
import { Skeleton } from '@/components/ui/skeleton';
import { ProfileAvatarSkeleton } from '@/app/profile/[slug]/ProfileAvatar';

type EndorseeProps = {
platform: PlatformType;
Expand Down Expand Up @@ -63,3 +65,17 @@ export const Endorsee = async ({
</div>
);
};

export const EndorseeSkeleton = () => {
return (
<>
<div className="sm:mt-3">
<ProfileAvatarSkeleton size="2xl" />
</div>
<div className="flex flex-col w-full sm:ml-4 gap-y-2 max-sm:items-center">
<Skeleton className="w-[160px] h-[32px] rounded-full bg-primary-200" />
<Skeleton className="w-[112px] h-[16px] rounded-full bg-primary-200" />
</div>
</>
);
};
2 changes: 1 addition & 1 deletion packages/dapp/src/lib/contracts/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { APP_ENV } from '@/utils/appEnv';

const getDefaultChainId = () => {
if (APP_ENV === 'development') {
return 1337;
return 11155111;
}

if (APP_ENV === 'staging') {
Expand Down

0 comments on commit 9824882

Please sign in to comment.