Compare commits

..

6 Commits

Author SHA1 Message Date
Hördle Bot
ac0bb02ba0 Bump version to 0.1.3 2025-12-01 18:18:17 +01:00
Hördle Bot
63269c2600 Change: Standard-Sprache von Deutsch auf Englisch geändert
- defaultLocale in proxy.ts auf 'en' geändert
- Fallback in i18n/request.ts auf 'en' geändert
- Fallback-Reihenfolge in lib/i18n.ts angepasst (en vor de)
- Share-URL-Logik in Game.tsx angepasst
- Dokumentation aktualisiert
2025-12-01 18:18:11 +01:00
Hördle Bot
17a39d677d Update: package-lock.json aktualisiert für baseline-browser-mapping 2025-12-01 18:15:22 +01:00
Hördle Bot
1ff0787e4e Bump version to 0.1.2 2025-12-01 18:11:39 +01:00
Hördle Bot
ed5f02bdec Fix: 'Kurieren' zu 'Kuratieren' korrigiert im Admin-Dashboard 2025-12-01 18:11:24 +01:00
Hördle Bot
e3a09864a6 Refactor: Dokumentation nach docs/ verschoben
- Alle Markdown-Dateien (außer README.md) nach docs/ verschoben
- Referenzen in README.md aktualisiert
- /docs zu .dockerignore hinzugefügt
2025-12-01 17:58:32 +01:00
20 changed files with 29 additions and 25 deletions

View File

@@ -50,6 +50,7 @@ Dockerfile*
.dockerignore .dockerignore
# Documentation # Documentation
/docs
*.md *.md
!README.md !README.md

View File

@@ -38,6 +38,9 @@ RUN if [ -n "$APP_VERSION" ]; then \
# Uncomment the following line in case you want to disable telemetry during the build. # Uncomment the following line in case you want to disable telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED 1 ENV NEXT_TELEMETRY_DISABLED 1
# Suppress baseline-browser-mapping warning about old data (informational only)
ENV NODE_ENV=production
# Generate Prisma Client # Generate Prisma Client
ENV DATABASE_URL="file:./dev.db" ENV DATABASE_URL="file:./dev.db"
RUN node_modules/.bin/prisma generate RUN node_modules/.bin/prisma generate

View File

