Skip to content

Commit fd7e228

Browse files
committed
adding welcome screen
1 parent b86e351 commit fd7e228

File tree

15 files changed

+295
-31
lines changed

15 files changed

+295
-31
lines changed

lib/features.js renamed to lib/TRACKING_POIS.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
44
*/
55

6-
export const FEATURES = {
6+
export const TRACKING_POIS = {
77
DISTANCE_ADDRESS_ENTERED: 'DISTANCE_ADDRESS_ENTERED',
8+
WELCOME_FINISHED: 'WELCOME_FINISHED',
9+
WELCOME_SKIPPED: 'WELCOME_SKIPPED',
810
};

lib/api/api.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { listingsRouter } from './routes/listingsRouter.js';
2323
import { getSettings } from '../services/storage/settingsStorage.js';
2424
import { dashboardRouter } from './routes/dashboardRouter.js';
2525
import { backupRouter } from './routes/backupRouter.js';
26+
import { trackingRouter } from './routes/trackingRoute.js';
2627
const service = restana();
2728
const staticService = files(path.join(getDirName(), '../ui/public'));
2829
const PORT = (await getSettings()).port || 9998;
@@ -36,6 +37,7 @@ service.use('/api/version', authInterceptor());
3637
service.use('/api/listings', authInterceptor());
3738
service.use('/api/dashboard', authInterceptor());
3839
service.use('/api/user/settings', authInterceptor());
40+
service.use('/api/tracking', authInterceptor());
3941

4042
// /admin can only be accessed when user is having admin permissions
4143
service.use('/api/admin', adminInterceptor());
@@ -50,6 +52,7 @@ service.use('/api/jobs', jobRouter);
5052
service.use('/api/login', loginRouter);
5153
service.use('/api/listings', listingsRouter);
5254
service.use('/api/dashboard', dashboardRouter);
55+
service.use('/api/tracking', trackingRouter);
5356
//this route is unsecured intentionally as it is being queried from the login page
5457
service.use('/api/demo', demoRouter);
5558

lib/api/routes/trackingRoute.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2026 by Christian Kellner.
3+
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
4+
*/
5+
6+
import restana from 'restana';
7+
import { trackPoi } from '../../services/tracking/Tracker.js';
8+
import { TRACKING_POIS } from '../../TRACKING_POIS.js';
9+
import logger from '../../services/logger.js';
10+
11+
const service = restana();
12+
const trackingRouter = service.newRouter();
13+
14+
trackingRouter.get('/trackingPois', async (req, res) => {
15+
res.body = TRACKING_POIS;
16+
res.send();
17+
});
18+
19+
trackingRouter.post('/poi', async (req, res) => {
20+
const { poi } = req.body;
21+
if (!poi) {
22+
res.statusCode = 400;
23+
res.send({ error: 'Feature name is required' });
24+
return;
25+
}
26+
27+
try {
28+
await trackPoi(poi);
29+
res.send({ success: true });
30+
} catch (error) {
31+
logger.error('Error tracking feature', error);
32+
res.statusCode = 500;
33+
res.send({ error: error.message });
34+
}
35+
});
36+
37+
export { trackingRouter };

lib/api/routes/userSettingsRoute.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { resetGeocoordinatesAndDistanceForUser } from '../../services/storage/li
1010
import { geocodeAddress } from '../../services/geocoding/geoCodingService.js';
1111
import { autocompleteAddress } from '../../services/geocoding/autocompleteService.js';
1212
import { fromJson } from '../../utils.js';
13-
import { trackFeature } from '../../services/tracking/Tracker.js';
14-
import { FEATURES } from '../../features.js';
13+
import { trackPoi } from '../../services/tracking/Tracker.js';
14+
import { TRACKING_POIS } from '../../TRACKING_POIS.js';
1515
import logger from '../../services/logger.js';
1616
import { runGeoCordTask } from '../../services/crons/geocoding-cron.js';
1717

@@ -53,7 +53,7 @@ userSettingsRouter.post('/home-address', async (req, res) => {
5353

5454
try {
5555
if (home_address) {
56-
await trackFeature(FEATURES.DISTANCE_ADDRESS_ENTERED);
56+
await trackPoi(TRACKING_POIS.DISTANCE_ADDRESS_ENTERED);
5757
const coords = await geocodeAddress(home_address);
5858
if (coords && coords.lat !== -1) {
5959
upsertSettings({ home_address: { address: home_address, coords } }, userId);
@@ -76,4 +76,25 @@ userSettingsRouter.post('/home-address', async (req, res) => {
7676
}
7777
});
7878

79+
userSettingsRouter.post('/news-hash', async (req, res) => {
80+
const userId = req.session.currentUser;
81+
const { news_hash } = req.body;
82+
83+
const globalSettings = await getSettings();
84+
if (globalSettings.demoMode) {
85+
res.statusCode = 403;
86+
res.send({ error: 'In demo mode, it is not allowed to change settings.' });
87+
return;
88+
}
89+
90+
try {
91+
upsertSettings({ news_hash }, userId);
92+
res.send({ success: true });
93+
} catch (error) {
94+
logger.error('Error updating news hash', error);
95+
res.statusCode = 500;
96+
res.send({ error: error.message });
97+
}
98+
});
99+
79100
export { userSettingsRouter };

lib/services/tracking/Tracker.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ export const trackMainEvent = async () => {
7070
}
7171
};
7272

73-
export const trackFeature = async (feature) => {
73+
export const trackPoi = async (poi) => {
7474
if (!(await shouldTrack())) return;
7575

7676
const trackingObj = await enrichTrackingObject({
77-
feature,
77+
feature: poi,
7878
});
7979

8080
await sendTrackingData('/feature', trackingObj);

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fredy",
3-
"version": "19.3.9",
3+
"version": "19.4.0",
44
"description": "[F]ind [R]eal [E]states [d]amn eas[y].",
55
"scripts": {
66
"prepare": "husky",
@@ -80,7 +80,7 @@
8080
"node-mailjet": "6.0.11",
8181
"p-throttle": "^8.1.0",
8282
"package-up": "^5.0.0",
83-
"puppeteer": "^24.37.2",
83+
"puppeteer": "^24.37.3",
8484
"puppeteer-extra": "^3.3.6",
8585
"puppeteer-extra-plugin-stealth": "^2.11.2",
8686
"query-string": "9.3.1",

ui/src/App.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import FredyFooter from './components/footer/FredyFooter.jsx';
2929
import WatchlistManagement from './views/listings/management/WatchlistManagement.jsx';
3030
import Dashboard from './views/dashboard/Dashboard.jsx';
3131
import ListingDetail from './views/listings/ListingDetail.jsx';
32+
import NewsModal from './components/news/NewsModal.jsx';
3233

3334
export default function FredyApp() {
3435
const actions = useActions();
@@ -48,6 +49,7 @@ export default function FredyApp() {
4849
await actions.generalSettings.getGeneralSettings();
4950
await actions.userSettings.getUserSettings();
5051
await actions.versionUpdate.getVersionUpdate();
52+
await actions.tracking.getTrackingPois();
5153
}
5254
setLoading(false);
5355
}
@@ -88,6 +90,7 @@ export default function FredyApp() {
8890
</>
8991
)}
9092
{settings.analyticsEnabled === null && !settings.demoMode && <TrackingModal />}
93+
<NewsModal />
9194
<Routes>
9295
<Route path="/403" element={<InsufficientPermission />} />
9396
<Route path="/jobs/new" element={<JobMutation />} />

ui/src/assets/news/1.png

531 KB
Loading

ui/src/assets/news/2.png

4.83 MB
Loading

ui/src/assets/news/3.png

3.73 MB
Loading

0 commit comments

Comments
 (0)