diff --git a/Gemfile b/Gemfile
index 2be3da5..807cce6 100644
--- a/Gemfile
+++ b/Gemfile
@@ -14,6 +14,9 @@ gem 'coffee-rails', '~> 4.1.0'
# Integrate Paperclip into Mongoid.
gem 'mongoid-paperclip'
+# Markdown rendering
+gem 'redcarpet'
+
# Stripe integration
gem 'stripe'
diff --git a/Gemfile.lock b/Gemfile.lock
index 5f4332e..194156d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -260,6 +260,7 @@ GEM
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
rdoc (4.3.0)
+ redcarpet (3.4.0)
remotipart (1.3.1)
responders (2.4.0)
actionpack (>= 4.2.0, < 5.3)
@@ -380,6 +381,7 @@ DEPENDENCIES
rails-i18n
rails_12factor
rails_admin
+ redcarpet
roadie-rails (~> 1.0)
route_translator
rspec-rails (~> 3.0)
diff --git a/app/assets/javascripts/greendays.coffee b/app/assets/javascripts/greendays.coffee
new file mode 100644
index 0000000..24f83d1
--- /dev/null
+++ b/app/assets/javascripts/greendays.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/app/assets/stylesheets/greendays.sass b/app/assets/stylesheets/greendays.sass
new file mode 100644
index 0000000..1c4a4b6
--- /dev/null
+++ b/app/assets/stylesheets/greendays.sass
@@ -0,0 +1,11 @@
+// Place all the styles related to the Greendays controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
+
+.well > h2
+ margin-top: 0px
+
+#map
+ width: 100%
+ height: 300px
+ margin-bottom: 12px
\ No newline at end of file
diff --git a/app/assets/stylesheets/nav.sass b/app/assets/stylesheets/nav.sass
index 4784233..a2549fe 100644
--- a/app/assets/stylesheets/nav.sass
+++ b/app/assets/stylesheets/nav.sass
@@ -23,8 +23,12 @@ nav#mainnav
li
font-size: 12pt
-
+
li.selected
background-color: $brand-success
a
color: white
+
+ #greendays
+ margin-bottom: 12px
+ border: 1px solid $brand-success
\ No newline at end of file
diff --git a/app/assets/stylesheets/scaffolds.scss b/app/assets/stylesheets/scaffolds.scss
new file mode 100644
index 0000000..4932c1f
--- /dev/null
+++ b/app/assets/stylesheets/scaffolds.scss
@@ -0,0 +1,30 @@
+.field_with_errors {
+ padding: 2px;
+ background-color: red;
+ display: table;
+}
+
+#error_explanation {
+ width: 450px;
+ border: 2px solid red;
+ padding: 7px;
+ padding-bottom: 0;
+ margin-bottom: 20px;
+ background-color: #f0f0f0;
+
+ h2 {
+ text-align: left;
+ font-weight: bold;
+ padding: 5px 5px 5px 15px;
+ font-size: 12px;
+ margin: -7px;
+ margin-bottom: 0px;
+ background-color: #c00;
+ color: #fff;
+ }
+
+ ul li {
+ font-size: 12px;
+ list-style: square;
+ }
+}
diff --git a/app/controllers/greendays_controller.rb b/app/controllers/greendays_controller.rb
new file mode 100644
index 0000000..b49e929
--- /dev/null
+++ b/app/controllers/greendays_controller.rb
@@ -0,0 +1,65 @@
+class GreendaysController < ApplicationController
+ before_action :only_admin, except: [:index, :show]
+ before_action :set_greenday, only: [:show, :edit, :update, :destroy]
+
+ def index
+ @greendays = Greenday.all.sort(title: 1)
+ end
+
+ def new
+ @greenday = Greenday.new
+ end
+
+ def edit; end
+
+ def create
+ @greenday = Greenday.new(greenday_params)
+
+ respond_to do |format|
+ if @greenday.save
+ format.html { redirect_to greendays_path, success: 'Greenday was successfully created.' }
+ format.json { render :show, status: :created, location: @greenday }
+ else
+ format.html { render :new }
+ format.json { render json: @greenday.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ def update
+ respond_to do |format|
+ if @greenday.update(greenday_params)
+ format.html { redirect_to greendays_path, notice: 'Greenday was successfully updated.' }
+ format.json { render :show, status: :ok, location: @greenday }
+ else
+ format.html { render :edit }
+ format.json { render json: @greenday.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ def destroy
+ @greenday.destroy
+ respond_to do |format|
+ format.html { redirect_to greendays_path, notice: 'Greenday was successfully destroyed.' }
+ format.json { head :no_content }
+ end
+ end
+
+ private
+
+ # Use callbacks to share common setup or constraints between actions.
+ def set_greenday
+ @greenday = Greenday.find(params[:id])
+ end
+
+ # Never trust parameters from the scary internet, only allow the white list through.
+ def greenday_params
+ params.require(:greenday).permit(:title, :address, :homepage, :description, :logo, :delete_logo)
+ end
+
+ def only_admin
+ return true if current_supporter && current_supporter.admin?
+ raise ActionController::RoutingError, 'Not Found'
+ end
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 63f80ea..1c47532 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -3,4 +3,13 @@ module ApplicationHelper
content_for :title, strip_tags(page_title.to_s)
page_title
end
+
+ def markdown(content)
+ @markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, space_after_headers: true)
+ @markdown.render(content)
+ end
+
+ def admin?
+ current_supporter && current_supporter.admin?
+ end
end
diff --git a/app/models/greenday.rb b/app/models/greenday.rb
new file mode 100644
index 0000000..197616e
--- /dev/null
+++ b/app/models/greenday.rb
@@ -0,0 +1,43 @@
+class Greenday
+ include Mongoid::Document
+ include Mongoid::Timestamps
+ include Geocoder::Model::Mongoid
+ include Mongoid::Paperclip
+
+ before_save :delete_logo?
+
+ has_mongoid_attached_file :logo,
+ path: ':attachment/:id/:style.:extension',
+ styles: {
+ original: ['1920x1680>', :jpg],
+ small: ['100x100#', :jpg],
+ medium: ['250x250', :jpg],
+ large: ['500x500>', :jpg]
+ },
+ convert_options: { all: '-background white -flatten +matte' }
+
+ field :title, type: String
+ field :address, type: String
+ field :homepage, type: String
+ field :description, type: String
+ field :coordinates, type: Array
+
+ geocoded_by :address
+ after_validation :geocode # auto-fetch coordinates
+
+ validates :title, presence: true
+ validates :address, presence: true
+ validates_attachment_content_type :logo, content_type: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif']
+
+ def delete_logo
+ @delete_logo ||= '0'
+ end
+
+ attr_writer :delete_logo
+
+ private
+
+ def delete_logo?
+ logo.clear if @delete_logo == '1'
+ end
+end
diff --git a/app/views/greendays/_form.html.slim b/app/views/greendays/_form.html.slim
new file mode 100644
index 0000000..a070085
--- /dev/null
+++ b/app/views/greendays/_form.html.slim
@@ -0,0 +1,14 @@
+= simple_form_for(@greenday) do |f|
+ = f.error_notification
+
+ .form-inputs
+ = f.input :title
+ = f.input :address, as: :text
+ = f.input :homepage
+ = f.input :description, as: :text
+ = f.input :logo, as: :file, required: false
+ = image_tag f.object.logo.url(:original), alt: '', class: 'img-responsive'
+ = f.input :delete_logo, as: :boolean
+
+ .form-actions
+ = f.button :submit, 'Shop speichern'
diff --git a/app/views/greendays/_greenday.json.jbuilder b/app/views/greendays/_greenday.json.jbuilder
new file mode 100644
index 0000000..d741703
--- /dev/null
+++ b/app/views/greendays/_greenday.json.jbuilder
@@ -0,0 +1,2 @@
+json.extract! greenday, :id, :title, :address, :coordinates, :homepage, :logo, :description, :created_at, :updated_at
+json.url greenday_url(greenday, format: :json)
diff --git a/app/views/greendays/edit.html.slim b/app/views/greendays/edit.html.slim
new file mode 100644
index 0000000..007d026
--- /dev/null
+++ b/app/views/greendays/edit.html.slim
@@ -0,0 +1,8 @@
+h1 Editing greenday
+
+== render 'form'
+
+= link_to 'Show', @greenday
+' |
+= link_to 'Back', greendays_path
+
diff --git a/app/views/greendays/index.html.slim b/app/views/greendays/index.html.slim
new file mode 100644
index 0000000..04b512b
--- /dev/null
+++ b/app/views/greendays/index.html.slim
@@ -0,0 +1,68 @@
+
+h1.sr-only = title 'Gründonnerstag'
+#map
+= link_to 'Neun Shop erfassen', new_greenday_path if admin?
+
+.row
+ - @greendays.each do |greenday|
+ .col-xs-12.col-sm-6.col-lg-4
+ .well
+ h2 = greenday.title
+ - if greenday.logo
+ = image_tag greenday.logo.url(:original), alt: '', class: 'img-responsive'
+ address = simple_format(greenday.address)
+ - if greenday.homepage
+ = link_to(greenday.homepage, greenday.homepage, target: "_blank")
+ p = markdown(greenday.description).html_safe
+
+ - if admin?
+ = link_to 'Bearbeiten', edit_greenday_path(greenday)
+ |
+ = link_to 'Löschen', greenday, data: { confirm: 'Are you sure?' }, method: :delete
+
+javascript:
+ function initMap() {
+
+ var map = new google.maps.Map(document.getElementById('map'), {
+ zoom: 8, center: {lat: 47.242, lng: 8.133},
+ });
+
+ var greendays_url = "#{greendays_url(format: :json)}"
+
+ var infowindow = new google.maps.InfoWindow({
+ content: '',
+ maxWidth: 200
+ });
+
+
+ $.getJSON(greendays_url, function(json) {
+ $.each(json, function(key, data) {
+ var marker = new google.maps.Marker({
+ position: {lat: data.coordinates[1], lng: data.coordinates[0] },
+ map: map,
+ title: data.title
+ });
+
+ marker.addListener('click', function() {
+ infowindow.open(map, marker);
+
+ var content = '' + data.title + ''
+ if(data.logo) {
+ content += ''
+ }
+ content += '
' + data.description + '
' + } + infowindow.setContent(content); + }); + }); + }); + } + +script async="" defer="" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBbwMtGKDqf4i8x9-OVP1-H_QVAKp92h2M&callback=initMap&libraries=visualization" \ No newline at end of file diff --git a/app/views/greendays/index.json.jbuilder b/app/views/greendays/index.json.jbuilder new file mode 100644 index 0000000..30d440e --- /dev/null +++ b/app/views/greendays/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @greendays, partial: 'greendays/greenday', as: :greenday diff --git a/app/views/greendays/new.html.slim b/app/views/greendays/new.html.slim new file mode 100644 index 0000000..7e340d3 --- /dev/null +++ b/app/views/greendays/new.html.slim @@ -0,0 +1,5 @@ +h1 New greenday + +== render 'form' + += link_to 'Back', greendays_path diff --git a/config/navigation.rb b/config/navigation.rb index bd087ce..93b7e02 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -57,6 +57,8 @@ SimpleNavigation::Configuration.run do |navigation| # against the current URI. You may also use a proc, or the symbol :subpath. # + primary.item :greendays, 'Gründonnerstag', greendays_path + unless supporter_signed_in? primary.item :home, I18n.t('.shared.topnavigation.support'), "/#{I18n.locale}" end @@ -79,5 +81,7 @@ SimpleNavigation::Configuration.run do |navigation| else primary.item :home, I18n.t('.shared.topnavigation.sign_in'), new_supporter_session_path end + + end end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 5281711..1032f30 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :greendays devise_for :supporters root to: 'supporters#new' diff --git a/spec/models/greenday_spec.rb b/spec/models/greenday_spec.rb new file mode 100644 index 0000000..d8ba7a7 --- /dev/null +++ b/spec/models/greenday_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Greenday, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/greendays_spec.rb b/spec/requests/greendays_spec.rb new file mode 100644 index 0000000..282b151 --- /dev/null +++ b/spec/requests/greendays_spec.rb @@ -0,0 +1,10 @@ +require 'rails_helper' + +RSpec.describe "Greendays", type: :request do + describe "GET /greendays" do + it "works! (now write some real specs)" do + get greendays_path + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/routing/greendays_routing_spec.rb b/spec/routing/greendays_routing_spec.rb new file mode 100644 index 0000000..6a08517 --- /dev/null +++ b/spec/routing/greendays_routing_spec.rb @@ -0,0 +1,39 @@ +require "rails_helper" + +RSpec.describe GreendaysController, type: :routing do + describe "routing" do + + it "routes to #index" do + expect(:get => "/greendays").to route_to("greendays#index") + end + + it "routes to #new" do + expect(:get => "/greendays/new").to route_to("greendays#new") + end + + it "routes to #show" do + expect(:get => "/greendays/1").to route_to("greendays#show", :id => "1") + end + + it "routes to #edit" do + expect(:get => "/greendays/1/edit").to route_to("greendays#edit", :id => "1") + end + + it "routes to #create" do + expect(:post => "/greendays").to route_to("greendays#create") + end + + it "routes to #update via PUT" do + expect(:put => "/greendays/1").to route_to("greendays#update", :id => "1") + end + + it "routes to #update via PATCH" do + expect(:patch => "/greendays/1").to route_to("greendays#update", :id => "1") + end + + it "routes to #destroy" do + expect(:delete => "/greendays/1").to route_to("greendays#destroy", :id => "1") + end + + end +end diff --git a/spec/views/greendays/edit.html.slim_spec.rb b/spec/views/greendays/edit.html.slim_spec.rb new file mode 100644 index 0000000..f5dc9d7 --- /dev/null +++ b/spec/views/greendays/edit.html.slim_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +RSpec.describe "greendays/edit", type: :view do + before(:each) do + @greenday = assign(:greenday, Greenday.create!( + :title => "MyString", + :address => "MyText", + :description => "MyText" + )) + end + + it "renders the edit greenday form" do + render + + assert_select "form[action=?][method=?]", greenday_path(@greenday), "post" do + + assert_select "input#greenday_title[name=?]", "greenday[title]" + + assert_select "textarea#greenday_address[name=?]", "greenday[address]" + + assert_select "textarea#greenday_description[name=?]", "greenday[description]" + end + end +end diff --git a/spec/views/greendays/index.html.slim_spec.rb b/spec/views/greendays/index.html.slim_spec.rb new file mode 100644 index 0000000..75e7e18 --- /dev/null +++ b/spec/views/greendays/index.html.slim_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +RSpec.describe 'greendays/index' do + before(:each) do + assign(:greendays, [ + Greenday.create!( + title: 'Title', + address: 'Address', + description: 'MyText' + ), + Greenday.create!( + title: 'Title', + address: 'Address', + description: 'MyText' + ) + ]) + end + + it 'renders a list of greendays' do + render + assert_select 'h2', text: 'Title'.to_s, count: 2 + assert_select "address", :text => "Address".to_s, count: 2 + assert_select "p", :text => "MyText".to_s, count: 2 + end +end diff --git a/spec/views/greendays/new.html.slim_spec.rb b/spec/views/greendays/new.html.slim_spec.rb new file mode 100644 index 0000000..6c6130e --- /dev/null +++ b/spec/views/greendays/new.html.slim_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +RSpec.describe "greendays/new", type: :view do + before(:each) do + assign(:greenday, Greenday.new( + :title => "MyString", + :address => "MyText", + :description => "MyText" + )) + end + + it "renders new greenday form" do + render + + assert_select "form[action=?][method=?]", greendays_path, "post" do + + assert_select "input#greenday_title[name=?]", "greenday[title]" + + assert_select "textarea#greenday_address[name=?]", "greenday[address]" + + assert_select "textarea#greenday_description[name=?]", "greenday[description]" + end + end +end