Skip to content

Commit

Permalink
feat: better loading skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
FelixFern committed Jul 21, 2024
1 parent e22c046 commit 86f9e21
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 106 deletions.
40 changes: 22 additions & 18 deletions src/routeTree.gen.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,48 @@
/* prettier-ignore-start */

/* eslint-disable */

// @ts-nocheck

// noinspection JSUnusedGlobalSymbols

// This file is auto-generated by TanStack Router

import { createFileRoute } from "@tanstack/react-router";
import { createFileRoute } from '@tanstack/react-router'

// Import Routes

import { Route as rootRoute } from "./routes/__root";
import { Route as PokemonIndexImport } from "./routes/pokemon/index";
import { Route as rootRoute } from './routes/__root'
import { Route as PokemonIndexImport } from './routes/pokemon/index'

// Create Virtual Routes

const IndexLazyImport = createFileRoute("/")();
const IndexLazyImport = createFileRoute('/')()

// Create/Update Routes

const IndexLazyRoute = IndexLazyImport.update({
path: "/",
path: '/',
getParentRoute: () => rootRoute,
} as any).lazy(() => import("./routes/index.lazy").then((d) => d.Route));
} as any).lazy(() => import('./routes/index.lazy').then((d) => d.Route))

const PokemonIndexRoute = PokemonIndexImport.update({
path: "/pokemon/",
path: '/pokemon/',
getParentRoute: () => rootRoute,
} as any);
} as any)

// Populate the FileRoutesByPath interface

declare module "@tanstack/react-router" {
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
"/": {
preLoaderRoute: typeof IndexLazyImport;
parentRoute: typeof rootRoute;
};
"/pokemon/": {
preLoaderRoute: typeof PokemonIndexImport;
parentRoute: typeof rootRoute;
};
'/': {
preLoaderRoute: typeof IndexLazyImport
parentRoute: typeof rootRoute
}
'/pokemon/': {
preLoaderRoute: typeof PokemonIndexImport
parentRoute: typeof rootRoute
}
}
}

Expand All @@ -47,6 +51,6 @@ declare module "@tanstack/react-router" {
export const routeTree = rootRoute.addChildren([
IndexLazyRoute,
PokemonIndexRoute,
]);
])

/* prettier-ignore-end */
25 changes: 25 additions & 0 deletions src/routes/pokemon/-components/CardLoading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Card, CardContent, CardHeader } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';

const CardLoading = () => {
return (
<Card className='cursor-pointer aspect-square'>
<CardHeader>
<div className='flex items-center justify-center'>
<Skeleton className='w-[128px] aspect-square duration-10 opacity-100' />
</div>
</CardHeader>
<CardContent>
<div className='flex flex-col items-center justify-center gap-2'>
<Skeleton className='w-40 h-4 opacity-100 duration-10' />
<div className='flex justify-center gap-2'>
<Skeleton className='w-16 h-4 opacity-100 duration-10' />
<Skeleton className='w-16 h-4 opacity-100 duration-10' />
</div>
</div>
</CardContent>
</Card>
);
};

export default CardLoading;
28 changes: 14 additions & 14 deletions src/routes/pokemon/-components/PokemonCard.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { Card, CardContent, CardHeader } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import { capitalizeString, cn, mapTypeColor } from '@/lib/utils';
import { GetAllPokemonData } from '@/types';
import { useState } from 'react';
import { usePokemonDetailData } from '../-hooks/usePokemonDetailData';
import CardLoading from './CardLoading';

