From ee1847c937e20ec2ce4cfb0c60930983b637e9b6 Mon Sep 17 00:00:00 2001
From: Axel Pettersson
Date: Sun, 1 Oct 2023 17:29:52 +0200
Subject: [PATCH] Various improvements and member document support
---
.../api/member/[id]/documents/[page]/route.ts | 22 +++
apps/web/app/cookie-policy/page.tsx | 2 +-
apps/web/app/error.tsx | 4 +-
apps/web/app/layout.tsx | 6 +-
apps/web/app/ledamot/[id]/biography-entry.tsx | 4 +-
apps/web/app/ledamot/[id]/biography.tsx | 2 +-
apps/web/app/ledamot/[id]/documents.tsx | 63 ++++++++-
apps/web/app/ledamot/[id]/statistics.tsx | 2 +-
apps/web/app/ledamot/[id]/tabs.tsx | 2 +-
apps/web/app/not-found.tsx | 2 +-
apps/web/app/om-oss/page.tsx | 2 +-
apps/web/app/page.tsx | 8 +-
apps/web/app/parti/[party]/page.tsx | 2 +-
.../standpunkter/[id]/party-standpoints.tsx | 29 ++--
apps/web/components/card.tsx | 19 ---
apps/web/components/common/breadcrumbs.tsx | 2 +-
apps/web/components/{ => common}/button.tsx | 0
apps/web/components/common/card.tsx | 52 +++++++
apps/web/components/common/pagination.tsx | 127 ++++++++++++++++++
apps/web/components/header/header.tsx | 2 +-
.../components/{ => header}/theme-toggle.tsx | 0
.../api/documents/parsers/member-document.ts | 8 +-
apps/web/lib/api/member/get-absence.ts | 2 +-
.../lib/api/member/get-member-with-absence.ts | 4 +-
apps/web/lib/api/member/parsers/absence.ts | 3 +-
apps/web/lib/api/member/types.ts | 15 ++-
apps/web/lib/api/parliament/types.ts | 3 +-
apps/web/lib/committes.ts | 18 +++
apps/web/lib/navigation.tsx | 9 +-
apps/web/lib/styles/committees.ts | 22 +++
apps/web/lib/styles/party.ts | 31 ++---
apps/web/tailwind.config.ts | 6 +-
32 files changed, 387 insertions(+), 86 deletions(-)
create mode 100644 apps/web/app/api/member/[id]/documents/[page]/route.ts
delete mode 100644 apps/web/components/card.tsx
rename apps/web/components/{ => common}/button.tsx (100%)
create mode 100644 apps/web/components/common/card.tsx
create mode 100644 apps/web/components/common/pagination.tsx
rename apps/web/components/{ => header}/theme-toggle.tsx (100%)
diff --git a/apps/web/app/api/member/[id]/documents/[page]/route.ts b/apps/web/app/api/member/[id]/documents/[page]/route.ts
new file mode 100644
index 000000000..b64c12c58
--- /dev/null
+++ b/apps/web/app/api/member/[id]/documents/[page]/route.ts
@@ -0,0 +1,22 @@
+import getMemberDocuments from "@lib/api/documents/get-member-documents";
+
+interface Payload {
+ params: {
+ id: string;
+ page: string;
+ };
+}
+
+export async function GET(
+ _request: Request,
+ { params: { id, page } }: Payload,
+) {
+ const pageInt = parseInt(page);
+
+ if (Number.isNaN(pageInt)) {
+ return new Response("Invalid page", { status: 400 });
+ }
+
+ const memberDocuments = await getMemberDocuments({ id, page: pageInt });
+ return Response.json(memberDocuments);
+}
diff --git a/apps/web/app/cookie-policy/page.tsx b/apps/web/app/cookie-policy/page.tsx
index 57bb426a2..7ab09e23c 100644
--- a/apps/web/app/cookie-policy/page.tsx
+++ b/apps/web/app/cookie-policy/page.tsx
@@ -1,4 +1,4 @@
-import { Card } from "@components/card";
+import { Card } from "@components/common/card";
import Container from "@components/common/container";
import PageTitle from "@components/common/page-title";
import { CodeBracketIcon } from "@heroicons/react/24/solid";
diff --git a/apps/web/app/error.tsx b/apps/web/app/error.tsx
index 253d8f1f5..2e3007c70 100644
--- a/apps/web/app/error.tsx
+++ b/apps/web/app/error.tsx
@@ -1,7 +1,7 @@
"use client";
-import { PrimaryButton } from "@components/button";
-import { Card } from "@components/card";
+import { PrimaryButton } from "@components/common/button";
+import { Card } from "@components/common/card";
import Container from "@components/common/container";
import PageTitle from "@components/common/page-title";
import { ExclamationCircleIcon } from "@heroicons/react/24/solid";
diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx
index 36b09ca0b..0bbddff8a 100644
--- a/apps/web/app/layout.tsx
+++ b/apps/web/app/layout.tsx
@@ -5,6 +5,7 @@ import Head from "./head";
import Footer from "./footer";
import Header from "@components/header/header";
import { ThemeProvider } from "@components/providers/theme-provider";
+import { twMerge } from "tailwind-merge";
const roboto = Roboto({
weight: ["300", "400", "500", "700"],
@@ -18,7 +19,10 @@ export default function RootLayout({ children }: PropsWithChildren) {
diff --git a/apps/web/app/ledamot/[id]/biography-entry.tsx b/apps/web/app/ledamot/[id]/biography-entry.tsx
index a5f790992..4de60b74e 100644
--- a/apps/web/app/ledamot/[id]/biography-entry.tsx
+++ b/apps/web/app/ledamot/[id]/biography-entry.tsx
@@ -25,9 +25,9 @@ export default function BiographyEntry({ information }: Props) {
{information.code}
-
+
{information.content}
-
+
);
}
diff --git a/apps/web/app/ledamot/[id]/biography.tsx b/apps/web/app/ledamot/[id]/biography.tsx
index 1aa7ee0bc..8af125f53 100644
--- a/apps/web/app/ledamot/[id]/biography.tsx
+++ b/apps/web/app/ledamot/[id]/biography.tsx
@@ -1,4 +1,4 @@
-import { Card } from "@components/card";
+import { Card } from "@components/common/card";
import type { Information } from "@lib/api/member/types";
import BiographyEntry from "./biography-entry";
diff --git a/apps/web/app/ledamot/[id]/documents.tsx b/apps/web/app/ledamot/[id]/documents.tsx
index 66dd72f99..6b6c4393a 100644
--- a/apps/web/app/ledamot/[id]/documents.tsx
+++ b/apps/web/app/ledamot/[id]/documents.tsx
@@ -1,9 +1,32 @@
"use client";
-import type { MemberDocuments } from "@lib/api/member/types";
-import { useState } from "react";
+import { Card, CommitteeHeader } from "@components/common/card";
+import Pagination from "@components/common/pagination";
+import type { MemberDocument, MemberDocuments } from "@lib/api/member/types";
+import { routes } from "@lib/navigation";
+import Link from "next/link";
+import { useRef, useState } from "react";
-function Document() {
- return hej
;
+interface DocumentProps {
+ document: MemberDocument;
+}
+
+function Document({ document }: DocumentProps) {
+ return (
+
+
+
+
+
+ {document.title}
+
+
{document.altTitle}
+
+ {document.subtitle}
+
+
+
+
+ );
}
interface Props {
@@ -12,13 +35,39 @@ interface Props {
}
export default function Documents({ initialDocuments, memberId }: Props) {
+ const containerRef = useRef(null);
+ const [page, setPage] = useState(1);
const [documents, setDocuments] = useState(initialDocuments.documents);
+ async function changePage(page: number) {
+ const response = await fetch(
+ `${window.location.origin}${routes.api.memberDocument(memberId, page)}`,
+ { next: { revalidate: 60 * 60 * 24 } },
+ );
+ const newDocuments: MemberDocuments = await response.json();
+ setPage(page);
+ setDocuments(newDocuments.documents);
+ containerRef.current?.scrollIntoView();
+ }
+
return (
- <>
+
+
{documents.map((document) => (
-
{document.altTitle}
+
))}
- >
+
+
);
}
diff --git a/apps/web/app/ledamot/[id]/statistics.tsx b/apps/web/app/ledamot/[id]/statistics.tsx
index 3420dedbf..80cc51eee 100644
--- a/apps/web/app/ledamot/[id]/statistics.tsx
+++ b/apps/web/app/ledamot/[id]/statistics.tsx
@@ -1,4 +1,4 @@
-import { Card } from "@components/card";
+import { Card } from "@components/common/card";
import type { MemberDetailedResponse } from "@lib/api/member/types";
import { twMerge } from "tailwind-merge";
diff --git a/apps/web/app/ledamot/[id]/tabs.tsx b/apps/web/app/ledamot/[id]/tabs.tsx
index f29cad6f8..18f1db074 100644
--- a/apps/web/app/ledamot/[id]/tabs.tsx
+++ b/apps/web/app/ledamot/[id]/tabs.tsx
@@ -1,6 +1,6 @@
"use client";
-import { Card } from "@components/card";
+import { Card } from "@components/common/card";
import type { MemberDocuments } from "@lib/api/member/types";
import { useState } from "react";
import Documents from "./documents";
diff --git a/apps/web/app/not-found.tsx b/apps/web/app/not-found.tsx
index 8c1ba8c0d..3f7de4a95 100644
--- a/apps/web/app/not-found.tsx
+++ b/apps/web/app/not-found.tsx
@@ -1,4 +1,4 @@
-import { Card } from "@components/card";
+import { Card } from "@components/common/card";
import Container from "@components/common/container";
import PageTitle from "@components/common/page-title";
import { ExclamationCircleIcon } from "@heroicons/react/24/solid";
diff --git a/apps/web/app/om-oss/page.tsx b/apps/web/app/om-oss/page.tsx
index 5ab591caf..1cfaf76a5 100644
--- a/apps/web/app/om-oss/page.tsx
+++ b/apps/web/app/om-oss/page.tsx
@@ -1,6 +1,6 @@
import { githubFrontend, githubProfile, linkedIn } from "@lib/socials";
import PageTitle from "@components/common/page-title";
-import { Card } from "@components/card";
+import { Card } from "@components/common/card";
import React from "react";
import { InformationCircleIcon } from "@heroicons/react/24/solid";
import ExternalLink from "@components/common/external-link";
diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx
index 09fadb736..3bd1220a5 100644
--- a/apps/web/app/page.tsx
+++ b/apps/web/app/page.tsx
@@ -1,9 +1,10 @@
-import { Card } from "@components/card";
+import { Card } from "@components/common/card";
import Typed from "@components/common/typed";
import Link from "next/link";
import { routes } from "@lib/navigation";
import PageTitle from "@components/common/page-title";
import Container from "@components/common/container";
+import { twMerge } from "tailwind-merge";
export const metadata = {
title: "Partiguiden | Rösta rätt",
@@ -53,7 +54,10 @@ export default function IndexPage() {
{subject.name}
diff --git a/apps/web/app/parti/[party]/page.tsx b/apps/web/app/parti/[party]/page.tsx
index 84f8dc198..64093c622 100644
--- a/apps/web/app/parti/[party]/page.tsx
+++ b/apps/web/app/parti/[party]/page.tsx
@@ -1,4 +1,4 @@
-import { Card } from "@components/card";
+import { Card } from "@components/common/card";
import Container from "@components/common/container";
import { Divider } from "@components/common/divider";
import ExternalLink from "@components/common/external-link";
diff --git a/apps/web/app/standpunkter/[id]/party-standpoints.tsx b/apps/web/app/standpunkter/[id]/party-standpoints.tsx
index 82272dbe9..8a3977907 100644
--- a/apps/web/app/standpunkter/[id]/party-standpoints.tsx
+++ b/apps/web/app/standpunkter/[id]/party-standpoints.tsx
@@ -1,13 +1,13 @@
"use client";
-import { Card } from "@components/card";
+import { Card } from "@components/common/card";
import { ChevronUpIcon } from "@heroicons/react/24/solid";
import { dateString } from "@lib/dates";
import {
- backgroundHover,
- borderBottom,
- marker,
- textColor,
+ partyBackgroundHover,
+ partyBorderBottom,
+ partyMarker,
+ partyTextColor,
} from "@lib/styles/party";
import type { Standpoint } from "@partiguiden/party-data/types";
import type { Party } from "@partiguiden/party-data/types";
@@ -34,13 +34,14 @@ export default function PartyStandpoints({
<>
{visible && (
@@ -49,7 +50,9 @@ export default function PartyStandpoints({
{standpoint.title}
{standpoint.opinions.length > 0 ? (
-
+
{standpoint.opinions.map((opinion) => (
- {opinion}
))}
@@ -61,8 +64,8 @@ export default function PartyStandpoints({
->;
-
-export function Card({ children, className = "", ...props }: BaseCardProps) {
- return (
-
- {children}
-
- );
-}
diff --git a/apps/web/components/common/breadcrumbs.tsx b/apps/web/components/common/breadcrumbs.tsx
index 56e387578..f550f23dd 100644
--- a/apps/web/components/common/breadcrumbs.tsx
+++ b/apps/web/components/common/breadcrumbs.tsx
@@ -17,7 +17,7 @@ export interface BreadcrumbsProps {
export default function Breadcrumbs({ links, current }: BreadcrumbsProps) {
return (
-