|  | @@ -0,0 +1,127 @@
 | 
	
		
			
				|  |  | +import { useTrainingTypesQuery, TrainingType } from '../../gql'
 | 
	
		
			
				|  |  | +import AddTrainingType from './AddTrainingType'
 | 
	
		
			
				|  |  | +import { useState, useEffect } from 'react'
 | 
	
		
			
				|  |  | +import { Modal } from '../../modal'
 | 
	
		
			
				|  |  | +import Dropdown from '../../dropdown/components/Dropdown'
 | 
	
		
			
				|  |  | +import { QueryHookOptions, QueryResult } from '@apollo/client'
 | 
	
		
			
				|  |  | +import { TextInput } from '../../form'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +interface ISelector<TQueryData, TQueryVariables> {
 | 
	
		
			
				|  |  | +  name: string
 | 
	
		
			
				|  |  | +  value: any
 | 
	
		
			
				|  |  | +  onChange: GenericEventHandler
 | 
	
		
			
				|  |  | +  callback: (selectedIndex: number) => void
 | 
	
		
			
				|  |  | +  query: (
 | 
	
		
			
				|  |  | +    baseOptions?: QueryHookOptions<TQueryData, { where: { OR: { [key: string]: string }[] } }>
 | 
	
		
			
				|  |  | +  ) => QueryResult<TQueryData, TQueryVariables>
 | 
	
		
			
				|  |  | +  searchKeys?: (keyof TQueryData)[]
 | 
	
		
			
				|  |  | +  dataKey: keyof TQueryData
 | 
	
		
			
				|  |  | +  selectedKey: keyof TQueryData
 | 
	
		
			
				|  |  | +  className?: string
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * The selector allows to select an item from a list and offers tools to add, edit or remove items.
 | 
	
		
			
				|  |  | + * @param param0
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +const Selector = <
 | 
	
		
			
				|  |  | +  TQueryData extends { [dataKey: string]: any[] },
 | 
	
		
			
				|  |  | +  TQueryVariables extends Record<string, any>
 | 
	
		
			
				|  |  | +>({
 | 
	
		
			
				|  |  | +  name,
 | 
	
		
			
				|  |  | +  value,
 | 
	
		
			
				|  |  | +  onChange,
 | 
	
		
			
				|  |  | +  query,
 | 
	
		
			
				|  |  | +  searchKeys,
 | 
	
		
			
				|  |  | +  dataKey,
 | 
	
		
			
				|  |  | +  className,
 | 
	
		
			
				|  |  | +}: ISelector<TQueryData, TQueryVariables>) => {
 | 
	
		
			
				|  |  | +  const [searchTerm, setSearchTerm] = useState('')
 | 
	
		
			
				|  |  | +  const searchVariables =
 | 
	
		
			
				|  |  | +    searchKeys && searchTerm !== ''
 | 
	
		
			
				|  |  | +      ? { variables: { where: { OR: searchKeys?.map((key) => ({ [key]: searchTerm })) } } }
 | 
	
		
			
				|  |  | +      : {}
 | 
	
		
			
				|  |  | +  const { data, error, loading } = query(searchVariables)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  useEffect(() => {
 | 
	
		
			
				|  |  | +    setTimeout(() => console.log('debouonced.'), 300)
 | 
	
		
			
				|  |  | +  }, [searchTerm])
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return (
 | 
	
		
			
				|  |  | +    <div className={className}>
 | 
	
		
			
				|  |  | +      <TextInput
 | 
	
		
			
				|  |  | +        name='search'
 | 
	
		
			
				|  |  | +        type='search'
 | 
	
		
			
				|  |  | +        value={searchTerm}
 | 
	
		
			
				|  |  | +        onChange={(event) => setSearchTerm(event.target.vale)}
 | 
	
		
			
				|  |  | +      />
 | 
	
		
			
				|  |  | +      <select
 | 
	
		
			
				|  |  | +        id={name}
 | 
	
		
			
				|  |  | +        name={name}
 | 
	
		
			
				|  |  | +        value={value}
 | 
	
		
			
				|  |  | +        onChange={(event) => {
 | 
	
		
			
				|  |  | +          const changeEvent: CustomChangeEvent = {
 | 
	
		
			
				|  |  | +            target: {
 | 
	
		
			
				|  |  | +              type: 'custom',
 | 
	
		
			
				|  |  | +              value: { id: event.target.value },
 | 
	
		
			
				|  |  | +              name,
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +          onChange(changeEvent)
 | 
	
		
			
				|  |  | +        }}
 | 
	
		
			
				|  |  | +      >
 | 
	
		
			
				|  |  | +        {loading && 'loading training types...'}
 | 
	
		
			
				|  |  | +        {error && 'error loading training types'}
 | 
	
		
			
				|  |  | +        {data &&
 | 
	
		
			
				|  |  | +          data[dataKey].map((item) => (
 | 
	
		
			
				|  |  | +            <option key={item.id} value={item.id}>
 | 
	
		
			
				|  |  | +              {item.name}
 | 
	
		
			
				|  |  | +            </option>
 | 
	
		
			
				|  |  | +          ))}
 | 
	
		
			
				|  |  | +      </select>
 | 
	
		
			
				|  |  | +      <button
 | 
	
		
			
				|  |  | +        type='button'
 | 
	
		
			
				|  |  | +        onClick={(event) => {
 | 
	
		
			
				|  |  | +          setModalState(true)
 | 
	
		
			
				|  |  | +        }}
 | 
	
		
			
				|  |  | +      >
 | 
	
		
			
				|  |  | +        Add type
 | 
	
		
			
				|  |  | +      </button>
 | 
	
		
			
				|  |  | +      <Modal state={[modalState, setModalState]}>
 | 
	
		
			
				|  |  | +        <AddTrainingType
 | 
	
		
			
				|  |  | +          onSuccess={(result) => {
 | 
	
		
			
				|  |  | +            setModalState(false)
 | 
	
		
			
				|  |  | +            if (result.data) {
 | 
	
		
			
				|  |  | +              onChange({
 | 
	
		
			
				|  |  | +                target: {
 | 
	
		
			
				|  |  | +                  type: 'custom',
 | 
	
		
			
				|  |  | +                  value: { id: result.data.createTrainingType.id },
 | 
	
		
			
				|  |  | +                  name,
 | 
	
		
			
				|  |  | +                },
 | 
	
		
			
				|  |  | +              })
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          }}
 | 
	
		
			
				|  |  | +        />
 | 
	
		
			
				|  |  | +      </Modal>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      <style jsx>{`
 | 
	
		
			
				|  |  | +        div {
 | 
	
		
			
				|  |  | +          display: flex;
 | 
	
		
			
				|  |  | +          align-items: center;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        label,
 | 
	
		
			
				|  |  | +        select,
 | 
	
		
			
				|  |  | +        button {
 | 
	
		
			
				|  |  | +          display: inline-block;
 | 
	
		
			
				|  |  | +          width: auto;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        select {
 | 
	
		
			
				|  |  | +          flex-grow: 1;
 | 
	
		
			
				|  |  | +          margin: 0 0.6em;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      `}</style>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +  )
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +export default Selector
 |