From 4a4a318c68fe6c50ee9f9451d1a38181c5d9607f Mon Sep 17 00:00:00 2001 From: Justin O'Boyle Date: Mon, 3 Oct 2022 21:34:11 -0400 Subject: [PATCH] OAP-18 Create basic framework to view books through OAPEN (rough is OK) (#5) * Create items/ route * Add basic query * Vercel * Fix typo * Fix type * Cleaner exports * Explain expandable --- .gitignore | 1 + web/components/core/SEO.tsx | 2 +- web/components/render/RenderItem.tsx | 66 +++++++++++ web/lib/oapen/OAPENTypes.ts | 37 ++++++ web/lib/oapen/index.ts | 1 + web/lib/oapen/items.ts | 69 +++++++++++ web/lib/oapen/query.ts | 8 ++ web/next-env.d.ts | 5 +- web/package-lock.json | 171 +++++++++++++++++++++++++++ web/package.json | 3 + web/pages/items/[uuid].tsx | 43 +++++++ web/pages/items/index.tsx | 38 ++++++ web/styles/globals.css | 8 +- web/tsconfig.json | 19 ++- 14 files changed, 463 insertions(+), 8 deletions(-) create mode 100644 .gitignore create mode 100644 web/components/render/RenderItem.tsx create mode 100644 web/lib/oapen/OAPENTypes.ts create mode 100644 web/lib/oapen/index.ts create mode 100644 web/lib/oapen/items.ts create mode 100644 web/lib/oapen/query.ts create mode 100644 web/pages/items/[uuid].tsx create mode 100644 web/pages/items/index.tsx diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e985853 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vercel diff --git a/web/components/core/SEO.tsx b/web/components/core/SEO.tsx index f5e0de7..3519154 100644 --- a/web/components/core/SEO.tsx +++ b/web/components/core/SEO.tsx @@ -1,4 +1,4 @@ -import { APP_NAME_TEXT, APP_DESCRIPTION } from "../constants"; +import { APP_NAME_TEXT, APP_DESCRIPTION } from "../../constants"; import Head from "next/head"; interface SEOComponents { diff --git a/web/components/render/RenderItem.tsx b/web/components/render/RenderItem.tsx new file mode 100644 index 0000000..64eae69 --- /dev/null +++ b/web/components/render/RenderItem.tsx @@ -0,0 +1,66 @@ +import { OAPENItemWithMetadata } from "../../lib/oapen/OAPENTypes"; +export const RenderItem = ({ item }: { item: OAPENItemWithMetadata }) => { + const type = item.metadata.find(({ key }) => key == "dc.type")?.value; + + if (type == "book") return ; + + return ( + <> +

Could not render this item with type {type}

