add toast and loading bar
This commit is contained in:
parent
00055f88be
commit
7192626dce
9 changed files with 110 additions and 17 deletions
21
package-lock.json
generated
21
package-lock.json
generated
|
@ -11,6 +11,7 @@
|
||||||
"next": "14.1.0",
|
"next": "14.1.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
|
"react-toastify": "^10.0.4",
|
||||||
"zustand": "^4.5.0"
|
"zustand": "^4.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -1163,6 +1164,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/clsx": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
@ -3722,6 +3731,18 @@
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/react-toastify": {
|
||||||
|
"version": "10.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.4.tgz",
|
||||||
|
"integrity": "sha512-etR3RgueY8pe88SA67wLm8rJmL1h+CLqUGHuAoNsseW35oTGJEri6eBTyaXnFKNQ80v/eO10hBYLgz036XRGgA==",
|
||||||
|
"dependencies": {
|
||||||
|
"clsx": "^2.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16",
|
||||||
|
"react-dom": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"next": "14.1.0",
|
"next": "14.1.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
|
"react-toastify": "^10.0.4",
|
||||||
"zustand": "^4.5.0"
|
"zustand": "^4.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { authors, affiliations, nationalities } from '../../db/data'
|
||||||
import { Zilla_Slab } from 'next/font/google'
|
import { Zilla_Slab } from 'next/font/google'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { notFound } from 'next/navigation'
|
import { notFound } from 'next/navigation'
|
||||||
import { Fragment } from 'react'
|
import { Fragment, Suspense } from 'react'
|
||||||
|
|
||||||
const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] })
|
const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] })
|
||||||
|
|
||||||
|
|
14
src/app/components/Loading.tsx
Normal file
14
src/app/components/Loading.tsx
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import styles from './loading.module.css'
|
||||||
|
const LoadingBar = () => {
|
||||||
|
return (
|
||||||
|
<div className='w-full mt-[-50px]'>
|
||||||
|
<div className='h-1.5 w-full bg-pink-100 overflow-hidden'>
|
||||||
|
<div
|
||||||
|
className={`${styles.progress} w-full h-full bg-blue-500 ${styles['left-right']}`}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LoadingBar
|
18
src/app/components/loading.module.css
Normal file
18
src/app/components/loading.module.css
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
.progress {
|
||||||
|
animation: progress 1s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-right {
|
||||||
|
transform-origin: 0% 50%;
|
||||||
|
}
|
||||||
|
@keyframes progress {
|
||||||
|
0% {
|
||||||
|
transform: translateX(0) scaleX(0);
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
transform: translateX(0) scaleX(0.4);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%) scaleX(0.5);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import { epoch2datestring } from '@/app/utils/epoch2datestring'
|
||||||
|
|
||||||
const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] })
|
const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] })
|
||||||
|
|
||||||
export function generateStaticParams () {
|
export function generateStaticParams() {
|
||||||
const documentsList = Object.keys(documents)
|
const documentsList = Object.keys(documents)
|
||||||
return documentsList.map((slug) => ({ slug }))
|
return documentsList.map((slug) => ({ slug }))
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export default function Page({
|
||||||
const { title, authors, topics, dates, references, code, type, latest } =
|
const { title, authors, topics, dates, references, code, type, latest } =
|
||||||
doc.manifest
|
doc.manifest
|
||||||
|
|
||||||
const generateTopics = () => {
|
const Topics = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<span className='font-bold'>Topics: </span>
|
<span className='font-bold'>Topics: </span>
|
||||||
|
@ -44,7 +44,7 @@ export default function Page({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateCode = () => {
|
const Code = () => {
|
||||||
if (code) {
|
if (code) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -62,7 +62,7 @@ export default function Page({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateAuthors = () => {
|
const Authors = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{authors.map((a: string, i) => (
|
{authors.map((a: string, i) => (
|
||||||
|
@ -78,7 +78,24 @@ export default function Page({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateItemBadge = (itemName: DocumentType) => {
|
const References = () => {
|
||||||
|
if (!references) return null
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<span className='font-bold'>References: </span>
|
||||||
|
{references.map((r: string, i) => (
|
||||||
|
<Fragment key={r}>
|
||||||
|
<Link href={r} target='_blank'>
|
||||||
|
{r}
|
||||||
|
</Link>
|
||||||
|
{i !== references.length - 1 ? ', ' : null}
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ItemBadge = ({ itemName }: Readonly<{ itemName: DocumentType }>) => {
|
||||||
let text = ''
|
let text = ''
|
||||||
let itemStyle: string =
|
let itemStyle: string =
|
||||||
'px-3 py-1.5 rounded inline-block w-fit mr-2 mt-4 text-slate-50 border-2 '
|
'px-3 py-1.5 rounded inline-block w-fit mr-2 mt-4 text-slate-50 border-2 '
|
||||||
|
@ -118,26 +135,38 @@ export default function Page({
|
||||||
className={`
|
className={`
|
||||||
text-slate-800 font-bold text-5xl mb-4
|
text-slate-800 font-bold text-5xl mb-4
|
||||||
${zillaSlab.className}
|
${zillaSlab.className}
|
||||||
|
text-wrap
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</h1>
|
</h1>
|
||||||
<p className={`text-slate-800 mt-2`}>{generateAuthors()}</p>
|
<p className={`text-slate-800 mt-2`}>
|
||||||
|
<Authors />
|
||||||
|
</p>
|
||||||
<p className='mt-4'>
|
<p className='mt-4'>
|
||||||
Latest revision published{' '}
|
Latest revision published{' '}
|
||||||
<span className='font-bold'>
|
<span className='font-bold'>
|
||||||
{epoch2datestring(dates[dates.length - 1])}
|
{epoch2datestring(dates[dates.length - 1])}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
{generateItemBadge(type)}
|
<ItemBadge itemName={type as DocumentType} />
|
||||||
<p className='inline-block border-gray-200 border-2 rounded px-2 py-1.5'>
|
<p className='inline-block border-gray-200 border-2 rounded px-2 py-1.5'>
|
||||||
Revision {latest}
|
Revision {latest}
|
||||||
</p>
|
</p>
|
||||||
<hr className='my-4' />
|
<hr className='my-4' />
|
||||||
<h4 className='text-2xl mt-5 font-serif font-semibold'>Abstract</h4>
|
<h4 className='text-2xl mt-5 font-serif font-semibold'>Abstract</h4>
|
||||||
<p className='my-4 text-xl text-slate-600 font-serif '>{abstract}</p>
|
<p className='my-4 text-xl text-slate-600 font-serif text-balance'>
|
||||||
<p className='my-2'>{generateTopics()}</p>
|
{abstract}
|
||||||
<p className='my-2'>{generateCode()}</p>
|
</p>
|
||||||
|
<p className='my-2'>
|
||||||
|
<Topics />
|
||||||
|
</p>
|
||||||
|
<p className='my-2'>
|
||||||
|
<Code />
|
||||||
|
</p>
|
||||||
|
<p className='my-2'>
|
||||||
|
<References />
|
||||||
|
</p>
|
||||||
<Link
|
<Link
|
||||||
href={`/download/${params.slug}/file${latest}.${file}`}
|
href={`/download/${params.slug}/file${latest}.${file}`}
|
||||||
download={`${params.slug}-rev-${latest}.pdf`}
|
download={`${params.slug}-rev-${latest}.pdf`}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 150px;
|
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background: linear-gradient(to left, #80bfff 0%, #ccc 50%, white 100%);
|
background: linear-gradient(to left, #80bfff 0%, #ccc 50%, white 100%);
|
||||||
color: black;
|
color: black;
|
||||||
|
@ -14,10 +13,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
/* top: 162.5px; */
|
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
/* margin-bottom: 50px; */
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@ import styles from './home.module.css'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import SearchBar from './searchBar/SearchBar'
|
import SearchBar from './searchBar/SearchBar'
|
||||||
import Container from './container/Container'
|
import Container from './container/Container'
|
||||||
|
import { ToastContainer } from 'react-toastify'
|
||||||
|
import 'react-toastify/dist/ReactToastify.css'
|
||||||
|
import { Suspense } from 'react'
|
||||||
|
import LoadingBar from './components/Loading'
|
||||||
|
|
||||||
/* The default font is Inter. If you want to use Zilla Slab (or any other Google Font,
|
/* The default font is Inter. If you want to use Zilla Slab (or any other Google Font,
|
||||||
which are pre-provided by Next.js in the 'next/font/google' module), you need to
|
which are pre-provided by Next.js in the 'next/font/google' module), you need to
|
||||||
|
@ -28,12 +32,14 @@ export default function RootLayout({
|
||||||
return (
|
return (
|
||||||
<html lang='en'>
|
<html lang='en'>
|
||||||
<body className={inter.className}>
|
<body className={inter.className}>
|
||||||
|
<ToastContainer />
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div className='max-w-[1200px] flex flex-nowrap mx-auto justify-between items-center'>
|
<div className='max-w-[1200px] flex flex-nowrap mx-auto justify-between items-center'>
|
||||||
<Link href='/affiliation/1280-eecs'>
|
<Link href='/affiliation/1280-eecs'>
|
||||||
<img
|
<img
|
||||||
className='h-[100px] mt-4'
|
className='h-[100px] mt-4'
|
||||||
src='/eexiv-2/img/logos/eecs-wordmark.png'
|
src='/eexiv-2/img/logos/eecs-wordmark.png'
|
||||||
|
alt='EECS'
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
<p className={`max-w-[600px] hidden md:inline`}>
|
<p className={`max-w-[600px] hidden md:inline`}>
|
||||||
|
@ -61,9 +67,11 @@ export default function RootLayout({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Container width='1200px' fill>
|
<Suspense fallback={<LoadingBar />}>
|
||||||
{children}
|
<Container width='1200px' fill>
|
||||||
</Container>
|
{children}
|
||||||
|
</Container>
|
||||||
|
</Suspense>
|
||||||
<footer>
|
<footer>
|
||||||
<div className={styles.footerContent}>
|
<div className={styles.footerContent}>
|
||||||
<Container width='1200px'>
|
<Container width='1200px'>
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
'use client'
|
'use client'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
export default function SearchBar() {
|
export default function SearchBar() {
|
||||||
|
const handleClick = () => {
|
||||||
|
toast.warn('This feature is currently under active development!')
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className='width-[40vw]'>
|
<div className='width-[40vw]'>
|
||||||
<input
|
<input
|
||||||
|
@ -11,6 +15,7 @@ export default function SearchBar() {
|
||||||
<button
|
<button
|
||||||
type='submit'
|
type='submit'
|
||||||
className='p-2.5 mx-4 border-2 rounded-xl hover:bg-blue-300'
|
className='p-2.5 mx-4 border-2 rounded-xl hover:bg-blue-300'
|
||||||
|
onClick={handleClick}
|
||||||
>
|
>
|
||||||
Search
|
Search
|
||||||
</button>
|
</button>
|
||||||
|
|
Loading…
Reference in a new issue