mirror of
https://github.com/orangecoding/fredy.git
synced 2026-06-16 12:31:07 +00:00
🕵️ More immoscout details (#258)
* 🕵️ More immoscout details - Added more details to immoscout api - description is now populated with a lot of data from the expose using app API - You can ignore certificates, if deploying locally and using the http notification adapter - More details for the test call/example for easier testing + placeholder image + actual values + address (famous Erika Mustermans address see https://de.wikipedia.org/wiki/Mustermann) - Grater timeout for geocode since the api is sometimes slow in germany - uiElement, type boolean, now has a label as well * 👀 Requested changes + some extra Req: - using logger - using node-fetch Extra: - boolean input fields will trigger the validate check, because they are set undefined at first - setting them to false if they are undefined now - added more data to the description (phone number and name of the agent) * ✅ Fixed import * ✅️ Toggle immoscout detail fetching * ✅️ Requested change
This commit is contained in:
@@ -304,6 +304,20 @@ export const useFredyState = create(
|
||||
throw Exception;
|
||||
}
|
||||
},
|
||||
async setImmoscoutDetails(enabled) {
|
||||
try {
|
||||
await xhrPost('/api/user/settings/immoscout-details', { immoscout_details: enabled });
|
||||
set((state) => ({
|
||||
userSettings: {
|
||||
...state.userSettings,
|
||||
settings: { ...state.userSettings.settings, immoscout_details: enabled },
|
||||
},
|
||||
}));
|
||||
} catch (Exception) {
|
||||
console.error('Error while trying to update immoscout details setting. Error:', Exception);
|
||||
throw Exception;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -27,10 +27,13 @@ const sortAdapter = (a, b) => {
|
||||
const validate = (selectedAdapter) => {
|
||||
const results = [];
|
||||
for (let uiElement of Object.values(selectedAdapter.fields || [])) {
|
||||
if (uiElement.value == null && !uiElement.optional) {
|
||||
if (uiElement.value == null && !uiElement.optional && uiElement.type !== 'boolean') {
|
||||
results.push('All fields are mandatory and must be set.');
|
||||
continue;
|
||||
}
|
||||
if (uiElement.type === 'boolean' && typeof uiElement.value !== 'boolean') {
|
||||
uiElement.value = false;
|
||||
}
|
||||
if (uiElement.type === 'number') {
|
||||
const numberValue = parseFloat(uiElement.value);
|
||||
if (isNaN(numberValue) || numberValue < 0) {
|
||||
@@ -153,12 +156,15 @@ export default function NotificationAdapterMutator({
|
||||
return (
|
||||
<Form key={key}>
|
||||
{uiElement.type === 'boolean' ? (
|
||||
<Switch
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
|
||||
<Switch
|
||||
checked={uiElement.value || false}
|
||||
onChange={(checked) => {
|
||||
setValue(selectedAdapter, uiElement, key, checked);
|
||||
}}
|
||||
/>
|
||||
{uiElement.label}
|
||||
</div>
|
||||
) : (
|
||||
<Form.Input
|
||||
style={{ width: '100%' }}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import { useEffect, useState, useMemo } from 'react';
|
||||
import { Divider, Button, AutoComplete, Toast, Banner } from '@douyinfe/semi-ui-19';
|
||||
import { IconSave, IconHome } from '@douyinfe/semi-icons';
|
||||
import { Divider, Button, AutoComplete, Toast, Banner, Switch } from '@douyinfe/semi-ui-19';
|
||||
import { IconSave, IconHome, IconSearch } from '@douyinfe/semi-icons';
|
||||
import { useSelector, useActions, useIsLoading } from '../../services/state/store';
|
||||
import { xhrGet } from '../../services/xhr';
|
||||
import { SegmentPart } from '../../components/segment/SegmentPart';
|
||||
@@ -14,6 +14,7 @@ import debounce from 'lodash/debounce';
|
||||
const UserSettings = () => {
|
||||
const actions = useActions();
|
||||
const homeAddress = useSelector((state) => state.userSettings.settings.home_address);
|
||||
const immoscoutDetails = useSelector((state) => state.userSettings.settings.immoscout_details);
|
||||
const [address, setAddress] = useState(homeAddress?.address || '');
|
||||
const [coords, setCoords] = useState(homeAddress?.coords || null);
|
||||
const saving = useIsLoading(actions.userSettings.setHomeAddress);
|
||||
@@ -84,6 +85,33 @@ const UserSettings = () => {
|
||||
</div>
|
||||
</SegmentPart>
|
||||
<Divider />
|
||||
<SegmentPart
|
||||
name="ImmoScout Details"
|
||||
Icon={IconSearch}
|
||||
helpText="When enabled, Fredy will fetch additional details (description, attributes, agent info) for each listing from ImmoScout. This provides richer notifications but makes an extra API call per listing."
|
||||
>
|
||||
<Banner
|
||||
type="warning"
|
||||
description="Enabling this feature significantly increases the number of API requests to ImmoScout. This raises the likelihood of being detected and rate-limited or blocked. Use at your own risk."
|
||||
closeIcon={null}
|
||||
style={{ marginBottom: '12px', maxWidth: '600px' }}
|
||||
/>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
||||
<Switch
|
||||
checked={!!immoscoutDetails}
|
||||
onChange={async (checked) => {
|
||||
try {
|
||||
await actions.userSettings.setImmoscoutDetails(checked);
|
||||
Toast.success('ImmoScout details setting updated.');
|
||||
} catch {
|
||||
Toast.error('Failed to update setting.');
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<span>Fetch detailed ImmoScout listings</span>
|
||||
</div>
|
||||
</SegmentPart>
|
||||
<Divider />
|
||||
<div style={{ marginTop: '20px' }}>
|
||||
<Button icon={<IconSave />} theme="solid" type="primary" onClick={handleSave} loading={saving}>
|
||||
Save Settings
|
||||
|
||||
Reference in New Issue
Block a user