Skip to content

Commit

Permalink
Updated book detail page for course and series links, search adjustme…
Browse files Browse the repository at this point in the history
…nts and fixes
  • Loading branch information
pookmish committed Nov 5, 2024
1 parent 3d0144b commit 465eb1a
Show file tree
Hide file tree
Showing 28 changed files with 677 additions and 1,726 deletions.
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@mui/base": "5.0.0-beta.61",
"@next/third-parties": "15.0.2",
"@tailwindcss/container-queries": "^0.1.1",
"@types/node": "^22.8.4",
"@types/node": "^22.9.0",
"@types/react": "^19.0.0-rc.1",
"@types/react-dom": "19.0.0-rc.1",
"algoliasearch": "5.12.0",
Expand All @@ -28,7 +28,7 @@
"decanter": "^7.3.0",
"drupal-jsonapi-params": "^2.3.2",
"graphql": "^16.9.0",
"graphql-request": "^7.1.0",
"graphql-request": "^7.1.2",
"graphql-tag": "^2.12.6",
"html-entities": "^2.5.2",
"html-react-parser": "^5.1.18",
Expand Down Expand Up @@ -56,29 +56,29 @@
"@graphql-codegen/typescript-graphql-request": "^6.2.0",
"@graphql-codegen/typescript-operations": "^4.3.1",
"@next/bundle-analyzer": "15.0.2",
"@storybook/addon-essentials": "^8.3.6",
"@storybook/addon-interactions": "^8.3.6",
"@storybook/addon-links": "^8.3.6",
"@storybook/addon-essentials": "^8.4.1",
"@storybook/addon-interactions": "^8.4.1",
"@storybook/addon-links": "^8.4.1",
"@storybook/addon-styling": "^1.3.7",
"@storybook/blocks": "^8.3.6",
"@storybook/nextjs": "^8.3.6",
"@storybook/react": "^8.3.6",
"@storybook/blocks": "^8.4.1",
"@storybook/nextjs": "^8.4.1",
"@storybook/react": "^8.4.1",
"@storybook/testing-library": "^0.2.2",
"@types/react-slick": "^0.23.13",
"concurrently": "^9.0.1",
"concurrently": "^9.1.0",
"encoding": "^0.1.13",
"eslint": "^9.13.0",
"eslint": "^9.14.0",
"eslint-config-next": "15.0.2",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-storybook": "^0.10.1",
"eslint-plugin-storybook": "^0.11.0",
"prettier": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.8",
"react-docgen": "^7.1.0",
"storybook": "^8.3.6",
"storybook": "^8.4.1",
"storybook-addon-module-mock": "^1.3.4",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"typescript-eslint": "^8.12.2"
"typescript-eslint": "^8.13.0"
},
"packageManager": "yarn@4.5.1",
"resolutions": {
Expand Down
21 changes: 13 additions & 8 deletions src/components/algolia-search/algolia-search-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const AlgoliaSearchForm = ({appId, searchIndex, searchApiKey, initialUiState = {
const Form = ({searchIndex}: {searchIndex: string}) => {
const router = useRouter()
const searchParams = useSearchParams()
const {value: onlyBooks, setValue: setOnlyBooks} = useBoolean(true)

const inputRef = useRef<HTMLInputElement>(null)
const {query, refine} = useSearchBox({})
Expand All @@ -70,7 +71,7 @@ const Form = ({searchIndex}: {searchIndex: string}) => {
attribute: "book_subject",
limit: 100,
})
const {items: bookTypeRefinementItems, refine: refineBookType} = useRefinementList({attribute: "book_type"})
const {refine: refineBookType} = useRefinementList({attribute: "book_type"})
const {
start: pubYearRange,
range: pubYearRangeBounds,
Expand Down Expand Up @@ -123,7 +124,9 @@ const Form = ({searchIndex}: {searchIndex: string}) => {
?.refinements.map(item => item.value)
if (chosenSubjects) params.set("subjects", chosenSubjects.join(","))

router.replace(`?${params.toString()}${window.location.hash || ""}`, {scroll: false})
const newSearch = params.toString()
if (window.location.search.replace(/^\?/, "") != newSearch)
router.replace(`?${newSearch}${window.location.hash || ""}`, {scroll: false})
}, [router, searchParams, currentRefinements, query, pubYearRange])

const {value: expanded, toggle: toggleExpanded} = useBoolean(false)
Expand Down Expand Up @@ -223,8 +226,11 @@ const Form = ({searchIndex}: {searchIndex: string}) => {
<input
className="peer sr-only"
type="checkbox"
checked={!!bookTypeRefinementItems.find(item => item.isRefined)}
onChange={() => refineBookType("book")}
checked={onlyBooks}
onChange={() => {
setOnlyBooks(!onlyBooks)
refineBookType("book")
}}
/>
<div className="h-6 w-16 rounded-full bg-press-sand-light shadow-inner peer-checked:bg-press-bay-light" />
<div className="absolute -left-1 -top-2 h-10 w-10 rounded-full border border-fog-dark bg-white shadow outline-8 outline-press-bay transition peer-checked:translate-x-full peer-checked:bg-press-grass peer-focus-visible:outline group-hocus:outline" />
Expand Down Expand Up @@ -349,10 +355,9 @@ const HitList = ({searchIndex}: {searchIndex: string}) => {
} = useSortBy({
items: [
{label: "Relevance", value: searchIndex},
{label: "Last Name, A-Z", value: `${searchIndex}_authors_asc`},
{label: "Last Name, Z-A", value: `${searchIndex}_authors_desc`},
{label: "Published Year, Asc", value: `${searchIndex}_published_asc`},
{label: "Published Year, Desc", value: `${searchIndex}_published_desc`},
{label: "Author, A-Z", value: `${searchIndex}_authors_asc`},
{label: "Author, Z-A", value: `${searchIndex}_authors_desc`},
{label: "Publication Year, Desc", value: `${searchIndex}_published_desc`},
],
})

Expand Down
30 changes: 16 additions & 14 deletions src/components/elements/paged-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,29 @@ const PagedList = ({
}: Props) => {
const ref = useRef(false)
const [items, setItems] = useState<JSX.Element[]>(Array.isArray(children) ? children : [children])
const [runAction, isRunning] = useServerAction<[number], JSX.Element>(loadPage)

const router = useRouter()
const searchParams = useSearchParams()

// Use the GET param for page, but make sure that it is between 1 and the last page. If it's a string or a number
// outside the range, fix the value, so it works as expected.
const {count: currentPage, setCount: setPage} = useCounter(1)
const {count: currentPage, setCount: setPage} = useCounter(parseInt(pageKey ? searchParams.get(pageKey) || "1" : "1"))
const {value: focusOnElement, setTrue: enableFocusElement, setFalse: disableFocusElement} = useBoolean(false)

const afterAction = useCallback(() => {
if (!pageKey) return

// Use search params to retain any other parameters.
const params = new URLSearchParams(searchParams.toString())
if (params.get(pageKey) === currentPage.toString() || (params.get(pageKey) === null && currentPage === 1)) return

params.delete(pageKey)
if (currentPage > 1) params.set(pageKey, `${currentPage}`)

router.replace(`?${params.toString()}${window.location.hash || ""}`, {scroll: false})
}, [currentPage, pageKey, router, searchParams])

const [runAction, isRunning] = useServerAction<[number], JSX.Element>(loadPage, afterAction)

const focusItemRef = useRef<HTMLLIElement>(null)

const goToPage = useCallback(
Expand Down Expand Up @@ -88,17 +101,6 @@ const PagedList = ({
if (focusOnElement) setFocusOnItem()
}, [focusOnElement, setFocusOnItem])

useEffect(() => {
if (!pageKey || !loadPage) return

// Use search params to retain any other parameters.
const params = new URLSearchParams(searchParams.toString())
params.delete(pageKey)
if (currentPage > 1) params.set(pageKey, `${currentPage}`)

router.replace(`?${params.toString()}${window.location.hash || ""}`, {scroll: false})
}, [loadPage, router, currentPage, pageKey, searchParams])

useEffect(() => {
const initialPage = Math.min(totalPages, Math.max(1, parseInt((pageKey && searchParams.get(pageKey)) || "1")))
if (initialPage > 1 && !ref.current) goToPage(initialPage, true)
Expand Down
23 changes: 1 addition & 22 deletions src/components/nodes/pages/sup-book/book-page/book-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ const BookPage = async ({node, ...props}: Props) => {
return linkParams.toString()
}

const bookSubject = node.supBookSubjects && createLinkParams(node.supBookSubjects[0])
return (
<article {...props} className="centered">
<SupBookMetadata node={node} />
Expand All @@ -40,16 +39,6 @@ const BookPage = async ({node, ...props}: Props) => {
<div className="mb-16 hidden w-8/12 flex-col sm:flex md:hidden">
<H1 className="type-2 mb-0 xl:text-[3.3rem]">{node.title}</H1>

{node.supBookSubjects && (
<Link
prefetch={false}
href={`/search?${bookSubject}`}
className="rs-mb-2 order-first text-18 font-normal text-stone-dark decoration-fog-dark underline-offset-[5px] hocus:text-archway-dark hocus:decoration-archway-dark hocus:decoration-2"
>
{node.supBookSubjects[0].parent?.name || node.supBookSubjects[0].name}
</Link>
)}

{node.supBookSubtitle && <div className="type-1 mt-5 font-medium xl:text-26">{node.supBookSubtitle}</div>}

{node.supBookAuthorsFull && (
Expand Down Expand Up @@ -79,16 +68,6 @@ const BookPage = async ({node, ...props}: Props) => {
<div className="mt-7 flex flex-col sm:mt-0 sm:hidden md:flex">
<H1 className="type-2 mb-0 xl:text-[3.3rem]">{node.title}</H1>

{node.supBookSubjects && (
<Link
prefetch={false}
href={`/search?${bookSubject}`}
className="rs-mb-2 order-first text-18 font-normal text-stone-dark decoration-fog-dark underline-offset-[5px] hocus:text-archway-dark hocus:decoration-archway-dark hocus:decoration-2"
>
{node.supBookSubjects[0].parent?.name || node.supBookSubjects[0].name}
</Link>
)}

{node.supBookSubtitle && (
<div className="type-1 mt-5 font-medium xl:text-26">{node.supBookSubtitle}</div>
)}
Expand Down Expand Up @@ -149,7 +128,7 @@ const BookPage = async ({node, ...props}: Props) => {
<br />
<Link
prefetch={false}
href={`/search?q=${node.supBookSeries.name}`}
href={node.supBookSeries.supSeriesPage?.url || `/search?q=${node.supBookSeries.name}`}
className="text-18 font-normal text-stone-dark"
>
{node.supBookSeries.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ const DigitalProjectPage = async ({node, ...props}: Props) => {
return linkParams.toString()
}

const bookSubjectLinkParams = node.supBookSubjects && createLinkParams(node.supBookSubjects[0])

return (
<article {...props} className="centered">
<SupBookMetadata node={node} />
Expand All @@ -41,16 +39,6 @@ const DigitalProjectPage = async ({node, ...props}: Props) => {
<div className="mb-16 hidden w-8/12 flex-col sm:flex md:hidden">
<H1 className="type-2 mb-0 xl:text-[3.3rem]">{node.title}</H1>

{node.supBookSubjects && (
<Link
prefetch={false}
href={`/search?${bookSubjectLinkParams}`}
className="rs-mb-2 order-first text-18 font-normal text-stone-dark decoration-fog-dark underline-offset-[5px] hocus:text-archway-dark hocus:decoration-archway-dark hocus:decoration-2"
>
{node.supBookSubjects[0].parent?.name || node.supBookSubjects[0].name}
</Link>
)}

{node.supBookSubtitle && <div className="type-0 mt-5 font-medium xl:text-21">{node.supBookSubtitle}</div>}

{node.supBookAuthorsFull && (
Expand Down Expand Up @@ -80,16 +68,6 @@ const DigitalProjectPage = async ({node, ...props}: Props) => {
<div className="mt-7 flex flex-col sm:mt-0 sm:hidden md:flex">
<H1 className="type-2 mb-0 xl:text-[3.3rem]">{node.title}</H1>

{node.supBookSubjects && (
<Link
prefetch={false}
href={`/search?${bookSubjectLinkParams}`}
className="rs-mb-2 order-first text-18 font-normal text-stone-dark decoration-fog-dark underline-offset-[5px] hocus:text-archway-dark hocus:decoration-archway-dark hocus:decoration-2"
>
{node.supBookSubjects[0].parent?.name || node.supBookSubjects[0].name}
</Link>
)}

{node.supBookSubtitle && (
<div className="type-0 mt-5 font-medium xl:text-21">{node.supBookSubtitle}</div>
)}
Expand Down Expand Up @@ -145,7 +123,9 @@ const DigitalProjectPage = async ({node, ...props}: Props) => {
<br />
<Link
prefetch={false}
href={`/search?q=${node.supBookSeries.name}&only-books=false`}
href={
node.supBookSeries.supSeriesPage?.url || `/search?q=${node.supBookSeries.name}&only-books=false`
}
className="text-18 font-normal text-stone-dark"
>
{node.supBookSeries.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const ListParagraph = async ({paragraph, ...props}: Props) => {
paragraph.suListView?.pageSize
)
: {items: [], totalItems: 0}
const addLoadMore = (paragraph.suListView?.pageSize || 3) > 99
const addLoadMore = (paragraph.suListView?.pageSize || 3) > 30

if (behaviors.list_paragraph?.hide_empty && viewItems.length === 0) return null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ const FilteringAuthorList = ({authors, ...props}: Props) => {
params.delete("author")
if (alphaChosen !== "") params.set("author", alphaChosen)

router.replace(`?${params.toString()}${window.location.hash || ""}`, {scroll: false})
const newSearch = params.toString()
if (window.location.search.replace(/^\?/, "") !== newSearch)
router.replace(`?${newSearch}${window.location.hash || ""}`, {scroll: false})
}, [router, searchParams, alphaChosen])

const loadPage = useCallback(
Expand Down
20 changes: 3 additions & 17 deletions src/components/views/card-view-grid.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
import NodeCard from "@components/nodes/cards/node-card"
import LoadMoreList from "@components/elements/load-more-list"
import {NodeUnion} from "@lib/gql/__generated__/drupal.d"
import {ViewDisplayProps} from "@components/views/view"

type Props = {
/**
* List of node entities.
*/
items: NodeUnion[]
/**
* If those nodes titles should display as <h2> or <h3>
*/
headingLevel?: "h2" | "h3"
/**
* Total number of items on all pages.
*/
totalItems: number
}

const CardViewGrid = ({items, headingLevel, totalItems}: Props) => {
const CardViewGrid = ({items, totalItems, headingLevel, loadPage}: ViewDisplayProps) => {
return (
<LoadMoreList
ulProps={{className: "list-unstyled grid @4xl:grid-cols-2 @7xl:grid-cols-3 gap-20 mb-20"}}
liProps={{className: ""}}
totalItems={totalItems}
loadPage={loadPage}
>
{items.map(item => (
<NodeCard node={item} key={item.id} headingLevel={headingLevel} />
Expand Down
21 changes: 3 additions & 18 deletions src/components/views/shared-tags/shared-tags-card-view.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,7 @@
import CardViewGrid from "@components/views/card-view-grid"
import {NodeUnion} from "@lib/gql/__generated__/drupal.d"
import {ViewDisplayProps} from "@components/views/view"

interface Props {
/**
* List of node entities.
*/
items: NodeUnion[]
/**
* If those nodes titles should display as <h2> or <h3>
*/
headingLevel?: "h2" | "h3"
/**
* Total number of items on all pages.
*/
totalItems: number
}

const SharedTagsCardView = async ({items = [], headingLevel, totalItems}: Props) => {
return <CardViewGrid items={items} headingLevel={headingLevel} totalItems={totalItems} />
const SharedTagsCardView = async (props: ViewDisplayProps) => {
return <CardViewGrid {...props} />
}
export default SharedTagsCardView
20 changes: 3 additions & 17 deletions src/components/views/stanford-courses/course-card-view.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,8 @@
import CardViewGrid from "@components/views/card-view-grid"
import {NodeStanfordCourse} from "@lib/gql/__generated__/drupal.d"
import {ViewDisplayProps} from "@components/views/view"

interface Props {
/**
* List of nodes to display.
*/
items: NodeStanfordCourse[]
/**
* If those nodes titles should display as <h2> or <h3>
*/
headingLevel?: "h2" | "h3"
/**
* Total number of items on all pages.
*/
totalItems: number
}

const CourseCardView = async ({items = [], headingLevel, totalItems}: Props) => {
return <CardViewGrid items={items} headingLevel={headingLevel} totalItems={totalItems} />
const CourseCardView = async (props: ViewDisplayProps<NodeStanfordCourse>) => {
return <CardViewGrid {...props} />
}
export default CourseCardView
Loading

0 comments on commit 465eb1a

Please sign in to comment.