Skip to content

Commit e177d0b

Browse files
committed
feat: add English localization
1 parent ecae0db commit e177d0b

File tree

7 files changed

+202
-53
lines changed

7 files changed

+202
-53
lines changed

demo/demo.jsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import { Planimetrie } from '../src/element.jsx'
44
import '../src/element.scss'
55

66
const App = () => {
7-
return <Planimetrie />
7+
let lang = 'it'
8+
9+
const isEnglish = location.href.includes('/en')
10+
if (isEnglish) lang = 'en'
11+
return <Planimetrie lang={lang} />
812
}
913

1014
render(<App />, document.body)

src/components/Buttons.jsx

+23-21
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ import { useState } from 'preact/hooks'
33
import { clsx } from '../lib/utils.js'
44
import { GridAnimation } from './Animations.jsx'
55
import { toChildArray } from 'preact'
6-
7-
const FLOOR_LABELS = ['Piano Terra', '1° Piano', '2° Piano']
8-
const GROUP_LABELS = ['Edifici A e B', 'Edificio ex-Albergo']
6+
import { LocalizedString } from './LocalizedString.jsx'
97

108
const LayerFloor = ({ label, viewportName, cameraToViewpoint, data: { viewpoint } }) => {
119
return (
@@ -17,15 +15,20 @@ const LayerFloor = ({ label, viewportName, cameraToViewpoint, data: { viewpoint
1715
>
1816
<LuEye size={16} />
1917
</div>
20-
<div class="fix-text">{label}</div>
18+
<div class="fix-text">
19+
<LocalizedString name={label} />
20+
</div>
2121
</div>
2222
)
2323
}
2424

2525
const LayerGroup = ({ label, data: { floors }, viewportName, cameraToViewpoint }) => {
26+
const FLOOR_LABELS = ['ground-floor', 'first-floor', 'second-floor']
2627
return (
2728
<div class="layer">
28-
<div class="row">{label}</div>
29+
<div class="row">
30+
<LocalizedString name={label} />
31+
</div>
2932
<div class="children">
3033
{floors.map((floor, i) => (
3134
<LayerFloor
@@ -103,6 +106,8 @@ export const Buttons = ({ planimetriaRef, reset, layerToggles: { dip, exdma }, s
103106
})
104107
}
105108

109+
const GROUP_LABELS = ['building-a-b', 'building-exdma']
110+
106111
return (
107112
<div class="buttons">
108113
<CollapsibleIconPanel
@@ -111,10 +116,14 @@ export const Buttons = ({ planimetriaRef, reset, layerToggles: { dip, exdma }, s
111116
>
112117
<LuLayers />
113118
<div class="label">
114-
<div class="fix-text">Livelli</div>
119+
<div class="fix-text">
120+
<LocalizedString name="floors" />
121+
</div>
115122
</div>
116123
<div class="content">
117-
<div class="title">Dipartimento di Matematica</div>
124+
<div class="title">
125+
<LocalizedString name="dip" />
126+
</div>
118127
<LayerGroup
119128
label={GROUP_LABELS[0]}
120129
data={dip}
@@ -132,7 +141,9 @@ export const Buttons = ({ planimetriaRef, reset, layerToggles: { dip, exdma }, s
132141
<CollapsibleIconButton onClick={onResetView}>
133142
<LuHome />
134143
<div class="label">
135-
<div class="fix-text">Reimposta Vista</div>
144+
<div class="fix-text">
145+
<LocalizedString name="reset-view" />
146+
</div>
136147
</div>
137148
</CollapsibleIconButton>
138149
<CollapsibleIconPanel
@@ -144,19 +155,10 @@ export const Buttons = ({ planimetriaRef, reset, layerToggles: { dip, exdma }, s
144155
<div class="fix-text">Help</div>
145156
</div>
146157
<div class="content">
147-
<div class="title">Come navigare la mappa</div>
148-
<ul>
149-
<li>Per spostare la mappa, trascina con il mouse o con un dito.</li>
150-
<li>Per zoomare, usa la rotellina del mouse o i gesti di pinch-to-zoom.</li>
151-
<li>Per ruotare, clicca e trascina con il tasto destro del mouse o con due dita.</li>
152-
<li>
153-
Per selezionare un piano, clicca sull'icona dell'occhio corrispondente dentro il
154-
pannello <LuLayers />.
155-
</li>
156-
<li>
157-
Per tornare alla vista iniziale, clicca su <LuHome />.
158-
</li>
159-
</ul>
158+
<div class="title">
159+
<LocalizedString name="help-title" />
160+
</div>
161+
<LocalizedString name="help-content" />
160162
</div>
161163
</CollapsibleIconPanel>
162164
</div>

src/components/LocalizedString.jsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { createContext } from 'preact'
2+
import { useContext } from 'preact/hooks'
3+
import i18n from '../i18n'
4+
5+
export const LangContext = createContext('it')
6+
7+
export const useLocalization = name => {
8+
const lang = useContext(LangContext)
9+
return i18n[name][lang]
10+
}
11+
12+
export const LocalizedString = ({ name }) => {
13+
const lang = useContext(LangContext)
14+
return <>{i18n[name][lang]}</>
15+
}

src/components/Search.jsx

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { LuSearch } from 'react-icons/lu'
22
import { clsx } from '../lib/utils.js'
33
import { useEventCallback, useFuse } from '../lib/hooks.js'
4+
import { useContext } from 'preact/hooks'
5+
import { LangContext, LocalizedString, useLocalization } from './LocalizedString.jsx'
6+
import i18n from '../i18n.jsx'
47

58
const HighlightedText = ({ indices, value }) => {
69
if (!indices) {
@@ -37,11 +40,13 @@ export const Search = ({ rooms, selectId, ...rest }) => {
3740
if (e.key === 'Escape') setQuery('')
3841
})
3942

43+
const searchPlaceholder = useLocalization('search-placeholder')
44+
4045
return (
4146
<div class={clsx('search', rest?.class)}>
4247
<div class="search-field">
4348
<input
44-
placeholder="Cerca il codice di una stanza o un professore..."
49+
placeholder={searchPlaceholder}
4550
type="text"
4651
value={query}
4752
onInput={e => setQuery(e.target.value)}
@@ -85,7 +90,9 @@ export const Search = ({ rooms, selectId, ...rest }) => {
8590
</div>
8691
) : (
8792
<div class="search-results">
88-
<div class="no-result">Nessun risultato...</div>
93+
<div class="no-result">
94+
<LocalizedString name="no-result" />
95+
</div>
8996
</div>
9097
))}
9198
</div>

src/components/Sidebar.jsx

+29-19
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,49 @@
11
import { clsx } from '../lib/utils.js'
2-
3-
const SIDEBAR_LABELS = {
4-
buildings: {
5-
['A']: 'Edificio A',
6-
['B']: 'Edificio B',
7-
['X']: 'Ex-Albergo',
8-
},
9-
floors: {
10-
['0']: 'Piano terra',
11-
['1']: 'Primo piano',
12-
['2']: 'Secondo Piano',
13-
},
14-
}
2+
import { LocalizedString } from './LocalizedString.jsx'
153

164
export const Sidebar = ({ rooms, ...rest }) => {
5+
const SIDEBAR_LABELS = {
6+
buildings: {
7+
['A']: 'building-a',
8+
['B']: 'building-b',
9+
['X']: 'building-x',
10+
},
11+
floors: {
12+
['0']: 'ground-floor',
13+
['1']: 'first-floor',
14+
['2']: 'second-floor',
15+
},
16+
}
1717
return (
1818
<div class={clsx('sidebar', rest?.class)}>
1919
{rooms.map(room => (
2020
<div class="room">
21-
<h2>Stanza "{room.number}"</h2>
21+
<h2>
22+
<LocalizedString name="room" /> "{room.number}"
23+
</h2>
2224
<h3>
23-
{SIDEBAR_LABELS.buildings[room.building] ?? 'Ignoto'},{' '}
24-
{SIDEBAR_LABELS.floors[room.floor] ?? 'Ignoto'}
25+
<LocalizedString name={SIDEBAR_LABELS.buildings[room.building] ?? 'unknown'} />,{' '}
26+
<LocalizedString name={SIDEBAR_LABELS.floors[room.floor] ?? 'unknown'} />
2527
</h3>
2628
<p>
27-
<strong>Codice:</strong> <code>{room.code}</code>
29+
<strong>
30+
<LocalizedString name="code" />:
31+
</strong>{' '}
32+
<code>{room.code}</code>
2833
</p>
2934
{room.notes && (
3035
<p>
31-
<strong>Note:</strong> {room.notes}
36+
<strong>
37+
<LocalizedString name="notes" />:
38+
</strong>{' '}
39+
{room.notes}
3240
</p>
3341
)}
3442
{room.roomAssignments.length > 0 && (
3543
<>
36-
<h3>Assegnazioni</h3>
44+
<h3>
45+
<LocalizedString name="assignments" />
46+
</h3>
3747
<ul>
3848
{room.roomAssignments.map(assignment => (
3949
<li>

src/element.jsx

+13-10
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import { PlanimetrieViewer } from './dm-planimetrie/PlanimetrieViewer.js'
55
import styles from './element.scss?inline'
66

77
import { useEffect, useRef, useState } from 'preact/hooks'
8-
import { Sets, clsx } from './lib/utils.js'
8+
import { clsx } from './lib/utils.js'
99
import { useEventCallback, useToggle, useToggleRegion } from './lib/hooks.js'
1010
import { createApiProxy } from './lib/mapper.js'
1111
import { render } from 'preact'
1212
import { Search } from './components/Search.jsx'
1313
import { Sidebar } from './components/Sidebar.jsx'
1414
import { Buttons } from './components/Buttons.jsx'
15+
import { LangContext } from './components/LocalizedString.jsx'
1516

1617
const Canvas3D = memo(({ planimetrieRef }) => {
1718
const canvasRef = useRef(null)
@@ -58,7 +59,7 @@ const loadRooms = async () => {
5859
.filter(room => room.polygon)
5960
}
6061

61-
export const Planimetrie = ({ selectedRoom }) => {
62+
export const Planimetrie = ({ selectedRoom, lang }) => {
6263
const [rooms, setRooms] = useState([])
6364
const [selection, setSelection] = useState(selectedRoom ?? null)
6465

@@ -128,19 +129,17 @@ export const Planimetrie = ({ selectedRoom }) => {
128129
const room = rooms.find(({ _id }) => _id === id)
129130

130131
if (room.building === 'A' || room.building === 'B') {
131-
// setDipVisible(true)
132132
layerSetters[`dm-floor-${room.floor}`](true)
133133
}
134134
if (room.building === 'X') {
135-
// setExdmaVisible(true)
136135
layerSetters[`exdma-floor-${room.floor}`](true)
137136
}
138137

139138
setSelection(id)
140139
}
141140

142141
return (
143-
<>
142+
<LangContext.Provider value={lang}>
144143
<div class="dm-planimetrie">
145144
<Canvas3D planimetrieRef={planimetrieRef} />
146145
<div class="overlay">
@@ -209,7 +208,7 @@ export const Planimetrie = ({ selectedRoom }) => {
209208
/>
210209
</div>
211210
</div>
212-
</>
211+
</LangContext.Provider>
213212
)
214213
}
215214

@@ -223,6 +222,7 @@ export class PlanimetrieElement extends HTMLElement {
223222
this.style.display = 'block'
224223
this.style.height = '720px'
225224
this.style.maxHeight = '100%'
225+
this.lang = 'it'
226226

227227
this.attachShadow({ mode: 'open' })
228228

@@ -240,21 +240,24 @@ export class PlanimetrieElement extends HTMLElement {
240240
const url = new URL(location.href)
241241
const initialSelection = url.searchParams.get('sel')
242242

243+
const isEnglish = location.href.includes('/en')
244+
if (isEnglish) this.lang = 'en'
245+
243246
console.log('Initial Room Selection:', initialSelection)
244247

245-
this.#render({ selectedId: initialSelection })
248+
this.#render({ selectedId: initialSelection, lang: this.lang })
246249
}
247250

248-
#render({ selectedId }) {
249-
render(<Planimetrie selectedRoom={selectedId} />, this.shadowRoot)
251+
#render({ selectedId, lang }) {
252+
render(<Planimetrie selectedRoom={selectedId} lang={lang} />, this.shadowRoot)
250253
}
251254

252255
/**
253256
* @param {string[]} selectedId
254257
* @returns {void}
255258
*/
256259
setSelection(selectedId) {
257-
this.#render({ selectedId })
260+
this.#render({ selectedId, lang: this.lang })
258261
}
259262
}
260263

0 commit comments

Comments
 (0)