diff --git a/designs/web-tcef.svg b/designs/web-tcef.svg index 51c0091..edab1b4 100644 --- a/designs/web-tcef.svg +++ b/designs/web-tcef.svg @@ -27,8 +27,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.69575618" - inkscape:cx="793.70078" - inkscape:cy="618.75125" + inkscape:cx="900.10663" + inkscape:cy="596.82354" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="false" @@ -64,33 +64,36 @@ width="442.13651" style="stroke-width:165.45117188" /> + y="14.26377" + rx="5" /> + x="27.583012" + y="83.608246" + rx="5" + ry="5" /> TODOS CONTRA EL FUEGO + transform="translate(-4.7272093,3.7645966)"> + x="220.07025" + y="84.41494" + rx="5" + ry="5" /> ESCOGE UN ÁREA ESCOGE UN ÁREA DE TÚ INTERÉS + x="109.71358" + y="237.57089" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12.69999981px;line-height:1.29999995;font-family:Roboto;-inkscape-font-specification:'Roboto, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#501616;stroke-width:0.26458332" + id="tspan4803">DE TÚ INTERÉS TE AVISAREMOS DEFUEGOS ACTIVOS - + x="187.7402" + y="176.10248" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FontAwesome;-inkscape-font-specification:FontAwesome;fill:#552200;fill-opacity:1;stroke-width:0.26458338"> + + INICIO MAPA ACTUAL CONTACTO HISTORIA ESPAÑOL MÁS + © COPYLEFT BLA BLA BLA + TE AVISAREMOS DEFUEGOS ACTIVOS diff --git a/imports/api/Users/server/send-welcome-email.js b/imports/api/Users/server/send-welcome-email.js index d15298d..c28b205 100644 --- a/imports/api/Users/server/send-welcome-email.js +++ b/imports/api/Users/server/send-welcome-email.js @@ -4,13 +4,13 @@ import getOAuthProfile from '../../../modules/get-oauth-profile'; export default (options, user) => { const OAuthProfile = getOAuthProfile(options, user); - const applicationName = 'Application Name'; + const applicationName = '¡Tod@s contra el Fuego!'; const firstName = OAuthProfile ? OAuthProfile.name.first : options.profile.name.first; const emailAddress = OAuthProfile ? OAuthProfile.email : options.email; return sendEmail({ to: emailAddress, - from: `${applicationName} `, + from: `${applicationName} `, subject: `[${applicationName}] Welcome, ${firstName}!`, template: 'welcome', templateVars: { diff --git a/imports/startup/client/i18n.js b/imports/startup/client/i18n.js new file mode 100644 index 0000000..da0c122 --- /dev/null +++ b/imports/startup/client/i18n.js @@ -0,0 +1,85 @@ +import i18n from 'i18next'; +import backend from 'i18next-xhr-backend'; +import LngDetector from 'i18next-browser-languagedetector'; +import Cache from 'i18next-localstorage-cache'; + +// Adapted from: https://github.com/appigram/ryfma-boilerplate/blob/44c1eabfb9928b5623afab36a23997969e5beb02/imports/startup/client/i18n.js + +const detectorOptions = { + // order and from where user language should be detected + order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag'], + + // keys or params to lookup language from + lookupQuerystring: 'lng', + lookupCookie: 'i18next', + lookupLocalStorage: 'i18nextLng', + + // cache user language on + caches: ['localStorage', 'cookie'], + excludeCacheFor: ['cimode'], // languages to not persist (cookie, localStorage) +}; + +const cacheOptions = { + // turn on or off + enabled: false, + // prefix for stored languages + prefix: 'i18next_res_', + // expiration + expirationTime: 7 * 24 * 60 * 60 * 1000, + // language versions + versions: {}, +}; + +var backOpts = { + // path where resources get loaded from + loadPath: '/locales/{{lng}}/{{ns}}.json', + + // path to post missing resources + addPath: '/locales/{{lng}}/{{ns}}.missing.json', + + // jsonIndent to use when storing json files + jsonIndent: 2 +}; + +i18n.use(backend) + .use(LngDetector) + .use(Cache) + .init({ + backend: backOpts, + lng: 'es', + //fallbackLng: 'es', + fallbackLng: { + 'en-US': ['en'], + 'en-GB': ['en'], + 'pt-BR': ['pt'], + 'default': ['es'] + }, + interpolation: { + escapeValue: false, // not needed for react!! + }, + whitelist: false, + // whitelist: ['es', 'en'], // allowed languages + load: 'all', // es-ES -> es, en-US -> en + debug: true, + ns: 'common', + defaultNS: 'common', + saveMissing: true, // if true seems it's fails to getResourceBundle + saveMissingTo: 'es', + keySeparator: 'ß', + nsSeparator: 'ð', + pluralSeparator: 'đ', + cache: cacheOptions, + detection: detectorOptions, + react: { + wait: true, + // https://react.i18next.com/components/i18next-instance.ht + /* bindI18n: 'languageChanged loaded', + bindStore: 'added removed', + nsMode: 'default' */ + } + }, function(err, t) { + // initialized and ready to + console.log(t('AppName')); + }); + +export default i18n; diff --git a/imports/startup/server/accounts/email-templates.js b/imports/startup/server/accounts/email-templates.js index 40a2f18..1e49cae 100644 --- a/imports/startup/server/accounts/email-templates.js +++ b/imports/startup/server/accounts/email-templates.js @@ -4,8 +4,8 @@ import getPrivateFile from '../../../modules/server/get-private-file'; import templateToHTML from '../../../modules/server/handlebars-email-to-html'; import templateToText from '../../../modules/server/handlebars-email-to-text'; -const name = 'Application Name'; -const email = ''; +const name = '¡Tod@s contra el Fuego!'; +const email = ''; const from = `${name} ${email}`; const emailTemplates = Accounts.emailTemplates; diff --git a/imports/ui/components/Footer/Footer.js b/imports/ui/components/Footer/Footer.js index e5f61b6..6cbaddf 100644 --- a/imports/ui/components/Footer/Footer.js +++ b/imports/ui/components/Footer/Footer.js @@ -2,6 +2,7 @@ import React from 'react'; import { year } from '@cleverbeagle/dates'; import { Link } from 'react-router-dom'; import { Grid } from 'react-bootstrap'; +import { translate } from 'react-i18next'; import './Footer.scss'; @@ -10,18 +11,21 @@ const copyrightYear = () => { return currentYear === '2017' ? '2017' : `2017-${currentYear}`; }; -const Footer = () => ( +const Footer = (props) => { + const { t } = props; + return (
-

