add copy to clipboard / read from querystring functionalities
This commit is contained in:
parent
9f719568a0
commit
b9dc623170
|
@ -0,0 +1,58 @@
|
|||
import { Box, Button, Card, Flex, Icon, Spacer } from '@chakra-ui/react';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IoShareSocialOutline } from 'react-icons/io5';
|
||||
import MediaQuery from 'react-responsive';
|
||||
import { MEDIA_QUERY_DESKTOP_STARTS, MEDIA_QUERY_MOBILE_ENDS } from '../constants/mediaquery';
|
||||
|
||||
export interface IProps {
|
||||
show: boolean
|
||||
onClick(): void
|
||||
}
|
||||
|
||||
const CopyToClipboardButton: React.FC<IProps> = (props) => {
|
||||
|
||||
const { show, onClick } = props
|
||||
|
||||
const [showSuccess, setShowSuccess] = useState<boolean>(false)
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleClick = () => {
|
||||
onClick()
|
||||
setShowSuccess(true)
|
||||
|
||||
setTimeout(() => {
|
||||
setShowSuccess(false)
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<MediaQuery minWidth={MEDIA_QUERY_DESKTOP_STARTS}>
|
||||
{show &&
|
||||
<Card backgroundColor={'transparent'} mt={{ base: 0, md: 4 }} mb={{ base: 0, md: 4 }} mx={{ base: 4, md: 4 }}>
|
||||
<Box p='4'>
|
||||
<Flex alignItems={'center'}>
|
||||
<Button bgColor={showSuccess ? 'green.400' : ''} onClick={handleClick}>
|
||||
{showSuccess ? t('search.copy_success'): t('search.copy_search_link')} <Icon as={IoShareSocialOutline} />
|
||||
</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Card>}
|
||||
</MediaQuery>
|
||||
<MediaQuery maxWidth={MEDIA_QUERY_MOBILE_ENDS}>
|
||||
{show &&
|
||||
<Box p='4'>
|
||||
<Flex alignItems={'center'}>
|
||||
<Button bgColor={showSuccess ? 'green.400' : ''} onClick={handleClick}>
|
||||
{showSuccess ? t('search.copy_success') : t('search.copy_search_link')} <Icon as={IoShareSocialOutline} />
|
||||
</Button>
|
||||
</Flex>
|
||||
</Box>}
|
||||
</MediaQuery>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CopyToClipboardButton;
|
|
@ -1,5 +1,6 @@
|
|||
import { GridItem, Icon, SimpleGrid } from '@chakra-ui/react';
|
||||
import React, { useState } from 'react';
|
||||
import { Button, GridItem, Icon, SimpleGrid, Flex, Box, Card } from '@chakra-ui/react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import MediaQuery from 'react-responsive'
|
||||
import {
|
||||
TbBook2,
|
||||
TbBuilding,
|
||||
|
@ -11,10 +12,13 @@ import {
|
|||
import search, { Book } from '../scripts/searcher';
|
||||
|
||||
import { IoLanguage } from 'react-icons/io5';
|
||||
import { IoShareSocialOutline } from 'react-icons/io5';
|
||||
import SearchInput from './SearchInput';
|
||||
import { useDebounceEffect } from 'ahooks';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import SearchLanguage from './SearchLanguage';
|
||||
import { MEDIA_QUERY_DESKTOP_STARTS, MEDIA_QUERY_MOBILE_ENDS } from '../constants/mediaquery';
|
||||
import CopyToClipboardButton from './CopyToClipboardButton';
|
||||
|
||||
function constructQuery(parts: Record<string, string>): string {
|
||||
return Object.keys(parts)
|
||||
|
@ -44,6 +48,27 @@ const Search: React.FC<SearchProps> = ({ setBooks }) => {
|
|||
const [complexQuery, setComplexQuery] = useState<string>('');
|
||||
const [showLanguageDropdown, setShowLanguageDropdown] = useState<boolean>(true)
|
||||
|
||||
useEffect(() => {
|
||||
const params = new Proxy(new URLSearchParams(window.location.search), {
|
||||
//@ts-ignore
|
||||
get: (searchParams, prop) => searchParams.get(prop),
|
||||
});
|
||||
|
||||
//@ts-ignore
|
||||
params.title && setTitle(String(params.title))
|
||||
|
||||
//@ts-ignore
|
||||
params.author && setAuthor(String(params.author))
|
||||
|
||||
//@ts-ignore
|
||||
if (params.language) {
|
||||
//@ts-ignore
|
||||
setLanguage(String(params.language))
|
||||
setShowLanguageDropdown(false)
|
||||
}
|
||||
|
||||
}, [])
|
||||
|
||||
const handleLanguageChange = (language: string) => {
|
||||
if (language == 'input') {
|
||||
setShowLanguageDropdown(false)
|
||||
|
@ -57,6 +82,27 @@ const Search: React.FC<SearchProps> = ({ setBooks }) => {
|
|||
setLanguage('')
|
||||
}
|
||||
|
||||
const hasAnySearchBeenMade = () => {
|
||||
return (
|
||||
title !== ''
|
||||
|| author !== ''
|
||||
|| language !== ''
|
||||
|| publisher !== ''
|
||||
|| extension !== ''
|
||||
|| isbn !== ''
|
||||
)
|
||||
}
|
||||
|
||||
const copyToClipboard = () => {
|
||||
const searchQuery = `${window.location.host}?title=${title}&author=${author}&language=${language}&publisher=${publisher}&isbn=${isbn}&extension=${extension}`;
|
||||
|
||||
navigator.clipboard.writeText(searchQuery).then(() => {
|
||||
//console.log('Async: Copying to clipboard was successful!');
|
||||
}, (err) => {
|
||||
//console.error('Async: Could not copy text: ', err);
|
||||
});
|
||||
}
|
||||
|
||||
useDebounceEffect(
|
||||
() => {
|
||||
const query = complexQuery
|
||||
|
@ -72,66 +118,71 @@ const Search: React.FC<SearchProps> = ({ setBooks }) => {
|
|||
);
|
||||
|
||||
return (
|
||||
<SimpleGrid
|
||||
columns={{ sm: 1, md: 2, lg: 3 }}
|
||||
spacing={{ base: 2, md: 4 }}
|
||||
px={{ base: 4, md: 8 }}
|
||||
>
|
||||
<SearchInput
|
||||
icon={<Icon as={TbBook2} />}
|
||||
placeholder={t('book.title')}
|
||||
value={title}
|
||||
onChange={setTitle}
|
||||
/>
|
||||
<SearchInput
|
||||
icon={<Icon as={TbUserCircle} />}
|
||||
placeholder={t('book.author')}
|
||||
value={author}
|
||||
onChange={setAuthor}
|
||||
/>
|
||||
<SearchInput
|
||||
icon={<Icon as={TbBuilding} />}
|
||||
placeholder={t('book.publisher')}
|
||||
value={publisher}
|
||||
onChange={setPublisher}
|
||||
/>
|
||||
<SearchInput
|
||||
icon={<Icon as={TbFileDescription} />}
|
||||
placeholder={t('book.extension')}
|
||||
value={extension}
|
||||
onChange={setExtension}
|
||||
/>
|
||||
|
||||
{!showLanguageDropdown && (<SearchInput
|
||||
icon={<Icon as={IoLanguage} />}
|
||||
placeholder={t('input.select_language')}
|
||||
value={language}
|
||||
onChange={handleLanguageChange}
|
||||
onClear={handleLanguageReset}
|
||||
/>)}
|
||||
|
||||
{showLanguageDropdown && (<SearchLanguage
|
||||
icon={<Icon as={IoLanguage} />}
|
||||
placeholder={t('input.select_language')}
|
||||
value={language}
|
||||
onChange={handleLanguageChange}
|
||||
/>)}
|
||||
|
||||
<SearchInput
|
||||
icon={<Icon as={TbHash} />}
|
||||
placeholder={t('book.isbn')}
|
||||
value={isbn}
|
||||
onChange={setISBN}
|
||||
/>
|
||||
<GridItem colSpan={{ sm: 1, md: 2, lg: 3 }}>
|
||||
<>
|
||||
<SimpleGrid
|
||||
columns={{ sm: 1, md: 2, lg: 3 }}
|
||||
spacing={{ base: 2, md: 4 }}
|
||||
px={{ base: 4, md: 8 }}
|
||||
>
|
||||
<SearchInput
|
||||
icon={<Icon as={TbReportSearch} />}
|
||||
placeholder={t('search.complex')}
|
||||
value={complexQuery}
|
||||
onChange={setComplexQuery}
|
||||
icon={<Icon as={TbBook2} />}
|
||||
placeholder={t('book.title')}
|
||||
value={title}
|
||||
onChange={setTitle}
|
||||
/>
|
||||
</GridItem>
|
||||
</SimpleGrid>
|
||||
<SearchInput
|
||||
icon={<Icon as={TbUserCircle} />}
|
||||
placeholder={t('book.author')}
|
||||
value={author}
|
||||
onChange={setAuthor}
|
||||
/>
|
||||
<SearchInput
|
||||
icon={<Icon as={TbBuilding} />}
|
||||
placeholder={t('book.publisher')}
|
||||
value={publisher}
|
||||
onChange={setPublisher}
|
||||
/>
|
||||
<SearchInput
|
||||
icon={<Icon as={TbFileDescription} />}
|
||||
placeholder={t('book.extension')}
|
||||
value={extension}
|
||||
onChange={setExtension}
|
||||
/>
|
||||
|
||||
{!showLanguageDropdown && (<SearchInput
|
||||
icon={<Icon as={IoLanguage} />}
|
||||
placeholder={t('input.select_language')}
|
||||
value={language}
|
||||
onChange={handleLanguageChange}
|
||||
onClear={handleLanguageReset}
|
||||
/>)}
|
||||
|
||||
{showLanguageDropdown && (<SearchLanguage
|
||||
icon={<Icon as={IoLanguage} />}
|
||||
placeholder={t('input.select_language')}
|
||||
value={language}
|
||||
onChange={handleLanguageChange}
|
||||
/>)}
|
||||
|
||||
<SearchInput
|
||||
icon={<Icon as={TbHash} />}
|
||||
placeholder={t('book.isbn')}
|
||||
value={isbn}
|
||||
onChange={setISBN}
|
||||
/>
|
||||
<GridItem colSpan={{ sm: 1, md: 2, lg: 3 }}>
|
||||
<SearchInput
|
||||
icon={<Icon as={TbReportSearch} />}
|
||||
placeholder={t('search.complex')}
|
||||
value={complexQuery}
|
||||
onChange={setComplexQuery}
|
||||
/>
|
||||
</GridItem>
|
||||
</SimpleGrid>
|
||||
<CopyToClipboardButton
|
||||
show={hasAnySearchBeenMade()}
|
||||
onClick={copyToClipboard} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -39,7 +39,9 @@
|
|||
"collapse": "Collapse"
|
||||
},
|
||||
"search": {
|
||||
"complex": "Complex search"
|
||||
"complex": "Complex search",
|
||||
"copy_search_link": "Copy to clipboard",
|
||||
"copy_success": "Copied!"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
|
@ -205,7 +207,9 @@
|
|||
"collapse": "Richiudi"
|
||||
},
|
||||
"search": {
|
||||
"complex": "Ricerca dettagliata"
|
||||
"complex": "Ricerca dettagliata",
|
||||
"copy_search_link": "Copia link ricerca",
|
||||
"copy_success": "Copiato negli appunti!"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Impostazioni",
|
||||
|
|
Loading…
Reference in New Issue