diff --git a/components/contexts/FactoryProvider/index.tsx b/components/contexts/FactoryProvider/index.tsx index 0bd05bf..5637237 100644 --- a/components/contexts/FactoryProvider/index.tsx +++ b/components/contexts/FactoryProvider/index.tsx @@ -35,20 +35,21 @@ export const FactoryProvider: FC = ({ children }) => { const locale = useLocale() const internationalizedFactories = useMemo(() => { if (locale !== 'en') - factories.map( - factory => (factory.name = factoryNames[locale]?.[factory.href] ?? factory.name) - ) + return factories.map(factory => ({ + ...factory, + name: factoryNames[locale]?.[factory.href] ?? factory.name + })) return factories }, [locale]) const findFactory = useMemo(() => { const detailsMap = Object.fromEntries( - factories.map((detail: EnrichedEntity) => [detail.href, detail]) + internationalizedFactories.map((detail: EnrichedEntity) => [detail.href, detail]) ) return (uid: string): EnrichedEntity | undefined => { return detailsMap[uid] } - }, []) + }, [internationalizedFactories]) const value: FactoryContextType = useMemo( () => ({ diff --git a/components/home/GroupBox/GroupBox.tsx b/components/home/GroupBox/GroupBox.tsx index 909811e..123b24c 100644 --- a/components/home/GroupBox/GroupBox.tsx +++ b/components/home/GroupBox/GroupBox.tsx @@ -9,12 +9,15 @@ import { fixedEncodeURIComponent, uniquify } from '../../../src/utils' import Link from 'next/link' import { useRouter } from 'next/router' import { useFactories } from '../../contexts/FactoryProvider' +import { i18n, I18n } from '../../shared/I18n/I18n' +import { useIntl } from 'react-intl' interface Props { group: Group } const GroupBoxBase: FC = ({ group }) => { + const intl = useIntl() const { query } = useRouter() const { factories, findFactory } = useFactories() const { @@ -99,19 +102,25 @@ const GroupBoxBase: FC = ({ group }) => { onClick={() => (!isDeleteConfirm ? setDeleteConfirm(true) : removeGroup(name))} style={{ display: 'block' }} > - {isDeleteConfirm ? 'Delete GroupBox?' : 'X'} + {isDeleteConfirm ? i18n(intl, 'page.home.group.delete.confirmation') : 'X'} -

Exported Factories

+

+ +

-

Mall Factories

+

+ +

{inputs.length ? ( <> -

Input Factories ({inputs.length})

+

+ ({inputs.length}) +

{inputs.map(input => ( = ({ group }) => { ) : null} {intermediates.length ? ( <> -

Intermediate Factories ({intermediates.length})

+

+ ({intermediates.length}) +

{intermediates.map(intermediate => ( = ({ group }) => { ) : null} {suggestionsExport.length ? ( <> -

Suggestions (Export)

+

+ +

{suggestionsExport.map(suggestion => ( = ({ group }) => { ) : null} {suggestionMall.length ? ( <> -

Suggestions (Mall)

+

+ +

{suggestionMall.map(suggestion => ( {

+

+ +

diff --git a/components/shared/I18n/I18n.tsx b/components/shared/I18n/I18n.tsx index afae3a4..0d028ef 100644 --- a/components/shared/I18n/I18n.tsx +++ b/components/shared/I18n/I18n.tsx @@ -1,11 +1,20 @@ -import { FC } from 'react' -import { FormattedMessage } from 'react-intl' +import { ComponentProps, FC } from 'react' +import { FormattedMessage, IntlShape } from 'react-intl' import { useMessages } from '../../../src/i18n' +import { FormatXMLElementFn, PrimitiveType } from 'intl-messageformat' -interface Props { +interface Props extends ComponentProps { id: keyof ReturnType['en'] } -export const I18n: FC = ({ id }) => { - return +export const I18n: FC = ({ children, ...props }) => { + return {children} +} + +export const i18n = ( + intl: IntlShape, + id: keyof ReturnType['en'], + values?: Record> +) => { + return intl.formatMessage({ id }, values, { ignoreTag: true }) } diff --git a/next.config.js b/next.config.js index 42c777a..3f4e395 100644 --- a/next.config.js +++ b/next.config.js @@ -19,7 +19,8 @@ const nextConfig = { }, i18n: { locales: ['en', 'de', 'nl'], - defaultLocale: 'en' + defaultLocale: 'en', + localeDetection: false } } diff --git a/pages/_document.tsx b/pages/_document.tsx new file mode 100644 index 0000000..f357176 --- /dev/null +++ b/pages/_document.tsx @@ -0,0 +1,22 @@ +import { DocumentProps, Head, Html, Main, NextScript } from 'next/document' +import { IntlProvider } from 'react-intl' +import { useMessages } from '../src/i18n' +import { FC } from 'react' + +const MyDocument: FC = ({ locale: _locale }) => { + const messages = useMessages() + const locale = _locale ?? '' in messages ? (_locale as keyof typeof messages) : 'en' + return ( + + + + +
+ + + + + ) +} + +export default MyDocument diff --git a/pages/index.tsx b/pages/index.tsx index 330b073..37fd1ee 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,15 +1,18 @@ import type { NextPage } from 'next' -import Head from 'next/head' import { Home } from '../components/home/Home' import { GroupProvider } from '../components/contexts/GroupProvider' import { getServerSidePropsGroupProvider, PropsGroupProvider } from '../src/getServerSideProps' +import Head from 'next/head' +import { useIntl } from 'react-intl' +import { i18n } from '../components/shared/I18n/I18n' const Page: NextPage = ({ id, ...initial }) => { + const intl = useIntl() return ( - Factorio Microservices - + {i18n(intl, 'page.home.head.title')} + diff --git a/res/i18n/de.json b/res/i18n/de.json index f1b04d3..c0bcdee 100644 --- a/res/i18n/de.json +++ b/res/i18n/de.json @@ -1,3 +1,25 @@ { - "page.home.title": "Factorio-Microservices" + "page.home.head.title": "Factorio Mikroservices", + "page.home.head.meta.description": "Fasse Factorio Fabriken zu Microservices zusammen", + "page.home.title": "Factorio Mikroservices", + "page.home.description": "Auf dieser Seite kannst du alle Einstellungen vornehmen. Gruppiere alle Fabriken zu Microservices zusammen. Ein Microservice ist eine Ansammlung bestimmter Montagemaschinen und anderen Fertigungen, die sich Eingaben (durch Züge) teilen. Optimale Gruppen sollten daher nur wenige Eingaben haben und viele Gegenstände produzieren. \"Exportierte Fabriken\" sind Ausgaben, die z.B. mit Zügen abgeholt, und für andere Services als Eingabe zu Verfügung stehen. \"Mall-Fabriken\" stellen mit Anbieterkisten die Waren zur Abholung durch den Spieler oder Roboter zur Verfügung. Die benötigten Eingabe-und Zwischenfabriken werden automatisch berechnet.", + "page.home.pref.basic.title": "Grundlegende Waren", + "page.home.pref.basic.description": "Grundlegende Waren können nicht in Fabriken hergestellt werden. Es kann sinnvoll sein hier z.B. Eisenplatten hinzuzufügen, wenn jene direkt beim Erz hergestellt werden.", + "page.home.pref.ignored.title": "Ignorierte Waren", + "page.home.pref.ignored.description": "Waren, die in in der Mall hergestellt werden sollen (z.B. Befeuerter Greifarm, weil es nicht benötigt wird) und auch nicht zwischen den Mikroservices exportiert werden sollen (z.B. Zahnräder, weil die bei Bedarf in der Fabrik selbst als Zwischenprodukt hergestellt wird).", + "page.home.group.add.title": "Neue Gruppe hinzufügen", + "page.home.group.add.default_group_name": "Neue Gruppe", + "page.home.group.add.button_text": "Gruppe \"{name}\" hinzufügen", + "page.home.group.missing.export.title": "Fehlende Export-Fabriken", + "page.home.group.missing.export.description": "Eine Auflistung aller Waren, die keine grundlegenden oder ignorierten Waren sind, und bei noch keiner Gruppe exportiert werden oder als Mall-Fabrik hinzugefügt wurden. Nur in dieser Liste falls von mindestens 3 anderen Waren verwendet.", + "page.home.group.missing.mall.title": "Fehlende Mall-Fabriken", + "page.home.group.missing.mall.description": "Eine Auflistung aller Waren, die keine grundlegenden oder ignorierten Waren sind, und bei noch keiner Gruppe exportiert werden oder als Mall-Fabrik hinzugefügt wurden. Nur in dieser Liste falls von maximal 2 anderen Waren verwendet.", + "page.home.group.missing.none": "Alle Fabriken hinzugefügt!", + "page.home.group.item.export": "Exportierte Waren", + "page.home.group.item.mall": "Waren für die Mall", + "page.home.group.item.input": "Angelieferte Waren", + "page.home.group.item.intermediate": "Zwischenprodukte", + "page.home.group.item.suggestion.export": "Empfohlene Exportwaren", + "page.home.group.item.suggestion.mall": "Empfohlene Mall-Fabriken", + "page.home.group.delete.confirmation": "Gruppe unwiderruflich löschen?" } diff --git a/res/i18n/en.json b/res/i18n/en.json index 9c9fa95..df7fc75 100644 --- a/res/i18n/en.json +++ b/res/i18n/en.json @@ -1,6 +1,25 @@ { - "page.home.head.title": "Next.js i18n example", - "page.home.head.meta.description": "Next.js i18n example - English", + "page.home.head.title": "Factorio Microservices", + "page.home.head.meta.description": "Group Factorio factories together into microservices", "page.home.title": "Factorio Microservices", - "page.home.description": "You are currently viewing the homepage in English 🚀" + "page.home.description": "On this page you can make all settings. Group all factories into microservices. A microservice is a collection of certain assembly machines and other fabrications that share inputs (through trains). Optimal groups should therefore have few inputs and produce many items. \"Exported factories\" are outputs that are picked up by trains, for example, and available to other services as inputs. \"Mall factories\" use vendor crates to make goods available for pickup by the player or robot. The required input and intermediate factories are calculated automatically.", + "page.home.pref.basic.title": "Basic goods", + "page.home.pref.basic.description": "Basic goods cannot be produced in factories. It may make sense to add iron plates here, for example, if they are produced directly at the ore.", + "page.home.pref.ignored.title": "Ignored goods", + "page.home.pref.ignored.description": "Goods that are to be manufactured in in the mall (e.g., burner inserter because it is not needed) and also are not to be exported between microservices (e.g., gears because that is manufactured in the factory itself as an intermediate product when needed).", + "page.home.group.add.title": "Add a new group", + "page.home.group.add.default_group_name": "New Group", + "page.home.group.add.button_text": "Add group \"{name}\"", + "page.home.group.missing.export.title": "Missing export factories", + "page.home.group.missing.export.description": "A listing of all goods that are not basic or ignored goods, and are not yet exported at any group or added as a mall factory. Only in this list if used by at least 3 other goods.", + "page.home.group.missing.mall.title": "Missing mall factories", + "page.home.group.missing.mall.description": "A listing of all goods that are not basic or ignored goods, and are not yet exported at any group or added as a mall factory. Only in this list if used by a maximum of 2 other goods.", + "page.home.group.missing.none": "All factories added!", + "page.home.group.item.export": "Exported goods", + "page.home.group.item.mall": "Mall goods", + "page.home.group.item.input": "Input goods", + "page.home.group.item.intermediate": "Intermediate factories", + "page.home.group.item.suggestion.export": "Suggested export goods", + "page.home.group.item.suggestion.mall": "Suggested mall goods", + "page.home.group.delete.confirmation": "Delete group permanently?" } diff --git a/tsconfig.test.json b/tsconfig.test.json index c17d2ec..f208ace 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -7,7 +7,7 @@ "next.config.js", "src/backend-custom-server/index", "scripts/*", - "res/*.json" + "res/**/*.json" ], "exclude": ["dist", ".next", "out", "node_modules", "cypress"] }