<Header doLogout={doLogout} />
<Routes>
<Route path="h/:hash" element={<AlttpSeed />} />
- <Route path="tech" element={<Techniques />} />
- <Route path="tech/:name" element={<Technique />} />
+ <Route
+ path="modes"
+ element={<Techniques namespace="modes" type="mode" />}
+ />
+ <Route
+ path="modes/:name"
+ element={<Technique namespace="modes" type="mode" />}
+ />
+ <Route
+ path="rulesets"
+ element={<Techniques namespace="rulesets" type="ruleset" />}
+ />
+ <Route
+ path="rulesets/:name"
+ element={<Technique namespace="rulesets" type="ruleset" />}
+ />
+ <Route
+ path="tech"
+ element={<Techniques namespace="techniques" type="tech" />}
+ />
+ <Route
+ path="tech/:name"
+ element={<Technique namespace="techniques" type="tech" />}
+ />
<Route path="tournaments/:id" element={<Tournament />} />
<Route path="users/:id" element={<User />} />
<Route path="/" element={<Front />} />
import axios from 'axios';
+import PropTypes from 'prop-types';
import React from 'react';
import { withTranslation } from 'react-i18next';
import { compareTranslation } from '../../helpers/Technique';
import i18n from '../../i18n';
-const Techniques = () => {
+const Techniques = ({ namespace, type }) => {
const [error, setError] = React.useState(null);
const [loading, setLoading] = React.useState(true);
const [techniques, setTechniques] = React.useState([]);
React.useEffect(() => {
const ctrl = new AbortController();
setLoading(true);
- window.document.title = i18n.t('techniques.heading');
+ window.document.title = i18n.t(`${namespace}.heading`);
axios
- .get(`/api/tech`, {
+ .get(`/api/content`, {
params: {
- type: 'tech',
+ type,
},
signal: ctrl.signal
})
return () => {
ctrl.abort();
};
- }, []);
+ }, [namespace, type]);
React.useEffect(() => {
- window.document.title = i18n.t('techniques.heading');
+ window.document.title = i18n.t(`${namespace}.heading`);
setTechniques(t => [...t].sort(compareTranslation('title', i18n.language)));
- }, [i18n.language]);
+ }, [namespace, i18n.language]);
if (loading) {
return <Loading />;
}
return <ErrorBoundary>
- <Overview techniques={techniques} />
+ <Overview namespace={namespace} techniques={techniques} />
</ErrorBoundary>;
};
+Techniques.propTypes = {
+ namespace: PropTypes.string,
+ type: PropTypes.string,
+};
+
export default withTranslation()(Techniques);
import React from 'react';
import { Link } from 'react-router-dom';
-import { getTranslation } from '../../helpers/Technique';
+import {
+ getLink,
+ getTranslation,
+} from '../../helpers/Technique';
import i18n from '../../i18n';
const List = ({ techniques }) => <ul className="tech-list">
{techniques.map(tech =>
<li key={tech.id}>
<h2>
- <Link to={`/tech/${tech.name}`}>
+ <Link to={getLink(tech)}>
{getTranslation(tech, 'title', i18n.language)}
</Link>
</h2>
import List from './List';
import i18n from '../../i18n';
-const Overview = ({ techniques }) => <Container>
- <h1>{i18n.t('techniques.heading')}</h1>
+const Overview = ({
+ namespace,
+ techniques,
+}) => <Container>
+ <h1>{i18n.t(`${namespace}.heading`)}</h1>
<List techniques={techniques} />
</Container>;
Overview.propTypes = {
+ namespace: PropTypes.string,
techniques: PropTypes.arrayOf(PropTypes.shape({
})),
};
import i18n from '../i18n';
+export const getLink = tech => {
+ if (tech.type === 'mode') {
+ return `/modes/${tech.name}`;
+ }
+ if (tech.type === 'ruleset') {
+ return `/rulesets/${tech.name}`;
+ }
+ return `/tech/${tech.name}`;
+};
+
export const getRelations = (tech, type) => {
const rs = (tech && tech.relations) || [];
return type ? rs.filter(r => r && r.pivot && r.pivot.type === type) : rs;
somaria: 'Cane of Somaria',
},
},
+ modes: {
+ heading: 'Modi',
+ },
participants: {
empty: 'Noch keine Teilnehmer eingetragen',
heading: 'Teilnehmer',
unlockError: 'Fehler beim Entsperren',
unlockSuccess: 'Runde entsperrt',
},
+ rulesets: {
+ heading: 'Regelsätze',
+ },
techniques: {
heading: 'Techniken',
seeAlso: 'Siehe auch',
somaria: 'Cane of Somaria',
},
},
+ modes: {
+ heading: 'Modes',
+ },
participants: {
empty: 'No participants on record',
heading: 'Participants',
unlockError: 'Error unlocking round',
unlockSuccess: 'Round unlocked',
},
+ rulesets: {
+ heading: 'Rulesets',
+ },
techniques: {
heading: 'Techniques',
seeAlso: 'See also',
Route::post('application/{application}/accept', 'App\Http\Controllers\ApplicationController@accept');
Route::post('application/{application}/reject', 'App\Http\Controllers\ApplicationController@reject');
+Route::get('content', 'App\Http\Controllers\TechniqueController@search');
+Route::get('content/{tech:name}', 'App\Http\Controllers\TechniqueController@single');
+
Route::get('discord-guilds', 'App\Http\Controllers\DiscordGuildController@search');
Route::get('discord-guilds/{guild_id}', 'App\Http\Controllers\DiscordGuildController@single');
Route::get('discord-guilds/{guild_id}/channels', 'App\Http\Controllers\DiscordChannelController@search');