1 Commits

Author SHA1 Message Date
ismailsosic
c39df7ec32 Add onEnter search 2023-03-08 12:08:29 +01:00
34 changed files with 217 additions and 499 deletions

View File

@@ -15,19 +15,16 @@
],
"rootMainFiles": [],
"pages": {
<<<<<<< Updated upstream
=======
"/": [
"static/chunks/webpack.js",
"static/chunks/main.js",
"static/chunks/pages/index.js"
],
"/[book]/[type]/[id]": [
"/[book]/[id]": [
"static/chunks/webpack.js",
"static/chunks/main.js",
"static/chunks/pages/[book]/[type]/[id].js"
"static/chunks/pages/[book]/[id].js"
],
>>>>>>> Stashed changes
"/_app": [
"static/chunks/webpack.js",
"static/chunks/main.js",

View File

@@ -1,5 +1 @@
<<<<<<< Updated upstream
self.__BUILD_MANIFEST={"polyfillFiles":["static/chunks/polyfills.js"],"devFiles":["static/chunks/react-refresh.js"],"ampDevFiles":["static/chunks/webpack.js","static/chunks/amp.js"],"lowPriorityFiles":["static/development/_buildManifest.js","static/development/_ssgManifest.js"],"rootMainFiles":[],"pages":{"/_app":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/_app.js"],"/_error":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/_error.js"],"/search":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/search.js"]},"ampFirstPages":[]}
=======
self.__BUILD_MANIFEST={"polyfillFiles":["static/chunks/polyfills.js"],"devFiles":["static/chunks/react-refresh.js"],"ampDevFiles":["static/chunks/webpack.js","static/chunks/amp.js"],"lowPriorityFiles":["static/development/_buildManifest.js","static/development/_ssgManifest.js"],"rootMainFiles":[],"pages":{"/":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/index.js"],"/[book]/[type]/[id]":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/[book]/[type]/[id].js"],"/_app":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/_app.js"],"/_error":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/_error.js"],"/search":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/search.js"]},"ampFirstPages":[]}
>>>>>>> Stashed changes
self.__BUILD_MANIFEST={"polyfillFiles":["static/chunks/polyfills.js"],"devFiles":["static/chunks/react-refresh.js"],"ampDevFiles":["static/chunks/webpack.js","static/chunks/amp.js"],"lowPriorityFiles":["static/development/_buildManifest.js","static/development/_ssgManifest.js"],"rootMainFiles":[],"pages":{"/":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/index.js"],"/[book]/[id]":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/[book]/[id].js"],"/_app":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/_app.js"],"/_error":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/_error.js"],"/search":["static/chunks/webpack.js","static/chunks/main.js","static/chunks/pages/search.js"]},"ampFirstPages":[]}

View File

@@ -2,10 +2,7 @@
"/_app": "pages/_app.js",
"/_error": "pages/_error.js",
"/_document": "pages/_document.js",
<<<<<<< Updated upstream
=======
"/[book]/[type]/[id]": "pages/[book]/[type]/[id].js",
"/": "pages/index.js",
>>>>>>> Stashed changes
"/[book]/[id]": "pages/[book]/[id].js",
"/search": "pages/search.js"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -131,11 +131,7 @@
/******/
/******/ /* webpack/runtime/getFullHash */
/******/ !function() {
<<<<<<< Updated upstream
/******/ __webpack_require__.h = function() { return "93e21dfb81445514"; }
=======
/******/ __webpack_require__.h = function() { return "95af3d6f0b2398ce"; }
>>>>>>> Stashed changes
/******/ __webpack_require__.h = function() { return "a2eda309a2e86c12"; }
/******/ }();
/******/
/******/ /* webpack/runtime/global */

View File

@@ -1,5 +1 @@
<<<<<<< Updated upstream
self.__BUILD_MANIFEST = {__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/_error":["static\u002Fchunks\u002Fpages\u002F_error.js"],"/search":["static\u002Fchunks\u002Fpages\u002Fsearch.js"],sortedPages:["\u002F_app","\u002F_error","\u002Fsearch"]};self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()
=======
self.__BUILD_MANIFEST = {__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":["static\u002Fchunks\u002Fpages\u002Findex.js"],"/_error":["static\u002Fchunks\u002Fpages\u002F_error.js"],"/search":["static\u002Fchunks\u002Fpages\u002Fsearch.js"],"/[book]/[type]/[id]":["static\u002Fchunks\u002Fpages\u002F[book]\u002F[type]\u002F[id].js"],sortedPages:["\u002F","\u002F_app","\u002F_error","\u002Fsearch","\u002F[book]\u002F[type]\u002F[id]"]};self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()
>>>>>>> Stashed changes
self.__BUILD_MANIFEST = {__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":["static\u002Fchunks\u002Fpages\u002Findex.js"],"/_error":["static\u002Fchunks\u002Fpages\u002F_error.js"],"/search":["static\u002Fchunks\u002Fpages\u002Fsearch.js"],"/[book]/[id]":["static\u002Fchunks\u002Fpages\u002F[book]\u002F[id].js"],sortedPages:["\u002F","\u002F_app","\u002F_error","\u002Fsearch","\u002F[book]\u002F[id]"]};self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()

File diff suppressed because one or more lines are too long

View File

@@ -1,32 +1,36 @@
# KitabCitab Web App
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).
KitabCitab Web App is app that provides books search services by name, author and terms from books.
## Getting Started
## Functionalities
First, run the development server:
- Search books
- Read books
```bash
npm run dev
# or
yarn dev
```
## App requirements
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
- Node.js
- Next.js
- ElasticSearch server (data)
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
## Installation
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
1. Clone this project from GitLab repository "https://gitlab.com/saburly/kitabcitab/kitabcitab-frontend.git".
2. In terminal, go to directory of the project and run "npm install" to install all packages.
3. Change ENV_VAR variable inside "envconfig.js" to your server url. Default is "http://localhost:9200".
4. Run "npm run dev" to start app, and then go to url "http://localhost:3000".
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
## Example of data object
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
result = {
"book" : "Hamine pustolovine",
"writer" : "Muhamed Ahmed Mustafa",
"pages": "98",
"text" : "Lorem ipsum"
}
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

View File

@@ -8,13 +8,15 @@ const Result = ({result, term}) => {
const [title, setTitle] = useState()
let sentences
const checkForMatches = (props) => {
const checkForMatches = (props) => {
if(props.length === 1) return setTitle(props)
if(props.length > 1){
return sentences.map(sentence => {
if(sentence.toLowerCase().includes(term.toLowerCase())) setTitle(sentence)
})
} else setTitle(props[0])
if(props.length > 1 ){
return sentences.map((sentence) => {
if(sentence.toLowerCase().includes(term.toLowerCase())) setTitle(sentence)
else setTitle(props[0])
})
}
}
@@ -33,7 +35,7 @@ const Result = ({result, term}) => {
return (
<div onClick={() => (router.push({pathname: `${result._index}/${result._type}/${result._id}`}))} className='
<div onClick={() => (router.push({pathname: `/${result._type}/${result._id}`}))} className='
self-end
bg-[#202124]
w-[100%]
@@ -53,4 +55,4 @@ const Result = ({result, term}) => {
)
}
export default Result
export default Result

View File

@@ -3,6 +3,7 @@ import Result from './Result'
const Results = ({data, term}) => {
console.log(data)
return (
<div className='

View File

@@ -1 +1 @@
export const ENV_VAR = "http://localhost:9200"
export const ENV_VAR = "http://localhost:9200/"

View File

@@ -1,23 +1,24 @@
import { AiOutlineLeft, AiOutlineRight } from 'react-icons/ai'
import Link from "next/link"
import { useRouter } from 'next/router'
import { ENV_VAR } from '../../../../envconfig'
import { ENV_VAR } from '../../../envconfig'
const result = ({data}) => {
const router = useRouter()
console.log(data)
const {book, writer, text} = data._source
const nextPageHandler = () => {
if(Number(data._id) + 1 === Number(data._source.pages) + 1) return
if(Number(data._id) + 1 === Number(data._source.numOfPages) + 1) return
router.push(`/${data._index}/${data._type}/${Number(data._id) + 1}`)
router.push(`/${book.toLowerCase()}/${Number(data._id) + 1}`)
}
const prevPageHandler = () => {
if(data._id - 1 === 0) return
router.push(`/${data._index}/${data._type}/${Number(data._id) - 1}`)
router.push(`/${book.toLowerCase()}/${Number(data._id) - 1}`)
}
return (
@@ -46,7 +47,7 @@ const result = ({data}) => {
"
>
<i className='rounded-3xl text-[#fff] px-3 py-auto' onClick={() => prevPageHandler()}><AiOutlineLeft size={25} /></i>
<p className="text-base tablet:text-2xl laptop:text-2xl text-[#fff] font-serif text-center">"{book}", {writer}, str. {data._id}</p>
<p className="text-base tablet:text-2xl laptop:text-2xl text-[#fff] font-serif text-center">"{book}", {writer}, str.{data._id}</p>
<i className='rounded-3xl text-[#fff] px-3 py-auto' onClick={() => nextPageHandler()}><AiOutlineRight size={25} /></i>
</div>
<div className='page flex laptop:justify-center laptop:min-w-[100%]'>
@@ -81,8 +82,9 @@ export default result
export async function getServerSideProps (context) {
try{
const res = await fetch(`${ENV_VAR}${context.resolvedUrl}`)
const res = await fetch(`${ENV_VAR}library${context.resolvedUrl}`)
const data = await res.json()
return { props: {data} }
}
catch{err => console.log(err)}

View File

@@ -5,7 +5,7 @@ import { useRouter } from 'next/router'
export default function Home({data}) {
const router = useRouter()
const searchInputRef = useRef(null)
const searchInputRef = useRef("")
const search = () => {
const term = searchInputRef.current.value
@@ -13,6 +13,11 @@ export default function Home({data}) {
router.push(`/search?term=${term}`)
}
const enterHandler = (e) => {
const term = searchInputRef.current.value
if(e.key === "Enter" && term !== "") router.push(`/search?term=${term}`)
}
return (
<div className="flex flex-col justify-center items-center w-[100vw] h-[50vh]">
<div className="p-10 ">
@@ -29,7 +34,7 @@ export default function Home({data}) {
"
>
<i className='rounded-3xl hover:border-black text-[#9aa0a6] px-3' onClick={() => search()}><AiOutlineSearch size={25}/></i>
<input ref={searchInputRef} className="bg-[#202124] group-hover:bg-[#303134] w-[80%] px-2 active:border-none text-white outline-none text-xl"/>
<input ref={searchInputRef} onKeyDown={(e) => enterHandler(e)} className="bg-[#202124] group-hover:bg-[#303134] w-[80%] px-2 active:border-none text-white outline-none text-xl"/>
<i className='rounded-3xl hover:border-black text-[#9aa0a6] px-3' onClick={() => (searchInputRef.current.value = "")}><AiOutlineClose size={25} /></i>
</div>
<button

View File

@@ -2,7 +2,6 @@ import React, { useState } from 'react'
import Results from '../components/Results'
import { AiOutlineClose, AiOutlineSearch } from 'react-icons/ai'
import Link from 'next/link'
import { useRef } from 'react'
import { useRouter } from 'next/router'
import { ENV_VAR } from '../envconfig'
@@ -10,14 +9,16 @@ import { ENV_VAR } from '../envconfig'
const SearchPage = ({data}) => {
const router = useRouter()
const [searchInput, setSearchInput] = useState(router.query.term)
const term = searchInput
const search = () => {
const term = searchInput
if(!term) return
router.push(`/search?term=${term}`)
}
console.log(data)
const enterHandler = (e) => {
if(e.key === "Enter" && term !== "") router.push(`/search?term=${term}`)
}
return (
<div className='flex flex-col justify-center'>
@@ -45,7 +46,7 @@ const SearchPage = ({data}) => {
"
>
<i className='rounded-3xl hover:border-black text-[#9aa0a6] px-3' onClick={() => search()}><AiOutlineSearch size={25}/></i>
<input value={searchInput} onChange={(e) => setSearchInput(e.target.value)} className="bg-[#303134] ml-5 w-[70%] active:border-none text-white outline-none text-lg "/>
<input onKeyDown={(e) => enterHandler(e)} value={searchInput} onChange={(e) => setSearchInput(e.target.value)} className="bg-[#303134] ml-5 w-[70%] active:border-none text-white outline-none text-lg "/>
<i className='rounded-3xl text-[#9aa0a6] px-3' onClick={() => setSearchInput("")}><AiOutlineClose size={25} /></i>
</div>
</div>
@@ -56,7 +57,7 @@ const SearchPage = ({data}) => {
export async function getServerSideProps(context) {
// Fetch data from external API
const res = await fetch(`${ENV_VAR}/_search?q=${context.query.term}`)
const res = await fetch(`${ENV_VAR}_search?q=${context.query.term}`)
const data = await res.json()
// Pass data to the page via props