Filter data

 avatar
unknown
javascript
2 years ago
8.2 kB
5
Indexable
// FilterSideBar.tsx

import '../assets/FilterSideBar.css';
import '@utdanningno/designsystem-react-select/designsystem-react-select.css';
import 'react-datepicker/dist/react-datepicker.css';
import 'react-bootstrap-range-slider/dist/react-bootstrap-range-slider.css';

import { Slider } from '@mui/material';
import { Select } from '@utdanningno/designsystem-react-select';
import nb from 'date-fns/locale/nb';
import React, { useEffect, useState } from 'react';
import DatePicker, { registerLocale, setDefaultLocale } from 'react-datepicker';

import { getFacet, usePostSearchQuery } from '../search/chatlogApi';
import { FacetMap, FacetRequestType, SearchRequest, SearchResult } from '../search/MessageTypes';

registerLocale('nb', nb);
setDefaultLocale('nb');

interface SearchbarProps {
	searchString: string | undefined;
	queryFacets: FacetRequestType[];
	onFacetsChanged: (newFacets: FacetRequestType[]) => void;
}

export const FilterSideBar = ({ searchString, queryFacets, onFacetsChanged }: SearchbarProps) => {
	// HOOKS
	const [data, setData] = useState<SearchResult>();
	const [startDate, setStartDate] = useState(null);
	const [endDate, setEndDate] = useState(null);
	const [value, setValue] = useState<number[]>([0, 100]);

	// HANDLE
	const handleChange = (event: Event, newValue: number | number[]) => {
		setValue(newValue as number[]);
	};

	const handleSelectChange = (values, id) => {
		const valueList = values.map((value) => value.id);
		handleSetItems(queryFacets, id, valueList);
	};

	const handleSetItems = (list: FacetRequestType[] | undefined, id: string, items: string[]) => {
		const newList = list?.map((filter) => {
			if (filter.id === id) {
				const updatedItem = {
					...filter,
					checked_item_ids: items,
				};
				return updatedItem;
			}
			return filter;
		});
		//console.log(newList, queryFacets);
		onFacetsChanged(newList ?? []);
	};

	// DATA
	const search: SearchRequest = {
		search_string: searchString,
		facets: queryFacets,
	};

	//console.log(search);
	const feedback = usePostSearchQuery(search);

	useEffect(() => {
		setData(feedback.data);
	}, [feedback.data]);

	//console.log(data);

	const facets: FacetMap = {
		date_range: getFacet('date_range', data?.facets),
		education_level: getFacet('education_level', data?.facets),
		employment_status: getFacet('employment_status', data?.facets),
		chat_duration_in_minutes: getFacet('chat_duration_in_minutes', data?.facets),
	};
	//console.log(facets);

	return (
		<div className="filter-sidebar">
			<div className="filter-box">
				<h5 className="filter-title">Tidspunkt</h5>

				<div className="date-wrapper">
					<div className="date">
						<p className="from-to-date">Fra: </p>
						<DatePicker
							dateFormat="dd/MM/yyyy"
							endDate={endDate}
							isClearable={true}
							onChange={(date: React.SetStateAction<null>) => setStartDate(date)}
							placeholderText={'DD/MM/YYYY'}
							selected={startDate}
							selectsStart
							startDate={startDate}
						/>
					</div>
					<div className="date">
						<p className="from-to-date">Til: </p>
						<DatePicker
							dateFormat="dd/MM/yyyy"
							endDate={endDate}
							isClearable={true}
							minDate={startDate}
							onChange={(date: React.SetStateAction<null>) => setEndDate(date)}
							placeholderText={'DD/MM/YYYY'}
							selected={endDate}
							selectsEnd
							startDate={startDate}
						/>
					</div>
				</div>
			</div>

			<div className="filter-box">
				<h5 className="filter-title">Informasjon om bruker</h5>
				<Select
					formatOptionLabel={(item, { context }) => {
						return context === 'menu' ? item.label : item.name;
					}}
					getOptionLabel={(item) => item.name + ' (' + item.count + ')'}
					getOptionValue={(item) => item.id}
					isMulti
					onChange={(values) => handleSelectChange(values, facets.education_level?.id)}
					options={facets.education_level?.items}
					placeholder={facets.education_level?.name.toString()}
				/>

				<Select
					formatOptionLabel={(item, { context }) => {
						return context === 'menu' ? item.label : item.name;
					}}
					getOptionLabel={(item) => item.name + ' (' + item.count + ')'}
					getOptionValue={(item) => item.id}
					isMulti
					onChange={(values) => handleSelectChange(values, facets.employment_status?.id)}
					options={facets.employment_status?.items}
					placeholder={facets.employment_status?.name.toString()}
				/>
			</div>

			<div className="filter-box">
				<h5 className="filter-title">Samtalelengde</h5>
				<Slider onChange={handleChange} value={value} valueLabelDisplay="auto" />
			</div>

			<div className="filter-box">
				<h5 className="filter-title">Om samtalen</h5>
			</div>
		</div>
	);
};


