diff --git a/.rspec b/.rspec
index 4e1e0d2f7..f26ef5abe 100644
--- a/.rspec
+++ b/.rspec
@@ -1 +1,2 @@
--color
+
diff --git a/.travis.yml b/.travis.yml
index c1d4bc930..cb294ec9c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,6 @@
language: ruby
+addons:
+ postgresql: "9.4"
rvm:
- "2.2.2"
cache: bundler
diff --git a/Gemfile b/Gemfile
index aeca43f64..de35b0b26 100644
--- a/Gemfile
+++ b/Gemfile
@@ -36,6 +36,9 @@ gem 'initialjs-rails'
gem 'unicorn'
gem 'paranoia'
+gem 'ahoy_matey', '~> 1.2.1'
+gem 'groupdate' # group temporary data
+
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug'
@@ -46,6 +49,7 @@ group :development, :test do
gem 'rspec-rails', '~> 3.0'
gem 'capybara'
gem 'factory_girl_rails'
+ gem 'fuubar'
gem 'launchy'
gem 'quiet_assets'
gem 'letter_opener_web', '~> 1.2.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index 92b372edc..2753c16ba 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -44,12 +44,23 @@ GEM
awesome_nested_set (>= 3.0)
acts_as_votable (0.10.0)
addressable (2.3.8)
+ ahoy_matey (1.2.1)
+ addressable
+ browser (>= 0.4.0)
+ errbase
+ geocoder
+ rails
+ referer-parser (>= 0.3.0)
+ request_store
+ user_agent_parser
+ uuidtools
arel (6.0.3)
awesome_nested_set (3.0.2)
activerecord (>= 4.0.0, < 5)
bcrypt (3.1.10)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
+ browser (0.9.1)
builder (3.2.2)
byebug (5.0.0)
columnize (= 0.9.0)
@@ -116,6 +127,7 @@ GEM
email_spec (1.6.0)
launchy (~> 2.1)
mail (~> 2.2)
+ errbase (0.0.3)
erubis (2.7.0)
execjs (2.5.2)
factory_girl (4.5.0)
@@ -132,8 +144,14 @@ GEM
activesupport (~> 4.1, >= 4.1.1)
railties (~> 4.1, >= 4.1.1)
tzinfo (~> 1.2, >= 1.2.2)
+ fuubar (2.0.0)
+ rspec (~> 3.0)
+ ruby-progressbar (~> 1.4)
+ geocoder (1.2.9)
globalid (0.3.6)
activesupport (>= 4.1.0)
+ groupdate (2.4.0)
+ activesupport (>= 3)
highline (1.7.3)
http-cookie (1.0.2)
domain_name (~> 0.5)
@@ -218,12 +236,18 @@ GEM
thor (>= 0.18.1, < 2.0)
raindrops (0.15.0)
rake (10.4.2)
+ referer-parser (0.3.0)
+ request_store (1.2.0)
responders (2.1.0)
railties (>= 4.2.0, < 5)
rest-client (1.8.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
+ rspec (3.3.0)
+ rspec-core (~> 3.3.0)
+ rspec-expectations (~> 3.3.0)
+ rspec-mocks (~> 3.3.0)
rspec-core (3.3.2)
rspec-support (~> 3.3.0)
rspec-expectations (3.3.1)
@@ -241,6 +265,7 @@ GEM
rspec-mocks (~> 3.3.0)
rspec-support (~> 3.3.0)
rspec-support (3.3.0)
+ ruby-progressbar (1.7.5)
sass (3.4.16)
sass-rails (5.0.3)
railties (>= 4.0.0, < 5.0)
@@ -291,6 +316,8 @@ GEM
kgio (~> 2.6)
rack
raindrops (~> 0.7)
+ user_agent_parser (2.2.0)
+ uuidtools (2.1.5)
warden (1.2.3)
rack (>= 1.0)
web-console (2.2.1)
@@ -311,6 +338,7 @@ DEPENDENCIES
acts-as-taggable-on
acts_as_commentable_with_threading
acts_as_votable
+ ahoy_matey (~> 1.2.1)
byebug
cancancan
capistrano (= 3.4.0)
@@ -327,6 +355,8 @@ DEPENDENCIES
factory_girl_rails
foundation-rails
foundation_rails_helper
+ fuubar
+ groupdate
i18n-tasks
initialjs-rails
jquery-rails
diff --git a/README.md b/README.md
index 1d8ef040d..9fe47f6ad 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ Las herramientas utilizadas para el frontend no están cerradas aún. Los estilo
## Configuración para desarrollo y tests
-Prerequisitos: tener instalado git, ImageMagick, Ruby 2.2.2, la gema `bundler`, y una librería moderna de PostgreSQL.
+Prerequisitos: tener instalado git, ImageMagick, Ruby 2.2.2, la gema `bundler`, y PostgreSQL (9.4 o superior).
```
cd participacion
diff --git a/README_EN.md b/README_EN.md
index e43be2875..40a39ae01 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -21,7 +21,7 @@ Frontend tools used include [SCSS](http://sass-lang.com/) over [Foundation](http
## Configuration for development and test environments
-Prerequisites: install git, ImageMagick, Ruby 2.2.2, bundler gem and PostgreSQL.
+Prerequisites: install git, ImageMagick, Ruby 2.2.2, bundler gem and PostgreSQL (>=9.4).
```
cd participacion
diff --git a/app/assets/fonts/icons.eot b/app/assets/fonts/icons.eot
index 166eca82e..069a97a8b 100644
Binary files a/app/assets/fonts/icons.eot and b/app/assets/fonts/icons.eot differ
diff --git a/app/assets/fonts/icons.svg b/app/assets/fonts/icons.svg
index 498eb27a7..8532ba86c 100644
--- a/app/assets/fonts/icons.svg
+++ b/app/assets/fonts/icons.svg
@@ -21,4 +21,5 @@
+
diff --git a/app/assets/fonts/icons.ttf b/app/assets/fonts/icons.ttf
index 285caed39..37dde64ba 100644
Binary files a/app/assets/fonts/icons.ttf and b/app/assets/fonts/icons.ttf differ
diff --git a/app/assets/fonts/icons.woff b/app/assets/fonts/icons.woff
index 02c11f23e..aeda5c384 100644
Binary files a/app/assets/fonts/icons.woff and b/app/assets/fonts/icons.woff differ
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 11bbe4cad..e630af974 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -17,6 +17,10 @@
//= require ckeditor/init
//= require social-share-button
//= require initial
+//= require ahoy
+//= require d3
+//= require c3
+//= require c3ext
//= require app
//= require_tree .
@@ -25,6 +29,7 @@ var initialize_modules = function() {
App.Users.initialize();
App.Votes.initialize();
App.Tags.initialize();
+ App.Stats.initialize();
};
$(function(){
diff --git a/app/assets/javascripts/stats.js.coffee b/app/assets/javascripts/stats.js.coffee
new file mode 100644
index 000000000..7fcdfb00a
--- /dev/null
+++ b/app/assets/javascripts/stats.js.coffee
@@ -0,0 +1,11 @@
+# Helper for generate C3.js graphs
+#----------------------------------------------------------------------
+
+buildGraph = (el) ->
+ url = $(el).data 'graph'
+ conf = bindto: el, data: {x: 'x', url: url, mimeType: 'json'}, axis: { x: {type: 'timeseries',tick: { format: '%Y-%m-%d' } }}
+ graph = c3.generate conf
+
+App.Stats =
+ initialize: ->
+ buildGraph(g) for g in $("[data-graph]")
diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss
new file mode 100644
index 000000000..f35811ecf
--- /dev/null
+++ b/app/assets/stylesheets/admin.scss
@@ -0,0 +1,153 @@
+// Table of Contents
+//
+// 01. Global styles
+// 02. Sidebar
+// 03. List elements
+//
+
+// 01. Global styles
+// - - - - - - - - - - - - - - - - - - - - - - - - -
+
+body.admin {
+ background: white;
+
+ h2 {
+ font-size: rem-calc(24);
+ font-weight: bold;
+ }
+
+ form {
+ .button {
+ margin-top: 0;
+ }
+ }
+
+ .button.secondary {
+ margin-right: rem-calc(12);
+ }
+
+ .button.create {
+ background: #EFD90C;
+ color: $text;
+
+ &:hover {
+ background: #BDAB09;
+ }
+ }
+
+ .admin-content {
+ margin-top: rem-calc(24);
+ }
+
+ .is-featured {
+ margin-top: rem-calc(36);
+ }
+}
+
+// 02. Sidebar
+// - - - - - - - - - - - - - - - - - - - - - - - - -
+
+.admin-sidebar {
+ margin-left: rem-calc(-15);
+ margin-top: rem-calc(-48);
+
+ ul {
+ list-style-type: none;
+ margin-left: 0;
+ padding: 0;
+
+ [class^="icon-"] {
+ display: inline-block;
+ font-size: rem-calc(24);
+ padding-right: rem-calc(24);
+ padding-top: rem-calc(4);
+ }
+
+ li {
+ background: #2E343F;
+ border-bottom: 1px solid #292f39;
+ border-top: 1px solid #353c49;
+ margin: 0;
+ outline: 0;
+
+ &:first-child {
+ background: #2B3139;
+ color: rgba(255,255,255,0.3);
+ padding: rem-calc(24) rem-calc(12);
+ text-transform: uppercase;
+ }
+
+ &.active{
+ background: #373D47;
+
+ a:not(.button) {
+ color: white;
+ }
+ }
+ }
+
+ li a:not(.button) {
+ color: rgba(255,255,255,0.3);
+ line-height: rem-calc(48);
+ padding-left: rem-calc(12);
+ vertical-align: top;
+
+ &:hover {
+ color: white;
+ }
+ }
+ }
+}
+
+// 03. List elements
+// - - - - - - - - - - - - - - - - - - - - - - - - -
+
+.admin-list {
+ list-style-type: none;
+ margin: 0;
+
+ form {
+ clear: both;
+
+ .checkbox {
+ font-size: rem-calc(12);
+ }
+ }
+
+ li {
+ border-bottom: 1px solid #E7E9EC;
+ font-size: rem-calc(14);
+ min-height: rem-calc(72);
+ padding: rem-calc(12);
+
+ &:first-child {
+ border-top: 1px solid #E7E9EC;
+ }
+
+ &:nth-child(odd) {
+ background: #F0F2F6;
+ }
+ }
+
+ .tag {
+ float: left;
+ font-size: rem-calc(18);
+ padding: 0;
+ }
+
+ .button {
+ margin: 0;
+ }
+}
+
+.delete {
+ border-bottom: 1px dotted #CF2A0E;
+ color: #F04124;
+ font-size: rem-calc(11);
+ margin-right: rem-calc(12);
+
+ &:hover, &:active, &:focus {
+ border: 0;
+ color: #cf2a0e;
+ }
+}
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index e4379397e..48bfdc7b4 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -6,5 +6,7 @@
@import "fonts";
@import "icons";
@import "variables";
+@import "admin";
@import "participacion";
@import "debates";
+@import "c3";
diff --git a/app/assets/stylesheets/debates.scss b/app/assets/stylesheets/debates.scss
index afc99b75a..c8b40f0c3 100644
--- a/app/assets/stylesheets/debates.scss
+++ b/app/assets/stylesheets/debates.scss
@@ -138,10 +138,6 @@
// 02. Index
// - - - - - - - - - - - - - - - - - - - - - - - - -
-.featured-debates {
- margin-top: rem-calc(23);
-}
-
.debate-featured {
.panel {
@@ -244,7 +240,6 @@
.debates-list {
margin-bottom: rem-calc(48);
- margin-top: rem-calc(24);
}
.debate {
diff --git a/app/assets/stylesheets/icons.scss b/app/assets/stylesheets/icons.scss
index cfebe4e83..616c037cd 100644
--- a/app/assets/stylesheets/icons.scss
+++ b/app/assets/stylesheets/icons.scss
@@ -79,3 +79,6 @@
.icon-star:before {
content: "n";
}
+.icon-eye:before {
+ content: "p";
+}
diff --git a/app/assets/stylesheets/participacion.scss b/app/assets/stylesheets/participacion.scss
index 710fb8c6d..d6490f4ae 100644
--- a/app/assets/stylesheets/participacion.scss
+++ b/app/assets/stylesheets/participacion.scss
@@ -10,6 +10,7 @@
// 08. Forms
// 09. Alerts
// 10. User account
+// 11. Filters
//
// 01. Variables
@@ -111,7 +112,6 @@ h1, h2, h3, h4, h5, h6 {
}
.sidebar {
- margin-top: rem-calc(24);
margin-bottom: rem-calc(48);
}
@@ -585,3 +585,36 @@ form {
}
}
}
+
+// 11. Filters
+// - - - - - - - - - - - - - - - - - - - - - - - - -
+
+.filters {
+
+ h2 {
+ display: inline-block;
+ font-size: rem-calc(24);
+ margin: rem-calc(24) 0;
+ }
+
+ select {
+ height: auto;
+ margin: rem-calc(24) rem-calc(6);
+ min-width: rem-calc(180);
+ outline: 0;
+ padding: rem-calc(12);
+ width: auto;
+
+ optgroup {
+ font-size: rem-calc(14);
+ }
+
+ option {
+
+ &:after {
+ content: "a";
+ font-family: "icons";
+ }
+ }
+ }
+}
diff --git a/app/controllers/admin/officials_controller.rb b/app/controllers/admin/officials_controller.rb
new file mode 100644
index 000000000..023f0f7fc
--- /dev/null
+++ b/app/controllers/admin/officials_controller.rb
@@ -0,0 +1,32 @@
+class Admin::OfficialsController < Admin::BaseController
+
+ def index
+ @officials = User.officials.page(params[:page])
+ end
+
+ def search
+ @users = User.with_email(params[:email]).page(params[:page])
+ end
+
+ def edit
+ @user = User.find(params[:id])
+ end
+
+ def update
+ @user = User.find(params[:id])
+ @user.update(user_params)
+ redirect_to admin_officials_path, notice: t("admin.officials.flash.official_updated")
+ end
+
+ def destroy
+ @official = User.officials.find(params[:id])
+ @official.remove_official_position!
+ redirect_to admin_officials_path, notice: t("admin.officials.flash.official_destroyed")
+ end
+
+ private
+ def user_params
+ params.require(:user).permit(:official_position, :official_level)
+ end
+
+end
\ No newline at end of file
diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb
new file mode 100644
index 000000000..b369d2cbc
--- /dev/null
+++ b/app/controllers/admin/settings_controller.rb
@@ -0,0 +1,17 @@
+class Admin::SettingsController < Admin::BaseController
+
+ def index
+ @settings = Setting.all
+ end
+
+ def update
+ @setting = Setting.find(params[:id])
+ @setting.update(settings_params)
+ redirect_to admin_settings_path, notice: t("admin.settings.flash.updated")
+ end
+
+ private
+ def settings_params
+ params.require(:setting).permit(:value)
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/api/api_controller.rb b/app/controllers/api/api_controller.rb
new file mode 100644
index 000000000..a7d0c1ea7
--- /dev/null
+++ b/app/controllers/api/api_controller.rb
@@ -0,0 +1,13 @@
+class Api::ApiController < ApplicationController
+ before_action :authenticate_user!
+ protect_from_forgery with: :null_session
+
+ skip_authorization_check
+ before_action :verify_administrator
+
+ private
+
+ def verify_administrator
+ raise CanCan::AccessDenied unless current_user.try(:administrator?)
+ end
+end
diff --git a/app/controllers/api/stats_controller.rb b/app/controllers/api/stats_controller.rb
new file mode 100644
index 000000000..d44262b45
--- /dev/null
+++ b/app/controllers/api/stats_controller.rb
@@ -0,0 +1,22 @@
+class Api::StatsController < Api::ApiController
+ def show
+ unless params[:events].present? || params[:visits].present?
+ return render json: {}, status: :bad_request
+ end
+
+ ds = Ahoy::DataSource.new
+
+ if params[:events].present?
+ event_types = params[:events].split ','
+ event_types.each do |event|
+ ds.add event.titleize, Ahoy::Event.where(name: event).group_by_day(:time).count
+ end
+ end
+
+ if params[:visits].present?
+ ds.add "Visits", Visit.group_by_day(:started_at).count
+ end
+
+ render json: ds.build
+ end
+end
diff --git a/app/controllers/debates_controller.rb b/app/controllers/debates_controller.rb
index eeb82825a..690ef62ea 100644
--- a/app/controllers/debates_controller.rb
+++ b/app/controllers/debates_controller.rb
@@ -26,7 +26,9 @@ class DebatesController < ApplicationController
def create
@debate = Debate.new(debate_params)
@debate.author = current_user
+
if @debate.save_with_captcha
+ ahoy.track :debate_created, debate_id: @debate.id
redirect_to @debate, notice: t('flash.actions.create.notice', resource_name: 'Debate')
else
load_featured_tags
diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb
new file mode 100644
index 000000000..1e76feb42
--- /dev/null
+++ b/app/controllers/stats_controller.rb
@@ -0,0 +1,14 @@
+class StatsController < ApplicationController
+ skip_authorization_check
+ before_action :verify_administrator
+
+ def show
+ @event_types = Ahoy::Event.select(:name).uniq.pluck(:name)
+ end
+
+ private
+
+ def verify_administrator
+ raise CanCan::AccessDenied unless current_user.try(:administrator?)
+ end
+end
diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb
index a7fef3aa2..09d325e08 100644
--- a/app/helpers/admin_helper.rb
+++ b/app/helpers/admin_helper.rb
@@ -4,6 +4,14 @@ module AdminHelper
render "/#{namespace}/menu"
end
+ def official_level_options
+ options = []
+ (0..5).each do |i|
+ options << [[t("admin.officials.level_#{i}"), Setting.value_for("official_level_#{i}_name")].compact.join(': '), i]
+ end
+ options
+ end
+
private
def namespace
diff --git a/app/helpers/stats_helper.rb b/app/helpers/stats_helper.rb
new file mode 100644
index 000000000..e517767e3
--- /dev/null
+++ b/app/helpers/stats_helper.rb
@@ -0,0 +1,16 @@
+module StatsHelper
+ def events_chart_tag(events, opt={})
+ events = events.join(',') if events.is_a? Array
+ opt[:data] ||= {}
+ opt[:data][:graph] = api_stats_path(events: events)
+ content_tag :div, "", opt
+ end
+
+ def visits_chart_tag(opt={})
+ events = events.join(',') if events.is_a? Array
+ opt[:data] ||= {}
+ opt[:data][:graph] = api_stats_path(visits: true)
+ content_tag :div, "", opt
+ end
+
+end
diff --git a/app/models/ahoy/data_source.rb b/app/models/ahoy/data_source.rb
new file mode 100644
index 000000000..2d52063bb
--- /dev/null
+++ b/app/models/ahoy/data_source.rb
@@ -0,0 +1,49 @@
+# This class combines multiple collections with shared keys into a
+# hash of collections compatible with C3.js charts
+#----------------------------------------------------------------------
+
+module Ahoy
+ class DataSource
+
+ # Adds a collection with the datasource
+ # Name is the name of the collection and will be showed in the
+ # chart
+ def add(name, collection)
+ collections.push data: collection, name: name
+ collection.each{ |k,v| add_key k }
+ end
+
+ def build
+ data = { x: [] }
+ keys.each do |k|
+ # Add the key with a valid date format
+ data[:x].push k.strftime("%Y-%m-%d")
+
+ # Add the value for each column, or 0 if not present
+ collections.each do |col|
+ data[col[:name]] ||= []
+ count = col[:data][k] || 0
+ data[col[:name]].push count
+ end
+ end
+
+ return data
+ end
+
+ private
+
+ def collections
+ @collections ||= []
+ end
+
+ def keys
+ @keys ||= []
+ end
+
+ def add_key(key)
+ keys.push(key) unless keys.include? key
+ end
+
+ end
+
+end
diff --git a/app/models/ahoy/event.rb b/app/models/ahoy/event.rb
new file mode 100644
index 000000000..2aac3c59c
--- /dev/null
+++ b/app/models/ahoy/event.rb
@@ -0,0 +1,8 @@
+module Ahoy
+ class Event < ActiveRecord::Base
+ self.table_name = "ahoy_events"
+
+ belongs_to :visit
+ belongs_to :user
+ end
+end
diff --git a/app/models/debate.rb b/app/models/debate.rb
index e029ffdd4..7d39384d5 100644
--- a/app/models/debate.rb
+++ b/app/models/debate.rb
@@ -22,6 +22,9 @@ class Debate < ActiveRecord::Base
before_validation :sanitize_description
before_validation :sanitize_tag_list
+ # Ahoy setup
+ visitable # Ahoy will automatically assign visit_id on create
+
def self.search(params)
if params[:tag]
tagged_with(params[:tag])
diff --git a/app/models/setting.rb b/app/models/setting.rb
new file mode 100644
index 000000000..1a52ebe60
--- /dev/null
+++ b/app/models/setting.rb
@@ -0,0 +1,7 @@
+class Setting < ActiveRecord::Base
+ default_scope { order(key: :desc) }
+
+ def self.value_for(key)
+ where(key: key).pluck(:value).first
+ end
+end
\ No newline at end of file
diff --git a/app/models/user.rb b/app/models/user.rb
index 764454874..ba4b32fa9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -12,6 +12,7 @@ class User < ActiveRecord::Base
validates :first_name, presence: true, if: :use_first_name?
validates :last_name, presence: true, if: :use_last_name?
validates :nickname, presence: true, if: :use_nickname?
+ validates :official_level, inclusion: {in: 0..5}
validates_associated :organization, message: false
@@ -20,9 +21,7 @@ class User < ActiveRecord::Base
scope :administrators, -> { joins(:administrators) }
scope :moderators, -> { joins(:moderator) }
scope :organizations, -> { joins(:organization) }
-
- attr_accessor :organization_name
- attr_accessor :is_organization
+ scope :officials, -> { where("official_level > 0") }
def name
return nickname if use_nickname?
@@ -47,6 +46,23 @@ class User < ActiveRecord::Base
organization.present?
end
+ def official?
+ official_level && official_level > 0
+ end
+
+ def add_official_position!(position, level)
+ return if position.blank? || level.blank?
+ update official_position: position, official_level: level.to_i
+ end
+
+ def remove_official_position!
+ update official_position: nil, official_level: 0
+ end
+
+ def self.with_email(e)
+ e.present? ? where(email: e) : none
+ end
+
private
def use_first_name?
!organization? && !use_nickname?
diff --git a/app/models/visit.rb b/app/models/visit.rb
new file mode 100644
index 000000000..6bb47fed0
--- /dev/null
+++ b/app/models/visit.rb
@@ -0,0 +1,4 @@
+class Visit < ActiveRecord::Base
+ has_many :ahoy_events, class_name: "Ahoy::Event"
+ belongs_to :user
+end
diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb
index a6a05ab32..585ca41a0 100644
--- a/app/views/admin/_menu.html.erb
+++ b/app/views/admin/_menu.html.erb
@@ -1,6 +1,56 @@
-
+
diff --git a/app/views/admin/comments/index.html.erb b/app/views/admin/comments/index.html.erb
index 1555fda0c..9c52d8834 100644
--- a/app/views/admin/comments/index.html.erb
+++ b/app/views/admin/comments/index.html.erb
@@ -1,14 +1,18 @@
-
-
<%= t("admin.comments.index.title") %>
+
<%= t("admin.comments.index.title") %>
-
- <% @comments.each do |comment| %>
-
- <% end %>
-
-
+
+ <% @comments.each do |comment| %>
+
+ <% end %>
+
diff --git a/app/views/admin/dashboard/index.html.erb b/app/views/admin/dashboard/index.html.erb
index ffc8a281a..8cea6ce36 100644
--- a/app/views/admin/dashboard/index.html.erb
+++ b/app/views/admin/dashboard/index.html.erb
@@ -1 +1,5 @@
-<%= t("admin.dashboard.index.title") %>
+<%= t("admin.dashboard.index.title") %>
+
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+
+Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.
diff --git a/app/views/admin/debates/index.html.erb b/app/views/admin/debates/index.html.erb
index ce07205b3..e7e1e5753 100644
--- a/app/views/admin/debates/index.html.erb
+++ b/app/views/admin/debates/index.html.erb
@@ -1,13 +1,13 @@
-
-
<%= t("admin.debates.index.title") %>
+
<%= t("admin.debates.index.title") %>
-
- <% @debates.each do |debate| %>
- <%= link_to admin_debate_path(debate) do %>
-
- <%= link_to debate.title, admin_debate_path(debate) %>
-
- <% end %>
- <% end %>
-
-
\ No newline at end of file
+
+ <% @debates.each do |debate| %>
+
+ <%= link_to debate.title, admin_debate_path(debate) %>
+
+ <%= link_to t("admin.actions.restore"), restore_admin_debate_path(debate),
+ method: :put, data: { confirm: t("admin.actions.confirm") },
+ class: "button radius tiny success right" %>
+
+ <% end %>
+
diff --git a/app/views/admin/debates/show.html.erb b/app/views/admin/debates/show.html.erb
index aaa22eec9..e740baf47 100644
--- a/app/views/admin/debates/show.html.erb
+++ b/app/views/admin/debates/show.html.erb
@@ -1,13 +1,12 @@
-
-
<%= t("admin.debates.index.title") %>
+
<%= t("admin.debates.index.title") %>
-
-
<%= @debate.title %>
-
<%= @debate.description %>
+
<%= @debate.title %>
-
- <%= link_to t('admin.actions.restore'), restore_admin_debate_path(@debate),
- method: :put, data: { confirm: t('admin.actions.confirm') } %>
-
-
-
\ No newline at end of file
+<%= @debate.description %>
+
+<%= link_to t("admin.debates.show.back"), admin_debates_path,
+ class: "button radius small secondary" %>
+
+<%= link_to t("admin.actions.restore"), restore_admin_debate_path(@debate),
+ method: :put, data: { confirm: t("admin.actions.confirm") },
+ class: "button radius small success" %>
diff --git a/app/views/admin/officials/edit.html.erb b/app/views/admin/officials/edit.html.erb
new file mode 100644
index 000000000..b986df2b5
--- /dev/null
+++ b/app/views/admin/officials/edit.html.erb
@@ -0,0 +1,14 @@
+<%= t("admin.officials.edit.title") %>
+
+<%= @user.name %> (<%= @user.email %>)
+<%= form_for @user, url: admin_official_path(@user) do |f| %>
+ <%= f.text_field :official_position %>
+ <%= f.select :official_level, official_level_options %>
+ <%= f.submit %>
+
+ <% if @user.official? %>
+ <%= link_to t("admin.officials.edit.destroy"), admin_official_path(@user), method: :delete, class: 'button tiny alert' %>
+ <% else %>
+ <%= link_to t("admin.officials.edit.cancel"), admin_officials_path, class: 'button tiny alert' %>
+ <% end %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/admin/officials/index.html.erb b/app/views/admin/officials/index.html.erb
new file mode 100644
index 000000000..d0a98a963
--- /dev/null
+++ b/app/views/admin/officials/index.html.erb
@@ -0,0 +1,25 @@
+<%= t("admin.officials.index.title") %>
+
+
+<%= form_for(User.new, url: search_admin_officials_path, as: :user, method: :get) do |f| %>
+ <%= text_field_tag :email, "", label: false, placeholder: t("admin.officials.index.search_email_placeholder") %>
+ <%= f.submit t("admin.officials.index.search") %>
+<% end %>
+
+
+
+<%= page_entries_info @officials %>
+
+
+
+<% @officials.each do |official| %>
+ <%= link_to official.name, edit_admin_official_path(official) %>
+ <%= official.official_position %>
+ <%= t("admin.officials.level_#{official.official_level}") %>
+
+<% end %>
+
+
+
+<%= paginate @officials %>
+
\ No newline at end of file
diff --git a/app/views/admin/officials/search.html.erb b/app/views/admin/officials/search.html.erb
new file mode 100644
index 000000000..9549c7ad0
--- /dev/null
+++ b/app/views/admin/officials/search.html.erb
@@ -0,0 +1,21 @@
+<%= t("admin.officials.search.title") %>
+
+
+<%= form_for(User.new, url: search_admin_officials_path, as: :user, method: :get) do |f| %>
+ <%= text_field_tag :email, "", label: false, placeholder: t("admin.officials.index.search_email_placeholder") %>
+ <%= f.submit t("admin.officials.search.search") %>
+<% end %>
+
+
+
+<%= page_entries_info @users %>
+
+
+
+<% @users.each do |user| %>
+ <%= link_to user.name, edit_admin_official_path(user) %>
+ <%= user.official_position %>
+ <%= t("admin.officials.level_#{user.official_level}") %>
+ <%= link_to user.official? ? t("admin.officials.search.edit_official") : t("admin.officials.search.make_official"), edit_admin_official_path(user) %>
+<% end %>
+
\ No newline at end of file
diff --git a/app/views/admin/settings/index.html.erb b/app/views/admin/settings/index.html.erb
new file mode 100644
index 000000000..321b307d0
--- /dev/null
+++ b/app/views/admin/settings/index.html.erb
@@ -0,0 +1,15 @@
+<%= t("admin.settings.index.title") %>
+
+
+ <% @settings.each do |setting| %>
+
+ <%= setting.key.classify %>
+
+ <%= form_for(setting, url: admin_setting_path(setting), html: { id: "edit_#{dom_id(setting)}"}) do |f| %>
+ <%= f.text_field :value, label: false, id: dom_id(setting) %>
+ <%= f.submit(class: "button radius tiny") %>
+ <% end %>
+
+
+ <% end %>
+
\ No newline at end of file
diff --git a/app/views/admin/tags/index.html.erb b/app/views/admin/tags/index.html.erb
index 4dbbed167..06d9e2385 100644
--- a/app/views/admin/tags/index.html.erb
+++ b/app/views/admin/tags/index.html.erb
@@ -1,29 +1,46 @@
-
-
<%= t("admin.tags.index.add_tag") %>
+
<%= t("admin.tags.index.add_tag") %>
- <%= form_for(@tag, url: admin_tags_path, as: :tag) do |f| %>
- <%= f.text_field :name, placeholder: t("admin.tags.name.placeholder") %>
- <%= f.check_box :featured, label: false %>
- <%= t("admin.tags.mark_as_featured") %>
- <%= f.submit(class: "button radius small") %>
- <% end %>
+<%= form_for(@tag, url: admin_tags_path, as: :tag) do |f| %>
+
+
+ <%= f.label :name, t("admin.tags.name.placeholder") %>
+ <%= f.text_field :name, placeholder: t("admin.tags.name.placeholder"), label: false %>
+
-
<%= t("admin.tags.index.title") %>
+
+ <%= f.label :featured do %>
+ <%= f.check_box :featured, label: false %>
+ <%= t("admin.tags.mark_as_featured") %>
+ <% end %>
+
+
-
- <% @tags.each do |tag| %>
-
- <%= tag.name %>
+ <%= f.submit(class: "button radius create") %>
- <%= form_for(tag, url: admin_tag_path(tag), as: :tag, html: { id: "edit_tag_#{tag.id}"}) do |f| %>
- <%= f.check_box :featured, label: false, id: "tag_featured_#{tag.id}" %>
- <%= t("admin.tags.mark_as_featured") %>
- <%= f.submit(class: "button radius tiny") %>
- <%= link_to t("admin.tags.destroy"), admin_tag_path(tag), method: :delete, class: 'button tiny alert' %>
+<% end %>
+
+<%= t("admin.tags.index.title") %>
+
+
+ <% @tags.each do |tag| %>
+
+ <%= tag.name %>
+
+ <%= form_for(tag,
+ url: admin_tag_path(tag),
+ as: :tag,
+ html: { id: "edit_tag_#{tag.id}", class: "text-right"}) do |f| %>
+
+ <%= f.label "featured_#{tag.id}" do %>
+ <%= f.check_box :featured, label: false, id: "tag_featured_#{tag.id}", class: "left" %>
+ <%= t("admin.tags.mark_as_featured") %>
<% end %>
-
- <% end %>
-
-
+ <%= f.submit(class: "button radius tiny success") %>
+
+ <%= link_to t("admin.tags.destroy"), admin_tag_path(tag), method: :delete, class: "delete" %>
+ <% end %>
+
+ <% end %>
+
diff --git a/app/views/debates/index.html.erb b/app/views/debates/index.html.erb
index 3a3881b76..0e3e41d1d 100644
--- a/app/views/debates/index.html.erb
+++ b/app/views/debates/index.html.erb
@@ -1,6 +1,79 @@
+
+
+
+
+
<%= t("debates.index.showing") %>
+
+
+
+ <%= t("debates.index.filter_debates") %>
+
+
+ <%= t("debates.index.filter_initiatives") %>
+
+
+ <%= t("debates.index.filter_debates_and_initiatives") %>
+
+
+
+
+
+ <%= t("debates.index.filter_news") %>
+
+
+ <%= t("debates.index.filter_votes") %>
+
+
+ <%= t("debates.index.filter_rated") %>
+
+
+
+
+
+
+
+
+
+
<%= t("debates.index.showing") %>
+
+
+
+ <%= t("debates.index.filter_debates") %>
+
+
+ <%= t("debates.index.filter_initiatives") %>
+
+
+ <%= t("debates.index.filter_debates_and_initiatives") %>
+
+
+
+
+
+ <%= t("debates.index.filter_news") %>
+
+
+ <%= t("debates.index.filter_votes") %>
+
+
+ <%= t("debates.index.filter_rated") %>
+
+
+
+ <%= t("debates.index.tag") %>
+
+
+ Lista de temas
+
+
+ (43)
+
+
+
+
-
+
<%= render @debates %>
@@ -10,4 +83,4 @@
-
\ No newline at end of file
+
diff --git a/app/views/layouts/_admin_header.html.erb b/app/views/layouts/_admin_header.html.erb
index b88dcded4..ffd7d34f4 100644
--- a/app/views/layouts/_admin_header.html.erb
+++ b/app/views/layouts/_admin_header.html.erb
@@ -10,12 +10,6 @@
<% end %>
]
-
- <%= link_to t("layouts.header.participation"), root_path, class: "selected" %> |
- <%= link_to t("layouts.header.external_link_transparency"), "#" %> |
- <%= link_to t("layouts.header.external_link_opendata"), "#" %> |
- <%= link_to t("layouts.header.external_link_blog"), "#" %>
-
@@ -25,7 +19,7 @@
<%= link_to root_path do %>
<%= image_tag('header_logo_madrid.png', class: 'left', size: '96x96') %>
- <%= t("layouts.header.open_gov", open: "#{t('layouts.header.open')} ").html_safe %> | <%= t("layouts.header.participation") %>
+ <%= t("layouts.header.open_gov", open: "#{t('layouts.header.open')} ").html_safe %> | <%= t("admin.dashboard.index.title") %>
<% end %>
diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb
index c754951f2..79ae8fcd9 100644
--- a/app/views/layouts/admin.html.erb
+++ b/app/views/layouts/admin.html.erb
@@ -12,22 +12,26 @@
<%= csrf_meta_tags %>
-
+
<%= render 'layouts/admin_header' %>
- <% if notice %>
- <%= notice %>
- <% end %>
+
- <% if alert %>
-
<%= alert %>
- <% end %>
+
+ <%= side_menu %>
+
-
- <%= side_menu %>
+
+ <% if notice %>
+
<%= notice %>
+ <% end %>
+
+ <% if alert %>
+
<%= alert %>
+ <% end %>
+
+ <%= yield %>
+
-
- <%= yield %>
-
-
\ No newline at end of file
+