From 88c0fec189bbffd521a07503544afa8498322297 Mon Sep 17 00:00:00 2001 From: jona159 Date: Mon, 4 May 2026 07:14:11 +0200 Subject: [PATCH 01/11] feat: make map landing page, mv current to about --- app/components/header/menu/index.tsx | 7 + app/routes/_index.tsx | 263 +-------------------------- app/routes/about.tsx | 259 ++++++++++++++++++++++++++ public/locales/de/menu.json | 1 + public/locales/en/menu.json | 1 + 5 files changed, 272 insertions(+), 259 deletions(-) create mode 100644 app/routes/about.tsx diff --git a/app/components/header/menu/index.tsx b/app/components/header/menu/index.tsx index f4491e42..2fbd91ac 100644 --- a/app/components/header/menu/index.tsx +++ b/app/components/header/menu/index.tsx @@ -12,6 +12,7 @@ import { Compass, ScrollText, MessagesSquare, + Info, } from 'lucide-react' import { useState } from 'react' import { useTranslation } from 'react-i18next' @@ -103,6 +104,12 @@ export default function Menu() { )} + + + + {t('about_label')} + + {!(matches[1].pathname === '/explore') && ( diff --git a/app/routes/_index.tsx b/app/routes/_index.tsx index ccb6e550..907332f3 100644 --- a/app/routes/_index.tsx +++ b/app/routes/_index.tsx @@ -1,260 +1,5 @@ -import { readItems } from '@directus/sdk' -import { useMediaQuery } from '@mantine/hooks' -import { motion } from 'framer-motion' -import { useEffect } from 'react' -import { useTranslation } from 'react-i18next' -import { - type LoaderFunctionArgs, - data, - Link, - useLoaderData, -} from 'react-router' -import { type Route } from './+types/_index' -import Footer from '~/components/landing/footer' -import { GlobeComponent } from '~/components/landing/globe.client' -import Header from '~/components/landing/header/header' -import Connect from '~/components/landing/sections/connect' -import Features from '~/components/landing/sections/features' -import Integrations from '~/components/landing/sections/integrations' -import Partners from '~/components/landing/sections/partners' -import PricingPlans from '~/components/landing/sections/pricing-plans' -import Stats from '~/components/landing/stats' -import { getLatestDevices } from '~/db/models/device.server' -import { type SupportedLanguage } from '~/i18next-config' -import { type Partner, getDirectusClient } from '~/lib/directus' -import { getLocale } from '~/middleware/i18next' -import { getUserId, getUserName } from '~/services/session-service.server' +import { redirect } from "react-router"; -const sections = [ - { - title: 'Features', - description: - 'The openSenseMap platform has a lot to offer that makes discoverability and sharing of environmental and sensor data easy.', - component: Features, - }, - { - title: 'Connect', - description: - 'Connect your devices to the openSenseMap platform and start sharing your environmental data with the world.', - component: Connect, - }, - { - title: 'Integrations', - description: - 'Integrate your devices with the openSenseMap platform and start sharing your environmental data with the world.', - component: Integrations, - }, - { - title: 'Pricing', - description: - 'Choose the right pricing plan for your needs and start sharing your environmental data with the world.', - component: PricingPlans, - }, -] - -export const loader = async ({ context, request }: Route.LoaderArgs) => { - const locale = getLocale(context) as SupportedLanguage - - const directus = getDirectusClient() - - const useCasesResponse = await directus.request( - readItems('use_cases', { - fields: ['*'], - filter: { - language: { _eq: locale }, - }, - }), - ) - - const featuresResponse = await directus.request( - readItems('features', { - fields: ['*'], - filter: { - language: { _eq: locale }, - }, - }), - ) - - const partnersResponse = await directus.request( - readItems('partners', { - fields: ['*'], - }), - ) - - const userId = await getUserId(request) - const userName = await getUserName(request) - const stats = await fetch('https://api.opensensemap.org/stats').then( - (res) => { - return res.json() - }, - ) - - const latestDevices = await getLatestDevices() - - return data({ - useCases: useCasesResponse, - features: featuresResponse, - partners: partnersResponse, - stats: stats, - header: { userId: userId, userName: userName }, - locale: locale, - latestDevices: latestDevices, - }) -} - -export default function Index() { - const { partners, stats, latestDevices } = useLoaderData<{ - partners: Partner[] - stats: number[] - latestDevices: any[] - }>() - - const { t } = useTranslation('landing') - - const isDesktop = useMediaQuery('(min-width: 768px)') - - /** - * Stupid workaround for chromium and webkit that both render double - * scroll bars when using scrollSnapType. - * Simply setting overflow hidden on the html element fixes it and - * the rest of the pages stay untouched from this. - */ - useEffect(() => { - document.documentElement.style.setProperty('overflow', 'hidden') - return () => { - document.documentElement.style.removeProperty('overflow') - } - }, []) - - return ( -
-
-
-
-
-
-
-
-

- openSenseMap -

- -

- {t('introduction')} -

-
-
- - - - - - - - - - - - - - -
-
- {isDesktop && ( -
- -
- )} -
- {isDesktop && ( -
- -
- )} -
- {sections.map((section, _index) => { - const Component = section.component - return ( -
- -
- ) - })} -
- -
-
-
-
- ) -} +export function loader() { + return redirect("/explore"); +} \ No newline at end of file diff --git a/app/routes/about.tsx b/app/routes/about.tsx new file mode 100644 index 00000000..be3d5d83 --- /dev/null +++ b/app/routes/about.tsx @@ -0,0 +1,259 @@ +import { readItems } from '@directus/sdk' +import { useMediaQuery } from '@mantine/hooks' +import { motion } from 'framer-motion' +import { useEffect } from 'react' +import { useTranslation } from 'react-i18next' +import { + data, + Link, + useLoaderData, +} from 'react-router' +import { type Route } from './+types/_index' +import Footer from '~/components/landing/footer' +import { GlobeComponent } from '~/components/landing/globe.client' +import Header from '~/components/landing/header/header' +import Connect from '~/components/landing/sections/connect' +import Features from '~/components/landing/sections/features' +import Integrations from '~/components/landing/sections/integrations' +import Partners from '~/components/landing/sections/partners' +import PricingPlans from '~/components/landing/sections/pricing-plans' +import Stats from '~/components/landing/stats' +import { getLatestDevices } from '~/db/models/device.server' +import { type SupportedLanguage } from '~/i18next-config' +import { type Partner, getDirectusClient } from '~/lib/directus' +import { getLocale } from '~/middleware/i18next' +import { getUserId, getUserName } from '~/services/session-service.server' + +const sections = [ + { + title: 'Features', + description: + 'The openSenseMap platform has a lot to offer that makes discoverability and sharing of environmental and sensor data easy.', + component: Features, + }, + { + title: 'Connect', + description: + 'Connect your devices to the openSenseMap platform and start sharing your environmental data with the world.', + component: Connect, + }, + { + title: 'Integrations', + description: + 'Integrate your devices with the openSenseMap platform and start sharing your environmental data with the world.', + component: Integrations, + }, + { + title: 'Pricing', + description: + 'Choose the right pricing plan for your needs and start sharing your environmental data with the world.', + component: PricingPlans, + }, +] + +export const loader = async ({ context, request }: Route.LoaderArgs) => { + const locale = getLocale(context) as SupportedLanguage + + const directus = getDirectusClient() + + const useCasesResponse = await directus.request( + readItems('use_cases', { + fields: ['*'], + filter: { + language: { _eq: locale }, + }, + }), + ) + + const featuresResponse = await directus.request( + readItems('features', { + fields: ['*'], + filter: { + language: { _eq: locale }, + }, + }), + ) + + const partnersResponse = await directus.request( + readItems('partners', { + fields: ['*'], + }), + ) + + const userId = await getUserId(request) + const userName = await getUserName(request) + const stats = await fetch('https://api.opensensemap.org/stats').then( + (res) => { + return res.json() + }, + ) + + const latestDevices = await getLatestDevices() + + return data({ + useCases: useCasesResponse, + features: featuresResponse, + partners: partnersResponse, + stats: stats, + header: { userId: userId, userName: userName }, + locale: locale, + latestDevices: latestDevices, + }) +} + +export default function Index() { + const { partners, stats, latestDevices } = useLoaderData<{ + partners: Partner[] + stats: number[] + latestDevices: any[] + }>() + + const { t } = useTranslation('landing') + + const isDesktop = useMediaQuery('(min-width: 768px)') + + /** + * Stupid workaround for chromium and webkit that both render double + * scroll bars when using scrollSnapType. + * Simply setting overflow hidden on the html element fixes it and + * the rest of the pages stay untouched from this. + */ + useEffect(() => { + document.documentElement.style.setProperty('overflow', 'hidden') + return () => { + document.documentElement.style.removeProperty('overflow') + } + }, []) + + return ( +
+
+
+
+
+
+
+
+

+ openSenseMap +

+ +

+ {t('introduction')} +

+
+
+ + + + + + + + + + + + + + +
+
+ {isDesktop && ( +
+ +
+ )} +
+ {isDesktop && ( +
+ +
+ )} +
+ {sections.map((section, _index) => { + const Component = section.component + return ( +
+ +
+ ) + })} +
+ +
+
+
+
+ ) +} diff --git a/public/locales/de/menu.json b/public/locales/de/menu.json index 7e555ae1..fd9f6b54 100644 --- a/public/locales/de/menu.json +++ b/public/locales/de/menu.json @@ -4,6 +4,7 @@ "explore_label": "Erkunden", "profile_label": "Profil", "settings_label": "Einstellungen", + "about_label": "Über OpenSenseMap", "my_devices_label": "Meine Geräte", "add_device_label": "Gerät hinzufügen", "tutorials_label": "Tutorials", diff --git a/public/locales/en/menu.json b/public/locales/en/menu.json index ee0f7dab..bd3c42b6 100644 --- a/public/locales/en/menu.json +++ b/public/locales/en/menu.json @@ -3,6 +3,7 @@ "subtitle": "Please sign in to see more content", "explore_label": "Explore", "profile_label": "Profile", + "about_label": "About", "settings_label": "Settings", "my_devices_label": "My Devices", "add_device_label": "Add Device", From 56068461f7547439a52f229590cad39828ac835c Mon Sep 17 00:00:00 2001 From: jona159 Date: Mon, 4 May 2026 16:35:52 +0200 Subject: [PATCH 02/11] fix: update copyright year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 21d75af1..298523bf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 openSenseMap +Copyright (c) 2026 openSenseMap Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From e3af3e4a5617f996cab7c1407412d21e0a6accb3 Mon Sep 17 00:00:00 2001 From: jona159 Date: Mon, 4 May 2026 16:36:12 +0200 Subject: [PATCH 03/11] feat: improve hosted text --- app/components/landing/sections/partners.tsx | 2 +- public/locales/de/partners.json | 2 +- public/locales/en/partners.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/components/landing/sections/partners.tsx b/app/components/landing/sections/partners.tsx index d08657bd..1ad5fef4 100644 --- a/app/components/landing/sections/partners.tsx +++ b/app/components/landing/sections/partners.tsx @@ -61,7 +61,7 @@ export default function Partners({ data }: PartnersProps) { }} className="flex flex-col items-center justify-center" > -

{t('hosted')}

+

{t('made_by')}

openSenseLab Logo diff --git a/public/locales/de/partners.json b/public/locales/de/partners.json index 814a58a6..8c031cd1 100644 --- a/public/locales/de/partners.json +++ b/public/locales/de/partners.json @@ -1,4 +1,4 @@ { "Partners": "Partner", - "hosted": "gehostet von" + "made_by": "Made with love in Münster by" } diff --git a/public/locales/en/partners.json b/public/locales/en/partners.json index ae46368a..e87cc898 100644 --- a/public/locales/en/partners.json +++ b/public/locales/en/partners.json @@ -1,4 +1,4 @@ { "Partners": "Partners", - "hosted": "hosted by" + "made_by": "Made with love in Münster by" } From 65bcf0e42f103351b3556c28469dbb2b601e81e8 Mon Sep 17 00:00:00 2001 From: jona159 Date: Mon, 4 May 2026 16:52:20 +0200 Subject: [PATCH 04/11] fix: copyright year, twitter icon --- app/components/landing/footer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/components/landing/footer.tsx b/app/components/landing/footer.tsx index 281c5779..239a1e4c 100644 --- a/app/components/landing/footer.tsx +++ b/app/components/landing/footer.tsx @@ -10,7 +10,7 @@ export default function Footer() {
- © 2025{' '} + © 2026{' '} openSenseLab @@ -72,7 +72,7 @@ export default function Footer() { viewBox="0 0 24 24" aria-hidden="true" > - + {t('twitter')} From e9ff39075024fd720175abd43447284810520a63 Mon Sep 17 00:00:00 2001 From: jona159 Date: Mon, 4 May 2026 16:53:13 +0200 Subject: [PATCH 05/11] fix: translations --- public/locales/de/features.json | 2 -- public/locales/de/landing.json | 2 +- public/locales/en/features.json | 2 -- public/locales/en/landing.json | 2 +- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/public/locales/de/features.json b/public/locales/de/features.json index 95e7a34d..60b24e94 100644 --- a/public/locales/de/features.json +++ b/public/locales/de/features.json @@ -2,10 +2,8 @@ "features": "Features", "description": "Die openSenseMap-Plattform hat viel zu bieten, was die Auffindbarkeit und den Austausch von Umwelt- und Sensordaten einfach macht.", "dataAggregation": "Erfassung von Daten", - "noDataRetention": "Keine Datenrückhaltung", "dataPublished": "Veröffentlichung der Daten als ODbL", "discoverDevices": "Entdecke Geräte", - "compareDevices": "Vergleiche Geräte", "downloadOptions": "Downloadoptionen", "httpRestApi": "HTTP REST API" } diff --git a/public/locales/de/landing.json b/public/locales/de/landing.json index 6f24cec5..6acf3728 100644 --- a/public/locales/de/landing.json +++ b/public/locales/de/landing.json @@ -1,5 +1,5 @@ { "introduction": "Die wahrscheinlich größte offene Plattform für Umwelt- und Sensordaten weltweit ermöglicht es allen Menschen kostenfrei auf umfangreiche Daten zuzugreifen, diese zu analysieren und eigene Messungen zu veröffentlichen. Dadurch ist ein einzigartiger Datensatz mit Echtzeitdaten überall auf der Welt entstanden, der nachprüfbare lokale wie globale Fakten zu Umweltphänomenen wie dem Klimawandel liefert.", "donate": "Spenden", - "explore": "Erkunden" + "map": "Karte" } diff --git a/public/locales/en/features.json b/public/locales/en/features.json index dc363b89..cdd69cde 100644 --- a/public/locales/en/features.json +++ b/public/locales/en/features.json @@ -2,10 +2,8 @@ "features": "Features", "description": "The openSenseMap platform has a lot to offer that makes discoverability and sharing of environmental and sensor data easy.", "dataAggregation": "Data aggregation", - "noDataRetention": "No data retention", "dataPublished": "Data published as ODbL", "discoverDevices": "Discover devices", - "compareDevices": "Compare devices", "downloadOptions": "Download options", "httpRestApi": "HTTP REST API" } diff --git a/public/locales/en/landing.json b/public/locales/en/landing.json index e2a8b0f4..f06d5123 100644 --- a/public/locales/en/landing.json +++ b/public/locales/en/landing.json @@ -1,5 +1,5 @@ { "introduction": "Probably the largest open platform for environmental and sensor data in the world, it allows anyone to access extensive data free of charge, analyze it and publish their own measurements. This has created a unique dataset with real-time data all over the world, providing verifiable local as well as global facts on environmental phenomena such as climate change.", "donate": "Donate", - "explore": "Explore" + "map": "Map" } From 29dcfcbfabca294814380a6aace581794e8f911a Mon Sep 17 00:00:00 2001 From: jona159 Date: Mon, 4 May 2026 17:13:12 +0200 Subject: [PATCH 06/11] fix: openSenseLab logo --- app/components/landing/sections/partners.tsx | 2 +- public/img/openSenseLab_Logo.svg | 1 + public/img/openSenseLab_logo.png | Bin 16514 -> 0 bytes 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 public/img/openSenseLab_Logo.svg delete mode 100644 public/img/openSenseLab_logo.png diff --git a/app/components/landing/sections/partners.tsx b/app/components/landing/sections/partners.tsx index 1ad5fef4..9d228e42 100644 --- a/app/components/landing/sections/partners.tsx +++ b/app/components/landing/sections/partners.tsx @@ -62,7 +62,7 @@ export default function Partners({ data }: PartnersProps) { className="flex flex-col items-center justify-center" >

{t('made_by')}

- openSenseLab Logo + openSenseLab Logo
diff --git a/public/img/openSenseLab_Logo.svg b/public/img/openSenseLab_Logo.svg new file mode 100644 index 00000000..4b7424ad --- /dev/null +++ b/public/img/openSenseLab_Logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/openSenseLab_logo.png b/public/img/openSenseLab_logo.png deleted file mode 100644 index 01d3e42e70807f9b5d308e7bb79ac118d0004dfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16514 zcmaK!W02=g)bGc(ZSB~$ZQJ(j*w$}6JGQZ7+qP}n*0cXxw{G26&x<6TR4RSWNxG}Q z>GSDGMR^H$7#tWNARu@tNl|4WAYg@mWmPDMe|wP1CW3zlXh%sc7a$;5)c-bMpo}c6 ze;0vWlqH0Ls;BYJ{+)nX2+0Wn0oBF9ej0%T0SRJCi3+KD0AJ}r3Zji{?>Kw^p~1uJ ziU^=u9nvSM6H7|7BpDv;d^{}nKfCH0>|9LEN$VUWE9p!lp>V5%Ww(U_38FeWJ!;*) zY4&AV;Y7k^qVE3s<=Dc*!@|??kn2wfw$~d73WA3s97s7k+sQUL3gUz%a6`S;_ z`+g-T66{GTkzk;SX@&fIf-eMb$N)JwS=Nnxb(YeOsUNV&oFtrsWg0u{o|9t*#J_q( za)Bjy8JJ=T_{J;k@~-L2*-h)p!XFgkV3RgMzPrQ!nUFsNB*Lkyyci`KU|K-JE@=dU z5P|&9y2oFRgAWWKXfxj2-9&uZDbbN6#DVMJVEah-N`;yMsl@*rI91t&6UW5<;9iz$ zL9?H6o{i;v%`V1Pr$}7xVLw=y@++K;3RbIkqhrH5GU6o6x6``2yaNE>IQj!Y!}&qw zPdpQpl=Zj(F-mC+%FcWHJ!ozz8$jSy$Ll|KeDU#wD24)7$s=d1T#l_#y~s1s5to;?+SKv*q>kOc3?o5RlXs!dO^S_1kp6{0 zm+dvTxmm=$ps-3p4FCA}6~ZK2+Qud|%26LJ7bzU1fKt>c%ouy{tSE~jqewgPK!RN! zI(xoIx!l$QrWDL|-+OVRW<^s+oRlgmAFBWsRpMq`I%5o3;h)hYpEJk`3c79I@u~~T ze8uaEU9*NaSo)Ch(gg0DLfif>zg17G zWsl%c=V1j&KK4q+Gh@{+2%EUJW~B(kfQQVL0HJoMobref8n#*3T!+DbX_JNj3x?R9 zf0zdbD@Fus%5da}4#Jj^>sm<$-a8n^m5?2<)p5Fb@dcMUg(7Pdl#);sv+vjLZQ~Sa zVm)BgbAL*J8s%YJ2O*vAT2i4nz_397{){G�R8F77NAq>mxesO6>pE(ZBvZ)Q#BS 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 From 997b029528cb33ff94bf814f421637b8b5a964d7 Mon Sep 17 00:00:00 2001 From: jona159 Date: Mon, 4 May 2026 17:13:30 +0200 Subject: [PATCH 07/11] fix: rm scroll snapping --- app/routes/about.tsx | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/app/routes/about.tsx b/app/routes/about.tsx index be3d5d83..30f596b8 100644 --- a/app/routes/about.tsx +++ b/app/routes/about.tsx @@ -112,26 +112,9 @@ export default function Index() { const isDesktop = useMediaQuery('(min-width: 768px)') - /** - * Stupid workaround for chromium and webkit that both render double - * scroll bars when using scrollSnapType. - * Simply setting overflow hidden on the html element fixes it and - * the rest of the pages stay untouched from this. - */ - useEffect(() => { - document.documentElement.style.setProperty('overflow', 'hidden') - return () => { - document.documentElement.style.removeProperty('overflow') - } - }, []) - return (
@@ -140,11 +123,6 @@ export default function Index() {
@@ -233,22 +211,16 @@ export default function Index() { {sections.map((section, _index) => { const Component = section.component return ( -
-
+ ) })}