Skip to content

Commit

Permalink
feat: add reader page to show publizon reader and enhance work page l…
Browse files Browse the repository at this point in the history
…ayout with smartLink
  • Loading branch information
ThomasGross committed Nov 22, 2024
1 parent 94f0a0b commit 6c231ca
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 64 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions app/work/[id]/read/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"use client"

import React from "react"

import Reader from "@/components/shared/publizonReader/PublizonReader"

function Page({ searchParams: { id } }: { searchParams: { id: string } }) {
const handleBack = () => {
window.history.back()
}

return (
<div className="absolute inset-0 h-screen w-screen">
<div className="absolute h-full w-full bg-reader-grey"></div>
<Reader onBackCallback={() => handleBack()} type="demo" identifier={id} />
</div>
)
}

export default Page
21 changes: 19 additions & 2 deletions components/pages/workPageLayout/WorkPageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,34 @@
import { useQuery } from "@tanstack/react-query"
import React from "react"

import { Button } from "@/components/shared/button/Button"
import SmartLink from "@/components/shared/smartLink/SmartLink"
import { useGetMaterialQuery } from "@/lib/graphql/generated/fbi/graphql"
import { resolveUrl } from "@/lib/helpers/helper.routes"

function WorkPageLayout({ wid }: { wid: string }) {
const data = useQuery({
const { data } = useQuery({
queryKey: useGetMaterialQuery.getKey({ wid }),
queryFn: useGetMaterialQuery.fetcher({ wid }),
})

const manifestations = data?.work?.manifestations.all
const identifier = manifestations?.[0].identifiers?.[0].value || ""

const url = resolveUrl({
routeParams: { work: "work", ":wid": wid, read: "read" },
queryParams: { id: identifier },
})

return (
<div>
<pre>{JSON.stringify({ data }, null, 2)}</pre>
{identifier && (
<Button asChild>

Check failure on line 28 in components/pages/workPageLayout/WorkPageLayout.tsx

View workflow job for this annotation

GitHub Actions / build

Property 'ariaLabel' is missing in type '{ children: Element; asChild: true; }' but required in type 'ButtonProps'.
<SmartLink linkType="external" href={url}>
Read
</SmartLink>
</Button>
)}
</div>
)
}
Expand Down
67 changes: 28 additions & 39 deletions components/shared/publizonReader/PublizonReader.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,70 @@
import React, { CSSProperties, useEffect } from "react"
"use client"

import { appendAsset, readerAssets } from "./helper"
import React, { useEffect } from "react"

// type ReaderType = { identifier?: string; orderId?: string };
import { appendAsset, readerAssets, removeAsset } from "./helper"

// Define mutually exclusive types for identifier and orderId
type ReaderType =
| {
type: "demo"
identifier: string
orderId?: never
onBackCallback: () => void
}
| {
identifier?: never
type: "rent"
orderId: string
onBackCallback: () => void
}

const Reader = ({ identifier, orderId }: ReaderType) => {
const Reader = (props: ReaderType) => {
useEffect(() => {
readerAssets.forEach(appendAsset)
}, [identifier, orderId])

const readerStyles: CSSProperties = {
position: "absolute",
top: "0", // Padding from the top
left: "0", // Padding from the left
right: "0", // Padding from the right
bottom: "0", // Padding from the bottom
padding: "20px", // Padding for the reader
width: "100%",
maxWidth: "unset",
zIndex: 1000,
// border: "1px dotted black", // Should be removed in production
margin: "0",
}

const handleBack = () => {
window.history.back()
}
// Attach the onReaderBackCallback function to the window object to be able to enable callback methods calls through the close button
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-shadow
window.onReaderBackCallback = () => {
props.onBackCallback()
}

const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === "Escape") {
handleBack()
return () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
delete window.onReaderBackCallback
readerAssets.forEach(removeAsset)
}
}
}, [props])

