mirror of
https://github.com/towfiqi/serpbear
synced 2025-06-26 18:15:54 +00:00
feat: Ability to keywords for both mobile and desktop at once.
closes #60, #66, #199
This commit is contained in:
parent
f48288473e
commit
3786438662
@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo, useRef, useState } from 'react';
|
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
||||||
import Icon from '../common/Icon';
|
import Icon from '../common/Icon';
|
||||||
import Modal from '../common/Modal';
|
import Modal from '../common/Modal';
|
||||||
import SelectField from '../common/SelectField';
|
import SelectField from '../common/SelectField';
|
||||||
@ -23,10 +23,11 @@ type KeywordsInput = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const AddKeywords = ({ closeModal, domain, keywords, scraperName = '', allowsCity = false }: AddKeywordsProps) => {
|
const AddKeywords = ({ closeModal, domain, keywords, scraperName = '', allowsCity = false }: AddKeywordsProps) => {
|
||||||
const [error, setError] = useState<string>('');
|
|
||||||
const [showTagSuggestions, setShowTagSuggestions] = useState(false);
|
|
||||||
const inputRef = useRef(null);
|
const inputRef = useRef(null);
|
||||||
const defCountry = localStorage.getItem('default_country') || 'US';
|
const defCountry = localStorage.getItem('default_country') || 'US';
|
||||||
|
|
||||||
|
const [error, setError] = useState<string>('');
|
||||||
|
const [showTagSuggestions, setShowTagSuggestions] = useState(false);
|
||||||
const [newKeywordsData, setNewKeywordsData] = useState<KeywordsInput>({ keywords: '', device: 'desktop', country: defCountry, domain, tags: '' });
|
const [newKeywordsData, setNewKeywordsData] = useState<KeywordsInput>({ keywords: '', device: 'desktop', country: defCountry, domain, tags: '' });
|
||||||
const { mutate: addMutate, isLoading: isAdding } = useAddKeywords(() => closeModal(false));
|
const { mutate: addMutate, isLoading: isAdding } = useAddKeywords(() => closeModal(false));
|
||||||
|
|
||||||
@ -35,23 +36,45 @@ const AddKeywords = ({ closeModal, domain, keywords, scraperName = '', allowsCit
|
|||||||
return [...new Set(allTags)];
|
return [...new Set(allTags)];
|
||||||
}, [keywords]);
|
}, [keywords]);
|
||||||
|
|
||||||
|
const setDeviceType = useCallback((input:string) => {
|
||||||
|
let updatedDevice = '';
|
||||||
|
if (newKeywordsData.device.includes(input)) {
|
||||||
|
updatedDevice = newKeywordsData.device.replace(',', '').replace(input, '');
|
||||||
|
} else {
|
||||||
|
updatedDevice = newKeywordsData.device ? `${newKeywordsData.device},${input}` : input;
|
||||||
|
}
|
||||||
|
setNewKeywordsData({ ...newKeywordsData, device: updatedDevice });
|
||||||
|
}, [newKeywordsData]);
|
||||||
|
|
||||||
const addKeywords = () => {
|
const addKeywords = () => {
|
||||||
if (newKeywordsData.keywords) {
|
const nkwrds = newKeywordsData;
|
||||||
const keywordsArray = [...new Set(newKeywordsData.keywords.split('\n').map((item) => item.trim()).filter((item) => !!item))];
|
if (nkwrds.keywords) {
|
||||||
|
const devices = nkwrds.device.split(',');
|
||||||
|
const multiDevice = nkwrds.device.includes(',') && devices.length > 1;
|
||||||
|
const keywordsArray = [...new Set(nkwrds.keywords.split('\n').map((item) => item.trim()).filter((item) => !!item))];
|
||||||
const currentKeywords = keywords.map((k) => `${k.keyword}-${k.device}-${k.country}${k.city ? `-${k.city}` : ''}`);
|
const currentKeywords = keywords.map((k) => `${k.keyword}-${k.device}-${k.country}${k.city ? `-${k.city}` : ''}`);
|
||||||
const keywordExist = keywordsArray.filter((k) => currentKeywords.includes(
|
|
||||||
`${k}-${newKeywordsData.device}-${newKeywordsData.country}${newKeywordsData.city ? `-${newKeywordsData.city}` : ''}`,
|
const keywordExist = keywordsArray.filter((k) =>
|
||||||
));
|
devices.some((device) => currentKeywords.includes(`${k}-${device}-${nkwrds.country}${nkwrds.city ? `-${nkwrds.city}` : ''}`)),
|
||||||
if ((keywordsArray.length === 1 || currentKeywords.length === keywordExist.length) && keywordExist.length > 0) {
|
);
|
||||||
|
|
||||||
|
if (!multiDevice && (keywordsArray.length === 1 || currentKeywords.length === keywordExist.length) && keywordExist.length > 0) {
|
||||||
setError(`Keywords ${keywordExist.join(',')} already Exist`);
|
setError(`Keywords ${keywordExist.join(',')} already Exist`);
|
||||||
setTimeout(() => { setError(''); }, 3000);
|
setTimeout(() => { setError(''); }, 3000);
|
||||||
} else {
|
} else {
|
||||||
const filteredKeywords = keywordsArray.filter((k) => !currentKeywords.includes(
|
const newKeywords = keywordsArray.flatMap((k) =>
|
||||||
`${k}-${newKeywordsData.device}-${newKeywordsData.country}${newKeywordsData.city ? `-${newKeywordsData.city}` : ''}`,
|
devices.filter((device) =>
|
||||||
));
|
!currentKeywords.includes(`${k}-${device}-${nkwrds.country}${nkwrds.city ? `-${nkwrds.city}` : ''}`),
|
||||||
const { device, country, domain: kDomain, tags, city } = newKeywordsData;
|
).map((device) => ({
|
||||||
const newKeywordsArray = filteredKeywords.map((nItem) => ({ keyword: nItem, device, country, domain: kDomain, tags, city }));
|
keyword: k,
|
||||||
addMutate(newKeywordsArray);
|
device,
|
||||||
|
country: nkwrds.country,
|
||||||
|
domain: nkwrds.domain,
|
||||||
|
tags: nkwrds.tags,
|
||||||
|
city: nkwrds.city,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
addMutate(newKeywords);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setError('Please Insert a Keyword');
|
setError('Please Insert a Keyword');
|
||||||
@ -59,7 +82,7 @@ const AddKeywords = ({ closeModal, domain, keywords, scraperName = '', allowsCit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const deviceTabStyle = 'cursor-pointer px-3 py-2 rounded mr-2';
|
const deviceTabStyle = 'cursor-pointer px-2 py-2 rounded';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal closeModal={() => { closeModal(false); }} title={'Add New Keywords'} width="[420px]">
|
<Modal closeModal={() => { closeModal(false); }} title={'Add New Keywords'} width="[420px]">
|
||||||
@ -92,13 +115,17 @@ const AddKeywords = ({ closeModal, domain, keywords, scraperName = '', allowsCit
|
|||||||
</div>
|
</div>
|
||||||
<ul className='flex text-xs font-semibold text-gray-500'>
|
<ul className='flex text-xs font-semibold text-gray-500'>
|
||||||
<li
|
<li
|
||||||
className={`${deviceTabStyle} ${newKeywordsData.device === 'desktop' ? ' bg-indigo-50 text-gray-700' : ''}`}
|
className={`${deviceTabStyle} mr-2 ${newKeywordsData.device.includes('desktop') ? ' bg-indigo-50 text-indigo-700' : ''}`}
|
||||||
onClick={() => setNewKeywordsData({ ...newKeywordsData, device: 'desktop' })}
|
onClick={() => setDeviceType('desktop')}>
|
||||||
><Icon type='desktop' classes={'top-[3px]'} size={15} /> <i className='not-italic hidden lg:inline-block'>Desktop</i></li>
|
<Icon type='desktop' classes={'top-[3px]'} size={15} /> <i className='not-italic hidden lg:inline-block'>Desktop</i>
|
||||||
|
<Icon type='check' classes={'pl-1'} size={12} color={newKeywordsData.device.includes('desktop') ? '#4338ca' : '#bbb'} />
|
||||||
|
</li>
|
||||||
<li
|
<li
|
||||||
className={`${deviceTabStyle} ${newKeywordsData.device === 'mobile' ? ' bg-indigo-50 text-gray-700' : ''}`}
|
className={`${deviceTabStyle} ${newKeywordsData.device.includes('mobile') ? ' bg-indigo-50 text-indigo-700' : ''}`}
|
||||||
onClick={() => setNewKeywordsData({ ...newKeywordsData, device: 'mobile' })}
|
onClick={() => setDeviceType('mobile')}>
|
||||||
><Icon type='mobile' /> <i className='not-italic hidden lg:inline-block'>Mobile</i></li>
|
<Icon type='mobile' /> <i className='not-italic hidden lg:inline-block'>Mobile</i>
|
||||||
|
<Icon type='check' classes={'pl-1'} size={12} color={newKeywordsData.device.includes('mobile') ? '#4338ca' : '#bbb'} />
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className='relative'>
|
<div className='relative'>
|
||||||
|
Loading…
Reference in New Issue
Block a user