├── .babelrc
├── .dockerignore
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature.md
└── workflows
│ └── tests.yml
├── .gitignore
├── .gitlab-ci.yml
├── .postcssrc.yml
├── .rspec
├── .rubocop.yml
├── .ruby-version
├── .tool-versions
├── CONTRIBUTORS.md
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── PULL_REQUEST_TEMPLATE.md
├── README-EN.md
├── README.md
├── Rakefile
├── app
├── assets
│ ├── config
│ │ └── manifest.js
│ ├── images
│ │ ├── .keep
│ │ ├── brazil_flag.svg
│ │ ├── favicon.ico
│ │ ├── header.jpg
│ │ ├── ico-password.png
│ │ ├── ico-user.png
│ │ ├── logo-mail.png
│ │ ├── people_in_love.svg
│ │ ├── preview-ribbon.png
│ │ ├── scale.png
│ │ ├── scale.svg
│ │ ├── test-ribbon.png
│ │ ├── trans-people.svg
│ │ ├── transervicos-logo.png
│ │ └── transervicos-logo.svg
│ ├── javascripts
│ │ ├── application.js
│ │ ├── cable.js
│ │ ├── channels
│ │ │ └── .keep
│ │ ├── components
│ │ │ ├── application.js
│ │ │ └── carousel.js
│ │ ├── email_validator.js
│ │ ├── error_formatter.js
│ │ ├── infinite_scroll.js
│ │ ├── like_dislike.js
│ │ ├── registrations.js
│ │ ├── report_validator.js
│ │ ├── required_validator.js
│ │ └── service_form.js
│ └── stylesheets
│ │ ├── _core.scss
│ │ ├── _variables.scss
│ │ ├── application.scss
│ │ ├── auth.scss
│ │ ├── jasny-bootstrap.min.css
│ │ └── welcome.scss
├── channels
│ └── application_cable
│ │ ├── channel.rb
│ │ └── connection.rb
├── controllers
│ ├── application_controller.rb
│ ├── concerns
│ │ └── .keep
│ ├── dashboard_controller.rb
│ ├── errors_controller.rb
│ ├── lists_controller.rb
│ ├── registrations_controller.rb
│ ├── reports_controller.rb
│ ├── services_controller.rb
│ ├── states_controller.rb
│ └── welcome_controller.rb
├── helpers
│ ├── application_helper.rb
│ ├── pagination_helper.rb
│ ├── registrations_helper.rb
│ └── services_helper.rb
├── javascript
│ ├── app.vue
│ └── packs
│ │ └── application.js
├── jobs
│ └── application_job.rb
├── mailers
│ └── application_mailer.rb
├── models
│ ├── .keep
│ ├── ability.rb
│ ├── address.rb
│ ├── application_record.rb
│ ├── area.rb
│ ├── city.rb
│ ├── concerns
│ │ └── .keep
│ ├── forbidden_word.rb
│ ├── report.rb
│ ├── service.rb
│ ├── state.rb
│ ├── subarea.rb
│ ├── user.rb
│ └── voting_session.rb
├── validators
│ ├── city_validator.rb
│ └── state_validator.rb
└── views
│ ├── dashboard
│ └── index.html.erb
│ ├── devise
│ ├── confirmations
│ │ └── new.html.erb
│ ├── mailer
│ │ ├── confirmation_instructions.html.erb
│ │ ├── password_change.html.erb
│ │ ├── preview
│ │ │ └── devise_mailer_preview.rb
│ │ ├── reset_password_instructions.html.erb
│ │ └── unlock_instructions.html.erb
│ ├── passwords
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── registrations
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── sessions
│ │ └── new.html.erb
│ ├── shared
│ │ └── _links.html.erb
│ └── unlocks
│ │ └── new.html.erb
│ ├── errors
│ ├── internal_error.html.erb
│ ├── not_found.html.erb
│ └── unacceptable.html.erb
│ ├── layouts
│ ├── application.html.erb
│ ├── mailer.html.erb
│ └── mailer.text.erb
│ ├── lists
│ └── services_with_reports.html.erb
│ ├── partials
│ ├── _like_unlike.html.erb
│ ├── _service.html.erb
│ ├── _service_list.html.erb
│ ├── _service_report.html.erb
│ └── _service_with_reports_list.html.erb
│ ├── reports
│ └── index.html.erb
│ ├── services
│ ├── _form.html.erb
│ ├── edit.html.erb
│ ├── index.html.erb
│ ├── index.json.jbuilder
│ ├── new.html.erb
│ ├── show.html.erb
│ └── show.json.jbuilder
│ ├── trans_mailer
│ ├── send_mail_report.html.erb
│ └── send_mail_report.txt.erb
│ └── welcome
│ └── index.html.erb
├── bin
├── bundle
├── rails
├── rake
├── setup
├── update
├── webpack
├── webpack-dev-server
└── yarn
├── config.ru
├── config
├── application.rb
├── boot.rb
├── brakeman.ignore
├── cable.yml
├── credentials.yml.enc
├── database.yml.example
├── environment.rb
├── environments
│ ├── development.rb
│ ├── production.rb
│ └── test.rb
├── initializers
│ ├── application_controller_renderer.rb
│ ├── assets.rb
│ ├── backtrace_silencers.rb
│ ├── content_security_policy.rb
│ ├── cookies_serializer.rb
│ ├── devise.rb
│ ├── filter_parameter_logging.rb
│ ├── inflections.rb
│ ├── mime_types.rb
│ ├── simple_form.rb
│ └── wrap_parameters.rb
├── locales
│ ├── devise.en.yml
│ ├── en.yml
│ ├── simple_form.en.yml
│ └── views
│ │ └── welcome
│ │ └── pt-br.yml
├── puma.rb
├── routes.rb
├── spring.rb
├── storage.yml
├── webpack
│ ├── development.js
│ ├── environment.js
│ ├── loaders
│ │ └── vue.js
│ ├── production.js
│ └── test.js
└── webpacker.yml
├── db
├── migrate
│ ├── 20151211201731_devise_create_users.rb
│ ├── 20151214201039_add_extra_fields_to_users.rb
│ ├── 20151214203920_create_services.rb
│ ├── 20151214205645_create_addresses.rb
│ ├── 20151222164956_add_service_id_to_address.rb
│ ├── 20151223150803_create_areas.rb
│ ├── 20151223151132_create_subareas.rb
│ ├── 20151229132522_add_relation_between_service_and_subarea.rb
│ ├── 20160119203424_add_relation_between_user_and_service.rb
│ ├── 20160120123758_create_friendly_id_slugs.rb
│ ├── 20160120124010_add_slug_to_services.rb
│ ├── 20160121150431_add_name_preference_to_user.rb
│ ├── 20160201174342_add_owner_fields_to_services.rb
│ ├── 20160202171035_add_another_phone_to_services.rb
│ ├── 20160202184346_add_admin_to_user.rb
│ ├── 20160219183101_create_states.rb
│ ├── 20160219191835_create_cities.rb
│ ├── 20160222182548_add_city_and_state_to_address.rb
│ ├── 20160301014528_add_website_to_services.rb
│ ├── 20160419185224_create_forbidden_words.rb
│ ├── 20160422180911_acts_as_votable_migration.rb
│ ├── 20160424224442_create_voting_sessions.rb
│ ├── 20160520165008_install_trigram.rb
│ ├── 20160520203043_add_index_service_name.rb
│ ├── 20160520211129_add_index_service_description.rb
│ ├── 20160523194021_create_extension_unaccent.rb
│ ├── 20160523201023_drop_extension_pg_trgm.rb
│ ├── 20160523201311_drop_indexes_pg_trgm_on_services.rb
│ ├── 20160609170644_create_reports.rb
│ ├── 20160613213641_add_email_to_report.rb
│ └── 20190120183617_create_active_storage_tables.active_storage.rb
├── schema.rb
├── seeds.rb
└── structure.sql
├── docker-compose.yml
├── entrypoint.sh
├── lib
├── assets
│ └── .keep
├── tasks
│ └── .keep
└── templates
│ └── erb
│ └── scaffold
│ └── _form.html.erb
├── log
└── .keep
├── package.json
├── public
├── 404.html
├── 422.html
├── 500.html
├── apple-touch-icon-precomposed.png
├── apple-touch-icon.png
├── favicon.ico
└── robots.txt
├── spec
├── features
│ ├── visitor_create_an_account_spec.rb
│ └── visitor_visit_root_path_spec.rb
├── models
│ ├── address_spec.rb
│ ├── area_spec.rb
│ ├── city_spec.rb
│ ├── report_spec.rb
│ ├── service_spec.rb
│ ├── state_spec.rb
│ ├── subarea_spec.rb
│ ├── user_spec.rb
│ └── votin_session_spec.rb
├── rails_helper.rb
└── spec_helper.rb
├── storage
└── .keep
├── tmp
└── .keep
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": "> 1%",
7 | "uglify": true
8 | },
9 | "useBuiltIns": true
10 | }]
11 | ],
12 |
13 | "plugins": [
14 | "syntax-dynamic-import",
15 | "transform-object-rest-spread",
16 | ["transform-class-properties", { "spec": true }]
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | ./.git
2 | ./tmp
3 | ./log
4 | ./node_modules
5 | ./coverage
6 | ./dumps
7 | ./public/system
8 | ./public/assets
9 | *.log
10 | ./Dockerfile*
11 | ./public/packs
12 | ./public/packs-test
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "🐞 Template para bug reports"
3 | about: Por favor use este template quando quiser enviar bug reports
4 | title: "[BUG] - "
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | # O que houve
11 | Descrição do bug
12 |
13 | - Quando eu [abro uma tela/clico em um botão], [algo inesperado acontece].
14 |
15 | # Como reproduzir o bug
16 | Escreva da maneira mais específica possível. Uma boa ideia é seguir a lista
17 | abaixo, dessa forma podemos encontrar e arrumar o problema de forma mais rápida:
18 |
19 | - Nome e versão do navegador usado
20 | - Nome e versão do sistema operacional
21 | - Prints, se possível. Eles ajudam muito a processar o problema.
22 | - Onde você clicou
23 | - O que aconteceu
24 |
25 | Agradecemos seu feedback! ♡
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "✨ Template de issue para novas features"
3 | about: "Quer ver uma feature nova no projeto? Crie uma issue usando este template."
4 | title: "[FEATURE] - "
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 | # O que é
10 | Descreva a feature que você gostaria de ver no projeto
11 |
12 | - Como uma [persona/papel] eu quero [ação] de forma que [resultado/benefício].
13 | - Quando [eu trabalho com alguma coisa/contexto de vida] eu quero que [motivação] de forma que [resultado/benefício].
14 |
15 | # Por que
16 | Motivos para incluir esta feature nova no projeto.
17 |
18 | Agradecemos seu feedback! ♡
19 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: Transerviços - Validações
2 | on: push
3 | jobs:
4 | test:
5 | runs-on: ubuntu-latest
6 | container:
7 | image: ruby:2.6.4
8 | env:
9 | PGUSER: postgres
10 | PGPASSWORD: postgres
11 | RAILS_ENV: test
12 | services:
13 | db:
14 | image: postgres:11
15 | env:
16 | POSTGRES_USER: postgres
17 | POSTGRES_PASSWORD: postgres
18 | ports:
19 | - 5432:5432
20 | options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
21 |
22 | steps:
23 | - uses: actions/checkout@master
24 | - uses: actions/setup-node@v1
25 | with:
26 | node-version: '8.16.2'
27 | - name: Setup dependencies
28 | run: |
29 | wget -q -O - https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
30 | echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
31 | apt-get update -yq
32 | apt-get install -y apt-transport-https build-essential cmake libpq-dev python3-software-properties software-properties-common unzip libgit2-dev yarn
33 | cp config/database.yml.example config/database.yml
34 | gem install bundler:2.0.1
35 | gem install pronto pronto-rubocop pronto-brakeman
36 | bundle check || bundle install --jobs $(nproc)
37 | bundle exec rails db:create db:migrate db:seed db:test:prepare
38 | yarn install
39 | yarn run build
40 | - run: pronto run -f gitlab -c origin/master
41 | - run: rubocop --config .rubocop.yml
42 | - run: brakeman
43 | - run: rspec spec
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-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 bundler config.
8 | /.bundle
9 |
10 | # Ignore all logfiles and tempfiles.
11 | /log/*
12 | /tmp/*
13 | !/log/.keep
14 | !/tmp/.keep
15 |
16 | # Ignore uploaded files in development
17 | /storage/*
18 | !/storage/.keep
19 |
20 | /config/database.yml
21 |
22 | /vendor/cache
23 | /node_modules
24 | /yarn-error.log
25 |
26 | /public/assets
27 | .byebug_history
28 |
29 | # Ignore master key for decrypting credentials and more.
30 | /config/master.key
31 | /public/packs
32 | /public/packs-test
33 | /node_modules
34 | yarn-debug.log*
35 | .yarn-integrity
36 |
37 | coverage
38 |
39 | .env
40 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | # This file is a template, and might need editing before it works on your project.
2 | # Official language image. Look for the different tagged releases at:
3 | # https://hub.docker.com/r/library/ruby/tags/
4 | image: "ruby:2.6"
5 |
6 | # Pick zero or more services to be used on all builds.
7 | # Only needed when using a docker container to run your tests in.
8 | # Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
9 | services:
10 | - postgres:latest
11 |
12 | variables:
13 | DATABASE_URL: postgresql://postgres@postgres
14 | RAILS_ENV: 'test'
15 |
16 | # Cache gems in between builds
17 | cache:
18 | paths:
19 | - vendor/ruby
20 | stages:
21 | - build
22 | - test
23 | - code_review
24 | - deploy
25 |
26 | # This is a basic example for a gem or script which doesn't use
27 | # services such as redis or postgres
28 | before_script:
29 | - ruby -v # Print out ruby version for debugging
30 | # Uncomment next line if your rails app needs a JS runtime:
31 | # Install node and some other deps
32 | - curl -sL https://deb.nodesource.com/setup_8.x | bash -
33 | - apt-get update -yq
34 | - apt-get install -y apt-transport-https build-essential cmake nodejs libpq-dev python3-software-properties software-properties-common unzip
35 |
36 | # Install yarn
37 | - wget -q -O - https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
38 | - echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
39 | - apt-get update -yq
40 | - apt-get install -y yarn
41 |
42 | - cp config/database.yml.example config/database.yml
43 | - gem install bundler # Bundler is not installed with the image
44 | - gem install pronto pronto-rubocop pronto-brakeman
45 | - bundle check || bundle install --jobs $(nproc)
46 | - yarn install
47 |
48 | code_review:
49 | stage: code_review
50 | script:
51 | - pronto run -f gitlab -c origin/master
52 | - rubocop --config .rubocop.yml
53 | - brakeman
54 | allow_failure: true
55 |
56 | build:
57 | stage: build
58 | script:
59 | - yarn run build
60 | - bundle exec rails db:create
61 | - bundle exec rails db:migrate
62 | - bundle exec rails db:seed # TODO: Change/refactor to run once
63 |
64 | test:
65 | stage: test
66 | script:
67 | - bundle exec rails db:test:prepare
68 | - rspec spec
69 |
70 | # This deploy job uses a simple deploy flow to Heroku, other providers, e.g. AWS Elastic Beanstalk
71 | # are supported too: https://github.com/travis-ci/dpl
72 | deploy:
73 | stage: deploy
74 | environment: production
75 | script:
76 | - gem install dpl
77 | - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_PRODUCTION_KEY
78 | only:
79 | - master
80 |
--------------------------------------------------------------------------------
/.postcssrc.yml:
--------------------------------------------------------------------------------
1 | plugins:
2 | postcss-import: {}
3 | postcss-cssnext: {}
4 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --require spec_helper
2 |
--------------------------------------------------------------------------------
/.rubocop.yml:
--------------------------------------------------------------------------------
1 | require:
2 | - rubocop-rails
3 |
4 | Metrics/LineLength:
5 | Max: 120
6 |
7 | AllCops:
8 | TargetRubyVersion: 2.6
9 | Exclude:
10 | - 'vendor/**/*'
11 | - 'node_modules/**/*'
12 | - 'bin/setup'
13 | - 'bin/update'
14 | - 'db/schema.rb'
15 | - 'db/migrate/*.rb'
16 | - 'spec/spec_helper.rb'
17 | - 'spec/rails_helper.rb'
18 |
19 | Style/Documentation:
20 | Enabled: false
21 |
22 | Metrics/BlockLength:
23 | ExcludedMethods: ['describe', 'context', 'feature', 'scenario', 'let']
24 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 2.6.4
2 |
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | ruby 2.6.4
2 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | **Contributors**
2 |
3 | * [Brandon Dees](https://twitter.com/brandondees)
4 | * [Eduardo Stuart](https://twitter.com/eduardostuart)
5 | * [Eliezer Salvato](https://medium.com/@eliezersalvato)
6 | * [Iago Cavalcante](https://twitter.com/iagoangelim)
7 | * [Klaus Kazlauskas](https://twitter.com/klauskpm)
8 | * [leandro Bighetti](https://twitter.com/leandrobighetti)
9 | * [Nayara Alves (Naahh)](https://twitter.com/_jhorse)
10 | * [Rachel Curioso](https://twitter.com/_rchc)
11 | * [Rafael França](https://twitter.com/rafaelfranca)
12 | * [Rimenes Ribeiro](https://twitter.com/rimenes)
13 |
14 | Thank you <3 You're awesome folks!!! <3
15 |
16 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ruby:2.6.4
2 | ENV BUNDLE_PATH="$GEM_HOME" HISTFILE="$APP_HOME/tmp/docker_histfile"
3 |
4 | RUN apt-get update -qq \
5 | && apt-get install -y --no-install-recommends nodejs postgresql-client cmake npm \
6 | && npm install -g yarn
7 |
8 | RUN mkdir /transervicos
9 | WORKDIR /transervicos
10 | RUN gem install bundler:2.0.1
11 | COPY Gemfile /transervicos/Gemfile
12 | COPY Gemfile.lock /transervicos/Gemfile.lock
13 | COPY . /transervicos
14 |
15 | # Install gems using Bundler
16 | RUN bundle check || (bundle install --no-cache --jobs=2 \
17 | && bundle clean --force \
18 | && rm -rf "$BUNDLE_PATH/gems/*/.git" \
19 | && rm -rf "$BUNDLE_PATH/bundler/gems/*/.git")
20 |
21 | # Install JS packages using Yarn
22 | COPY package.json yarn.lock /transervicos/
23 | RUN yarn install && yarn cache clean
24 |
25 | # Add a script to be executed every time the container starts.
26 | COPY entrypoint.sh /usr/bin/
27 | RUN chmod +x /usr/bin/entrypoint.sh
28 | ENTRYPOINT ["entrypoint.sh"]
29 | EXPOSE 3000
30 |
31 | # Start the main process.
32 | CMD ["rails", "server", "-b", "0.0.0.0"]
33 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 | git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5 |
6 | ruby '2.6.4'
7 |
8 | gem 'acts_as_votable'
9 | gem 'bootsnap', '>= 1.1.0', require: false
10 | gem 'bootstrap-sass'
11 | gem 'cancancan'
12 | gem 'coffee-rails', '~> 4.2'
13 | gem 'devise'
14 | gem 'friendly_id'
15 | gem 'i18n', '1.0.0'
16 | gem 'jasny-bootstrap-rails'
17 | gem 'jbuilder', '~> 2.5'
18 | gem 'jquery-turbolinks'
19 | gem 'pg', '~> 1.1', '>= 1.1.4'
20 | gem 'puma', '~> 3.12'
21 | gem 'rails', '~> 5.2'
22 | gem 'rails_admin'
23 | gem 'sassc-rails'
24 | gem 'simple_form'
25 | gem 'turbolinks', '~> 5'
26 | gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]
27 | gem 'uglifier', '>= 1.3.0'
28 | gem 'webpacker'
29 | gem 'will_paginate'
30 | gem 'will_paginate-bootstrap'
31 |
32 | group :development, :test do
33 | gem 'awesome_print'
34 | gem 'byebug', platforms: %i[mri mingw x64_mingw]
35 | gem 'factory_bot_rails'
36 | gem 'pry-rails'
37 | gem 'rspec-activemodel-mocks'
38 | gem 'rspec-rails', '~> 3.8'
39 | end
40 |
41 | group :development do
42 | gem 'better_errors'
43 | gem 'binding_of_caller'
44 | gem 'listen', '>= 3.0.5', '< 3.2'
45 | gem 'pronto'
46 | gem 'pronto-rubocop', require: false
47 | gem 'rubocop', require: false
48 | gem 'rubocop-rails'
49 | gem 'spring'
50 | gem 'spring-watcher-listen', '~> 2.0.0'
51 | end
52 |
53 | group :test do
54 | gem 'capybara', '>= 2.15'
55 | gem 'shoulda-matchers'
56 | gem 'simplecov', require: false
57 | end
58 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # O que
2 | Descrição do que você fez com as mudanças propostas no código.
3 |
4 | # Por que
5 | Por que você abriu este pull request.
6 |
7 | # Amostra
8 | Você pode anexar imagens nesta descrição pra nos mostrar o resultado, se for possível.
9 |
--------------------------------------------------------------------------------
/README-EN.md:
--------------------------------------------------------------------------------
1 | [](https://www.codetriage.com/juuh42dias/transervicos)
2 |
3 | Version in [PORTUGUESE](https://github.com/juuh42dias/transervicos/blob/master/README.md)
4 |
5 | # Transerviços
6 | This is a Rails 5.2.x application.
7 |
8 | # Documentation
9 |
10 | This README describes the goal of this repository and how to configure the development environment. There are also other documentation sources as follow:
11 |
12 | ## Pre conditions:
13 | ### Requirements:
14 |
15 | **Ruby 2.6.4**, preferably managed using [Rbenv](https://github.com/rbenv/rbenv)
16 | [PostgreSQL](https://www.digitalocean.com/community/tutorials/how-to-set-up-ruby-on-rails-with-postgres) must be installed and accepting connections.
17 |
18 |
19 | **Docker and Docker Compose (optional)**
20 |
21 | You can use [Docker](https://docs.docker.com/install/) and [Docker
22 | Compose](https://docs.docker.com/compose/install/)
23 | to run this project on development or test mode.
24 |
25 | If you need help to configure the Ruby development environment, consult this Rails OS X installation guide.
26 |
27 | #
28 | # Getting Started without Docker
29 |
30 | **bin/setup**
31 | Execute the bin/setup script. This script will:
32 |
33 | * Verify if the necessary Ruby version is installed
34 | * Install the gems using Bundler
35 | * Create local copies of `.env` and `database.yml`
36 | * Create, migrate and populate the database
37 | * Run!
38 | * Run the `bin/rake test` to guarantee that everything is working fine.
39 | * Run `bin/rake test:system` to execute every system tests.
40 | * Run `bin/rails`
41 |
42 |
43 | # Gettint Started with Docker
44 |
45 | After you have installed Docker and Docker Compose, run the commands below:
46 |
47 | * `docker-compose build` to create the Docker Images
48 | * `docker-compose run web bash` to open a `shell` inside the container with the
49 | application already setup
50 |
51 |
52 | Within this `shell` you must setup the application database before running other
53 | commands. To do so, run: `bin/setup`
54 |
55 | To run the application, run:
56 |
57 | `rails server -b 0.0.0.0`
58 |
59 | # Testing
60 |
61 | ## PENDING
62 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.codetriage.com/juuh42dias/transervicos)
2 |
3 | Version in [ENGLISH](https://github.com/juuh42dias/transervicos/blob/master/README-EN.md)
4 |
5 | # Transerviços
6 | Esta é uma aplicação Rails 5.2.x
7 |
8 | # Documentação
9 |
10 | Este README descreve o objetivo deste repositório e como configurar um ambiente de desenvolvimento. Outras fontes de documentação são as seguintes:
11 |
12 | ## Pré requisitos
13 | ### Este projeto requer:
14 |
15 |
16 | **Ruby 2.6.4**, preferencialmente gerenciado usando [Rbenv](https://github.com/rbenv/rbenv).
17 | [PostgreSQL](https://www.digitalocean.com/community/tutorials/how-to-set-up-ruby-on-rails-with-postgres) deve estar instalado e aceitando conexões.
18 |
19 | **Docker e Docker Compose (opcionais)**
20 | Uma alternativa para executar o projeto em modo de desenvolvimento e/ou testes é
21 | utilizar o [Docker](https://docs.docker.com/install/) com [Docker
22 | Compose](https://docs.docker.com/compose/install/).
23 |
24 | Se você precisar de ajuda para configurar um ambiente de desenvolvimento Ruby, consulte este Guia de instalação do Rails OS X.
25 |
26 | # Começando sem Docker
27 |
28 | **bin/setup**
29 | Execute o script bin/setup. Este script irá:
30 |
31 | * Verificar se você tem a versão necessária do Ruby
32 | * Instalar gemas usando o Bundler
33 | * Criar cópias locais de .env e database.yml
34 | * Criar, migrar e propagar/popular o banco de dados
35 | * Executá-lo!
36 | * Executar o teste bin/rake para garantir que tudo funcione.
37 | * Executar teste bin/rake: sistema para executar testes do sistema.
38 | * Execute bin/rails
39 |
40 | # Começando com Docker
41 |
42 | Com Docker e Docker Compose instalados, execute no diretório raíz do projeto:
43 |
44 | * `docker-compose build` para criar as imagens necessárias
45 | * `docker-compose run web bash` para acessar o `shell` do container já com a
46 | aplicação instalada
47 |
48 | Dentro desse `shell` você deve configurar o banco de dados antes de executar
49 | outros comandos. Para isso execute:
50 |
51 | `bin/setup`
52 |
53 | Para executar a aplicação, a partir do `shell` do Docker, execute:
54 |
55 | `rails server -b 0.0.0.0 `
56 |
57 |
58 | # Executando o projeto de forma local
59 |
60 | Para executar o projeto de forma local, após executar o comando `bin/setup`,
61 | basta executar `rails server`. A aplicação estará disponível no endereço:
62 | `localhost:3000` em seu navegador.
63 |
64 | Caso você esteja utilizando Docker, basta executar `docker-compose up`. A aplicação estará disponível no endereço:
65 | `localhost:3000` em seu navegador.
66 |
67 |
68 | # Rodando testes
69 |
70 | ## PENDENTE
71 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Add your own tasks in files placed in lib/tasks ending in .rake,
4 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
5 |
6 | require_relative 'config/application'
7 |
8 | Rails.application.load_tasks
9 |
--------------------------------------------------------------------------------
/app/assets/config/manifest.js:
--------------------------------------------------------------------------------
1 | //= link_tree ../images
2 | //= link_directory ../javascripts .js
3 | //= link_directory ../stylesheets .css
4 |
--------------------------------------------------------------------------------
/app/assets/images/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/.keep
--------------------------------------------------------------------------------
/app/assets/images/brazil_flag.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
22 |
23 |
24 |
26 |
27 |
28 |
34 |
35 |
36 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/assets/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/favicon.ico
--------------------------------------------------------------------------------
/app/assets/images/header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/header.jpg
--------------------------------------------------------------------------------
/app/assets/images/ico-password.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/ico-password.png
--------------------------------------------------------------------------------
/app/assets/images/ico-user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/ico-user.png
--------------------------------------------------------------------------------
/app/assets/images/logo-mail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/logo-mail.png
--------------------------------------------------------------------------------
/app/assets/images/people_in_love.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
13 |
17 |
18 |
19 |
22 |
23 |
24 |
27 |
28 |
29 |
32 |
33 |
34 |
36 |
37 |
38 |
40 |
41 |
42 |
44 |
45 |
46 |
47 |
48 |
50 |
51 |
52 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
64 |
65 |
66 |
67 |
69 |
70 |
71 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/app/assets/images/preview-ribbon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/preview-ribbon.png
--------------------------------------------------------------------------------
/app/assets/images/scale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/scale.png
--------------------------------------------------------------------------------
/app/assets/images/scale.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
43 |
44 |
45 |
46 |
47 |
48 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/app/assets/images/test-ribbon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/test-ribbon.png
--------------------------------------------------------------------------------
/app/assets/images/transervicos-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/images/transervicos-logo.png
--------------------------------------------------------------------------------
/app/assets/images/transervicos-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
12 |
14 |
15 |
18 |
19 |
21 |
22 |
23 |
28 |
31 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/assets/javascripts/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into application.js, which will include all the files
2 | // listed below.
3 | //
4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
5 | // vendor/assets/javascripts directory can be referenced here using a relative path.
6 | //
7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 | // compiled file. JavaScript code in this file should be added after the last require_* statement.
9 | //
10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11 | // about supported directives.
12 | //
13 |
14 | //= require jquery
15 | //= require jquery.turbolinks
16 | //= require jquery_ujs
17 | //= require turbolinks
18 | //= require_tree .
19 | //= require bootstrap-sprockets
20 | //= require jasny-bootstrap.min
21 | //= require components/application
22 |
23 | (function($, window, document) {
24 | 'use strict';
25 |
26 | $(function() {
27 | $('select[data-option-dependent=true]').each(function () {
28 | var _this = $(this);
29 | var subareaSelectId = _this.attr('id');
30 | var areaSelectId = _this.data('option-observed');
31 | var optionsDocumentUrl = _this.data('option-url');
32 | var optionValue = _this.data('option-key-method');
33 | var optionText = _this.data('option-value-method');
34 | var subareaDefaultOption = _this.has('option[value=\'\']').size() ? _this.find('option[value=\'\']') : $('').text('Selecione uma subárea');
35 | var subareaElement = $('select#' + subareaSelectId);
36 | var areaElement = $('#' + areaSelectId);
37 |
38 | if (!subareaElement.val() && areaElement.size() > 1) {
39 | subareaElement.attr('disabled', true);
40 | }
41 |
42 | areaElement.on('change', function() {
43 | var regexp = /:[0-9a-zA-Z_]+:/g;
44 | subareaElement.empty().append(subareaDefaultOption);
45 | if (areaElement.val()) {
46 | var url = optionsDocumentUrl.replace(regexp, areaElement.val());
47 | $.getJSON(url, function(data) {
48 | subareaElement.append(buildOptions(data, optionValue, optionText));
49 | subareaElement.attr('disabled', false);
50 | });
51 | }
52 | });
53 | });
54 |
55 | var buildOptions = function(collection, valueAttr, textAttr) {
56 | var options = [];
57 | $.each(collection, function(index, object) {
58 | options.push($(' ').val(object[valueAttr]).text(object[textAttr]));
59 | });
60 | return options;
61 | };
62 |
63 | var loadCitiesForState = function(){
64 | var stateId = $('#state-selector').find("option:selected").val();
65 | var citySelector = $('#city-selector');
66 | if (stateId === '') {
67 | citySelector.attr('disabled', true);
68 | } else {
69 | if (stateId === undefined) return;
70 |
71 | var url = '/state/' + stateId;
72 | $.getJSON(url, function(data) {
73 | citySelector.html($(' ').val('').text('Selecione uma cidade'));
74 | citySelector.append(buildOptions(data['cities'], 'id', 'name'));
75 | citySelector.removeAttr('disabled');
76 | }).done(function(){
77 | var cityId = citySelector.data('selected-city');
78 | if (cityId) {
79 | citySelector.find('option[value=' + cityId + ']').attr('selected','selected');
80 | }
81 | });
82 | }
83 | };
84 |
85 | $("#search-form").bind("reset", function() {
86 | $('#search-description').val('');
87 | $('#state-selector').val('');
88 | var citySelector = $('#city-selector');
89 | citySelector.val('');
90 | var cityId = citySelector.data('selected-city');
91 | if(cityId) {
92 | citySelector.find('option[value=' + cityId + ']').remove('selected');
93 | citySelector.data('selected-city','','');
94 | }
95 | citySelector.attr('disabled', true);
96 | return false;
97 | });
98 |
99 | $('#user_phone_number, #service_phone, #service_other_phone').inputmask({
100 | mask: '(99) 9999?99999'
101 | });
102 |
103 | if ($('#user_social_name').val() === '') {
104 | $('#user_name_preference_social').attr('disabled', true);
105 | }
106 |
107 | if ($('#user_civil_name').val() === '') {
108 | $('#user_name_preference_civil').attr('disabled', true);
109 | }
110 |
111 | $('#state-selector').on('change', loadCitiesForState);
112 |
113 | loadCitiesForState();
114 | });
115 |
116 | }(window.jQuery, window, document));
117 |
--------------------------------------------------------------------------------
/app/assets/javascripts/cable.js:
--------------------------------------------------------------------------------
1 | // Action Cable provides the framework to deal with WebSockets in Rails.
2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command.
3 | //
4 | //= require action_cable
5 | //= require_self
6 | //= require_tree ./channels
7 |
8 | (function() {
9 | this.App || (this.App = {});
10 |
11 | App.cable = ActionCable.createConsumer();
12 |
13 | }).call(this);
14 |
--------------------------------------------------------------------------------
/app/assets/javascripts/channels/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/assets/javascripts/channels/.keep
--------------------------------------------------------------------------------
/app/assets/javascripts/components/application.js:
--------------------------------------------------------------------------------
1 | //= require ./carousel
2 |
--------------------------------------------------------------------------------
/app/assets/javascripts/components/carousel.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 | $('.carousel .control i').on('click', function () {
3 | var m = $(this).data('m'), $container = $(this).closest('.carousel').find('.carousel-container');
4 |
5 | $container.children('.carousel-element').hide().filter('[data-m="'+m+'"]').show();
6 | $(this).parent().children('i').removeClass('active');
7 | $(this).addClass('active');
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/app/assets/javascripts/email_validator.js:
--------------------------------------------------------------------------------
1 | var validateEmail = function(email){
2 | var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
3 | return emailReg.test(email);
4 | };
5 |
6 | var executeValidation = function(parent) {
7 | var input = parent.find('input');
8 | var span = parent.find('span');
9 | if(validateEmail(input.val())){
10 | setMessageAndClass(span, '', 'error');
11 | return true;
12 | }else{
13 | setMessageAndClass(span, 'O e-mail informado é inválido', 'error_required');
14 | return false;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/assets/javascripts/error_formatter.js:
--------------------------------------------------------------------------------
1 | var setMessageAndClass = function(element, message, clazz) {
2 | element.html(message);
3 | var actualClazz = element.attr("class");
4 | element.removeClass(actualClazz);
5 | element.addClass(clazz);
6 | };
7 |
--------------------------------------------------------------------------------
/app/assets/javascripts/infinite_scroll.js:
--------------------------------------------------------------------------------
1 | (function($, window, document) {
2 |
3 | var ready = function(){
4 | if ($('#infinite-scrolling').size() > 0) {
5 | $(window).scroll(function(){
6 | var more_posts_url = $('.pagination a[rel=next]').attr('href');
7 | if (more_posts_url && $(window).scrollTop() > $(document).height() - $(window).height() - 350){
8 | $('.pagination').html("");
9 | var elem = $('
Carregando...
');
10 | $("#posts").append(elem);
11 | $.ajax(more_posts_url, {
12 | method: 'GET',
13 | success: function(data) {
14 | elem.remove();
15 | $("#posts").append(data);
16 | var pageNumber = $('.pagination .active').text();
17 | configureLikeDislike($('#posts-'+pageNumber))
18 | }
19 | });
20 | } else if (!more_posts_url) {
21 | $('.pagination').remove();
22 | }
23 | return;
24 | });
25 | }
26 | }
27 |
28 | $(document).ready(ready);
29 | }(window.jQuery, window, document));
30 |
--------------------------------------------------------------------------------
/app/assets/javascripts/like_dislike.js:
--------------------------------------------------------------------------------
1 | var configureLikeDislike = function(parent){
2 | var upvote = $(parent).find('.upvote').closest('div');
3 | upvote.click(function(event){
4 | var target = $(event.currentTarget).closest('div.likes-container');
5 | var serviceId = $(target).data('service');
6 | var currentClass = 'fa-thumbs-o-up';
7 | var newClass = 'fa-thumbs-up';
8 |
9 | if($(target).find('i').hasClass('fa-thumbs-up')){
10 | currentClass = 'fa-thumbs-up';
11 | newClass = 'fa-thumbs-o-up';
12 | }
13 |
14 | $.ajax('/servicos/'+serviceId+'/like', {
15 | method: 'PUT',
16 | success: function(data) {
17 | console.log(data);
18 | switchClasses(target,'i',currentClass, newClass);
19 | switchClasses(target,'i','fa-thumbs-down', 'fa-thumbs-o-down');
20 |
21 | updateNumbers(target, data.upvotes, data.downvotes);
22 | },
23 | error: function() {
24 | console.log('Oops');
25 | }
26 | });
27 | });
28 |
29 | var downvote = $(parent).find('.downvote').closest('div');
30 | downvote.click(function(event){
31 | var target = $(event.currentTarget).closest('div.likes-container');
32 | var serviceId = $(target).data('service');
33 |
34 | var currentClass = 'fa-thumbs-o-down';
35 | var newClass = 'fa-thumbs-down';
36 |
37 | if($(target).find('i').hasClass('fa-thumbs-down')){
38 | currentClass = 'fa-thumbs-down';
39 | newClass = 'fa-thumbs-o-down';
40 | }
41 |
42 | $.ajax('/servicos/'+serviceId+'/dislike', {
43 | method: 'PUT',
44 | success: function(data) {
45 | console.log(data);
46 | switchClasses(target,'i',currentClass, newClass);
47 | switchClasses(target,'i','fa-thumbs-up', 'fa-thumbs-o-up');
48 | updateNumbers(target, data.upvotes, data.downvotes);
49 | },
50 | error: function() {
51 | console.log('Oops');
52 | }
53 | });
54 | });
55 |
56 | var updateNumbers = function(parent, upvotes, downvotes){
57 | var thumbUpNumber = $(parent).find('span.number-thumbs-up');
58 | thumbUpNumber.html('('+upvotes+')');
59 | var thumbDownNumber = $(parent).find('span.number-thumbs-down');
60 | thumbDownNumber.html('('+downvotes+')');
61 | }
62 |
63 | var switchClasses = function(parent, element, currentClass, newClass){
64 | $(parent).find(element+'.'+currentClass)
65 | .addClass(newClass)
66 | .removeClass(currentClass);
67 | }
68 | };
69 |
70 | (function($, window, document) {
71 | 'use strict';
72 |
73 | $(function() {
74 | var ready = function(){
75 | configureLikeDislike(document);
76 | };
77 |
78 | $(document).ready(ready);
79 | });
80 |
81 | }(window.jQuery, window, document));
82 |
--------------------------------------------------------------------------------
/app/assets/javascripts/registrations.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | $('#new_user input').focusout(function() {
3 | validateField($(this).parent());
4 | });
5 |
6 | $('#user_email').focusout(function() {
7 | if(isValidValue($(this))){
8 | executeValidation($(this).parent());
9 | }
10 | });
11 |
12 | $('#new_user :submit').click(function(event) {
13 | var $inputs = $('#new_user :input');
14 | var fails = 0;
15 | $inputs.each(function() {
16 | if(!validateField($(this).parent())){
17 | fails++;
18 | }
19 | });
20 | if(!!fails){
21 | event.preventDefault();
22 | }else{
23 | $('#new_user').submit();
24 | }
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/app/assets/javascripts/report_validator.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 |
3 | var emailField = $('#report_email');
4 | var descriptionField = $('#description');
5 | var authorizeBox = $('#authorize-report');
6 |
7 | emailField.focusout(function() {
8 | validateField($(this).parent());
9 | });
10 |
11 | authorizeBox.focusout(function() {
12 | validateReportAuthorization($(this).parent());
13 | });
14 |
15 | descriptionField.focusout(function() {
16 | validateTextArea($(this).parent());
17 | });
18 |
19 | emailField.focusout(function() {
20 | validateEmailFormat(this);
21 | });
22 |
23 | submitReport();
24 | });
25 |
26 | var validateEmailFormat = function (email) {
27 | if(isValidValue($(email))){
28 | return executeValidation($(email).parent());
29 | }
30 | }
31 |
32 | var validateReportAuthorization = function(parent){
33 | var span = parent.find('span');
34 |
35 | if ($('#authorize-report:checked').length > 0) {
36 | setMessageAndClass(span, '', 'error');
37 | return true;
38 | } else {
39 | setMessageAndClass(span, 'Por favor, autorize o envio da denúncia', 'error_required');
40 | return false;
41 | }
42 | }
43 |
44 | var submitReport = function(){
45 | $('#report_service_form :submit').click(function(event) {
46 | var $inputs = $('#report_service_form .form-control');
47 | var fails = 0;
48 |
49 | $inputs.each(function() {
50 | if($(this).is("textarea")){
51 | if(!validateTextArea($(this).parent())){
52 | fails++;
53 | }
54 | } else{
55 | if(!validateField($(this).parent())){
56 | fails++;
57 | }
58 | }
59 | });
60 |
61 | if(!validateEmailFormat($('#report_email')) || !validateReportAuthorization($('#authorize-report').parent())){
62 | fails++;
63 | }
64 |
65 | if(!!fails){
66 | event.preventDefault();
67 | }else{
68 | $('#report_service_form').submit();
69 | }
70 | });
71 | }
--------------------------------------------------------------------------------
/app/assets/javascripts/required_validator.js:
--------------------------------------------------------------------------------
1 | var validateField = function(parent){
2 | var span = parent.find('span');
3 | var input = parent.find('input');
4 | var result = isValidValue(input);
5 |
6 | if(result){
7 | setMessageAndClass(span, '', 'error');
8 | }else{
9 | setMessageAndClass(span, 'O campo é requerido', 'error_required');
10 | }
11 | return result;
12 | };
13 |
14 | var validateTextArea = function (parent) {
15 | var textarea = parent.find('textarea');
16 | var span = parent.find('span');
17 | var result = isValidValue(textarea);
18 |
19 | if(result){
20 | setMessageAndClass(span, '', 'error');
21 | }else{
22 | setMessageAndClass(span, 'O campo é requerido', 'error_required');
23 | }
24 |
25 | return result;
26 | }
27 |
28 | var isValidValue = function(element) {
29 | return !!element.val();
30 | };
31 |
--------------------------------------------------------------------------------
/app/assets/javascripts/service_form.js:
--------------------------------------------------------------------------------
1 | (function($, window, document) {
2 | 'use strict';
3 |
4 | $(function() {
5 |
6 | var updateOwnerData = function() {
7 | if ($('#owner-check input:checked').val() == 'recomendacao') {
8 | $('#dados-recomendacao').show();
9 | $('#service_owner_name').prop('required',true);
10 | }
11 | else {
12 | $('#dados-recomendacao').hide();
13 | $('#service_owner_name').prop('required',false);
14 | }
15 | }
16 |
17 | var ready = function(){
18 | if( $('#owner-check').data('is-owner') == true ) {
19 | $('#prestador2').prop('checked', true);
20 | } else {
21 | $('#prestador1').prop('checked', true);
22 | }
23 |
24 | $('[name="prestador"]').on('change', updateOwnerData);
25 |
26 | updateOwnerData();
27 | };
28 |
29 | $(document).ready(ready);
30 | });
31 |
32 | }(window.jQuery, window, document));
33 |
34 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/_core.scss:
--------------------------------------------------------------------------------
1 | /*Fonts*/
2 | $font1: 'Passion One';
3 | $font2: 'Bitter';
4 | $font3: 'Nunito';
5 |
6 | /*Colors*/
7 | $fuchsia: #b1054f;
8 | $purple: #23263c;
9 | $light-blue: #D2EBF8;
10 | $dark-blue: #446a90;
11 |
12 | /*Color classes*/
13 | .bg-fuchsia,
14 | .bg-purple,
15 | .bg-dark-blue {
16 | color: rgba(255,255,255,0.9);
17 | }
18 |
19 | .bg-fuchsia {background-color: $fuchsia;}
20 | .bg-purple {background-color: $purple}
21 | .bg-light-blue {background-color: $light-blue}
22 | .bg-dark-blue {background-color: $dark-blue}
23 |
24 | .text-fuchsia {color: $fuchsia !important;}
25 | .text-purple {color: $purple;}
26 | .text-light-blue {color: $light-blue;}
27 | .text-dark-blue {color: $dark-blue;}
28 | .text-white {color: white;}
29 |
30 |
31 | /*Typography*/
32 | .font0-8x {
33 | font-size: 0.8em;
34 | }
35 | .font1-2x {
36 | font-size: 1.2em;
37 | }
38 | .font1-5x {
39 | font-size: 1.5em;
40 | }
41 |
42 |
43 | /*Footer heights*/
44 | $footer-height-xs: 259px;
45 | $footer-height-sm: 193px;
46 | $footer-height-md: $footer-height-sm;
47 | $footer-height-xl: $footer-height-sm;
48 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/auth.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the Registrations controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
5 | .auth {
6 | h1 {
7 | font-size: 48px;
8 | color: #FFF;
9 | margin: 60px 0;
10 | text-align: center;
11 | }
12 |
13 | .container {
14 | width: 100%;
15 | padding: 0 20px;
16 | max-width: 500px;
17 | margin: 0 auto;
18 | }
19 |
20 | .field-group {
21 | box-shadow: 1px 2px 8px rgba(0,0,0,0.5);
22 | margin-bottom: 30px;;
23 | }
24 |
25 | .field {
26 | input[type=text], input[type=email], input[type=password], input[type=tel], input[type=date] {
27 | width: 100%;
28 | border: 1px solid #CCC;
29 | border-top: none;
30 | line-height: 45px;
31 | font-size: 16px;
32 | font-family: inherit;
33 | padding: 0 10px 0 50px;
34 | background-repeat: no-repeat;
35 | background-position: 15px 12px;
36 | }
37 | input[type=checkbox] {
38 |
39 | }
40 | &:first-child {
41 | input[type=text], input[type=email], input[type=password] {
42 | border-top: 1px solid #CCC;
43 | border-radius: 3px 3px 0 0;
44 | }
45 | }
46 | &:last-child {
47 | input[type=text], input[type=email], input[type=password] {
48 | border-radius: 0 0 3px 3px;
49 | }
50 | }
51 | }
52 |
53 | .input-user {
54 | background-image: image-url("ico-user.png");
55 | }
56 |
57 | .input-password {
58 | background-image: image-url("ico-password.png");
59 | }
60 |
61 | .btn {
62 | line-height: 45px;
63 | background: #FFF;
64 | border: none;
65 | width: 100%;
66 | border-radius: 3px;
67 | box-shadow: 1px 2px 8px rgba(0,0,0,0.5);
68 | color: #5E96CD;
69 | font-family: Passion One;
70 | font-weight: 700;
71 | text-transform: uppercase;
72 | font-size: 24px;
73 | padding: 0;
74 | cursor: pointer;
75 | text-decoration: none;
76 | display: inline-block;
77 | text-align: center;
78 |
79 | &:hover, &:focus {
80 | box-shadow: 0px 1px 8px rgba(0,0,0,0.5);
81 | line-height: 44px;
82 | padding: 1px 0 0 0;
83 | background: #F5F5F5;
84 | }
85 | }
86 |
87 | .not-user-text {
88 | color: #FFF;
89 | font-size: 20px;
90 | text-align: center;
91 | margin-top: 50px;
92 | }
93 |
94 | .lnk-forgot-password {
95 | color: #FFF;
96 | text-align: center;
97 | display: block;
98 | text-align: center;
99 | font-weight: normal;
100 | font-size: 16px;
101 | margin: 20px;
102 | font-style: italic;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/welcome.scss:
--------------------------------------------------------------------------------
1 | // Place all the styles related to the welcome controller here.
2 | // They will automatically be included in application.css.
3 | // You can use Sass (SCSS) here: http://sass-lang.com/
4 |
5 | @import "core"; /*Global settings*/
6 | @import "variables"; /*Bootstrap variables*/
7 |
8 | header#main-header {
9 | color: white;
10 | padding: 3vh 0 8vh 0;
11 | margin: 0;
12 | h1 {
13 | font-family: $font1;
14 | font-weight: 700;
15 | font-size: 7em;
16 | text-shadow: 0 2px 5px rgba(0,0,0,0.2);
17 | text-transform: uppercase;
18 | margin: 8vh 0;
19 | @media (max-width: $screen-xs-max) {
20 | font-size: 3.5em;
21 | margin: 1vh 0;
22 | }
23 | }
24 | .lead {
25 | font-family: $font2;
26 | font-size: 1.8em;
27 | @media (max-width: $screen-xs-max) {
28 | font-size: 1.4em;
29 | }
30 | p {
31 | margin-bottom: 30px;
32 | }
33 | }
34 | .cadastre-busque {
35 | .btn-contorno {
36 | margin: 0 12px;
37 | }
38 | @media (max-width: $screen-sm-max) {
39 | line-height: 2em;
40 | }
41 | }
42 | }
43 |
44 | section#error-page {
45 | padding: 30px 0;
46 | }
47 |
48 | section#feedback-tw {
49 | padding: 30px 0;
50 | background-image: image-url("test-ribbon.png");
51 | background-repeat: no-repeat;
52 | background-position: top left;
53 | background-size: 100px 100px;
54 | @media (max-width: $screen-xs-max) {
55 | background-size: 80px 80px;
56 | }
57 | h2 {
58 | margin: 0 0 1em 0;
59 | }
60 | p {
61 | margin-bottom: 1em;
62 | }
63 | a {
64 | color: mix(white, $fuchsia, 40%);
65 | }
66 | }
67 |
68 | section#trans-hoje {
69 | padding: 10vh 0;
70 | background: #FFF;
71 | .row {
72 | &>div {
73 | h2 {
74 | @media (max-width: $screen-xs-max) {
75 | margin-top: 10vh;
76 | }
77 | }
78 | &:first-of-type {
79 | h2 {
80 | margin-top: 0;
81 | }
82 | }
83 | }
84 | }
85 | h2 {
86 | font-size: 24px;
87 | font-family: $font1;
88 | color: $dark-blue;
89 | text-transform: uppercase;
90 | margin: 0 0 15px 0;
91 | padding: 0 50px;
92 | &:before {
93 | display: block;
94 | margin: 0 auto;
95 | margin-bottom: 15px;
96 | content: "";
97 | width: 60px;
98 | height: 60px;
99 | background-size: 100%;
100 | }
101 | &.brazil:before {
102 | background: image-url("brazil_flag.svg") no-repeat 0 0;
103 | }
104 | &.rights:before {
105 | background: image-url("scale.svg") no-repeat 0 0;
106 | }
107 | &.change:before {
108 | background: image-url("people_in_love.svg") no-repeat 0 0;
109 | }
110 | }
111 | a {
112 | font-family: $font1;
113 | font-weight: 500;
114 | font-size: 1.5em;
115 | }
116 | }
117 |
118 | section#desconstruindo-mitos {
119 | background: $light-blue;
120 | padding: 10vh 0;
121 | -webkit-transition:all .35s;
122 | -moz-transition:all .35s;
123 | transition:all .35s;
124 | border-top: 2px $fuchsia solid;
125 | border-bottom: 2px $dark-blue solid;
126 | h1 {
127 | font-family: $font1;
128 | text-transform: uppercase;
129 | font-size: 3.5em;
130 | margin-bottom: 1em;
131 | color: $dark-blue;
132 | @media (max-width: $screen-xs-max) {
133 | font-size: 2em;
134 | }
135 | }
136 | .mitos-controle {
137 | text-align: center;
138 | line-height: 2.5em;
139 | color: transparentize($dark-blue, 0.65);
140 | cursor: pointer;
141 | i {
142 | margin: 0 5px;
143 | &.active {
144 | color: $dark-blue;
145 | }
146 | }
147 | }
148 | .mito {
149 | h2 {
150 | font-family: $font2;
151 | color: $dark-blue;
152 | margin-bottom: 1em;
153 | }
154 | p {
155 | color: darken($dark-blue, 30%);
156 | margin-bottom: 1em;
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/app/channels/application_cable/channel.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module ApplicationCable
4 | class Channel < ActionCable::Channel::Base
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/app/channels/application_cable/connection.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module ApplicationCable
4 | class Connection < ActionCable::Connection::Base
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationController < ActionController::Base
4 | include CanCan::ControllerAdditions
5 |
6 | NOT_ALLOWED_MESSAGE = 'Você não está autorizado a acessar esta página'
7 | # Prevent CSRF attacks by raising an exception.
8 | # For APIs, you may want to use :null_session instead.
9 | protect_from_forgery with: :exception
10 |
11 | def after_sign_in_path_for(_resource)
12 | dashboard_path
13 | end
14 |
15 | def load_subareas
16 | area = Area.find(params[:area_id])
17 | respond_to do |format|
18 | format.json { render json: area.subareas }
19 | end
20 | end
21 |
22 | rescue_from CanCan::AccessDenied do
23 | respond_to do |format|
24 | format.json { render nothing: true, status: :forbidden }
25 | format.html { redirect_to main_app.new_user_session_path, alert: NOT_ALLOWED_MESSAGE }
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/controllers/concerns/.keep
--------------------------------------------------------------------------------
/app/controllers/dashboard_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DashboardController < ApplicationController
4 | before_action :authenticate_user!, only: [:index]
5 |
6 | def index
7 | @services = current_user.services
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/app/controllers/errors_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ErrorsController < ApplicationController
4 | def not_found
5 | render status: :not_found
6 | end
7 |
8 | def unnacceptable
9 | render status: :unnprocessable_entity
10 | end
11 |
12 | def internal_error
13 | render status: :internal_server_error
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/app/controllers/lists_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ListsController < ApplicationController
4 | include PaginationHelper
5 | before_action :authenticate_user!
6 |
7 | RECORDS_PER_PAGE = 10
8 |
9 | def services_with_reports
10 | @services = Service.list_services_with_reports
11 | @services = paginate_services(@services, RECORDS_PER_PAGE, params[:page])
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/app/controllers/registrations_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RegistrationsController < Devise::RegistrationsController
4 | def sign_up_params
5 | params.require(:user).permit(common_params + [:terms_of_service])
6 | end
7 |
8 | def account_update_params
9 | params.require(:user).permit(common_params + [:current_password])
10 | end
11 |
12 | def common_params
13 | %i[social_name civil_name birth_date username email
14 | phone_number password password_confirmation name_preference]
15 | end
16 |
17 | def after_update_path_for(_resource)
18 | dashboard_path
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/app/controllers/reports_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ReportsController < ApplicationController
4 | before_action :authenticate_user!, only: [:find_reports_by_service]
5 |
6 | def create
7 | @report = Report.new(params[:report].permit(:detail, :email, :service_id))
8 | send_mail_report(@report) if @report.save
9 | redirect_to controller: 'services', action: 'index'
10 | end
11 |
12 | def send_mail_report(report)
13 | TransMailer.send_mail_report(report).deliver_now
14 | end
15 |
16 | def find_reports_by_service
17 | @reports = Report.get_by_service(params[:service_id])
18 | @service = Service.find(params[:service_id])
19 | render :index
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/app/controllers/services_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ServicesController < ApplicationController
4 | include PaginationHelper
5 | before_action :set_service, only: %i[show edit update destroy]
6 | before_action :authenticate_user!, only: %i[new create]
7 | load_and_authorize_resource
8 |
9 | RECORDS_PER_PAGE = 10
10 | # GET /services
11 | # GET /services.json
12 | def index
13 | prepare_search
14 | @services = paginate_services(@services, RECORDS_PER_PAGE, params[:page])
15 | render partial: '/partials/service_list' if request.xhr?
16 | end
17 |
18 | # GET /services/1
19 | # GET /services/1.json
20 | def show; end
21 |
22 | # GET /services/new
23 | def new
24 | @service = Service.new
25 | @address = @service.build_address
26 | @subarea = @service.build_subarea
27 | end
28 |
29 | # GET /services/1/edit
30 | def edit; end
31 |
32 | # POST /services
33 | # POST /services.json
34 | # rubocop:disable Metrics/AbcSize
35 | def create
36 | @service = current_user.services.build(service_params)
37 | respond_to do |format|
38 | if @service.save
39 | format.html { redirect_to dashboard_path, notice: 'Service was successfully created.' }
40 | format.json { render :show, status: :created, location: @service }
41 | else
42 | format.html { render :new }
43 | format.json { render json: @service.errors, status: :unprocessable_entity }
44 | end
45 | end
46 | end
47 | # rubocop:enable Metrics/AbcSize
48 |
49 | # PATCH/PUT /services/1
50 | # PATCH/PUT /services/1.json
51 | def update
52 | respond_to do |format|
53 | if @service.update(service_params)
54 | format.html { redirect_to @service, notice: 'Service was successfully updated.' }
55 | format.json { render :show, status: :ok, location: @service }
56 | else
57 | format.html { render :edit }
58 | format.json { render json: @service.errors, status: :unprocessable_entity }
59 | end
60 | end
61 | end
62 |
63 | # DELETE /services/1
64 | # DELETE /services/1.json
65 | def destroy
66 | @service.destroy
67 | respond_to do |format|
68 | format.html { redirect_to services_url, notice: 'Service was successfully destroyed.' }
69 | format.json { head :no_content }
70 | end
71 | end
72 |
73 | def upvote
74 | @service = Service.find(params[:id])
75 | @voter = current_user || VotingSession.find_or_create_voting_session(request.remote_ip)
76 |
77 | if @voter.voted_up_on? @service
78 | @service.unliked_by @voter
79 | else
80 | @service.undisliked_by(@voter) if @voter.voted_down_on?(@service)
81 | @service.liked_by @voter
82 | end
83 |
84 | render json: build_json_votes(@service, 'upvoted')
85 | end
86 |
87 | def downvote
88 | @service = Service.find(params[:id])
89 | @voter = current_user || VotingSession.find_or_create_voting_session(request.remote_ip)
90 |
91 | if @voter.voted_down_on? @service
92 | @service.undisliked_by @voter
93 | else
94 | @service.unliked_by @voter if @voter.voted_up_on? @service
95 | @service.downvote_by @voter
96 | end
97 |
98 | render json: build_json_votes(@service, 'downvoted')
99 | end
100 |
101 | private
102 |
103 | # Use callbacks to share common setup or constraints between actions.
104 | def set_service
105 | @service = Service.friendly.find(params[:id])
106 | end
107 |
108 | # Never trust parameters from the scary internet, only allow the white list through.
109 | def service_params
110 | address_attributes = %i[id street number complement neighborhood city_id state_id]
111 | params.require(:service).permit(:name, :description, :phone, :other_phone,
112 | :subarea_id, :owner_name, :owner_email,
113 | :website, address_attributes: address_attributes)
114 | end
115 |
116 | # rubocop:disable Metrics/AbcSize
117 | def prepare_search
118 | @services = Service.where(nil) # creates an anonymous scope
119 | @services = @services.text_search(params[:search]) if params[:search].present?
120 | if params[:state] && params[:state][:state_id].present?
121 | @services = @services.state_search(params[:state][:state_id])
122 | end
123 | @services = @services.city_search(params[:city][:city_id]) if params[:city] && params[:city][:city_id].present?
124 | end
125 |
126 | def build_json_votes(service, action)
127 | {
128 | service_id: service.id,
129 | upvotes: service.get_upvotes.size,
130 | downvotes: service.get_downvotes.size,
131 | action: action
132 | }
133 | end
134 | # rubocop:enable Metrics/AbcSize
135 | end
136 |
--------------------------------------------------------------------------------
/app/controllers/states_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class StatesController < ApplicationController
4 | respond_to :json
5 | def show
6 | state = State.find(params[:id])
7 | respond_with(state.as_json(include: :cities))
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/app/controllers/welcome_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class WelcomeController < ApplicationController
4 | end
5 |
--------------------------------------------------------------------------------
/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module ApplicationHelper
4 | end
5 |
--------------------------------------------------------------------------------
/app/helpers/pagination_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module PaginationHelper
4 | def paginate_services(services, records_per_page, page = 1)
5 | services.paginate(page: page, per_page: records_per_page)
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/app/helpers/registrations_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module RegistrationsHelper
4 | end
5 |
--------------------------------------------------------------------------------
/app/helpers/services_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module ServicesHelper
4 | def save_service_text(service)
5 | service.persisted? ? 'Salvar alterações' : 'Cadastrar serviço'
6 | end
7 |
8 | def states_selector
9 | State.all.order(:name)
10 | end
11 |
12 | def should_display_owner_data(service)
13 | service.try(:owner_name).present?
14 | end
15 |
16 | def get_selected_subarea_id(service)
17 | service.subarea&.area ? service.subarea.area.id : nil
18 | end
19 |
20 | def get_selected_subareas(service)
21 | service.subarea&.area ? service.subarea.area.subareas : []
22 | end
23 |
24 | def read_selected_state_from_url
25 | params[:state][:state_id] if params[:state] && params[:state][:state_id].present?
26 | end
27 |
28 | def read_selected_city_from_url
29 | params[:city][:city_id] if params[:city] && params[:city][:city_id].present?
30 | end
31 |
32 | def user_voted_for?(service)
33 | voter = current_user || VotingSession.find_by(ip: request.remote_ip)
34 | voter&.voted_for?(service)
35 | end
36 |
37 | def user_voted_up_service?(service)
38 | voter = current_user || VotingSession.find_by(ip: request.remote_ip)
39 | voter&.voted_for?(service) && voter&.voted_up_on?(service)
40 | end
41 |
42 | def user_voted_down_service?(service)
43 | voter = current_user || VotingSession.find_by(ip: request.remote_ip)
44 | voter&.voted_for?(service) && voter&.voted_down_on?(service)
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/app/javascript/app.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ job.title }}
6 |
7 |
8 |
9 |
10 |
11 |
27 |
28 |
34 |
--------------------------------------------------------------------------------
/app/javascript/packs/application.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console:0 */
2 | // This file is automatically compiled by Webpack, along with any other files
3 | // present in this directory. You're encouraged to place your actual application logic in
4 | // a relevant structure within app/javascript and only use these pack files to reference
5 | // that code so it'll be compiled.
6 | //
7 | // To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
8 | // layout file, like app/views/layouts/application.html.erb
9 |
10 | // console.log('Hello World from Webpacker')
11 |
12 |
13 | /* eslint no-console: 0 */
14 | // Run this example by adding <%= javascript_pack_tag 'hello_vue' %> (and
15 | // <%= stylesheet_pack_tag 'hello_vue' %> if you have styles in your component)
16 | // to the head of your layout file,
17 | // like app/views/layouts/application.html.erb.
18 | // All it does is render Hello Vue
at the bottom of the page.
19 |
20 | import Vue from 'vue'
21 | import App from '../app.vue'
22 |
23 | document.addEventListener('turbolinks:load', () => {
24 | const el = document.body.appendChild(document.createElement('index'))
25 | const app = new Vue({
26 | el,
27 | render: h => h(App)
28 | })
29 |
30 | console.log(app)
31 | })
32 |
33 |
34 | // The above code uses Vue without the compiler, which means you cannot
35 | // use Vue to target elements in your existing html templates. You would
36 | // need to always use single file components.
37 | // To be able to target elements in your existing html/erb templates,
38 | // comment out the above code and uncomment the below
39 | // Add <%= javascript_pack_tag 'hello_vue' %> to your layout
40 | // Then add this markup to your html template:
41 | //
42 | //
43 | // {{message}}
44 | //
45 | //
46 |
47 |
48 | // import Vue from 'vue/dist/vue.esm'
49 | // import App from '../app.vue'
50 | //
51 | // document.addEventListener('turbolinks:load', () => {
52 | // const app = new Vue({
53 | // el: '#hello',
54 | // data: {
55 | // message: "Can you say hello?"
56 | // },
57 | // components: { App }
58 | // })
59 | // })
60 | //
61 | //
62 | //
63 | // If the using turbolinks, install 'vue-turbolinks':
64 | //
65 | // yarn add 'vue-turbolinks'
66 | //
67 | // Then uncomment the code block below:
68 | //
69 | // import TurbolinksAdapter from 'vue-turbolinks'
70 | // import Vue from 'vue/dist/vue.esm'
71 | // import App from '../app.vue'
72 | //
73 | // Vue.use(TurbolinksAdapter)
74 | //
75 | // document.addEventListener('turbolinks:load', () => {
76 | // const app = new Vue({
77 | // el: '#hello',
78 | // data: {
79 | // message: "Can you say hello?"
80 | // },
81 | // components: { App }
82 | // })
83 | // })
84 |
--------------------------------------------------------------------------------
/app/jobs/application_job.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationJob < ActiveJob::Base
4 | end
5 |
--------------------------------------------------------------------------------
/app/mailers/application_mailer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationMailer < ActionMailer::Base
4 | default from: 'from@example.com'
5 | layout 'mailer'
6 | end
7 |
--------------------------------------------------------------------------------
/app/models/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/models/.keep
--------------------------------------------------------------------------------
/app/models/ability.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Ability
4 | include CanCan::Ability
5 |
6 | def initialize(user)
7 | if user.nil?
8 | can :read, Service
9 | else
10 | can %i[read create], Service
11 | can %i[update destroy], Service, user_id: user.id
12 | can :manage, :all if user.admin?
13 | end
14 | can %i[upvote downvote], Service
15 | # Define abilities for the passed in user here. For example:
16 | #
17 | # user ||= User.new # guest user (not logged in)
18 | # if user.admin?
19 | # can :manage, :all
20 | # else
21 | # can :read, :all
22 | # end
23 | #
24 | # The first argument to `can` is the action you are giving the user
25 | # permission to do.
26 | # If you pass :manage it will apply to every action. Other common actions
27 | # here are :read, :create, :update and :destroy.
28 | #
29 | # The second argument is the resource the user can perform the action on.
30 | # If you pass :all it will apply to every resource. Otherwise pass a Ruby
31 | # class of the resource.
32 | #
33 | # The third argument is an optional hash of conditions to further filter the
34 | # objects.
35 | # For example, here the user can only update published articles.
36 | #
37 | # can :update, Article, :published => true
38 | #
39 | # See the wiki for details:
40 | # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/app/models/address.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Address < ApplicationRecord
4 | belongs_to :service
5 | belongs_to :state
6 | belongs_to :city
7 |
8 | validates_with CityValidator
9 | validates_with StateValidator
10 |
11 | accepts_nested_attributes_for :city
12 | accepts_nested_attributes_for :state
13 | end
14 |
--------------------------------------------------------------------------------
/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ApplicationRecord < ActiveRecord::Base
4 | self.abstract_class = true
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/area.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Area < ApplicationRecord
4 | has_many :subareas, dependent: :destroy
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/city.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class City < ApplicationRecord
4 | belongs_to :state
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/app/models/concerns/.keep
--------------------------------------------------------------------------------
/app/models/forbidden_word.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ForbiddenWord < ApplicationRecord
4 | end
5 |
--------------------------------------------------------------------------------
/app/models/report.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Report < ApplicationRecord
4 | belongs_to :service
5 | validates :detail, presence: true
6 | validates :service, presence: true
7 | validates :email, presence: true
8 |
9 | def self.get_by_service(service_id)
10 | Report.where(service_id: service_id)
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/app/models/service.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Service < ApplicationRecord
4 | extend FriendlyId
5 | friendly_id :name, use: :slugged
6 |
7 | acts_as_votable
8 |
9 | validates :subarea, presence: true
10 | validates :address, presence: true
11 | validates :name, presence: true
12 | validates :description, presence: true
13 | validates :website, format: {
14 | with: %r{\A(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w\.-]*)*\/?\Z}i,
15 | message: 'Site deve estar no formato: www.meusite.com.br'
16 | }, if: proc { |a| a.website.present? }
17 | validate :description_cannot_contain_forbidden_word
18 | validate :name_cannot_contain_forbidden_word
19 |
20 | has_one :address, dependent: :destroy
21 | belongs_to :subarea
22 | belongs_to :user
23 |
24 | accepts_nested_attributes_for :address
25 |
26 | default_scope { order('name ASC') }
27 |
28 | before_save { |service| service.website = url_with_protocol(service.website) if service.website.present? }
29 | # rubocop:disable Metrics/LineLength
30 | scope :text_search, lambda { |text|
31 | where('unaccent(lower(services.name)) LIKE unaccent(:text) OR unaccent(lower(services.description)) LIKE unaccent(:text)', text: "%#{text.downcase}%")
32 | }
33 | # rubocop:enable Metrics/LineLength
34 | scope :state_search, ->(state_id) { joins(address: :state).where(states: { id: state_id }) }
35 | scope :city_search, ->(city_id) { joins(address: :city).where(cities: { id: city_id }) }
36 | scope :list_services_with_reports, -> { joins('join reports on reports.service_id = services.id').distinct }
37 |
38 | def owner
39 | user.preferred_name
40 | end
41 |
42 | def reports_count
43 | Service.joins("join reports on reports.service_id = services.id and services.id = #{id}").count
44 | end
45 |
46 | private
47 |
48 | FORBIDDEN_WORD_ERROR_MESSAGE = 'do serviço contém palavras não permitidas. As palavras são: '
49 |
50 | def description_cannot_contain_forbidden_word
51 | forbidden_words_in_description = forbidden_words_in description
52 | validate_forbidden_words :description, forbidden_words_in_description
53 | end
54 |
55 | def name_cannot_contain_forbidden_word
56 | forbidden_words_in_name = forbidden_words_in name
57 | validate_forbidden_words :name, forbidden_words_in_name
58 | end
59 |
60 | def forbidden_words_in(content)
61 | word_list = ForbiddenWord.all.map(&:word)
62 | word_list.keep_if do |word|
63 | content =~ /\b#{Regexp.escape(word)}\b/i
64 | end
65 | end
66 |
67 | def validate_forbidden_words(field, forbidden_words)
68 | message = FORBIDDEN_WORD_ERROR_MESSAGE + forbidden_words.join(', ') + '.'
69 | errors.add(field, message) unless forbidden_words.empty?
70 | end
71 |
72 | def url_with_protocol(url)
73 | /^https?/i.match?(url) ? url : "http://#{url}"
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/app/models/state.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class State < ApplicationRecord
4 | has_many :cities, dependent: :destroy
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/subarea.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Subarea < ApplicationRecord
4 | belongs_to :area
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/user.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class User < ApplicationRecord
4 | # Include default devise modules. Others available are:
5 | # :confirmable, :lockable, :timeoutable and :omniauthable
6 | devise :database_authenticatable, :registerable,
7 | :recoverable, :rememberable, :trackable, :validatable
8 |
9 | acts_as_voter
10 |
11 | before_save :set_name_preference
12 |
13 | validates :social_name, presence: true
14 | validates :birth_date, presence: true
15 | validates :terms_of_service, acceptance: true
16 | validates :username, uniqueness: true, allow_blank: true
17 | validate :age
18 | has_many :services, dependent: :destroy
19 |
20 | SOCIAL_NAME_PREFERENCE = 'S'
21 | CIVIL_NAME_PREFERENCE = 'C'
22 |
23 | attr_accessor :birth_date_picker
24 |
25 | def age
26 | today = Date.current
27 | return if birth_date && (birth_date + 18.years) < today
28 |
29 | errors.add(:_, 'É preciso ser maior de idade.')
30 | end
31 |
32 | def preferred_name
33 | if name_preference == CIVIL_NAME_PREFERENCE
34 | civil_name.empty? ? social_name : civil_name
35 | elsif name_preference == SOCIAL_NAME_PREFERENCE
36 | social_name.empty? ? civil_name : social_name
37 | end
38 | end
39 |
40 | def set_name_preference
41 | self.name_preference = social_name.blank? ? CIVIL_NAME_PREFERENCE : SOCIAL_NAME_PREFERENCE
42 | end
43 |
44 | rails_admin do
45 | configure :birth_date do
46 | strftime_format '%d-%m-%Y'
47 | end
48 | end
49 | end
50 |
--------------------------------------------------------------------------------
/app/models/voting_session.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class VotingSession < ApplicationRecord
4 | acts_as_voter
5 |
6 | def self.find_or_create_voting_session(ip)
7 | find_by(ip: ip) || create(ip: ip)
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/app/validators/city_validator.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CityValidator < ActiveModel::Validator
4 | REQUIRED_MESSAGE = 'deve ser selecionada'
5 | FAIL_MESSAGE = 'não existe'
6 |
7 | def validate(model)
8 | if model.city_id.blank?
9 | model.errors[:city_id] << REQUIRED_MESSAGE
10 | else
11 | model.errors[:city_id] << FAIL_MESSAGE unless City.exists?(model.city_id)
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/app/validators/state_validator.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class StateValidator < ActiveModel::Validator
4 | REQUIRED_MESSAGE = 'deve ser selecionado'
5 | FAIL_MESSAGE = 'não existe'
6 |
7 | def validate(model)
8 | if model.state_id.blank?
9 | model.errors[:state_id] << REQUIRED_MESSAGE
10 | else
11 | model.errors[:state_id] << FAIL_MESSAGE unless State.exists?(model.state_id)
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/app/views/dashboard/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Olá,
9 | <%= current_user.social_name %>
10 |
11 |
12 |
41 |
42 |
43 |
44 | <% if @services.empty? %>
45 |
46 |
Você ainda não cadastrou nenhum serviço.
47 | <%= link_to 'Cadastre o primeiro!', new_service_path, class:"btn btn-contorno" %>
48 |
49 | <% else %>
50 |
51 |
Meus serviços
52 | <% @services.each do |service| %>
53 | <%= render '/partials/service', service: service %>
54 | <% end %>
55 |
56 | <% end %>
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/app/views/devise/confirmations/new.html.erb:
--------------------------------------------------------------------------------
1 | Resend confirmation instructions
2 |
3 | <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
4 | <%= devise_error_messages! %>
5 |
6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
9 |
10 |
11 |
12 | <%= f.submit "Resend confirmation instructions" %>
13 |
14 | <% end %>
15 |
16 | <%= render "devise/shared/links" %>
17 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/confirmation_instructions.html.erb:
--------------------------------------------------------------------------------
1 | Welcome <%= @email %>!
2 |
3 | You can confirm your account email through the link below:
4 |
5 | <%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>
6 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/password_change.html.erb:
--------------------------------------------------------------------------------
1 | Hello <%= @resource.email %>!
2 |
3 | We're contacting you to notify you that your password has been changed.
4 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/preview/devise_mailer_preview.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Devise
4 | class MailerPreview < ActionMailer::Preview
5 | def reset_password_instructions
6 | Devise::Mailer.reset_password_instructions(User.first, 'faketoken')
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/reset_password_instructions.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
64 |
65 |
66 |
67 |
68 |
71 |
74 |
75 |
76 |
77 | Olá <%= @resource.social_name %> !
78 |
79 | Abaixo está o link que você solicitou para fazer a mudança de sua senha de acesso ao Transerviços.
80 |
81 |
82 |
83 | <%= link_to 'Mudar minha senha', edit_password_url(@resource, reset_password_token: @token) %>
84 |
85 |
86 |
87 |
88 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/unlock_instructions.html.erb:
--------------------------------------------------------------------------------
1 | Hello <%= @resource.email %>!
2 |
3 | Your account has been locked due to an excessive number of unsuccessful sign in attempts.
4 |
5 | Click the link below to unlock your account:
6 |
7 | <%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>
8 |
--------------------------------------------------------------------------------
/app/views/devise/passwords/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Esqueceu sua senha?
6 |
7 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
8 | <%= devise_error_messages! %>
9 | <%= f.hidden_field :reset_password_token %>
10 |
11 |
12 |
25 |
26 |
27 |
28 | <%= f.submit "Mudar minha senha", class:"btn btn-form btn-block" %>
29 |
30 | <% end %>
31 |
32 |
33 | <%= render "devise/shared/links" %>
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/views/devise/passwords/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Esqueceu sua senha?
6 |
7 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
8 | <%= devise_error_messages! %>
9 |
10 |
Insira seu endereço de email abaixo para receber as intruções de como redefinir sua senha.
11 |
12 |
13 | <%= f.label :email, "Endereço de email", :class=>"label-required" %>
14 | <%= f.email_field :email, autofocus: true, class:"form-control" %>
15 |
16 |
17 |
18 |
19 | <%= f.submit "Enviar instruções", class:"btn btn-form btn-block" %>
20 |
21 | <% end %>
22 |
23 |
24 | <%= render "devise/shared/links" %>
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/views/devise/registrations/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Editar meus dados
6 |
7 | <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
8 | <%= devise_error_messages! %>
9 |
10 |
11 |
12 | <%= f.label :social_name, "Nome" %>
13 | <%= f.text_field :social_name, placeholder:'Você pode usar seu nome social', autofocus: true, class: 'form-control' %>
14 |
15 |
16 | <%= f.label :birth_date, "Data de nascimento", :class=>"label-required" %>
17 | <%= f.text_field :birth_date, class: 'form-control', value: f.object.birth_date.strftime("%d/%m/%Y") %>
18 |
19 |
20 | <%= f.label :password, "Nova senha", :class=>"label-required" %>
21 | <%= f.password_field :password, placeholder: '(deixe em branco para não alterá-la)', autocomplete: "off", class: 'form-control' %>
22 |
23 |
24 | <%= f.label :password_confirmation, "Nova senha (confirmação)", :class=>"label-required" %>
25 | <%= f.password_field :password_confirmation, placeholder: '(repita a nova senha para alterá-la)', autocomplete: "off", class: 'form-control' %>
26 |
27 |
28 | <%= f.label :email, "Endereço de e-mail", :class=>"label-required" %>
29 | <%= f.email_field :email, class: 'form-control' %>
30 |
31 |
32 |
33 |
Forneça sua senha atual para confirmar as alterações:
34 |
35 |
36 | <%= f.label :current_password, "Senha atual", :class=>"label-required" %>
37 | <%= f.password_field :current_password, autocomplete: "off", class:"form-control" %>
38 |
39 |
40 |
41 |
42 | <%= f.submit "Atualizar meus dados", class:"btn btn-form btn-block" %>
43 |
44 | <% end %>
45 |
46 |
Caso deseje excluir sua conta, clique no botão abaixo.
47 | <%= button_to "Excluir minha conta", registration_path(resource_name), data: { confirm: "Você tem certeza que quer excluir sua conta?" }, method: :delete, class:"btn btn-form btn-block" %>
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/views/devise/sessions/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Entrar no Transerviços
6 | <% if flash[:notice] %>
7 |
8 | <%= flash[:notice] %>
9 |
10 | <% end %>
11 | <% if flash[:alert] %>
12 |
13 | <%= flash[:alert] %>
14 |
15 | <% end %>
16 | <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
17 |
18 |
19 | <%= f.label :email, "Endereço de email", :class=>"label-required" %>
20 | <%= f.email_field :email, autofocus: true, class: 'form-control' %>
21 |
22 |
23 | <%= f.label :password, "Senha", :class=>"label-required" %>
24 | <%= f.password_field :password, class: 'form-control' %>
25 |
26 |
27 |
28 |
29 | <%= f.submit "Entrar", class: 'btn btn-block btn-form' %>
30 |
31 | <% end %>
32 |
33 |
Ainda não é usuário?
34 |
35 | <%= link_to "Cadastre-se", new_registration_path(resource_name), class: 'btn btn-block btn-form' %>
36 |
37 | <%= link_to "Esqueci a senha", new_password_path(resource_name), class: 'lnk-forgot-password' %>
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/views/devise/shared/_links.html.erb:
--------------------------------------------------------------------------------
1 | <%- if controller_name != 'sessions' %>
2 | <%= link_to "Entrar", new_session_path(resource_name) %>
3 | <% end -%>
4 |
5 | <%- if devise_mapping.registerable? && controller_name != 'registrations' %>
6 | <%= link_to "Cadastre-se", new_registration_path(resource_name) %>
7 | <% end -%>
8 |
9 | <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
10 | <%= link_to "Esqueceu sua senha?", new_password_path(resource_name) %>
11 | <% end -%>
12 |
13 | <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
14 | <%= link_to "Não recebeu as instruções de confirmação?", new_confirmation_path(resource_name) %>
15 | <% end -%>
16 |
17 | <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
18 | <%= link_to "Não recebeu as instruções de desbloqueio?", new_unlock_path(resource_name) %>
19 | <% end -%>
20 |
21 | <%- if devise_mapping.omniauthable? %>
22 | <%- resource_class.omniauth_providers.each do |provider| %>
23 | <%= link_to "Entrar com #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %>
24 | <% end -%>
25 | <% end -%>
26 |
--------------------------------------------------------------------------------
/app/views/devise/unlocks/new.html.erb:
--------------------------------------------------------------------------------
1 | Resend unlock instructions
2 |
3 | <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
4 | <%= devise_error_messages! %>
5 |
6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true %>
9 |
10 |
11 |
12 | <%= f.submit "Resend unlock instructions" %>
13 |
14 | <% end %>
15 |
16 | <%= render "devise/shared/links" %>
17 |
--------------------------------------------------------------------------------
/app/views/errors/internal_error.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Um erro interno aconteceu!
6 |
Nossa equipe foi notificada e está atuando para corrigir o problema!
7 | <%= link_to 'Voltar para página inicial', root_url, class:"btn btn-contorno" %>
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/views/errors/not_found.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Página não encontrada
6 |
Verifique a url digitada ou volte para a página anterior
7 | <%= link_to 'Voltar para página inicial', root_url, class:"btn btn-contorno" %>
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/views/errors/unacceptable.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Página não encontrada
6 |
Verifique a url digitada ou volte para a página anterior
7 | <%= link_to 'Voltar para página inicial', root_url, class:"btn btn-contorno" %>
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= yield %>
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.text.erb:
--------------------------------------------------------------------------------
1 | <%= yield %>
2 |
--------------------------------------------------------------------------------
/app/views/lists/services_with_reports.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Lista de Serviços com Denúncias
5 |
6 | <% if @services.empty? %>
7 |
8 |
Não há serviços cadastrados.
9 |
10 | <% else %>
11 |
12 | <%= render '/partials/service_with_reports_list', services: @services %>
13 |
14 | <% end %>
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/views/partials/_like_unlike.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | (<%= service.get_upvotes.size %>)
5 |
6 |
7 |
8 | (<%= service.get_downvotes.size %>)
9 |
10 |
11 |
12 | Denunciar
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/views/partials/_service.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= service.name %>
5 |
6 | <%= render '/partials/like_unlike', service: service %>
7 |
8 |
9 |
10 |
11 |
12 |
13 | <%= service.description %>
14 |
15 |
16 |
17 |
18 | <% unless service.website.blank? %>
19 |
20 |
21 |
<%= link_to service.website, service.website, target: :_blank %>
22 |
23 | <% end %>
24 | <% if !service.phone.blank? %>
25 |
26 |
27 |
<%= service.phone %>
28 |
29 | <% end %>
30 | <% if !service.other_phone.blank? %>
31 |
32 |
33 |
<%= service.other_phone %>
34 |
35 | <% end %>
36 |
37 |
38 |
39 | <% if service.owner_name.blank? %>
40 | <%= service.owner %>
41 | <% else %>
42 | <%= service.owner_name %>
43 |
44 | Cadastrado por <%= service.owner %>
45 |
46 | <% end %>
47 |
48 |
49 |
50 |
51 | <% if !service.address.street.blank? & !service.address.number.blank? %>
52 |
53 | <%= "#{service.address.street}" %>
54 | <% if !service.address.number.blank? %>
55 | , <%= "#{service.address.number}" %>
56 | <% end %>
57 |
58 | <% end %>
59 | <% if !service.address.complement.blank? %>
60 |
61 | <%= "#{service.address.complement}" %>
62 |
63 | <% end %>
64 | <% if !service.address.neighborhood.blank? %>
65 |
66 | <%= "#{service.address.neighborhood}" %>
67 |
68 | <% end %>
69 |
70 | <%= "#{service.address.city.name}, #{service.address.state.name}" %>
71 |
72 |
73 | <% if service.subarea %>
74 |
75 |
76 |
<%= "#{service.subarea.area.area if service.subarea.area}" %>
77 |
<%= "#{service.subarea.subarea}" %>
78 |
79 | <% end %>
80 |
81 |
82 | <% if can? :edit, service %>
83 |
91 | <% end %>
92 |
93 |
--------------------------------------------------------------------------------
/app/views/partials/_service_list.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <% @services.each do |service| %>
3 |
4 |
5 |
6 |
7 |
<%= service.name %>
8 |
9 | <% if service.subarea %>
10 |
11 |
12 |
13 |
14 |
15 | <%= service.subarea.area.area %>
16 |
17 |
18 |
19 |
20 | <%= service.subarea.subarea %>
21 |
22 |
23 | <% end %>
24 |
25 | <%= render '/partials/like_unlike', service: service %>
26 |
27 |
28 |
29 | <%= link_to service, class: "btn-go pull-right", "aria-label": "Ver detalhes", title: "Ver detalhes" do %>
30 |
31 | <% end %>
32 |
33 |
34 | <%= service.description %>
35 |
36 | <% unless service.website.blank? %>
37 |
38 |
39 |
<%= link_to service.website.html_safe, service.website, target: :_blank %>
40 |
41 | <% end %>
42 | <% if !service.phone.blank? %>
43 |
44 |
45 |
<%= service.phone %>
46 |
47 | <% end %>
48 |
49 |
50 | <% if service.owner_name.blank? %>
51 |
<%= service.owner %>
52 | <% else %>
53 |
<%= service.owner_name %>
54 |
55 | Cadastrado por <%= service.owner %>
56 |
57 | <% end %>
58 |
59 |
60 |
61 |
<%= service.address.city.name %> – <%= service.address.state.name %>
62 |
63 |
64 |
65 |
66 |
67 | <% end %>
68 |
69 | <%= will_paginate @services, renderer: BootstrapPagination::Rails, next_label: 'Seguinte', previous_label: 'Anterior' %>
70 |
71 | <%= render '/partials/service_report' %>
72 |
73 |
80 |
--------------------------------------------------------------------------------
/app/views/partials/_service_report.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= form_for :report, url: report_path, :html => {:id => 'report_service_form'} do |f| %>
5 |
9 |
10 | <%= f.hidden_field :service_id, required: true %>
11 |
12 | <%= f.label :email, "Insira seu email:", class: "control-label label-required" %>
13 | <%= f.text_field(:email, id:'report_email', class: 'form-control') %>
14 |
15 |
16 |
17 | <%= f.label :detail, "Insira a descrição da sua denúncia para este serviço (máximo 255 caracteres):", class:"control-label label-required" %>
18 | <%= f.text_area(:detail, id:'description', rows: 10, class: 'form-control', maxlength: "255") %>
19 |
20 |
21 |
22 | <%= f.check_box :authorize, :id =>"authorize-report" %>
23 | <%= f.label "Autorizo o envio da denúncia",:for => "authorize-report", class: "control-label label-required" %>
24 |
25 |
26 |
27 |
31 | <% end %>
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/views/partials/_service_with_reports_list.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <% @services.each do |service| %>
3 |
4 |
5 |
6 |
<%= service.name %>
7 |
8 |
9 |
10 | <% if service.subarea %>
11 | <%= service.subarea.area.area %>
12 | <%= service.subarea.subarea %>
13 | <% end %>
14 |
15 |
16 |
17 |
18 |
19 |
20 | <%= service.description %>
21 |
22 | <% unless service.website.blank? %>
23 |
24 |
25 |
<%= link_to service.website.html_safe, service.website, target: :_blank %>
26 |
27 | <% end %>
28 | <% if !service.phone.blank? %>
29 |
30 |
31 |
<%= service.phone %>
32 |
33 | <% end %>
34 |
35 |
36 | <% if service.owner_name.blank? %>
37 |
<%= service.owner %>
38 | <% else %>
39 |
<%= service.owner_name %>
40 |
41 | Cadastrado por <%= service.owner %>
42 |
43 | <% end %>
44 |
45 |
46 |
47 |
<%= service.address.city.name %> – <%= service.address.state.name %>
48 |
49 |
50 |
51 |
52 |
Denúncias
53 |
<%= service.reports_count %>
54 |
Ver denúncias
55 |
56 |
57 |
58 | <% end %>
59 |
60 | <%= will_paginate @services, renderer: BootstrapPagination::Rails, next_label: 'Seguinte', previous_label: 'Anterior' %>
61 |
62 |
63 |
--------------------------------------------------------------------------------
/app/views/reports/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%= @service.name %>
8 |
9 |
10 |
11 |
12 |
13 | <%= @service.description %>
14 |
15 | <% unless @service.website.blank? %>
16 |
17 |
18 |
<%= link_to @service.website.html_safe, @service.website, target: :_blank %>
19 |
20 | <% end %>
21 | <% if !@service.phone.blank? %>
22 |
23 |
24 |
<%= @service.phone %>
25 |
26 | <% end %>
27 |
28 |
29 | <% if @service.owner_name.blank? %>
30 |
<%= @service.owner %>
31 | <% else %>
32 |
<%= @service.owner_name %>
33 |
34 | Cadastrado por <%= @service.owner %>
35 |
36 | <% end %>
37 |
38 |
39 |
40 |
<%= @service.address.city.name %> – <%= @service.address.state.name %>
41 |
42 |
43 |
44 |
45 |
46 | <% @reports.each do |report| %>
47 |
48 |
49 |
<%= report.email %>
50 |
<%= report.detail %>
51 |
52 |
53 | <% end %>
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app/views/services/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Editar serviço
6 | <%= render 'form' %>
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/views/services/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <% if user_signed_in? %>
5 |
6 | <% if !@services.empty? %>
7 | <%= link_to new_service_path, class:"btn btn-sm btn-contorno" do %>
8 | Cadastrar serviço
9 | <% end %>
10 | <% end %>
11 |
12 | <% end %>
13 | Busca de Serviços
14 |
15 |
16 |
17 |
Campos de busca
18 |
19 | <%= form_tag(services_path, :method => "get", id: "search-form") do %>
20 |
21 |
22 |
23 | <%= label_tag 'search-description', "Nome ou Descrição", class: 'control-label' %>
24 | <%= text_field_tag :search, params[:search], placeholder: "Nome ou Descrição", id: 'search-description', class: 'form-control' %>
25 |
26 |
27 | <%= label_tag 'state-selector', "Estado", class: 'control-label' %>
28 | <%= collection_select :state, :state_id, states_selector, :id, :name, { include_blank: 'Selecione um estado', selected: read_selected_state_from_url }, {id: 'state-selector', class: 'form-control' } %>
29 |
30 |
31 | <%= label_tag 'city-selector', "Cidade", class: 'control-label' %>
32 | <%= collection_select :city, :city_id, [], :id, :name, {prompt: 'Selecione uma cidade'}, {id: 'city-selector', disabled: true , 'data-selected-city' => read_selected_city_from_url, class: 'form-control' }%>
33 |
34 |
35 |
36 |
37 | <%= button_tag "Limpar Campos", type: :reset, id: "reset_button", class: 'btn font1-2x btn-search' %>
38 | <%= submit_tag "Buscar", class: 'btn font1-2x btn-search' %>
39 |
40 |
41 |
42 | <% end %>
43 |
44 | <% if @services.empty? %>
45 |
46 |
Não há serviços cadastrados.
47 | <%= link_to 'Cadastre o primeiro!', new_service_path, class:"btn btn-contorno" %>
48 |
49 | <% else %>
50 |
51 | <%= render '/partials/service_list', services: @services %>
52 |
53 | <% end %>
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app/views/services/index.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.array!(@services) do |service|
4 | json.extract! service, :id, :area, :subarea, :name, :description, :phone, :website
5 | json.url service_url(service, format: :json)
6 | end
7 |
--------------------------------------------------------------------------------
/app/views/services/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Cadastro de novo serviço
6 | <%= render 'form' %>
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/views/services/show.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= render '/partials/service', service: @service %>
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/views/services/show.json.jbuilder:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | json.extract! @service, :id, :area, :subarea, :name, :description, :phone, :created_at, :updated_at
4 |
--------------------------------------------------------------------------------
/app/views/trans_mailer/send_mail_report.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
64 |
65 |
66 |
67 |
68 |
71 |
74 |
75 |
76 |
77 | Olá!
78 |
79 | Abaixo está a denúncia que o serviço <%= @report.service.name %> recebeu:
80 |
81 |
82 | Remetente: <%= @report.email %>
83 |
84 |
85 | Descrição: <%= @report.detail %>
86 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/app/views/trans_mailer/send_mail_report.txt.erb:
--------------------------------------------------------------------------------
1 | Olá!
2 | ===============================================
3 |
4 | Abaixo está a denúncia que o serviço <%= @report.service.name %> recebeu:
5 |
6 | Remetente: <%= @report.email %>
7 |
8 | Descrição: <%= @report.detail %>
9 |
--------------------------------------------------------------------------------
/app/views/welcome/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= image_tag 'transervicos-logo.svg', alt: 'Transerviços' %>
7 |
8 |
9 |
10 |
Você gostaria de cadastrar algum serviço que não discrimine as pessoas
11 | trans e travestis?
12 | <% if !user_signed_in? %><%= link_to 'cadastre-se', new_user_registration_path, { :class=>"btn-contorno" } %>
13 | <% else %>
14 | <%= link_to 'Cadastre serviço', new_service_path, { :class=>"btn-contorno" } %>
15 | <% end %>
16 |
17 |
18 |
19 |
Você está em busca de serviços oferecidos por essas pessoas ou que não as discriminem?
20 |
21 | <%= link_to 'busque serviços', services_path, { :class=>"btn-contorno" } %>
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
Como é ser trans ou travesti no Brasil hoje?
37 |
38 | O Brasil é o país campeão mundial de assassinatos de travestis e transexuais.
39 | A discriminação faz com que a grande maioria dessas pessoas não consiga
40 | completar seus estudos e esteja fora do mercado de trabalho formal.
41 |
42 |
43 |
44 |
45 |
Direitos que, por lei, deveríamos ter
46 |
47 | Aprovação de uma lei de identidade de gênero para que as pessoas trans
48 | e travestis possam modificar seus documentos sem grandes burocracias,
49 | direito ao emprego, acesso ao sistema de saúde, leis de proteção contra
50 | a transfobia, dentre outros.
51 |
52 |
53 |
54 |
55 |
O que eu posso fazer para mudar isso?
56 |
57 | Que tal contratar uma das talentosas pessoas trans e travestis que anunciam
58 | nesse site? E caso você conheça algum serviço que é verdadeiramente
59 | respeitoso com as pessoas trans e travestis, que tal publicá-lo aqui?
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | <%= t('.carousel.header').html_safe %>
72 |
73 |
74 |
75 |
76 | <%= image_tag 'trans-people.svg', { :class=>"img-responsive", :alt=>"Ilustração de pessoas trans" } %>
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
<%= t('.carousel.myth') %>
89 |
90 | <%= t('.carousel.elements.first.myth_explain') %>
91 |
92 |
93 |
<%= t('.carousel.fact') %>
94 |
95 | <%= t('.carousel.elements.first.fact_explain').html_safe %>
96 |
97 |
98 |
99 |
<%= t('.carousel.myth') %>
100 |
101 |
102 | <%= t('.carousel.elements.second.myth_explain') %>
103 |
104 |
105 |
<%= t('.carousel.fact') %>
106 |
107 | <%= t('.carousel.elements.second.fact_explain').html_safe %>
108 |
109 |
110 |
111 |
<%= t('.carousel.myth') %>
112 |
113 |
114 | <%= t('.carousel.elements.third.myth_explain') %>
115 |
116 |
<%= t('.carousel.fact') %>
117 |
118 | <%= t('.carousel.elements.third.fact_explain').html_safe %>
119 |
120 |
121 |
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
5 | load Gem.bin_path('bundler', 'bundle')
6 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | APP_PATH = File.expand_path('../config/application', __dir__)
5 | require_relative '../config/boot'
6 | require 'rails/commands'
7 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require_relative '../config/boot'
5 | require 'rake'
6 | Rake.application.run
7 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require 'fileutils'
5 | include FileUtils
6 |
7 | # path to your application root.
8 | APP_ROOT = File.expand_path('..', __dir__)
9 |
10 | def system!(*args)
11 | system(*args) || abort("\n== Command #{args} failed ==")
12 | end
13 |
14 | chdir APP_ROOT do
15 | # This script is a starting point to setup your application.
16 | # Add necessary setup steps to this file.
17 |
18 | puts '== Installing dependencies =='
19 | system! 'gem install bundler --conservative'
20 | system('bundle check') || system!('bundle install')
21 |
22 | # Install JavaScript dependencies if using Yarn
23 | # system('bin/yarn')
24 |
25 | puts "\n== Copying sample files =="
26 | unless File.exist?('config/database.yml')
27 | cp 'config/database.yml.example', 'config/database.yml'
28 | end
29 |
30 | puts "\n== Preparing database =="
31 | system! 'bin/rails db:setup'
32 |
33 | puts "\n== Removing old logs and tempfiles =="
34 | system! 'bin/rails log:clear tmp:clear'
35 |
36 | puts "\n== Restarting application server =="
37 | system! 'bin/rails restart'
38 | end
39 |
--------------------------------------------------------------------------------
/bin/update:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require 'fileutils'
5 | include FileUtils
6 |
7 | # path to your application root.
8 | APP_ROOT = File.expand_path('..', __dir__)
9 |
10 | def system!(*args)
11 | system(*args) || abort("\n== Command #{args} failed ==")
12 | end
13 |
14 | chdir APP_ROOT do
15 | # This script is a way to update your development environment automatically.
16 | # Add necessary update steps to this file.
17 |
18 | puts '== Installing dependencies =='
19 | system! 'gem install bundler --conservative'
20 | system('bundle check') || system!('bundle install')
21 |
22 | # Install JavaScript dependencies if using Yarn
23 | # system('bin/yarn')
24 |
25 | puts "\n== Updating database =="
26 | system! 'bin/rails db:migrate'
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/webpack:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | ENV['RAILS_ENV'] ||= ENV['RACK_ENV'] || 'development'
5 | ENV['NODE_ENV'] ||= 'development'
6 |
7 | require 'pathname'
8 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
9 | Pathname.new(__FILE__).realpath)
10 |
11 | require 'rubygems'
12 | require 'bundler/setup'
13 |
14 | require 'webpacker'
15 | require 'webpacker/webpack_runner'
16 | Webpacker::WebpackRunner.run(ARGV)
17 |
--------------------------------------------------------------------------------
/bin/webpack-dev-server:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | ENV['RAILS_ENV'] ||= ENV['RACK_ENV'] || 'development'
5 | ENV['NODE_ENV'] ||= 'development'
6 |
7 | require 'pathname'
8 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
9 | Pathname.new(__FILE__).realpath)
10 |
11 | require 'rubygems'
12 | require 'bundler/setup'
13 |
14 | require 'webpacker'
15 | require 'webpacker/dev_server_runner'
16 | Webpacker::DevServerRunner.run(ARGV)
17 |
--------------------------------------------------------------------------------
/bin/yarn:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | APP_ROOT = File.expand_path('..', __dir__)
5 | Dir.chdir(APP_ROOT) do
6 | exec 'yarnpkg', *ARGV
7 | rescue Errno::ENOENT
8 | warn 'Yarn executable was not detected in the system.'
9 | warn 'Download Yarn at https://yarnpkg.com/en/docs/install'
10 | exit 1
11 | end
12 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # This file is used by Rack-based servers to start the application.
4 |
5 | require_relative 'config/environment'
6 |
7 | run Rails.application
8 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative 'boot'
4 |
5 | require 'rails/all'
6 |
7 | # Require the gems listed in Gemfile, including any gems
8 | # you've limited to :test, :development, or :production.
9 | Bundler.require(*Rails.groups)
10 |
11 | module Transervicos
12 | class Application < Rails::Application
13 | # Initialize configuration defaults for originally generated Rails version.
14 | config.load_defaults 5.2
15 |
16 | config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
17 | config.i18n.enforce_available_locales = false
18 | config.i18n.available_locales = %i[pt-br]
19 | config.i18n.default_locale = :'pt-br'
20 | # Settings in config/environments/* take precedence over those specified here.
21 | # Application configuration can go into files in config/initializers
22 | # -- all .rb files in that directory are automatically loaded after loading
23 | # the framework and any gems in your application.
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
4 |
5 | require 'bundler/setup' # Set up gems listed in the Gemfile.
6 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
7 |
--------------------------------------------------------------------------------
/config/brakeman.ignore:
--------------------------------------------------------------------------------
1 | {
2 | "ignored_warnings": [
3 | {
4 | "warning_type": "Cross-Site Scripting",
5 | "warning_code": 4,
6 | "fingerprint": "2a44b61876ad78ab6caa258a825ef4ba869849d1628866d97122ce3c32fdcfb4",
7 | "check_name": "LinkToHref",
8 | "message": "Potentially unsafe model attribute in `link_to` href",
9 | "file": "app/views/reports/index.html.erb",
10 | "line": 18,
11 | "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
12 | "code": "link_to(Service.find(params[:service_id]).website.html_safe, Service.find(params[:service_id]).website, :target => :_blank)",
13 | "render_path": [
14 | {
15 | "type": "controller",
16 | "class": "ReportsController",
17 | "method": "find_reports_by_service",
18 | "line": 19,
19 | "file": "app/controllers/reports_controller.rb",
20 | "rendered": {
21 | "name": "reports/index",
22 | "file": "app/views/reports/index.html.erb"
23 | }
24 | }
25 | ],
26 | "location": {
27 | "type": "template",
28 | "template": "reports/index"
29 | },
30 | "user_input": "Service.find(params[:service_id]).website",
31 | "confidence": "Weak",
32 | "note": ""
33 | }
34 | ],
35 | "updated": "2019-10-23 21:19:13 -0300",
36 | "brakeman_version": "4.7.0"
37 | }
38 |
--------------------------------------------------------------------------------
/config/cable.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: async
3 |
4 | test:
5 | adapter: async
6 |
7 | production:
8 | adapter: redis
9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
10 | channel_prefix: transervicos_production
11 |
--------------------------------------------------------------------------------
/config/credentials.yml.enc:
--------------------------------------------------------------------------------
1 | p6E0OGBkHqjtH/tdvCQdGxMR4/fh3qs6gSaE313tOW39sfrv6ZNQInpTzUxaFpXgLLX/cUF8CyoLbOK2IGe7RAAyUxiioIYPECgpZesjSjbV4Cc1qo4W82fAyuufW9FgmIlHHsmWONrCEVn6BK9h2GAWzyfv2kd4S9rCFWMC+l4eIUg+g1OghJzYoQk9cUPbbJHKcDSfeBuRosqZdjiS7IOkVqGQoHj8Jr1oFzG8t4pDwsLZf/QcCEFZoS/2oLBonmTbaLEqDy87lHQTM0y0CIoN72bjUjb9aZ1S294O9ZMpMCsEDJmlKBLlFrGjhhCrZc9/jjnBkI42SLnXJzre6H4AYTH3cC77NjAiJmfaLch+Z0/8vSMrmTIM7wde5T3w8X3xF3KpvsUwH1u67/yURw01t8plTjVPFemN--elAR5V9BcvyrYVqz--6EC7Z0gB0MKPiuvvmUAmJA==
--------------------------------------------------------------------------------
/config/database.yml.example:
--------------------------------------------------------------------------------
1 | # PostgreSQL. Versions 9.1 and up are supported.
2 | #
3 | # Install the pg driver:
4 | # gem install pg
5 | # On OS X with Homebrew:
6 | # gem install pg -- --with-pg-config=/usr/local/bin/pg_config
7 | # On OS X with MacPorts:
8 | # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
9 | # On Windows:
10 | # gem install pg
11 | # Choose the win32 build.
12 | # Install PostgreSQL and put its /bin directory on your path.
13 | #
14 | # Configure Using Gemfile
15 | # gem 'pg'
16 | #
17 | default: &default
18 | adapter: postgresql
19 | encoding: unicode
20 | # For details on connection pooling, see Rails configuration guide
21 | # http://guides.rubyonrails.org/configuring.html#database-pooling
22 | host: db
23 | username: postgres
24 | password:
25 | pool: 5
26 |
27 | development:
28 | <<: *default
29 | database: transervicos_development
30 |
31 | # The specified database role being used to connect to postgres.
32 | # To create additional roles in postgres see `$ createuser --help`.
33 | # When left blank, postgres will use the default role. This is
34 | # the same name as the operating system user that initialized the database.
35 | #username: transervicos
36 |
37 | # The password associated with the postgres role (username).
38 | #password:
39 |
40 | # Connect on a TCP socket. Omitted by default since the client uses a
41 | # domain socket that doesn't need configuration. Windows does not have
42 | # domain sockets, so uncomment these lines.
43 | #host: localhost
44 |
45 | # The TCP port the server listens on. Defaults to 5432.
46 | # If your server runs on a different port number, change accordingly.
47 | #port: 5432
48 |
49 | # Schema search path. The server defaults to $user,public
50 | #schema_search_path: myapp,sharedapp,public
51 |
52 | # Minimum log levels, in increasing order:
53 | # debug5, debug4, debug3, debug2, debug1,
54 | # log, notice, warning, error, fatal, and panic
55 | # Defaults to warning.
56 | #min_messages: notice
57 |
58 | # Warning: The database defined as "test" will be erased and
59 | # re-generated from your development database when you run "rake".
60 | # Do not set this db to the same as development or production.
61 | test:
62 | <<: *default
63 | database: transervicos_test
64 |
65 | # As with config/secrets.yml, you never want to store sensitive information,
66 | # like your database password, in your source code. If your source code is
67 | # ever seen by anyone, they now have access to your database.
68 | #
69 | # Instead, provide the password as a unix environment variable when you boot
70 | # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
71 | # for a full rundown on how to provide these environment variables in a
72 | # production deployment.
73 | #
74 | # On Heroku and other platform providers, you may have a full connection URL
75 | # available as an environment variable. For example:
76 | #
77 | # DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
78 | #
79 | # You can use this database configuration with:
80 | #
81 | # production:
82 | # url: <%= ENV['DATABASE_URL'] %>
83 | #
84 | production:
85 | <<: *default
86 | database: transervicos_production
87 | username: transervicos
88 | password: <%= ENV['TRANSERVICOS_DATABASE_PASSWORD'] %>
89 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Load the Rails application.
4 | require_relative 'application'
5 |
6 | # Initialize the Rails application.
7 | Rails.application.initialize!
8 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Rails.application.configure do
4 | # Verifies that versions and hashed value of the package contents in the project's package.json
5 | config.webpacker.check_yarn_integrity = true
6 | # Settings specified here will take precedence over those in config/application.rb.
7 |
8 | # In the development environment your application's code is reloaded on
9 | # every request. This slows down response time but is perfect for development
10 | # since you don't have to restart the web server when you make code changes.
11 | config.cache_classes = false
12 |
13 | # Do not eager load code on boot.
14 | config.eager_load = false
15 |
16 | # Show full error reports.
17 | config.consider_all_requests_local = true
18 |
19 | # Enable/disable caching. By default caching is disabled.
20 | # Run rails dev:cache to toggle caching.
21 | if Rails.root.join('tmp', 'caching-dev.txt').exist?
22 | config.action_controller.perform_caching = true
23 |
24 | config.cache_store = :memory_store
25 | config.public_file_server.headers = {
26 | 'Cache-Control' => "public, max-age=#{2.days.to_i}"
27 | }
28 | else
29 | config.action_controller.perform_caching = false
30 |
31 | config.cache_store = :null_store
32 | end
33 |
34 | # Store uploaded files on the local file system (see config/storage.yml for options)
35 | config.active_storage.service = :local
36 |
37 | # Don't care if the mailer can't send.
38 | config.action_mailer.raise_delivery_errors = false
39 |
40 | config.action_mailer.perform_caching = false
41 |
42 | # Print deprecation notices to the Rails logger.
43 | config.active_support.deprecation = :log
44 |
45 | # Raise an error on page load if there are pending migrations.
46 | config.active_record.migration_error = :page_load
47 |
48 | # Highlight code that triggered database queries in logs.
49 | config.active_record.verbose_query_logs = true
50 |
51 | # Debug mode disables concatenation and preprocessing of assets.
52 | # This option may cause significant delays in view rendering with a large
53 | # number of complex assets.
54 | config.assets.debug = true
55 |
56 | # Suppress logger output for asset requests.
57 | config.assets.quiet = true
58 |
59 | # Raises error for missing translations
60 | # config.action_view.raise_on_missing_translations = true
61 |
62 | # Use an evented file watcher to asynchronously detect changes in source code,
63 | # routes, locales, etc. This feature depends on the listen gem.
64 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker
65 | end
66 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Rails.application.configure do
4 | # Verifies that versions and hashed value of the package contents in the project's package.json
5 | config.webpacker.check_yarn_integrity = false
6 | # Settings specified here will take precedence over those in config/application.rb.
7 |
8 | # Code is not reloaded between requests.
9 | config.cache_classes = true
10 |
11 | # Eager load code on boot. This eager loads most of Rails and
12 | # your application in memory, allowing both threaded web servers
13 | # and those relying on copy on write to perform better.
14 | # Rake tasks automatically ignore this option for performance.
15 | config.eager_load = true
16 |
17 | # Full error reports are disabled and caching is turned on.
18 | config.consider_all_requests_local = false
19 | config.action_controller.perform_caching = true
20 |
21 | # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
22 | # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
23 | # config.require_master_key = true
24 |
25 | # Disable serving static files from the `/public` folder by default since
26 | # Apache or NGINX already handles this.
27 | config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
28 |
29 | # Compress JavaScripts and CSS.
30 | config.assets.js_compressor = :uglifier
31 | # config.assets.css_compressor = :sass
32 |
33 | # Do not fallback to assets pipeline if a precompiled asset is missed.
34 | config.assets.compile = false
35 |
36 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
37 |
38 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
39 | # config.action_controller.asset_host = 'http://assets.example.com'
40 |
41 | # Specifies the header that your server uses for sending files.
42 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
43 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
44 |
45 | # Store uploaded files on the local file system (see config/storage.yml for options)
46 | config.active_storage.service = :local
47 |
48 | # Mount Action Cable outside main process or domain
49 | # config.action_cable.mount_path = nil
50 | # config.action_cable.url = 'wss://example.com/cable'
51 | # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
52 |
53 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
54 | # config.force_ssl = true
55 |
56 | # Use the lowest log level to ensure availability of diagnostic information
57 | # when problems arise.
58 | config.log_level = :debug
59 |
60 | # Prepend all log lines with the following tags.
61 | config.log_tags = [:request_id]
62 |
63 | # Use a different cache store in production.
64 | # config.cache_store = :mem_cache_store
65 |
66 | # Use a real queuing backend for Active Job (and separate queues per environment)
67 | # config.active_job.queue_adapter = :resque
68 | # config.active_job.queue_name_prefix = "transervicos_#{Rails.env}"
69 |
70 | config.action_mailer.perform_caching = false
71 |
72 | # Ignore bad email addresses and do not raise email delivery errors.
73 | # Set this to true and configure the email server for immediate delivery to raise delivery errors.
74 | # config.action_mailer.raise_delivery_errors = false
75 |
76 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
77 | # the I18n.default_locale when a translation cannot be found).
78 | config.i18n.fallbacks = true
79 |
80 | # Send deprecation notices to registered listeners.
81 | config.active_support.deprecation = :notify
82 |
83 | # Use default logging formatter so that PID and timestamp are not suppressed.
84 | config.log_formatter = ::Logger::Formatter.new
85 |
86 | # Use a different logger for distributed setups.
87 | # require 'syslog/logger'
88 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
89 |
90 | if ENV['RAILS_LOG_TO_STDOUT'].present?
91 | logger = ActiveSupport::Logger.new(STDOUT)
92 | logger.formatter = config.log_formatter
93 | config.logger = ActiveSupport::TaggedLogging.new(logger)
94 | end
95 |
96 | # Do not dump schema after migrations.
97 | config.active_record.dump_schema_after_migration = false
98 | end
99 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Rails.application.configure do
4 | # Settings specified here will take precedence over those in config/application.rb.
5 |
6 | # The test environment is used exclusively to run your application's
7 | # test suite. You never need to work with it otherwise. Remember that
8 | # your test database is "scratch space" for the test suite and is wiped
9 | # and recreated between test runs. Don't rely on the data there!
10 | config.cache_classes = true
11 |
12 | # Do not eager load code on boot. This avoids loading your whole application
13 | # just for the purpose of running a single test. If you are using a tool that
14 | # preloads Rails for running tests, you may have to set it to true.
15 | config.eager_load = false
16 |
17 | # Configure public file server for tests with Cache-Control for performance.
18 | config.public_file_server.enabled = true
19 | config.public_file_server.headers = {
20 | 'Cache-Control' => "public, max-age=#{1.hour.to_i}"
21 | }
22 |
23 | # Show full error reports and disable caching.
24 | config.consider_all_requests_local = true
25 | config.action_controller.perform_caching = false
26 |
27 | # Raise exceptions instead of rendering exception templates.
28 | config.action_dispatch.show_exceptions = false
29 |
30 | # Disable request forgery protection in test environment.
31 | config.action_controller.allow_forgery_protection = false
32 |
33 | # Store uploaded files on the local file system in a temporary directory
34 | config.active_storage.service = :test
35 |
36 | config.action_mailer.perform_caching = false
37 |
38 | # Tell Action Mailer not to deliver emails to the real world.
39 | # The :test delivery method accumulates sent emails in the
40 | # ActionMailer::Base.deliveries array.
41 | config.action_mailer.delivery_method = :test
42 |
43 | # Print deprecation notices to the stderr.
44 | config.active_support.deprecation = :stderr
45 |
46 | # Raises error for missing translations
47 | # config.action_view.raise_on_missing_translations = true
48 | end
49 |
--------------------------------------------------------------------------------
/config/initializers/application_controller_renderer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # ActiveSupport::Reloader.to_prepare do
6 | # ApplicationController.renderer.defaults.merge!(
7 | # http_host: 'example.org',
8 | # https: false
9 | # )
10 | # end
11 |
--------------------------------------------------------------------------------
/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Version of your assets, change this if you want to expire all your assets.
6 | Rails.application.config.assets.version = '1.0'
7 |
8 | # Add additional assets to the asset load path.
9 | # Rails.application.config.assets.paths << Emoji.images_path
10 | # Add Yarn node_modules folder to the asset load path.
11 | Rails.application.config.assets.paths << Rails.root.join('node_modules')
12 |
13 | # Precompile additional assets.
14 | # application.js, application.css, and all non-JS/CSS in the app/assets
15 | # folder are already added.
16 | # Rails.application.config.assets.precompile += %w( admin.js admin.css )
17 |
--------------------------------------------------------------------------------
/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
6 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
7 |
8 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
9 | # Rails.backtrace_cleaner.remove_silencers!
10 |
--------------------------------------------------------------------------------
/config/initializers/content_security_policy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Define an application-wide content security policy
6 | # For further information see the following documentation
7 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
8 |
9 | # Rails.application.config.content_security_policy do |policy|
10 | # policy.default_src :self, :https
11 | # policy.font_src :self, :https, :data
12 | # policy.img_src :self, :https, :data
13 | # policy.object_src :none
14 | # policy.script_src :self, :https
15 | # policy.style_src :self, :https
16 |
17 | # # Specify URI for violation reports
18 | # # policy.report_uri "/csp-violation-report-endpoint"
19 | # end
20 |
21 | # If you are using UJS then enable automatic nonce generation
22 | # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
23 |
24 | # Report CSP violations to a specified URI
25 | # For further information see the following documentation:
26 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
27 | # Rails.application.config.content_security_policy_report_only = true
28 |
29 | Rails.application.config.content_security_policy do |policy|
30 | if Rails.env.development?
31 | policy.script_src :self, :https, :unsafe_eval
32 | else
33 | policy.script_src :self, :https
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/config/initializers/cookies_serializer.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Specify a serializer for the signed and encrypted cookie jars.
6 | # Valid options are :json, :marshal, and :hybrid.
7 | Rails.application.config.action_dispatch.cookies_serializer = :json
8 |
--------------------------------------------------------------------------------
/config/initializers/devise.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Devise.setup do |config|
4 | config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
5 | require 'devise/orm/active_record'
6 | config.case_insensitive_keys = [:email]
7 | config.strip_whitespace_keys = [:email]
8 | config.skip_session_storage = [:http_auth]
9 | config.stretches = Rails.env.test? ? 1 : 11
10 | config.reconfirmable = true
11 | config.password_length = 6..128
12 | config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
13 | config.reset_password_within = 6.hours
14 | config.sign_out_via = :delete
15 | end
16 |
--------------------------------------------------------------------------------
/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Configure sensitive parameters which will be filtered from the log file.
6 | Rails.application.config.filter_parameters += [:password]
7 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Add new inflection rules using the following format. Inflections
6 | # are locale specific, and you may define rules for as many different
7 | # locales as you wish. All of these examples are active by default:
8 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
9 | # inflect.plural /^(ox)$/i, '\1en'
10 | # inflect.singular /^(ox)en/i, '\1'
11 | # inflect.irregular 'person', 'people'
12 | # inflect.uncountable %w( fish sheep )
13 | # end
14 |
15 | # These inflection rules are supported but not enabled by default:
16 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
17 | # inflect.acronym 'RESTful'
18 | # end
19 |
--------------------------------------------------------------------------------
/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # Add new mime types for use in respond_to blocks:
6 | # Mime::Type.register "text/richtext", :rtf
7 |
--------------------------------------------------------------------------------
/config/initializers/simple_form.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | SimpleForm.setup do |config|
4 | config.wrappers(
5 | :default,
6 | class: :input,
7 | hint_class: :field_with_hint,
8 | error_class: :field_with_errors,
9 | valid_class: :field_without_errors
10 | ) do |b|
11 | b.use :html5
12 | b.use :placeholder
13 | b.optional :maxlength
14 | b.optional :minlength
15 | b.optional :pattern
16 | b.optional :min_max
17 | b.optional :readonly
18 | b.use :label_input
19 | b.use :hint, wrap_with: { tag: :span, class: :hint }
20 | b.use :error, wrap_with: { tag: :span, class: :error }
21 | end
22 |
23 | config.default_wrapper = :default
24 |
25 | config.boolean_style = :nested
26 | config.button_class = 'btn'
27 | config.error_notification_tag = :div
28 | config.error_notification_class = 'error_notification'
29 | config.browser_validations = false
30 | config.boolean_label_class = 'checkbox'
31 | end
32 |
--------------------------------------------------------------------------------
/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Be sure to restart your server when you modify this file.
4 |
5 | # This file contains settings for ActionController::ParamsWrapper which
6 | # is enabled by default.
7 |
8 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
9 | ActiveSupport.on_load(:action_controller) do
10 | wrap_parameters format: [:json]
11 | end
12 |
13 | # To enable root element in JSON for ActiveRecord objects.
14 | # ActiveSupport.on_load(:active_record) do
15 | # self.include_root_in_json = true
16 | # end
17 |
--------------------------------------------------------------------------------
/config/locales/devise.en.yml:
--------------------------------------------------------------------------------
1 | # Additional translations at https://github.com/plataformatec/devise/wiki/I18n
2 |
3 | en:
4 | devise:
5 | confirmations:
6 | confirmed: "Your email address has been successfully confirmed."
7 | send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
8 | send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
9 | failure:
10 | already_authenticated: "You are already signed in."
11 | inactive: "Your account is not activated yet."
12 | invalid: "Invalid %{authentication_keys} or password."
13 | locked: "Your account is locked."
14 | last_attempt: "You have one more attempt before your account is locked."
15 | not_found_in_database: "Invalid %{authentication_keys} or password."
16 | timeout: "Your session expired. Please sign in again to continue."
17 | unauthenticated: "You need to sign in or sign up before continuing."
18 | unconfirmed: "You have to confirm your email address before continuing."
19 | mailer:
20 | confirmation_instructions:
21 | subject: "Confirmation instructions"
22 | reset_password_instructions:
23 | subject: "Reset password instructions"
24 | unlock_instructions:
25 | subject: "Unlock instructions"
26 | email_changed:
27 | subject: "Email Changed"
28 | password_change:
29 | subject: "Password Changed"
30 | omniauth_callbacks:
31 | failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
32 | success: "Successfully authenticated from %{kind} account."
33 | passwords:
34 | no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
35 | send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
36 | send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
37 | updated: "Your password has been changed successfully. You are now signed in."
38 | updated_not_active: "Your password has been changed successfully."
39 | registrations:
40 | destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
41 | signed_up: "Welcome! You have signed up successfully."
42 | signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
43 | signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
44 | signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
45 | update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address."
46 | updated: "Your account has been updated successfully."
47 | sessions:
48 | signed_in: "Signed in successfully."
49 | signed_out: "Signed out successfully."
50 | already_signed_out: "Signed out successfully."
51 | unlocks:
52 | send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
53 | send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
54 | unlocked: "Your account has been unlocked successfully. Please sign in to continue."
55 | errors:
56 | messages:
57 | already_confirmed: "was already confirmed, please try signing in"
58 | confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
59 | expired: "has expired, please request a new one"
60 | not_found: "not found"
61 | not_locked: "was not locked"
62 | not_saved:
63 | one: "1 error prohibited this %{resource} from being saved:"
64 | other: "%{count} errors prohibited this %{resource} from being saved:"
65 |
--------------------------------------------------------------------------------
/config/locales/en.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/simple_form.en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | simple_form:
3 | "yes": 'Yes'
4 | "no": 'No'
5 | required:
6 | text: 'required'
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: "Please review the problems below:"
13 | # Examples
14 | # labels:
15 | # defaults:
16 | # password: 'Password'
17 | # user:
18 | # new:
19 | # email: 'E-mail to sign in.'
20 | # edit:
21 | # email: 'E-mail.'
22 | # hints:
23 | # defaults:
24 | # username: 'User name to sign in.'
25 | # password: 'No special characters, please.'
26 | # include_blanks:
27 | # defaults:
28 | # age: 'Rather not say'
29 | # prompts:
30 | # defaults:
31 | # age: 'Select your age'
32 |
--------------------------------------------------------------------------------
/config/puma.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Puma can serve each request in a thread from an internal thread pool.
4 | # The `threads` method setting takes two numbers: a minimum and maximum.
5 | # Any libraries that use thread pools should be configured to match
6 | # the maximum value specified for Puma. Default is set to 5 threads for minimum
7 | # and maximum; this matches the default thread size of Active Record.
8 | #
9 | threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }
10 | threads threads_count, threads_count
11 |
12 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
13 | #
14 | port ENV.fetch('PORT') { 3000 }
15 |
16 | # Specifies the `environment` that Puma will run in.
17 | #
18 | environment ENV.fetch('RAILS_ENV') { 'development' }
19 |
20 | # Specifies the number of `workers` to boot in clustered mode.
21 | # Workers are forked webserver processes. If using threads and workers together
22 | # the concurrency of the application would be max `threads` * `workers`.
23 | # Workers do not work on JRuby or Windows (both of which do not support
24 | # processes).
25 | #
26 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
27 |
28 | # Use the `preload_app!` method when specifying a `workers` number.
29 | # This directive tells Puma to first boot the application and load code
30 | # before forking the application. This takes advantage of Copy On Write
31 | # process behavior so workers use less memory.
32 | #
33 | # preload_app!
34 |
35 | # Allow puma to be restarted by `rails restart` command.
36 | plugin :tmp_restart
37 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Rails.application.routes.draw do
4 | mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
5 |
6 | scope(path_names: { new: 'novo', edit: 'editar' }) do
7 | resources :services, path: 'servicos' do
8 | member do
9 | put 'like', to: 'services#upvote'
10 | put 'dislike', to: 'services#downvote'
11 | end
12 | end
13 | end
14 |
15 | get 'dashboard', to: 'dashboard#index'
16 |
17 | get 'state/:id', to: 'states#show', format: 'json'
18 |
19 | get 'area/:area_id/subareas', to: 'application#load_subareas', as: 'subareas', format: :json
20 |
21 | devise_for :users, controllers: { registrations: 'registrations' }
22 |
23 | root 'welcome#index'
24 |
25 | match '/404', to: 'errors#not_found', via: :all
26 | match '/422', to: 'errors#unacceptable', via: :all
27 | match '/500', to: 'errors#internal_error', via: :all
28 |
29 | post 'reports', to: 'reports#create', as: 'report'
30 | match 'list/services_with_reports', to: 'lists#services_with_reports', via: :all
31 | get 'reports/:service_id', to: 'reports#find_reports_by_service', as: 'reports_by_service'
32 | end
33 |
--------------------------------------------------------------------------------
/config/spring.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | %w[
4 | .ruby-version
5 | .rbenv-vars
6 | tmp/restart.txt
7 | tmp/caching-dev.txt
8 | ].each { |path| Spring.watch(path) }
9 |
--------------------------------------------------------------------------------
/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 | const vue = require('./loaders/vue')
3 |
4 | environment.loaders.append('vue', vue)
5 | module.exports = environment
6 |
--------------------------------------------------------------------------------
/config/webpack/loaders/vue.js:
--------------------------------------------------------------------------------
1 | const { dev_server: devServer } = require('@rails/webpacker').config
2 |
3 | const isProduction = process.env.NODE_ENV === 'production'
4 | const inDevServer = process.argv.find(v => v.includes('webpack-dev-server'))
5 | const extractCSS = !(inDevServer && (devServer && devServer.hmr)) || isProduction
6 |
7 | module.exports = {
8 | test: /\.vue(\.erb)?$/,
9 | use: [{
10 | loader: 'vue-loader',
11 | options: { extractCSS }
12 | }]
13 | }
14 |
--------------------------------------------------------------------------------
/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_output_path: packs
7 | cache_path: tmp/cache/webpacker
8 |
9 | # Additional paths webpack should lookup modules
10 | # ['app/assets', 'engine/foo/app/assets']
11 | resolved_paths: []
12 |
13 | # Reload manifest.json on all requests so we reload latest compiled packs
14 | cache_manifest: false
15 |
16 | extensions:
17 | - .vue
18 | - .js
19 | - .sass
20 | - .scss
21 | - .css
22 | - .module.sass
23 | - .module.scss
24 | - .module.css
25 | - .png
26 | - .svg
27 | - .gif
28 | - .jpeg
29 | - .jpg
30 |
31 | development:
32 | <<: *default
33 | compile: true
34 |
35 | # Reference: https://webpack.js.org/configuration/dev-server/
36 | dev_server:
37 | https: false
38 | host: localhost
39 | port: 3035
40 | public: localhost:3035
41 | hmr: false
42 | # Inline should be set to true if using HMR
43 | inline: true
44 | overlay: true
45 | compress: true
46 | disable_host_check: true
47 | use_local_ip: false
48 | quiet: false
49 | headers:
50 | 'Access-Control-Allow-Origin': '*'
51 | watch_options:
52 | ignored: /node_modules/
53 |
54 |
55 | test:
56 | <<: *default
57 | compile: true
58 |
59 | # Compile test packs to a separate directory
60 | public_output_path: packs-test
61 |
62 | production:
63 | <<: *default
64 |
65 | # Production depends on precompilation of packs prior to booting for performance.
66 | compile: false
67 |
68 | # Cache manifest.json for performance
69 | cache_manifest: true
70 | check_yarn_integrity: false
71 |
--------------------------------------------------------------------------------
/db/migrate/20151211201731_devise_create_users.rb:
--------------------------------------------------------------------------------
1 | class DeviseCreateUsers < ActiveRecord::Migration[4.2]
2 | def change # rubocop:disable Metrics/MethodLength
3 | create_table(:users) do |t|
4 | ## Database authenticatable
5 | t.string :email, null: false, default: ''
6 | t.string :encrypted_password, null: false, default: ''
7 |
8 | ## Recoverable
9 | t.string :reset_password_token
10 | t.datetime :reset_password_sent_at
11 |
12 | ## Rememberable
13 | t.datetime :remember_created_at
14 |
15 | ## Trackable
16 | t.integer :sign_in_count, default: 0, null: false
17 | t.datetime :current_sign_in_at
18 | t.datetime :last_sign_in_at
19 | t.inet :current_sign_in_ip
20 | t.inet :last_sign_in_ip
21 |
22 | ## Confirmable
23 | # t.string :confirmation_token
24 | # t.datetime :confirmed_at
25 | # t.datetime :confirmation_sent_at
26 | # t.string :unconfirmed_email # Only if using reconfirmable
27 |
28 | ## Lockable
29 | # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
30 | # t.string :unlock_token # Only if unlock strategy is :email or :both
31 | # t.datetime :locked_at
32 |
33 | t.timestamps null: false
34 | end
35 |
36 | add_index :users, :email, unique: true
37 | add_index :users, :reset_password_token, unique: true
38 | # add_index :users, :confirmation_token, unique: true
39 | # add_index :users, :unlock_token, unique: true
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/db/migrate/20151214201039_add_extra_fields_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddExtraFieldsToUsers < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :users, :social_name, :string
4 | add_column :users, :civil_name, :string
5 | add_column :users, :birth_date, :date
6 | add_column :users, :username, :string
7 | add_column :users, :phone_number, :string
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20151214203920_create_services.rb:
--------------------------------------------------------------------------------
1 | class CreateServices < ActiveRecord::Migration[4.2]
2 | def change
3 | create_table :services do |t|
4 | t.string :name
5 | t.text :description
6 | t.string :phone
7 |
8 | t.timestamps null: false
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/db/migrate/20151214205645_create_addresses.rb:
--------------------------------------------------------------------------------
1 | class CreateAddresses < ActiveRecord::Migration[4.2]
2 | def change
3 | create_table :addresses do |t|
4 | t.string :street
5 | t.string :number
6 | t.string :complement
7 | t.string :neighborhood
8 | t.string :city
9 | t.string :state
10 |
11 | t.timestamps null: false
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/db/migrate/20151222164956_add_service_id_to_address.rb:
--------------------------------------------------------------------------------
1 | class AddServiceIdToAddress < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :addresses, :service_id, :integer
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20151223150803_create_areas.rb:
--------------------------------------------------------------------------------
1 | class CreateAreas < ActiveRecord::Migration[4.2]
2 | def change
3 | create_table :areas do |t|
4 | t.string :area
5 |
6 | t.timestamps null: false
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20151223151132_create_subareas.rb:
--------------------------------------------------------------------------------
1 | class CreateSubareas < ActiveRecord::Migration[4.2]
2 | def change
3 | create_table :subareas do |t|
4 | t.string :subarea
5 |
6 | t.timestamps null: false
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20151229132522_add_relation_between_service_and_subarea.rb:
--------------------------------------------------------------------------------
1 | class AddRelationBetweenServiceAndSubarea < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :services, :subarea_id, :integer
4 | add_column :subareas, :area_id, :integer
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/db/migrate/20160119203424_add_relation_between_user_and_service.rb:
--------------------------------------------------------------------------------
1 | class AddRelationBetweenUserAndService < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :services, :user_id, :integer
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20160120123758_create_friendly_id_slugs.rb:
--------------------------------------------------------------------------------
1 | class CreateFriendlyIdSlugs < ActiveRecord::Migration[4.2]
2 | def change # rubocop:disable Metrics/MethodLength
3 | create_table :friendly_id_slugs do |t|
4 | t.string :slug, null: false
5 | t.integer :sluggable_id, null: false
6 | t.string :sluggable_type, limit: 50
7 | t.string :scope
8 | t.datetime :created_at
9 | end
10 | add_index :friendly_id_slugs, :sluggable_id
11 | add_index :friendly_id_slugs, [:slug, :sluggable_type]
12 | add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], unique: true
13 | add_index :friendly_id_slugs, :sluggable_type
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/db/migrate/20160120124010_add_slug_to_services.rb:
--------------------------------------------------------------------------------
1 | class AddSlugToServices < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :services, :slug, :string
4 | add_index :services, :slug, unique: true
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/db/migrate/20160121150431_add_name_preference_to_user.rb:
--------------------------------------------------------------------------------
1 | class AddNamePreferenceToUser < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :users, :name_preference, :string, limit: 1
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20160201174342_add_owner_fields_to_services.rb:
--------------------------------------------------------------------------------
1 | class AddOwnerFieldsToServices < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :services, :owner_name, :string
4 | add_column :services, :owner_email, :string
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/db/migrate/20160202171035_add_another_phone_to_services.rb:
--------------------------------------------------------------------------------
1 | class AddAnotherPhoneToServices < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :services, :other_phone, :string
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20160202184346_add_admin_to_user.rb:
--------------------------------------------------------------------------------
1 | class AddAdminToUser < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :users, :admin, :boolean, default: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20160219183101_create_states.rb:
--------------------------------------------------------------------------------
1 | class CreateStates < ActiveRecord::Migration[4.2]
2 | def change
3 | create_table :states do |t|
4 | t.string :acronym
5 | t.string :name
6 |
7 | t.timestamps null: false
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20160219191835_create_cities.rb:
--------------------------------------------------------------------------------
1 | class CreateCities < ActiveRecord::Migration[4.2]
2 | def change
3 | create_table :cities do |t|
4 | t.string :name
5 | t.integer :state_id
6 |
7 | t.timestamps null: false
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20160222182548_add_city_and_state_to_address.rb:
--------------------------------------------------------------------------------
1 | class AddCityAndStateToAddress < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :addresses, :city_id, :integer
4 | add_column :addresses, :state_id, :integer
5 | remove_column :addresses, :city
6 | remove_column :addresses, :state
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/db/migrate/20160301014528_add_website_to_services.rb:
--------------------------------------------------------------------------------
1 | class AddWebsiteToServices < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :services, :website, :string
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20160419185224_create_forbidden_words.rb:
--------------------------------------------------------------------------------
1 | class CreateForbiddenWords < ActiveRecord::Migration[4.2]
2 | def change
3 | create_table :forbidden_words do |t|
4 | t.string :word
5 |
6 | t.timestamps null: false
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20160422180911_acts_as_votable_migration.rb:
--------------------------------------------------------------------------------
1 | class ActsAsVotableMigration < ActiveRecord::Migration[4.2]
2 | def self.up
3 | create_table :votes do |t|
4 | t.references :votable, polymorphic: true
5 | t.references :voter, polymorphic: true
6 |
7 | t.boolean :vote_flag
8 | t.string :vote_scope
9 | t.integer :vote_weight
10 |
11 | t.timestamps
12 | end
13 |
14 | create_indexes
15 | end
16 |
17 | def self.down
18 | drop_table :votes
19 | end
20 |
21 | private_class_method def self.create_indexes
22 | if ActiveRecord::VERSION::MAJOR < 4
23 | add_index :votes, [:votable_id, :votable_type]
24 | add_index :votes, [:voter_id, :voter_type]
25 | end
26 |
27 | add_index :votes, [:voter_id, :voter_type, :vote_scope]
28 | add_index :votes, [:votable_id, :votable_type, :vote_scope]
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/db/migrate/20160424224442_create_voting_sessions.rb:
--------------------------------------------------------------------------------
1 | class CreateVotingSessions < ActiveRecord::Migration[4.2]
2 | def change
3 | create_table :voting_sessions do |t|
4 | t.string :ip
5 |
6 | t.timestamps null: false
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20160520165008_install_trigram.rb:
--------------------------------------------------------------------------------
1 | class InstallTrigram < ActiveRecord::Migration[4.2]
2 | def self.up
3 | ActiveRecord::Base.connection.execute('CREATE EXTENSION IF NOT EXISTS pg_trgm;')
4 | end
5 |
6 | def self.down
7 | ActiveRecord::Base.connection.execute('DROP EXTENSION pg_trgm;')
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20160520203043_add_index_service_name.rb:
--------------------------------------------------------------------------------
1 | class AddIndexServiceName < ActiveRecord::Migration[4.2]
2 | def change
3 | execute "
4 | create index on services using gin(to_tsvector('portuguese', name));
5 | "
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20160520211129_add_index_service_description.rb:
--------------------------------------------------------------------------------
1 | class AddIndexServiceDescription < ActiveRecord::Migration[4.2]
2 | def change
3 | execute "
4 | create index on services using gin(to_tsvector('portuguese', description));
5 | "
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20160523194021_create_extension_unaccent.rb:
--------------------------------------------------------------------------------
1 | class CreateExtensionUnaccent < ActiveRecord::Migration[4.2]
2 | def self.up
3 | ActiveRecord::Base.connection.execute('CREATE EXTENSION IF NOT EXISTS unaccent;')
4 | end
5 |
6 | def self.down
7 | ActiveRecord::Base.connection.execute('DROP EXTENSION unaccent;')
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20160523201023_drop_extension_pg_trgm.rb:
--------------------------------------------------------------------------------
1 | class DropExtensionPgTrgm < ActiveRecord::Migration[4.2]
2 | def change
3 | ActiveRecord::Base.connection.execute('DROP EXTENSION IF EXISTS pg_trgm;')
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20160523201311_drop_indexes_pg_trgm_on_services.rb:
--------------------------------------------------------------------------------
1 | class DropIndexesPgTrgmOnServices < ActiveRecord::Migration[4.2]
2 | def change
3 | ActiveRecord::Base.connection.execute('DROP INDEX IF EXISTS services_to_tsvector_idx;')
4 | ActiveRecord::Base.connection.execute('DROP INDEX IF EXISTS services_to_tsvector_idx1;')
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/db/migrate/20160609170644_create_reports.rb:
--------------------------------------------------------------------------------
1 | class CreateReports < ActiveRecord::Migration[4.2]
2 | def change
3 | create_table :reports do |t|
4 | t.string :detail
5 | t.references :service, index: true, foreign_key: true
6 |
7 | t.timestamps null: false
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20160613213641_add_email_to_report.rb:
--------------------------------------------------------------------------------
1 | class AddEmailToReport < ActiveRecord::Migration[4.2]
2 | def change
3 | add_column :reports, :email, :string
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20190120183617_create_active_storage_tables.active_storage.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # This migration comes from active_storage (originally 20170806125915)
4 | class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
5 | def change
6 | create_table :active_storage_blobs do |t|
7 | t.string :key, null: false
8 | t.string :filename, null: false
9 | t.string :content_type
10 | t.text :metadata
11 | t.bigint :byte_size, null: false
12 | t.string :checksum, null: false
13 | t.datetime :created_at, null: false
14 |
15 | t.index [:key], unique: true
16 | end
17 |
18 | create_table :active_storage_attachments do |t|
19 | t.string :name, null: false
20 | t.references :record, null: false, polymorphic: true, index: false
21 | t.references :blob, null: false
22 |
23 | t.datetime :created_at, null: false
24 |
25 | t.index %i[record_type record_id name blob_id], name: 'index_active_storage_attachments_uniqueness', unique: true
26 | t.foreign_key :active_storage_blobs, column: :blob_id
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/db/seeds.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'net/http'
4 | require 'json'
5 |
6 | # Areas e Subareas
7 | areas = {
8 | "Saúde": [
9 | 'Odontologia', 'Cirurgia Plástica', 'Urologia', 'Ginecologia', 'Endocrinologia', 'Dermatologia', 'Cirurgia Geral',
10 | 'Infectologia', 'Proctologia'
11 | ],
12 | "Direito": ['Advocacia'],
13 | "Educação": ['Preparatório Pré-Vestibular', 'Ensino Médio', 'Ensino Fundamental', 'Ensino Superior', 'Idioma'],
14 | "Religião": [],
15 | "Comidas": [],
16 | "Beleza": [],
17 | "Eventos": [],
18 | "Moda": ['Costura'],
19 | "Higiene": ['Limpeza'],
20 | "Atendimento ao público": [],
21 | "Alimentação": [],
22 | "Tecnologia": []
23 | }
24 |
25 | areas.each do |area_name, subareas|
26 | area_exists = Area.find_by(area: area_name)
27 | next unless !Area.all.exists? || !area_exists
28 |
29 | area = Area.create(area: area_name)
30 | subareas.each { |subarea_name| Subarea.create(subarea: subarea_name, area_id: area.id) }
31 | Subarea.create(subarea: 'Outro', area_id: area.id)
32 | end
33 |
34 | unless Area.find_by(area: 'Outro')
35 | area = Area.create(area: 'Outro')
36 | Subarea.create(subarea: 'Outro', area_id: area.id)
37 | end
38 |
39 | module BRPopulate
40 | def self.states
41 | http = Net::HTTP.new('raw.githubusercontent.com', 443)
42 | http.use_ssl = true
43 | JSON.parse http.get('/celsodantas/br_populate/master/states.json').body
44 | end
45 |
46 | def self.capital?(city, state)
47 | city['name'] == state['capital']
48 | end
49 |
50 | def self.populate
51 | states.each do |state|
52 | state_obj = State.new(acronym: state['acronym'], name: state['name'])
53 | state_obj.save
54 |
55 | state['cities'].each do |city|
56 | c = City.new
57 | c.name = city['name']
58 | c.state = state_obj
59 | c.save
60 | end
61 | end
62 | end
63 | end
64 |
65 | BRPopulate.populate
66 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | db:
4 | image: postgres
5 | volumes:
6 | - ./tmp/db:/var/lib/postgresql/data
7 | web:
8 | build: .
9 | command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
10 | volumes:
11 | - .:/transervicos
12 | ports:
13 | - "3000:3000"
14 | depends_on:
15 | - db
16 |
--------------------------------------------------------------------------------
/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | # Remove a potentially pre-existing server.pid for Rails.
5 | rm -f /transervicos/tmp/pids/server.pid
6 |
7 | # Then exec the container's main process (what's set as CMD in the Dockerfile).
8 | exec "$@"
9 |
--------------------------------------------------------------------------------
/lib/assets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/lib/assets/.keep
--------------------------------------------------------------------------------
/lib/tasks/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/lib/tasks/.keep
--------------------------------------------------------------------------------
/lib/templates/erb/scaffold/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%# frozen_string_literal: true %>
2 | <%%= simple_form_for(@<%= singular_table_name %>) do |f| %>
3 | <%%= f.error_notification %>
4 | <%%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
5 |
6 |
7 | <%- attributes.each do |attribute| -%>
8 | <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
9 | <%- end -%>
10 |
11 |
12 |
13 | <%%= f.button :submit %>
14 |
15 | <%% end %>
16 |
--------------------------------------------------------------------------------
/log/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/log/.keep
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "transervicos",
3 | "private": true,
4 | "scripts": {
5 | "build": "./bin/webpack",
6 | "test": "mocha"
7 | },
8 | "dependencies": {
9 | "@rails/webpacker": "3.5",
10 | "babel": "^6.23.0",
11 | "chai": "^4.2.0",
12 | "mocha": "^5.2.0",
13 | "vue": "^2.6.9",
14 | "vue-loader": "14.2.2",
15 | "vue-template-compiler": "^2.6.9"
16 | },
17 | "devDependencies": {
18 | "webpack-dev-server": "3.1.11"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The page you were looking for doesn't exist.
62 |
You may have mistyped the address or the page may have moved.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
The change you wanted was rejected.
62 |
Maybe you tried to change something you didn't have access to.
63 |
64 |
If you are the application owner check the logs for more information.
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
6 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
We're sorry, but something went wrong.
62 |
63 |
If you are the application owner check the logs for more information.
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/public/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/public/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/public/favicon.ico
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 |
--------------------------------------------------------------------------------
/spec/features/visitor_create_an_account_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | feature 'Visitor create an account' do
6 | scenario 'successfully' do
7 | visit root_path
8 | click_on 'cadastre-se'
9 | fill_in 'Nome', with: 'Austin Smith'
10 | fill_in 'Data de nascimento', with: '01/01/1980'
11 | fill_in 'Senha', with: '12345678'
12 | fill_in 'Senha (confirmação)', with: '12345678'
13 | fill_in 'Endereço de e-mail', with: 'austin@email.com'
14 | check 'Aceito os termos de uso'
15 | click_on 'Cadastrar'
16 |
17 | expect(page).to have_css('h1.panel-title', text: 'Olá, Austin Smith')
18 | expect(page).to have_css('div.sem-servicos p',
19 | text: 'Você ainda não cadastrou nenhum serviço.')
20 | expect(page).to have_link('Cadastre o primeiro!', href: new_service_path)
21 | end
22 |
23 | scenario 'and should be older than 18' do
24 | birth_date = 17.years.ago.strftime('%d/%m/%Y')
25 | visit root_path
26 | click_on 'cadastre-se'
27 | fill_in 'Nome', with: 'Austin Smith'
28 | fill_in 'Data de nascimento', with: birth_date
29 | fill_in 'Senha', with: '12345678'
30 | fill_in 'Senha (confirmação)', with: '12345678'
31 | fill_in 'Endereço de e-mail', with: 'austin@email.com'
32 | check 'Aceito os termos de uso'
33 | click_on 'Cadastrar'
34 |
35 | expect(page).to have_content('É preciso ser maior de idade')
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/spec/features/visitor_visit_root_path_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | feature 'Visitor visit root path' do
6 | scenario 'successfully' do
7 | visit root_path
8 | expect(page).to have_css('header#main-header img[src*=transervicos-logo]')
9 | expect(page).to have_link('cadastre-se', href: new_user_registration_path)
10 | expect(page).to have_link('busque serviço', href: services_path)
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/models/address_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe Address, type: :model do
6 | describe 'associations' do
7 | it { should belong_to(:service) }
8 | it { should belong_to(:state) }
9 | it { should belong_to(:city) }
10 | end
11 |
12 | describe 'attributes' do
13 | it { should accept_nested_attributes_for(:city) }
14 | it { should accept_nested_attributes_for(:state) }
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/spec/models/area_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe Area do
6 | describe 'associations' do
7 | it { should have_many(:subareas) }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/models/city_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe City do
6 | describe 'associations' do
7 | it { should belong_to(:state) }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/models/report_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe Report do
6 | describe 'associations' do
7 | it { should belong_to(:service) }
8 | end
9 |
10 | describe 'validations' do
11 | it { should validate_presence_of(:detail) }
12 | it { should validate_presence_of(:service) }
13 | it { should validate_presence_of(:email) }
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/models/service_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe Service do
6 | describe 'associations' do
7 | it { should have_one(:address) }
8 | it { should belong_to(:subarea) }
9 | it { should belong_to(:user) }
10 | it { should accept_nested_attributes_for(:address) }
11 | end
12 |
13 | describe 'validations' do
14 | it { should validate_presence_of(:subarea) }
15 | it { should validate_presence_of(:address) }
16 | it { should validate_presence_of(:name) }
17 | it { should validate_presence_of(:description) }
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/spec/models/state_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe State do
6 | describe 'associations' do
7 | it { should have_many(:cities) }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/models/subarea_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe Subarea do
6 | describe 'associations' do
7 | it { should belong_to(:area) }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/models/user_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe User do
6 | describe 'associations' do
7 | it { should have_many(:services) }
8 | end
9 |
10 | describe 'validations' do
11 | it { should validate_presence_of(:social_name) }
12 | it { should validate_presence_of(:birth_date) }
13 | it { should validate_uniqueness_of(:username) }
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/models/votin_session_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe VotingSession do
6 | end
7 |
--------------------------------------------------------------------------------
/spec/rails_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # This file is copied to spec/ when you run 'rails generate rspec:install'
4 | require 'spec_helper'
5 | ENV['RAILS_ENV'] ||= 'test'
6 | require File.expand_path('../config/environment', __dir__)
7 | # Prevent database truncation if the environment is production
8 | abort('The Rails environment is running in production mode!') if Rails.env.production?
9 | require 'rspec/rails'
10 | # Add additional requires below this line. Rails is not loaded until this point!
11 | require 'simplecov'
12 | SimpleCov.start 'rails'
13 | # Requires supporting ruby files with custom matchers and macros, etc, in
14 | # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
15 | # run as spec files by default. This means that files in spec/support that end
16 | # in _spec.rb will both be required and run as specs, causing the specs to be
17 | # run twice. It is recommended that you do not name files matching this glob to
18 | # end with _spec.rb. You can configure this pattern with the --pattern
19 | # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
20 | #
21 | # The following line is provided for convenience purposes. It has the downside
22 | # of increasing the boot-up time by auto-requiring all files in the support
23 | # directory. Alternatively, in the individual `*_spec.rb` files, manually
24 | # require only the support files necessary.
25 | #
26 | # Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
27 |
28 | # Checks for pending migrations and applies them before tests are run.
29 | # If you are not using ActiveRecord, you can remove these lines.
30 | begin
31 | ActiveRecord::Migration.maintain_test_schema!
32 | rescue ActiveRecord::PendingMigrationError => e
33 | puts e.to_s.strip
34 | exit 1
35 | end
36 | RSpec.configure do |config|
37 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
38 | config.fixture_path = "#{::Rails.root}/spec/fixtures"
39 |
40 | Shoulda::Matchers.configure do |config|
41 | config.integrate do |with|
42 | with.test_framework :rspec
43 | with.library :rails
44 | end
45 | end
46 | # If you're not using ActiveRecord, or you'd prefer not to run each of your
47 | # examples within a transaction, remove the following line or assign false
48 | # instead of true.
49 | config.use_transactional_fixtures = true
50 |
51 | # RSpec Rails can automatically mix in different behaviours to your tests
52 | # based on their file location, for example enabling you to call `get` and
53 | # `post` in specs under `spec/controllers`.
54 | #
55 | # You can disable this behaviour by removing the line below, and instead
56 | # explicitly tag your specs with their type, e.g.:
57 | #
58 | # RSpec.describe UsersController, :type => :controller do
59 | # # ...
60 | # end
61 | #
62 | # The different available types are documented in the features, such as in
63 | # https://relishapp.com/rspec/rspec-rails/docs
64 | config.infer_spec_type_from_file_location!
65 |
66 | # Filter lines from Rails gems in backtraces.
67 | config.filter_rails_from_backtrace!
68 | # arbitrary gems may also be filtered via:
69 | # config.filter_gems_from_backtrace("gem name")
70 | end
71 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # This file was generated by the `rails generate rspec:install` command. Conventionally, all
4 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5 | # The generated `.rspec` file contains `--require spec_helper` which will cause
6 | # this file to always be loaded, without a need to explicitly require it in any
7 | # files.
8 | #
9 | # Given that it is always loaded, you are encouraged to keep this file as
10 | # light-weight as possible. Requiring heavyweight dependencies from this file
11 | # will add to the boot time of your test suite on EVERY test run, even for an
12 | # individual file that may not need all of that loaded. Instead, consider making
13 | # a separate helper file that requires the additional dependencies and performs
14 | # the additional setup, and require it from the spec files that actually need
15 | # it.
16 | #
17 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
18 | RSpec.configure do |config|
19 | # rspec-expectations config goes here. You can use an alternate
20 | # assertion/expectation library such as wrong or the stdlib/minitest
21 | # assertions if you prefer.
22 | config.expect_with :rspec do |expectations|
23 | # This option will default to `true` in RSpec 4. It makes the `description`
24 | # and `failure_message` of custom matchers include text for helper methods
25 | # defined using `chain`, e.g.:
26 | # be_bigger_than(2).and_smaller_than(4).description
27 | # # => "be bigger than 2 and smaller than 4"
28 | # ...rather than:
29 | # # => "be bigger than 2"
30 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true
31 | end
32 |
33 | # rspec-mocks config goes here. You can use an alternate test double
34 | # library (such as bogus or mocha) by changing the `mock_with` option here.
35 | config.mock_with :rspec do |mocks|
36 | # Prevents you from mocking or stubbing a method that does not exist on
37 | # a real object. This is generally recommended, and will default to
38 | # `true` in RSpec 4.
39 | mocks.verify_partial_doubles = true
40 | end
41 |
42 | # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
43 | # have no way to turn it off -- the option exists only for backwards
44 | # compatibility in RSpec 3). It causes shared context metadata to be
45 | # inherited by the metadata hash of host groups and examples, rather than
46 | # triggering implicit auto-inclusion in groups with matching metadata.
47 | config.shared_context_metadata_behavior = :apply_to_host_groups
48 |
49 | # The settings below are suggested to provide a good initial experience
50 | # with RSpec, but feel free to customize to your heart's content.
51 | # # This allows you to limit a spec run to individual examples or groups
52 | # # you care about by tagging them with `:focus` metadata. When nothing
53 | # # is tagged with `:focus`, all examples get run. RSpec also provides
54 | # # aliases for `it`, `describe`, and `context` that include `:focus`
55 | # # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
56 | # config.filter_run_when_matching :focus
57 | #
58 | # # Allows RSpec to persist some state between runs in order to support
59 | # # the `--only-failures` and `--next-failure` CLI options. We recommend
60 | # # you configure your source control system to ignore this file.
61 | # config.example_status_persistence_file_path = "spec/examples.txt"
62 | #
63 | # # Limits the available syntax to the non-monkey patched syntax that is
64 | # # recommended. For more details, see:
65 | # # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
66 | # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
67 | # # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
68 | # config.disable_monkey_patching!
69 | #
70 | # # Many RSpec users commonly either run the entire suite or an individual
71 | # # file, and it's useful to allow more verbose output when running an
72 | # # individual spec file.
73 | # if config.files_to_run.one?
74 | # # Use the documentation formatter for detailed output,
75 | # # unless a formatter has already been configured
76 | # # (e.g. via a command-line flag).
77 | # config.default_formatter = "doc"
78 | # end
79 | #
80 | # # Print the 10 slowest examples and example groups at the
81 | # # end of the spec run, to help surface which specs are running
82 | # # particularly slow.
83 | # config.profile_examples = 10
84 | #
85 | # # Run specs in random order to surface order dependencies. If you find an
86 | # # order dependency and want to debug it, you can fix the order by providing
87 | # # the seed, which is printed after each run.
88 | # # --seed 1234
89 | # config.order = :random
90 | #
91 | # # Seed global randomization in this process using the `--seed` CLI option.
92 | # # Setting this allows you to use `--seed` to deterministically reproduce
93 | # # test failures related to randomization by passing the same `--seed` value
94 | # # as the one that triggered the failure.
95 | # Kernel.srand config.seed
96 | end
97 |
--------------------------------------------------------------------------------
/storage/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/storage/.keep
--------------------------------------------------------------------------------
/tmp/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juuh42dias/transervicos/a9247b1f516223720dc0389be5c79382d4796cf4/tmp/.keep
--------------------------------------------------------------------------------