├── .browserslistrc ├── .dockerignore ├── .editorconfig ├── .env ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── blank.md │ └── generic-proposal-issue-template.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .rubocop.yml ├── .ruby-version ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── Procfile ├── README.md ├── Rakefile ├── app.json ├── app ├── admin │ ├── admin_user.rb │ ├── dashboard.rb │ └── restroom.rb ├── assets │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ ├── images │ │ ├── .keep │ │ ├── Logo-Small.png │ │ ├── Logo-lg.png │ │ ├── ToiletLogo-large.png │ │ ├── ToiletLogo.png │ │ ├── UnisexRestroom.png │ │ ├── app-store.svg │ │ ├── city-photo-2x.jpg │ │ ├── city-photo-3x.jpg │ │ ├── city-photo-original-fullsize.jpg │ │ ├── city-photo.jpg │ │ ├── currentLocation.png │ │ ├── facebook.png │ │ ├── favicon.ico │ │ ├── github.png │ │ ├── layers-2x.png │ │ ├── layers.png │ │ ├── loading.gif │ │ ├── logo-100x100.png │ │ ├── logo-dark.svg │ │ ├── mail.png │ │ ├── marker-circle.png │ │ ├── marker-circle2x.png │ │ ├── marker-icon-2x.png │ │ ├── marker-icon.png │ │ ├── marker-shadow.png │ │ ├── patreon.png │ │ ├── play-store.png │ │ ├── qrcode-sign-no-handi.png │ │ ├── qrcode-sign-with-handi.png │ │ ├── rr-sign-no-handi.png │ │ ├── rr-sign-with-handi.png │ │ ├── show-icon.png │ │ ├── splashlanding.png │ │ ├── submit.png │ │ ├── submit.svg │ │ ├── text-msg-demo.png │ │ ├── tumblr.png │ │ ├── twitter.png │ │ ├── unisex-slider.png │ │ └── unisex-slider.svg │ ├── javascripts │ │ └── active_admin.js │ └── stylesheets │ │ ├── _mobile.scss │ │ ├── _refuge_core.scss │ │ ├── active_admin.scss │ │ ├── application.scss │ │ ├── components │ │ ├── common.scss │ │ ├── nav.scss │ │ └── search.scss │ │ ├── framework_and_overrides.scss │ │ ├── map │ │ └── main.scss │ │ ├── pages │ │ ├── api_docs.scss │ │ └── splash.scss │ │ ├── restrooms │ │ ├── main.scss │ │ ├── new.scss │ │ └── restroom-list.scss │ │ └── sass │ │ ├── _mixins.scss │ │ ├── _screen_sizes.sass │ │ └── _variables.scss ├── controllers │ ├── api │ │ ├── base.rb │ │ ├── docs_controller.rb │ │ └── v1 │ │ │ ├── base.rb │ │ │ └── restrooms.rb │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ ├── contacts_controller.rb │ ├── pages_controller.rb │ └── restrooms_controller.rb ├── helpers │ ├── pagy_helper.rb │ ├── recaptcha_helper.rb │ └── restrooms_helper.rb ├── javascript │ └── packs │ │ ├── application.js │ │ ├── lib │ │ ├── geocoder.js │ │ └── maps.js.erb │ │ └── views │ │ ├── api │ │ └── docs │ │ │ └── index.js │ │ └── restrooms │ │ ├── index.js │ │ ├── new.js │ │ ├── restrooms.js │ │ └── search.js ├── jobs │ └── application_job.rb ├── mailers │ └── .keep ├── models │ ├── admin_user.rb │ ├── application_record.rb │ ├── concerns │ │ └── .keep │ ├── contact.rb │ ├── rating_level.rb │ └── restroom.rb ├── services │ └── save_restroom.rb └── views │ ├── api │ └── docs │ │ └── index.html │ ├── contacts │ ├── create.html.haml │ └── new.html.haml │ ├── layouts │ ├── _disqus_tag.html.erb │ ├── _footer.html.haml │ ├── _head.html.haml │ ├── _header.html.haml │ ├── _messages.html.haml │ ├── _navigation.html.haml │ ├── _piwik_tag.html.haml │ ├── _search.html.haml │ ├── application.html.haml │ └── splash.html.haml │ ├── pages │ ├── about.html.haml │ ├── business_info.html.haml │ ├── index.html.haml │ ├── license.hmtl.haml │ ├── signs.html.haml │ └── text.html.haml │ └── restrooms │ ├── _formsubmit.html.haml │ ├── _restroom.html.haml │ ├── edit.html.haml │ ├── index.html.haml │ ├── nearby.html.haml │ ├── new.html.haml │ └── show.html.haml ├── babel.config.js ├── bin ├── bourbon ├── bundle ├── bundler ├── coderay ├── dotenv ├── geocode ├── haml ├── htmldiff ├── kramdown ├── ldiff ├── nokogiri ├── pry ├── rackup ├── rails ├── rake ├── rdoc ├── ri ├── rspec ├── sass ├── sass-convert ├── scss ├── sdoc ├── sdoc-merge ├── setup ├── spring ├── sprockets ├── thor ├── tilt ├── tt ├── update ├── webpack └── webpack-dev-server ├── config.rb ├── config.ru ├── config ├── application.rb ├── boot.rb ├── cucumber.yml ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── active_admin.rb │ ├── application.rb │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── bugsnag.rb │ ├── content_security_policy.rb │ ├── cookies_serializer.rb │ ├── devise.rb │ ├── filter_parameter_logging.rb │ ├── geocoder.rb │ ├── high_voltage.rb │ ├── inflections.rb │ ├── kaminari_config.rb │ ├── mime_types.rb │ ├── new_framework_defaults.rb │ ├── new_framework_defaults_5_2.rb │ ├── new_framework_defaults_7_0.rb │ ├── new_framework_defaults_7_1.rb │ ├── pagy.rb │ ├── permissions_policy.rb │ ├── rakismet.rb │ ├── secret_token.rb │ ├── session_store.rb │ ├── setup_mail.rb │ ├── simple_form.rb │ ├── simple_form_bootstrap.rb │ └── wrap_parameters.rb ├── locales │ ├── about_translations.yml │ ├── en │ │ ├── about.en.yml │ │ ├── business_info.yml │ │ ├── contacts.en.yml │ │ ├── devise.en.yml │ │ ├── footer.en.yml │ │ ├── navigation.en.yml │ │ ├── restroom.en.yml │ │ ├── restrooms.en.yml │ │ ├── search.en.yml │ │ ├── signs.en.yml │ │ ├── simple_form.en.yml │ │ ├── splash.en.yml │ │ └── text_msg.en.yml │ ├── es │ │ ├── about.es.yml │ │ ├── business_info.es.yml │ │ ├── contacts.es.yml │ │ ├── devise.es.yml │ │ ├── footer.es.yml │ │ ├── navigation.es.yml │ │ ├── restroom.es.yml │ │ ├── restrooms.es.yml │ │ ├── search.es.yml │ │ ├── signs.es.yml │ │ ├── simple_form.es.yml │ │ ├── splash.es.yml │ │ └── text_msg.es.yml │ ├── fil │ │ ├── about.fil.yml │ │ ├── business_info.fil.yml │ │ ├── contacts.fil.yml │ │ ├── devise.fil.yml │ │ ├── footer.fil.yml │ │ ├── navigation.fil.yml │ │ ├── restroom.fil.yml │ │ ├── restrooms.fil.yml │ │ ├── search.fil.yml │ │ ├── signs.fil.yml │ │ ├── simple_form.fil.yml │ │ ├── splash.fil.yml │ │ └── text_msg.fil.yml │ ├── fr │ │ ├── about.fr.yml │ │ ├── business_info.yml │ │ ├── contacts.fr.yml │ │ ├── devise.fr.yml │ │ ├── footer.fr.yml │ │ ├── navigation.fr.yml │ │ ├── restroom.fr.yml │ │ ├── restrooms.fr.yml │ │ ├── search.fr.yml │ │ ├── signs.fr.yml │ │ ├── simple_form.fr.yml │ │ ├── splash.fr.yml │ │ └── text_msg.fr.yml │ ├── hi │ │ ├── about.hi.yml │ │ ├── business_info.yml │ │ ├── contacts.hi.yml │ │ ├── devise.hi.yml │ │ ├── footer.hi.yml │ │ ├── hi.yml │ │ ├── navigation.hi.yml │ │ ├── restroom.hi.yml │ │ ├── restrooms.hi.yml │ │ ├── search.hi.yml │ │ ├── signs.hi.yml │ │ ├── simple_form.hi.yml │ │ ├── splash.hi.yml │ │ └── text_msg.hi.yml │ ├── it │ │ ├── about.it.yml │ │ ├── business_info.yml │ │ ├── contacts.it.yml │ │ ├── devise.it.yml │ │ ├── footer.it.yml │ │ ├── navigation.it.yml │ │ ├── restroom.it.yml │ │ ├── restrooms.it.yml │ │ ├── search.it.yml │ │ ├── signs.it.yml │ │ ├── simple_form.it.yml │ │ ├── splash.it.yml │ │ └── text_msg.it.yml │ ├── pl │ │ ├── about.pl.yml │ │ ├── business_info.pl.yml │ │ ├── contacts.pl.yml │ │ ├── devise.pl.yml │ │ ├── footer.pl.yml │ │ ├── navigation.pl.yml │ │ ├── restroom.pl.yml │ │ ├── restrooms.pl.yml │ │ ├── search.pl.yml │ │ ├── signs.pl.yml │ │ ├── simple_form.pl.yml │ │ ├── splash.pl.yml │ │ └── text_msg.pl.yml │ └── pt-BR │ │ ├── about.pt-BR.yml │ │ ├── activerecord.pt-BR.yml │ │ ├── business_info.pt-BR.yml │ │ ├── contacts.pt-BR.yml │ │ ├── devise.pt-BR.yml │ │ ├── footer.pt-BR.yml │ │ ├── navigation.pt-BR.yml │ │ ├── pt-BR.yml │ │ ├── restroom.pt-BR.yml │ │ ├── restrooms.pt-BR.yml │ │ ├── search.pt-BR.yml │ │ ├── signs.pt-BR.yml │ │ ├── simple_form.pt-BR.yml │ │ ├── splash.pt-BR.yml │ │ └── text_msg.pt-BR.yml ├── puma.rb ├── routes.rb ├── spring.rb ├── storage.yml ├── webpack │ ├── development.js │ ├── environment.js │ ├── loaders │ │ └── erb.js │ ├── production.js │ └── test.js └── webpacker.yml ├── db ├── export.csv ├── migrate │ ├── 20131128044650_create_bathrooms.rb │ ├── 20131225210247_change_table.rb │ ├── 20131225221341_add_column_for_flags.rb │ ├── 20140117004118_add_visability.rb │ ├── 20140117055923_change_flags_to_up_vote_down_vote.rb │ ├── 20140119222501_add_countryfor_international_listings.rb │ ├── 20140207051319_devise_create_admin_users.rb │ ├── 20140207051321_create_active_admin_comments.rb │ ├── 20140315033524_add_unaccent_extension.rb │ ├── 20140413154842_rename_bathrooms_to_restrooms.rb │ ├── 20140423031801_change_access_and_bath_type_to_boolean.rb │ ├── 20151018191859_add_changing_table_flag_to_restrooms.rb │ ├── 20180107190215_add_edit_id_to_restrooms.rb │ ├── 20180306165419_add_approved_to_restrooms.rb │ └── 20180613231032_set_edit_id_to_id.rb ├── schema.rb └── seeds.rb ├── docker-compose.yml ├── features ├── edit.feature └── step_definitions │ └── edit_steps.rb ├── lib ├── assets │ └── .keep ├── tasks │ ├── .keep │ ├── assets.rake │ └── fix_accents.rake └── templates │ └── erb │ ├── controller │ └── view.html.erb │ └── scaffold │ ├── _form.html.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── new.html.erb │ └── show.html.erb ├── log └── .keep ├── package.json ├── postcss.config.js ├── promo └── rectangle_sticker_3_by_4_not_rasterized.psd ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico ├── fr-rr-sign-no-handi.pdf ├── fr-rr-sign-with-handi.pdf ├── robots.txt ├── rr-sign-no-handi.pdf └── rr-sign-with-handi.pdf ├── setup └── entry ├── spec ├── api │ └── v1 │ │ └── restrooms_spec.rb ├── controllers │ ├── pages_controller_spec.rb │ └── restrooms_controller_spec.rb ├── factories │ └── restrooms.rb ├── features │ ├── contacts_spec.rb │ └── restrooms_spec.rb ├── fixtures │ ├── guess_in_oakland.json │ ├── guess_in_vancouver.json │ └── guess_in_winnipeg.json ├── models │ ├── rating_level_spec.rb │ └── restroom_spec.rb ├── services │ └── save_restroom_spec.rb ├── spec_helper.rb └── support │ ├── factory_bot.rb │ ├── locations.rb │ ├── rspec.rb │ └── shared_examples │ └── localized_request.rb ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | **/.git 3 | **/.github 4 | **/node_modules 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.{md,markdown}] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | DEVISE_SECRET_KEY=3f4915489bd10fdbacb4f22dbf772a4be6e2d2d1616a1af7913f0f6645784ddffd6a71ab9f69a99ed7941f16d3092e1872bc4bc9add5a0615c630c90f94fc032 2 | RAILS_SECRET_KEY=4944cf251e3dbf309ed71ebcd8990a1479d793011cd4011761e3fbea9ecc59edefd0cb49a0ed9b5c0261ab0dda841962bb7dd28fd3f99579bfa2beec26329961 3 | RECAPTCHA_SITE_KEY=6Le_W5gUAAAAAJFOELNu2LkSR2E6sXYIVZrMe6V0 4 | RECAPTCHA_SECRET_KEY=6Le_W5gUAAAAABZpnGQtfVaQdfluuLrf8wihooeo 5 | COMPOSE_HTTP_TIMEOUT=360 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | setup/entry text eol=lf 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/blank.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Blank 3 | about: A free-form and empty issue for you to fill in any way you see fit 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/generic-proposal-issue-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Generic Proposal Issue Template 3 | about: Generic issue template for any proposed change. Has sections to add context 4 | and guidance for how to implement the proposal. Designed to make issues clear and 5 | easy to understand/work on. 6 | title: '' 7 | labels: '' 8 | assignees: '' 9 | 10 | --- 11 | 12 | _(This is a template. Please fill in the areas under each heading. Thanks!)_ 13 | 14 | _(You may delete this text at the top when done!)_ 15 | 16 | ## Scope / difficulty 17 | 18 | A concise description of what files this will change, or what topic areas this proposal includes. 19 | 20 | If you think this proposal is easy or hard, you can say so here, so contributors will know what to expect. 21 | 22 | ## Impact 23 | 24 | A concise description of what benefits and changes this proposal would introduce when complete. 25 | 26 | _(Helps convey what this means to the Refuge Restrooms project, and why this proposal is worth working on.)_ 27 | 28 | ## Rationale 29 | 30 | What motivated you to make this proposal. Why this proposal is needed, why it makes sense, why it is the right thing to do, etc. 31 | 32 | _(The human side of the reason for this proposal. Optional, but always nice to include!)_ 33 | 34 | ## Proposal 35 | 36 | The main proposal. 37 | 38 | Include info (including background and context) people will need to understand your proposal. 39 | 40 | Links and documentation that help explain parts of your proposal are welcome. 41 | 42 | ## How to actually do this: 43 | 44 | Any guidance on how to complete the proposal. Can be a concrete set of steps such as "Just need to edit this file [link-to-file-on-our-GitHub]", "This guide should help: [link]", etc. 45 | 46 | Links and documentation that help explain how to actually fix this problem/implement the proposal, if you have them, are welcome. 47 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Context 2 | - Fixes #[issueNumber] 3 | - short_summary_here 4 | 5 | # Summary of Changes 6 | 7 | - change_1_here 8 | - change_2_here 9 | 10 | # Checklist 11 | 12 | - [ ] Tested Mobile Responsiveness 13 | - [ ] Added Unit Tests 14 | - [ ] CI Passes 15 | - [ ] Deploys to Heroku on test Correctly (Maintainers will handle) 16 | - [ ] Added Documentation (Service and Code when required) 17 | 18 | # Screenshots 19 | 20 | ## Before 21 | 22 | ## After 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore the default SQLite database. 8 | /db/*.sqlite3 9 | /db/*.sqlite3-journal 10 | 11 | # Ignore all logfiles and tempfiles. 12 | /log/*.log 13 | /tmp 14 | 15 | ### Rails ### 16 | *.rbc 17 | *.sassc 18 | .sass-cache 19 | capybara-*.html 20 | .rspec 21 | /log 22 | /tmp 23 | /db/*.sqlite3 24 | /public/system 25 | /coverage/ 26 | /spec/tmp 27 | **.orig 28 | rerun.txt 29 | pickle-email-*.html 30 | config/initializers/secret_token.rb 31 | config/secrets.yml 32 | config/initializers/new_framework_defaults_5_1.rb 33 | config/initializers/application_controller_renderer.rb 34 | config/cable.yml 35 | bin/yarn 36 | 37 | ## Environment normalisation: 38 | /.bundle 39 | /vendor/bundle 40 | .env 41 | .powrc 42 | 43 | ## Ignore .DS_Store files in case people haven't setup a global gitignore 44 | .DS_Store 45 | 46 | ## editor temp files 47 | *.swp 48 | *.swo 49 | 50 | ## Vagrant working directory 51 | .vagrant 52 | ruby 53 | 54 | ## zsh rake pugin 55 | .rake_tasks 56 | 57 | /public/packs 58 | /public/packs-test 59 | /node_modules 60 | /yarn-error.log 61 | yarn-debug.log* 62 | .yarn-integrity 63 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | # The behavior of RuboCop can be controlled via the .rubocop.yml 2 | # configuration file. It makes it possible to enable/disable 3 | # certain cops (checks) and to alter their behavior if they accept 4 | # any parameters. The file can be placed either in your home 5 | # directory or in some project directory. 6 | # 7 | # RuboCop will start looking for the configuration file in the directory 8 | # where the inspected file is and continue its way up to the root directory. 9 | # 10 | # See https://docs.rubocop.org/rubocop/configuration 11 | 12 | require: 13 | - rubocop-rails 14 | - rubocop-rspec 15 | 16 | AllCops: 17 | NewCops: enable 18 | Exclude: 19 | - 'Gemfile' 20 | - '**/*.rake' 21 | - 'bin/**/*' 22 | - 'config/**/*' 23 | - 'db/**/*' 24 | - 'node_modules/**/*' 25 | - 'vendor/**/*' 26 | - 'tmp/**/*' 27 | - 'Rakefile' 28 | - 'config.rb' 29 | - 'config.ru' 30 | 31 | Style/Documentation: 32 | Enabled: false 33 | 34 | Style/FrozenStringLiteralComment: 35 | Enabled: false 36 | 37 | Style/StringLiterals: 38 | Enabled: false 39 | 40 | Metrics/BlockLength: 41 | AllowedMethods: 42 | - describe 43 | - context 44 | - factory 45 | - define 46 | 47 | RSpec/ExampleLength: 48 | Enabled: false 49 | 50 | RSpec/MultipleExpectations: 51 | Enabled: false 52 | 53 | Style/RegexpLiteral: 54 | AllowInnerSlashes: true 55 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.2.2 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | env: 2 | global: 3 | - CC_TEST_REPORTER_ID=c18df080592f9c99ca8080a6d5e052aa5fd3964044a0fe0b71e48f8e18998dc2 4 | language: minimal 5 | dist: jammy 6 | services: docker 7 | install: 8 | - docker-compose build 9 | before_script: 10 | - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter 11 | - chmod +x ./cc-test-reporter 12 | - ./cc-test-reporter before-build 13 | script: 14 | - docker-compose run web rubocop 15 | - docker-compose run -e "RAILS_ENV=test" web rake db:test:prepare spec 16 | after_script: 17 | - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT --prefix /refugerestrooms 18 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.2.2-slim 2 | 3 | # Add basic binaries 4 | RUN apt-get update \ 5 | && apt-get install -y curl g++ gcc libfontconfig libpq-dev make patch xz-utils chromium \ 6 | # Clean up the apt cache 7 | && rm -rf /var/lib/apt/lists/* 8 | 9 | # Specify a major version of Node.js to download and install 10 | ENV NODEJS_MAJOR_VERSION=16 11 | 12 | # Download and extract Node.js from archive supplied by nodejs.org 13 | RUN curl -L https://nodejs.org/dist/latest-v$NODEJS_MAJOR_VERSION\.x/SHASUMS256.txt -O \ 14 | && ARCHIVE_FILENAME=$(grep -o "node-*.*.*-linux-x64.tar.xz" SHASUMS256.txt) \ 15 | && curl -L https://nodejs.org/dist/latest-v$NODEJS_MAJOR_VERSION.x/$ARCHIVE_FILENAME -o nodejs.tar.xz \ 16 | && tar xf nodejs.tar.xz \ 17 | && mv ./node-v*-linux-x64 /usr/local/nodejs \ 18 | # Clean up the Node.js archive and SHASUMS256.txt 19 | && rm nodejs.tar.xz SHASUMS256.txt 20 | 21 | # Add Node.js binaries to PATH (includes Node and NPM, will include Yarn) 22 | ENV PATH="/usr/local/nodejs/bin/:${PATH}" 23 | 24 | # Install Yarn 25 | RUN npm install -g yarn 26 | 27 | # Make the "/refugerestrooms" folder, run all subsequent commands in that folder 28 | RUN mkdir /refugerestrooms 29 | WORKDIR /refugerestrooms 30 | 31 | # Install Ruby gems with Bundler 32 | COPY Gemfile Gemfile.lock /refugerestrooms/ 33 | RUN bundle install 34 | 35 | # Install Node.js packages with Yarn 36 | COPY package.json yarn.lock /refugerestrooms/ 37 | RUN yarn install --pure-lockfile && yarn cache clean 38 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | ruby '3.2.2' 3 | 4 | gem 'rails', '7.1.2' 5 | 6 | gem 'activeadmin', '~> 3.1.0' 7 | gem 'bootsnap', require: false 8 | gem 'bootstrap-sass', '>= 3.4.1' 9 | gem 'bugsnag' 10 | gem 'coffee-rails', '~> 4.2' 11 | gem 'country_select' 12 | gem 'devise', '~> 4.8.1' 13 | gem 'geocoder', '~> 1.6.1' 14 | gem 'grape', '~> 1.6.2' 15 | gem 'grape-pagy' 16 | gem 'grape-swagger' 17 | gem 'haml' 18 | gem 'high_voltage', '~> 3.0.0' 19 | gem 'http_accept_language' 20 | gem 'jbuilder', '~> 2.5' 21 | gem 'mail_form', '>= 1.7.0' 22 | gem 'net-smtp', require: false 23 | gem 'net-imap', require: false 24 | gem 'net-pop', require: false 25 | gem 'pagy' 26 | gem 'pg' 27 | gem 'pg_search' 28 | gem 'puma' 29 | gem 'rack-cors', :require => 'rack/cors' 30 | gem 'rack-jsonp' 31 | gem 'rakismet' 32 | gem 'sassc-rails' 33 | gem 'simple_form', '~> 5.0' 34 | gem 'sprockets', '< 4' 35 | gem 'turbolinks' 36 | gem 'uglifier', '>= 1.3.0' 37 | gem 'webpacker', '~> 5' 38 | 39 | group :development, :test do 40 | gem 'better_errors', '~> 2.9.1' 41 | gem 'binding_of_caller' 42 | gem 'factory_bot_rails', '~> 4.8.2' 43 | gem 'pry' 44 | gem 'rspec-rails' 45 | gem 'rubocop', require: false 46 | gem 'rubocop-rails', require: false 47 | gem 'rubocop-rspec', require: false 48 | end 49 | 50 | group :development do 51 | gem 'i18n-debug' 52 | end 53 | 54 | group :test do 55 | gem 'capybara' 56 | gem 'database_cleaner' 57 | gem 'cuprite' 58 | gem 'simplecov', '~> 0.22.0', require: false 59 | gem 'webmock', '~> 3.12.1' 60 | end 61 | 62 | group :doc do 63 | gem 'sdoc', require: false 64 | end 65 | 66 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 67 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 68 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | SaferstallsRails::Application.load_tasks 7 | 8 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "refugerestrooms", 3 | "description": "refuge heroku app.json", 4 | "scripts": { 5 | "postdeploy": "bundle exec rake db:migrate" 6 | }, 7 | "env": { 8 | "AKISMET_KEY": { 9 | "required": true 10 | }, 11 | "BUGSNAG_API_TOKEN": { 12 | "required": true 13 | }, 14 | "DEVISE_SECRET_KEY": { 15 | "required": true 16 | }, 17 | "EMAIL": { 18 | "required": true 19 | }, 20 | "EMAIL_PASSWORD": { 21 | "required": true 22 | }, 23 | "GOOGLE_MAPS_API_KEY": { 24 | "required": true 25 | }, 26 | "LANG": { 27 | "required": true 28 | }, 29 | "RACK_ENV": { 30 | "required": true 31 | }, 32 | "RAILS_ENV": { 33 | "required": true 34 | }, 35 | "RAILS_SECRET_KEY": { 36 | "required": true 37 | }, 38 | "RAILS_SERVE_STATIC_FILES": { 39 | "required": true 40 | }, 41 | "SECRET_KEY_BASE": { 42 | "required": true 43 | } 44 | }, 45 | "formation": { 46 | }, 47 | "addons": [ 48 | "heroku-postgresql" 49 | ], 50 | "buildpacks": [ 51 | { 52 | "url": "heroku/nodejs" 53 | }, 54 | { 55 | "url": "heroku/ruby" 56 | } 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /app/admin/admin_user.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.register AdminUser do 2 | permit_params :email, :password, :password_confirmation 3 | 4 | index do 5 | column :email 6 | column :current_sign_in_at 7 | column :last_sign_in_at 8 | column :sign_in_count 9 | actions 10 | end 11 | 12 | filter :email 13 | 14 | form do |f| 15 | f.inputs 'Admin Details' do 16 | f.input :email 17 | f.input :password 18 | f.input :password_confirmation 19 | end 20 | f.actions 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/admin/dashboard.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.register_page "Dashboard" do 2 | menu priority: 1, label: proc { I18n.t('active_admin.dashboard') } 3 | 4 | content title: proc { I18n.t('active_admin.dashboard') } do 5 | div class: 'blank_slate_container', id: 'dashboard_default_message' do 6 | span class: 'blank_slate' do 7 | span I18n.t('active_admin.dashboard_welcome.welcome') 8 | small I18n.t('active_admin.dashboard_welcome.call_to_action') 9 | end 10 | end 11 | 12 | # Here is an example of a simple dashboard with columns and panels. 13 | # 14 | # columns do 15 | # column do 16 | # panel "Recent Posts" do 17 | # ul do 18 | # Post.recent(5).map do |post| 19 | # li link_to(post.title, admin_post_path(post)) 20 | # end 21 | # end 22 | # end 23 | # end 24 | 25 | # column do 26 | # panel "Info" do 27 | # para "Welcome to ActiveAdmin." 28 | # end 29 | # end 30 | # end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/admin/restroom.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.register Restroom do 2 | permit_params :name, :street, :city, :state, :accessible, :changing_table, :unisex, :directions, 3 | :comment, :latitude, :longitude, :country, :edit_id, :approved 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/.keep -------------------------------------------------------------------------------- /app/assets/images/Logo-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/Logo-Small.png -------------------------------------------------------------------------------- /app/assets/images/Logo-lg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/Logo-lg.png -------------------------------------------------------------------------------- /app/assets/images/ToiletLogo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/ToiletLogo-large.png -------------------------------------------------------------------------------- /app/assets/images/ToiletLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/ToiletLogo.png -------------------------------------------------------------------------------- /app/assets/images/UnisexRestroom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/UnisexRestroom.png -------------------------------------------------------------------------------- /app/assets/images/city-photo-2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/city-photo-2x.jpg -------------------------------------------------------------------------------- /app/assets/images/city-photo-3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/city-photo-3x.jpg -------------------------------------------------------------------------------- /app/assets/images/city-photo-original-fullsize.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/city-photo-original-fullsize.jpg -------------------------------------------------------------------------------- /app/assets/images/city-photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/city-photo.jpg -------------------------------------------------------------------------------- /app/assets/images/currentLocation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/currentLocation.png -------------------------------------------------------------------------------- /app/assets/images/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/facebook.png -------------------------------------------------------------------------------- /app/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/favicon.ico -------------------------------------------------------------------------------- /app/assets/images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/github.png -------------------------------------------------------------------------------- /app/assets/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/layers-2x.png -------------------------------------------------------------------------------- /app/assets/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/layers.png -------------------------------------------------------------------------------- /app/assets/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/loading.gif -------------------------------------------------------------------------------- /app/assets/images/logo-100x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/logo-100x100.png -------------------------------------------------------------------------------- /app/assets/images/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/mail.png -------------------------------------------------------------------------------- /app/assets/images/marker-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/marker-circle.png -------------------------------------------------------------------------------- /app/assets/images/marker-circle2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/marker-circle2x.png -------------------------------------------------------------------------------- /app/assets/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/marker-icon-2x.png -------------------------------------------------------------------------------- /app/assets/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/marker-icon.png -------------------------------------------------------------------------------- /app/assets/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/marker-shadow.png -------------------------------------------------------------------------------- /app/assets/images/patreon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/patreon.png -------------------------------------------------------------------------------- /app/assets/images/play-store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/play-store.png -------------------------------------------------------------------------------- /app/assets/images/qrcode-sign-no-handi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/qrcode-sign-no-handi.png -------------------------------------------------------------------------------- /app/assets/images/qrcode-sign-with-handi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/qrcode-sign-with-handi.png -------------------------------------------------------------------------------- /app/assets/images/rr-sign-no-handi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/rr-sign-no-handi.png -------------------------------------------------------------------------------- /app/assets/images/rr-sign-with-handi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/rr-sign-with-handi.png -------------------------------------------------------------------------------- /app/assets/images/show-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/show-icon.png -------------------------------------------------------------------------------- /app/assets/images/splashlanding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/splashlanding.png -------------------------------------------------------------------------------- /app/assets/images/submit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/submit.png -------------------------------------------------------------------------------- /app/assets/images/text-msg-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/text-msg-demo.png -------------------------------------------------------------------------------- /app/assets/images/tumblr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/tumblr.png -------------------------------------------------------------------------------- /app/assets/images/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/twitter.png -------------------------------------------------------------------------------- /app/assets/images/unisex-slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/assets/images/unisex-slider.png -------------------------------------------------------------------------------- /app/assets/javascripts/active_admin.js: -------------------------------------------------------------------------------- 1 | //= require active_admin/base 2 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_refuge_core.scss: -------------------------------------------------------------------------------- 1 | @import 'sass/_mixins'; 2 | @import 'sass/_screen_sizes'; 3 | @import 'sass/_variables'; 4 | @import 'framework_and_overrides'; 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/active_admin.scss: -------------------------------------------------------------------------------- 1 | // SASS variable overrides must be declared before loading up Active Admin's styles. 2 | // 3 | // To view the variables that Active Admin provides, take a look at 4 | // `app/assets/stylesheets/active_admin/mixins/_variables.css.scss` in the 5 | // Active Admin source. 6 | // 7 | // For example, to change the sidebar width: 8 | // $sidebar-width: 242px; 9 | 10 | // Active Admin's got SASS! 11 | @import "active_admin/mixins"; 12 | @import "active_admin/base"; 13 | 14 | // Overriding any non-variable SASS must be done after the fact. 15 | // For example, to change the default status-tag color: 16 | // 17 | // .status_tag { background: #6090DB; } 18 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | */ 13 | 14 | @import 'refuge_core'; 15 | @import 'components/*'; 16 | @import 'pages/*'; 17 | @import 'restrooms/*'; 18 | @import 'map/*'; 19 | @import '_mobile'; 20 | -------------------------------------------------------------------------------- /app/assets/stylesheets/components/nav.scss: -------------------------------------------------------------------------------- 1 | .navbar-default{ 2 | padding: 5px 0px; 3 | background-color: transparent; 4 | border-color: transparent; 5 | 6 | .navbar-brand { 7 | color: white; 8 | width: 16em; 9 | padding: 13.5px 60px; 10 | &:hover { 11 | color: white; 12 | } 13 | &:focus { 14 | color: $light-purple; 15 | } 16 | } 17 | 18 | ul.navbar-nav > li > a { 19 | font-size: 10pt; 20 | color: white; 21 | &:hover, &:focus { 22 | color: $light-purple; 23 | } 24 | } 25 | 26 | .navbar-toggle { 27 | color: white; 28 | &:hover { 29 | background-color: white; 30 | color: black; 31 | } 32 | } 33 | 34 | .toiletLogo { 35 | width: 45px; 36 | height: 45px; 37 | background-image: asset-url("logo-100x100.png"); 38 | background-size: auto 100%; 39 | background-repeat: no-repeat; 40 | position: relative; 41 | float: left; 42 | cursor: pointer; 43 | top: 2px 44 | } 45 | 46 | .dropdown-menu > li { 47 | &:not(:last-child) { 48 | border-bottom: 1px solid $light-gray; 49 | } 50 | 51 | > a { 52 | white-space: normal; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/assets/stylesheets/components/search.scss: -------------------------------------------------------------------------------- 1 | .current-location-button { 2 | .fa-refresh { 3 | display: none; 4 | } 5 | } 6 | 7 | .submit-search-button { 8 | .fa-refresh { 9 | display: none; 10 | } 11 | } 12 | 13 | .header { 14 | .navbar-toggle:hover { 15 | background-color: $light-purple; 16 | border-color: $light-purple 17 | } 18 | } 19 | 20 | 21 | .search-container { 22 | margin: 10px 0px; 23 | 24 | .search-bar { 25 | height: 44px; 26 | border: 2px solid $purple; 27 | } 28 | 29 | .btn { 30 | border: 2px solid $purple; 31 | background-color: white; 32 | color: $purple; 33 | height: 44px; 34 | } 35 | } 36 | 37 | 38 | 39 | .locating { 40 | background-position: 50%; 41 | color: white; 42 | background-color: #8377af; 43 | border-color: #8377af; 44 | .fa-location-arrow { 45 | display: none; 46 | } 47 | .fa-search { 48 | display: none; 49 | } 50 | .fa-refresh { 51 | display: inherit; 52 | } 53 | .btn-text { 54 | display: none 55 | } 56 | } 57 | 58 | .current-location-button { 59 | border-left: 1px solid black 60 | } 61 | 62 | // .submit-search-button:hover, 63 | // .submit-search-button:focus, 64 | // .current-location-button:hover, 65 | // .current-location-button:focus, { 66 | // background-color: white; 67 | // color: black; 68 | // border-color: $light-purple; 69 | // } 70 | -------------------------------------------------------------------------------- /app/assets/stylesheets/framework_and_overrides.scss: -------------------------------------------------------------------------------- 1 | @import 'bootstrap'; 2 | 3 | // import the CSS framework 4 | // make all images responsive by default 5 | 6 | body { 7 | overflow-x: hidden; 8 | font-family: $font-stack; 9 | font-size: 1.4em; 10 | background: white; 11 | color: $base-color; 12 | } 13 | 14 | img { 15 | @extend .img-responsive; 16 | margin: 0 auto; 17 | } 18 | 19 | header { 20 | background-color: $purple; 21 | } 22 | // THESE ARE EXAMPLES YOU CAN MODIFY 23 | // create your own classes 24 | // to make views framework-neutral 25 | 26 | // apply styles to HTML elements 27 | // to make views framework-neutral 28 | 29 | // This fixes Bootstrap from messing with Google Maps CSS 30 | #mapArea img { 31 | max-width: none; 32 | } 33 | #mapArea label { 34 | width: auto; 35 | display: inline; 36 | } 37 | 38 | // Removes the negative margin applied by Bootstrap 39 | .row { 40 | margin-left: auto; 41 | margin-right: auto; 42 | } 43 | 44 | // Eliminates double-padding due to nested .container divs 45 | .header > .container > .container { 46 | padding-left: 0; 47 | padding-right: 0; 48 | } 49 | -------------------------------------------------------------------------------- /app/assets/stylesheets/map/main.scss: -------------------------------------------------------------------------------- 1 | #mapArea { 2 | width: 100%; 3 | height: 400px; 4 | } 5 | 6 | .markerPopup { 7 | .changingTable, .unisexRestroom, .ADARestroom { 8 | display: inline-block; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/pages/api_docs.scss: -------------------------------------------------------------------------------- 1 | #swagger-ui-container { 2 | margin-top: 20px; 3 | 4 | .info .title { 5 | display: none; 6 | } 7 | .opblock-summary-get { 8 | background-color: #e7f0f7; 9 | border: 1px solid #c3d9ec; 10 | cursor: pointer; 11 | padding: 5px; 12 | 13 | .opblock-summary-method { 14 | background-color: #0f6ab4; 15 | color: #fff; 16 | margin: 5px; 17 | padding: 5px; 18 | } 19 | } 20 | 21 | .opblock-body { 22 | background-color: #e7f0f7; 23 | border: 1px solid #c3d9ec; 24 | padding: 5px; 25 | } 26 | 27 | .response-col_description pre { 28 | overflow: scroll; 29 | width: 80vw; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/assets/stylesheets/pages/splash.scss: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100% 3 | } 4 | 5 | body { 6 | height: 100% 7 | } 8 | 9 | .splash-background { 10 | background: image-url('city-photo.jpg') no-repeat 50% 50% fixed; 11 | -webkit-background-size: cover; 12 | -moz-background-size: cover; 13 | -o-background-size: cover; 14 | background-size: cover; 15 | min-width: 100%; 16 | min-height: 100%; 17 | 18 | nav { 19 | background: rgb(0, 0, 0); 20 | background: rgba(0, 0, 0, 0.7); 21 | @include border-radius(5px); 22 | } 23 | 24 | footer { 25 | color: white; 26 | background-color: transparent; 27 | bottom: 0px; 28 | left: 0px; 29 | right: 0px; 30 | margin-bottom: 25px; 31 | a { 32 | color: white; 33 | text-decoration: underline; 34 | &.iconLink { 35 | text-decoration: none 36 | } 37 | } 38 | } 39 | 40 | } 41 | 42 | .splash-content { 43 | padding: 75px 10px 0px 10px; 44 | 45 | .search-bar { 46 | height: 70px; 47 | font-size: 18pt; 48 | } 49 | 50 | .input-group-btn > .btn { 51 | height: 70px; 52 | width: 70px; 53 | &:hover { 54 | border-color: $dark-purple; 55 | } 56 | } 57 | 58 | .splash-text-container { 59 | @include border-radius(5px); 60 | color: white; 61 | background: rgb(0, 0, 0); /* fallback color */ 62 | background: rgba(0, 0, 0, 0.6); 63 | } 64 | 65 | h1 { 66 | font-weight: bold; 67 | font-size: 34pt; 68 | padding-bottom: 20px 69 | } 70 | 71 | h3 { 72 | font-weight: 400; 73 | padding-top: 20px 74 | } 75 | 76 | .splash-bottom-padding { 77 | padding-bottom: 60px 78 | } 79 | 80 | .splash-add-restroom-btn { 81 | width: 100%; 82 | font-size: 16pt; 83 | font-weight: bold; 84 | margin-bottom: 40px; 85 | @include box-shadow(7px 7px 24px 0px rgba(50, 50, 50, 0.75)); 86 | 87 | i { 88 | vertical-align: middle; 89 | margin-left: 20px 90 | } 91 | } 92 | } 93 | 94 | .top-cities-container { 95 | padding: 5px; 96 | color: white; 97 | background: rgb(0, 0, 0); /* fallback color */ 98 | background: rgba(0, 0, 0, 0.4); 99 | p { 100 | margin: 0 101 | } 102 | a { 103 | color: white; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /app/assets/stylesheets/restrooms/new.scss: -------------------------------------------------------------------------------- 1 | .guess-btn { 2 | margin-top: 5px; 3 | margin-bottom: 15px; 4 | .fa-refresh { 5 | display: none 6 | } 7 | 8 | &.locating { 9 | .fa-refresh { 10 | padding: 0px 10px; 11 | display: inherit 12 | } 13 | } 14 | } 15 | div.nearby-container > h2 { 16 | margin-top: 5px; 17 | } 18 | .new-restrooms-form-container { 19 | margin-top: 32px; 20 | } 21 | .submit-new-bathroom-form { 22 | margin-top: 32px; 23 | } 24 | -------------------------------------------------------------------------------- /app/assets/stylesheets/restrooms/restroom-list.scss: -------------------------------------------------------------------------------- 1 | // Restrooms List 2 | .restrooms-list { 3 | display: block; 4 | padding: 0; 5 | list-style: none; 6 | 7 | .listItem { 8 | display: block; 9 | width: 100%; 10 | padding-bottom: 1em; 11 | margin-bottom: 1em; 12 | border-bottom: 1px solid $gray; 13 | &:last-child { 14 | border-bottom: none; 15 | } 16 | } 17 | 18 | .listItemImage { 19 | display: inline-block; 20 | vertical-align: top; 21 | float: left; 22 | margin: 0.25em 1%; 23 | width: 8%; 24 | height: 8vw; 25 | background: #41326b asset-url("ToiletLogo.png") 50% 50% no-repeat; 26 | background-size: 60%; 27 | border-radius: $rounded-corners; 28 | } 29 | 30 | .itemInfo { 31 | display: inline-block; 32 | vertical-align: top; 33 | float: left; 34 | width: 58%; 35 | margin: 0 1%; 36 | 37 | a { 38 | font-size: 15px; 39 | } 40 | 41 | .itemStreet { 42 | margin-bottom: 0.5em; 43 | font-size: 14px; 44 | } 45 | 46 | .itemRating { 47 | width: 60%; 48 | min-width: 105px; 49 | max-width: 150px; 50 | border-radius: $rounded-corners; 51 | color: #FFF; 52 | text-align: center; 53 | font-family: $font-stack; 54 | font-size: 14px; 55 | padding: 0.5em; 56 | margin: 0; 57 | } 58 | } 59 | 60 | .itemExtraInfo { 61 | display: inline-block; 62 | vertical-align: top; 63 | float: right; 64 | width: 27%; 65 | margin: 0 0.5%; 66 | 67 | .itemDistance { 68 | font-size: 12px; 69 | padding-bottom: 1em; 70 | text-align: right; 71 | } 72 | } 73 | 74 | .itemIcons { 75 | text-align: right; 76 | 77 | > * { 78 | display: inline-block; 79 | } 80 | } 81 | 82 | 83 | @include tablet { 84 | .listItemImage { 85 | width: 55px; 86 | height: 55px; 87 | } 88 | } 89 | 90 | @include desktop { 91 | .listItemImage { 92 | width: 55px; 93 | height: 55px; 94 | } 95 | .itemInfo { 96 | margin: 0 0.5%; 97 | .itemName { 98 | a { 99 | font-size: 18px; 100 | } 101 | } 102 | .itemStreet { 103 | font-size: 15px; 104 | } 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /app/assets/stylesheets/sass/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin border-radius($radius) { 2 | -webkit-border-radius: $radius; 3 | -moz-border-radius: $radius; 4 | border-radius: $radius; 5 | } 6 | 7 | @mixin text-shadow($attributes...){ 8 | -webkit-text-shadow: $attributes; 9 | -moz-text-shadow: $attributes; 10 | text-shadow: $attributes; 11 | } 12 | 13 | @mixin box-shadow($attributes...){ 14 | -webkit-box-shadow: $attributes; 15 | -moz-box-shadow: $attributes; 16 | box-shadow: $attributes; 17 | } 18 | 19 | @mixin shadow($color) { 20 | @include box-shadow(0px 0px 15px 0px $color); 21 | } 22 | 23 | @mixin inset-shadow($color) { 24 | @include box-shadow(inset 0px 0px 15px 0px $color); 25 | } 26 | 27 | @mixin top-bottom-inset-shadow($offset, $blur, $spread, $color) { 28 | @include box-shadow(inset 0px $offset $blur $spread $color, inset 0px #{-$offset} $blur $spread $color); 29 | } 30 | 31 | @mixin inset-text-shadow { 32 | text-shadow: 1px 1px 0 white; 33 | } 34 | 35 | @mixin outset-text-shadow { 36 | text-shadow: -1px -1px 0 white; 37 | } 38 | -------------------------------------------------------------------------------- /app/assets/stylesheets/sass/_screen_sizes.sass: -------------------------------------------------------------------------------- 1 | $tablet-width: 768px 2 | $desktop-width: 1024px 3 | 4 | @mixin tablet 5 | @media (min-width: #{$tablet-width}) and (max-width: #{$desktop-width - 1px}) 6 | @content 7 | 8 | @mixin desktop 9 | @media (min-width: #{$desktop-width}) 10 | @content 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | /*All From Susy File*/ 2 | 3 | $font-stack: Ubuntu, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Cantarell, "Helvetica Neue", sans-serif; 4 | $primary-color: #333333; 5 | $purple: #41326B; 6 | $light-purple: #8377af; 7 | $dark-purple: #0E0036; 8 | $base-color: #161616; 9 | $secondary-background: white; 10 | $green: #69b94a; 11 | $yellow: #f5a939; 12 | $red: #d6564b; 13 | $gray: #AAA; 14 | $light-gray: #eee; 15 | $white: #FFFFFF; 16 | $rounded-corners: 5px; 17 | -------------------------------------------------------------------------------- /app/controllers/api/base.rb: -------------------------------------------------------------------------------- 1 | module API 2 | class Base < Grape::API 3 | mount API::V1::Base 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/api/docs_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class DocsController < ApplicationController 3 | def index; end 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/api/v1/base.rb: -------------------------------------------------------------------------------- 1 | # TODO: autoloading order changed. This should be managed by configs instead: 2 | # https://guides.rubyonrails.org/v7.0/autoloading_and_reloading_constants.html#autoloading-when-the-application-boots 3 | require_relative 'restrooms' 4 | 5 | module API 6 | module V1 7 | class Base < Grape::API 8 | use Rack::JSONP 9 | mount API::V1::Restrooms 10 | 11 | add_swagger_documentation base_path: '/api', api_version: 'v1', hide_documentation_path: true 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | include Pagy::Backend 5 | 6 | protect_from_forgery with: :exception 7 | 8 | around_action :switch_locale 9 | before_action :mobile_filter_header 10 | 11 | def mobile_filter_header 12 | @mobile = true 13 | end 14 | 15 | def switch_locale(&) 16 | locale = http_accept_language.language_region_compatible_from(I18n.available_locales) 17 | locale ||= I18n.default_locale 18 | 19 | I18n.with_locale(locale, &) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/contacts_controller.rb: -------------------------------------------------------------------------------- 1 | require_relative '../helpers/recaptcha_helper' 2 | 3 | class ContactsController < ApplicationController 4 | def new 5 | @contact = Contact.new(restroom_id: params['restroom_id'], restroom_name: params['restroom_name']) 6 | end 7 | 8 | # rubocop:disable Metrics/AbcSize 9 | # rubocop:disable Metrics/MethodLength 10 | def create 11 | @contact = Contact.new(params[:contact]) 12 | unless @contact.valid? 13 | flash.now[:error] = I18n.t('contacts.submitted.cannot-send') 14 | render :new 15 | return 16 | end 17 | 18 | # Verify recaptcha code 19 | recaptcha_response = params['g-recaptcha-response'] 20 | unless RecaptchaHelper.valid_token? recaptcha_response 21 | flash.now[:error] = I18n.t('helpers.reCAPTCHA.failed') 22 | render :new 23 | return 24 | end 25 | 26 | @contact.request = request 27 | @contact.deliver 28 | flash.now[:error] = nil 29 | flash.now[:notice] = I18n.t('contacts.submitted.thank-you-exclamation') 30 | end 31 | # rubocop:enable Metrics/AbcSize 32 | # rubocop:enable Metrics/MethodLength 33 | end 34 | -------------------------------------------------------------------------------- /app/controllers/pages_controller.rb: -------------------------------------------------------------------------------- 1 | class PagesController < ApplicationController 2 | include HighVoltage::StaticPage 3 | layout 'splash', only: [:index] 4 | end 5 | -------------------------------------------------------------------------------- /app/helpers/pagy_helper.rb: -------------------------------------------------------------------------------- 1 | module PagyHelper 2 | include Pagy::Frontend 3 | end 4 | -------------------------------------------------------------------------------- /app/helpers/recaptcha_helper.rb: -------------------------------------------------------------------------------- 1 | require 'net/http' 2 | require 'uri' 3 | require 'json' 4 | 5 | module RecaptchaHelper 6 | def self.valid_token?(token) 7 | json_body = verify(token) 8 | 9 | if json_body['success'] 10 | true 11 | else 12 | false 13 | end 14 | end 15 | 16 | def self.verify(token) 17 | # Get secret from env 18 | secret = ENV.fetch('RECAPTCHA_SECRET_KEY', nil) 19 | 20 | uri = URI('https://www.google.com/recaptcha/api/siteverify') 21 | request = Net::HTTP::Post.new(uri) 22 | request.set_form_data('secret' => secret, 'response' => token) 23 | response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |https| 24 | https.request(request) 25 | end 26 | 27 | JSON.parse(response.body) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /app/helpers/restrooms_helper.rb: -------------------------------------------------------------------------------- 1 | module RestroomsHelper 2 | KILO_DISTANCE_CONVERSION = 1.609344 3 | def miles_to_kilometers(miles) 4 | miles * KILO_DISTANCE_CONVERSION 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/javascript/packs/application.js: -------------------------------------------------------------------------------- 1 | // Vendor 2 | import Rails from '@rails/ujs' 3 | Rails.start() 4 | 5 | require('jquery') 6 | import 'bootstrap/dist/js/bootstrap' 7 | 8 | // Views 9 | import './views/restrooms/index' 10 | import './views/restrooms/new' 11 | import './views/restrooms/restrooms' 12 | import './views/restrooms/search' 13 | import ApiDocs from './views/api/docs' 14 | 15 | document.addEventListener('DOMContentLoaded', function() { 16 | if (document.getElementById('swagger-ui-container') != null ) { ApiDocs.loadSearch() } 17 | }) 18 | -------------------------------------------------------------------------------- /app/javascript/packs/views/api/docs/index.js: -------------------------------------------------------------------------------- 1 | import SwaggerUI from 'swagger-ui' 2 | 3 | export default { 4 | loadSearch() { 5 | new SwaggerUI({ 6 | url: '/api/swagger_doc.json', 7 | dom_id: '#swagger-ui-container', 8 | }) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /app/javascript/packs/views/restrooms/index.js: -------------------------------------------------------------------------------- 1 | import { Maps } from '../../lib/maps'; 2 | 3 | let URLParamsParser = window.URLSearchParams; 4 | 5 | // Polyfill for old browsers. 6 | if (!URLParamsParser) { 7 | URLParamsParser = function (locationSearch) { 8 | this.get = (key) => this.queryParams[key]; 9 | this.queryParams = locationSearch 10 | .slice(1) 11 | .split('&') 12 | .map(param => param.split('=')) 13 | .reduce((acc, value) => { 14 | return acc.concat(value); 15 | }, []) 16 | .reduce((acc, currValue, currIdx, ary) => { 17 | if(currIdx % 2 == 0) { 18 | acc[currValue] = ary[currIdx + 1]; 19 | } 20 | return acc; 21 | }, {}); 22 | } 23 | } 24 | 25 | $(function(){ 26 | function getSearchParams() { 27 | const { search: search } = location; 28 | return new URLParamsParser(search); 29 | } 30 | 31 | if (getSearchParams().get('view') == 'map') { 32 | $("#list").hide(); 33 | $.get('/restrooms' + window.location.search , {}, (points) => { 34 | const lat = getSearchParams().get('lat'); 35 | const long = getSearchParams().get('long'); 36 | 37 | Maps.loadMapWithPoints(lat, long, points); 38 | $("#mapContainer").fadeIn(500); 39 | }, 'json'); 40 | } else { 41 | $("#mapContainer").hide(); 42 | } 43 | }); 44 | -------------------------------------------------------------------------------- /app/javascript/packs/views/restrooms/restrooms.js: -------------------------------------------------------------------------------- 1 | // Place all the behaviors and hooks related to the matching controller here. 2 | // All this logic will automatically be available in application.js. 3 | // You can use CoffeeScript in this file: http://coffeescript.org/ 4 | 5 | $(() => { 6 | const filters = { 7 | '#ada_filter': 'accessible', 8 | '#unisex_filter': 'unisex', 9 | '#changing_table_filter': 'changing_table' 10 | }; 11 | 12 | function getSearchParams() { 13 | const { search: search } = location; 14 | return new URLSearchParams(search); 15 | } 16 | function applyFilters(filters) { 17 | const { origin: url, pathname: path } = location; 18 | const searchParams = getSearchParams(); 19 | searchParams.set('filters', filters); 20 | location = `${url}${path}?${searchParams.toString()}` 21 | } 22 | 23 | function getFilters() { 24 | const searchParams = getSearchParams(); 25 | const filters = searchParams.get('filters') || ''; 26 | return filters.split(',').filter(filter => filter && filter.length > 0); 27 | } 28 | 29 | function removeFilter(toRemove) { 30 | const filters = 31 | getFilters() 32 | .filter((filter) => filter != toRemove); 33 | 34 | applyFilters(filters); 35 | } 36 | 37 | function addFilter(filter) { 38 | let filters = getFilters(); 39 | 40 | if (filters.indexOf(filter) == -1) { 41 | filters.push(filter); 42 | } 43 | 44 | applyFilters(filters); 45 | } 46 | 47 | function addOnClickEvent(filterElementId) { 48 | const filter = filters[filterElementId]; 49 | $(filterElementId).click(function() { 50 | if ($(this).hasClass("active")) { 51 | removeFilter(filter); 52 | } else { 53 | addFilter(filter); 54 | } 55 | }); 56 | } 57 | 58 | Object.keys(filters).forEach(addOnClickEvent); 59 | }); 60 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/mailers/.keep -------------------------------------------------------------------------------- /app/models/admin_user.rb: -------------------------------------------------------------------------------- 1 | class AdminUser < ApplicationRecord 2 | # Include default devise modules. Others available are: 3 | # :confirmable, :lockable, :timeoutable and :omniauthable 4 | devise :database_authenticatable, 5 | :recoverable, :rememberable, :trackable, :validatable 6 | end 7 | -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/app/models/concerns/.keep -------------------------------------------------------------------------------- /app/models/contact.rb: -------------------------------------------------------------------------------- 1 | class Contact < MailForm::Base 2 | attribute :name, validate: true 3 | attribute :email, validate: URI::MailTo::EMAIL_REGEXP 4 | attribute :restroom_id, allow_blank: true 5 | attribute :restroom_name, allow_blank: true 6 | attribute :message 7 | attribute :nickname, captcha: true 8 | 9 | validate :restroom_must_exist 10 | 11 | def restroom_must_exist 12 | return if restroom_id.blank? 13 | return if Restroom.exists?(id: restroom_id, name: restroom_name) 14 | 15 | errors.add(:base, "Must be valid restroom ID and name") 16 | end 17 | 18 | # Declare the e-mail headers. It accepts anything the mail method 19 | # in ActionMailer accepts. 20 | def headers 21 | { 22 | subject: "My Contact Form #{restroom_id}", 23 | to: "refugerestrooms@gmail.com", 24 | from: %("#{name}" <#{email}>), # :from overriden by google smtp config 25 | reply_to: %("#{name}" <#{email}>) 26 | } 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /app/models/rating_level.rb: -------------------------------------------------------------------------------- 1 | class RatingLevel 2 | def self.for_restroom(restroom) 3 | percentage = restroom.rating_percentage 4 | 5 | if percentage > 70 6 | green 7 | elsif percentage > 50 8 | yellow 9 | else 10 | red 11 | end 12 | end 13 | 14 | def self.green 15 | new('Green') 16 | end 17 | 18 | def self.yellow 19 | new('Yellow') 20 | end 21 | 22 | def self.red 23 | new('Red') 24 | end 25 | 26 | def initialize(level) 27 | @level = level 28 | end 29 | 30 | def hash 31 | @level.hash 32 | end 33 | 34 | def ==(other) 35 | eql?(other) 36 | end 37 | 38 | def eql?(other) 39 | self.class == other.class && to_s == other.to_s 40 | end 41 | 42 | def to_s 43 | @level.to_s 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /app/services/save_restroom.rb: -------------------------------------------------------------------------------- 1 | class SaveRestroom 2 | def initialize(restroom) 3 | @restroom = restroom 4 | end 5 | 6 | def call 7 | if @restroom.spam? 8 | @restroom.errors.add(:spam, 'This restroom is spam') 9 | else 10 | Restroom.transaction do 11 | @restroom.save 12 | @restroom.update(edit_id: @restroom.id) if @restroom.approved? 13 | end 14 | end 15 | @restroom 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/api/docs/index.html: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /app/views/contacts/create.html.haml: -------------------------------------------------------------------------------- 1 | .container 2 | %h1= t('contacts.submitted.thank-you-period') 3 | %p.centered-text= t('contacts.submitted.we-will-get-back-to-you') 4 | -------------------------------------------------------------------------------- /app/views/contacts/new.html.haml: -------------------------------------------------------------------------------- 1 | - if @contact.restroom_name.present? 2 | %h1= t('.request-edit-for-restroom', restroom_name: @contact.restroom_name) 3 | - else 4 | %h1= t('.contact-title') 5 | = simple_form_for @contact, html: {class: 'form-vertical headroom'} do |f| 6 | %p 7 | = f.input :name, :required => true 8 | = f.input :email, :required => true 9 | = f.input :message, :as => :text, :required => false, :input_html => {:rows => 10} 10 | .hidden 11 | = f.hidden_field :restroom_id, :required => false 12 | = f.hidden_field :restroom_name, :required => false 13 | = f.hidden_field :nickname, :hint => t('.leave-this-field-blank') 14 | .form-group 15 | .g-recaptcha{'data-sitekey' => "#{ENV['RECAPTCHA_SITE_KEY']}"} 16 | .form-actions 17 | = f.button :submit, :class=> "linkbutton" 18 | -------------------------------------------------------------------------------- /app/views/layouts/_disqus_tag.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | comments powered by Disqus 26 | -------------------------------------------------------------------------------- /app/views/layouts/_footer.html.haml: -------------------------------------------------------------------------------- 1 | %footer 2 | .footer 3 | %a.iconLink{:href => "https://github.com/RefugeRestrooms/refugerestrooms", :aria => { :label => t('.aria-labels.github')}} 4 | %i.icon.fa.fa-github-square.fa-3x 5 | %a.iconLink{:href => "https://twitter.com/refugerestrooms", :aria => { :label => t('.aria-labels.twitter')}} 6 | %i.icon.fa.fa-twitter-square.fa-3x 7 | %a.iconLink{:href => "https://www.facebook.com/refugerestrooms", :aria => { :label => t('.aria-labels.facebook')}} 8 | %i.icon.fa.fa-facebook-square.fa-3x 9 | %a.iconLink{:href => contact_path, :aria => { :label => t('.aria-labels.email')}} 10 | %i.icon.fa.fa-envelope.fa-3x 11 | %br/ 12 | = t('.refuge-restrooms-is-open-source') 13 | %a{:href => "https://github.com/RefugeRestrooms/refugerestrooms"} #{t('.code-on-github')} 14 | %br/ 15 | = t('.contribute-to-the-project') 16 | %a{:href => "https://patreon.com/refugerestrooms"} #{t('.on-patreon')} 17 | %br/ 18 | = "\© #{t('.copyleft')} #{Date.today.year} #{t('.refuge-restrooms')}".html_safe 19 | 20 | -------------------------------------------------------------------------------- /app/views/layouts/_head.html.haml: -------------------------------------------------------------------------------- 1 | %meta{:content => "width=device-width, initial-scale=1.0", :name => "viewport"}/ 2 | %title= content_for?(:title) ? yield(:title) : "REFUGE Restrooms" 3 | %meta{:content => content_for?(:description) ? yield(:description) : "Refuge Restrooms", :name => "description"}/ 4 | %meta{:content => "gender neutral restrooms,gender,neutral,restrooms, unisex restrooms, unisex, restrooms, refuge restrooms, refuge, restrooms", :name => "keywords"}/ 5 | %link{:href => "//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css", :rel => "stylesheet", :name => "fontawesome"}/ 6 | %meta{:content => "RefugeRestrooms.org", :name => "author"}/ 7 | %meta{:content => "initial-scale=1, maximum-scale=1", :name => "viewport"}/ 8 | 9 | %script{:src => "https://maps.googleapis.com/maps/api/js?v=quarterly&libraries=places&key=AIzaSyCEjTsxAkHtqGhECdsqNwwpW5pslQcJuuE"} 10 | = javascript_include_tag "https://www.google.com/recaptcha/api.js", :async => true, :defer => true 11 | = stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true 12 | = javascript_pack_tag "application", "data-turbolinks-track": "reload" 13 | = csrf_meta_tags 14 | = render 'layouts/piwik_tag' 15 | 16 | -------------------------------------------------------------------------------- /app/views/layouts/_header.html.haml: -------------------------------------------------------------------------------- 1 | .header 2 | .container 3 | = render 'layouts/navigation' 4 | = render 'layouts/search' 5 | -------------------------------------------------------------------------------- /app/views/layouts/_messages.html.haml: -------------------------------------------------------------------------------- 1 | - flash.each do |name, msg| 2 | - if msg.is_a?(String) 3 | %div{:class => "alert alert-#{name == :notice ? "success" : "danger"}"} 4 | %button.close{"aria-hidden" => "true", "data-dismiss" => "alert", :type => "button"} × 5 | = content_tag :div, msg, :id => "flash_#{name}" 6 | -------------------------------------------------------------------------------- /app/views/layouts/_navigation.html.haml: -------------------------------------------------------------------------------- 1 | .container 2 | .row.min-headroom 3 | .col-xs-12.nav-column 4 | %nav.nav.navbar-default{:role => "navigation"} 5 | / Brand and toggle get grouped for better mobile display 6 | .navbar-header 7 | %a#logo.toiletLogo{:href => "/"} 8 | .navbar-brand Refuge Restrooms 9 | %button.navbar-toggle{"data-target" => "#bs-example-navbar-collapse-1", "data-toggle" => "collapse", :type => "button"} 10 | %span.sr-only= t('.toggle-navigation-button-label') 11 | %i.fa.fa-bars.fa-2x 12 | / Collect the nav links, forms, and other content for toggling 13 | #bs-example-navbar-collapse-1.collapse.navbar-collapse 14 | %ul.nav.navbar-nav.navbar-right 15 | %li= link_to t('.submit-a-new-restroom-hyperlink-label'), new_restroom_path 16 | %li= link_to t('.about-hyperlink-label'), page_path('about') 17 | %li= link_to t('.contact-hyperlink-label'), contact_path 18 | %li.dropdown 19 | %a.dropdown-toggle{"data-toggle" => "dropdown", :href => "#"} 20 | = t('.resources-dropdown-button-label') 21 | %b.caret 22 | %ul.dropdown-menu 23 | %li= link_to t('.download-unisex-restroom-signs-hyperlink-label'), page_path('signs') 24 | %li= link_to t('.public-api-hyperlink-label'), '/api/docs/' 25 | / /.navbar-collapse 26 | -------------------------------------------------------------------------------- /app/views/layouts/_piwik_tag.html.haml: -------------------------------------------------------------------------------- 1 | 2 | :javascript 3 | var _paq = _paq || []; 4 | /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ 5 | _paq.push(['trackPageView']); 6 | _paq.push(['enableLinkTracking']); 7 | (function() { 8 | var u="https://refugerestrooms.matomo.cloud/"; 9 | _paq.push(['setTrackerUrl', u+'piwik.php']); 10 | _paq.push(['setSiteId', '1']); 11 | var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 12 | g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); 13 | })(); 14 | 15 | -------------------------------------------------------------------------------- /app/views/layouts/_search.html.haml: -------------------------------------------------------------------------------- 1 | - splash = false if local_assigns[:splash].nil? 2 | 3 | .row.search-container 4 | = form_tag restrooms_path, class: "search-restrooms-form", method: :get do 5 | = hidden_field_tag :lat, "" 6 | = hidden_field_tag :long, "" 7 | .input-group 8 | = text_field_tag :search, params[:search], class: "form-control search-bar", aria: {label: t("search_bar.enter_location")} 9 | .input-group-btn 10 | %button.btn.btn-light-purple.submit-search-button{type: "button", title: t('.search'), value: t('.search'), aria: { label: t('.search') }} 11 | %i.fa.fa-search.fa-2x 12 | %i.fa.fa-refresh.fa-spin.fa-2x 13 | %button.btn.btn-light-purple.current-location-button{type: "button", title: t('.search-by-current-location'), aria: { label: t('.search-by-current-location') }, value: (splash ? t('.search-by-current-location') : nil ) } 14 | %i.fa.fa-location-arrow.fa-2x 15 | %i.fa.fa-refresh.fa-spin.fa-2x 16 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang: I18n.locale} 3 | %head 4 | = render 'layouts/head' 5 | %body 6 | - if @mobile 7 | - # For iOS and Android clients redirecting to our pages for input of bathrooms, we will hide the header. 8 | %header 9 | = render 'layouts/header' 10 | %main 11 | .container 12 | = render 'layouts/messages' 13 | = yield 14 | = render 'layouts/footer' 15 | 16 | -------------------------------------------------------------------------------- /app/views/layouts/splash.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang: I18n.locale} 3 | %head 4 | = render 'layouts/head' 5 | %body 6 | .splash-background 7 | = render 'layouts/navigation' 8 | .container 9 | = yield 10 | -------------------------------------------------------------------------------- /app/views/pages/about.html.haml: -------------------------------------------------------------------------------- 1 | %span.abouttext 2 | %center 3 | %h1= t('about.title') 4 | %h3 5 | %a{:href => "https://github.com/RefugeRestrooms/refugerestrooms", :class => "paddedForSafety"} 6 | = t('about.contribute') 7 | .text-padding.p-text-sizebump 8 | %h3 9 | = t('about.p1header') 10 | %p= t('about.p1.first') 11 | %p= t('about.p1.second') 12 | %h3 13 | = t('about.p2header') 14 | %p 15 | = t('about.p2') 16 | %h3 17 | = t('about.p3header') 18 | %p 19 | = t('about.p3') 20 | %h3 21 | = t('about.p4header') 22 | %p 23 | = t('about.p4') 24 | %h3 25 | = t('about.p5header') 26 | %p 27 | = t('about.p5.first').html_safe 28 | %p 29 | = t('about.p5.second').html_safe 30 | %p 31 | = t('about.p5.third').html_safe 32 | %p 33 | = t('about.p5.fourth').html_safe 34 | %h3 35 | = t('about.p6header') 36 | %p 37 | = t('about.p6').html_safe 38 | 39 | -------------------------------------------------------------------------------- /app/views/pages/business_info.html.haml: -------------------------------------------------------------------------------- 1 | %span.business_infotext 2 | %center 3 | %h1= t('business_info.title') 4 | .text-padding.p-text-sizebump 5 | %h3 6 | = t('business_info.p1header') 7 | %p 8 | = t('business_info.p1').html_safe 9 | %h3 10 | = t('business_info.p2header') 11 | %p 12 | = t('business_info.p2') 13 | %h3 14 | = t('business_info.p3header') 15 | %p 16 | = t('business_info.p3') 17 | %h3 18 | = t('business_info.p4header') 19 | %p 20 | = t('business_info.p4.first') 21 | %p 22 | = t('business_info.p4.second').html_safe 23 | %ul 24 | %li 25 | = t('business_info.p4.list1') 26 | %li 27 | = t('business_info.p4.list2') 28 | %li 29 | = t('business_info.p4.list3') 30 | %li 31 | = t('business_info.p4.list4') 32 | %li 33 | = t('business_info.p4.list5') 34 | %li 35 | = t('business_info.p4.list6') 36 | %h3 37 | = t('business_info.p5header') 38 | %p 39 | = t('business_info.p5') 40 | %h3 41 | = t('business_info.p6header') 42 | %p 43 | = t('business_info.p6') 44 | 45 | -------------------------------------------------------------------------------- /app/views/pages/index.html.haml: -------------------------------------------------------------------------------- 1 | .splash-content 2 | .row 3 | .col-xs-12.col-sm-8.col-sm-offset-2 4 | .splash-text-container.centered-text 5 | %h3.headroom 6 | = t('.life-is-tough') 7 | %h1.centered-text 8 | = t('.find-refuge') 9 | 10 | .row.more-headroom 11 | .col-xs-12.col-sm-8.col-sm-offset-2 12 | = render partial: "layouts/search", locals: {splash: true} 13 | 14 | .row.more-headroom 15 | .col-xs-12.col-sm-6.col-sm-offset-3 16 | = button_to new_restroom_path, method: :get, class: "btn btn-lg btn-purple splash-add-restroom-btn" do 17 | = t('.add-restroom-button-label') 18 | %i.fa.fa-plus-square-o.fa-2x 19 | .row.even-more-headroom 20 | .col-xs-6.col-sm-3.col-sm-offset-3 21 | = link_to image_tag("app-store.svg", role: "img", alt: t('.html-alt-attributes.app-store')), "https://itunes.apple.com/us/app/refuge-restrooms/id968531953?mt=8" 22 | .col-xs-6.col-sm-3 23 | = link_to image_tag("play-store.png", alt: t('.html-alt-attributes.play-store')), "https://play.google.com/store/apps/details?id=org.refugerestrooms" 24 | 25 | .row.more-headroom.splash-bottom-padding 26 | .col-xs-12.col-sm-6.col-sm-offset-3 27 | = link_to image_tag("patreon.png", alt: t('.html-alt-attributes.patreon')), "https://patreon.com/refugerestrooms" 28 | = render 'layouts/footer' 29 | -------------------------------------------------------------------------------- /app/views/pages/signs.html.haml: -------------------------------------------------------------------------------- 1 | .text-padding 2 | %h1 3 | = t('.title') 4 | %p= t('.intro') 5 | %div{:style => "float:left;width:45%;text-align:center;margin:0 15px;"} 6 | %h3= t(".head-accessible") 7 | %a{:href => "/rr-sign-with-handi.pdf"} 8 | = image_tag('rr-sign-with-handi.png', :style => "padding:15px;border:1px solid #444;") 9 | %p= t(".download") 10 | = image_tag('qrcode-sign-with-handi.png', :width => "200") 11 | %div{:style => "float:left;width:45%;text-align:center;margin:0 15px;"} 12 | %h3= t(".head-non-accessible") 13 | %a{:href => "/rr-sign-no-handi.pdf"} 14 | = image_tag('rr-sign-no-handi.png', :style => "padding:15px;border:1px solid #444;") 15 | %p= t(".download") 16 | = image_tag('qrcode-sign-no-handi.png', :width => "200") 17 | %div{:style => "clear:both;"} 18 | %br/ 19 | -------------------------------------------------------------------------------- /app/views/pages/text.html.haml: -------------------------------------------------------------------------------- 1 | .text-padding 2 | %h1= t('pages.text.title') 3 | %p.centered-text= t('pages.text.intro').html_safe 4 | %h2.centered-text= t('pages.text.instructions') 5 | %p.centered-text= t('.tip') 6 | %div.centered-text{:style => "margin:30px auto"} 7 | %img{:src => "/assets/text-msg-demo.png"}/ 8 | -------------------------------------------------------------------------------- /app/views/restrooms/_formsubmit.html.haml: -------------------------------------------------------------------------------- 1 | %h1= t('restroom.add_new') 2 | 3 | = simple_form_for @restroom, :url => restrooms_path, :method => :post, html: {class: 'submit-new-bathroom-form form-vertical'} do |f| 4 | %h5= t('restroom.required') 5 | .clearfix 6 | %button.btn.btn-light-purple.guess-btn{:type => "button", :value => t('restroom.guess_location')} 7 | = t('restroom.guess_location') 8 | %i.fa.fa-refresh.fa-spin 9 | 10 | / Add map for preview 11 | #mapArea.hidden{ data: { latitude: 38.904735, longitude: -77.033812 } } 12 | 13 | .nearby-container.footroom 14 | // Content of nearby restrooms gets rendered here. 15 | 16 | = f.input :name, :required => true 17 | = f.input :street, :required => true 18 | = f.input :city, :required => true 19 | = f.input :state, :required => true 20 | = f.input :country, priority: ["United States", "Canada", "United Kingdom"], :required => true, input_html: {class: 'form-control'} 21 | = f.hidden_field :latitude 22 | = f.hidden_field :longitude 23 | = f.hidden_field :edit_id 24 | = f.hidden_field :approved 25 | = f.input :accessible, :collection => [[t('restroom.accessible'), true], [t('restroom.not_accessible'), false]], :include_blank => false 26 | = f.input :unisex, :collection => [[t('restroom.type.unisex'), true], [t('restroom.type.single_stall'), false]], :include_blank => false 27 | = f.input :changing_table, :collection => [[t('restroom.changing_table'), true], [t('restroom.no_changing_table'), false]], :include_blank => false 28 | = f.input :directions, :placeholder => t('restroom.directions_hint'), :as => :text, :required => false, :input_html => { :class => "span6" } 29 | = f.input :comment, :placeholder => t('restroom.comments_hint'), :as => :text, :required => false, :input_html => { :class => "span6" } 30 | 31 | .form-group 32 | .g-recaptcha{'data-sitekey' => "#{ENV['RECAPTCHA_SITE_KEY']}"} 33 | 34 | / Click to preview location 35 | %button{type: 'button', class: 'preview-btn linkbutton'} 36 | = t('restroom.preview') 37 | = f.button :submit, t('restroom.restsubmit'), :class => "linkbutton" 38 | -------------------------------------------------------------------------------- /app/views/restrooms/_restroom.html.haml: -------------------------------------------------------------------------------- 1 | - unisex_class = restroom.unisex? ? '' : 'not_unisex' 2 | - accessible_class = restroom.accessible? ? '' : 'not_accessible' 3 | - changing_table_class = restroom.changing_table? ? '' : 'no_changing_table' 4 | 5 | %li{ class: "listItem clearfix #{unisex_class} #{accessible_class} #{changing_table_class}", 6 | data: { id: restroom.id} } 7 | .listItemImage 8 | / image tag goes here 9 | .itemInfo 10 | .itemName= link_to_unless_current(restroom.name.titleize, restroom) 11 | .itemStreet="#{restroom.street}, #{restroom.city}, #{restroom.state}" 12 | - if restroom.rated? 13 | - rating_class_name = case RatingLevel.for_restroom(restroom) 14 | - when RatingLevel.green then 'greenRating' 15 | - when RatingLevel.yellow then 'yellowRating' 16 | - when RatingLevel.red then 'redRating' 17 | - else '' 18 | %div{:class => "itemRating #{rating_class_name}"} 19 | = t('restroom.rating.positive', percentage: restroom.rating_percentage.round) 20 | - else 21 | .itemRating= t('restroom.rating.unrated') 22 | 23 | .itemExtraInfo 24 | .itemDistance 25 | - if restroom.respond_to?(:distance) 26 | = restroom.distance.round(2) 27 | = t("restroom.distance.miles") 28 | \/ 29 | = miles_to_kilometers(restroom.distance).round(2) 30 | = t("restroom.distance.kilometers") 31 | .itemIcons 32 | - if restroom.unisex? 33 | .unisexRestroom{:title => t("restroom.type.unisex")} 34 | %i.fa.fa-transgender-alt.fa-2x 35 | - if restroom.accessible? 36 | .ADARestroom{:title => t("restroom.accessible")} 37 | %i.fa.fa-wheelchair.fa-2x 38 | - if restroom.changing_table? 39 | .changingTable{:title => t("restroom.changing_table")} 40 | %i.fa.fa-child.fa-2x 41 | -------------------------------------------------------------------------------- /app/views/restrooms/edit.html.haml: -------------------------------------------------------------------------------- 1 | = render "formsubmit" 2 | -------------------------------------------------------------------------------- /app/views/restrooms/index.html.haml: -------------------------------------------------------------------------------- 1 | .row 2 | .col-xs-12.headroom 3 | #filters.clearfix 4 | .btn-group{:data => {:toggle => "buttons"}} 5 | %button#ada_filter.filter.btn.btn-light-purple.linkbutton{:title => t("restroom.accessible"), :class => ("active" if @filters.keys.include?('accessible'))} 6 | %input{:type => "checkbox", :checked => @filters.keys.include?('accessible')} 7 | %i.fa.fa-wheelchair 8 | %button#unisex_filter.filter.btn-light-purple.btn.linkbutton{:title => t("restroom.type.unisex"), :class => ("active" if @filters.keys.include?('unisex'))} 9 | %input{:type => "checkbox", :checked => @filters.keys.include?('unisex')} 10 | %i.fa.fa-transgender-alt 11 | %button#changing_table_filter.filter.btn-light-purple.btn.linkbutton{:title => t("restroom.changing_table"), :class => ("active" if @filters.keys.include?('changing_table'))} 12 | %input{:type => "checkbox", :checked => @filters.keys.include?('changing_table')} 13 | %i.fa.fa-child 14 | 15 | - view_label = @view == 'map' ? 'List View' : 'Map View' 16 | - view_toggle = @view == 'map' ? {view: 'list'} : {view: 'map'} 17 | = link_to view_label, restrooms_path(request.query_parameters.merge(view_toggle)), class: 'map-toggle-btn linkbutton btn pull-right btn-lg btn-light-purple' 18 | 19 | .restrooms-index-content 20 | .row 21 | .col-sm-12.headroom 22 | #results 23 | = content_tag 'div', id: 'mapContainer', data: { latitude: params[:lat], longitude: params[:long] } do 24 | #mapArea 25 | .row 26 | .col-sm-12.headroom 27 | %ul{:class => "restrooms-list", :id => "list"} 28 | = render @restrooms 29 | != pagy_nav @pagy 30 | / .row 31 | / .col-xs-12.headroom 32 | / .restrooms-index-content 33 | / = content_tag 'div', id: 'map-container', data: { latitude: params[:lat], longitude: params[:long] } do 34 | / #map-content 35 | / .restrooms-list 36 | / = render @restrooms 37 | / != pagy_nav @pagy 38 | 39 | 40 | / #results.headroom 41 | / = content_tag 'div', id: 'mapContainer', data: { latitude: params[:lat], longitude: params[:long] } do 42 | / #mapArea 43 | / #list.restrooms-list 44 | / = render @restrooms 45 | / != pagy_nav @pagy 46 | -------------------------------------------------------------------------------- /app/views/restrooms/nearby.html.haml: -------------------------------------------------------------------------------- 1 | - if @restrooms.empty? 2 | .none 3 | %p= t('.none') 4 | - else 5 | %h2= t('.heading') 6 | %p= t('.body') 7 | .minimalRestroomList= render @restrooms 8 | .clearfix 9 | -------------------------------------------------------------------------------- /app/views/restrooms/new.html.haml: -------------------------------------------------------------------------------- 1 | .row 2 | .col-sm-12 3 | .new-restrooms-form-container.form-container 4 | = render 'formsubmit' 5 | -------------------------------------------------------------------------------- /app/views/restrooms/show.html.haml: -------------------------------------------------------------------------------- 1 | .row.headroom 2 | .col-xs-12 3 | .listItem.showPageItem{"data-id" => @restroom.id} 4 | = render partial: 'restrooms/restroom', locals: { restroom: @restroom } 5 | 6 | .showPageContent 7 | .row 8 | .col-xs-12 9 | .btn-group{role: "group"} 10 | = link_to restroom_path(restroom: { upvote: true }), 11 | method: 'put' do 12 | %button.btn.btn-lg.btn-success 13 | %i.fa.fa-thumbs-up 14 | = t('.thumbs-up-button-label') 15 | 16 | = link_to restroom_path(restroom: { downvote: true }), 17 | method: 'put' do 18 | %button.btn.btn-lg.btn-danger 19 | %i.fa.fa-thumbs-down 20 | = t('.thumbs-down-button-label') 21 | .row.headroom 22 | .col-xs-12 23 | 24 | %p 25 | %strong #{t('restroom.directions')}: 26 | = @restroom.directions 27 | %p 28 | %strong #{t('restroom.comments')}: 29 | = @restroom.comment 30 | %p= link_to t('restroom.edit.editlisting'), new_restroom_path(id: @restroom.id, restroom_name: @restroom.name, edit_id: @restroom.edit_id) 31 | .row 32 | .col-xs-12 33 | #map 34 | %div#mapArea{ data: { latitude: @restroom.latitude, longitude: @restroom.longitude } } 35 | %hr 36 | .row 37 | .col-xs-12 38 | = render partial: 'layouts/disqus_tag', locals: { identifier: "restroom-#{@restroom.id}", title: @restroom.name, url: request.original_url } 39 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | var validEnv = ['development', 'test', 'production'] 3 | var currentEnv = api.env() 4 | var isDevelopmentEnv = api.env('development') 5 | var isProductionEnv = api.env('production') 6 | var isTestEnv = api.env('test') 7 | 8 | if (!validEnv.includes(currentEnv)) { 9 | throw new Error( 10 | 'Please specify a valid `NODE_ENV` or ' + 11 | '`BABEL_ENV` environment variables. Valid values are "development", ' + 12 | '"test", and "production". Instead, received: ' + 13 | JSON.stringify(currentEnv) + 14 | '.' 15 | ) 16 | } 17 | 18 | return { 19 | presets: [ 20 | isTestEnv && [ 21 | '@babel/preset-env', 22 | { 23 | targets: { 24 | node: 'current' 25 | } 26 | } 27 | ], 28 | (isProductionEnv || isDevelopmentEnv) && [ 29 | '@babel/preset-env', 30 | { 31 | forceAllTransforms: true, 32 | useBuiltIns: 'entry', 33 | corejs: 3, 34 | modules: false, 35 | exclude: ['transform-typeof-symbol'] 36 | } 37 | ] 38 | ].filter(Boolean), 39 | plugins: [ 40 | 'babel-plugin-macros', 41 | '@babel/plugin-syntax-dynamic-import', 42 | isTestEnv && 'babel-plugin-dynamic-import-node', 43 | '@babel/plugin-transform-destructuring', 44 | [ 45 | '@babel/plugin-proposal-class-properties', 46 | { 47 | loose: true 48 | } 49 | ], 50 | [ 51 | '@babel/plugin-proposal-object-rest-spread', 52 | { 53 | useBuiltIns: true 54 | } 55 | ], 56 | [ 57 | '@babel/plugin-transform-runtime', 58 | { 59 | helpers: false 60 | } 61 | ], 62 | [ 63 | '@babel/plugin-transform-regenerator', 64 | { 65 | async: false 66 | } 67 | ] 68 | ].filter(Boolean) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /bin/bourbon: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'bourbon' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('bourbon', 'bourbon') 17 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/bundler: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'bundler' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('bundler', 'bundler') 17 | -------------------------------------------------------------------------------- /bin/coderay: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'coderay' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('coderay', 'coderay') 17 | -------------------------------------------------------------------------------- /bin/dotenv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'dotenv' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('dotenv', 'dotenv') 17 | -------------------------------------------------------------------------------- /bin/geocode: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'geocode' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('geocoder', 'geocode') 17 | -------------------------------------------------------------------------------- /bin/haml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'haml' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('haml', 'haml') 17 | -------------------------------------------------------------------------------- /bin/htmldiff: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'htmldiff' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('diff-lcs', 'htmldiff') 17 | -------------------------------------------------------------------------------- /bin/kramdown: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'kramdown' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('kramdown', 'kramdown') 17 | -------------------------------------------------------------------------------- /bin/ldiff: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'ldiff' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('diff-lcs', 'ldiff') 17 | -------------------------------------------------------------------------------- /bin/nokogiri: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'nokogiri' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('nokogiri', 'nokogiri') 17 | -------------------------------------------------------------------------------- /bin/pry: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'pry' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('pry', 'pry') 17 | -------------------------------------------------------------------------------- /bin/rackup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'rackup' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('rack', 'rackup') 17 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /bin/rdoc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'rdoc' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('rdoc', 'rdoc') 17 | -------------------------------------------------------------------------------- /bin/ri: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'ri' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('rdoc', 'ri') 17 | -------------------------------------------------------------------------------- /bin/rspec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'rspec' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('rspec-core', 'rspec') 17 | -------------------------------------------------------------------------------- /bin/sass: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'sass' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('sass', 'sass') 17 | -------------------------------------------------------------------------------- /bin/sass-convert: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'sass-convert' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('sass', 'sass-convert') 17 | -------------------------------------------------------------------------------- /bin/scss: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'scss' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('sass', 'scss') 17 | -------------------------------------------------------------------------------- /bin/sdoc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'sdoc' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('sdoc', 'sdoc') 17 | -------------------------------------------------------------------------------- /bin/sdoc-merge: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'sdoc-merge' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('sdoc', 'sdoc-merge') 17 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | 4 | # path to your application root. 5 | APP_ROOT = File.expand_path("..", __dir__) 6 | 7 | def system!(*args) 8 | system(*args, exception: true) 9 | end 10 | 11 | FileUtils.chdir APP_ROOT do 12 | # This script is a way to set up or update your development environment automatically. 13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome. 14 | # Add necessary setup steps to this file. 15 | 16 | puts "== Installing dependencies ==" 17 | system! "gem install bundler --conservative" 18 | system("bundle check") || system!("bundle install") 19 | 20 | # puts "\n== Copying sample files ==" 21 | # unless File.exist?("config/database.yml") 22 | # FileUtils.cp "config/database.yml.sample", "config/database.yml" 23 | # end 24 | 25 | puts "\n== Preparing database ==" 26 | system! "bin/rails db:prepare" 27 | 28 | puts "\n== Removing old logs and tempfiles ==" 29 | system! "bin/rails log:clear tmp:clear" 30 | 31 | puts "\n== Restarting application server ==" 32 | system! "bin/rails restart" 33 | end 34 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast 4 | # It gets overwritten when you run the `spring binstub` command 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ spring \((.*?)\)$.*?^$/m) 11 | ENV["GEM_PATH"] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR) 12 | ENV["GEM_HOME"] = "" 13 | Gem.paths = ENV 14 | 15 | gem "spring", match[1] 16 | require "spring/binstub" 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /bin/sprockets: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'sprockets' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('sprockets', 'sprockets') 17 | -------------------------------------------------------------------------------- /bin/thor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'thor' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('thor', 'thor') 17 | -------------------------------------------------------------------------------- /bin/tilt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'tilt' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('tilt', 'tilt') 17 | -------------------------------------------------------------------------------- /bin/tt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'tt' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('treetop', 'tt') 17 | -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = File.expand_path('..', __dir__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a way to update your development environment automatically. 15 | # Add necessary update steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | # Install JavaScript dependencies if using Yarn 22 | # system('bin/yarn') 23 | 24 | puts "\n== Updating database ==" 25 | system! 'bin/rails db:migrate' 26 | 27 | puts "\n== Removing old logs and tempfiles ==" 28 | system! 'bin/rails log:clear tmp:clear' 29 | 30 | puts "\n== Restarting application server ==" 31 | system! 'bin/rails restart' 32 | end 33 | -------------------------------------------------------------------------------- /bin/webpack: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "bundler/setup" 11 | 12 | require "webpacker" 13 | require "webpacker/webpack_runner" 14 | 15 | APP_ROOT = File.expand_path("..", __dir__) 16 | Dir.chdir(APP_ROOT) do 17 | Webpacker::WebpackRunner.run(ARGV) 18 | end 19 | -------------------------------------------------------------------------------- /bin/webpack-dev-server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "bundler/setup" 11 | 12 | require "webpacker" 13 | require "webpacker/dev_server_runner" 14 | 15 | APP_ROOT = File.expand_path("..", __dir__) 16 | Dir.chdir(APP_ROOT) do 17 | Webpacker::DevServerRunner.run(ARGV) 18 | end 19 | -------------------------------------------------------------------------------- /config.rb: -------------------------------------------------------------------------------- 1 | require 'susy' 2 | 3 | http_path = "/" 4 | css_dir = "stylesheets" 5 | sass_dir = "sass" 6 | images_dir = "images" 7 | javascripts_dir = "javascripts" 8 | 9 | # You can select your preferred output style here (can be overridden via the command line): 10 | # output_style = :expanded or :nested or :compact or :compressed 11 | 12 | relative_assets = true 13 | 14 | # To disable debugging comments that display the original location of your selectors. Uncomment: 15 | line_comments = false 16 | 17 | 18 | # If you prefer the indented syntax, you might want to regenerate this 19 | # project again passing --syntax sass, or you can uncomment this: 20 | preferred_syntax = :sass 21 | # and then run: 22 | # sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass 23 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails/all" 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module SaferstallsRails 10 | class Application < Rails::Application 11 | # Initialize configuration defaults for originally generated Rails version. 12 | config.load_defaults 5.0 13 | 14 | # Please, add to the `ignore` list any other `lib` subdirectories that do 15 | # not contain `.rb` files, or that should not be reloaded or eager loaded. 16 | # Common ones are `templates`, `generators`, or `middleware`, for example. 17 | config.autoload_lib(ignore: %w(assets tasks)) 18 | 19 | # Configuration for the application, engines, and railties goes here. 20 | # 21 | # These settings can be overridden in specific environments using the files 22 | # in config/environments, which are processed later. 23 | # 24 | # config.time_zone = "Central Time (US & Canada)" 25 | # config.eager_load_paths << Rails.root.join("extras") 26 | 27 | # Settings in config/environments/* take precedence over those specified here. 28 | # Application configuration can go into files in config/initializers 29 | # -- all .rb files in that directory are automatically loaded after loading 30 | # the framework and any gems in your application. 31 | config.middleware.insert_before 0, Rack::Cors do 32 | allow do 33 | origins "*" 34 | resource "/api/*", headers: :any, methods: [:get, :post, :options] 35 | end 36 | end 37 | 38 | # I18n stuff 39 | config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')] 40 | config.i18n.available_locales = [:en, :es, :fil, :fr, :hi, :it, :pl, :"pt-BR", :tl] 41 | config.i18n.default_locale = :en 42 | 43 | 44 | 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /config/cucumber.yml: -------------------------------------------------------------------------------- 1 | <% 2 | rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" 3 | rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" 4 | std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip" 5 | %> 6 | default: <%= std_opts %> features 7 | wip: --tags @wip:3 --wip features 8 | rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip 9 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: postgresql 3 | encoding: unicode 4 | host: db 5 | username: postgres 6 | password: 7 | pool: 5 8 | 9 | development: 10 | <<: *default 11 | database: bathrooms_development 12 | 13 | 14 | test: 15 | <<: *default 16 | database: bathrooms_test 17 | 18 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/initializers/application.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.generators do |g| 2 | g.test_framework :rspec 3 | end -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = "1.0" 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in the app/assets 11 | # folder are already added. 12 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 13 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/bugsnag.rb: -------------------------------------------------------------------------------- 1 | Bugsnag.configure do |config| 2 | config.api_key = ENV["BUGSNAG_API_TOKEN"] 3 | end 4 | -------------------------------------------------------------------------------- /config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy. 4 | # See the Securing Rails Applications Guide for more information: 5 | # https://guides.rubyonrails.org/security.html#content-security-policy-header 6 | 7 | # Rails.application.configure do 8 | # config.content_security_policy do |policy| 9 | # policy.default_src :self, :https 10 | # policy.font_src :self, :https, :data 11 | # policy.img_src :self, :https, :data 12 | # policy.object_src :none 13 | # policy.script_src :self, :https 14 | # policy.style_src :self, :https 15 | # # Specify URI for violation reports 16 | # # policy.report_uri "/csp-violation-report-endpoint" 17 | # end 18 | # 19 | # # Generate session nonces for permitted importmap, inline scripts, and inline styles. 20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } 21 | # config.content_security_policy_nonce_directives = %w(script-src style-src) 22 | # 23 | # # Report violations without enforcing the policy. 24 | # # config.content_security_policy_report_only = true 25 | # end 26 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. 4 | # Use this to limit dissemination of sensitive information. 5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. 6 | Rails.application.config.filter_parameters += [ 7 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :password 8 | ] 9 | -------------------------------------------------------------------------------- /config/initializers/geocoder.rb: -------------------------------------------------------------------------------- 1 | Geocoder.configure( 2 | 3 | # street address geocoding service (default :nominatim) 4 | lookup: :google, 5 | 6 | # to use an API key: 7 | api_key: ENV['GOOGLE_MAPS_API_KEY'], 8 | 9 | # geocoding service request timeout, in seconds (default 3): 10 | timeout: 5, 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /config/initializers/high_voltage.rb: -------------------------------------------------------------------------------- 1 | HighVoltage.configure do |config| 2 | config.routes = false 3 | end 4 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/kaminari_config.rb: -------------------------------------------------------------------------------- 1 | Kaminari.configure do |config| 2 | config.default_per_page = 10 3 | config.max_per_page = nil 4 | config.window = 4 5 | config.outer_window = 0 6 | config.left = 0 7 | config.right = 0 8 | config.page_method_name = :page 9 | config.param_name = :page 10 | end 11 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/initializers/new_framework_defaults.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains migration options to ease your Rails 5.0 upgrade. 4 | # 5 | # Once upgraded flip defaults one by one to migrate to the new default. 6 | # 7 | # Read the Rails 5.0 release notes for more info on each option. 8 | 9 | # Enable per-form CSRF tokens. Previous versions had false. 10 | Rails.application.config.action_controller.per_form_csrf_tokens = false 11 | 12 | # Enable origin-checking CSRF mitigation. Previous versions had false. 13 | Rails.application.config.action_controller.forgery_protection_origin_check = false 14 | 15 | # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. 16 | # Previous versions had false. 17 | ActiveSupport.to_time_preserves_timezone = false 18 | 19 | # Require `belongs_to` associations by default. Previous versions had false. 20 | Rails.application.config.active_record.belongs_to_required_by_default = false 21 | 22 | # Do not halt callback chains when a callback returns false. Previous versions had true. 23 | # ActiveSupport.halt_callback_chains_on_return_false = true - Removed with Rails 5.2 24 | -------------------------------------------------------------------------------- /config/initializers/new_framework_defaults_5_2.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains migration options to ease your Rails 5.2 upgrade. 4 | # 5 | # Once upgraded flip defaults one by one to migrate to the new default. 6 | # 7 | # Read the Guide for Upgrading Ruby on Rails for more info on each option. 8 | 9 | # Make Active Record use stable #cache_key alongside new #cache_version method. 10 | # This is needed for recyclable cache keys. 11 | # Rails.application.config.active_record.cache_versioning = true 12 | 13 | # Use AES-256-GCM authenticated encryption for encrypted cookies. 14 | # Also, embed cookie expiry in signed or encrypted cookies for increased security. 15 | # 16 | # This option is not backwards compatible with earlier Rails versions. 17 | # It's best enabled when your entire app is migrated and stable on 5.2. 18 | # 19 | # Existing cookies will be converted on read then written with the new scheme. 20 | # Rails.application.config.action_dispatch.use_authenticated_cookie_encryption = true 21 | 22 | # Use AES-256-GCM authenticated encryption as default cipher for encrypting messages 23 | # instead of AES-256-CBC, when use_authenticated_message_encryption is set to true. 24 | # Rails.application.config.active_support.use_authenticated_message_encryption = true 25 | 26 | # Add default protection from forgery to ActionController::Base instead of in 27 | # ApplicationController. 28 | # Rails.application.config.action_controller.default_protect_from_forgery = true 29 | 30 | # Store boolean values are in sqlite3 databases as 1 and 0 instead of 't' and 31 | # 'f' after migrating old data. 32 | # Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true 33 | 34 | # Use SHA-1 instead of MD5 to generate non-sensitive digests, such as the ETag header. 35 | # Rails.application.config.active_support.use_sha1_digests = true 36 | 37 | # Make `form_with` generate id attributes for any generated HTML tags. 38 | # Rails.application.config.action_view.form_with_generates_ids = true 39 | -------------------------------------------------------------------------------- /config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide HTTP permissions policy. For further 4 | # information see: https://developers.google.com/web/updates/2018/06/feature-policy 5 | 6 | # Rails.application.config.permissions_policy do |policy| 7 | # policy.camera :none 8 | # policy.gyroscope :none 9 | # policy.microphone :none 10 | # policy.usb :none 11 | # policy.fullscreen :self 12 | # policy.payment :self, "https://secure.example.com" 13 | # end 14 | -------------------------------------------------------------------------------- /config/initializers/rakismet.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.rakismet.key = ENV['AKISMET_KEY'] || 'test' 2 | Rails.application.config.rakismet.url = 'http://refugerestrooms.org' 3 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure your secret_key_base is kept private 11 | # if you're sharing your code publicly. 12 | SaferstallsRails::Application.configure do 13 | 14 | config.secret_key_base = ENV['RAILS_SECRET_KEY'] 15 | 16 | end 17 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_saferstalls_rails_session' 4 | -------------------------------------------------------------------------------- /config/initializers/setup_mail.rb: -------------------------------------------------------------------------------- 1 | ActionMailer::Base.delivery_method = :smtp 2 | ActionMailer::Base.smtp_settings = { 3 | :address => "smtp.gmail.com", 4 | :port => 587, 5 | :domain => "whatever.org", 6 | :user_name => ENV['EMAIL'], 7 | :password => ENV['EMAIL_PASSWORD'], 8 | :authentication => "plain", 9 | :enable_starttls_auto => true 10 | } -------------------------------------------------------------------------------- /config/initializers/simple_form_bootstrap.rb: -------------------------------------------------------------------------------- 1 | # Taken from https://gist.github.com/adamico/6510093 2 | 3 | # http://stackoverflow.com/questions/14972253/simpleform-default-input-class 4 | # https://github.com/plataformatec/simple_form/issues/316 5 | 6 | # Use this setup block to configure all options available in SimpleForm. 7 | SimpleForm.setup do |config| 8 | 9 | config.input_class = 'form-control' 10 | 11 | config.boolean_style = :nested 12 | 13 | config.wrappers :bootstrap3, tag: 'div', class: 'form-group', error_class: 'has-error', 14 | defaults: { input_html: { class: 'default_class' } } do |b| 15 | 16 | b.use :html5 17 | b.use :min_max 18 | b.use :maxlength 19 | b.use :placeholder 20 | 21 | b.optional :pattern 22 | b.optional :readonly 23 | 24 | b.use :label_input 25 | b.use :hint, wrap_with: { tag: 'span', class: 'help-block' } 26 | b.use :error, wrap_with: { tag: 'span', class: 'help-block has-error' } 27 | end 28 | 29 | config.wrappers :bootstrap3_horizontal, tag: 'div', class: 'form-group', error_class: 'has-error', 30 | defaults: { input_html: { class: 'default-class '}, wrapper_html: { class: "col-lg-10 col-md-10"} } do |b| 31 | 32 | b.use :html5 33 | b.use :min_max 34 | b.use :maxlength 35 | b.use :placeholder 36 | 37 | b.optional :pattern 38 | b.optional :readonly 39 | 40 | b.use :label 41 | b.wrapper :right_column, tag: :div do |component| 42 | component.use :input 43 | end 44 | b.use :hint, wrap_with: { tag: 'span', class: 'help-block' } 45 | b.use :error, wrap_with: { tag: 'span', class: 'help-block has-error' } 46 | end 47 | 48 | config.wrappers :group, tag: 'div', class: "form-group", error_class: 'has-error', 49 | defaults: { input_html: { class: 'default-class '} } do |b| 50 | 51 | b.use :html5 52 | b.use :min_max 53 | b.use :maxlength 54 | b.use :placeholder 55 | 56 | b.optional :pattern 57 | b.optional :readonly 58 | 59 | b.use :label 60 | b.use :input, wrap_with: { class: "input-group" } 61 | b.use :hint, wrap_with: { tag: 'span', class: 'help-block' } 62 | b.use :error, wrap_with: { tag: 'span', class: 'help-block has-error' } 63 | end 64 | 65 | config.default_wrapper = :bootstrap3 66 | end 67 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/locales/about_translations.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at http://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /config/locales/en/contacts.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | contacts: 3 | new: 4 | request-edit-for-restroom: 'Request Edit for %{restroom_name} Restroom' 5 | contact-title: 'Contact' 6 | leave-this-field-blank: 'Leave this field blank!' 7 | submitted: 8 | thank-you-period: 'Thank you for your message.' 9 | thank-you-exclamation: 'Thank you for your message!' 10 | cannot-send: 'Cannot send message.' 11 | we-will-get-back-to-you: "We'll get back to you soon." 12 | -------------------------------------------------------------------------------- /config/locales/en/footer.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | layouts: 3 | footer: 4 | aria-labels: 5 | github: 'Refuge Restrooms on GitHub' 6 | twitter: 'Refuge Restrooms on twitter' 7 | facebook: 'Refuge Restrooms on Facebook' 8 | email: 'Email Refuge Restrooms' 9 | refuge-restrooms-is-open-source: 'refuge restrooms is open source.' 10 | code-on-github: 'code on github.' 11 | contribute-to-the-project: 'contribute to the project' 12 | on-patreon: 'on patreon.' 13 | copyleft: 'copyleft' 14 | refuge-restrooms: 'refuge restrooms.' 15 | -------------------------------------------------------------------------------- /config/locales/en/navigation.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | layouts: 3 | navigation: 4 | toggle-navigation-button-label: 'Toggle navigation' 5 | submit-a-new-restroom-hyperlink-label: 'Submit a New Restroom' 6 | about-hyperlink-label: 'About' 7 | contact-hyperlink-label: 'Contact' 8 | 9 | resources-dropdown-button-label: 'Resources' 10 | download-unisex-restroom-signs-hyperlink-label: 'Download Unisex Restroom Signs' 11 | public-api-hyperlink-label: Public API 12 | -------------------------------------------------------------------------------- /config/locales/en/restrooms.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | restrooms: 3 | index: 4 | map-view-button-label: 'Map View' 5 | 6 | show: 7 | thumbs-up-button-label: 'Thumbs Up' 8 | thumbs-down-button-label: 'Thumbs Down' 9 | -------------------------------------------------------------------------------- /config/locales/en/search.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | layouts: 3 | search: 4 | search: 'Search' 5 | search-by-current-location: 'Search by Current Location' 6 | 7 | -------------------------------------------------------------------------------- /config/locales/en/signs.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | pages: 3 | signs: 4 | title: 'Downloadable Restroom Signs' 5 | intro: 'If you have a public restroom in your building or business that is gender-neutral, let people know. You (and/or the building owner/management) can add it to the database, and post one of the signs below to let people know you support safe access for all. Both signs are printable PDF files.' 6 | head-accessible: 'Accessible Restrooms' 7 | head-non-accessible: 'Non-Accessible Restrooms' 8 | download: 'Download PDF' 9 | -------------------------------------------------------------------------------- /config/locales/en/simple_form.en.yml: -------------------------------------------------------------------------------- 1 | # See this documentation: https://github.com/plataformatec/simple_form#i18n 2 | # And this StackOverflow answer: https://stackoverflow.com/questions/35906089/changing-simple-form-submit-button-i18n-text 3 | 4 | en: 5 | simple_form: 6 | "yes": 'Yes' 7 | "no": 'No' 8 | required: 9 | text: 'required' 10 | mark: '*' 11 | # You can uncomment the line below if you need to overwrite the whole required html. 12 | # When using html, text and mark won't be used. 13 | # html: '*' 14 | error_notification: 15 | default_message: "Please review the problems below:" 16 | 17 | labels: 18 | defaults: 19 | name: 'Name' 20 | street: 'Street' 21 | city: 'City' 22 | state: 'State/Province' 23 | country: 'Country' 24 | accessible: 'Accessible' 25 | unisex: 'Unisex' 26 | changing_table: 'Changing Table' 27 | directions: 'Directions' 28 | comment: 'Comment' 29 | email: 'Email' 30 | message: 'Message' 31 | contact: 32 | name: 'Name' 33 | email: 'Email' 34 | message: 'Message' 35 | 36 | helpers: 37 | reCAPTCHA: 38 | failed: 'reCAPTCHA required.' 39 | submit: 40 | contact: 41 | # This is the "Send message" button on the "Contact" page. 42 | create: 'Send message' 43 | 44 | # Labels and hints examples 45 | # labels: 46 | # defaults: 47 | # password: 'Password' 48 | # user: 49 | # new: 50 | # email: 'E-mail to sign in.' 51 | # edit: 52 | # email: 'E-mail.' 53 | # hints: 54 | # defaults: 55 | # username: 'User name to sign in.' 56 | # password: 'No special characters, please.' 57 | 58 | -------------------------------------------------------------------------------- /config/locales/en/splash.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | pages: 3 | index: 4 | life-is-tough: 'Sometimes life is tough...' 5 | find-refuge: 'Find Refuge' 6 | add-restroom-button-label: 'Add A Restroom' 7 | 8 | html-alt-attributes: 9 | app-store: 'Refuge Restrooms iOS app download' 10 | play-store: 'Refuge Restrooms Android app download' 11 | patreon: 'Support the project on Patreon' 12 | -------------------------------------------------------------------------------- /config/locales/en/text_msg.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | pages: 3 | text: 4 | title: 'Get Closest Restroom by Text' 5 | intro: 'If you just need to get to the closest safe restroom right now, you can get it by text on any phone that has SMS.' 6 | instructions: 'Text your location to +1 (415) 367-3288' 7 | tip: "For the most accurate results, include street address, city, state and country. You'll get a location name and address back instantly!" 8 | -------------------------------------------------------------------------------- /config/locales/es/contacts.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | contacts: 3 | new: 4 | request-edit-for-restroom: 'Solicitar Edición para el baño de %{restroom_name}' 5 | contact-title: 'Contacto' 6 | leave-this-field-blank: 'Dejar este campo en blanco.' 7 | submitted: 8 | thank-you-period: 'Gracias por su mensaje.' 9 | thank-you-exclamation: '¡Gracias por su mensaje!' 10 | cannot-send: 'No se pudo enviar su mensaje.' 11 | we-will-get-back-to-you: "Nos pondremos en contacto con usted pronto." 12 | -------------------------------------------------------------------------------- /config/locales/es/footer.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | layouts: 3 | footer: 4 | aria-labels: 5 | github: 'Refuge Restrooms en GitHub' 6 | twitter: 'Refuge Restrooms en twitter' 7 | facebook: 'Refuge Restrooms en Facebook' 8 | tumblr: 'Blog de Refuge Restrooms en tumblr' 9 | email: 'Enviar email a Refuge Restrooms' 10 | refuge-restrooms-is-open-source: 'refuge restrooms es de código abierto.' 11 | code-on-github: 'código en github.' 12 | contribute-to-the-project: 'contribuye al proyecto' 13 | on-patreon: 'en patreon.' 14 | copyleft: 'copyleft' 15 | refuge-restrooms: 'refuge restrooms.' 16 | -------------------------------------------------------------------------------- /config/locales/es/navigation.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | layouts: 3 | navigation: 4 | toggle-navigation-button-label: 'Alternar navigación' 5 | submit-a-new-restroom-hyperlink-label: 'Agregar un nuevo baño' 6 | about-hyperlink-label: 'Acerca de Refuge' 7 | contact-hyperlink-label: 'Contacto' 8 | 9 | resources-dropdown-button-label: 'Recursos' 10 | download-unisex-restroom-signs-hyperlink-label: 'Descargar señalización para baños unisex' 11 | public-api-hyperlink-label: Public API 12 | -------------------------------------------------------------------------------- /config/locales/es/restrooms.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | restrooms: 3 | index: 4 | map-view-button-label: 'Vista del Mapa' 5 | 6 | show: 7 | thumbs-up-button-label: 'Aprobar este baño' 8 | thumbs-down-button-label: 'Desaprobar este baño' 9 | -------------------------------------------------------------------------------- /config/locales/es/search.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | layouts: 3 | search: 4 | search: 'Buscar' 5 | search-by-current-location: 'Buscar por ubicación actual' 6 | -------------------------------------------------------------------------------- /config/locales/es/signs.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | pages: 3 | signs: 4 | title: 'Señalización de baños para descargar' 5 | intro: 'Si su empresa o edificio tiene baños sin diferenciación por género, puedes imprimir los carteles para informar esto a la gente. Tú (o quien esté a cargo del edificio o empresa) puedes agregar los baños a nuestra base de datos, y colgar la señalización para que la gente sepa que ustedes apoyan el acceso seguro para todes. Ambos carteles son PDFs listos para imprimir.' 6 | head-accessible: 'Baños Accesibles' 7 | head-non-accessible: 'Baños No Accesibles' 8 | download: 'Descargar PDF' 9 | -------------------------------------------------------------------------------- /config/locales/es/simple_form.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | simple_form: 3 | "yes": 'Si' 4 | "no": 'No' 5 | required: 6 | text: 'requerido' 7 | mark: '*' 8 | # You can uncomment the line below if you need to overwrite the whole required html. 9 | # When using html, text and mark won't be used. 10 | # html: '*' 11 | error_notification: 12 | default_message: "Por favor revise los problemas encontrados:" 13 | 14 | labels: 15 | defaults: 16 | name: 'Nombre' 17 | street: 'Calle' 18 | city: 'Ciudad' 19 | state: 'Estado/Provincia' 20 | country: 'País' 21 | accessible: 'Accesible' 22 | unisex: 'Unisex' 23 | changing_table: 'Con mesa para cambiar pañales' 24 | directions: 'Indicaciones' 25 | comment: 'Comentarios' 26 | email: 'Email' 27 | message: 'Mensaje' 28 | contact: 29 | name: 'Nombre' 30 | email: 'Email' 31 | message: 'Mensaje' 32 | 33 | helpers: 34 | submit: 35 | contact: 36 | # This is the "Send message" button on the "Contact" page. 37 | create: 'Enviar' 38 | 39 | # Labels and hints examples 40 | # labels: 41 | # defaults: 42 | # password: 'Password' 43 | # user: 44 | # new: 45 | # email: 'E-mail to sign in.' 46 | # edit: 47 | # email: 'E-mail.' 48 | # hints: 49 | # defaults: 50 | # username: 'User name to sign in.' 51 | # password: 'No special characters, please.' 52 | -------------------------------------------------------------------------------- /config/locales/es/splash.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | pages: 3 | index: 4 | life-is-tough: 'A veces la vida es dura...' 5 | find-refuge: 'Encontrá refugio' 6 | add-restroom-button-label: 'Agregar un baño' 7 | -------------------------------------------------------------------------------- /config/locales/es/text_msg.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | pages: 3 | text: 4 | title: 'Recibir el baño más cercano por mensaje de texto' 5 | intro: 'Si necesitas llegar al baño seguro más cercano, ahora mismo, puedes recibirlo por mensaje de texto en cualquier teléfono que tiene SMS.' 6 | instructions: 'Envía tu ubicación +1 (415) 367-3288' 7 | tip: 'Para obtener los resultados más precisos, incluya la dirección de la calle, la ciudad, el estado y el país. ¡Obtendrá una ubicación con nombre y dirección inmediatamente!' 8 | -------------------------------------------------------------------------------- /config/locales/fil/contacts.fil.yml: -------------------------------------------------------------------------------- 1 | fil: 2 | contacts: 3 | new: 4 | request-edit-for-restroom: 'Humiling ng pagbabago para sa %{restroom_name}' 5 | contact-title: 'Makipag-ugnay' 6 | leave-this-field-blank: 'Iwanang blangko ang patlang na ito!' 7 | submitted: 8 | thank-you-period: 'Salamat sa iyong mensahe.' 9 | thank-you-exclamation: 'Salamat sa iyong mensahe!' 10 | cannot-send: 'Hindi maipadala ang mensahe.' 11 | we-will-get-back-to-you: "Babalik kami sa iyo sa lalong madaling panahon." 12 | -------------------------------------------------------------------------------- /config/locales/fil/footer.fil.yml: -------------------------------------------------------------------------------- 1 | fil: 2 | layouts: 3 | footer: 4 | aria-labels: 5 | github: 'Refuge Restrooms sa GitHub' 6 | twitter: 'Refuge Restrooms sa twitter' 7 | facebook: 'Refuge Restrooms sa Facebook' 8 | email: 'Mag-padala ng mensahe sa Refuge Restrooms' 9 | refuge-restrooms-is-open-source: 'Ang Refuge Restrooms ay bukas para sa lahat na gamitin.' 10 | code-on-github: 'code sa github.' 11 | contribute-to-the-project: 'mag-ambag sa proyekto' 12 | on-patreon: 'sa patreon.' 13 | copyleft: 'copyleft' 14 | refuge-restrooms: 'Refuge Restrooms' 15 | -------------------------------------------------------------------------------- /config/locales/fil/navigation.fil.yml: -------------------------------------------------------------------------------- 1 | fil: 2 | layouts: 3 | navigation: 4 | toggle-navigation-button-label: 'I-toggle ang nabigasyon' 5 | submit-a-new-restroom-hyperlink-label: 'Magsumite ng Bagong Banyo' 6 | about-hyperlink-label: 'Tungkol sa' 7 | contact-hyperlink-label: 'Makipag-ugnay sa' 8 | 9 | resources-dropdown-button-label: 'Mga Mapagkukunan' 10 | download-unisex-restroom-signs-hyperlink-label: 'I-download ang Mga Palatandaan ng Unisex na Banyo' 11 | public-api-hyperlink-label: 'Pampublikong API' 12 | -------------------------------------------------------------------------------- /config/locales/fil/restrooms.fil.yml: -------------------------------------------------------------------------------- 1 | fil: 2 | restrooms: 3 | index: 4 | map-view-button-label: 'Tingna ang Mapa' 5 | 6 | show: 7 | thumbs-up-button-label: 'Sang-ayunan' 8 | thumbs-down-button-label: 'Huwag Sang-ayunan' 9 | -------------------------------------------------------------------------------- /config/locales/fil/search.fil.yml: -------------------------------------------------------------------------------- 1 | fil: 2 | layouts: 3 | search: 4 | search: 'Paghahanap' 5 | search-by-current-location: 'Maghanap ayon sa Kasalukuyang Lokasyon' -------------------------------------------------------------------------------- /config/locales/fil/signs.fil.yml: -------------------------------------------------------------------------------- 1 | fil: 2 | pages: 3 | signs: 4 | title: 'Nada-download na Mga Palatandaan ng Banyo' 5 | intro: 'Kung mayroon kang pampublikong banyo sa iyong gusali o negosyo na neutral sa kasarian, ipaalam sa mga tao. Ikaw (at / o ang may-ari / pamamahala ng gusali) ay maaaring idagdag ito sa database, at mag-sumite ng isa sa mga tanda sa ibaba upang ipaalam sa mga tao na sinusuportahan mo ang ligtas na pag-gamit para sa lahat. Ang parehong mga palatandaan ay maaaring imprentahin na mga PDF file.' 6 | head-accessible: 'Magagamit na mga Banyo' 7 | head-non-accessible: 'Mga Banyo na Hindi Mapupuntahan' 8 | download: 'I-download ang PDF' 9 | -------------------------------------------------------------------------------- /config/locales/fil/simple_form.fil.yml: -------------------------------------------------------------------------------- 1 | # See this documentation: https://github.com/plataformatec/simple_form#i18n 2 | # And this StackOverflow answer: https://stackoverflow.com/questions/35906089/changing-simple-form-submit-button-i18n-text 3 | 4 | fil: 5 | simple_form: 6 | "yes": 'Oo' 7 | "no": 'Hindi' 8 | required: 9 | text: 'kailangan' 10 | mark: '*' 11 | # You can uncomment the line below if you need to overwrite the whole required html. 12 | # When using html, text and mark won't be used. 13 | # html: '*' 14 | error_notification: 15 | default_message: "Mangyaring suriin ang mga problema sa ibaba:" 16 | 17 | labels: 18 | defaults: 19 | name: 'Pangalan' 20 | street: 'Kalye' 21 | city: 'Lungsod' 22 | state: 'Estado / Lalawigan' 23 | country: 'Bansa' 24 | accessible: 'Magagamit' 25 | unisex: 'Unisex' 26 | changing_table: 'Pagpapalit ng lamesa' 27 | directions: 'Mga Direksyon' 28 | comment: 'Magkomento' 29 | email: 'Email' 30 | message: 'Mensahe' 31 | contact: 32 | name: 'Pangalan' 33 | email: 'Email' 34 | message: 'Mensahe' 35 | 36 | helpers: 37 | submit: 38 | contact: 39 | # This is the "Send message" button on the "Contact" page. 40 | create: 'Magpadala ng Mensahe' 41 | 42 | # Labels and hints examples 43 | # labels: 44 | # defaults: 45 | # password: 'Password' 46 | # user: 47 | # new: 48 | # email: 'E-mail upang mag-sign in.' 49 | # edit: 50 | # email: 'E-mail.' 51 | # hints: 52 | # defaults: 53 | # username: 'Pangalan ng user na mag-sign in.' 54 | # password: 'Walang espesyal na mga character, mangyaring.' 55 | -------------------------------------------------------------------------------- /config/locales/fil/splash.fil.yml: -------------------------------------------------------------------------------- 1 | fil: 2 | pages: 3 | index: 4 | life-is-tough: 'Minsan ang buhay ay matigas ...' 5 | find-refuge: 'Maghanap ng Refuge' 6 | add-restroom-button-label: 'Magdagdag ng isa pang Banyo' 7 | 8 | html-alt-attributes: 9 | app-store: 'I-download ang Refuge Restrooms iOS app' 10 | play-store: 'I-download ang Refuge Restrooms Android app' 11 | patreon: 'Suportahan ang proyekto sa Patreon' 12 | -------------------------------------------------------------------------------- /config/locales/fil/text_msg.fil.yml: -------------------------------------------------------------------------------- 1 | fil: 2 | pages: 3 | text: 4 | title: 'Kumuha ng pinakamalapit na banyo sa pamamagitan ng Teksto' 5 | intro: 'Kung kailangan mo lamang upang makakuha ng pinakamalapit at ligtas na banyo ngayon, maaari mong makuha ito sa pamamagitan ng text sa anumang telepono na may SMS.' 6 | instructions: 'I-text ang iyong lokasyon sa +1 (415) 367-3288' 7 | tip: "Para sa pinaka-tumpak na mga resulta, isama ang kalyeng kinaroroonan, lungsod, estado at bansa. Makakakuha ka agad ng pangalan ng lokasyon at kinaroroonan!" 8 | -------------------------------------------------------------------------------- /config/locales/fr/contacts.fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | contacts: 3 | new: 4 | request-edit-for-restroom: "Demande d'edition pour Toilettes %{restroom_name}" 5 | contact-title: 'Contact' 6 | leave-this-field-blank: 'Laissez ce champ vide !' 7 | submitted: 8 | thank-you-period: 'Merci pour votre message.' 9 | thank-you-exclamation: 'Merci pour votre message !' 10 | cannot-send: "Impossible d'envoyer votre message." 11 | we-will-get-back-to-you: "Nous reviendrons vers vous bientôt." 12 | -------------------------------------------------------------------------------- /config/locales/fr/footer.fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | layouts: 3 | footer: 4 | aria-labels: 5 | github: 'Refuge Restrooms sur GitHub' 6 | twitter: 'Refuge Restrooms sur twitter' 7 | facebook: 'Refuge Restrooms sur Facebook' 8 | tumblr: 'Le blog de Refuge Restrooms sur tumblr' 9 | email: 'Email Refuge Restrooms' 10 | refuge-restrooms-is-open-source: 'Refuge Restrooms est open source.' 11 | code-on-github: 'Code sur github.' 12 | contribute-to-the-project: 'Contribuez au projet' 13 | on-patreon: 'sur Patreon.' 14 | copyleft: 'copyleft' 15 | refuge-restrooms: 'Refuge Restrooms.' -------------------------------------------------------------------------------- /config/locales/fr/navigation.fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | layouts: 3 | navigation: 4 | toggle-navigation-button-label: 'Basculer en mode navigation' 5 | submit-a-new-restroom-hyperlink-label: 'Soumettre de nouvelles toilettes' 6 | about-hyperlink-label: 'À Propos' 7 | contact-hyperlink-label: 'Contact' 8 | 9 | resources-dropdown-button-label: 'Ressources' 10 | download-unisex-restroom-signs-hyperlink-label: 'Télécharger des panneaux pour toilettes unisexes' 11 | public-api-hyperlink-label: "API Publique" 12 | -------------------------------------------------------------------------------- /config/locales/fr/restrooms.fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | restrooms: 3 | index: 4 | map-view-button-label: 'Voir la carte' 5 | 6 | show: 7 | thumbs-up-button-label: "J'aime ces toilettes" 8 | thumbs-down-button-label: "Je n'aime pas ces toilettes" 9 | -------------------------------------------------------------------------------- /config/locales/fr/search.fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | layouts: 3 | search: 4 | search: 'Recherche' 5 | search-by-current-location: "Recherche à partir de votre position actuelle" -------------------------------------------------------------------------------- /config/locales/fr/signs.fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | pages: 3 | signs: 4 | title: 'Panneaux pour toilettes à técharger' 5 | intro: "Si vous avez des toilettes publiques dans votre immeuble ou votre entreprise qui ne sont pas sexistes, faites-le savoir. Vous (et/ou le propriétaire du bâtiment/la direction) pouvez l'ajouter à la base de données et afficher l'un des panneaux ci-dessous pour faire savoir aux gens que vous soutenez un accès sûr pour tous. Les deux panneaux sont des fichiers PDF imprimables." 6 | head-accessible: 'Toilettes Accesibles' 7 | head-non-accessible: 'Toilettes Inacessibles' 8 | download: 'Télécharger au format PDF' 9 | -------------------------------------------------------------------------------- /config/locales/fr/simple_form.fr.yml: -------------------------------------------------------------------------------- 1 | # See this documentation: https://github.com/plataformatec/simple_form#i18n 2 | # And this StackOverflow answer: https://stackoverflow.com/questions/35906089/changing-simple-form-submit-button-i18n-text 3 | 4 | fr: 5 | simple_form: 6 | "oui": 'Oui' 7 | "non": 'Non' 8 | required: 9 | text: 'requis' 10 | mark: '*' 11 | # You can uncomment the line below if you need to overwrite the whole required html. 12 | # When using html, text and mark won't be used. 13 | # html: '*' 14 | error_notification: 15 | default_message: "Veuillez corriger les problèmes ci-dessous:" 16 | 17 | labels: 18 | defaults: 19 | name: 'Nom' 20 | street: 'Adresse' 21 | city: 'Ville' 22 | state: 'État/Région' 23 | country: 'Pays' 24 | accessible: 'Accessible' 25 | unisex: 'Unisexe' 26 | changing_table: 'Table à langer' 27 | directions: 'Indications' 28 | comment: 'Commentaire' 29 | email: 'Email' 30 | message: 'Message' 31 | contact: 32 | name: 'Nom' 33 | email: 'Email' 34 | message: 'Message' 35 | 36 | helpers: 37 | submit: 38 | contact: 39 | # This is the "Send message" button on the "Contact" page. 40 | create: 'Envoyer' 41 | 42 | # Labels and hints examples 43 | # labels: 44 | # defaults: 45 | # password: 'Password' 46 | # user: 47 | # new: 48 | # email: 'E-mail to sign in.' 49 | # edit: 50 | # email: 'E-mail.' 51 | # hints: 52 | # defaults: 53 | # username: 'User name to sign in.' 54 | # password: 'No special characters, please.' 55 | 56 | -------------------------------------------------------------------------------- /config/locales/fr/splash.fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | pages: 3 | index: 4 | life-is-tough: 'Parfois la vie est dure...' 5 | find-refuge: 'Trouver un Refuge' 6 | add-restroom-button-label: 'Ajouter Des Toilettes' 7 | -------------------------------------------------------------------------------- /config/locales/fr/text_msg.fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | pages: 3 | text: 4 | title: "Recevez les toilettes les plus proches par SMS" 5 | intro: "Si vous avez besoin de connaitre les toilettes sécurisées les plus proches tout de suite, vous pouvez les recevoir par SMS sur n'importe quel téléphone." 6 | instructions: "Envoyez votre localisation au +1 (415) 367-3288 " 7 | tip: "Pour des résultats plus précis, veuillez inclure l'adresse exacte, la ville, la région et le pays. Vous recevrez en un instant le nom de l'emplacement et son adresse exacte !" 8 | -------------------------------------------------------------------------------- /config/locales/hi/contacts.hi.yml: -------------------------------------------------------------------------------- 1 | hi: 2 | contacts: 3 | new: 4 | request-edit-for-restroom: '% {restroom_name} रेस्टरूम के लिए संशोधन का अनुरोध करें' 5 | contact-title: 'संपर्क' 6 | leave-this-field-blank: 'इस फील्ड को खाली छोड़ दो!' 7 | submitted: 8 | thank-you-period: 'आपके संदेश के लिए धन्यवाद।' 9 | thank-you-exclamation: 'आपके संदेश के लिए धन्यवाद!' 10 | cannot-send: 'सन्देश भेजने में दिक्कत आ रही हैं।' 11 | we-will-get-back-to-you: "हम जल्द ही आपसे संपर्क करेंगे।" 12 | -------------------------------------------------------------------------------- /config/locales/hi/footer.hi.yml: -------------------------------------------------------------------------------- 1 | hi: 2 | layouts: 3 | footer: 4 | aria-labels: 5 | github: 'गिटहब पर रिफ्यूज रेस्टरूम' 6 | twitter: 'ट्विटर पर रिफ्यूज रेस्टरूम' 7 | facebook: 'फेसबुक पर रिफ्यूज रेस्टरूम' 8 | tumblr: 'टम्बलर पर रिफ्यूज रेस्टरूम ब्लॉग' 9 | email: 'ईमेल रिफ्यूज रेस्टरूम' 10 | refuge-restrooms-is-open-source: 'रिफ्यूज रेस्टरूम ओपन सोर्स है।' 11 | code-on-github: 'गिटहब पर कोड।' 12 | contribute-to-the-project: 'परियोजना में योगदान' 13 | on-patreon: 'पेट्रियन पर' 14 | copyleft: 'copyleft' 15 | refuge-restrooms: 'रिफ्यूज रेस्टरूम.' 16 | -------------------------------------------------------------------------------- /config/locales/hi/hi.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at http://guides.rubyonrails.org/i18n.html. 31 | 32 | hi: 33 | hello: "हेलो दुनिया !" 34 | -------------------------------------------------------------------------------- /config/locales/hi/navigation.hi.yml: -------------------------------------------------------------------------------- 1 | hi: 2 | layouts: 3 | navigation: 4 | toggle-navigation-button-label: 'नेविगेशन टॉगल करें' 5 | submit-a-new-restroom-hyperlink-label: 'एक नया रेस्टरूम सबमिट करें' 6 | about-hyperlink-label: 'बारे में' 7 | contact-hyperlink-label: 'संपर्क' 8 | 9 | resources-dropdown-button-label: 'संसाधन' 10 | download-unisex-restroom-signs-hyperlink-label: 'यूनिसेक्स रेस्टरूम साइन्स डाउनलोड करें' 11 | public-api-hyperlink-label: Public API 12 | -------------------------------------------------------------------------------- /config/locales/hi/restrooms.hi.yml: -------------------------------------------------------------------------------- 1 | hi: 2 | restrooms: 3 | index: 4 | map-view-button-label: 'मानचित्र दृश्य' 5 | 6 | show: 7 | thumbs-up-button-label: 'शाबाशी' 8 | thumbs-down-button-label: 'नाकामयाबी' 9 | -------------------------------------------------------------------------------- /config/locales/hi/search.hi.yml: -------------------------------------------------------------------------------- 1 | hi: 2 | layouts: 3 | search: 4 | search: 'खोज' 5 | search-by-current-location: 'वर्तमान स्थान से खोजें' 6 | 7 | -------------------------------------------------------------------------------- /config/locales/hi/signs.hi.yml: -------------------------------------------------------------------------------- 1 | hi: 2 | pages: 3 | signs: 4 | title: 'डाउनलोड करने योग्य रेस्टरूम प्रतिक' 5 | intro: 'अगर आपके पास अपनी इमारत या व्यापार में सार्वजनिक विश्राम कक्ष है जो लिंग-तटस्थ है, तो लोगों को बताएं। आप (और / या भवन मालिक / प्रबंधन) इसे डेटाबेस में जोड़ सकते हैं, और लोगों को यह जानने के लिए नीचे दिए गए संकेतों में से एक पोस्ट कर सकते हैं कि आप सभी के लिए सुरक्षित पहुंच का समर्थन करते हैं। दोनों संकेत प्रिंट करने योग्य पीडीएफ फाइलें हैं। ' 6 | head-accessible: 'सुलभ रेस्टरूम' 7 | head-non-accessible: 'गैर-सुलभ रेस्टरूम' 8 | download: 'पीडीएफ डाउनलोड करें' 9 | -------------------------------------------------------------------------------- /config/locales/hi/simple_form.hi.yml: -------------------------------------------------------------------------------- 1 | # See this documentation: https://github.com/plataformatec/simple_form#i18n 2 | # And this StackOverflow answer: https://stackoverflow.com/questions/35906089/changing-simple-form-submit-button-i18n-text 3 | 4 | hi: 5 | simple_form: 6 | "yes": 'हाँ' 7 | "no": 'नहीं' 8 | required: 9 | text: 'आवश्यक' 10 | mark: '*' 11 | # You can uncomment the line below if you need to overwrite the whole required html. 12 | # When using html, text and mark won't be used. 13 | # html: '*' 14 | error_notification: 15 | default_message: "कृपया नीचे दी गई समस्याओं की समीक्षा करें:" 16 | 17 | labels: 18 | defaults: 19 | name: 'नाम' 20 | street: 'गली' 21 | city: 'शहर' 22 | state: 'राज्य / प्रांत' 23 | country: 'देश' 24 | accessible: 'सुलभ' 25 | unisex: 'यूनिसेक्स' 26 | changing_table: 'चेंजिंग टेबल' 27 | directions: 'दिशानिर्देश' 28 | comment: 'टिप्पणी' 29 | email: 'ईमेल' 30 | message: 'संदेश' 31 | contact: 32 | name: 'नाम' 33 | email: 'ईमेल' 34 | message: 'संदेश' 35 | 36 | helpers: 37 | submit: 38 | contact: 39 | # This is the "Send message" button on the "Contact" page. 40 | create: 'संदेश भेजें' 41 | 42 | # Labels and hints examples 43 | # labels: 44 | # defaults: 45 | # password: 'Password' 46 | # user: 47 | # new: 48 | # email: 'E-mail to sign in.' 49 | # edit: 50 | # email: 'E-mail.' 51 | # hints: 52 | # defaults: 53 | # username: 'User name to sign in.' 54 | # password: 'No special characters, please.' 55 | 56 | -------------------------------------------------------------------------------- /config/locales/hi/splash.hi.yml: -------------------------------------------------------------------------------- 1 | hi: 2 | pages: 3 | index: 4 | life-is-tough: 'कभी-कभी जीवन कठिन होता है ...' 5 | find-refuge: 'रिफ्यूज खोजे ' 6 | add-restroom-button-label: 'एक रेस्टरूम जोड़ें' 7 | -------------------------------------------------------------------------------- /config/locales/hi/text_msg.hi.yml: -------------------------------------------------------------------------------- 1 | hi: 2 | pages: 3 | text: 4 | title: 'पाठ द्वारा निकटतम रेस्टरूम प्राप्त करें' 5 | intro: 'अगर आपको अभी निकटतम सुरक्षित रेस्टरूम में जाना है अभी अभी em>, तो आप इसे किसी भी फोन पर टेक्स्ट द्वारा प्राप्त कर सकते हैं जिसमें एसएमएस है।' 6 | instructions: 'अपना स्थान इस नंबर पर टेक्स्ट करें +1 (415) 367-3288' 7 | tip: "सबसे सटीक परिणामों के लिए, सड़क का पता, शहर, राज्य और देश शामिल करें। आपको तुरंत स्थान का नाम और पता मिलेगा!" 8 | -------------------------------------------------------------------------------- /config/locales/it/contacts.it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | contacts: 3 | new: 4 | request-edit-for-restroom: 'Richiesta di modifica per il servizio igienico %{restroom_name}' 5 | contact-title: 'Contatto' 6 | leave-this-field-blank: 'Lascia questo spazio bianco!' 7 | submitted: 8 | thank-you-period: 'Grazie per il tuo messaggio.' 9 | thank-you-exclamation: 'Grazie per il tuo messaggio!' 10 | cannot-send: 'Non riesco ad inviare il messaggio.' 11 | we-will-get-back-to-you: "Torneremo presto." 12 | -------------------------------------------------------------------------------- /config/locales/it/footer.it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | layouts: 3 | footer: 4 | aria-labels: 5 | github: 'Refuge Restrooms su GitHub' 6 | twitter: 'Refuge Restrooms su twitter' 7 | facebook: 'Refuge Restrooms su Facebook' 8 | tumblr: 'Il blog di Refuge Restrooms su tumblr' 9 | email: 'Invia una email a Refuge Restrooms' 10 | refuge-restrooms-is-open-source: 'refuge restrooms è open source.' 11 | code-on-github: 'modifica il codice su github.' 12 | contribute-to-the-project: 'contribuisci al progetto' 13 | on-patreon: 'su patreon.' 14 | copyleft: 'copyleft' 15 | refuge-restrooms: 'refuge restrooms.' 16 | -------------------------------------------------------------------------------- /config/locales/it/navigation.it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | layouts: 3 | navigation: 4 | toggle-navigation-button-label: 'Attiva la navigazione' 5 | submit-a-new-restroom-hyperlink-label: 'Invia un nuovo servizio igienico' 6 | about-hyperlink-label: 'About' 7 | contact-hyperlink-label: 'Contatti' 8 | 9 | resources-dropdown-button-label: 'Risorse' 10 | download-unisex-restroom-signs-hyperlink-label: 'Scarica le insegne Unisex Restroom' 11 | public-api-hyperlink-label: API Pubblica 12 | -------------------------------------------------------------------------------- /config/locales/it/restrooms.it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | restrooms: 3 | index: 4 | map-view-button-label: 'Visualizzazione mappa' 5 | 6 | show: 7 | thumbs-up-button-label: 'Pollice su' 8 | thumbs-down-button-label: 'Pollice giù' 9 | -------------------------------------------------------------------------------- /config/locales/it/search.it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | layouts: 3 | search: 4 | search: 'Ricerca' 5 | search-by-current-location: 'Cerca in base alla posizione attuale' 6 | 7 | -------------------------------------------------------------------------------- /config/locales/it/signs.it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | pages: 3 | signs: 4 | title: 'Insegne Restroom scaricabili' 5 | intro: "Se hai un servizio igienico pubblico nel tuo edificio o nella tua attività che è gender-neutral, fallo sapere agli altri. Tu (e/o il proprietario/management dell'edificio) puoi aggiungerlo al database, e affiggere una delle insegne in basso per far sapere alle persone il tuo sostegno all'accesso sicuro per tutti. Entrambe le insegne sono file PDF stampabili." 6 | head-accessible: 'Servizi igienici accessibili' 7 | head-non-accessible: 'Servizi igienici non accessibili' 8 | download: 'Scarica PDF' 9 | -------------------------------------------------------------------------------- /config/locales/it/simple_form.it.yml: -------------------------------------------------------------------------------- 1 | # See this documentation: https://github.com/plataformatec/simple_form#i18n 2 | # And this StackOverflow answer: https://stackoverflow.com/questions/35906089/changing-simple-form-submit-button-i18n-text 3 | 4 | it: 5 | simple_form: 6 | "si": 'Sì' 7 | "no": 'No' 8 | required: 9 | text: 'richiesto' 10 | mark: '*' 11 | # You can uncomment the line below if you need to overwrite the whole required html. 12 | # When using html, text and mark won't be used. 13 | # html: '*' 14 | error_notification: 15 | default_message: "Per favore descrivi il problema in basso:" 16 | 17 | labels: 18 | defaults: 19 | name: 'Nome' 20 | street: 'Via' 21 | city: 'Città' 22 | state: 'Regione/Provincia' 23 | country: 'Paese' 24 | accessible: 'Accessibile' 25 | unisex: 'Unisex' 26 | changing_table: 'Fasciatoio' 27 | directions: 'Indicazioni' 28 | comment: 'Commento' 29 | email: 'Email' 30 | message: 'Messaggio' 31 | contact: 32 | name: 'Nome' 33 | email: 'Email' 34 | message: 'Messaggio' 35 | 36 | helpers: 37 | submit: 38 | contact: 39 | # This is the "Send message" button on the "Contact" page. 40 | create: 'Invia messaggio' 41 | 42 | # Labels and hints examples 43 | # labels: 44 | # defaults: 45 | # password: 'Password' 46 | # user: 47 | # new: 48 | # email: 'E-mail to sign in.' 49 | # edit: 50 | # email: 'E-mail.' 51 | # hints: 52 | # defaults: 53 | # username: 'User name to sign in.' 54 | # password: 'No special characters, please.' 55 | 56 | -------------------------------------------------------------------------------- /config/locales/it/splash.it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | pages: 3 | index: 4 | life-is-tough: 'A volte la vita è dura...' 5 | find-refuge: 'Trova un rifugio' 6 | add-restroom-button-label: 'Aggiungi un servizio igienico' 7 | -------------------------------------------------------------------------------- /config/locales/it/text_msg.it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | pages: 3 | text: 4 | title: 'Ricevi il servizio igienico più vicino via SMS' 5 | intro: 'Sei hai solo bisogno di arrivare al servizio igienico sicuro più vicino adesso, puoi riceverlo tramite testo su qualunque telefono che abbia gli SMS.' 6 | instructions: 'Scrivi la tua posizione al +1 (415) 367-3288' 7 | tip: "Per i risultati più precisi, includi indirizzo, città, stato/provincia e paese. Riceverai istantaneamente il nome di una località e l'indirizzo!" 8 | -------------------------------------------------------------------------------- /config/locales/pl/contacts.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | contacts: 3 | new: 4 | request-edit-for-restroom: 'Zasugeruj zmianę w łazience %{restroom_name}' 5 | contact-title: 'Kontakt' 6 | leave-this-field-blank: 'Zostaw to pole puste!' 7 | submitted: 8 | thank-you-period: 'Dziękujemy za wiadomość.' 9 | thank-you-exclamation: 'Dziękujemy za wiadomość!' 10 | cannot-send: 'Nie można było wysłać wiadomości.' 11 | we-will-get-back-to-you: "Odpowiemy wkrótce." 12 | -------------------------------------------------------------------------------- /config/locales/pl/footer.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | layouts: 3 | footer: 4 | aria-labels: 5 | github: 'Refuge Restrooms na GitHubie' 6 | twitter: 'Refuge Restrooms na Twitterze' 7 | facebook: 'Refuge Restrooms na Facebooku' 8 | tumblr: 'blog Refuge Restrooms na Tumblrze' 9 | email: 'napisz email do Refuge Restrooms' 10 | refuge-restrooms-is-open-source: 'refuge restrooms jest projektem open source.' 11 | code-on-github: 'wesprzyj na githubie' 12 | contribute-to-the-project: 'wesprzyj projekt' 13 | on-patreon: 'na Patreonie' 14 | copyleft: 'copyleft' 15 | refuge-restrooms: 'refuge restrooms.' -------------------------------------------------------------------------------- /config/locales/pl/navigation.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | layouts: 3 | navigation: 4 | toggle-navigation-button-label: 'Nawigacja' 5 | submit-a-new-restroom-hyperlink-label: 'Dodaj łazienkę' 6 | about-hyperlink-label: 'O Refuge' 7 | contact-hyperlink-label: 'Kontakt' 8 | resources-dropdown-button-label: 'Materiały' 9 | download-unisex-restroom-signs-hyperlink-label: 'Pobierz znaki łazienek unisex' 10 | public-api-hyperlink-label: Public API 11 | -------------------------------------------------------------------------------- /config/locales/pl/restrooms.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | restrooms: 3 | index: 4 | map-view-button-label: 'Mapa' 5 | 6 | show: 7 | thumbs-up-button-label: 'Kciuk w górę' 8 | thumbs-down-button-label: 'Kciuk w dół' 9 | -------------------------------------------------------------------------------- /config/locales/pl/search.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | layouts: 3 | search: 4 | search: 'Szukaj' 5 | search-by-current-location: 'Szukaj, używając lokalizacji' 6 | 7 | -------------------------------------------------------------------------------- /config/locales/pl/signs.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | pages: 3 | signs: 4 | title: 'Pobierz znaki do łazienek' 5 | intro: 'Jeżeli w Twojej placówce znajduje się publiczna łazienka dostępna niezależnie od płci, możesz dodać ją do bazy danych i udostępnić któryś z poniższych znaków. W ten sposób dasz znać odwiedzającym, że cenisz ich bezpieczeństwo i komfort. Pliki są w formacie PDF, możliwe do wydrukowania w wysokiej rozdzielczości.' 6 | head-accessible: 'Z udogodnieniami dla osób niepełnosprawnych' 7 | head-non-accessible: 'Bez udogodnień dla osób niepełnosprawnych' 8 | download: 'Pobierz PDF' 9 | -------------------------------------------------------------------------------- /config/locales/pl/simple_form.pl.yml: -------------------------------------------------------------------------------- 1 | # See this documentation: https://github.com/plataformatec/simple_form#i18n 2 | # And this StackOverflow answer: https://stackoverflow.com/questions/35906089/changing-simple-form-submit-button-i18n-text 3 | 4 | pl: 5 | simple_form: 6 | "yes": 'Tak' 7 | "no": 'Nie' 8 | required: 9 | text: 'wymagane' 10 | mark: '*' 11 | # You can uncomment the line below if you need to overwrite the whole required html. 12 | # When using html, text and mark won't be used. 13 | # html: '*' 14 | error_notification: 15 | default_message: "Sprawdź poniższe informacje:" 16 | 17 | labels: 18 | defaults: 19 | name: 'Nazwa' 20 | street: 'Ulica' 21 | city: 'Miasto' 22 | state: 'Stan / województwo' 23 | country: 'Kraj' 24 | accessible: 'Z udogodnieniami dla osób niepełnosprawnych' 25 | unisex: 'Unisex' 26 | changing_table: 'Przewijak' 27 | directions: 'Wskazówki' 28 | comment: 'Komentarz' 29 | email: 'Email' 30 | message: 'Wiadomość' 31 | contact: 32 | name: 'Imię' 33 | email: 'Email' 34 | message: 'Wiadomość' 35 | 36 | helpers: 37 | submit: 38 | contact: 39 | # This is the "Send message" button on the "Contact" page. 40 | create: 'Wyślij wiadomość' 41 | 42 | # Labels and hints examples 43 | # labels: 44 | # defaults: 45 | # password: 'Hasło' 46 | # user: 47 | # new: 48 | # email: 'Podaj email aby się zalogować.' 49 | # edit: 50 | # email: 'email.' 51 | # hints: 52 | # defaults: 53 | # username: 'Login' 54 | # password: 'Bez znaków specjalnych.' 55 | 56 | -------------------------------------------------------------------------------- /config/locales/pl/splash.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | pages: 3 | index: 4 | life-is-tough: 'Sometimes life is tough...' 5 | find-refuge: 'Find Refuge' 6 | add-restroom-button-label: 'Dodaj łazienkę' 7 | -------------------------------------------------------------------------------- /config/locales/pl/text_msg.pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | pages: 3 | text: 4 | title: 'Usługa niedostęna w Polsce.' 5 | -------------------------------------------------------------------------------- /config/locales/pt-BR/activerecord.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | activerecord: 3 | errors: 4 | messages: 5 | accepted: "deve ser aceito(a)" 6 | blank: "deve ser preenchido(a)" 7 | confirmation: "não foi confirmado(a) corretamente" 8 | date_starting_today: "não pode ser uma data passada" 9 | empty: "deve ser preenchido(a)" 10 | equal_to: "deve ser igual a %{count}" 11 | even: "deve ser par" 12 | exclusion: "é reservado(a)" 13 | greater_than: "deve ser maior que %{count}" 14 | greater_than_or_equal_to: "deve ser maior ou igual a %{count}" 15 | inclusion: "não foi preenchido" 16 | invalid: "está inválido(a)" 17 | less_than: "deve ser menor que %{count}" 18 | less_than_or_equal_to: "deve ser menor ou igual a %{count}" 19 | not_a_number: "não é um número" 20 | not_in_program: "não está no programa %{program}" 21 | odd: "deve ser ímpar" 22 | overlaps: "está conflitando com outro plano existente" 23 | record_invalid: "não é válido" 24 | taken: "já está em uso" 25 | too_long: "é muito longo(a) (máximo de %{count} caracteres)" 26 | too_short: "é muito curto(a) (mínimo de %{count} caracteres)" 27 | uniq: "deve ser único(a)" 28 | wrong_length: "tem o comprimento errado (deve ter %{count} caracteres)" 29 | -------------------------------------------------------------------------------- /config/locales/pt-BR/contacts.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | contacts: 3 | new: 4 | request-edit-for-restroom: 'Solicitar alteração para o banheiro %{restroom_name}' 5 | contact-title: 'Contato' 6 | leave-this-field-blank: 'Deixe este campo em branco!' 7 | submitted: 8 | thank-you-period: 'Obrigado por sua mensagem.' 9 | thank-you-exclamation: 'Obrigado por sua mensagem!' 10 | cannot-send: 'Não foi possível enviar a mensagem.' 11 | we-will-get-back-to-you: "Entraremos em contato em breve." 12 | -------------------------------------------------------------------------------- /config/locales/pt-BR/footer.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | layouts: 3 | footer: 4 | aria-labels: 5 | github: 'Refuge Restrooms no GitHub' 6 | twitter: 'Refuge Restrooms no Twitter' 7 | facebook: 'Refuge Restrooms no Facebook' 8 | tumblr: 'Blog do Refuge Restrooms no Tumblr' 9 | email: 'Envie um Email para Refuge Restrooms' 10 | refuge-restrooms-is-open-source: 'Refuge Restrooms é código aberto.' 11 | code-on-github: 'Código no GitHub.' 12 | contribute-to-the-project: 'Contribua com o projeto' 13 | on-patreon: 'no Patreon.' 14 | copyleft: 'Copyleft' 15 | refuge-restrooms: 'Refuge Restrooms.' 16 | -------------------------------------------------------------------------------- /config/locales/pt-BR/navigation.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | layouts: 3 | navigation: 4 | toggle-navigation-button-label: 'Alternar navegação' 5 | submit-a-new-restroom-hyperlink-label: 'Cadastrar Banheiro' 6 | about-hyperlink-label: 'Sobre' 7 | contact-hyperlink-label: 'Contato' 8 | 9 | resources-dropdown-button-label: 'Recursos' 10 | download-unisex-restroom-signs-hyperlink-label: 'Baixar Avisos de Banheiro Unissex' 11 | public-api-hyperlink-label: API Pública 12 | -------------------------------------------------------------------------------- /config/locales/pt-BR/pt-BR.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at http://guides.rubyonrails.org/i18n.html. 31 | 32 | pt-BR: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /config/locales/pt-BR/restrooms.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | restrooms: 3 | index: 4 | map-view-button-label: 'Ver mapa' 5 | 6 | show: 7 | thumbs-up-button-label: 'Gostei' 8 | thumbs-down-button-label: 'Não Gostei' 9 | -------------------------------------------------------------------------------- /config/locales/pt-BR/search.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | layouts: 3 | search: 4 | search: 'Buscar' 5 | search-by-current-location: 'Buscar pela localização atual' 6 | 7 | -------------------------------------------------------------------------------- /config/locales/pt-BR/signs.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | pages: 3 | signs: 4 | title: 'Baixar Avisos de Banheiro' 5 | intro: 'Se você tiver um banheiro público no seu prédio ou empresa que é neutro de gênero, divulgue. Você (e/ou quem cuida do prédio/gerência) pode adicioná-lo ao banco de dados e ainda colocar um dos avisos abaixo para que se saiba que você apoia o acesso seguro para todas as pessoas. Ambos os avisos são arquivos PDF imprimíveis.' 6 | head-accessible: 'Banheiros Acessíveis' 7 | head-non-accessible: 'Banheiros Não Acessíveis' 8 | download: 'Baixe o PDF' 9 | -------------------------------------------------------------------------------- /config/locales/pt-BR/simple_form.pt-BR.yml: -------------------------------------------------------------------------------- 1 | # See this documentation: https://github.com/plataformatec/simple_form#i18n 2 | # And this StackOverflow answer: https://stackoverflow.com/questions/35906089/changing-simple-form-submit-button-i18n-text 3 | 4 | pt-BR: 5 | simple_form: 6 | "yes": 'Sim' 7 | "no": 'Não' 8 | required: 9 | text: 'obrigatório' 10 | mark: '*' 11 | # You can uncomment the line below if you need to overwrite the whole required html. 12 | # When using html, text and mark won't be used. 13 | # html: '*' 14 | error_notification: 15 | default_message: "Por favor verifique os problemas abaixo:" 16 | 17 | labels: 18 | defaults: 19 | name: 'Nome' 20 | street: 'Endereço' 21 | city: 'Cidade' 22 | state: 'Estado' 23 | country: 'País' 24 | accessible: 'Acessível' 25 | unisex: 'Unissex' 26 | changing_table: 'Trocador' 27 | directions: 'Instruções' 28 | comment: 'Comentário' 29 | email: 'Email' 30 | message: 'Mensagem' 31 | contact: 32 | name: 'Nome' 33 | email: 'Email' 34 | message: 'Mensagem' 35 | 36 | helpers: 37 | submit: 38 | contact: 39 | # This is the "Send message" button on the "Contact" page. 40 | create: 'Enviar mensagem' 41 | 42 | # Labels and hints examples 43 | # labels: 44 | # defaults: 45 | # password: 'Password' 46 | # user: 47 | # new: 48 | # email: 'E-mail to sign in.' 49 | # edit: 50 | # email: 'E-mail.' 51 | # hints: 52 | # defaults: 53 | # username: 'User name to sign in.' 54 | # password: 'No special characters, please.' 55 | 56 | -------------------------------------------------------------------------------- /config/locales/pt-BR/splash.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | pages: 3 | index: 4 | life-is-tough: 'Às vezes a vida é dura...' 5 | find-refuge: 'Encontre Refúgio' 6 | add-restroom-button-label: 'Cadastre um banheiro' 7 | -------------------------------------------------------------------------------- /config/locales/pt-BR/text_msg.pt-BR.yml: -------------------------------------------------------------------------------- 1 | pt-BR: 2 | pages: 3 | text: 4 | title: 'Ache o banheiro mais próximo por SMS' 5 | intro: 'Se você precisa do banheiro mais próximo agora, você pode conseguir por SMS em qualquer telefone que suporte esse serviço.' 6 | instructions: 'Mande sua localização para +1 (415) 367-3288 (EUA)' 7 | tip: "Pra resultados mais precisos, inclua o endereço, cidade, estado e país. Você receberá o nome e endereço do local imediatamente!" 8 | -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 8 | threads threads_count, threads_count 9 | 10 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 11 | # 12 | port ENV.fetch("PORT") { 3000 } 13 | 14 | # Specifies the `environment` that Puma will run in. 15 | # 16 | environment ENV.fetch("RAILS_ENV") { "development" } 17 | 18 | # Specifies the number of `workers` to boot in clustered mode. 19 | # Workers are forked webserver processes. If using threads and workers together 20 | # the concurrency of the application would be max `threads` * `workers`. 21 | # Workers do not work on JRuby or Windows (both of which do not support 22 | # processes). 23 | # 24 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 25 | 26 | # Use the `preload_app!` method when specifying a `workers` number. 27 | # This directive tells Puma to first boot the application and load code 28 | # before forking the application. This takes advantage of Copy On Write 29 | # process behavior so workers use less memory. 30 | # 31 | # preload_app! 32 | 33 | # Allow puma to be restarted by `rails restart` command. 34 | plugin :tmp_restart 35 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | # TODO autoloading order changed. This should be managed by configs instead: 2 | # https://guides.rubyonrails.org/v7.0/autoloading_and_reloading_constants.html#autoloading-when-the-application-boots 3 | require_relative '../app/controllers/api/v1/base' 4 | require_relative '../app/controllers/api/base' 5 | 6 | Rails.application.routes.draw do 7 | # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 8 | 9 | devise_for :admin_users, ActiveAdmin::Devise.config 10 | ActiveAdmin.routes(self) 11 | resources :restrooms, except: [:edit, :destroy] 12 | 13 | namespace :api do 14 | resources :docs, only: [:index] 15 | end 16 | 17 | mount API::Base => '/api' 18 | 19 | get '/contact', to: 'contacts#new' 20 | get "/*id" => 'pages#show', as: :page, format: false 21 | root 'pages#index' 22 | 23 | resources "contacts", only: [:new, :create] 24 | end 25 | -------------------------------------------------------------------------------- /config/spring.rb: -------------------------------------------------------------------------------- 1 | %w( 2 | .ruby-version 3 | .rbenv-vars 4 | tmp/restart.txt 5 | tmp/caching-dev.txt 6 | ).each { |path| Spring.watch(path) } 7 | -------------------------------------------------------------------------------- /config/storage.yml: -------------------------------------------------------------------------------- 1 | test: 2 | service: Disk 3 | root: <%= Rails.root.join("tmp/storage") %> 4 | 5 | local: 6 | service: Disk 7 | root: <%= Rails.root.join("storage") %> 8 | 9 | # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) 10 | # amazon: 11 | # service: S3 12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> 13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> 14 | # region: us-east-1 15 | # bucket: your_own_bucket 16 | 17 | # Remember not to checkin your GCS keyfile to a repository 18 | # google: 19 | # service: GCS 20 | # project: your_project 21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> 22 | # bucket: your_own_bucket 23 | 24 | # Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) 25 | # microsoft: 26 | # service: AzureStorage 27 | # storage_account_name: your_account_name 28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> 29 | # container: your_container_name 30 | 31 | # mirror: 32 | # service: Mirror 33 | # primary: local 34 | # mirrors: [ amazon, google, microsoft ] 35 | -------------------------------------------------------------------------------- /config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | 3 | // jQuery 4 | const webpack = require('webpack') 5 | environment.plugins.prepend('Provide', 6 | new webpack.ProvidePlugin({ 7 | $: 'jquery/src/jquery', 8 | jQuery: 'jquery/src/jquery' 9 | }) 10 | ) 11 | 12 | // rails-erb-loader 13 | const erb = require('./loaders/erb') 14 | environment.loaders.append('erb', erb) 15 | 16 | module.exports = environment 17 | -------------------------------------------------------------------------------- /config/webpack/loaders/erb.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test: /\.erb$/, 3 | enforce: 'pre', 4 | exclude: /node_modules/, 5 | use: [{ 6 | loader: 'rails-erb-loader', 7 | options: { 8 | runner: (/^win/.test(process.platform) ? 'ruby ' : '') + 'bin/rails runner' 9 | } 10 | }] 11 | } 12 | -------------------------------------------------------------------------------- /config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /config/webpacker.yml: -------------------------------------------------------------------------------- 1 | # Note: You must restart bin/webpack-dev-server for changes to take effect 2 | 3 | default: &default 4 | source_path: app/javascript 5 | source_entry_path: packs 6 | public_root_path: public 7 | public_output_path: packs 8 | cache_path: tmp/cache/webpacker 9 | webpack_compile_output: true 10 | 11 | # Additional paths webpack should lookup modules 12 | # ['app/assets', 'engine/foo/app/assets'] 13 | additional_paths: [] 14 | 15 | # Reload manifest.json on all requests so we reload latest compiled packs 16 | cache_manifest: false 17 | 18 | # Extract and emit a css file 19 | extract_css: false 20 | 21 | static_assets_extensions: 22 | - .jpg 23 | - .jpeg 24 | - .png 25 | - .gif 26 | - .tiff 27 | - .ico 28 | - .svg 29 | - .eot 30 | - .otf 31 | - .ttf 32 | - .woff 33 | - .woff2 34 | 35 | extensions: 36 | - .js.erb 37 | - .mjs 38 | - .js 39 | - .sass 40 | - .scss 41 | - .css 42 | - .module.sass 43 | - .module.scss 44 | - .module.css 45 | - .png 46 | - .svg 47 | - .gif 48 | - .jpeg 49 | - .jpg 50 | 51 | development: 52 | <<: *default 53 | compile: true 54 | 55 | # Reference: https://webpack.js.org/configuration/dev-server/ 56 | dev_server: 57 | https: false 58 | host: localhost 59 | port: 3035 60 | public: localhost:3035 61 | hmr: false 62 | # Inline should be set to true if using HMR 63 | inline: true 64 | overlay: true 65 | compress: true 66 | disable_host_check: true 67 | use_local_ip: false 68 | quiet: false 69 | pretty: false 70 | headers: 71 | 'Access-Control-Allow-Origin': '*' 72 | watch_options: 73 | ignored: '**/node_modules/**' 74 | 75 | 76 | test: 77 | <<: *default 78 | compile: true 79 | 80 | # Compile test packs to a separate directory 81 | public_output_path: packs-test 82 | 83 | production: 84 | <<: *default 85 | 86 | # Production depends on precompilation of packs prior to booting for performance. 87 | compile: false 88 | 89 | # Extract and emit a css file 90 | extract_css: true 91 | 92 | # Cache manifest.json for performance 93 | cache_manifest: true 94 | -------------------------------------------------------------------------------- /db/migrate/20131128044650_create_bathrooms.rb: -------------------------------------------------------------------------------- 1 | class CreateBathrooms < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :bathrooms do |t| 4 | t.string :name 5 | t.string :street 6 | t.string :city 7 | t.string :state 8 | t.integer :access 9 | t.integer :type 10 | t.text :directions 11 | t.text :comment 12 | t.float :latitude 13 | t.float :longitude 14 | 15 | t.timestamps 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /db/migrate/20131225210247_change_table.rb: -------------------------------------------------------------------------------- 1 | class ChangeTable < ActiveRecord::Migration[4.2] 2 | def change 3 | rename_column :bathrooms, :type, :bath_type 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20131225221341_add_column_for_flags.rb: -------------------------------------------------------------------------------- 1 | class AddColumnForFlags < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :bathrooms, :flags, :integer, :default => 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140117004118_add_visability.rb: -------------------------------------------------------------------------------- 1 | class AddVisability < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :bathrooms, :visable, :boolean, :default => true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140117055923_change_flags_to_up_vote_down_vote.rb: -------------------------------------------------------------------------------- 1 | class ChangeFlagsToUpVoteDownVote < ActiveRecord::Migration[4.2] 2 | def change 3 | remove_column :bathrooms, :flags 4 | remove_column :bathrooms, :visable 5 | add_column :bathrooms, :downvote, :integer, :default => 0 6 | add_column :bathrooms, :upvote, :integer, :default => 0 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20140119222501_add_countryfor_international_listings.rb: -------------------------------------------------------------------------------- 1 | class AddCountryforInternationalListings < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :bathrooms, :country, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140207051319_devise_create_admin_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseCreateAdminUsers < ActiveRecord::Migration[4.2] 2 | def migrate(direction) 3 | super 4 | # Create a default user 5 | AdminUser.create!(:email => 'admin@example.com', :password => 'password', :password_confirmation => 'password') if direction == :up 6 | end 7 | 8 | def change 9 | create_table(:admin_users) do |t| 10 | ## Database authenticatable 11 | t.string :email, :null => false, :default => "" 12 | t.string :encrypted_password, :null => false, :default => "" 13 | 14 | ## Recoverable 15 | t.string :reset_password_token 16 | t.datetime :reset_password_sent_at 17 | 18 | ## Rememberable 19 | t.datetime :remember_created_at 20 | 21 | ## Trackable 22 | t.integer :sign_in_count, :default => 0, :null => false 23 | t.datetime :current_sign_in_at 24 | t.datetime :last_sign_in_at 25 | t.string :current_sign_in_ip 26 | t.string :last_sign_in_ip 27 | 28 | ## Confirmable 29 | # t.string :confirmation_token 30 | # t.datetime :confirmed_at 31 | # t.datetime :confirmation_sent_at 32 | # t.string :unconfirmed_email # Only if using reconfirmable 33 | 34 | ## Lockable 35 | # t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts 36 | # t.string :unlock_token # Only if unlock strategy is :email or :both 37 | # t.datetime :locked_at 38 | 39 | 40 | t.timestamps 41 | end 42 | 43 | add_index :admin_users, :email, :unique => true 44 | add_index :admin_users, :reset_password_token, :unique => true 45 | # add_index :admin_users, :confirmation_token, :unique => true 46 | # add_index :admin_users, :unlock_token, :unique => true 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /db/migrate/20140207051321_create_active_admin_comments.rb: -------------------------------------------------------------------------------- 1 | class CreateActiveAdminComments < ActiveRecord::Migration[4.2] 2 | def self.up 3 | create_table :active_admin_comments do |t| 4 | t.string :namespace 5 | t.text :body 6 | t.string :resource_id, :null => false 7 | t.string :resource_type, :null => false 8 | t.references :author, :polymorphic => true 9 | t.timestamps 10 | end 11 | add_index :active_admin_comments, [:namespace] 12 | add_index :active_admin_comments, [:author_type, :author_id] 13 | add_index :active_admin_comments, [:resource_type, :resource_id] 14 | end 15 | 16 | def self.down 17 | drop_table :active_admin_comments 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /db/migrate/20140315033524_add_unaccent_extension.rb: -------------------------------------------------------------------------------- 1 | class AddUnaccentExtension < ActiveRecord::Migration[4.2] 2 | def up 3 | execute "create extension unaccent" 4 | end 5 | 6 | def down 7 | execute "drop extension unaccent" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20140413154842_rename_bathrooms_to_restrooms.rb: -------------------------------------------------------------------------------- 1 | class RenameBathroomsToRestrooms < ActiveRecord::Migration[4.2] 2 | def change 3 | rename_table :bathrooms, :restrooms 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140423031801_change_access_and_bath_type_to_boolean.rb: -------------------------------------------------------------------------------- 1 | class ChangeAccessAndBathTypeToBoolean < ActiveRecord::Migration[4.2] 2 | def up 3 | # If access is 1 it is accessible 4 | # If bath_type is 0 it is unisex 5 | connection.execute(%q{ 6 | ALTER TABLE restrooms ALTER access TYPE bool 7 | USING CASE WHEN access=0 THEN FALSE 8 | ELSE TRUE END; 9 | 10 | ALTER TABLE restrooms ALTER bath_type TYPE bool 11 | USING CASE WHEN bath_type=1 THEN FALSE 12 | ELSE TRUE END; 13 | }) 14 | 15 | change_table :restrooms do |t| 16 | t.rename :access, :accessible 17 | t.rename :bath_type, :unisex 18 | end 19 | 20 | change_column :restrooms, :accessible, :boolean, default: false 21 | change_column :restrooms, :unisex, :boolean, default: false 22 | end 23 | 24 | def down 25 | change_table :restrooms do |t| 26 | t.rename :accessible, :access 27 | t.rename :unisex, :bath_type 28 | end 29 | 30 | connection.execute(%q{ 31 | ALTER TABLE restrooms ALTER access DROP DEFAULT; 32 | ALTER TABLE restrooms ALTER access TYPE integer 33 | USING CASE WHEN access=TRUE THEN 1 34 | ELSE 0 END; 35 | 36 | ALTER TABLE restrooms ALTER bath_type DROP DEFAULT; 37 | ALTER TABLE restrooms ALTER bath_type TYPE integer 38 | USING CASE WHEN bath_type=FALSE THEN 1 39 | ELSE 0 END; 40 | }) 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /db/migrate/20151018191859_add_changing_table_flag_to_restrooms.rb: -------------------------------------------------------------------------------- 1 | class AddChangingTableFlagToRestrooms < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :restrooms, :changing_table, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20180107190215_add_edit_id_to_restrooms.rb: -------------------------------------------------------------------------------- 1 | class AddEditIdToRestrooms < ActiveRecord::Migration[5.1] 2 | def change 3 | add_column :restrooms, :edit_id, :integer, :default => 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20180306165419_add_approved_to_restrooms.rb: -------------------------------------------------------------------------------- 1 | class AddApprovedToRestrooms < ActiveRecord::Migration[5.1] 2 | def change 3 | add_column :restrooms, :approved, :boolean, :default => true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20180613231032_set_edit_id_to_id.rb: -------------------------------------------------------------------------------- 1 | class SetEditIdToId < ActiveRecord::Migration[5.1] 2 | def change 3 | Restroom.update_all('edit_id = id') 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | 9 | require 'csv' 10 | 11 | Restroom.transaction do 12 | CSV.foreach('db/export.csv') do |row| 13 | restroom = Restroom.create( 14 | :name => row[1], 15 | :street => row[3], 16 | :city => row[4], 17 | :state => row[5], 18 | :accessible => row[10], 19 | :unisex => row[2], 20 | :directions => row[11], 21 | :comment => row[12], 22 | :latitude => row[8], 23 | :longitude => row[9], 24 | :country => row[6] 25 | ) 26 | restroom.update(edit_id: restroom.id) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | volumes: 4 | bundle: 5 | driver: local 6 | 7 | services: 8 | db: 9 | image: postgres 10 | restart: always 11 | environment: 12 | POSTGRES_PASSWORD: uaI7m2kmWd949DMv4dCh 13 | 14 | web: 15 | environment: 16 | PGPASSWORD: uaI7m2kmWd949DMv4dCh 17 | build: . 18 | entrypoint: [setup/entry] 19 | command: bundle exec rails s -p 3000 -b '0.0.0.0' 20 | volumes: 21 | - .:/refugerestrooms 22 | - /refugerestrooms/node_modules 23 | - bundle:/usr/local/bundle 24 | ports: 25 | - "3000:3000" 26 | depends_on: 27 | - db 28 | -------------------------------------------------------------------------------- /features/edit.feature: -------------------------------------------------------------------------------- 1 | Feature: Edit restroom 2 | 3 | Scenario: Visit a restroom page 4 | When I am on the restroom page for id 1 5 | Then I should see the edit link 6 | 7 | Scenario: View an edit 8 | When I visit the edit page for 'Winnepeg Restroom' 9 | Then I should see the restroom address 10 | -------------------------------------------------------------------------------- /features/step_definitions/edit_steps.rb: -------------------------------------------------------------------------------- 1 | Given(/^I am on the restroom page for id 1$/) do 2 | FactoryBot.create( 3 | :restroom, 4 | id: 1, 5 | name: 'Winnipeg restroom', 6 | street: '91 Albert St.', 7 | city: 'Winnipeg', 8 | state: 'MB', 9 | country: 'Canada'.merge(locations[:Winnipeg]) 10 | ) 11 | visit '/restrooms/1' 12 | end 13 | 14 | Then(/^I should see the edit link$/) do 15 | expect(page).to have_content("Propose an edit to this listing.") 16 | end 17 | 18 | Given(/^I visit the edit page for 'Winnepeg restroom'$/) do 19 | FactoryBot.create( 20 | :restroom, 21 | id: 1, 22 | name: 'Winnipeg restroom', 23 | street: '91 Albert St.', 24 | city: 'Winnipeg', 25 | state: 'MB', 26 | country: 'Canada'.merge(locations[:Winnipeg]) 27 | ) 28 | visit '/restrooms/new?edit_id=1&restroom_id=1' 29 | end 30 | 31 | Then(/^I should see the restroom address$/) do 32 | expect(page).to have_content("684 East hastings") 33 | end 34 | 35 | Given(/^I submit an edit to 'Winnepeg Restroom'$/) do 36 | FactoryBot.create( 37 | :restroom, 38 | id: 1, 39 | name: 'Winnipeg restroom', 40 | street: '91 Albert St.', 41 | city: 'Winnipeg', 42 | state: 'MB', 43 | country: 'Canada'.merge(locations[:Winnipeg]) 44 | ) 45 | visit '/restrooms/new?edit_id=1&restroom_id=1' 46 | fill_in 'restroom[name]', with: 'Not Winnepeg restroom' 47 | click_button "Save Restroom" 48 | end 49 | 50 | Then(/^I should see that the edit has been submitted$/) do 51 | expect(page).to have_content("Your edit has been submitted. We will review it and update the listing") 52 | end 53 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/lib/assets/.keep -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/lib/tasks/.keep -------------------------------------------------------------------------------- /lib/tasks/assets.rake: -------------------------------------------------------------------------------- 1 | namespace :assets do 2 | desc "Compile assets" 3 | task precompile: [:environment] do 4 | Rake::Task["webpacker:compile"].invoke 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/tasks/fix_accents.rake: -------------------------------------------------------------------------------- 1 | namespace :db do 2 | desc "Fix wrongly-encoded accented characters (use db:fix_accents[dry_run] to preview changes)" 3 | task :fix_accents, [:dry_run] => [:environment] do |t, args| 4 | args.with_defaults(dry_run: false) 5 | 6 | transformations = { 7 | "Ž" => "é", 8 | "™" => "ô", 9 | "è" => "è", 10 | "é" => "é", 11 | "�Restroom�" => "'Restroom'", 12 | "� " => "é ", 13 | "ÌÊ" => "à", 14 | "Ì«" => "ô", 15 | "Ì©" => "é", 16 | "̬s" => "’s", 17 | "̬" => "è", 18 | "̨" => "î", 19 | "Ìø" => "ï", 20 | "ÌÛ" => "À", 21 | "\u008F" => "è", 22 | "á" => "á", 23 | "&" => "&", 24 | "ç" => "ç" 25 | } 26 | 27 | if args.dry_run 28 | puts "Dry running fix_accents" 29 | else 30 | puts "Running fix_accents" 31 | end 32 | 33 | puts "" 34 | 35 | fields = [:name, :street, :city, :directions, :comment] 36 | 37 | fields.each do |field| 38 | where_clause = transformations.keys.map{|original| "#{field} like '%#{original}%'"}.join(" OR ") 39 | 40 | puts field, "="*field.length,"" 41 | 42 | Restroom.where(where_clause).each do |restroom| 43 | transformations.each do |original, transformed| 44 | restroom.send("#{field}=", restroom.send(field).gsub(original, transformed)) 45 | end 46 | 47 | puts restroom.id, "", restroom.send("#{field}_was"), "", restroom.send(field), "\n\n" 48 | 49 | restroom.save unless args.dry_run 50 | end 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/templates/erb/controller/view.html.erb: -------------------------------------------------------------------------------- 1 |Find me in <%= @path %>
5 | -------------------------------------------------------------------------------- /lib/templates/erb/scaffold/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%%= form_for(@<%= singular_table_name %>, :html => { :class => "form-horizontal" }) do |f| %> 2 | <%% if @<%= singular_table_name %>.errors.any? %> 3 |<%= attribute.human_name %> | 15 | <% end -%> 16 |17 | | 18 | | 19 | | <%%= <%= singular_table_name %>.<%= attribute.name %> %> | 26 | <% end -%> 27 |<%%= link_to 'Show', <%= singular_table_name %> %> | 28 |<%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %> | 29 |<%%= link_to 'Destroy', <%= singular_table_name %>, method: :delete, data: { confirm: 'Are you sure?' } %> | 30 | <%% end %> 31 | 32 |
---|
You may have mistyped the address or the page may have moved.
55 |If you are the application owner check the logs for more information.
57 | 58 | 59 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |Maybe you tried to change something you didn't have access to.
55 |If you are the application owner check the logs for more information.
57 | 58 | 59 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |If you are the application owner check the logs for more information.
56 | 57 | 58 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/public/favicon.ico -------------------------------------------------------------------------------- /public/fr-rr-sign-no-handi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/public/fr-rr-sign-no-handi.pdf -------------------------------------------------------------------------------- /public/fr-rr-sign-with-handi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/public/fr-rr-sign-with-handi.pdf -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /public/rr-sign-no-handi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/public/rr-sign-no-handi.pdf -------------------------------------------------------------------------------- /public/rr-sign-with-handi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/public/rr-sign-with-handi.pdf -------------------------------------------------------------------------------- /setup/entry: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Check by local gems and if is something is missing, run bundle install 5 | bundle check || bundle install --jobs 20 --retry 5 6 | 7 | # Set up the database for development, and seed with placeholder data from `db/export.csv` 8 | SEEDING_DONT_GEOCODE="true" rails db:setup 9 | 10 | exec "$@" 11 | -------------------------------------------------------------------------------- /spec/controllers/pages_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe PagesController do 4 | it_behaves_like 'localized request', :index 5 | 6 | it "#index" do 7 | get :index 8 | expect(response).to have_http_status(:success) 9 | end 10 | 11 | it "#about" do 12 | get :show, params: { id: 'about' } 13 | expect(response).to have_http_status(:success) 14 | end 15 | 16 | it "#signs" do 17 | get :show, params: { id: 'signs' } 18 | expect(response).to have_http_status(:success) 19 | end 20 | 21 | it "#text" do 22 | get :show, params: { id: 'text' } 23 | expect(response).to have_http_status(:success) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/controllers/restrooms_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe RestroomsController do 4 | it_behaves_like 'localized request', :index 5 | 6 | it "#index" do 7 | get :index 8 | 9 | expect(response).to have_http_status(:success) 10 | end 11 | 12 | describe "voting" do 13 | let(:restroom) { create(:restroom) } 14 | 15 | it "can downvote" do 16 | post_params = { 17 | id: restroom.id, 18 | restroom: { 19 | downvote: true 20 | } 21 | } 22 | 23 | expect do 24 | post :update, params: post_params 25 | end.to change { restroom.reload.downvote }.by 1 26 | end 27 | 28 | it "can upvote" do 29 | post_params = { 30 | id: restroom.id, 31 | restroom: { 32 | upvote: true 33 | } 34 | } 35 | 36 | expect do 37 | post :update, params: post_params 38 | end.to change { restroom.reload.upvote }.by 1 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /spec/factories/restrooms.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :restroom do 3 | name { 'The SF LGBT Center' } 4 | street { '1800 Market St' } 5 | city { 'San Francisco' } 6 | state { 'CA' } 7 | country { 'US' } 8 | upvote { 22 } 9 | downvote { 11 } 10 | comment { 'Comment' } 11 | directions { 'Direction' } 12 | approved { true } 13 | 14 | after(:create) do |restroom| 15 | restroom.update(edit_id: restroom.id) 16 | end 17 | 18 | trait :geocoded do 19 | latitude { 37.7749 } 20 | longitude { -122.4194 } 21 | end 22 | 23 | trait :unisex do 24 | unisex { true } 25 | end 26 | 27 | trait :ada do 28 | accessible { true } 29 | end 30 | 31 | trait :comment do 32 | comment { 'Spacious, single-stall with auto-flushing toilet and ADA railings.' } 33 | end 34 | 35 | trait :directions do 36 | directions { 'Near the back, past the counter on the left.' } 37 | end 38 | 39 | factory :unisex_restroom, traits: [:unisex] 40 | factory :ada_restroom, traits: [:ada] 41 | factory :unisex_and_ada_restroom, traits: %i[unisex ada] 42 | 43 | factory :oakland_restroom do 44 | name { 'Some Cafe' } 45 | street { '1400 Broadway' } 46 | city { 'Oakland' } 47 | state { 'CA' } 48 | country { 'US' } 49 | latitude { 37.8044 } 50 | longitude { -122.27081 } 51 | end 52 | 53 | factory :spam_restroom do 54 | name { 'Spam Cafe' } 55 | street { 'Spam Street' } 56 | city { 'Spam City' } 57 | state { 'Spam State' } 58 | country { 'Spam Country' } 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /spec/features/contacts_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'the contact process' do 4 | it 'shows a generic contact when contact is not from restroom form' do 5 | restroom = create(:restroom, name: "Mission Creek Cafe") 6 | 7 | visit restroom_path restroom 8 | click_link 'Contact' 9 | 10 | expect(page).not_to have_content('Mission Creek Cafe') 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/models/rating_level_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe RatingLevel do 4 | describe '.for_restroom' do 5 | it 'returns green level for restrooms with a rating higher than 70%' do 6 | restroom = Restroom.new upvote: 71, downvote: 29 7 | expect(described_class.for_restroom(restroom)).to eq described_class.green 8 | end 9 | 10 | it 'returns red level for restrooms with a rating up to 50%' do 11 | restroom = Restroom.new upvote: 50, downvote: 50 12 | expect(described_class.for_restroom(restroom)).to eq described_class.red 13 | end 14 | 15 | it 'returns yellow level for restrooms with a rating of 51%' do 16 | restroom = Restroom.new upvote: 51, downvote: 49 17 | expect(described_class.for_restroom(restroom)).to eq described_class.yellow 18 | end 19 | 20 | it 'returns yellow level for restrooms with a rating of 70%' do 21 | restroom = Restroom.new upvote: 70, downvote: 30 22 | expect(described_class.for_restroom(restroom)).to eq described_class.yellow 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/services/save_restroom_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe SaveRestroom do 4 | it 'saves a restroom' do 5 | restroom = build(:restroom, id: 1) 6 | 7 | actual_restroom = described_class.new(restroom).call 8 | 9 | expect(Restroom.all.size).to eq(1) 10 | expect(actual_restroom.id).to eq(1) 11 | expect(actual_restroom.edit_id).to eq(1) 12 | expect(actual_restroom.approved?).to be(true) 13 | end 14 | 15 | it 'creates an error for spam' do 16 | restroom = build(:spam_restroom) 17 | 18 | actual_restroom = described_class.new(restroom).call 19 | 20 | expect(Restroom.all.size).to eq(0) 21 | expect(actual_restroom.errors.key?(:spam)).to be true 22 | end 23 | 24 | it "updates the edit id and approved" do 25 | restroom = build(:restroom) 26 | restroom.edit_id = 1 27 | restroom.approved = false 28 | 29 | actual_restroom = described_class.new(restroom).call 30 | 31 | expect(Restroom.all.size).to eq(1) 32 | expect(actual_restroom.edit_id).to eq(1) 33 | expect(actual_restroom.approved?).to be(false) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /spec/support/locations.rb: -------------------------------------------------------------------------------- 1 | module Locations 2 | def locations 3 | { 4 | Winnipeg: { latitude: 49.8975494, longitude: -97.140118 }, 5 | Vancouver: { latitude: 49.281006, longitude: -123.089959 }, 6 | Oakland: { latitude: 37.8044, longitude: -122.2708 } 7 | } 8 | end 9 | 10 | def mock_location(location_name) 11 | location = locations[location_name.to_sym] 12 | page.execute_script " 13 | navigator.geolocation.getCurrentPosition = function(success, failure) { 14 | success({ coords: { 15 | latitude: #{location[:latitude]}, 16 | longitude: #{location[:longitude]} 17 | }, timestamp: Date.now() }); 18 | } 19 | " 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/support/rspec.rb: -------------------------------------------------------------------------------- 1 | require 'capybara/cuprite' 2 | require 'capybara/rspec' 3 | require 'rspec/rails' 4 | require 'json' 5 | # spec/spec_helper.rb 6 | # 7 | 8 | require_relative 'locations' 9 | 10 | Capybara.javascript_driver = :cuprite 11 | Capybara.register_driver(:cuprite) do |app| 12 | Capybara::Cuprite::Driver.new(app, window_size: [1200, 800], browser_options: { 'no-sandbox': nil }, timeout: 30) 13 | end 14 | 15 | WebMock.disable_net_connect!(allow_localhost: true) 16 | 17 | RSpec.configure do |config| 18 | config.include Locations 19 | 20 | config.before do 21 | stub_request(:get, "http://maps.googleapis.com/maps/api/geocode/json?language=en&latlng=37.8044,-122.2708") 22 | .with( 23 | headers: { 24 | 'Accept' => '*/*', 25 | 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 26 | 'User-Agent' => 'Ruby' 27 | } 28 | ) 29 | .to_return(status: 200, body: File.new(Rails.root.join('spec/fixtures/guess_in_oakland.json')), headers: {}) 30 | 31 | recaptcha_response = { 'success' => true } 32 | stub_request(:post, 'https://www.google.com/recaptcha/api/siteverify') 33 | .to_return(status: 200, body: recaptcha_response.to_json, 34 | headers: { 'Content-Type' => 'application/json' }) 35 | 36 | # Akismet response for spam 37 | stub_request(:post, /.*.rest.akismet.com\/1.1\/comment-check/) 38 | .with(body: /^.*Spam.*$/) 39 | .to_return(status: 200, body: 'true', headers: {}) 40 | 41 | # Akismet response for non-spam 42 | stub_request(:post, /.*.rest.akismet.com\/1.1\/comment-check/) 43 | .with { |request| request.body.exclude? "Spam" } 44 | .to_return(status: 200, body: 'false', headers: {}) 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /spec/support/shared_examples/localized_request.rb: -------------------------------------------------------------------------------- 1 | shared_examples_for 'localized request' do |action| 2 | it 'calls I18n.with_locale in requests' do 3 | allow(I18n).to receive(:with_locale) 4 | 5 | get action 6 | 7 | expect(I18n).to have_received(:with_locale).with(:en) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/vendor/assets/javascripts/.keep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RefugeRestrooms/refugerestrooms/1c8ecbdea379496077d1e3a145e41b74bf790a55/vendor/assets/stylesheets/.keep --------------------------------------------------------------------------------