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

feat: profile loading skeleton #4

Merged
merged 2 commits into from
Jun 6, 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
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
Loading