Skip to content

Commit

Permalink
Add the DataProvider page
Browse files Browse the repository at this point in the history
Add some layout

API:
- Connect search to API
- Trying some APIv3

Pagination:
- Add pagination
- Improve pagination component
- Improve Pagination interface

Temporarily hide claim card

Improve MapCard interface

Upgrade @oacore/design to 'latest'
  • Loading branch information
Joozty authored and viktor-yakubiv committed Jan 19, 2021
1 parent 784fa22 commit d401f3a
Show file tree
Hide file tree
Showing 32 changed files with 1,042 additions and 378 deletions.
8 changes: 7 additions & 1 deletion design.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const path = require('path')

const icons = ['office-building']
const icons = [
'office-building',
'chevron-left',
'chevron-right',
'chevron-double-left',
'chevron-double-right',
]

const iconsRoot = path.join(
path.dirname(require.resolve('@mdi/svg/package.json')),
Expand Down
83 changes: 57 additions & 26 deletions hooks/use-sync-url-params-with-store/index.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,64 @@
import { useEffect, useCallback } from 'react'
import { useEffect } from 'react'
import { useRouter } from 'next/router'

import useDebouncedEffect from '../use-debounced-effect'
import useDebouncedEffect from 'hooks/use-debounced-effect'

export const useSyncUrlParamsWithStore = (params) => {
export const useSyncUrlParamsWithStore = (paramsInstance) => {
const router = useRouter()
const setUrlParams = () => {
const newParams = Array.from(params.entries()).filter(
const { schema, ...params } = paramsInstance

const newParams = Object.entries(params).filter(
([, value]) => value != null
)
const query = Object.fromEntries(newParams)
router.push(
{ pathname: router.pathname, query },
{
// asPath contains url params so we need to get rid of them
// and replace them with the new ones.
pathname: new URL(router.route, window.location.origin).pathname,
query,
},
{ shallow: true }

const { pathname: pathnameUrl } = new URL(
router.asPath,
window.location.origin
)
const { pathname: pathnameAs } = new URL(
router.pathname,
window.location.origin
)

const urlParams = new URLSearchParams(newParams)

urlParams.sort()

if (
`${window.location.pathname}${window.location.search}` !==
`${pathnameUrl}?${urlParams.toString()}`
) {
const updateParams =
window.location.search === '' ? router.replace : router.push

updateParams(
{
pathname: `${pathnameAs}`,
query: { ...router.query, ...urlParams },
},
`${pathnameUrl}?${urlParams.toString()}`,

{ shallow: true }
)
}
}

const handleRouteChange = useCallback(
(nextUrl) => {
const { searchParams } = new URL(nextUrl, window.location.origin)
Array.from(searchParams.entries()).forEach(([key, value]) => {
const handleRouteChange = (nextUrl) => {
const { schema, ...params } = paramsInstance
const { searchParams } = new URL(nextUrl, window.location.origin)

const newParams = Array.from(searchParams.entries()).filter(
([key, value]) =>
// We want to compare like it because URLSearch params doesn't
// automatically convert param (e.g. size) to number.
// eslint-disable-next-line eqeqeq
if (params.has(key) && params[key] != value) params[key] = value
})
},
[params]
)
params[key] != value
)

if (newParams.length)
paramsInstance.changeParams(Object.fromEntries(newParams))
}

useEffect(() => {
router.events.on('routeChangeComplete', handleRouteChange)
Expand All @@ -43,9 +68,15 @@ export const useSyncUrlParamsWithStore = (params) => {
}, [])

// whenever any param changes in store reflect it to the URL
useDebouncedEffect(() => {
setUrlParams()
}, Array.from(params.values()))
useDebouncedEffect(
() => {
setUrlParams()
},
Object.keys(paramsInstance)
.sort()
.filter((key) => key !== 'schema')
.map((key) => paramsInstance[key])
)
}

export default useSyncUrlParamsWithStore
26 changes: 0 additions & 26 deletions main/hooks.js

This file was deleted.

63 changes: 63 additions & 0 deletions modules/authors-box/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { useState } from 'react'
import { Button, Link } from '@oacore/design'
import { classNames } from '@oacore/design/lib/utils'

import styles from './styles.module.css'

const AuthorLink = ({ name }) => (
<Link
href={`https://core.ac.uk/search?q=author:(${name})`}
className={styles.authorLink}
>
{name.replace(',', ' ')}
</Link>
)

const Authors = ({ authors }) => {
const [isExpanded, setIsExpanded] = useState(false)
if (authors.length <= 3) {
return authors.map((author, index) => (
<>
<AuthorLink name={author.name} />
{index < authors.length - 1 ? ', ' : ''}
</>
))
}

return (
<>
<AuthorLink name={authors[0].name} />,{' '}
<AuthorLink name={authors[1].name} />,{' '}
<span
className={classNames.use(
styles.moreAuthorsBox,
isExpanded && styles.moreAuthorsExpanded
)}
>
<Button
className={styles.showMore}
aria-controls="more-authors"
onClick={() => setIsExpanded(true)}
aria-hidden={isExpanded}
title="Show more authors"
>
+ {authors.length - 3} MORE
</Button>
<span
id="more-authors"
aria-hidden={!isExpanded}
className={styles.moreAuthors}
>
{authors.slice(2, -1).map((author) => (
<>
<AuthorLink name={author.name} />,{' '}
</>
))}
</span>
</span>
<AuthorLink name={authors[authors.length - 1].name} />
</>
)
}

export default Authors
36 changes: 36 additions & 0 deletions modules/authors-box/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.author-link {
color: var(--gray-800);
text-decoration: underline;
}

.show-more {
position: relative;
padding: 0 0.25rem;
margin: 0 0.25rem;
color: var(--gray-700);
text-transform: uppercase;
white-space: nowrap;
background: var(--gray-100);
}

.show-more::after {
position: absolute;
right: -0.05rem;
content: ',';
}

.more-authors {
display: none;
}

.more-authors-box {
display: contents;
}

.more-authors-expanded .show-more {
display: none;
}

.more-authors-expanded .more-authors {
display: inline-block;
}
2 changes: 0 additions & 2 deletions modules/repositories-map/index.jsx → modules/map/index.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import React from 'react'
import dynamic from 'next/dynamic'
import { ProgressSpinner } from '@oacore/design'
import { classNames } from '@oacore/design/lib/utils'

import styles from './styles.module.css'

const Map = dynamic(() => import('./map'), {
ssr: false,
loading: () => <ProgressSpinner className={styles.loader} />,
})

const RepositoriesMap = React.memo(
Expand Down
43 changes: 18 additions & 25 deletions modules/repositories-map/map.jsx → modules/map/map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const markerIcon = L.icon({
popupAnchor: [0, -32],
})

const CustomMap = ({ dataProviders }) => {
const CustomMap = ({ locations }) => {
const mapContainerRef = useRef(null)
const map = useRef(null)

Expand All @@ -34,7 +34,10 @@ const CustomMap = ({ dataProviders }) => {
)

map.current = L.map(mapContainerRef.current, {
center: centerPosition,
center:
locations.length > 1
? centerPosition
: new L.LatLng(locations[0].latitude, locations[0].longitude),
zoom: 2,
maxBounds: [
[-90, -180],
Expand All @@ -52,40 +55,30 @@ const CustomMap = ({ dataProviders }) => {
icon: markerIcon,
})

dataProviders
.filter(
({ name, dataProviderLocation }) =>
dataProviderLocation != null &&
dataProviderLocation.latitude != null &&
dataProviderLocation.longitude != null &&
name
)
.forEach(({ id, name, dataProviderLocation }) => {
const marker = L.marker(
new L.LatLng(
dataProviderLocation.latitude,
dataProviderLocation.longitude
),
{
title: name,
icon: markerIcon,
}
)
locations.forEach(({ name, href, latitude, longitude }) => {
const marker = L.marker(new L.LatLng(latitude, longitude), {
title: name,
icon: markerIcon,
})

if (href) {
marker.bindPopup(
`<a
href="https://core.ac.uk/search?q=repositories.id:(${id})"
href={href}
target="_blank"
rel="noopener noreferrer"
>
${name}
</a>`
)
markers.addLayer(marker)
})
} else marker.bindPopup(name)

markers.addLayer(marker)
})

map.current.addLayer(markers)
return () => map.current.removeLayer(markers)
}, [dataProviders])
}, [locations])

return <div ref={mapContainerRef} className={styles.map} />
}
Expand Down
File renamed without changes.
8 changes: 4 additions & 4 deletions modules/search-layout/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Content from './content'
import Sidebar from './sidebar'
import Result from './result'
import Results from './results'
import Main from './main'
import Search from './search'
import ResultStats from './result-stats'

Search.Content = Content
Search.Sidebar = Sidebar
Search.Result = Result
Search.Results = Results
Search.Main = Main
Search.ResultStats = ResultStats

export default Search
12 changes: 12 additions & 0 deletions modules/search-layout/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react'
import { classNames } from '@oacore/design/lib/utils'

import styles from './styles.module.css'

const Main = ({ children, className, tag: Tag = 'div', ...restProps }) => (
<Tag className={classNames.use(styles.main, className)} {...restProps}>
{children}
</Tag>
)

export default Main
15 changes: 0 additions & 15 deletions modules/search-layout/results.jsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { classNames } from '@oacore/design/lib/utils'

import styles from './styles.module.css'

const Content = ({ children, className, ...restProps }) => (
<div className={classNames.use(styles.content, className)} {...restProps}>
const Sidebar = ({ children, className, ...restProps }) => (
<div className={classNames.use(styles.sidebar, className)} {...restProps}>
{children}
</div>
)

export default Content
export default Sidebar
Loading

0 comments on commit d401f3a

Please sign in to comment.