mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-28 09:24:24 +01:00
use i18next instead of angular-translate for react components
This commit is contained in:
parent
14091f547e
commit
408531d13a
@ -2,7 +2,8 @@
|
||||
* This component is a "card" publicly presenting the details of a plan
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { Suspense } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { react2angular } from 'react2angular';
|
||||
import { IFilterService } from 'angular';
|
||||
import moment from 'moment';
|
||||
@ -10,6 +11,7 @@ import _ from 'lodash'
|
||||
import { IApplication } from '../models/application';
|
||||
import { Plan } from '../models/plan';
|
||||
import { User, UserRole } from '../models/user';
|
||||
import '../lib/i18n';
|
||||
|
||||
declare var Application: IApplication;
|
||||
|
||||
@ -19,11 +21,11 @@ interface PlanCardProps {
|
||||
operator: User,
|
||||
isSelected: boolean,
|
||||
onSelectPlan: (plan: Plan) => void,
|
||||
_t: (key: string, interpolation?: object) => Promise<string>,
|
||||
$filter: IFilterService
|
||||
}
|
||||
|
||||
const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan, isSelected, _t, $filter }) => {
|
||||
const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan, isSelected, $filter }) => {
|
||||
const { t } = useTranslation('public');
|
||||
/**
|
||||
* Return the formatted localized amount of the given plan (eg. 20.5 => "20,50 €")
|
||||
*/
|
||||
@ -75,22 +77,35 @@ const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan,
|
||||
{!hasSubscribedToThisPlan() && <button className={`subscribe-button ${isSelected ? 'selected-card' : ''}`}
|
||||
onClick={handleSelectPlan}
|
||||
disabled={!_.isNil(user.subscription)}>
|
||||
{user && <span>{_t('app.public.plans.i_choose_that_plan')}</span>}
|
||||
{!user && <span>{_t('app.public.plans.i_subscribe_online')}</span>}
|
||||
{user && <span>{t('app.public.plans.i_choose_that_plan')}</span>}
|
||||
{!user && <span>{t('app.public.plans.i_subscribe_online')}</span>}
|
||||
</button>}
|
||||
{hasSubscribedToThisPlan() && <button className="subscribe-button" disabled>
|
||||
{ _t('app.public.plans.i_already_subscribed') }
|
||||
{ t('app.public.plans.i_already_subscribed') }
|
||||
</button>}
|
||||
</div>}
|
||||
{canSubscribeForOther() && <div className="cta-button">
|
||||
<button className={`subscribe-button ${isSelected ? 'selected-card' : ''}`}
|
||||
onClick={handleSelectPlan}
|
||||
disabled={_.isNil(user)}>
|
||||
<span>{ _t('app.public.plans.i_choose_that_plan') }</span>
|
||||
<span>{ t('app.public.plans.i_choose_that_plan') }</span>
|
||||
</button>
|
||||
</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Application.Components.component('planCard', react2angular(PlanCard, ['plan', 'user', 'operator', 'onSelectPlan', 'isSelected'], ['_t', '$filter']));
|
||||
const PlanCardWrapper: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan, isSelected, $filter }) => {
|
||||
const loading = (
|
||||
<div className="fa-3x">
|
||||
<i className="fas fa-circle-notch fa-spin"></i>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<Suspense fallback={loading}>
|
||||
<PlanCard plan={plan} user={user} operator={operator} isSelected={isSelected} onSelectPlan={onSelectPlan} $filter={$filter} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
Application.Components.component('planCard', react2angular(PlanCardWrapper, ['plan', 'user', 'operator', 'onSelectPlan', 'isSelected'], ['$filter']));
|
||||
|
22
app/frontend/src/javascript/lib/i18n.ts
Normal file
22
app/frontend/src/javascript/lib/i18n.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import i18n from 'i18next';
|
||||
import ICU from 'i18next-icu';
|
||||
import HttpApi from 'i18next-http-backend';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
|
||||
declare var Fablab: any;
|
||||
|
||||
i18n
|
||||
.use(ICU)
|
||||
.use(HttpApi)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
lng: Fablab.locale,
|
||||
fallbackLng: 'en',
|
||||
ns: ['admin', 'logged', 'public', 'shared'],
|
||||
defaultNS: 'shared',
|
||||
backend: {
|
||||
loadPath: '/api/translations/{{lng}}/app.{{ns}}'
|
||||
}
|
||||
});
|
||||
|
||||
export default i18n;
|
@ -344,6 +344,9 @@
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
button.subscribe-button:focus, button.subscribe-button:hover {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# frozen_string_literal: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Stylesheet is a cached CSS file that allows to easily customize the interface of Fab-manager with some configurable colors and
|
||||
# a picture for the background of the user's profile.
|
||||
@ -82,8 +82,8 @@ class Stylesheet < ApplicationRecord
|
||||
scss_files = Dir['app/themes/casemate/**/*.scss']
|
||||
|
||||
templates = ''
|
||||
erb_files.each { |erb_file| templates.concat(ERB.new(File.read(erb_file)).result) }
|
||||
scss_files.each { |scss_file| templates.concat(File.read(scss_file)) }
|
||||
erb_files.each { |erb_file| templates += ERB.new(File.read(erb_file)).result }
|
||||
scss_files.each { |scss_file| templates += File.read(scss_file) }
|
||||
|
||||
engine = SassC::Engine.new(templates, style: :compressed)
|
||||
engine.render.presence
|
||||
|
@ -81,6 +81,9 @@
|
||||
"elasticsearch-browser": "3.1",
|
||||
"fullcalendar": "3.10.2",
|
||||
"holderjs": "2.6",
|
||||
"i18next": "^19.8.3",
|
||||
"i18next-http-backend": "^1.0.21",
|
||||
"i18next-icu": "^1.4.2",
|
||||
"jasny-bootstrap": "3.1",
|
||||
"jquery": ">=3.5.0",
|
||||
"jquery-ujs": "^1.2.2",
|
||||
@ -94,6 +97,7 @@
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0",
|
||||
"react-i18next": "^11.7.3",
|
||||
"react-switch": "^5.0.1",
|
||||
"react2angular": "^4.0.6",
|
||||
"summernote": "0.8.18",
|
||||
|
65
yarn.lock
65
yarn.lock
@ -979,6 +979,13 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.12.0", "@babel/runtime@^7.3.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740"
|
||||
integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/template@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
|
||||
@ -4567,6 +4574,13 @@ html-minifier-terser@^5.1.1:
|
||||
relateurl "^0.2.7"
|
||||
terser "^4.6.3"
|
||||
|
||||
html-parse-stringify2@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a"
|
||||
integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=
|
||||
dependencies:
|
||||
void-elements "^2.0.1"
|
||||
|
||||
htmlparser2@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-4.1.0.tgz#9a4ef161f2e4625ebf7dfbe6c0a2f52d18a59e78"
|
||||
@ -4652,6 +4666,27 @@ https-browserify@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||
|
||||
i18next-http-backend@^1.0.21:
|
||||
version "1.0.21"
|
||||
resolved "https://registry.yarnpkg.com/i18next-http-backend/-/i18next-http-backend-1.0.21.tgz#cee901b3527dad5165fa91de973b6aa6404c1c37"
|
||||
integrity sha512-UDeHoV2B+31Gr++0KFAVjM5l+SEwePpF6sfDyaDq5ennM9QNJ78PBEMPStwkreEm4h5C8sT7M1JdNQrLcU1Wdg==
|
||||
dependencies:
|
||||
node-fetch "2.6.1"
|
||||
|
||||
i18next-icu@^1.4.2:
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/i18next-icu/-/i18next-icu-1.4.2.tgz#2b79d1ac2c2d542725219beac34a74db15cd2ff9"
|
||||
integrity sha512-EqHafx/sL8eoEowwqi5P6cXtLrzJXBKI4RmV+UaMXlpIJNfckVsq873F2KkMKkApxiw2ATj46C8MurmhMsHQGw==
|
||||
dependencies:
|
||||
intl-messageformat "2.2.0"
|
||||
|
||||
i18next@^19.8.3:
|
||||
version "19.8.3"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-19.8.3.tgz#10df7222db8c23389b13bceb9ba67a5e20a0241e"
|
||||
integrity sha512-eVrqAw2gGGYYJaJMYw4VM1FNFawLD4b84IsoTZMVXeWHaxAM2gyTa34j2Sip15UkBz/LrSxdFJj0Jhlrz7EvHA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.0"
|
||||
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
@ -4825,6 +4860,18 @@ interpret@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
|
||||
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
|
||||
|
||||
intl-messageformat-parser@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075"
|
||||
integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU=
|
||||
|
||||
intl-messageformat@2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc"
|
||||
integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw=
|
||||
dependencies:
|
||||
intl-messageformat-parser "1.4.0"
|
||||
|
||||
invariant@^2.2.2, invariant@^2.2.4:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
||||
@ -6016,6 +6063,11 @@ no-case@^3.0.3:
|
||||
lower-case "^2.0.1"
|
||||
tslib "^1.10.0"
|
||||
|
||||
node-fetch@2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
node-forge@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
||||
@ -7574,6 +7626,14 @@ react-dom@^17.0.0:
|
||||
object-assign "^4.1.1"
|
||||
scheduler "^0.20.0"
|
||||
|
||||
react-i18next@^11.7.3:
|
||||
version "11.7.3"
|
||||
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.7.3.tgz#256461c46baf5b3208c3c6860ca4e569fc7ed053"
|
||||
integrity sha512-7sYZqVZgdaS9Z0ZH6nuJFErCD0zz5wK3jR4/xCrWjZcxHHF3GRu7BXdicbSPprZV4ZYz7LJzxxMHO7dg5Qb70A==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.3.1"
|
||||
html-parse-stringify2 "2.0.1"
|
||||
|
||||
react-is@^16.8.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
@ -9245,6 +9305,11 @@ vm-browserify@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||
|
||||
void-elements@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
|
||||
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
|
||||
|
||||
watchpack-chokidar2@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"
|
||||
|
Loading…
Reference in New Issue
Block a user