+
+ +
{JSON.stringify(item, null, 4)}
+
+ + ); +}; +interface InternalBook { + title?: string; + author?: string; + // date + accessioned?: string; + issued?: string; + uri?: string; + abstract?: string; + language?: string; + classification?: string; + altTitle?: string; + publisherName?: string; + pageCount?: string; + item: OAPENItemWithMetadata; +} +const transformToBook = (item: OAPENItemWithMetadata) => { + return { + item, + title: item.metadata.find(({ key }) => key == "dc.title")?.value, + author: item.metadata.find(({ key }) => key == "dc.contributor.author") + ?.value, + accessioned: item.metadata.find(({ key }) => key == "dc.date.accessioned") + ?.value, + issued: item.metadata.find(({ key }) => key == "dc.date.issued")?.value, + uri: item.metadata.find(({ key }) => key == "dc.identifier.uri")?.value, + abstract: item.metadata.find(({ key }) => key == "dc.description.abstract") + ?.value, + language: item.metadata.find(({ key }) => key == "dc.language")?.value, + classification: item.metadata.find( + ({ key }) => key == "dc.subject.classification" + )?.value, + altTitle: item.metadata.find(({ key }) => key == "dc.title.alternative") + ?.value, + publisherName: item.metadata.find(({ key }) => key == "publisher.name") + ?.value, + pageCount: item.metadata.find(({ key }) => key == "oapen.pages")?.value, + }; +}; + +export const RenderBook = ({ book }: { book: InternalBook }) => { + return ( + <> +

{book?.title}

+

+ by {book?.author} ({book?.pageCount} pages) +

+

{book?.abstract}

+ + ); +}; diff --git a/web/lib/oapen/OAPENTypes.ts b/web/lib/oapen/OAPENTypes.ts new file mode 100644 index 0000000..56106ca --- /dev/null +++ b/web/lib/oapen/OAPENTypes.ts @@ -0,0 +1,37 @@ +export type OAPENTypeID = string; +export type OAPENHandle = string; +export type OAPENType = string; +export type OAPENExpandable = string; +export type OAPENBitstreams = string; +export type OAPENApiRelativePath = string; +export type URL = string; + +export interface Expandable { + // OAPEN returns a list of "expandables" -- things you can further query for additionally (like metadata). Once the expandable is added to the object, it's removed from this list. + expand?: OAPENExpandable[]; +} + +export interface OAPENItemRaw { + uuid: OAPENTypeID; + name?: string; + handle?: OAPENHandle; + type?: OAPENType; + archived: boolean; + withdrawn: boolean; + link?: OAPENApiRelativePath; +} + +export interface RawMetadataItem { + key: string; + value: string; + qualifier?: string; + language?: string; + element?: string; +} + +type HasMetadata = { + metadata: RawMetadataItem[]; +}; + +export type OAPENItemQueried = OAPENItemRaw & Expandable; +export type OAPENItemWithMetadata = OAPENItemQueried & HasMetadata; diff --git a/web/lib/oapen/index.ts b/web/lib/oapen/index.ts new file mode 100644 index 0000000..6ef2e8c --- /dev/null +++ b/web/lib/oapen/index.ts @@ -0,0 +1 @@ +export * as OAPENItems from "./items"; diff --git a/web/lib/oapen/items.ts b/web/lib/oapen/items.ts new file mode 100644 index 0000000..bd3a95b --- /dev/null +++ b/web/lib/oapen/items.ts @@ -0,0 +1,69 @@ +import type { + OAPENItemQueried, + OAPENExpandable, + OAPENApiRelativePath, + OAPENType, + OAPENTypeID, + OAPENItemRaw, + RawMetadataItem, + OAPENItemWithMetadata, +} from "./OAPENTypes"; +import { get } from "./query"; + +const transformRawItemQueried = (item: any) => { + return { + uuid: item.uuid as OAPENTypeID, + name: (item?.name || "") as string, + handle: item?.handle as string, + type: item?.type as OAPENType, + // comes in sometimes as string or boolean, if null return false + archived: Boolean(item?.archived), + withdrawn: Boolean(item?.withdrawn), + link: item?.link as OAPENApiRelativePath, + expand: item?.expand as OAPENExpandable[], + } as OAPENItemQueried; +}; + +export const getItemsRaw = async (): Promise => { + const rawText = await get("items"); + + const transformed = rawText.map( + transformRawItemQueried + ) as OAPENItemQueried[]; + + return transformed; +}; + +const getItemSingleRaw = async (uuid: string): Promise => { + const rawText = await get(["items", uuid].map(encodeURIComponent).join("/")); + + const transformed = transformRawItemQueried(rawText); + + return transformed; +}; + +export const getItemSingleMetadata = async ( + uuid: string +): Promise => { + const rawText = await get( + ["items", uuid, "metadata"].map(encodeURIComponent).join("/") + ); + return rawText as RawMetadataItem[]; +}; + +const combineItemMetadata = ( + item: OAPENItemQueried, + metadata: RawMetadataItem[] +): OAPENItemWithMetadata => { + return { ...item, metadata } as OAPENItemWithMetadata; +}; + +export const getItemWithMetadata = async ( + uuid: string +): Promise => { + const [item, metadata] = await Promise.all([ + getItemSingleRaw(uuid), + getItemSingleMetadata(uuid), + ]); + return combineItemMetadata(item, metadata); +}; diff --git a/web/lib/oapen/query.ts b/web/lib/oapen/query.ts new file mode 100644 index 0000000..f79be64 --- /dev/null +++ b/web/lib/oapen/query.ts @@ -0,0 +1,8 @@ +const ENDPOINT = "https://library.oapen.org/rest"; +import axios from "axios"; + +export async function get(url = "") { + const post_url = [ENDPOINT, url].join("/"); + const text = (await axios.get(post_url)).data; + return text; +} diff --git a/web/next-env.d.ts b/web/next-env.d.ts index 7b7aa2c..4f11a03 100644 --- a/web/next-env.d.ts +++ b/web/next-env.d.ts @@ -1,2 +1,5 @@ /// -/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/web/package-lock.json b/web/package-lock.json index af757ee..a245952 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -8,11 +8,14 @@ "name": "oapen-suggestion-service", "version": "0.1.0", "dependencies": { + "@types/axios": "^0.14.0", + "axios": "^0.27.2", "next": "12.3.1", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { + "@types/node": "18.8.1", "@types/react": "18.0.21", "eslint": "8.24.0", "eslint-config-next": "12.3.1", @@ -368,12 +371,27 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/axios": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.0.tgz", + "integrity": "sha512-KqQnQbdYE54D7oa/UmYVMZKq7CO4l8DEENzOKc4aBRwxCXSlJXGz83flFx5L7AWrOQnmuN3kVsRdt+GZPPjiVQ==", + "deprecated": "This is a stub types definition for axios (https://github.com/mzabriskie/axios). axios provides its own type definitions, so you don't need @types/axios installed!", + "dependencies": { + "axios": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/node": { + "version": "18.8.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.1.tgz", + "integrity": "sha512-vuYaNuEIbOYLTLUAJh50ezEbvxrD43iby+lpUA2aa148Nh5kX/AVO/9m1Ahmbux2iU5uxJTNF9g2Y+31uml7RQ==", + "dev": true + }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -648,6 +666,11 @@ "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/axe-core": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz", @@ -657,6 +680,15 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -762,6 +794,17 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -844,6 +887,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1507,6 +1558,38 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2136,6 +2219,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3272,12 +3374,26 @@ "tslib": "^2.4.0" } }, + "@types/axios": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.0.tgz", + "integrity": "sha512-KqQnQbdYE54D7oa/UmYVMZKq7CO4l8DEENzOKc4aBRwxCXSlJXGz83flFx5L7AWrOQnmuN3kVsRdt+GZPPjiVQ==", + "requires": { + "axios": "*" + } + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/node": { + "version": "18.8.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.1.tgz", + "integrity": "sha512-vuYaNuEIbOYLTLUAJh50ezEbvxrD43iby+lpUA2aa148Nh5kX/AVO/9m1Ahmbux2iU5uxJTNF9g2Y+31uml7RQ==", + "dev": true + }, "@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -3459,12 +3575,26 @@ "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "axe-core": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz", "integrity": "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==", "dev": true }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -3542,6 +3672,14 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3602,6 +3740,11 @@ "object-keys": "^1.1.1" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4120,6 +4263,21 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4572,6 +4730,19 @@ "picomatch": "^2.3.1" } }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/web/package.json b/web/package.json index c446000..5ac5f27 100644 --- a/web/package.json +++ b/web/package.json @@ -9,11 +9,14 @@ "lint": "next lint" }, "dependencies": { + "@types/axios": "^0.14.0", + "axios": "^0.27.2", "next": "12.3.1", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { + "@types/node": "18.8.1", "@types/react": "18.0.21", "eslint": "8.24.0", "eslint-config-next": "12.3.1", diff --git a/web/pages/items/[uuid].tsx b/web/pages/items/[uuid].tsx new file mode 100644 index 0000000..011d385 --- /dev/null +++ b/web/pages/items/[uuid].tsx @@ -0,0 +1,43 @@ +import type { GetStaticProps, GetStaticPaths } from "next"; +import { OAPENItems } from "../../lib/oapen"; +import type { OAPENItemWithMetadata } from "../../lib/oapen/OAPENTypes"; +import { RenderItem } from "../../components/render/RenderItem"; + +interface SingleItemProps { + item: OAPENItemWithMetadata; +} + +export default function ItemSingle({ item }: SingleItemProps) { + const name = + item.name || item.metadata.find(({ key }) => key == "grantor.name")?.value; + const type = item.metadata.find(({ key }) => key == "dc.type")?.value; + console.log({ item }); + return ( + <> + + + ); +} + +// TODO update +export const getStaticPaths: GetStaticPaths = async () => { + return { + paths: [], + fallback: "blocking", // can also be true or 'blocking + }; +}; + +export const getStaticProps: GetStaticProps = async ( + context +) => { + const item = await OAPENItems.getItemWithMetadata(context?.params?.uuid + ""); + const data: SingleItemProps = { + item, + }; + + return { + props: { + ...data, + }, + }; +}; diff --git a/web/pages/items/index.tsx b/web/pages/items/index.tsx new file mode 100644 index 0000000..cf1e18c --- /dev/null +++ b/web/pages/items/index.tsx @@ -0,0 +1,38 @@ +import type { GetStaticProps } from "next"; +import { OAPENItems } from "../../lib/oapen"; +import type { OAPENItemQueried } from "../../lib/oapen/OAPENTypes"; +import Link from "next/link"; + +interface ManyProps { + many: OAPENItemQueried[]; +} + +export default function ItemMany({ many }: ManyProps) { + return ( + <> +

Listing

+ + + ); +} + +export const getStaticProps: GetStaticProps = async (context) => { + const many = await OAPENItems.getItemsRaw(); + const data: ManyProps = { + many, + }; + + return { + props: { + ...data, + }, + }; +}; diff --git a/web/styles/globals.css b/web/styles/globals.css index e5e2dcc..743b5ac 100644 --- a/web/styles/globals.css +++ b/web/styles/globals.css @@ -1,14 +1,18 @@ html, body { padding: 0; - margin: 0; + max-width: 900px; + margin-left: auto; + margin-right: auto; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + color: white; + background-color: black; } a { color: inherit; - text-decoration: none; + /* text-decoration: none; */ } * { diff --git a/web/tsconfig.json b/web/tsconfig.json index 4fa631c..e6bb8eb 100644 --- a/web/tsconfig.json +++ b/web/tsconfig.json @@ -1,7 +1,11 @@ { "compilerOptions": { "target": "es5", - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -12,8 +16,15 @@ "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve" + "jsx": "preserve", + "incremental": true }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx" + ], + "exclude": [ + "node_modules" + ] }