Skip to content

Commit

Permalink
home, search and detail page ready
Browse files Browse the repository at this point in the history
  • Loading branch information
karolina-siemieniuk-morawska committed Nov 9, 2023
1 parent 90c297b commit 27e28a4
Show file tree
Hide file tree
Showing 39 changed files with 5,009 additions and 0 deletions.
6 changes: 6 additions & 0 deletions ui/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": ["next","next/core-web-vitals"],
"rules": {
"react/display-name": "off"
}
}
37 changes: 37 additions & 0 deletions ui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

token.ts
21 changes: 21 additions & 0 deletions ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
8 changes: 8 additions & 0 deletions ui/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
largePageDataBytes: 256 * 100000,
},
}

module.exports = nextConfig
35 changes: 35 additions & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "ui",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@ant-design/cssinjs": "^1.17.2",
"antd": "^5.10.1",
"moment": "^2.29.4",
"next": "13.5.5",
"nextjs-progressbar": "^0.0.16",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-html-parser": "^2.0.2"
},
"devDependencies": {
"@types/node": "^20",
"@types/react-html-parser": "^2.0.4",
"autoprefixer": "^10",
"eslint": "^8",
"eslint-config-next": "13.5.5",
"postcss": "^8",
"tailwindcss": "^3",
"typescript": "^5"
},
"resolutions": {
"**/@types/react": "^18.2.29",
"**/@types/react-dom": "^18.2.14"
}
}
6 changes: 6 additions & 0 deletions ui/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Binary file added ui/public/images/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/public/images/background.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/public/images/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/public/images/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/public/images/favicon.ico
Binary file not shown.
Binary file added ui/public/images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/public/images/orcid-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 71 additions & 0 deletions ui/src/components/detail/DetailPageInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from "react";
import moment from "moment";
import { Divider } from "antd";

import { JournalInfo, ArticleIdentifier, License, Result } from "@/types/types";
import { resolveIdentifierLink } from "@/utils/utils";
import FulltextFiles from "../shared/FulltextFiles";
import PublicationInfo from "../shared/PublicationInfo";

const DetailPageInfo = ({ article }: { article: Result }) => {
const { artid, publisher } =
(article?.publication_info?.[0] as JournalInfo) || {};

const renderIdentifierLinks = (identifiers: ArticleIdentifier[]) => {
return identifiers?.map((identifier) => (
<div key={identifier?.identifier_type}>
<dt>{identifier?.identifier_type}:</dt>
{identifier?.identifier_type === "arXiv" && (
<dd>
{article?.article_arxiv_category?.map(
(category) => category?.primary && category?.category
)}
</dd>
)}
<dd>
<a href={resolveIdentifierLink(identifier)}>
{identifier?.identifier_value}
</a>
</dd>
</div>
));
};

const renderLicenses = (licenses: License[]) => {
return licenses?.map((licence) => (
<a href={licence?.url} key={licence?.name}>
{licence?.name}
</a>
));
};

return (
<dl className="m-0 pb-5">
<dt>Published on:</dt>
<dd>{moment(article?.publication_date).format("DD MMMM YYYY")}</dd>
<dt>Created on:</dt>
<dd>{moment(article?._created_at).format("DD MMMM YYYY")}</dd>
<dt>Publisher:</dt>
<dd>{publisher}</dd>
<dt>Published in:</dt>
<dd>
<PublicationInfo data={article?.publication_info?.[0]} page="detail" />
</dd>
{artid && <dd>Article ID: {artid}</dd>}
{renderIdentifierLinks(article?.article_identifiers)}
<dt>Copyrights:</dt>
<dd>{article?.copyright?.[0]?.statement}</dd>
<dt>Licence:</dt>
<dd>{renderLicenses(article?.related_licenses)}</dd>

<Divider />

<dt>Fulltext files:</dt>
<dd className="flex mt-2">
<FulltextFiles files={article?.related_files} />
</dd>
</dl>
);
};

export default DetailPageInfo;
32 changes: 32 additions & 0 deletions ui/src/components/home/TabContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from "react";
import Link from "next/link";

import { Country, Journal } from "@/types/types";
import { getSearchUrl } from "@/utils/utils";

