feat: search functionality

This commit is contained in:
TresAbhi committed 2023-09-18 23:25:24 +00:00
1 parent cbeb83d8d0
commit 57f6e928b7
2 files changed
+116 -16

No files matched your search

+18 -1
View File
@@ -1,4 +1,5 @@
import { style } from '@vanilla-extract/css';
import { theme } from '../../../stitches.config';
export const toolBar = style({
'@media': {
@@ -12,7 +13,7 @@ export const toolBar = style({
gap: 8,
});
export const button = style({
export const toolbarButton = style({
'@media': {
'screen and (min-width: 640px)': {
flex: 0,
@@ -21,3 +22,19 @@ export const button = style({
flex: 1,
});
export const searchButton = style({
border: 'none',
background: 'none',
fontSize: 16,
display: 'flex',
padding: 8,
alignItems: 'center',
justifyContent: 'space-between',
cursor: 'pointer',
':hover': {
backgroundColor: theme.colors.componentInteractiveHover,
borderRadius: 4,
},
});
+98 -15
View File
@@ -2,15 +2,21 @@
import { CopyIcon, ListBulletIcon, ReloadIcon } from '@radix-ui/react-icons';
import { debounce } from 'lodash';
import { ChangeEvent, useRef } from 'react';
import { ChangeEvent, useRef, useState } from 'react';
import { Button } from '../../../components/Button';
import PageWrapper from '../../../components/PageWrapper';
import { SearchBar } from '../../../components/SearchBar';
import { REGION_NAMES } from '../../../constants/regions';
import { AccountListWithServer } from '../../../core/blitz/listPlayers';
import { theme } from '../../../stitches.config';
import * as styles from './page.css';
export default function Page() {
const input = useRef<HTMLInputElement>(null);
const [searchResults, setSearchResults] = useState<
AccountListWithServer | undefined
>(undefined);
const [showSearchResults, setShowSearchResults] = useState(false);
const handleChange = debounce(
async (event: ChangeEvent<HTMLInputElement>) => {
if (event.target.value) {
@@ -18,11 +24,7 @@ export default function Page() {
`/api/list/players?search=${event.target.value}`,
).then((response) => response.json() as Promise<AccountListWithServer>);
console.log(
players
.map((player) => `${player.region} - ${player.nickname}`)
.join('\n'),
);
setSearchResults(players);
} else {
// TODO
}
@@ -33,21 +35,102 @@ export default function Page() {
return (
<PageWrapper>
<div className={styles.toolBar}>
<SearchBar
ref={input}
onChange={handleChange}
style={{ flex: 1 }}
placeholder="Search for a player..."
/>
<div style={{ flex: 1, boxSizing: 'border-box', position: 'relative' }}>
<SearchBar
ref={input}
style={{ width: '100%', boxSizing: 'border-box' }}
onChange={(event) => {
if (event.target.value) {
setShowSearchResults(true);
setSearchResults(undefined);
} else {
setShowSearchResults(false);
}
handleChange(event);
}}
placeholder="Search for a player..."
/>
{showSearchResults && (
<div
style={{
display: 'flex',
position: 'absolute',
width: '100%',
top: '100%',
marginTop: 8,
flexDirection: 'column',
backgroundColor: theme.colors.componentNonInteractive,
border: theme.borderStyles.nonInteractive,
borderRadius: 4,
padding: 8,
boxSizing: 'border-box',
}}
>
{searchResults === undefined ? (
<div
style={{
display: 'flex',
alignContent: 'center',
justifyContent: 'center',
fontSize: 16,
color: theme.colors.textLowContrast,
}}
>
Searching...
</div>
) : searchResults.length === 0 ? (
<div
style={{
display: 'flex',
alignContent: 'center',
justifyContent: 'center',
fontSize: 16,
color: theme.colors.textLowContrast,
}}
>
No results
</div>
) : (
searchResults?.map(({ account_id, nickname, region }) => (
<button
key={account_id}
className={styles.searchButton}
onClick={() => {
setShowSearchResults(false);
if (input.current) input.current.value = nickname;
}}
>
<span
style={{
color: theme.colors.textHighContrast,
}}
>
{nickname}
</span>
<span
style={{
color: theme.colors.textLowContrast,
}}
>
{REGION_NAMES[region]}
</span>
</button>
))
)}
</div>
)}
</div>
<div style={{ display: 'flex', gap: 8 }}>
<Button className={styles.button} color="dangerous">
<Button className={styles.toolbarButton} color="dangerous">
<ReloadIcon /> Reset
</Button>
<Button className={styles.button}>
<Button className={styles.toolbarButton}>
<CopyIcon /> Embed
</Button>
<Button className={styles.button}>
<Button className={styles.toolbarButton}>
<ListBulletIcon /> Options
</Button>
</div>