const PokemonCard = ({ name }: GetAllPokemonData) => {
const { data, isLoading } = usePokemonDetailData({ name });
const [hovered, setHovered] = useState(false);

if (isLoading) {
return <CardLoading />;
}

return (
<Card
className='cursor-pointer aspect-square'
Expand All @@ -17,19 +21,15 @@ const PokemonCard = ({ name }: GetAllPokemonData) => {
>
<CardHeader>
<div className='flex items-center justify-center'>
{isLoading ? (
<Skeleton className='h-[128px] aspect-square' />
) : (
<img
src={
hovered
? data?.sprites.front_shiny
: data?.sprites.front_default
}
alt={data?.name}
className='w-[128px] aspect-square duration-100 opacity-100'
/>
)}
<img
src={
hovered
? data?.sprites.front_shiny
: data?.sprites.front_default
}
alt={data?.name}
className='w-[128px] aspect-square duration-100 opacity-100'
/>
</div>
</CardHeader>
<CardContent>
Expand Down
148 changes: 74 additions & 74 deletions src/routes/pokemon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,83 @@
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious
} from "@/components/ui/pagination";
import { Skeleton } from "@/components/ui/skeleton";
import { GetAllPokemonParams } from "@/types";
import { Link, createFileRoute } from "@tanstack/react-router";
import PokemonCard from "./-components/PokemonCard";
import { usePokemonImpl } from "./-usePokemonImpl";
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious
} from '@/components/ui/pagination';
import { GetAllPokemonParams } from '@/types';
import { Link, createFileRoute } from '@tanstack/react-router';
import CardLoading from './-components/CardLoading';
import PokemonCard from './-components/PokemonCard';
import { usePokemonImpl } from './-usePokemonImpl';

export const Route = createFileRoute("/pokemon/")({
component: Pokemon,
validateSearch: (search: Record<string, unknown>): GetAllPokemonParams => {
return {
limit: (search.limit as number) ?? 15,
offset: (search.offset as number) ?? 0
};
}
export const Route = createFileRoute('/pokemon/')({
component: Pokemon,
validateSearch: (search: Record<string, unknown>): GetAllPokemonParams => {
return {
limit: (search.limit as number) ?? 15,
offset: (search.offset as number) ?? 0
};
}
});

function Pokemon() {
const params = Route.useSearch();
const params = Route.useSearch();

const { data, isLoading } = usePokemonImpl({ params });
const { data, isLoading } = usePokemonImpl({ params });

return (
<>
{isLoading ? (
<div className='grid grid-cols-5 gap-4 mb-6'>
{Array(15)
.fill(0)
.map(() => (
<Skeleton className='w-full aspect-square' />
))}
</div>
) : (
<div className='grid grid-cols-5 gap-4 mb-6'>
{data?.results.map((pokemon) => (
<PokemonCard {...pokemon} key={pokemon.name} />
))}
</div>
)}
return (
<>
{isLoading ? (
<div className='grid grid-cols-5 gap-4 mb-6'>
{Array(15)
.fill(0)
.map(() => (
<CardLoading />
))}
</div>
) : (
<div className='grid grid-cols-5 gap-4 mb-6'>
{data?.results.map((pokemon) => (
<PokemonCard {...pokemon} key={pokemon.name} />
))}
</div>
)}

<Pagination>
<PaginationContent>
<PaginationItem>
<Link
href='#'
search={{
...params,
offset: params.offset - params.limit
}}
disabled={params.offset === 0}
>
<PaginationPrevious />
</Link>
</PaginationItem>
<PaginationItem>
<PaginationLink href='#' isActive>
{params.offset / params.limit + 1}
</PaginationLink>
</PaginationItem>
<PaginationItem>
<Link
href='#'
disabled={params.offset === data?.count}
search={{
...params,
offset: params.offset + params.limit
}}
>
<PaginationNext href='#' />
</Link>
</PaginationItem>
</PaginationContent>
</Pagination>
</>
);
<Pagination>
<PaginationContent>
<PaginationItem>
<Link
href='#'
search={{
...params,
offset: params.offset - params.limit
}}
disabled={params.offset === 0}
>
<PaginationPrevious />
</Link>
</PaginationItem>
<PaginationItem>
<PaginationLink href='#' isActive>
{params.offset / params.limit + 1}
</PaginationLink>
</PaginationItem>
<PaginationItem>
<Link
href='#'
disabled={params.offset === data?.count}
search={{
...params,
offset: params.offset + params.limit
}}
>
<PaginationNext href='#' />
</Link>
</PaginationItem>
</PaginationContent>
</Pagination>
</>
);
}

0 comments on commit 86f9e21

Please sign in to comment.