const TabContent = ({
data,
type,
}: {
data: Journal[] | Country[];
type: "country" | "journal";
}) => {
return (
<div className="tab-content">
<ul>
{data?.map((item: Journal | Country) => {
return (
<li key={item?.key} className="journal flex justify-between">
<Link href={getSearchUrl(1, 20, { [type]: item?.key }, true)}>
{item?.key}
</Link>
<span className="badge">{item?.doc_count}</span>
</li>
);
})}
</ul>
</div>
);
};

export default TabContent;
56 changes: 56 additions & 0 deletions ui/src/components/search/ResultItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from "react";
import { FilePdfOutlined, FileTextOutlined } from "@ant-design/icons";
import ReactHtmlParser from "react-html-parser";

import { ArticleIdentifier, Result } from "@/types/types";
import PublicationInfo from "../shared/PublicationInfo";
import Authors from "../shared/Authors";
import { resolveIdentifierLink } from "@/utils/utils";
import FulltextFiles from "../shared/FulltextFiles";

const ResultItem = ({ article }: { article: Result }) => {
const renderIdentifierLinks = (identifiers: ArticleIdentifier[]) => {
return identifiers.map((identifier) => (
<span key={identifier?.identifier_type}>
{identifier?.identifier_type}:{" "}
<a href={resolveIdentifierLink(identifier)}>
{identifier?.identifier_value}
</a>{" "}
</span>
));
};

return (
<li className="search-results-record border-0 border-b border-solid border-slate-200 py-6">
<a href={`/records/${article?.id}`} className="mb-2 block text-lg">
{ReactHtmlParser(article?.title)}
</a>
<div className="mb-2">
<Authors authors={article?.authors} page="search" />
<small className="search-results-record-date">
{" "}
- {article?.publication_date}
</small>
</div>
<p className="search-results-record-abstract mb-4">
{ReactHtmlParser(article?.abstract)}
</p>
<div className="lg:flex justify-between items-end">
<div>
<PublicationInfo
data={article?.publication_info?.[0]}
page="search"
/>
<p className="text-sm">
{renderIdentifierLinks(article?.article_identifiers)}
</p>
</div>
<div className="flex justify-end mt-2">
<FulltextFiles files={article?.related_files} size="small" />
</div>
</div>
</li>
);
};

export default ResultItem;
36 changes: 36 additions & 0 deletions ui/src/components/search/SearchPagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { Pagination } from "antd";
import { useRouter, useSearchParams } from "next/navigation";

import { getSearchUrl, Params } from "@/utils/utils";

const SearchPagination = ({
count,
params,
}: {
count: number;
params: Params;
}) => {
const router = useRouter();

const page = Number(useSearchParams().get("page")) ?? 1;
const size = Number(useSearchParams().get("page_size")) ?? 20;

const onPageChange = (page: number) => {
router.push(getSearchUrl(page, size, params));
};

return (
<Pagination
size="small"
pageSize={size}
total={count}
onChange={(page) => onPageChange(page)}
showSizeChanger={false}
current={page}
hideOnSinglePage
/>
);
};

export default SearchPagination;
39 changes: 39 additions & 0 deletions ui/src/components/search/SearchResults.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from "react";

import { Result } from "@/types/types";
import ResultItem from "./ResultItem";
import SearchPagination from "./SearchPagination";

function SearchResults({
results,
count,
params,
}: {
results: Result[];
count: number;
params: any;
}) {
return (
<div>
<div className="mt-4 mb-6 flex justify-between align-center">
<p className="flex items-center">Found {count} results.</p>
<SearchPagination count={count} params={params} />
<div className="sort flex items-center">
{count > 0 && "Add sort here"}
</div>
</div>
<ul className="border-0 border-t border-solid border-slate-200">
{results &&
results?.length > 0 &&
results?.map((article: any) => (
<ResultItem key={article?.id} article={article} />
))}
</ul>
<div className="flex justify-center">
<SearchPagination count={count} params={params} />
</div>
</div>
);
}

export default SearchResults;
Loading

0 comments on commit 27e28a4

Please sign in to comment.