diff --git a/cucumber/features/pages.feature b/cucumber/features/pages.feature index a421709..1946218 100644 --- a/cucumber/features/pages.feature +++ b/cucumber/features/pages.feature @@ -10,6 +10,16 @@ Feature: Test all secundary pages | activeFires | Active Fires | Then I check that all pages works properly + Scenario: Check that all secondary pages work well + Given a list of page urls and contents + | login | Login | true | + | signup | Sign Up | true | + | recover-password | Recover Password | true | + | verify-email/something | Verify | true | + | fire/inexistent | This page doesn't exist | false | + | fire/Fe26.2**1a0361ed0384f741403682e26b4bbc3850bee24e775da13c9782b22365ea895f*r_3gmVad5vzkeyqPpo6UcA*1s5fFz3iDGKTYP2RCvXMshof00QCHf4ErDl9K2dxoX0u-J-t6scyOWG8pGp3ehg_FfEtyR_kYcEKU3rE0jaSlZbD09TIvhiIJeS3C6Uc8YD-rit0XBrgsVKfYSxKzTRoOYiYFJ8JYd298hMtfiASePjS05Z58hhicyCcJYYRlarqDScG3LiVY3lL5y2nfcdIMNuSjCiKOJWuMkxwd9nR1UHMudLl0hEoy56mPdnHpDYtP9IYUlIOk1LlWBxcmHKifbXeqHu94p8j13Kk20dh2R49Hw3KsSoE9UbWmGQA9wAZXT82301i3rGF5GPAKjlTlRYcWisQurnPwHSVmx3DhUdiYwKGxt4KeaM5QVI4BE9octvE41OOprB_-Il105diQEh2Y9vdvX51ZVWIRfCboICPM6rJb0Oin7U7F1iM-oD_5s3DGnelfM5LGBcKwiB5paMo5M5vdBMaO-zR216cW9yGVXw9IZqHx8xDQWnoHAZjt8NLHeiGF2QOmIGtEUH7qnwhGpkcvszajmAZzR8saZgoH1qfBfvpVA41YfV14gU**4d030f05e23ad75409cebc609107467fc60be5077d52cf041087cd024fc4dc45*GY97aGFc1MyAsoO3Qxqtgwk9j-MbAPdEGBmEHq6r8VU | Additional information | false | + Then I check that all page urls works properly + Scenario: Check that other non visible pages work well Given a list of non visible pages ids and contents | status | Status | diff --git a/cucumber/features/steps_definitions/login.js b/cucumber/features/steps_definitions/login.js index 84f4d26..03f11f8 100644 --- a/cucumber/features/steps_definitions/login.js +++ b/cucumber/features/steps_definitions/login.js @@ -65,8 +65,8 @@ module.exports = function doSteps(notos) { */ function closeAlert() { - client.waitForVisible('.bert-alert', 5000); - client.click('.bert-content'); + // client.waitForVisible('.bert-alert', 5000); + // client.click('.bert-content'); client.waitUntil(() => client.isVisible('.bert-alert') === false, 10000); } diff --git a/cucumber/features/steps_definitions/pages.js b/cucumber/features/steps_definitions/pages.js index ff2632a..1ce3c8c 100644 --- a/cucumber/features/steps_definitions/pages.js +++ b/cucumber/features/steps_definitions/pages.js @@ -17,6 +17,21 @@ module.exports = function () { client.waitForVisible(id, 10000); client.click(id); client.waitForText('#react-root', content); + // https://jasmine.github.io/2.3/introduction.html#section-Expectations + expect(client.getTitle()).toContain(pages[i][1]); + } + + function processPageUrl(i) { + const url = `${pages[i][0]}`; + const content = pages[i][1]; + client.url(`${process.env.ROOT_URL}/${url}`); + client.waitForVisible('#react-root', 10000); + client.waitForText('#react-root', content); + const checkTitle = pages[i][2] === 'true'; + // https://jasmine.github.io/2.3/introduction.html#section-Expectations + if (checkTitle) { + expect(client.getTitle()).toContain(pages[i][1]); + } } this.Given(/^a list of non visible pages ids and contents$/, (table, callback) => { @@ -35,9 +50,25 @@ module.exports = function () { this.Then(/^I check that all pages works properly$/, (callback) => { goHome(client); + if (client.isVisible('#logout')) { + client.click('#logout'); + } for (let i = 0; i < pages.length; i += 1) { processPage(i); } callback(); }); + + this.Given(/^a list of page urls and contents$/, (table, callback) => { + pages = table.raw(); + callback(); + }); + + this.Then(/^I check that all page urls works properly$/, (callback) => { + goHome(client); + for (let i = 0; i < pages.length; i += 1) { + processPageUrl(i); + } + callback(); + }); }; diff --git a/imports/api/Fires/server/publications.js b/imports/api/Fires/server/publications.js index be2be60..68eb4c8 100644 --- a/imports/api/Fires/server/publications.js +++ b/imports/api/Fires/server/publications.js @@ -24,11 +24,29 @@ const options = { const geocoder = NodeGeocoder(options); +const unseal = async (obj) => { + try { + const unsealed = await urlEnc.decrypt(obj); + return unsealed; + } catch (error) { + // console.warn(error); + return undefined; + } +}; + +const unsealW = obj => unseal(obj); + Meteor.publish('fireFromHash', function fireFromHash(fireEnc) { check(fireEnc, String); try { // console.log(fireEnc); - const unsealed = Promise.await(urlEnc.decrypt(fireEnc)); + // const unsealed = Promise.await(urlEnc.decrypt(fireEnc)); + const unsealed = Promise.await(unsealW(fireEnc)); + if (unsealed === undefined) { + console.info(`Wrong fire: ${fireEnc}`); + // https://guide.meteor.com/data-loading.html + return this.ready(); + } const w = unsealed.when; unsealed.when = new Date(w); const c = unsealed.createdAt; @@ -36,7 +54,6 @@ Meteor.publish('fireFromHash', function fireFromHash(fireEnc) { const u = unsealed.updatedAt; unsealed.updatedAt = !u ? new Date() : new Date(u); // console.log(unsealed); - // FIXME: if (typeof unsealed.confidence === 'string') { unsealed.confidence = Number.parseInt(unsealed.confidence, 10); @@ -55,7 +72,7 @@ Meteor.publish('fireFromHash', function fireFromHash(fireEnc) { } // console.log(unsealed.address); } catch (reve) { - console.error(reve); + console.warn(reve); } } if (fire.count() === 0) { @@ -65,9 +82,9 @@ Meteor.publish('fireFromHash', function fireFromHash(fireEnc) { } return findFire(unsealed); /* console.log(`fires: ${fire.count()}`); - * return fire; */ + * return fire; */ } catch (e) { - console.error(e); - throw new Meteor.Error('500', e); + console.warn(e); + return this.ready(); } }); diff --git a/imports/startup/client/meta.js b/imports/startup/client/meta.js new file mode 100644 index 0000000..e1c64f2 --- /dev/null +++ b/imports/startup/client/meta.js @@ -0,0 +1,4 @@ +/* eslint-env jquery */ + +// remove static description so it's not duplicated +$('meta[name=description]').remove(); diff --git a/imports/startup/common/i18n.js b/imports/startup/common/i18n.js index 2db4371..2aeeea1 100644 --- a/imports/startup/common/i18n.js +++ b/imports/startup/common/i18n.js @@ -15,7 +15,7 @@ const backOpts = { jsonIndent: 2 }; -const forceDebug = true; +const forceDebug = false; const shouldDebug = (forceDebug && !Meteor.isProduction); const i18nOpts = { diff --git a/imports/ui/components/Utils/location.js b/imports/ui/components/Utils/location.js new file mode 100644 index 0000000..8f60415 --- /dev/null +++ b/imports/ui/components/Utils/location.js @@ -0,0 +1,13 @@ +import { Meteor } from 'meteor/meteor'; +import { ReactiveVar } from 'meteor/reactive-var'; + +export const location = new ReactiveVar(); + +export const currentLocation = () => { + if (Meteor.isClient) { + return window.location.pathname; + } + return location.get(); +}; + +export const isHome = () => currentLocation() === '/'; diff --git a/imports/ui/layouts/App/App.js b/imports/ui/layouts/App/App.js index 2cdac13..4b1eb86 100644 --- a/imports/ui/layouts/App/App.js +++ b/imports/ui/layouts/App/App.js @@ -14,6 +14,7 @@ import { Roles } from 'meteor/alanning:roles'; import Blaze from 'meteor/gadicc:blaze-react-component'; // i18n import i18n, { i18nReady } from '/imports/startup/client/i18n'; +import '/imports/startup/client/meta'; import '/imports/startup/client/ravenLogger'; import '/imports/startup/client/geolocation'; import '/imports/startup/client/piwik-start.js'; diff --git a/imports/ui/pages/Fires/Fires.js b/imports/ui/pages/Fires/Fires.js index 4cf0e06..3196865 100644 --- a/imports/ui/pages/Fires/Fires.js +++ b/imports/ui/pages/Fires/Fires.js @@ -25,21 +25,25 @@ class Fire extends React.Component { constructor(props) { super(props); this.state = { + loading: props.loading, + notfound: props.notfound, when: props.when }; } componentWillReceiveProps(nextProps) { - if (this.props.when !== nextProps.when) { + if (this.props.when !== nextProps.when || this.props.loading !== nextProps.loading || this.props.notfound !== nextProps.notfound) { // console.log(`Next when ${nextProps.when}`); this.setState({ + loading: nextProps.loading, + notfound: nextProps.notfound, when: nextProps.when }); } } shouldComponentUpdate(nextProps, nextState) { - return !(nextState.when === this.state.when); + return !(nextState.when === this.state.when && nextState.loading === this.state.loading && this.state.notfound === nextState.notfound); } onTypeSelect(key) { @@ -55,23 +59,27 @@ class Fire extends React.Component { } render() { - const { loading, fire, t } = this.props; + const { + notfound, loading, fire, t + } = this.props; + /* console.log(`loading fire: ${loading}`); + * console.log(`Not found fire: ${notfound}`); */ if (fire && fire.when) { this.dateLongFormat = dateLongFormat(fire.when); + this.title = fire.address ? + t('Información adicional sobre fuego detectado en {{where}} el {{when}}', { where: fire.address, when: this.dateLongFormat }) : + t('Información adicional sobre fuego detectado el {{when}}', { when: this.dateLongFormat }); } - const title = fire.address ? - t('Información adicional sobre fuego detectado en {{where}} el {{when}}', { where: fire.address, when: this.dateLongFormat }) : - t('Información adicional sobre fuego detectado el {{when}}', { when: this.dateLongFormat }); - return (fire ? ( + + return (fire && !loading ? (
- {t('AppName')}: {t('Información adicional sobre fuego')} - + {!loading && -

{title}

+

{this.title}

{ this.fireMap = map; @@ -147,13 +155,14 @@ class Fire extends React.Component {
}
- ) : ); + ) : { notfound && }); } } Fire.propTypes = { t: PropTypes.func.isRequired, loading: PropTypes.bool.isRequired, + notfound: PropTypes.bool.isRequired, when: PropTypes.instanceOf(Date), fire: PropTypes.object }; @@ -167,10 +176,15 @@ const FireContainer = withTracker(({ match }) => { const fireEncrypt = match.params.id; const subscription = Meteor.subscribe('fireFromHash', fireEncrypt); // console.log(`Subs ready: ${subscription.ready()}, fire: ${JSON.stringify(FiresCollection.findOne())}`); + const loading = !subscription.ready(); + const notfound = !loading && FiresCollection.find().count() === 0; + /* console.log(`loading fire: ${loading}`); + * console.log(`Not found fire: ${notfound}`); */ return { - loading: !subscription.ready(), + loading, fire: FiresCollection.findOne(), - when: subscription.ready() ? FiresCollection.findOne().when : null + notfound, + when: subscription.ready() && FiresCollection.findOne() ? FiresCollection.findOne().when : null }; })(Fire); diff --git a/imports/ui/pages/FiresMap/FiresMap.js b/imports/ui/pages/FiresMap/FiresMap.js index f3b3fa5..62d61b8 100644 --- a/imports/ui/pages/FiresMap/FiresMap.js +++ b/imports/ui/pages/FiresMap/FiresMap.js @@ -29,6 +29,7 @@ import FireAlertsCollection from '/imports/api/FireAlerts/FireAlerts'; import SiteSettings from '/imports/api/SiteSettings/SiteSettings'; import UserSubsToFiresCollection from '/imports/api/Subscriptions/Subscriptions'; import { isNotHomeAndMobile, isChrome } from '/imports/ui/components/Utils/isMobile'; +import { isHome } from '/imports/ui/components/Utils/location'; import './FiresMap.scss'; @@ -110,18 +111,17 @@ class FiresMap extends React.Component { } handleLeafletLoad(map) { - // console.log(map); - if (map) { - // console.log('Firesmap loading'); + if (map && map.leafletElement) { + const lmap = map.leafletElement; try { - const bounds = this.getMap().getBounds(); + const bounds = lmap.getBounds(); mapSize.set([bounds.getNorthEast(), bounds.getSouthWest()]); if (!this.state.scaleAdded) { this.addScale(); this.state.scaleAdded = true; } } catch (e) { - console.log('Failed to set map bounds and scale'); + console.warn('Failed to set map bounds and scale'); } this.state.union = subsUnion(this.state.union, { map, @@ -134,15 +134,14 @@ class FiresMap extends React.Component { render() { const { t } = this.props; - console.log(`Rendering ${this.props.loading ? 'loading' : 'LOADED'} map ${this.props.activefires.length + this.props.firealerts.length} of ${this.props.activefirestotal} total. Subs users ready ${this.props.subsready}, reactive ${this.state.viewport.zoom >= MAXZOOMREACTIVE}`); - + console.log(`Rendering ${this.props.loading ? 'loading' : 'LOADED'} map ${this.props.activefires.length + this.props.firealerts.length} of ${this.props.activefirestotal} total. Subs users ready ${this.props.subsready} (${this.props.userSubs.length}), reactive ${this.state.viewport.zoom >= MAXZOOMREACTIVE}`); return ( /* Large number of markers: https://stackoverflow.com/questions/43015854/large-dataset-of-markers-or-dots-in-leaflet/43019740#43019740 */
{ this.divElement = divElement; }} > - { window.location.pathname !== '/' && + { !isHome() && {t('AppName')}: {t('Fuegos activos')} @@ -199,7 +198,7 @@ class FiresMap extends React.Component { onClick={this.onClickReset} viewport={this.state.viewport} onViewportChanged={this.onViewportChanged} - sleep={window.location.pathname === '/' && !isChrome} + sleep={isHome() && !isChrome} sleepTime={10750} wakeTime={750} sleepNote diff --git a/imports/ui/pages/Login/Login.js b/imports/ui/pages/Login/Login.js index 8d7dc5c..0ff48f8 100644 --- a/imports/ui/pages/Login/Login.js +++ b/imports/ui/pages/Login/Login.js @@ -6,6 +6,7 @@ import { Row, FormGroup, ControlLabel, Button } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import { Meteor } from 'meteor/meteor'; import { Bert } from 'meteor/themeteorchef:bert'; +import { Helmet } from 'react-helmet'; import { translate } from 'react-i18next'; import { T9n } from 'meteor-accounts-t9n'; import { testId } from '/imports/ui/components/Utils/TestUtils'; @@ -68,6 +69,9 @@ class Login extends React.Component { render() { return (
+ + {this.t('AppName')}: {this.t('Iniciar sesión')} +

{this.t('Iniciar sesión')}

diff --git a/imports/ui/pages/Logout/Logout.js b/imports/ui/pages/Logout/Logout.js index 329f072..0d0c2f9 100644 --- a/imports/ui/pages/Logout/Logout.js +++ b/imports/ui/pages/Logout/Logout.js @@ -1,6 +1,8 @@ import React from 'react'; +import { Meteor } from 'meteor/meteor'; import Icon from '../../components/Icon/Icon'; import { translate, Trans } from 'react-i18next'; +import { Helmet } from 'react-helmet'; import './Logout.scss'; @@ -12,6 +14,9 @@ class Logout extends React.Component { render() { return (
+ + {this.props.t('AppName')}: {this.props.t('Logout')} +

Gracias por Participar

También puedes seguirnos en la web

    diff --git a/imports/ui/pages/NotFound/NotFound.js b/imports/ui/pages/NotFound/NotFound.js index 3b19036..fee65d3 100644 --- a/imports/ui/pages/NotFound/NotFound.js +++ b/imports/ui/pages/NotFound/NotFound.js @@ -1,9 +1,13 @@ import React from 'react'; import { Alert } from 'react-bootstrap'; import { translate, Trans } from 'react-i18next'; +import { Helmet } from 'react-helmet'; const NotFound = () => (
    + + This page doesn't exist" +

    Upppps: Esta página no existe diff --git a/imports/ui/pages/Page/Page.js b/imports/ui/pages/Page/Page.js index 273c8f9..8d42e2f 100644 --- a/imports/ui/pages/Page/Page.js +++ b/imports/ui/pages/Page/Page.js @@ -15,7 +15,6 @@ const Page = ({ title, subtitle, content }) => ( {i18n.t('AppName')}: {title} - diff --git a/imports/ui/pages/RecoverPassword/RecoverPassword.js b/imports/ui/pages/RecoverPassword/RecoverPassword.js index f3b5d65..72c9156 100644 --- a/imports/ui/pages/RecoverPassword/RecoverPassword.js +++ b/imports/ui/pages/RecoverPassword/RecoverPassword.js @@ -5,6 +5,7 @@ import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; import { Accounts } from 'meteor/accounts-base'; import { Bert } from 'meteor/themeteorchef:bert'; +import { Helmet } from 'react-helmet'; import AccountPageFooter from '../../components/AccountPageFooter/AccountPageFooter'; import validate from '../../../modules/validate'; import { translate } from 'react-i18next'; @@ -24,16 +25,16 @@ class RecoverPassword extends React.Component { rules: { emailAddress: { required: true, - email: true, - }, + email: true + } }, messages: { emailAddress: { - required: this.t("Necesitamos un correo aquí."), - email: this.t("¿Es este correo correcto?"), - }, + required: this.t('Necesitamos un correo aquí.'), + email: this.t('¿Es este correo correcto?') + } }, - submitHandler() { component.handleSubmit(); }, + submitHandler() { component.handleSubmit(); } }); } @@ -46,7 +47,7 @@ class RecoverPassword extends React.Component { if (error) { Bert.alert(T9n.get(`error.accounts.${error.reason}`), 'danger'); } else { - Bert.alert(t("checkResetEmail", {email: email}), 'success'); + Bert.alert(t('checkResetEmail', { email }), 'success'); history.push('/login'); } }); @@ -55,14 +56,17 @@ class RecoverPassword extends React.Component { render() { return (

    + + {this.t('AppName')}: {this.t('Recupera tu contraseña')} + -

    {this.t("Recupera tu contraseña")}

    +

    {this.t('Recupera tu contraseña')}

    - {this.t("Introduce tu correo abajo para recibir un enlace para resetear tu contraseña.")} + {this.t('Introduce tu correo abajo para recibir un enlace para resetear tu contraseña.')}
    (this.form = form)} onSubmit={event => event.preventDefault()}> - {this.t("Correo electrónico")} + {this.t('Correo electrónico')} - + -

    {this.t("¿Recuerdas tu contraseña?")} {this.t("Iniciar sesión")}.

    +

    {this.t('¿Recuerdas tu contraseña?')} {this.t('Iniciar sesión')}.

    @@ -82,7 +86,7 @@ class RecoverPassword extends React.Component { } RecoverPassword.propTypes = { - history: PropTypes.object.isRequired, + history: PropTypes.object.isRequired }; export default translate([], { wait: true })(RecoverPassword); diff --git a/imports/ui/pages/ResetPassword/ResetPassword.js b/imports/ui/pages/ResetPassword/ResetPassword.js index dad8f1b..bd5e1b2 100644 --- a/imports/ui/pages/ResetPassword/ResetPassword.js +++ b/imports/ui/pages/ResetPassword/ResetPassword.js @@ -4,6 +4,7 @@ import { Row, Alert, FormGroup, ControlLabel, Button } from 'react-bootstrap'; import Col from '../../components/Col/Col'; import { Accounts } from 'meteor/accounts-base'; import { Bert } from 'meteor/themeteorchef:bert'; +import { Helmet } from 'react-helmet'; import validate from '../../../modules/validate'; import { translate } from 'react-i18next'; import { T9n } from 'meteor-accounts-t9n'; @@ -61,6 +62,9 @@ class ResetPassword extends React.Component { render() { return (
    + + {this.t('AppName')}: {this.t('Resetea tu contraseña')} +

    {this.t("Resetea tu contraseña")}

    diff --git a/imports/ui/pages/Signup/Signup.js b/imports/ui/pages/Signup/Signup.js index ba8f595..d89af19 100644 --- a/imports/ui/pages/Signup/Signup.js +++ b/imports/ui/pages/Signup/Signup.js @@ -1,22 +1,24 @@ /* eslint-disable react/jsx-indent-props */ +/* eslint-disable import/no-absolute-path */ import React from 'react'; import { Row, FormGroup, ControlLabel, Button, Checkbox } from 'react-bootstrap'; -import Col from '../../components/Col/Col'; import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; import { Meteor } from 'meteor/meteor'; import { Accounts } from 'meteor/accounts-base'; import { Bert } from 'meteor/themeteorchef:bert'; +import { translate, Trans } from 'react-i18next'; +import { T9n } from 'meteor-accounts-t9n'; +import { Helmet } from 'react-helmet'; import { testId } from '/imports/ui/components/Utils/TestUtils'; +import Col from '../../components/Col/Col'; import Icon from '../../components/Icon/Icon'; import OAuthLoginButtons from '../../components/OAuthLoginButtons/OAuthLoginButtons'; import InputHint from '../../components/InputHint/InputHint'; import AccountPageFooter from '../../components/AccountPageFooter/AccountPageFooter'; import validate from '../../../modules/validate'; import './Signup.scss'; -import { translate, Trans } from 'react-i18next'; -import { T9n } from 'meteor-accounts-t9n'; class Signup extends React.Component { constructor(props) { @@ -120,6 +122,9 @@ class Signup extends React.Component { const { t, history } = this.props; return (
    + + {this.t('AppName')}: {this.t('Registrarse')} +

    {t('Registrarse')}

    diff --git a/imports/ui/pages/Status/Status.js b/imports/ui/pages/Status/Status.js index 2df164a..3909468 100644 --- a/imports/ui/pages/Status/Status.js +++ b/imports/ui/pages/Status/Status.js @@ -7,6 +7,7 @@ import PropTypes from 'prop-types'; import { translate } from 'react-i18next'; import { withTracker } from 'meteor/react-meteor-data'; import Blaze from 'meteor/gadicc:blaze-react-component'; +import { Helmet } from 'react-helmet'; /* https://github.com/meteor/docs/blob/version-NEXT/long-form/oplog-observe-driver.md @@ -26,6 +27,9 @@ class Status extends Component { render() { return ( + + {this.t('AppName')}: Status +

    Status

    diff --git a/imports/ui/pages/Subscriptions/Subscriptions.js b/imports/ui/pages/Subscriptions/Subscriptions.js index 23a45f7..f9b3cc6 100644 --- a/imports/ui/pages/Subscriptions/Subscriptions.js +++ b/imports/ui/pages/Subscriptions/Subscriptions.js @@ -9,6 +9,7 @@ import { Meteor } from 'meteor/meteor'; import { withTracker } from 'meteor/react-meteor-data'; import { Trans, translate } from 'react-i18next'; import { Bert } from 'meteor/themeteorchef:bert'; +import { Helmet } from 'react-helmet'; import UserSubsToFiresCollection from '/imports/api/Subscriptions/Subscriptions'; import SelectionMap, { action } from '/imports/ui/components/SelectionMap/SelectionMap'; import confirm from '/imports/ui/components/Prompt/Confirm'; @@ -84,6 +85,9 @@ class Subscriptions extends Component { const firstBtnTitle = ['Añadir zona', '', 'Terminar']; // view, add, edit return (!loading ? (
    + + {t('AppName')}: {t('Suscripciones a alertas de fuegos en zonas de mi interés')} +

    Suscripciones a alertas de fuegos en zonas de mi interés

    { subscriptions.length === 0 ? No estás suscrito a fuegos en ninguna zona : diff --git a/imports/ui/pages/VerifyEmail/VerifyEmail.js b/imports/ui/pages/VerifyEmail/VerifyEmail.js index db3dc91..6bdc918 100644 --- a/imports/ui/pages/VerifyEmail/VerifyEmail.js +++ b/imports/ui/pages/VerifyEmail/VerifyEmail.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Alert } from 'react-bootstrap'; import { Meteor } from 'meteor/meteor'; +import { Helmet } from 'react-helmet'; import { Accounts } from 'meteor/accounts-base'; import { Bert } from 'meteor/themeteorchef:bert'; import { translate } from 'react-i18next'; @@ -32,6 +33,9 @@ class VerifyEmail extends React.Component { render() { return (
    + + {this.t('AppName')}: {this.t('Verifica tu dirección de correo')} + {!this.state.error ? this.t('Verificando...') : this.state.error} diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 867e2c5..5ba9314 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -66,8 +66,8 @@ "Uso de Cookies": "Use of Cookies", "Utilizamos cookies para asegurar un mejor uso de nuestra web. Si continúas navegando, consideramos que aceptas su uso": "We use cookies to ensure a better use of our website. If you continue browsing, we consider that you accept their use", "Participa": "Get Involved", - "activeFires": "Active fires", - "Fuegos activos": "Active fires", + "activeFires": "Active Fires", + "Fuegos activos": "Active Fires", "noActiveFireInMapCount": "There are no active fires in this area of the map. There is a total of <1><0>{{countTotal}} active fires detected worldwide.", "activeFireInMapCount": "On the map marked in red <1><0>{{count,number}} active fires. There is a total of <3><0>{{countTotal,number}} active fires detected worldwide by NASA.", "activeNeigFireInMapCount": "In Orange, the fires recently reported by our users.", @@ -161,5 +161,6 @@ "Verifica tu dirección de correo": "Verify Your Email Address", "Zonas vigiladas": "Monitored areas", "En verde, las zonas vigiladas por nuestros usuari@s actualmente": "In green, the areas monitored by our users currently", - "Datos actualizados <1>.": "Data updated <1>." + "Datos actualizados <1>.": "Data updated <1>.", + "Información adicional sobre fuego": "Additional information about fire" }