From 798ef10469101e7566992c7dcb30d610a11b6933 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com>
Date: Mon, 24 Jun 2024 14:10:23 -0500
Subject: [PATCH] feat: skeletons
---
.../tools/tankopedia/components/NoResults.tsx | 30 +++++++++++++++++
.../tools/tankopedia/components/Results.tsx | 32 ++++++++++++++++---
.../tools/tankopedia/components/SearchBar.tsx | 8 ++---
.../components/SkeletonTankCard.tsx | 10 ++++++
.../tankopedia/components/TankCardWrapper.tsx | 1 +
.../tools/tankopedia/components/TierCard.tsx | 28 ++--------------
src/app/tools/tankopedia/page.tsx | 11 +------
src/stores/tankopediaFilters.ts | 2 ++
8 files changed, 78 insertions(+), 44 deletions(-)
create mode 100644 src/app/tools/tankopedia/components/NoResults.tsx
create mode 100644 src/app/tools/tankopedia/components/SkeletonTankCard.tsx
diff --git a/src/app/tools/tankopedia/components/NoResults.tsx b/src/app/tools/tankopedia/components/NoResults.tsx
new file mode 100644
index 000000000..c4c32c300
--- /dev/null
+++ b/src/app/tools/tankopedia/components/NoResults.tsx
@@ -0,0 +1,30 @@
+import { Flex, Link, Text } from '@radix-ui/themes';
+import { useTankopediaFilters } from '../../../../stores/tankopediaFilters';
+
+interface NoResultsProps {
+ type?: 'filters' | 'search';
+}
+
+export function NoResults({ type = 'filters' }: NoResultsProps) {
+ return (
+
+
+ No tanks found.{' '}
+
+ useTankopediaFilters.setState(
+ useTankopediaFilters.getInitialState(),
+ true,
+ )
+ }
+ >
+ {type === 'filters' ? 'Try clearing filters' : 'Try searching again'}
+
+ .
+
+
+ );
+}
diff --git a/src/app/tools/tankopedia/components/Results.tsx b/src/app/tools/tankopedia/components/Results.tsx
index 7285b3bef..440ab02ad 100644
--- a/src/app/tools/tankopedia/components/Results.tsx
+++ b/src/app/tools/tankopedia/components/Results.tsx
@@ -1,5 +1,6 @@
import { Callout, Flex } from '@radix-ui/themes';
import { go } from 'fuzzysort';
+import { times } from 'lodash';
import { memo, use, useMemo } from 'react';
import { ExperimentIcon } from '../../../../components/ExperimentIcon';
import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration';
@@ -16,7 +17,9 @@ import {
import { unionBoundingBox } from '../../../../core/blitzkit/unionBoundingBox';
import { useTankopediaFilters } from '../../../../stores/tankopediaFilters';
import { FilterControl } from './FilterControl';
+import { NoResults } from './NoResults';
import { SearchBar } from './SearchBar';
+import { SkeletonTankCard } from './SkeletonTankCard';
import { TankCard } from './TankCard';
import { TankCardWrapper } from './TankCardWrapper';
import { TierCard } from './TierCard';
@@ -30,6 +33,7 @@ export const Results = memo(() => {
const search = useTankopediaFilters((state) => state.search);
const tier = useTankopediaFilters((state) => state.tier);
const sort = useTankopediaFilters((state) => state.sort);
+ const searching = useTankopediaFilters((state) => state.searching);
const searchedTanks = useMemo(() => {
if (search !== undefined) {
const searchedRaw = go(search, awaitedTankNames, {
@@ -330,7 +334,7 @@ export const Results = memo(() => {
- {!search && }
+ {!search && !searching && }
{testing === 'only' && (
@@ -346,11 +350,29 @@ export const Results = memo(() => {
)}
- {!search && sort.by === 'meta.tier' && }
+ {!search && sort.by === 'meta.tier' && !searching && (
+
+ )}
- {(search || sort.by !== 'meta.tier') && (
-
- {searchedTanks?.map((tank) => )}
+ {(search || sort.by !== 'meta.tier') && !searching && searchedTanks && (
+ <>
+ {searchedTanks.length > 0 && (
+
+ {searchedTanks.map((tank) => (
+
+ ))}
+
+ )}
+
+ {searchedTanks.length === 0 && }
+ >
+ )}
+
+ {searching && (
+
+ {times(Math.round(10 + 10 * Math.random()), (index) => (
+
+ ))}
)}
diff --git a/src/app/tools/tankopedia/components/SearchBar.tsx b/src/app/tools/tankopedia/components/SearchBar.tsx
index 0deb97b33..e5287fcba 100644
--- a/src/app/tools/tankopedia/components/SearchBar.tsx
+++ b/src/app/tools/tankopedia/components/SearchBar.tsx
@@ -2,7 +2,7 @@ import { CaretRightIcon, MagnifyingGlassIcon } from '@radix-ui/react-icons';
import { Button, Flex, Spinner, TextField } from '@radix-ui/themes';
import { debounce } from 'lodash';
import { useRouter } from 'next/navigation';
-import { KeyboardEventHandler, useCallback, useRef, useState } from 'react';
+import { KeyboardEventHandler, useCallback, useRef } from 'react';
import { Link } from '../../../../components/Link';
import { TankDefinition } from '../../../../core/blitzkit/tankDefinitions';
import { useTankopediaFilters } from '../../../../stores/tankopediaFilters';
@@ -14,11 +14,11 @@ interface SearchBarProps {
export function SearchBar({ topResult }: SearchBarProps) {
const router = useRouter();
- const [searching, setSearching] = useState(false);
const input = useRef(null);
+ const searching = useTankopediaFilters((state) => state.searching);
const search = useCallback(
debounce(() => {
- setSearching(false);
+ useTankopediaFilters.setState({ searching: false });
if (!input.current) return;
@@ -31,7 +31,7 @@ export function SearchBar({ topResult }: SearchBarProps) {
[],
);
const handleChange = useCallback(() => {
- setSearching(true);
+ useTankopediaFilters.setState({ searching: true });
search();
}, []);
const handleKeyDown = useCallback(
diff --git a/src/app/tools/tankopedia/components/SkeletonTankCard.tsx b/src/app/tools/tankopedia/components/SkeletonTankCard.tsx
new file mode 100644
index 000000000..5aaff521e
--- /dev/null
+++ b/src/app/tools/tankopedia/components/SkeletonTankCard.tsx
@@ -0,0 +1,10 @@
+import { Flex, Skeleton } from '@radix-ui/themes';
+
+export function SkeletonTankCard() {
+ return (
+
+
+
+
+ );
+}
diff --git a/src/app/tools/tankopedia/components/TankCardWrapper.tsx b/src/app/tools/tankopedia/components/TankCardWrapper.tsx
index 73bbde572..67fc8940d 100644
--- a/src/app/tools/tankopedia/components/TankCardWrapper.tsx
+++ b/src/app/tools/tankopedia/components/TankCardWrapper.tsx
@@ -3,6 +3,7 @@ import { Grid, GridProps } from '@radix-ui/themes';
export function TankCardWrapper(props: GridProps) {
return (
-
- No tanks found.{' '}
-
- useTankopediaFilters.setState(
- useTankopediaFilters.getInitialState(),
- true,
- )
- }
- >
- Try clearing filters
-
- .
-
-
- );
+ if (tanks.length === 0) return ;
return (
-
+
{tanks.map((tank) => (
))}
diff --git a/src/app/tools/tankopedia/page.tsx b/src/app/tools/tankopedia/page.tsx
index 76231debb..f27557f56 100644
--- a/src/app/tools/tankopedia/page.tsx
+++ b/src/app/tools/tankopedia/page.tsx
@@ -1,21 +1,12 @@
'use client';
-import { Flex } from '@radix-ui/themes';
import PageWrapper from '../../../components/PageWrapper';
import { Results } from './components/Results';
export default function Page() {
return (
-
- {/* */}
-
-
+
);
}
diff --git a/src/stores/tankopediaFilters.ts b/src/stores/tankopediaFilters.ts
index fb1c4a154..ffcaeb958 100644
--- a/src/stores/tankopediaFilters.ts
+++ b/src/stores/tankopediaFilters.ts
@@ -15,6 +15,7 @@ export interface TankopediaFilters {
by: TankopediaSortBy;
direction: TankopediaSortDirection;
};
+ searching: boolean;
}
export const useTankopediaFilters = create()(() => ({
@@ -24,6 +25,7 @@ export const useTankopediaFilters = create()(() => ({
direction: 'descending',
},
tier: 10,
+ searching: false,
}));
export function mutateTankopediaFilters(