Skip to content

Commit

Permalink
feat(app): add questions pagination (#403)
Browse files Browse the repository at this point in the history
* Updates

* Refactor questions page

* Update page.tsx

* feat(app): add questions pagination

* feat(app): add dark mode to page item

* refactor(app): remove activeHref from props

* feat(app): add redirect to first category page

* feat(app): add current page technology

Co-authored-by: Michal Miszczyszyn <michal@mmiszy.pl>
  • Loading branch information
AdiPol1359 and typeofweb committed Dec 12, 2022
1 parent 2923fba commit c20b11a
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 28 deletions.
40 changes: 40 additions & 0 deletions apps/app/src/app/questions/[technology]/[page]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { redirect } from "next/navigation";
import { QuestionItem } from "../../../../components/QuestionItem/QuestionItem";
import { QuestionsPagination } from "../../../../components/QuestionsPagination";
import { PAGE_SIZE } from "../../../../lib/constants";
import { technologies } from "../../../../lib/technologies";
import { getAllQuestions } from "../../../../services/questions.service";

export default async function QuestionsPage({
params,
}: {
params: { technology: string; page: string };
}) {
const page = parseInt(params.page);

if (!technologies.includes(params.technology) || isNaN(page)) {
return redirect("/");
}

const { data } = await getAllQuestions({
category: params.technology,
limit: PAGE_SIZE,
offset: (page - 1) * PAGE_SIZE,
});

return (
<div className="flex flex-col gap-y-10">
{data.data.map(({ id, question, _levelId, acceptedAt, votesCount }) => (
<QuestionItem
key={id}
title={question}
level={_levelId}
creationDate={new Date(acceptedAt || "")}
votes={votesCount}
voted={id % 2 === 0}
/>
))}
<QuestionsPagination technology={params.technology} total={data.meta.total} />
</div>
);
}
28 changes: 3 additions & 25 deletions apps/app/src/app/questions/[technology]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
import { redirect } from "next/navigation";
import { QuestionItem } from "../../../components/QuestionItem/QuestionItem";
import { technologies } from "../../../lib/technologies";
import { getAllQuestions } from "../../../services/questions.service";

export default async function QuestionsPage({ params }: { params: { technology: string } }) {
if (!technologies.includes(params.technology)) {
return redirect("/");
}

const { data } = await getAllQuestions({ category: params.technology, limit: 20 });

return (
<div className="flex flex-col gap-y-10">
{data.data.map(({ id, question, _levelId, acceptedAt, votesCount }) => (
<QuestionItem
key={id}
title={question}
level={_levelId}
creationDate={new Date(acceptedAt || "")}
votes={votesCount}
voted={id % 2 === 0}
/>
))}
</div>
);
};
export default function TechnologyPage({ params }: { params: { technology: string } }) {
return redirect(`/questions/${params.technology}/1`);
}
2 changes: 1 addition & 1 deletion apps/app/src/app/questions/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const QuestionsPageLayout = ({ children }: { readonly children: ReactNode }) =>
<>
<Container className="flex">
<QuestionsSidebar />
<main className="grow py-8 pl-11">{children}</main>
<main className="grow py-4 pl-0 sm:py-8 sm:pl-11">{children}</main>
</Container>
<MobileActionButtons />
</>
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/app/questions/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { redirect } from "next/navigation";

export default function QuestionsPage() {
return redirect("/questions/js");
return redirect("/questions/js/1");
}
2 changes: 1 addition & 1 deletion apps/app/src/components/ActiveLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const ActiveLink = ({
...rest
}: ActiveLinkProps) => {
const pathname = usePathname();
const isActive = href === pathname;
const isActive = pathname?.startsWith(href.toString());

return (
<Link href={href} className={twMerge(className, isActive && activeClassName)} {...rest}>
Expand Down
26 changes: 26 additions & 0 deletions apps/app/src/components/QuestionsPagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { PAGE_SIZE } from "../lib/constants";
import { ActiveLink } from "./ActiveLink";

type QuestionsPaginationProps = Readonly<{
technology: string;
total: number;
}>;

export const QuestionsPagination = ({ technology, total }: QuestionsPaginationProps) => {
const pages = Math.ceil(total / PAGE_SIZE);

return (
<div className="flex justify-center gap-x-3">
{Array.from({ length: pages }).map((_, i) => (
<ActiveLink
key={i}
href={`/questions/${technology}/${i + 1}`}
className="flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border-2 border-primary text-primary transition-colors duration-300 hover:bg-violet-100 dark:text-white dark:hover:bg-violet-800"
activeClassName="bg-primary text-white"
>
{i + 1}
</ActiveLink>
))}
</div>
);
};
1 change: 1 addition & 0 deletions apps/app/src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const PAGE_SIZE = 20;

0 comments on commit c20b11a

Please sign in to comment.