From 6f34dd7c00bf0bd152a97b175390be00c3a0ba31 Mon Sep 17 00:00:00 2001
From: Daniel Karbach <daniel.karbach@localhorst.tv>
Date: Tue, 23 Aug 2022 10:45:48 +0200
Subject: [PATCH] technique translations

---
 app/Models/Technique.php                      |  9 +++++
 app/Models/TechniqueTranslation.php           | 11 ++++++
 ...12_create_technique_translations_table.php | 37 +++++++++++++++++++
 resources/js/components/techniques/Detail.js  | 21 ++++++++---
 resources/js/components/techniques/Outline.js | 10 +++--
 resources/js/helpers/Technique.js             | 15 ++++++++
 6 files changed, 95 insertions(+), 8 deletions(-)
 create mode 100644 app/Models/TechniqueTranslation.php
 create mode 100644 database/migrations/2022_08_23_082412_create_technique_translations_table.php
 create mode 100644 resources/js/helpers/Technique.js

diff --git a/app/Models/Technique.php b/app/Models/Technique.php
index 1a54a0e..256afc0 100644
--- a/app/Models/Technique.php
+++ b/app/Models/Technique.php
@@ -17,7 +17,16 @@ class Technique extends Model
 			->using(TechniqueChapter::class);
 	}
 
+	public function translations() {
+		return $this->hasMany(TechniqueTranslation::class);
+	}
+
 	protected $casts = [
 		'index' => 'boolean',
 	];
+
+	protected $with = [
+		'translations',
+	];
+
 }
diff --git a/app/Models/TechniqueTranslation.php b/app/Models/TechniqueTranslation.php
new file mode 100644
index 0000000..e7c7603
--- /dev/null
+++ b/app/Models/TechniqueTranslation.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class TechniqueTranslation extends Model
+{
+	use HasFactory;
+}
diff --git a/database/migrations/2022_08_23_082412_create_technique_translations_table.php b/database/migrations/2022_08_23_082412_create_technique_translations_table.php
new file mode 100644
index 0000000..20c6083
--- /dev/null
+++ b/database/migrations/2022_08_23_082412_create_technique_translations_table.php
@@ -0,0 +1,37 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+	/**
+	 * Run the migrations.
+	 *
+	 * @return void
+	 */
+	public function up()
+	{
+		Schema::create('technique_translations', function (Blueprint $table) {
+			$table->id();
+			$table->foreignId('technique_id')->constrained();
+			$table->string('locale');
+			$table->text('title');
+			$table->text('short');
+			$table->text('description');
+			$table->timestamps();
+			$table->unique(['technique_id', 'locale']);
+		});
+	}
+
+	/**
+	 * Reverse the migrations.
+	 *
+	 * @return void
+	 */
+	public function down()
+	{
+		Schema::dropIfExists('technique_translations');
+	}
+};
diff --git a/resources/js/components/techniques/Detail.js b/resources/js/components/techniques/Detail.js
index d586a9a..d955397 100644
--- a/resources/js/components/techniques/Detail.js
+++ b/resources/js/components/techniques/Detail.js
@@ -1,19 +1,30 @@
 import PropTypes from 'prop-types';
 import React from 'react';
 import { Container } from 'react-bootstrap';
+import { withTranslation } from 'react-i18next';
 
 import Outline from './Outline';
+import { getTranslation } from '../../helpers/Technique';
+import i18n from '../../i18n';
 
 const Detail = ({ technique }) => <Container as="article">
-	<h1>{technique.title}</h1>
+	<h1>{getTranslation(technique, 'title', i18n.language)}</h1>
 	<Outline technique={technique} />
-	<div dangerouslySetInnerHTML={{ __html: technique.description }} />
+	<div dangerouslySetInnerHTML={{
+		__html: getTranslation(technique, 'description', i18n.language),
+	}} />
 	{technique.chapters ? technique.chapters.map(chapter =>
 		<section id={`c${chapter.id}`} key={`c${chapter.id}`}>
 			{chapter.pivot.level ?
-				React.createElement(`h${chapter.pivot.level}`, {}, chapter.title)
+				React.createElement(
+					`h${chapter.pivot.level}`,
+					{},
+					getTranslation(chapter, 'title', i18n.language),
+				)
 			: null}
-			<div dangerouslySetInnerHTML={{ __html: chapter.description }} />
+			<div dangerouslySetInnerHTML={{
+				__html: getTranslation(chapter, 'description', i18n.language),
+			}} />
 		</section>
 	) : null}
 </Container>;
@@ -27,4 +38,4 @@ Detail.propTypes = {
 	}),
 };
 
-export default Detail;
+export default withTranslation()(Detail);
diff --git a/resources/js/components/techniques/Outline.js b/resources/js/components/techniques/Outline.js
index bf98eba..ae18aa8 100644
--- a/resources/js/components/techniques/Outline.js
+++ b/resources/js/components/techniques/Outline.js
@@ -1,6 +1,10 @@
 import PropTypes from 'prop-types';
 import React from 'react';
 import { ListGroup } from 'react-bootstrap';
+import { withTranslation } from 'react-i18next';
+
+import { getTranslation } from '../../helpers/Technique';
+import i18n from '../../i18n';
 
 const Outline = ({ technique }) => technique.chapters && technique.chapters.length ?
 	<aside className="tech-outline mb-3 ms-3">
@@ -10,9 +14,9 @@ const Outline = ({ technique }) => technique.chapters && technique.chapters.leng
 					action
 					href={`#c${chapter.id}`}
 					key={`c${chapter.id}`}
-					title={chapter.short || null}
+					title={getTranslation(chapter, 'short', i18n.language) || null}
 				>
-					{chapter.title}
+					{getTranslation(chapter, 'title', i18n.language)}
 				</ListGroup.Item>
 			: null)}
 		</ListGroup>
@@ -26,4 +30,4 @@ Outline.propTypes = {
 	}),
 };
 
-export default Outline;
+export default withTranslation()(Outline);
diff --git a/resources/js/helpers/Technique.js b/resources/js/helpers/Technique.js
new file mode 100644
index 0000000..ea60cc7
--- /dev/null
+++ b/resources/js/helpers/Technique.js
@@ -0,0 +1,15 @@
+export const getTranslation = (tech, prop, lang) => {
+	const direct = tech.translations.find(t => t.locale === lang);
+	if (direct) {
+		return direct[prop];
+	}
+	const sameLang = tech.translations.find(t => t.locale.substr(0, 2) === lang.substr(0, 2));
+	if (sameLang) {
+		return sameLang[prop];
+	}
+	return tech[prop];
+};
+
+export default {
+	getTranslation,
+};
-- 
2.39.5