Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Localization support for About and Dashboard #95

Merged
merged 7 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"dayjs": "^1.11.9",
"geolib": "^3.3.3",
"http-proxy-middleware": "^2.0.6",
"i18next": "^23.5.1",
"leaflet": "^1.8.0",
"lodash.debounce": "^4.0.8",
"moment": "^2.29.4",
Expand All @@ -23,6 +24,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-ga4": "^2.1.0",
"react-i18next": "^13.2.2",
"react-leaflet": "^4.0.1",
"react-leaflet-cluster": "^2.1.0",
"react-router-dom": "^6.6.1",
Expand Down
20 changes: 10 additions & 10 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import './App.scss'
import TimelinePage from 'src/pages/TimelinePage'
import { ConfigProvider, Layout } from 'antd'
import 'leaflet/dist/leaflet.css'
import { TEXTS } from 'src/resources/texts'
import { TEXT_KEYS } from 'src/resources/texts'
import styled from 'styled-components'
import heIL from 'antd/es/locale/he_IL'
import { BrowserRouter as Router, Navigate, Route, Routes, useSearchParams } from 'react-router-dom'
Expand Down Expand Up @@ -46,42 +46,42 @@ const StyledBody = styled.div`

const PAGES = [
{
label: TEXTS.dashboard_page_title,
label: TEXT_KEYS.dashboard_page_title,
key: '/dashboard',
},
{
label: TEXTS.timeline_page_title,
label: TEXT_KEYS.timeline_page_title,
key: '/timeline',
searchParamsRequired: true,
},
{
label: TEXTS.gaps_page_title,
label: TEXT_KEYS.gaps_page_title,
key: '/gaps',
searchParamsRequired: true,
},
{
label: TEXTS.gaps_patterns_page_title,
label: TEXT_KEYS.gaps_patterns_page_title,
key: '/gaps_patterns',
},
{
label: TEXTS.realtime_map_page_title,
label: TEXT_KEYS.realtime_map_page_title,
key: '/map',
},
{
label: TEXTS.singleline_map_page_title,
label: TEXT_KEYS.singleline_map_page_title,
key: '/single-line-map',
searchParamsRequired: true,
},
{
label: TEXTS.about_title,
label: TEXT_KEYS.about_title,
key: '/about',
},
{
label: TEXTS.report_a_bug_title,
label: TEXT_KEYS.report_a_bug_title,
key: 'https://github.com/hasadna/open-bus-map-search/issues',
},
{
label: TEXTS.donate_title,
label: TEXT_KEYS.donate_title,
key: 'https://www.jgive.com/new/he/ils/donation-targets/3268#donation-modal',
},
]
Expand Down
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
import ReactGA from 'react-ga4'
import './locale/allTranslations'

ReactGA.initialize('G-0YRQT80GG1')

Expand Down
20 changes: 20 additions & 0 deletions src/locale/allTranslations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import translationsEN from './en.json'
import translationsHE from './he.json'

i18n.use(initReactI18next).init({
resources: {
he: {
translation: translationsHE,
},
en: {
translation: translationsEN,
},
},

// Default Language
lng: 'he',
})

export default i18n
71 changes: 71 additions & 0 deletions src/locale/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"realtime_map_explanation": "Location data of buses collected in real time",
"timeline_page_title": "Historical timeline",
"realtime_map_page_title": "Real time map",
"gaps_page_title": "Trips that didn't take place",
"singleline_map_page_title": "Map by line",
"choose_datetime": "Date and time",
"choose_date": "Date",
"choose_time": "Time",
"choose_operator": "Operating Company",
"operator_placeholder": "For example: Dan",
"choose_line": "line number",
"line_placeholder": "For example: 17a",
"choose_route": "Choosing a travel route (XXX options)",
"choose_stop": "Select a station (XXX options)",
"direction_arrow": "⟵",
"date_format": "YYYY-MM-DD",
"time_format": "HH:mm:ss",
"datetime_format": "HH:mm:ss · YYYY-MM-DD",
"loading_routes": "Charging routes",
"loading_stops": "Charging stop stations",
"loading_gaps": "Charging trip gaps",
"timestamp_target": "⌚ Search time",
"timestamp_gtfs": "🕛 Planned stop time",
"timestamp_siri": "🚌 Actual stop time",
"loading_hits": "Charging travel times",
"line_not_found": "The line is not found",
"hits_not_found": "No planned or actual trips found",
"planned_time": "Scheduled time",
"planned_status": "status",
"ride_as_planned": "✔️ came out as planned",
"ride_missing": "❌ missing ride",
"ride_extra": "🧐 An unplanned trip",
"ride_duped": "❇️ Double ride",
"checkbox_only_gaps": "Only gaps",
"dashboard_page_title": "Public transport operators according to planned trips",
"dashboard_tooltip_content": "A GPS is attached to every line in Israel that reports the location of the bus every few moments.\nSo what is a missed trip? This is a trip that was planned, but was not reported to have taken place in the GPS data. You can see it in the app for example, but when you wait at the station, it will never arrive",
"worst_lines_page_title": "The worst lines of the 5 major operators",
"rides_planned": "planned trips",
"rides_actual": "Trips out",
"dashboard_page_graph_title": "Exit percentages of total trips by time",
"from_date": "dated",
"to_date": "Until",
"watch_locations_in_range": "View bus locations within a range of",
"minutes": "דקות",
"minutes_5": "5 דקות",
"show_x_bus_locations": "Bus locations",
"from_time_x_to_time_y": "From XXX to YYY",
"choose_start_time": "Select a start time",
"group_by_hour_tooltip_content": "Kibbutz by hour",
"start": "start",
"end": "end",
"about_title": "About",
"donate_title": "For Donations",
"report_a_bug_title": "Report a bug",
"website_name": "Database",
"what_is_website": "What is the \"Databus\" site?",
"what_is_website_paragraph": "The database website of the workshop for public knowledge presents data on the quality of public transportation lines in Israel (reliability, accuracy, route). Databus actually connects several government information sources:",
"planning_information": "The planning information - GTFS - which is published every day and contains the details of the lines, station locations, transit times, etc.",
"performance_information": "Performance information - SIRI - Every bus in Israel is attached to a GPS transmitter that reports the location of the bus every few seconds.",
"discovered_mistake": "We discovered an error or outdated information, what do we do?",
"discovered_mistake_paragraph": "Since all the information presented on the site is based on the official sources of information, it is recommended to contact the publisher for clarification or correction of the problem. The \"Databus\" team will be happy to help you understand who the government entity is that published the data or information that requires clarification or correction.",
"privacy": "privacy",
"license": "User license",
"questions": "Questions? Comments? ideas?",
"funding": "Funding",
"mr_meir": "Mr. Asher Meir",
"innovation_authority": "Innovation Authority",
"migdal_company": "\"A tower in the community\"",
"and_smaller_donors": "And other small contributions from my friends and fans of the workshop."
}
71 changes: 71 additions & 0 deletions src/locale/he.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"realtime_map_explanation": "נתוני מיקום של אוטובוסים שנאספו בזמן אמת",
"timeline_page_title": "לוח זמנים היסטורי",
"realtime_map_page_title": "מפה בזמן אמת",
"gaps_page_title": "נסיעות שלא יצאו",
"singleline_map_page_title": "מפה לפי קו",
"choose_datetime": "תאריך ושעה",
"choose_date": "תאריך",
"choose_time": "שעה",
"choose_operator": "חברה מפעילה",
"operator_placeholder": "לדוגמא: דן",
"choose_line": "מספר קו",
"line_placeholder": "לדוגמא: 17א",
"choose_route": "בחירת מסלול נסיעה (XXX אפשרויות)",
"choose_stop": "בחירת תחנה (XXX אפשרויות)",
"direction_arrow": "⟵",
"date_format": "YYYY-MM-DD",
"time_format": "HH:mm:ss",
"datetime_format": "HH:mm:ss · YYYY-MM-DD",
"loading_routes": "מסלולי נסיעה בטעינה",
"loading_stops": "תחנות עצירה בטעינה",
"loading_gaps": "פערי נסיעות בטעינה",
"timestamp_target": "זמן החיפוש ⌚",
"timestamp_gtfs": "זמן עצירה מתוכנן 🕛",
"timestamp_siri": "זמן עצירה בפועל 🚌",
"loading_hits": "זמני נסיעה בטעינה",
"line_not_found": "הקו לא נמצא",
"hits_not_found": "לא נמצאו נסיעות מתוכננות או בפועל",
"planned_time": "שעה מתוכננת",
"planned_status": "סטטוס",
"ride_as_planned": "יצאה כמתוכנן ✔️",
"ride_missing": "נסיעה חסרה ❌",
"ride_extra": "נסיעה שלא תוכננה 🧐",
"ride_duped": "נסיעה כפולה ❇️",
"checkbox_only_gaps": "רק פערים",
"dashboard_page_title": "מפעילי תח\"צ לפי קיום נסיעות מתוכננות",
"dashboard_tooltip_content": "על כל קו בישראל מוצמד GPS שמדווח את מיקום האוטובוס כל כמה רגעים.\nאז מה היא נסיעה שלא בוצעה? זאת נסיעה שתוכננה, אבל לא דווח שיצאה בנתוני הGPS. תוכלו לראות אותה באפליקציה למשל, אבל כשתחכו בתחנה, היא לעולם לא תגיע",
"worst_lines_page_title": "הקווים הגרועים ביותר של 5 המפעילות הגדולות",
"rides_planned": "נסיעות שתוכננו",
"rides_actual": "נסיעות שיצאו",
"dashboard_page_graph_title": "אחוזי יציאה מסך הנסיעות לפי זמן",
"from_date": "מתאריך",
"to_date": "עד תאריך",
"watch_locations_in_range": "צפה במיקומי אוטובוסים בטווח של",
"minutes": "דקות",
"minutes_5": "5 דקות",
"show_x_bus_locations": "מיקומי אוטובוסים",
"from_time_x_to_time_y": "משעה XXX עד שעה YYY",
"choose_start_time": "בחירת שעת התחלה",
"group_by_hour_tooltip_content": "קיבוץ לפי שעה",
"start": "התחלה",
"end": "סיום",
"about_title": "אודות",
"donate_title": "לתרומות",
"report_a_bug_title": "דיווח על באג",
"website_name": "דאטאבוס",
"what_is_website": "מהו אתר “דאטאבוס”?",
"what_is_website_paragraph": "אתר דאטאבוס של הסדנא לידע ציבורי מציג נתונים על איכות קווי התחבורה הציבורית בארץ (אמינות, דיוק, מסלול). דאטאבוס מחבר למעשה בין מספר מקורות מידע ממשלתיים:",
"planning_information": "מידע התכנון - GTFS - המפורסם כל יום ומכיל את פרטי הקווים, מיקומי התחנות, שעות המעבר בהן וכו'.",
"performance_information": "מידע הביצוע - SIRI - לכל אוטובוס בישראל מוצמד משדר GPS שמדווח את מיקום האוטובוס כל כמה שניות.",
"discovered_mistake": "גילינו טעות או מידע לא מעודכן, מה עושים?",
"discovered_mistake_paragraph": "מכיוון שכל המידע המוצג באתר מתבסס על מקורות המידע הרשמיים, מומלץ לפנות לגורם המפרסם לצורך בירור או תיקון הבעיה. צוות “דאטאבוס“ ישמח לסייע לכם להבין מיהו הגורם הממשלתי שפרסם את הנתון או המידע שדורשים בירור או תיקון.",
"privacy": "פרטיות",
"license": "רשיון שימוש",
"questions": "שאלות? תגובות? רעיונות?",
"funding": "מימון",
"mr_meir": "מר אשר מאיר",
"innovation_authority": "רשות החדשנות",
"migdal_company": "“מגדל בקהילה“",
"and_smaller_donors": "ותרומות קטנות נוספות של ידידי ואוהדי הסדנא."
}
49 changes: 32 additions & 17 deletions src/pages/About.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import styled from 'styled-components'
import React from 'react'
import { TEXTS } from 'src/resources/texts'
import { TEXT_KEYS } from 'src/resources/texts'
import SlackIcon from '../resources/slack-icon.svg'
import { useTranslation } from 'react-i18next'

const About = () => {
const { t } = useTranslation()

return (
<AboutStyle>
<div className="about-center-container">
<h1>{TEXTS.website_name}</h1>
<h1>{t(TEXT_KEYS.website_name)}</h1>
<WhatIsWebsite />
<DiscoveredMistake />
<Privacy />
Expand All @@ -20,31 +23,37 @@ const About = () => {
}

const WhatIsWebsite = () => {
const { t } = useTranslation()

return (
<ParagraphStyle>
<h2>{TEXTS.what_is_website}</h2>
<p>{TEXTS.what_is_website_paragraph}</p>
<h2>{t(TEXT_KEYS.what_is_website)}</h2>
<p>{t(TEXT_KEYS.what_is_website_paragraph)}</p>
<ul style={{ listStyle: 'disc', paddingRight: '40px' }}>
<li>{TEXTS.planning_information}</li>
<li>{TEXTS.performance_information}</li>
<li>{t(TEXT_KEYS.planning_information)}</li>
<li>{t(TEXT_KEYS.performance_information)}</li>
</ul>
</ParagraphStyle>
)
}

const DiscoveredMistake = () => {
const { t } = useTranslation()

return (
<ParagraphStyle>
<h2>{TEXTS.discovered_mistake}</h2>
<p>{TEXTS.discovered_mistake_paragraph}</p>
<h2>{t(TEXT_KEYS.discovered_mistake)}</h2>
<p>{t(TEXT_KEYS.discovered_mistake_paragraph)}</p>
</ParagraphStyle>
)
}

const Privacy = () => {
const { t } = useTranslation()

return (
<ParagraphStyle>
<h2>{TEXTS.privacy}</h2>
<h2>{t(TEXT_KEYS.privacy)}</h2>
<p>
באתר מוטמע שירות{' '}
<a href="https://marketingplatform.google.com/about/analytics/">Google Analytics </a>
Expand All @@ -58,9 +67,11 @@ const Privacy = () => {
}

const License = () => {
const { t } = useTranslation()

return (
<ParagraphStyle>
<h2>{TEXTS.license}</h2>
<h2>{t(TEXT_KEYS.license)}</h2>
<p>
כל המידע המוצג באתר מבוסס על נתונים המפורסמים במקורות המידע הממשלתיים. השימוש במידע כפוף ל
<a href="https://creativecommons.org/licenses/by-sa/4.0/">רישיון CC BY-SA 4.0 </a>
Expand All @@ -72,9 +83,11 @@ const License = () => {
}

const Questions = () => {
const { t } = useTranslation()

return (
<ParagraphStyle>
<h2>{TEXTS.questions}</h2>
<h2>{t(TEXT_KEYS.questions)}</h2>
<ul>
<li>
<a href="https://www.hasadna.org.il/%D7%A6%D7%95%D7%A8-%D7%A7%D7%A9%D7%A8/">
Expand All @@ -98,17 +111,19 @@ const Questions = () => {
}

const Funding = () => {
const { t } = useTranslation()

return (
<ParagraphStyle>
<h2>{TEXTS.funding}</h2>
<p>{TEXTS.funding_paragraph}</p>
<h2>{t(TEXT_KEYS.funding)}</h2>
<p>{t(TEXT_KEYS.funding_paragraph)}</p>
<ul>
<li>{TEXTS.mr_meir}</li>
<li>{TEXTS.innovation_authority}</li>
<li>{TEXTS.migdal_company}</li>
<li>{t(TEXT_KEYS.mr_meir)}</li>
<li>{t(TEXT_KEYS.innovation_authority)}</li>
<li>{t(TEXT_KEYS.migdal_company)}</li>
<li>
<a href="https://www.jgive.com/new/he/ils/donation-targets/3268#donation-modal">
{TEXTS.and_smaller_donors}
{t(TEXT_KEYS.and_smaller_donors)}
</a>
</li>
</ul>
Expand Down
Loading
Loading