if (orderId) {
if (props.type === "rent") {
return (
<div>
<p>orderId: {orderId}</p>
<p>orderId: {props.orderId}</p>
<div
style={readerStyles}
id="pubhub-reader"
// eslint-disable-next-line react/no-unknown-property
order-id={orderId}
order-id={props.orderId}
role="button"
tabIndex={0}
onClick={handleBack}
onKeyDown={handleKeyDown}
close-href="javascript:window.onReaderBackCallback()"
aria-label="Go back"
/>
</div>
)
}

if (identifier) {
if (props.type === "demo") {
return (
<div
style={readerStyles}
id="pubhub-reader"
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line react/no-unknown-property
identifier={identifier}
identifier={props.identifier}
close-href="javascript:window.onReaderBackCallback()"
role="button"
tabIndex={0}
onClick={handleBack}
onKeyDown={handleKeyDown}
aria-label="Go back"
/>
)
Expand Down
12 changes: 12 additions & 0 deletions components/shared/publizonReader/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,15 @@ export const appendAsset = ({ src, type }: AssetType) => {
document.head.appendChild(linkElement)
}
}

export const removeAsset = ({ src, type }: AssetType) => {
if (type === "script") {
const scriptElement = document.querySelector(`script[src="${src}"]`)
scriptElement?.remove()
}

if (type === "link") {
const linkElement = document.querySelector(`link[href="${src}"]`)
linkElement?.remove()
}
}
36 changes: 36 additions & 0 deletions components/shared/smartLink/SmartLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Link from "next/link"
import React from "react"

function SmartLink({
href,
target = "_self",
linkType = "internal",
children,
className,
}: {
href: string
target?: string
linkType?: "internal" | "external"
children: React.ReactNode
className?: string
}) {
// Internal link
if (linkType === "internal") {
return (
<Link className={className} href={href} target={target}>
{children}
</Link>
)
}

// External link
if (linkType === "external") {
return (
<a className={className} href={href} target={target}>
{children}
</a>
)
}
}

export default SmartLink
2 changes: 1 addition & 1 deletion components/shared/workCard/WorkCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const WorkCard = ({ work }: WorkCardProps) => {
return (
<Link
className="block space-y-3 lg:space-y-5"
href={resolveUrl({ type: "work", routeParams: { wid: work.workId } })}>
href={resolveUrl({ routeParams: { work: "work", wid: work.workId } })}>
<div>
<div
key={work.workId}
Expand Down
36 changes: 16 additions & 20 deletions lib/helpers/helper.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@ type RouteParams = { [key: string]: string | number }
type QueryParams = { [key: string]: string | number }

export function buildRoute({
route,
params,
query,
}: {
route: string
params?: RouteParams
query?: QueryParams
}): string {
let route = ""
if (params) {
route = Object.keys(params).reduce((acc, key) => {
const value = encodeURIComponent(params[key])
return acc.replace(`:${key}`, value)
return `${acc}/${value}`
}, route)
}

Expand All @@ -33,28 +32,25 @@ export function buildRoute({

type ResolveUrlOptions =
| {
type: "work"
routeParams?: { wid: number | string }
routeParams?: { work: "work"; wid: number | string }
queryParams?: QueryParams
}
| {
type: "search"
routeParams?: undefined
routeParams?: { work: "work"; ":wid": number | string; read: "read" }
queryParams?: QueryParams
}
| {
routeParams?: { search: "search" }
queryParams?: QueryParams
}

export const resolveUrl = ({ type, routeParams, queryParams }: ResolveUrlOptions) => {
switch (type as ResolveUrlOptions["type"]) {
case "work":
if (!routeParams?.wid) return ""
return buildRoute({
route: "/work/:wid",
params: { wid: routeParams.wid },
query: queryParams,
})
case "search":
return buildRoute({ route: "/search", query: queryParams })
default:
return ""
export const resolveUrl = ({ routeParams, queryParams }: ResolveUrlOptions) => {
if (!routeParams) {
throw new Error("routeParams is required")

Check failure on line 49 in lib/helpers/helper.routes.ts

View workflow job for this annotation

GitHub Actions / Unit test

__tests__/url.test.ts > That resolveUrl can return a search url

Error: routeParams is required ❯ Module.resolveUrl lib/helpers/helper.routes.ts:49:11 ❯ __tests__/url.test.ts:20:19
}

return buildRoute({
params: routeParams,
query: queryParams,
})
}
3 changes: 3 additions & 0 deletions lib/shadcn/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { cn as classNames } from "../helpers/helper.cn"

export const cn = classNames
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@
"dependencies": {
"@next/env": "^14.2.15",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.1.0",
"@redux-devtools/extension": "^3.3.0",
"@tanstack/react-query": "^5.59.0",
"@types/lodash": "^4.17.12",
"@xstate/react": "^4.1.3",
"@uidotdev/usehooks": "^2.4.1",
"@xstate/react": "^4.1.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
Expand Down
1 change: 1 addition & 0 deletions styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
--blue-overlay: hsla(238, 54%, 89%, 0.09);

--border: hsla(48, 4.4%, 77.8%, 1);
--reader-grey: hsla(0, 0%, 94.1%, 1);

--shadow-1: hsla(0, 0%, 0%, 0.5);
--shadow-2: hsla(0, 0%, 0%, 0.15);
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ export const extendedTheme = {
},
foreground: "var(--foreground)",
border: "var(--border)",
"reader-grey": "var(--reader-grey)",
content: {
pink: "var(--content-pink)",
blue: "var(--content-blue)",
Expand Down

0 comments on commit 6c231ca

Please sign in to comment.