From 8238d74e0492962446c8ce7f82a7ec43b0aadadc Mon Sep 17 00:00:00 2001 From: Haaxor1689 Date: Mon, 5 Aug 2024 22:53:34 +0200 Subject: [PATCH] Homepage rework --- src/app/FiltersSection.tsx | 11 +-- src/app/page.tsx | 34 +++++---- src/components/NoResults.tsx | 7 ++ src/components/Tabs.tsx | 75 ++++++++++++++++++++ src/components/tree-lists/LocalTrees.tsx | 5 +- src/components/tree-lists/ProposalTrees.tsx | 5 +- src/components/tree-lists/PublicTrees.tsx | 6 +- src/components/tree-lists/TalentTreeGrid.tsx | 26 +++---- src/components/tree-lists/TurtleTrees.tsx | 5 +- src/server/api/types.ts | 3 +- 10 files changed, 132 insertions(+), 45 deletions(-) create mode 100644 src/components/NoResults.tsx create mode 100644 src/components/Tabs.tsx diff --git a/src/app/FiltersSection.tsx b/src/app/FiltersSection.tsx index bf09446..e8b2d04 100644 --- a/src/app/FiltersSection.tsx +++ b/src/app/FiltersSection.tsx @@ -24,10 +24,13 @@ const FiltersSection = (defaultValues: FiltersT) => { const values = useDebounced(watch()); useEffect(() => { - const params = new URLSearchParams(); + const params = new URLSearchParams(searchParams.toString()); if (values.name) params.set('name', values.name); + else params.delete('name'); if (values.from) params.set('from', values.from); + else params.delete('from'); if (values.class) params.set('class', values.class.toString()); + else params.delete('class'); if (searchParams.toString() === params.toString()) return; router.push(`${window.location.origin}${pathname}?${params.toString()}`); @@ -35,10 +38,8 @@ const FiltersSection = (defaultValues: FiltersT) => { return ( -
-
- -
+
+
{ }> - - - - }> - - - - }> - - - - }> - + + }, + proposals: { + title: 'Proposals', + component: + }, + personal: { + title: 'Personal', + component: + }, + public: { + title: 'Public', + component: + } + }} + /> ); diff --git a/src/components/NoResults.tsx b/src/components/NoResults.tsx new file mode 100644 index 0000000..e603001 --- /dev/null +++ b/src/components/NoResults.tsx @@ -0,0 +1,7 @@ +const NoResults = () => ( +
+ No results found +
+); + +export default NoResults; diff --git a/src/components/Tabs.tsx b/src/components/Tabs.tsx new file mode 100644 index 0000000..0047b87 --- /dev/null +++ b/src/components/Tabs.tsx @@ -0,0 +1,75 @@ +'use client'; + +import { type ReactNode } from 'react'; +import cls from 'classnames'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; + +import NoResults from './NoResults'; + +type Tab = { + title: string; + count?: number; + component: ReactNode; +}; + +export type TabsList = Record; + +type Props = { + tabs: TabsList; + noTabsContent?: ReactNode; +}; + +const Tabs = ({ tabs, noTabsContent }: Props) => { + const searchParams = useSearchParams(); + const router = useRouter(); + const pathname = usePathname(); + + const current = searchParams.get('tab') ?? Object.entries(tabs)[0]?.[0]; + + const setCurrent = (tab: string | null) => { + const params = new URLSearchParams(searchParams); + + if (tab) params.set('tab', tab); + else params.delete('tab'); + + params.delete('page'); + params.delete('pageSize'); + params.delete('sort'); + + router.push(`${pathname}?${params}`); + }; + + const tabArray = Object.entries(tabs); + + return ( +
+
+ {tabArray.map(([key, tab]) => ( +
+ +
+ ))} +
+ {!tabArray.length + ? noTabsContent ?? + : tabs[current as never]?.component ?? } +
+ ); +}; + +export default Tabs; diff --git a/src/components/tree-lists/LocalTrees.tsx b/src/components/tree-lists/LocalTrees.tsx index 150c292..6967c4d 100644 --- a/src/components/tree-lists/LocalTrees.tsx +++ b/src/components/tree-lists/LocalTrees.tsx @@ -7,6 +7,8 @@ import { type FiltersT } from '~/server/api/types'; import Spinner from '~/components/styled/Spinner'; import useLocalTrees from '~/hooks/useLocalTrees'; +import NoResults from '../NoResults'; + import TalentTreeGrid from './TalentTreeGrid'; type Props = FiltersT & { @@ -22,11 +24,10 @@ const LocalTrees = ({ serverList, name, from, class: classId }: Props) => { return ; if (!serverList.length && !Object.values(savedSpecs ?? {}).length) - return null; + return ; return ( { const list = await listProposalTalentTrees(props).catch(() => []); - if (!list.length) return null; + if (!list.length) return ; return ( ({ href: `/tree/${s.id}`, ...s diff --git a/src/components/tree-lists/PublicTrees.tsx b/src/components/tree-lists/PublicTrees.tsx index 2d7600f..80c61e4 100644 --- a/src/components/tree-lists/PublicTrees.tsx +++ b/src/components/tree-lists/PublicTrees.tsx @@ -1,15 +1,17 @@ import { listPublicTalentTrees } from '~/server/api/routers/talentTree'; import { type FiltersT } from '~/server/api/types'; +import NoResults from '../NoResults'; + import TalentTreeGrid from './TalentTreeGrid'; const PublicTrees = async (props: FiltersT) => { const list = await listPublicTalentTrees(props).catch(() => []); - if (!list.length) return null; + + if (!list.length) return ; return ( ({ href: `/tree/${s.id}`, ...s diff --git a/src/components/tree-lists/TalentTreeGrid.tsx b/src/components/tree-lists/TalentTreeGrid.tsx index 5e61a9d..97833a2 100644 --- a/src/components/tree-lists/TalentTreeGrid.tsx +++ b/src/components/tree-lists/TalentTreeGrid.tsx @@ -96,28 +96,18 @@ const GridItem = (item: Item) => { }; type Props = { - title: string; list: Item[]; }; -const TalentTreeGrid = ({ title, list }: Props) => ( -
-

( +
+
- {title} -

-

{title}

-
-
- {list.map(item => ( - - ))} -
+ {list.map(item => ( + + ))}
); diff --git a/src/components/tree-lists/TurtleTrees.tsx b/src/components/tree-lists/TurtleTrees.tsx index 3d277de..a901d3e 100644 --- a/src/components/tree-lists/TurtleTrees.tsx +++ b/src/components/tree-lists/TurtleTrees.tsx @@ -1,16 +1,17 @@ import { listTurtleTalentTrees } from '~/server/api/routers/talentTree'; import { type FiltersT } from '~/server/api/types'; +import NoResults from '../NoResults'; + import TalentTreeGrid from './TalentTreeGrid'; const TurtleTrees = async (props: FiltersT) => { const list = await listTurtleTalentTrees(props); - if (!list.length) return null; + if (!list.length) return ; return ( ({ href: `/tree/${s.id}`, ...s diff --git a/src/server/api/types.ts b/src/server/api/types.ts index e9f1454..d8ed297 100644 --- a/src/server/api/types.ts +++ b/src/server/api/types.ts @@ -58,7 +58,8 @@ export const CalculatorParams = z.object({ .string() .regex(/^\d*-\d*-\d*$/) .optional(), - c: z.coerce.number().optional() + c: z.coerce.number().optional(), + tab: z.string().optional() }); export type CalculatorParamsT = z.infer;