// SearchPage.tsx

import { useState } from 'react';
import { useSearchParams } from 'react-router-dom';

import { Content } from '../components/Content';
import { FilterSideBar } from '../components/FilterSideBar';
import { Header } from '../components/Header';
import { Searchbar } from '../components/Searchbar';
import { FacetRequestType, MultiSelectFacetRequest } from '../search/MessageTypes';

const initializeFacetList = () => {
	const educationFilter: FacetRequestType = {
		id: 'education_level',
		type: 'MULTI_SELECT',
		checked_item_ids: [],
	};

	const statusFilter: FacetRequestType = {
		id: 'employment_status',
		type: 'MULTI_SELECT',
		checked_item_ids: [],
	};
	return [educationFilter, statusFilter];
};

export const SearchPage = () => {
	const [searchParams, setSearchParams] = useSearchParams();
	const [facetList, setFacetList] = useState<FacetRequestType[]>(initializeFacetList);

	const query = searchParams.get('query') ?? undefined;

	const handleQueryChanged = (newQuery: string) => {
		setSearchParams({ query: newQuery });
	};

	const handleFacetListChanged = (newFacets: FacetRequestType[]) => {
		setFacetList(newFacets);
	};

	return (
		<div>
			<Header />
			<div className="body">
				<Searchbar onQueryChanged={handleQueryChanged} query={query} />
				<div className="container">
					<FilterSideBar searchString={query} queryFacets={facetList} onFacetsChanged={handleFacetListChanged} />
					<Content searchString={query} queryFacets={facetList} />
				</div>
			</div>
		</div>
	);
};

// Content.tsx

import '../assets/Content.css';

import { Checkbox } from '@utdanningno/designsystem-react';
import { Select } from '@utdanningno/designsystem-react-select';
import { useState } from 'react';
import React from 'react';

import { usePostSearchQuery } from '../search/chatlogApi';
import { MultiSelectFacetRequest, SearchHit, SearchRequest } from '../search/MessageTypes';
import { ChatBox } from './ChatBox';

export const Content = (props) => {
	// PROPS
	const searchString = props.searchString;
	const queryFacets = props.queryFacets;

	// HOOKS
	const [userChecked, setUserChecked] = React.useState<boolean>(true);
	const [supervisorChecked, setSupervisorChecked] = React.useState<boolean>(true);
	const [selected, setSelected] = useState([]);

	// HANDLE
	const handleUserCheckboxChange = () => {
		setUserChecked(!userChecked);
	};

	const handleSupervisorCheckboxChange = () => {
		setSupervisorChecked(!supervisorChecked);
	};

	const handleSelectChange = (values) => {
		setSelected(values);
	};

	// DATA
	const search: SearchRequest = {
		search_string: searchString,
		facets: queryFacets,
	};

	const { data } = usePostSearchQuery(search);
	//console.log(data);

	return (
		<div className="content">
			<div className="choose-author">
				<span className="author-title">Søk i tekst fra: </span>
				<Checkbox defaultChecked={true} id="user" label="Besøkende" name="user" onChange={handleUserCheckboxChange} value="user" />
				<Checkbox defaultChecked={true} id="supervisor" label="Veileder" name="supervisor" onChange={handleSupervisorCheckboxChange} value="supervisor" />
				<Checkbox defaultChecked={true} id="feedback" label="Tilbakemelding" name="feedback" value="feedback" />
			</div>
			<div className="sortby">
				<Select onChange={handleSelectChange} placeholder="Sorter etter" />
			</div>
			<div>{data ? data.hits.map((hit: SearchHit, key: number) => <ChatBox data={hit} key={key.toString()} />) : ''}</div>
		</div>
	);
};
Editor is loading...