© {copyrightYear()} Application Name

+

© Copyleft {copyrightYear()} {t('OrgNameFull')}

    -
  • Terms of Service
  • -
  • Privacy Policy
  • +
  • {t('Términos')} {t('de Servicio')}
  • +
  • {t('Política')} {t('de Privacidad')}
-); + ); +}; Footer.propTypes = {}; -export default Footer; +export default translate([], { wait: true })(Footer); diff --git a/imports/ui/components/Navigation/Navigation.js b/imports/ui/components/Navigation/Navigation.js index ffc3020..36ecdb9 100644 --- a/imports/ui/components/Navigation/Navigation.js +++ b/imports/ui/components/Navigation/Navigation.js @@ -4,6 +4,7 @@ import { Navbar } from 'react-bootstrap'; import { Link } from 'react-router-dom'; import PublicNavigation from '../PublicNavigation/PublicNavigation'; import AuthenticatedNavigation from '../AuthenticatedNavigation/AuthenticatedNavigation'; +import { translate } from 'react-i18next'; import './Navigation.scss'; @@ -11,7 +12,7 @@ const Navigation = props => ( - Pup + {props.t('AppName')} @@ -29,4 +30,6 @@ Navigation.propTypes = { authenticated: PropTypes.bool.isRequired, }; -export default Navigation; +// export default Navigation; + +export default translate([], { wait: true })(Navigation); diff --git a/imports/ui/layouts/App/App.js b/imports/ui/layouts/App/App.js index 2be6a1f..2452d29 100644 --- a/imports/ui/layouts/App/App.js +++ b/imports/ui/layouts/App/App.js @@ -28,6 +28,11 @@ import Footer from '../../components/Footer/Footer'; import Terms from '../../pages/Terms/Terms'; import Privacy from '../../pages/Privacy/Privacy'; import ExamplePage from '../../pages/ExamplePage/ExamplePage'; +// i18n +import { I18nextProvider } from 'react-i18next'; +import i18n from '/imports/startup/client/i18n'; +//https://react.i18next.com/components/i18nextprovider.html + import './App.scss'; @@ -41,7 +46,10 @@ const handleResendVerificationEmail = (emailAddress) => { }); }; + + const App = props => ( + {!props.loading ?
{props.userId && !props.emailVerified ?

Hey friend! Can you verify your email address ({props.emailAddress}) for us?

: ''} @@ -61,7 +69,7 @@ const App = props => ( - + @@ -69,6 +77,7 @@ const App = props => (
: ''}
+
); App.defaultProps = { diff --git a/imports/ui/layouts/App/App.scss b/imports/ui/layouts/App/App.scss index e3d6669..a57950a 100644 --- a/imports/ui/layouts/App/App.scss +++ b/imports/ui/layouts/App/App.scss @@ -21,3 +21,11 @@ padding: 0; } } + +body { + background: url(/home-fire.jpg) no-repeat center center fixed; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} diff --git a/imports/ui/pages/Index/Index.js b/imports/ui/pages/Index/Index.js index 35709e5..4d8a5ab 100644 --- a/imports/ui/pages/Index/Index.js +++ b/imports/ui/pages/Index/Index.js @@ -1,15 +1,14 @@ import React from 'react'; import { Button } from 'react-bootstrap'; +import { translate } from 'react-i18next'; import './Index.scss'; -const Index = () => ( +const Index = (props) => { + const { t } = props; + return (
- Clever Beagle -

Pup

+

{props.t('AppName')}

A boilerplate for products.

@@ -19,6 +18,7 @@ const Index = () => (

Need help and want to stay accountable building your product? Check out Clever Beagle.

-); + ); +}; -export default Index; +export default translate([], { wait: true })(Index); diff --git a/imports/ui/pages/Index/Index.scss b/imports/ui/pages/Index/Index.scss index 0e397a2..3fb18b4 100644 --- a/imports/ui/pages/Index/Index.scss +++ b/imports/ui/pages/Index/Index.scss @@ -3,10 +3,12 @@ .Index { padding: 20px; - background: $cb-blue; + background: lighten($todos-back1, 75%); text-align: center; border-radius: 3px; - color: #fff; + color: $todos-font1; + opacity: 0.5; + filter: alpha(opacity=50); img { width: 100px; @@ -14,7 +16,9 @@ } h1 { - font-size: 28px; + font-size: 86px; + text-transform: uppercase; + font-family: 'Roboto'; } p { diff --git a/imports/ui/stylesheets/app.scss b/imports/ui/stylesheets/app.scss index 21c9469..be7cbf1 100644 --- a/imports/ui/stylesheets/app.scss +++ b/imports/ui/stylesheets/app.scss @@ -1,3 +1,4 @@ @import './colors'; @import './forms'; @import './bootstrap-overrides'; +@import 'web-fonts'; diff --git a/imports/ui/stylesheets/colors.scss b/imports/ui/stylesheets/colors.scss index 0e0e2f2..110ea5a 100644 --- a/imports/ui/stylesheets/colors.scss +++ b/imports/ui/stylesheets/colors.scss @@ -18,3 +18,8 @@ $cb-blue: #4285F4; $cb-green: #00D490; $cb-yellow: #FFCF50; $cb-red: #DA5847; + +$todos-back1: #AC9393; +$todos-back2: #FFFFFF; +$todos-font1: #280B0B; +$todos-font2: #501616; diff --git a/imports/ui/stylesheets/custom.scss b/imports/ui/stylesheets/custom.scss new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json index 5462567..bdeaf69 100644 --- a/package.json +++ b/package.json @@ -14,16 +14,22 @@ "core-js": "^2.5.1", "fs": "0.0.1-security", "handlebars": "^4.0.10", + "i18next": "^10.0.7", + "i18next-browser-languagedetector": "^2.1.0", + "i18next-localstorage-cache": "^1.1.1", + "i18next-xhr-backend": "^1.5.0", "jquery": "^2.2.4", "jquery-validation": "^1.17.0", "juice": "^4.1.1", "lodash": "^4.17.4", "meteor-node-stubs": "^0.2.11", + "moment": "^2.19.2", "prop-types": "^15.5.10", "react": "^15.6.1", "react-addons-pure-render-mixin": "^15.6.0", "react-bootstrap": "^0.31.2", "react-dom": "^15.6.1", + "react-i18next": "^6.1.0", "react-router-bootstrap": "^0.24.3", "react-router-dom": "^4.2.2", "simpl-schema": "^0.3.2" diff --git a/public/locales/es/common.json b/public/locales/es/common.json new file mode 100644 index 0000000..710b8df --- /dev/null +++ b/public/locales/es/common.json @@ -0,0 +1,11 @@ +{ + "AppName": "Tod@s contra el Fuego", + "AppNameFull": "¡Tod@s contra el Fuego!", + "OrgName": "Comunes", + "OrgNameFull": "Asociación Comunes", + "Privacidad": "Privacidad", + "Términos": "Términos", + "de Servicio": "de Servicio", + "Política": "Política", + "de Privacidad": "de Privacidad" +}