import React from 'react'; import {useDispatch, useSelector} from 'react-redux'; import {Divider, Input, Radio, TimePicker, Button, RadioGroup, Checkbox} from '@douyinfe/semi-ui'; import {InputNumber} from '@douyinfe/semi-ui'; import Headline from '../../components/headline/Headline'; import {xhrPost} from '../../services/xhr'; import {SegmentPart} from '../../components/segment/SegmentPart'; import {Banner, Toast} from '@douyinfe/semi-ui'; import {IconSave, IconCalendar, IconKey, IconRefresh, IconSignal, IconLineChartStroked, IconSearch} from '@douyinfe/semi-icons'; import './GeneralSettings.less'; function formatFromTimestamp(ts) { const date = new Date(ts); return `${date.getHours()}:${date.getMinutes() > 9 ? date.getMinutes() : '0' + date.getMinutes()}`; } function formatFromTBackend(time) { if (time == null || time.length === 0) { return null; } const date = new Date(); const split = time.split(':'); date.setHours(split[0]); date.setMinutes(split[1]); return date.getTime(); } const GeneralSettings = function GeneralSettings() { const dispatch = useDispatch(); const [loading, setLoading] = React.useState(true); const settings = useSelector((state) => state.generalSettings.settings); const [interval, setInterval] = React.useState(''); const [port, setPort] = React.useState(''); const [scrapingAntApiKey, setScrapingAntApiKey] = React.useState(''); const [scrapingAntProxy, setScrapingAntProxy] = React.useState(''); const [workingHourFrom, setWorkingHourFrom] = React.useState(null); const [workingHourTo, setWorkingHourTo] = React.useState(null); const [demoMode, setDemoMode] = React.useState(null); const [analyticsEnabled, setAnalyticsEnabled] = React.useState(null); React.useEffect(() => { async function init() { await dispatch.generalSettings.getGeneralSettings(); setLoading(false); } init(); }, []); React.useEffect(() => { async function init() { setInterval(settings?.interval); setPort(settings?.port); setScrapingAntApiKey(settings?.scrapingAnt?.apiKey); setWorkingHourFrom(settings?.workingHours?.from); setWorkingHourTo(settings?.workingHours?.to); setScrapingAntProxy(settings?.scrapingAnt?.proxy || 'datacenter'); setAnalyticsEnabled(settings?.analytics || false); setDemoMode(settings?.demoMode || false); } init(); }, [settings]); const nullOrEmpty = (val) => val == null || val.length === 0; const throwMessage = (message, type) => { if (type === 'error') { Toast.error(message); } else { Toast.success(message); } }; const onStore = async () => { if (nullOrEmpty(interval)) { throwMessage('Interval may not be empty.', 'error'); return; } if (nullOrEmpty(port)) { throwMessage('Port may not be empty.', 'error'); return; } if ( (!nullOrEmpty(workingHourFrom) && nullOrEmpty(workingHourTo)) || (nullOrEmpty(workingHourFrom) && !nullOrEmpty(workingHourTo)) ) { throwMessage('Working hours to and from must be set if either to or from has been set before.', 'error'); return; } try { await xhrPost('/api/admin/generalSettings', { interval, port, scrapingAnt: { apiKey: scrapingAntApiKey, proxy: scrapingAntProxy, }, workingHours: { from: workingHourFrom, to: workingHourTo, }, demoMode, analyticsEnabled }); } catch (exception) { console.error(exception); if(exception?.json?.message != null){ throwMessage(exception.json.message, 'error'); }else { throwMessage('Error while trying to store settings.', 'error'); } return; } throwMessage('Settings stored successfully. We will reload your browser in 3 seconds.', 'success'); setTimeout(()=>{ location.reload(); }, 3000); }; return (
{!loading && (
`${value}`.replace(/\D/g, '')} onChange={(value) => setInterval(value)} suffix={'minutes'} /> `${value}`.replace(/\D/g, '')} onChange={(value) => setPort(value)} /> setScrapingAntApiKey(val)} /> ScrapingAnt is needed to scrape Immoscout. ScrapingAnt itself is using 2 different types of proxies
} style={{marginBottom: '1rem'}} description={

Datacenter-Proxy

Proxy server located in one of the datacenters across the world. Datacenter proxies are slower and more likely to fail, but they are cheaper. A call with a datacenter proxy cost 10 credits.

Residential-Proxy

High-quality proxy server located in one of the real people houses across the world. Datacenter proxies are faster and more likely to success, but they are more expensive.

On the free tier, you have 10.000 credits, so chose your option wisely. Keep in mind, only successful calls will be charged.
} /> setScrapingAntProxy(e.target.value)}> Datacenter proxy Residential proxy
{ setWorkingHourFrom(val == null ? null : formatFromTimestamp(val)); }} /> { setWorkingHourTo(val == null ? null : formatFromTimestamp(val)); }} />
Explanation
} style={{marginBottom: '1rem'}} description={
Analytics are disabled by default. If you choose to enable them, we will begin tracking the following:
The data is sent anonymously and helps me understand which providers or adapters are being used the most. In the end it helps me to improve fredy.
} /> setAnalyticsEnabled(e.target.checked)} > Enabled Explanation } style={{marginBottom: '1rem'}} description={
In demo mode, Fredy will not (really) search for any real estates. Fredy is in a lockdown mode. Also all database files will be set back to the default values at midnight.
} /> setDemoMode(e.target.checked)} > Enabled
)} ); }; export default GeneralSettings;