Skip to content

Commit

Permalink
feat: search campaigns prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
gparlakov committed Nov 1, 2024
1 parent fde9809 commit cd4f43d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 3 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ Watch releases of this repository to be notified about future updates:
## Contributors ✨

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-85-orange.svg?style=flat-square)](#contributors-)

<!-- ALL-CONTRIBUTORS-BADGE:END -->

Please check [contributors guide](https://github.com/podkrepi-bg/frontend/blob/master/CONTRIBUTING.md) for:
Expand Down
65 changes: 62 additions & 3 deletions src/components/client/campaigns/CampaignFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import React, { useMemo, useState } from 'react'
import { styled } from '@mui/material/styles'
import { Box, CircularProgress, Grid, IconButton, Typography } from '@mui/material'
import {
Box,
CircularProgress,
Grid,
IconButton,
TextField,
TextFieldProps,
Typography,
} from '@mui/material'
import { debounce } from 'lodash'
import { useCampaignList } from 'common/hooks/campaigns'
import CampaignsList from './CampaignsList'
import { CampaignResponse } from 'gql/campaigns'
Expand Down Expand Up @@ -79,19 +88,64 @@ const categories: {
others: {},
}

export type SearchFieldProps = TextFieldProps & {
debounceMs?: number
onSearch: (v: string) => void
}
export function SearchField({ debounceMs, onSearch, ...textProps }: SearchFieldProps) {
const debounceSearch = useMemo(
() => debounce(onSearch, debounceMs, { leading: false, trailing: true }),
[],
)

const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
event.preventDefault()
const searchText = event.target.value
const normalizedText = typeof searchText === 'string' ? searchText.trim() : ''
Number(debounceMs) > 0 ? debounceSearch(normalizedText) : onSearch(normalizedText)
}
return (
<TextField
label="Search"
type="search"
variant="outlined"
size="small"
onChange={handleSearch}
sx={{ minWidth: 250 }}
{...textProps}
/>
)
}

export default function CampaignFilter() {
const { t } = useTranslation()
const { data: campaigns, isLoading } = useCampaignList(true)
const [selectedCategory, setSelectedCategory] = useState<string>('ALL')
const [searchValue, setSearchValue] = useState('')

// TODO: add filters&sorting of campaigns so people can select based on personal preferences
const campaignToShow = useMemo<CampaignResponse[]>(() => {
const filteredCampaigns = useMemo<CampaignResponse[]>(() => {
if (selectedCategory === 'ALL') {
return campaigns ?? []
}
return (
campaigns?.filter((campaign) => campaign.campaignType.category === selectedCategory) ?? []
)
}, [campaigns, selectedCategory])
}, [campaigns, selectedCategory, searchValue])

const campaignToShow = useMemo<CampaignResponse[]>(() => {
if (searchValue == null || searchValue === '') {
return filteredCampaigns
}

return (
filteredCampaigns?.filter((c) =>
typeof searchValue === 'string' && searchValue != ''
? c.title?.toLocaleLowerCase()?.includes(searchValue)
: true,
) ?? []
)
}, [filteredCampaigns, searchValue])

return (
<>
Expand Down Expand Up @@ -134,6 +188,11 @@ export default function CampaignFilter() {
</IconButton>
</Grid>
</Grid>
<Grid container>
<Grid item sx={{ my: 5 }}>
<SearchField onSearch={setSearchValue} debounceMs={300} />
</Grid>
</Grid>
</Root>
</Grid>
{isLoading ? (
Expand Down

0 comments on commit cd4f43d

Please sign in to comment.