Skip to content

Commit

Permalink
Homepage rework
Browse files Browse the repository at this point in the history
  • Loading branch information
Haaxor1689 committed Aug 5, 2024
1 parent 7a703bf commit 8238d74
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 45 deletions.
11 changes: 6 additions & 5 deletions src/app/FiltersSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,22 @@ 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()}`);
}, [values, pathname, router, searchParams]);

return (
<FormProvider {...formProps}>
<div className="flex flex-col items-stretch gap-2 md:flex-row">
<div className="px-2 md:px-0">
<ListFilter size={38} className="text-orange" />
</div>
<div className="flex flex-row items-stretch gap-2">
<ListFilter size={38} className="w-[41px] shrink-0 text-orange" />
<form className="tw-surface flex grow flex-col items-stretch gap-2 md:flex-row md:items-center md:p-4">
<Input
{...register('name')}
Expand Down
34 changes: 21 additions & 13 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Spinner from '~/components/styled/Spinner';
import PublicTrees from '~/components/tree-lists/PublicTrees';
import TurtleTrees from '~/components/tree-lists/TurtleTrees';
import ProposalTrees from '~/components/tree-lists/ProposalTrees';
import Tabs from '~/components/Tabs';

import FiltersSection from './FiltersSection';

Expand All @@ -19,19 +20,26 @@ const Home = async ({ searchParams }: { searchParams: FiltersT }) => {
<FiltersSection {...params.data} />

<Suspense fallback={<Spinner className="my-6 self-center" />}>
<PersonalTrees {...params.data} />
</Suspense>

<Suspense fallback={<Spinner className="my-6 self-center" />}>
<PublicTrees {...params.data} />
</Suspense>

<Suspense fallback={<Spinner className="my-6 self-center" />}>
<ProposalTrees {...params.data} />
</Suspense>

<Suspense fallback={<Spinner className="my-6 self-center" />}>
<TurtleTrees {...params.data} />
<Tabs
tabs={{
turtle: {
title: 'Turtle WoW',
component: <TurtleTrees {...params.data} />
},
proposals: {
title: 'Proposals',
component: <ProposalTrees {...params.data} />
},
personal: {
title: 'Personal',
component: <PersonalTrees {...params.data} />
},
public: {
title: 'Public',
component: <PublicTrees {...params.data} />
}
}}
/>
</Suspense>
</>
);
Expand Down
7 changes: 7 additions & 0 deletions src/components/NoResults.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const NoResults = () => (
<div className="tw-surface flex grow items-center justify-center py-6 text-blueGray">
No results found
</div>
);

export default NoResults;
75 changes: 75 additions & 0 deletions src/components/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -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<string, Tab>;

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 (
<div className="flex flex-row items-stretch gap-2">
<div className="flex flex-col gap-2 py-3">
{tabArray.map(([key, tab]) => (
<div
key={key}
className={cls(
'tw-surface -mr-2 border-r-0 p-0',
current === key && 'bg-darkGray'
)}
>
<button
onClick={() => setCurrent(key)}
className={cls(
'tw-hocus tw-color block px-2 py-3 font-fontin text-2xl uppercase'
)}
style={{ textOrientation: 'mixed', writingMode: 'vertical-rl' }}
>
{tab.title}
{!!tab.count && ` (${tab.count})`}
</button>
</div>
))}
</div>
{!tabArray.length
? noTabsContent ?? <NoResults />
: tabs[current as never]?.component ?? <NoResults />}
</div>
);
};

export default Tabs;
5 changes: 3 additions & 2 deletions src/components/tree-lists/LocalTrees.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 & {
Expand All @@ -22,11 +24,10 @@ const LocalTrees = ({ serverList, name, from, class: classId }: Props) => {
return <Spinner className="self-center" />;

if (!serverList.length && !Object.values(savedSpecs ?? {}).length)
return null;
return <NoResults />;

return (
<TalentTreeGrid
title="Personal"
list={[
...serverList,
...Object.values(savedSpecs ?? {})
Expand Down
5 changes: 3 additions & 2 deletions src/components/tree-lists/ProposalTrees.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { listProposalTalentTrees } from '~/server/api/routers/talentTree';
import { type FiltersT } from '~/server/api/types';

import NoResults from '../NoResults';

import TalentTreeGrid from './TalentTreeGrid';

const ProposalTrees = async (props: FiltersT) => {
const list = await listProposalTalentTrees(props).catch(() => []);

if (!list.length) return null;
if (!list.length) return <NoResults />;

return (
<TalentTreeGrid
title="Proposals"
list={list.map(s => ({
href: `/tree/${s.id}`,
...s
Expand Down
6 changes: 4 additions & 2 deletions src/components/tree-lists/PublicTrees.tsx
Original file line number Diff line number Diff line change
@@ -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 <NoResults />;

return (
<TalentTreeGrid
title="Public"
list={list.map(s => ({
href: `/tree/${s.id}`,
...s
Expand Down
26 changes: 8 additions & 18 deletions src/components/tree-lists/TalentTreeGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,28 +96,18 @@ const GridItem = (item: Item) => {
};

type Props = {
title: string;
list: Item[];
};

const TalentTreeGrid = ({ title, list }: Props) => (
<div className="flex flex-col items-stretch gap-2 md:flex-row">
<h3
className="tw-color hidden py-3 md:block"
style={{ textOrientation: 'mixed', writingMode: 'vertical-rl' }}
const TalentTreeGrid = ({ list }: Props) => (
<div className="tw-surface grow p-2 md:p-4">
<div
className="grid items-start gap-3"
style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))' }}
>
{title}
</h3>
<h3 className="tw-color px-2 md:hidden">{title}</h3>
<div className="tw-surface grow p-2 md:p-4">
<div
className="grid items-start gap-3"
style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))' }}
>
{list.map(item => (
<GridItem key={item.href} {...item} />
))}
</div>
{list.map(item => (
<GridItem key={item.href} {...item} />
))}
</div>
</div>
);
Expand Down
5 changes: 3 additions & 2 deletions src/components/tree-lists/TurtleTrees.tsx
Original file line number Diff line number Diff line change
@@ -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 <NoResults />;

return (
<TalentTreeGrid
title="Turtle WoW"
list={list.map(s => ({
href: `/tree/${s.id}`,
...s
Expand Down
3 changes: 2 additions & 1 deletion src/server/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof CalculatorParams>;
Expand Down

0 comments on commit 8238d74

Please sign in to comment.