@@ -56,18 +56,18 @@ Eine Web-App inspiriert von Heardle, bei der Nutzer täglich einen Song anhand k
Hördle unterstützt vollständige Mehrsprachigkeit für Deutsch und Englisch. Hördle unterstützt vollständige Mehrsprachigkeit für Deutsch und Englisch.
👉 **[Vollständige i18n-Dokumentation](I18N.md)** 👉 **[Vollständige i18n-Dokumentation](docs/I18N.md)**
**Schnellstart:** **Schnellstart:**
- Deutsche Version: `http://localhost:3000/de` - Deutsche Version: `http://localhost:3000/de`
- Englische Version: `http://localhost:3000/en` - Englische Version: `http://localhost:3000/en`
- Root (`/`) leitet automatisch zur Standardsprache (Deutsch) um - Root (`/`) leitet automatisch zur Standardsprache (Englisch) um
## White Labeling ## White Labeling
Hördle ist "White Label Ready". Das bedeutet, du kannst das Branding (Name, Farben, Logos) komplett anpassen, ohne den Code zu ändern. Hördle ist "White Label Ready". Das bedeutet, du kannst das Branding (Name, Farben, Logos) komplett anpassen, ohne den Code zu ändern.
👉 **[Anleitung zur Anpassung (White Label Guide)](WHITE_LABEL.md)** 👉 **[Anleitung zur Anpassung (White Label Guide)](docs/WHITE_LABEL.md)**
Die Konfiguration erfolgt einfach über Umgebungsvariablen und CSS-Variablen. Die Konfiguration erfolgt einfach über Umgebungsvariablen und CSS-Variablen.
@@ -115,13 +115,13 @@ Das Ziel ist es, den Song mit so wenigen Hinweisen wie möglich zu erraten und d
```bash ```bash
npm run dev npm run dev
``` ```
Die App läuft unter `http://localhost:3000` (leitet automatisch zu `/de` um). Die App läuft unter `http://localhost:3000` (leitet automatisch zu `/en` um).
## Deployment mit Docker ## Deployment mit Docker
Das Projekt ist für den Betrieb mit Docker optimiert. Das Projekt ist für den Betrieb mit Docker optimiert.
👉 **[White Labeling mit Docker? Hier klicken!](WHITE_LABEL.md#docker-deployment)** 👉 **[White Labeling mit Docker? Hier klicken!](docs/WHITE_LABEL.md#docker-deployment)**
1. **Vorbereitung:** 1. **Vorbereitung:**
Kopiere die Beispiel-Konfiguration: Kopiere die Beispiel-Konfiguration:

View File

@@ -275,8 +275,8 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
const genreText = genre ? `${isSpecial ? t('special') : t('genre')}: ${genre}\n` : ''; const genreText = genre ? `${isSpecial ? t('special') : t('genre')}: ${genre}\n` : '';
let shareUrl = `https://${config.domain}`; let shareUrl = `https://${config.domain}`;
// Add locale prefix if not default (de) // Add locale prefix if not default (en)
if (locale !== 'de') { if (locale !== 'en') {
shareUrl += `/${locale}`; shareUrl += `/${locale}`;
} }
if (genre) { if (genre) {

View File

@@ -8,14 +8,14 @@ Die i18n-Implementierung basiert auf [next-intl](https://next-intl-docs.vercel.a
## Unterstützte Sprachen ## Unterstützte Sprachen
- **Deutsch (de)** - Standardsprache - **Englisch (en)** - Standardsprache
- **Englisch (en)** - **Deutsch (de)**
## URL-Struktur ## URL-Struktur
Alle Routen sind lokalisiert: Alle Routen sind lokalisiert:
- `http://localhost:3000/` → Redirect zu `/de` (Standard) - `http://localhost:3000/` → Redirect zu `/en` (Standard)
- `http://localhost:3000/de` → Deutsche Version - `http://localhost:3000/de` → Deutsche Version
- `http://localhost:3000/en` → Englische Version - `http://localhost:3000/en` → Englische Version
- `http://localhost:3000/de/admin` → Admin-Dashboard (Deutsch) - `http://localhost:3000/de/admin` → Admin-Dashboard (Deutsch)
@@ -103,8 +103,8 @@ const genreNameEn = getLocalizedValue(genre.name, 'en'); // "Rock"
**Fallback-Verhalten:** **Fallback-Verhalten:**
1. Versucht die angeforderte Locale (`de` oder `en`) 1. Versucht die angeforderte Locale (`de` oder `en`)
2. Fallback zu `de` falls nicht vorhanden 2. Fallback zu `en` falls nicht vorhanden
3. Fallback zu `en` falls nicht vorhanden 3. Fallback zu `de` falls nicht vorhanden
4. Fallback zum ersten verfügbaren Schlüssel 4. Fallback zum ersten verfügbaren Schlüssel
5. Fallback zum übergebenen `fallback`-Parameter 5. Fallback zum übergebenen `fallback`-Parameter
@@ -195,7 +195,7 @@ Bestehende Daten werden automatisch migriert:
Der Proxy (`proxy.ts`) leitet Anfragen automatisch um: Der Proxy (`proxy.ts`) leitet Anfragen automatisch um:
- `/``/de` (Standard) - `/``/en` (Standard)
- Ungültige Locales → 404 - Ungültige Locales → 404
- Validiert Locale-Parameter - Validiert Locale-Parameter
@@ -223,7 +223,7 @@ GET /api/specials?locale=en
GET /api/news?locale=de GET /api/news?locale=de
``` ```
Falls kein `locale` angegeben wird, wird `de` als Standard verwendet. Falls kein `locale` angegeben wird, wird `en` als Standard verwendet.
## Best Practices ## Best Practices

View File

@@ -9,7 +9,7 @@ export default getRequestConfig(async ({ requestLocale }) => {
console.log('[i18n/request] incoming requestLocale:', locale); console.log('[i18n/request] incoming requestLocale:', locale);
if (!locale || !locales.includes(locale as (typeof locales)[number])) { if (!locale || !locales.includes(locale as (typeof locales)[number])) {
locale = 'de'; locale = 'en';
console.log('[i18n/request] falling back to default locale:', locale); console.log('[i18n/request] falling back to default locale:', locale);
} }

View File

@@ -16,12 +16,12 @@ export function getLocalizedValue(
if (typeof value === 'object') { if (typeof value === 'object') {
if (value[locale]) return value[locale]; if (value[locale]) return value[locale];
// Fallback to 'de'
if (value['de']) return value['de'];
// Fallback to 'en' // Fallback to 'en'
if (value['en']) return value['en']; if (value['en']) return value['en'];
// Fallback to 'de'
if (value['de']) return value['de'];
// Fallback to first key // Fallback to first key
const keys = Object.keys(value); const keys = Object.keys(value);
if (keys.length > 0) return value[keys[0]]; if (keys.length > 0) return value[keys[0]];

View File

@@ -125,7 +125,7 @@
"delete": "Löschen", "delete": "Löschen",
"save": "Speichern", "save": "Speichern",
"cancel": "Abbrechen", "cancel": "Abbrechen",
"curate": "Kurieren", "curate": "Kuratieren",
"name": "Name", "name": "Name",
"subtitle": "Untertitel", "subtitle": "Untertitel",
"maxAttempts": "Max. Versuche", "maxAttempts": "Max. Versuche",

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "hoerdle", "name": "hoerdle",
"version": "0.1.0.15", "version": "0.1.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "hoerdle", "name": "hoerdle",
"version": "0.1.0.15", "version": "0.1.2",
"dependencies": { "dependencies": {
"@prisma/client": "^6.19.0", "@prisma/client": "^6.19.0",
"bcryptjs": "^3.0.3", "bcryptjs": "^3.0.3",

View File

@@ -1,6 +1,6 @@
{ {
"name": "hoerdle", "name": "hoerdle",
"version": "0.1.1", "version": "0.1.3",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",

View File

@@ -2,9 +2,9 @@ import createMiddleware from 'next-intl/middleware';
import type { NextRequest } from 'next/server'; import type { NextRequest } from 'next/server';
const i18nMiddleware = createMiddleware({ const i18nMiddleware = createMiddleware({
locales: ['de', 'en'], locales: ['en', 'de'],
defaultLocale: 'de', defaultLocale: 'en',
// Wir nutzen überall Locale-Präfixe (`/de`, `/en`) // Wir nutzen überall Locale-Präfixe (`/en`, `/de`)
localePrefix: 'always' localePrefix: 'always'
}); });