]> git.localhorst.tv Git - alttp.git/commitdiff
tech ruleset classification
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 13 Jan 2023 13:24:54 +0000 (14:24 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 13 Jan 2023 13:24:54 +0000 (14:24 +0100)
app/Models/Technique.php
database/migrations/2022_08_19_080601_tech_index.php
database/migrations/2023_01_13_121640_tech_ruleset.php [new file with mode: 0644]
resources/js/components/common/Icon.js
resources/js/components/techniques/Detail.js
resources/js/components/techniques/List.js
resources/js/components/techniques/Rulesets.js [new file with mode: 0644]
resources/js/i18n/de.js
resources/js/i18n/en.js
resources/sass/techniques.scss

index f0a29d39ec3e975bf4ff973220ab83e50da25555..c8ad91b96bc56294fb1acbbba7963f31fb5de58e 100644 (file)
@@ -30,6 +30,7 @@ class Technique extends Model
 
        protected $casts = [
                'index' => 'boolean',
+               'rulesets' => 'array',
        ];
 
        protected $with = [
index d1b6d6e3ef79dd1fe1197f4641126a01a40c1220..e0f615a17af8386132eb0c2042121f19f6fcad80 100644 (file)
@@ -26,7 +26,7 @@ return new class extends Migration
         */
        public function down()
        {
-               Schema::table('rounds', function(Blueprint $table) {
+               Schema::table('techniques', function(Blueprint $table) {
                        $table->dropColumn('index');
                        $table->dropColumn('priority');
                });
diff --git a/database/migrations/2023_01_13_121640_tech_ruleset.php b/database/migrations/2023_01_13_121640_tech_ruleset.php
new file mode 100644 (file)
index 0000000..1765f40
--- /dev/null
@@ -0,0 +1,32 @@
+<?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::table('techniques', function(Blueprint $table) {
+                       $table->text('rulesets')->nullable()->default(null);
+               });
+       }
+
+       /**
+        * Reverse the migrations.
+        *
+        * @return void
+        */
+       public function down()
+       {
+               Schema::table('techniques', function(Blueprint $table) {
+                       $table->dropColumn('rulesets');
+               });
+       }
+};
index 581ce6ff0da8d0ca2b77e186f13719db820b0cb0..bce75f58dd79bbfa35fcda17117d8ee859e033b4 100644 (file)
@@ -59,6 +59,7 @@ const makePreset = (presetDisplayName, presetName) => {
 
 Icon.ACCEPT = makePreset('AcceptIcon', 'square-check');
 Icon.ADD = makePreset('AddIcon', 'circle-plus');
+Icon.ALLOWED = makePreset('AllowedIcon', 'square-check');
 Icon.APPLY = makePreset('ApplyIcon', 'right-to-bracket');
 Icon.APPLICATIONS = makePreset('ApplicationsIcon', 'person-running');
 Icon.CHART = makePreset('ChartIcon', 'chart-line');
@@ -66,6 +67,7 @@ Icon.DISCORD = makePreset('DiscordIcon', ['fab', 'discord']);
 Icon.EDIT = makePreset('EditIcon', 'edit');
 Icon.FINISHED = makePreset('FinishedIcon', 'square-check');
 Icon.FIRST_PLACE = makePreset('FirstPlaceIcon', 'trophy');
+Icon.FORBIDDEN = makePreset('ForbiddenIcon', 'square-xmark');
 Icon.FORFEIT = makePreset('ForfeitIcon', 'square-xmark');
 Icon.LANGUAGE = makePreset('LanguageIcon', 'language');
 Icon.LOCKED = makePreset('LockedIcon', 'lock');
@@ -80,6 +82,7 @@ Icon.SETTINGS = makePreset('SettingsIcon', 'cog');
 Icon.STREAM = makePreset('StreamIcon', ['fab', 'twitch']);
 Icon.THIRD_PLACE = makePreset('ThirdPlaceIcon', 'award');
 Icon.TWITCH = makePreset('TwitchIcon', ['fab', 'twitch']);
+Icon.UNKNOWN = makePreset('UnknownIcon', 'square-question');
 Icon.UNLOCKED = makePreset('UnlockedIcon', 'lock-open');
 Icon.VIDEO = makePreset('VideoIcon', 'video');
 Icon.YOUTUBE = makePreset('YoutubeIcon', ['fab', 'youtube']);
index 488205b2e6d68ffdd374ae93d78a5b0cfe704b6b..665392365b40120b0c9834fa01eeb5d7d145b7d2 100644 (file)
@@ -5,6 +5,7 @@ import { withTranslation } from 'react-i18next';
 
 import List from './List';
 import Outline from './Outline';
+import Rulesets from './Rulesets';
 import RawHTML from '../common/RawHTML';
 import {
        getRelations,
@@ -15,7 +16,12 @@ import {
 import i18n from '../../i18n';
 
 const Detail = ({ technique }) => <Container as="article">
-       <h1>{getTranslation(technique, 'title', i18n.language)}</h1>
+       <div className="d-flex align-items-center justify-content-between">
+               <h1>{getTranslation(technique, 'title', i18n.language)}</h1>
+               {technique && technique.rulesets ?
+                       <Rulesets technique={technique} />
+               : null}
+       </div>
        <Outline technique={technique} />
        <RawHTML html={getTranslation(technique, 'description', i18n.language)} />
        {technique.chapters ? technique.chapters.map(chapter =>
@@ -41,6 +47,8 @@ Detail.propTypes = {
                chapters: PropTypes.arrayOf(PropTypes.shape({
                })),
                description: PropTypes.string,
+               rulesets: PropTypes.shape({
+               }),
                title: PropTypes.string,
        }),
 };
index 58f0eaef254a5c10ba118b92e5b471f8e5e31389..e18937e9d21ff5660fa44d9e53e09912c1106dec 100644 (file)
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
 import React from 'react';
 import { Link } from 'react-router-dom';
 
+import Rulesets from './Rulesets';
 import {
        getLink,
        getTranslation,
@@ -10,13 +11,18 @@ import i18n from '../../i18n';
 
 const List = ({ techniques }) => <ul className="tech-list">
        {techniques.map(tech =>
-               <li key={tech.id}>
-                       <h2>
-                               <Link to={getLink(tech)}>
-                                       {getTranslation(tech, 'title', i18n.language)}
-                               </Link>
-                       </h2>
-                       <p>{getTranslation(tech, 'short', i18n.language)}</p>
+               <li className="d-flex align-items-start justify-content-between" key={tech.id}>
+                       <div>
+                               <h2>
+                                       <Link to={getLink(tech)}>
+                                               {getTranslation(tech, 'title', i18n.language)}
+                                       </Link>
+                               </h2>
+                               <p>{getTranslation(tech, 'short', i18n.language)}</p>
+                       </div>
+               {tech.rulesets ?
+                       <Rulesets technique={tech} />
+               : null}
                </li>
        )}
 </ul>;
diff --git a/resources/js/components/techniques/Rulesets.js b/resources/js/components/techniques/Rulesets.js
new file mode 100644 (file)
index 0000000..6d4ee50
--- /dev/null
@@ -0,0 +1,36 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+
+import Icon from '../common/Icon';
+
+const Rulesets = ({ technique }) => {
+       const { t } = useTranslation();
+
+       return <div className="ruleset-box">
+               {['competitive', 'owg', 'mg', 'nl'].map(r =>
+                       <span key={r} title={t(`techniques.rulesetDescriptions.${r}`)}>
+                               {technique && technique.rulesets && technique.rulesets[r] ?
+                                       <Icon.ALLOWED className="text-success" />
+                               : null}
+                               {technique && technique.rulesets && !technique.rulesets[r] ?
+                                       <Icon.FORBIDDEN className="text-danger" />
+                               : null}
+                               {!technique || !technique.rulesets ?
+                                       <Icon.UNKNOWN />
+                               : null}
+                               {' '}
+                               {t(`techniques.rulesetCodes.${r}`)}
+                       </span>
+               )}
+       </div>;
+};
+
+Rulesets.propTypes = {
+       technique: PropTypes.shape({
+               rulesets: PropTypes.shape({
+               }),
+       }),
+};
+
+export default Rulesets;
index e77d1de6bc8d03974984bbbebb356f1ddbe8bdd7..1334fde3c9cca4f46dbae0856d55f276251e6fec 100644 (file)
@@ -294,6 +294,7 @@ export default {
                },
                icon: {
                        AddIcon: 'Hinzufügen',
+                       AllowedIcon: 'Erlaubt',
                        ApplicationsIcon: 'Anträge',
                        ApplyIcon: 'Beantragen',
                        ChartIcon: 'Diagramm',
@@ -301,6 +302,7 @@ export default {
                        EditIcon: 'Bearbeiten',
                        FinishedIcon: 'Abgeschlossen',
                        FirstPlaceIcon: 'Erster Platz',
+                       ForbiddenIcon: 'Verboten',
                        ForfeitIcon: 'Aufgegeben',
                        LanguageIcon: 'Sprache',
                        LockedIcon: 'Gesperrt',
@@ -313,6 +315,7 @@ export default {
                        StreamIcon: 'Stream',
                        ThirdPlaceIcon: 'Dritter Platz',
                        TwitchIcon: 'Twitch',
+                       UnknownIcon: 'Unbekannt',
                        UnlockedIcon: 'Offen',
                        YoutubeIcon: 'YouTube',
                        VideoIcon: 'Video',
@@ -486,6 +489,18 @@ export default {
                },
                techniques: {
                        heading: 'Techniken',
+                       rulesetCodes: {
+                               competitive: 'COM',
+                               mg: 'MG',
+                               nl: 'NL',
+                               owg: 'OWG',
+                       },
+                       rulesetDescriptions: {
+                               competitive: 'Competitive',
+                               mg: 'Major Glitches',
+                               nl: 'No Logic',
+                               owg: 'Overworld Glitches',
+                       },
                        seeAlso: 'Siehe auch',
                },
                tournaments: {
index 5a6695afdb6644a26909a2dd7f9f235fd3f6bb01..d4e61bb7a7c5474de8f6ec82256de445e9cf5bff 100644 (file)
@@ -294,6 +294,7 @@ export default {
                },
                icon: {
                        AddIcon: 'Add',
+                       AllowedIcon: 'Allowed',
                        ApplicationsIcon: 'Applications',
                        ApplyIcon: 'Apply',
                        ChartIcon: 'Chart',
@@ -301,6 +302,7 @@ export default {
                        EditIcon: 'Edit',
                        FinishedIcon: 'Finished',
                        FirstPlaceIcon: 'First Place',
+                       ForbiddenIcon: 'Forbidden',
                        ForfeitIcon: 'Forfeit',
                        LanguageIcon: 'Language',
                        LockedIcon: 'Locked',
@@ -313,6 +315,7 @@ export default {
                        StreamIcon: 'Stream',
                        ThirdPlaceIcon: 'Third Place',
                        TwitchIcon: 'Twitch',
+                       UnknownIcon: 'Unknown',
                        UnlockedIcon: 'Unlocked',
                        YoutubeIcon: 'YouTube',
                        VideoIcon: 'Video',
@@ -486,6 +489,18 @@ export default {
                },
                techniques: {
                        heading: 'Techniques',
+                       rulesetCodes: {
+                               competitive: 'COM',
+                               mg: 'MG',
+                               nl: 'NL',
+                               owg: 'OWG',
+                       },
+                       rulesetDescriptions: {
+                               competitive: 'Competitive',
+                               mg: 'Major Glitches',
+                               nl: 'No Logic',
+                               owg: 'Overworld Glitches',
+                       },
                        seeAlso: 'See also',
                },
                tournaments: {
index 19dcf417be16f743721df2aa4624f7e3335efd31..a28c4386f05acfcc989fa56c15f195fe931800f5 100644 (file)
@@ -1,3 +1,11 @@
+.ruleset-box {
+       display: inline-grid;
+       grid-template-columns: 1fr 1fr;
+       gap: 0 1ex;
+       padding: 0.5ex;
+       border-radius: 0.5ex;
+}
+
 .tech-list {
        margin: 1em 0;
        padding: 0;