added selector component. all questions page fixes and improvements

This commit is contained in:
mrfry 2023-04-03 17:20:58 +02:00
parent 5c779a657d
commit dfc5c93022
9 changed files with 104 additions and 48 deletions

View file

@ -1,16 +0,0 @@
// eslint-disable-next-line no-undef
const useLocalhost = process && process.env.NODE_ENV === 'development'
const constants = {
siteUrl: !useLocalhost ? 'https://frylabs.net/' : 'http://localhost:8080/',
apiUrl: !useLocalhost
? 'https://frylabs.net/api/'
: 'http://localhost:8080/api/',
chatUrl: !useLocalhost ? 'https://frylabs.net/' : 'http://localhost:8080/',
mobileWindowWidth: 700,
maxQuestionsToRender: 250,
imageExts: ['gif', 'png', 'jpeg', 'jpg'],
videoExts: ['mp4', 'mkv', 'webm'],
}
export default constants

View file

@ -6,8 +6,11 @@ function highlightText(text, toHighlight) {
} }
try { try {
const re = new RegExp(toHighlight, 'gi') const re = new RegExp(toHighlight, 'gi')
const splitText = text.split(toHighlight) const splitText = text.split(re)
console.log(splitText) if (splitText.length === 1) {
return text
}
return ( return (
<> <>
{splitText[0]} {splitText[0]}

View file

@ -0,0 +1,48 @@
import React, { useState } from 'react'
import styles from './Selector.module.css'
export default function Selector(props) {
const { activeItem, data, onSelect, getLength, getName } = props
const [searchTerm, setSearchTerm] = useState('')
const dataToDisplay = data.filter((item) => {
return getName(item).toLowerCase().includes(searchTerm.toLowerCase())
})
return (
<div className={styles.container}>
<input
type={'text'}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder={'Kezdj el írni a kereséshez ...'}
/>
<div className="selector">
{dataToDisplay.length === 0 && (
<div className={styles.noResult}>
<span className={styles.itemName}>{'Nincs találat'}</span>
</div>
)}
{dataToDisplay.map((item, i) => {
return (
<div
className={
activeItem && getName(activeItem) === getName(item)
? 'selectorItem activeSelectorItem'
: 'selectorItem'
}
key={i}
onClick={() => onSelect(item)}
>
<span className={styles.itemName}>{getName(item)}</span>
{getLength && (
<span className={styles.questionCount}>
[ {getLength(item)} ]
</span>
)}
</div>
)
})}
</div>
</div>
)
}

View file

@ -0,0 +1,23 @@
.questionCount {
justify-content: flex-end;
white-space: nowrap;
}
.itemName {
word-wrap: break-word;
}
.container {
width: 450px
}
.container input {
border: 1px solid var(--text-color);
border-radius: 5px;
padding: 10px;
}
.noResult {
margin: 5px;
text-align: center;
}

View file

@ -1,3 +1,4 @@
import React from 'react'
import styles from './SubjectSelector.module.css' import styles from './SubjectSelector.module.css'
export default function SubjectSelector(props) { export default function SubjectSelector(props) {

View file

@ -2,14 +2,15 @@
const useLocalhost = process && process.env.NODE_ENV === 'development' const useLocalhost = process && process.env.NODE_ENV === 'development'
const constants = { const constants = {
siteUrl: !useLocalhost ? 'https://frylabs.net/' : 'http://localhost:8080/', siteUrl: useLocalhost ? 'http://localhost:8080/' : 'https://frylabs.net/',
apiUrl: !useLocalhost apiUrl: useLocalhost
? 'https://frylabs.net/api/' ? 'http://localhost:8080/api/'
: 'http://localhost:8080/api/', : 'https://frylabs.net/api/',
chatUrl: !useLocalhost ? 'https://frylabs.net/' : 'http://localhost:8080/', chatUrl: useLocalhost ? 'http://localhost:8080/' : 'https://frylabs.net/',
mobileWindowWidth: 700, mobileWindowWidth: 700,
maxQuestionsToRender: 250, maxQuestionsToRender: 250,
imageExts: ['gif', 'png', 'jpeg', 'jpg'], imageExts: ['gif', 'png', 'jpeg', 'jpg'],
videoExts: ['mp4', 'mkv', 'webm'], videoExts: ['mp4', 'mkv', 'webm'],
} }
export default constants export default constants

View file

@ -112,6 +112,7 @@ input:focus {
} }
.data { .data {
word-wrap: anywhere;
font-size: 13px; font-size: 13px;
color: #a1a1a1; color: #a1a1a1;
} }
@ -123,10 +124,11 @@ input:focus {
font-size: 30px; font-size: 30px;
} }
.subjectSelector { .subjectSelector, .selector {
overflow: auto; overflow: auto;
height: auto; height: auto;
max-height: 250px; max-height: 150px;
min-height: 150px;
margin: 10px; margin: 10px;
padding: 5px; padding: 5px;
padding-right: 10px; padding-right: 10px;
@ -134,8 +136,8 @@ input:focus {
background-color: #141414; background-color: #141414;
} }
.subjItem { .subjItem, .selectorItem {
font-size: 18px; font-size: 14px;
padding: 3px; padding: 3px;
padding-top: 5px; padding-top: 5px;
margin-top: 4px; margin-top: 4px;
@ -144,12 +146,12 @@ input:focus {
justify-content: space-between; justify-content: space-between;
} }
.activeSubjItem { .activeSubjItem, .activeSelectorItem {
background-color: var(--text-color); background-color: var(--text-color);
color: black; color: black;
} }
.subjItem:hover:not(.activeSubjItem) { .subjItem:hover:not(.activeSubjItem), .selectorItem:hover:not(.activeSelectorItem) {
background-color: #555; background-color: #555;
color: white; color: white;
} }

View file

@ -1,3 +1,5 @@
import React from 'react'
function Error({ statusCode }) { function Error({ statusCode }) {
const render404 = () => { const render404 = () => {
return ( return (

View file

@ -7,6 +7,7 @@ import Subject from '../components/Subject'
import SubjectSelector from '../components/SubjectSelector' import SubjectSelector from '../components/SubjectSelector'
import ExternalLinkIcon from '../components/externalLinkIcon' import ExternalLinkIcon from '../components/externalLinkIcon'
import SearchBar from '../components/searchBar' import SearchBar from '../components/searchBar'
import Selector from '../components/Selector'
import styles from './allQuestions.module.css' import styles from './allQuestions.module.css'
@ -202,13 +203,16 @@ export default function AllQuestions({ router, globalState, setGlobalState }) {
</div> </div>
</div> </div>
<div className={'selectContainer'}> <div className={'selectContainer'}>
<select <Selector
value={selectedDb} data={[...dbs, { path: 'all', name: 'Összes kérdés' }]}
onChange={(event) => { getName={(db) => db.name}
const key = event.target.value activeItem={dbs[selectedDb]}
onSelect={(item) => {
// FIXME: active item is all then no highlight
const key = dbs.findIndex((x) => x.path === item.path)
setData(null) setData(null)
setSelectedDb(key) setSelectedDb(key === 'all' ? 'all' : key)
if (parseInt(key) === -1) { if (key === 'all') {
router.replace( router.replace(
`${router.pathname}?question=${encodeURIComponent( `${router.pathname}?question=${encodeURIComponent(
searchTerm searchTerm
@ -228,19 +232,7 @@ export default function AllQuestions({ router, globalState, setGlobalState }) {
{ shallow: true } { shallow: true }
) )
}} }}
> />
<option value={-1}>{' Válassz egy adatbázist!'}</option>
{dbs.map((db, i) => {
return (
<option value={i} key={db.path}>
{db.name}
</option>
)
})}
<option value={'all'} key={'all'}>
{'Összes kérdés'}
</option>
</select>
</div> </div>
</> </>
) )