tramway-landing 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/config/tramway_landing_manifest.js +2 -0
  6. data/app/assets/javascripts/justified_images.js +284 -0
  7. data/app/assets/javascripts/tramway/landing/application.js.coffee +3 -0
  8. data/app/assets/javascripts/tramway/landing/footer.js.coffee +24 -0
  9. data/app/assets/stylesheets/tramway/landing/application.css.sass +16 -0
  10. data/app/assets/stylesheets/tramway/landing/collage.css.sass +36 -0
  11. data/app/assets/stylesheets/tramway/landing/justified.css +13 -0
  12. data/app/controllers/tramway/landing/application_controller.rb +11 -0
  13. data/app/decorators/tramway/landing/block_decorator.rb +26 -0
  14. data/app/decorators/tramway/landing/block_types/cards_decorator.rb +13 -0
  15. data/app/decorators/tramway/landing/block_types/features_decorator.rb +9 -0
  16. data/app/forms/tramway/landing/block_form.rb +15 -0
  17. data/app/helpers/tramway/landing/application_helper.rb +8 -0
  18. data/app/jobs/tramway/landing/application_job.rb +6 -0
  19. data/app/mailers/tramway/landing/application_mailer.rb +8 -0
  20. data/app/models/tramway/landing/application_record.rb +7 -0
  21. data/app/models/tramway/landing/block.rb +24 -0
  22. data/app/uploaders/tramway/landing/photo_versions.rb +15 -0
  23. data/app/views/layouts/tramway/landing/application.html.haml +28 -0
  24. data/app/views/tramway/landing/blocks/block_types/_cards.html.haml +36 -0
  25. data/app/views/tramway/landing/blocks/block_types/_contacts.html.haml +48 -0
  26. data/app/views/tramway/landing/blocks/block_types/_features.html.haml +26 -0
  27. data/app/views/tramway/landing/blocks/block_types/_footer.html.haml +16 -0
  28. data/app/views/tramway/landing/blocks/block_types/_header.html.haml +22 -0
  29. data/app/views/tramway/landing/blocks/block_types/_page.html.haml +9 -0
  30. data/config/initializers/assets.rb +1 -0
  31. data/config/initializers/tramway.rb +1 -0
  32. data/config/locales/models.yml +19 -0
  33. data/config/locales/state_machines.yml +15 -0
  34. data/config/routes.rb +2 -0
  35. data/lib/tasks/tramway/landing_tasks.rake +4 -0
  36. data/lib/tramway/landing.rb +7 -0
  37. data/lib/tramway/landing/engine.rb +7 -0
  38. data/lib/tramway/landing/generates/install_generator.rb +21 -0
  39. data/lib/tramway/landing/generates/templates/add_anchor_to_tramway_landing_blocks.rb +5 -0
  40. data/lib/tramway/landing/generates/templates/add_description_to_tramway_landing_blocks.rb +5 -0
  41. data/lib/tramway/landing/generates/templates/add_navbar_link_to_tramway_landing_blocks.rb +5 -0
  42. data/lib/tramway/landing/generates/templates/create_tramway_landing_blocks.rb +14 -0
  43. data/lib/tramway/landing/version.rb +5 -0
  44. metadata +86 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bc98a307ccf33e690b805a6adfeb1b7f110be1269bae2a02a90d3f7c1a0cc6e9
4
+ data.tar.gz: 5b85a0739fbc0da2ff548f1f79ff5a2dede5b5f0796f2e09fd36ce145825bf14
5
+ SHA512:
6
+ metadata.gz: e8fedc657c02b00f46af054ddf56a81c78acf2ef148b6eeb79ba375911702c0a7194e80de56f15743bd4aa4db4ce5474871db00eb596a9469e56eac06aedff9e
7
+ data.tar.gz: f8d3d47ccc3dc8f1787b1ed027ddbd3deecbde84031b1b42a1cb1f39d47543c42ca5372e3287e53b7147f551487f3a09d234303e3671f67458bdff3f28745a92
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2018 Pavel Kalashnikov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Tramway::Landing
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'tramway-landing'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install tramway-landing
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Tramway::Landing'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ require 'bundler/gem_tasks'
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'test'
31
+ t.pattern = 'test/**/*_test.rb'
32
+ t.verbose = false
33
+ end
34
+
35
+
36
+ task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/tramway/landing .js
2
+ //= link_directory ../stylesheets/tramway/landing .css
@@ -0,0 +1,284 @@
1
+ /*jshint white:false*/
2
+ /* global jQuery: true*/
3
+ // the semi-colon before function invocation is a safety net against concatenated
4
+ // scripts and/or other plugins which may not be closed properly.
5
+ ;
6
+ (function($, window, document, undefined) {
7
+ 'use strict';
8
+ // undefined is used here as the undefined global variable in ECMAScript 3 is
9
+ // mutable (ie. it can be changed by someone else). undefined isn't really being
10
+ // passed in so we can ensure the value of it is truly undefined. In ES5, undefined
11
+ // can no longer be modified.
12
+
13
+ // window and document are passed through as local variable rather than global
14
+ // as this (slightly) quickens the resolution process and can be more efficiently
15
+ // minified (especially when both are regularly referenced in your plugin).
16
+
17
+ // Create the defaults once
18
+ var pluginName = 'justifiedImages';
19
+
20
+
21
+ // The actual plugin constructor
22
+
23
+ function Plugin(element, options) {
24
+ this.element = element;
25
+ this.$el = $(element);
26
+ this._name = pluginName;
27
+ this.init(options);
28
+ }
29
+
30
+ Plugin.prototype = {
31
+ defaults: {
32
+ template: function(data) {
33
+ return '<div class="photo-container" style="height:' + data.displayHeight + 'px;margin-right:' + data.marginRight + 'px;">' +
34
+ '<img class="image-thumb" src="' + data.src + '" style="width:' + data.displayWidth + 'px;height:' + data.displayHeight + 'px;" >' +
35
+ '</div>';
36
+ },
37
+ appendBlocks : function(){ return []; },
38
+ rowHeight: 150,
39
+ maxRowHeight: 350,
40
+ handleResize: false,
41
+ margin: 1,
42
+ imageSelector: 'image-thumb',
43
+ imageContainer: 'photo-container'
44
+ },
45
+ init: function(options) {
46
+ this.options = $.extend({}, this.defaults, options);
47
+ this.displayImages();
48
+ if (this.options.handleResize) {
49
+ this.handleResize();
50
+ }
51
+ },
52
+ getBlockInRow: function(rowNum){
53
+ var appendBlocks = this.options.appendBlocks();
54
+ for (var i = 0; i < appendBlocks.length; i++) {
55
+ var block = appendBlocks[i];
56
+ if(block.rowNum === rowNum){
57
+ return block;
58
+ }
59
+ }
60
+ },
61
+ displayImages: function() {
62
+ var self = this,
63
+ ws = [],
64
+ rowNum = 0,
65
+ baseLine = 0,
66
+ limit = this.options.images.length,
67
+ photos = this.options.images,
68
+ rows = [],
69
+ totalWidth = 0,
70
+ appendBlocks = this.options.appendBlocks();
71
+ var w = this.$el.width();
72
+ var border = parseInt(this.options.margin, 10);
73
+ var d = this.$el,
74
+ h = parseInt(this.options.rowHeight, 10);
75
+
76
+ $.each(this.options.images, function(index, image) {
77
+ var size = self.options.getSize(image);
78
+ var wt = parseInt(size.width, 10);
79
+ var ht = parseInt(size.height, 10);
80
+ if (ht !== h) {
81
+ wt = Math.floor(wt * (h / ht));
82
+ }
83
+ totalWidth += wt;
84
+ ws.push(wt);
85
+ });
86
+
87
+ $.each(appendBlocks, function(index, block){
88
+ totalWidth += block.width;
89
+ });
90
+ var perRowWidth = totalWidth / Math.ceil(totalWidth / w);
91
+ console.log('rows', Math.ceil(totalWidth / w));
92
+ var tw = 0;
93
+ while (baseLine < limit) {
94
+ var row = {
95
+ width: 0,
96
+ photos: []
97
+ },
98
+ c = 0,
99
+ block = this.getBlockInRow(rows.length + 1);
100
+ if(block){
101
+ row.width += block.width;
102
+ tw += block.width;
103
+ }
104
+ while ((tw + ws[baseLine + c] / 2 <= perRowWidth * (rows.length + 1)) && (baseLine + c < limit)) {
105
+ tw += ws[baseLine + c];
106
+ row.width += ws[baseLine + c];
107
+ row.photos.push({
108
+ width: ws[baseLine + c],
109
+ photo: photos[baseLine + c]
110
+ });
111
+ c++;
112
+ }
113
+ baseLine += c;
114
+ rows.push(row);
115
+ }
116
+ console.log(rows.length, rows);
117
+ /*for (var i = 1; i < rows.length; i++) {
118
+ var row = rows[i];
119
+ for (var j = 0; j < row.photos.length; j++) {
120
+ var photo = row.photos[j].photo;
121
+ };
122
+ }*/
123
+ for (var i = 0; i < rows.length; i++) {
124
+ var row = rows[i],
125
+ lastRow = false;
126
+ rowNum = i + 1;
127
+ if (this.options.maxRows && rowNum > this.options.maxRows) {
128
+ break;
129
+ }
130
+ if (i === rows.length - 1) {
131
+ lastRow = true;
132
+ }
133
+ tw = -1 * border;
134
+ var newBlock = this.getBlockInRow(lastRow ? -1 : rowNum), availableRowWidth = w;
135
+ if(newBlock){
136
+ availableRowWidth -= newBlock.width;
137
+ tw = 0;
138
+ }
139
+
140
+ // Ratio of actual width of row to total width of images to be used.
141
+ var r = availableRowWidth / row.width, //Math.min(w / row.width, this.options.maxScale),
142
+ c = row.photos.length;
143
+
144
+ // new height is not original height * ratio
145
+ var ht = Math.min(Math.floor(h * r), parseInt(this.options.maxRowHeight,10));
146
+ r = ht / this.options.rowHeight;
147
+ var domRow = $('<div/>', {
148
+ 'class': 'picrow'
149
+ });
150
+ domRow.height(ht + border);
151
+ d.append(domRow);
152
+
153
+ var imagesHtml = '';
154
+ for (var j = 0; j < row.photos.length; j++) {
155
+ var photo = row.photos[j].photo;
156
+ // Calculate new width based on ratio
157
+ var wt = Math.floor(row.photos[j].width * r);
158
+ tw += wt + border;
159
+
160
+ imagesHtml += this.renderPhoto(photo, {
161
+ src: this.options.thumbnailPath(photo, wt, ht),
162
+ width: wt,
163
+ height: ht
164
+ }, newBlock ? false : j === row.photos.length - 1);
165
+ }
166
+ if(imagesHtml === ''){
167
+ domRow.remove();
168
+ continue;
169
+ }
170
+
171
+ domRow.html(imagesHtml);
172
+
173
+
174
+
175
+ if ((Math.abs(tw - availableRowWidth) < 0.05 * availableRowWidth)) {
176
+ // if total width is slightly smaller than
177
+ // actual div width then add 1 to each
178
+ // photo width till they match
179
+ var k = 0;
180
+ while (tw < availableRowWidth) {
181
+ var div1 = domRow.find('.' + this.options.imageContainer + ':nth-child(' + (k + 1) + ')'),
182
+ img1 = div1.find('.' + this.options.imageSelector);
183
+ img1.width(img1.width() + 1);
184
+ k = (k + 1) % c;
185
+ tw++;
186
+ }
187
+ // if total width is slightly bigger than
188
+ // actual div width then subtract 1 from each
189
+ // photo width till they match
190
+ k = 0;
191
+ while (tw > availableRowWidth) {
192
+ var div2 = domRow.find('.' + this.options.imageContainer + ':nth-child(' + (k + 1) + ')'),
193
+ img2 = div2.find('.' + this.options.imageSelector);
194
+ img2.width(img2.width() - 1);
195
+ k = (k + 1) % c;
196
+ tw--;
197
+ }
198
+ } else{
199
+ if( availableRowWidth - tw > 0.05 * availableRowWidth ){
200
+ var diff = availableRowWidth-tw,
201
+ adjustedDiff = 0,
202
+ images = domRow.find('.' + this.options.imageContainer),
203
+ marginTop = 0;
204
+ for(var l = 0 ; l < images.length ; l++ ){
205
+ var currentDiff = diff / (images.length),
206
+ imgDiv = images.eq(l),
207
+ img = imgDiv.find('.' + this.options.imageSelector),
208
+ imageWidth = img.width(),
209
+ imageHeight = img.height();
210
+ if( i === images.length - 1 ){
211
+ currentDiff = diff - adjustedDiff;
212
+ }
213
+ img.width( imageWidth + currentDiff );
214
+ img.height( ( imageHeight / imageWidth ) * (imageWidth + currentDiff) );
215
+ marginTop = (imageHeight - img.height()) / 2;
216
+ img.css('margin-top', marginTop);
217
+ adjustedDiff += currentDiff;
218
+ }
219
+ }
220
+ }
221
+
222
+ if(newBlock){
223
+ $('<div />', {
224
+ class : this.options.imageContainer + ' added-block',
225
+ css : {
226
+ width : newBlock.width,
227
+ height: ht
228
+ },
229
+ html : newBlock.html
230
+ }).appendTo(domRow);
231
+ }
232
+ }
233
+ },
234
+ renderPhoto: function(image, obj, isLast) {
235
+ var data = {},
236
+ d;
237
+ d = $.extend({}, image, {
238
+ src: obj.src,
239
+ displayWidth: obj.width,
240
+ displayHeight: obj.height,
241
+ marginRight: isLast ? 0 : this.options.margin
242
+ });
243
+ if (this.options.dataObject) {
244
+ data[this.options.dataObject] = d;
245
+ } else {
246
+ data = d;
247
+ }
248
+ return this.options.template(data);
249
+ },
250
+ handleResize: function() {},
251
+ refresh: function(options) {
252
+ this.options = $.extend({}, this.defaults, options);
253
+ this.$el.empty();
254
+ this.displayImages();
255
+ }
256
+ };
257
+
258
+
259
+ // A really lightweight plugin wrapper around the constructor,
260
+ // preventing against multiple instantiations
261
+ $.fn[pluginName] = function(option) {
262
+ var args = arguments,
263
+ result;
264
+
265
+ this.each(function() {
266
+ var $this = $(this),
267
+ data = $.data(this, 'plugin_' + pluginName),
268
+ options = typeof option === 'object' && option;
269
+ if (!data) {
270
+ $this.data('plugin_' + pluginName, (data = new Plugin(this, options)));
271
+ }else{
272
+ if (typeof option === 'string') {
273
+ result = data[option].apply(data, Array.prototype.slice.call(args, 1));
274
+ } else {
275
+ data.refresh.call(data, options);
276
+ }
277
+ }
278
+ });
279
+
280
+ // To enable plugin returns values
281
+ return result || this;
282
+ };
283
+
284
+ })(jQuery, window, document);
@@ -0,0 +1,3 @@
1
+ #= require jquery
2
+ #= require jquery_ujs
3
+ #= require_tree .
@@ -0,0 +1,24 @@
1
+ #= require justified_images
2
+
3
+ $(document).ready ->
4
+ $('.logo_collage1').empty().justifiedImages
5
+ images: photos
6
+ rowHeight: 200
7
+ maxRowHeight: 400
8
+ thumbnailPath: (photo, width, height) ->
9
+ purl = photo.url_s
10
+ if photo.url_n and (width > photo.width_s * 1.2 or height > photo.height_s * 1.2)
11
+ purl = photo.url_n
12
+ if photo.url_m and (width > photo.width_n * 1.2 or height > photo.height_n * 1.2)
13
+ purl = photo.url_m
14
+ if photo.url_z and (width > photo.width_m * 1.2 or height > photo.height_m * 1.2)
15
+ purl = photo.url_z
16
+ if photo.url_l and (width > photo.width_z * 1.2 or height > photo.height_z * 1.2)
17
+ purl = photo.url_l
18
+ purl
19
+ getSize: (photo) ->
20
+ {
21
+ width: photo.width_s
22
+ height: photo.height_s
23
+ }
24
+ margin: 1
@@ -0,0 +1,16 @@
1
+ /*
2
+ *= require_tree .
3
+ *= require_self
4
+ */
5
+
6
+ html, body, header, #intro
7
+ height: 100%
8
+
9
+ #intro
10
+ background-repeat: no-repeat
11
+ background-position: center center
12
+ background-attachment: fixed
13
+ -webkit-background-size: cover
14
+ -moz-background-size: cover
15
+ -o-background-size: cover
16
+ background-size: cover
@@ -0,0 +1,36 @@
1
+ .logo_collage
2
+ line-height: 0
3
+ -webkit-column-count: 5
4
+ -webkit-column-gap: 0px
5
+ -moz-column-count: 5
6
+ -moz-column-gap: 0px
7
+ column-count: 5
8
+ column-gap: 0px
9
+ img
10
+ width: 100% !important
11
+ height: auto !important
12
+ margin: 1px
13
+
14
+ @media (max-width: 1200px)
15
+ .logo_collage
16
+ -moz-column-count: 4
17
+ -webkit-column-count: 4
18
+ column-count: 4
19
+
20
+ @media (max-width: 1000px)
21
+ .logo_collage
22
+ -moz-column-count: 3
23
+ -webkit-column-count: 3
24
+ column-count: 3
25
+
26
+ @media (max-width: 800px)
27
+ .logo_collage
28
+ -moz-column-count: 2
29
+ -webkit-column-count: 2
30
+ column-count: 2
31
+
32
+ @media (max-width: 400px)
33
+ .logo_collage
34
+ -moz-column-count: 1
35
+ -webkit-column-count: 1
36
+ column-count: 1
@@ -0,0 +1,13 @@
1
+
2
+ .image-container{
3
+ position: relative;
4
+ }
5
+ .photo-container{
6
+ float: left;
7
+ position: relative;
8
+ overflow: hidden;
9
+ }
10
+ .image-thumb{
11
+ position: relative;
12
+ background-color: #eee;
13
+ }
@@ -0,0 +1,11 @@
1
+ module Tramway
2
+ module Landing
3
+ class ApplicationController < ActionController::Base
4
+ protect_from_forgery with: :exception
5
+
6
+ def application
7
+ ::Tramway::Core::Application.first
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ class Tramway::Landing::BlockDecorator < ::Tramway::Core::ApplicationDecorator
2
+ class << self
3
+ def collections
4
+ [ :all ]
5
+ end
6
+
7
+ def list_attributes
8
+ [ :position, :view_state ]
9
+ end
10
+ end
11
+
12
+ delegate :position, to: :object
13
+
14
+ def view_state
15
+ object.human_view_state_name
16
+ end
17
+
18
+ def view_state_button_color(event)
19
+ case event
20
+ when :publish
21
+ :primary
22
+ when :hide
23
+ :secondary
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ class Tramway::Landing::BlockTypes::CardsDecorator < ::Tramway::Core::ApplicationDecorator
2
+ def image; end
3
+
4
+ def title; end
5
+
6
+ def description; end
7
+
8
+ def button; end
9
+
10
+ def icon; end
11
+
12
+ def path; end
13
+ end
@@ -0,0 +1,9 @@
1
+ class Tramway::Landing::BlockTypes::FeaturesDecorator < ::Tramway::Core::ApplicationDecorator
2
+ def icon; end
3
+
4
+ def image; end
5
+
6
+ def title; end
7
+
8
+ def text; end
9
+ end
@@ -0,0 +1,15 @@
1
+ class Tramway::Landing::BlockForm < ::Tramway::Core::ApplicationForm
2
+ properties :title, :background, :view_state, :block_type, :position, :navbar_link, :anchor, :description
3
+
4
+ def initialize(object)
5
+ form_object = super object
6
+ form_properties title: :string,
7
+ background: :file,
8
+ position: :numeric,
9
+ block_type: :default,
10
+ navbar_link: :default,
11
+ anchor: :string,
12
+ description: :default
13
+ form_object
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ module Tramway
2
+ module Landing
3
+ module ApplicationHelper
4
+ include Tramway::Admin::RussianCasesHelper
5
+ include Tramway::Profiles::LinksHelper
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module Tramway
2
+ module Landing
3
+ class ApplicationJob < ActiveJob::Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ module Tramway
2
+ module Landing
3
+ class ApplicationMailer < ActionMailer::Base
4
+ default from: 'from@example.com'
5
+ layout 'mailer'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module Tramway
2
+ module Landing
3
+ class ApplicationRecord < ::Tramway::Core::ApplicationRecord
4
+ self.abstract_class = true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ class Tramway::Landing::Block < ::Tramway::Landing::ApplicationRecord
2
+ enumerize :block_type, in: [ :header, :footer, :page, :cards, :features, :contacts, :news ]
3
+ enumerize :navbar_link, in: [ :exist, :not_exist ], default: :not_exist
4
+
5
+ mount_uploader :background, PhotoUploader
6
+
7
+ state_machine :view_state, initial: :published do
8
+ state :published
9
+ state :hidden
10
+
11
+ event :publish do
12
+ transition hidden: :published
13
+ end
14
+
15
+ event :hide do
16
+ transition published: :hidden
17
+ end
18
+ end
19
+
20
+ scope :on_main_page, -> { active.where(view_state: :published).order :position }
21
+ scope :with_navbar_link, -> { where navbar_link: :exist }
22
+ scope :header, -> { on_main_page.where(block_type: :header).first }
23
+ scope :footer, -> { on_main_page.where(block_type: :footer).first }
24
+ end
@@ -0,0 +1,15 @@
1
+ module Tramway::Landing::PhotoVersions
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ version :card do
6
+ process resize_to_fill: [400, 400, 'North']
7
+ end
8
+
9
+ version :horizontal do
10
+ process resize_to_fill: [1600, 700, 'Center']
11
+ end
12
+ end
13
+ end
14
+
15
+ PhotoUploader.include Tramway::Landing::PhotoVersions
@@ -0,0 +1,28 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %meta{content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}
5
+ %title
6
+ = yield :title
7
+ = stylesheet_link_tag "tramway/landing/application", media: "all"
8
+ = javascript_include_tag "tramway/landing/application"
9
+ = javascript_include_tag "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js", integrity: "sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl", crossorigin: "anonymous"
10
+ = javascript_include_tag "https://code.jquery.com/jquery-3.2.1.slim.min.js", integrity: "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN", crossorigin: "anonymous"
11
+ = javascript_include_tag "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js", integrity: "sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q", crossorigin: "anonymous"
12
+ = csrf_meta_tags
13
+ = yield :head_content
14
+ %body
15
+ = stylesheet_link_tag 'https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.4.5/css/mdb.min.css'
16
+ = javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.4.5/js/mdb.js'
17
+ = javascript_include_tag 'https://cdn.rawgit.com/CezarLuiz0/anchor.js/master/dist/anchor.min.js'
18
+ - if @blocks&.any?
19
+ = render "tramway/landing/blocks/block_types/header", block: @blocks.header
20
+ %main{ class: ('mt-5' if @blocks&.any?) }
21
+ .container
22
+ - if @blocks&.any?
23
+ - (@blocks - [@blocks.header] - [@blocks.footer]).each do |block|
24
+ = render "tramway/landing/blocks/block_types/#{block.block_type}", block: block
25
+ .container-fluid
26
+ = yield
27
+ - if @blocks&.any?
28
+ = render "tramway/landing/blocks/block_types/footer", block: @blocks.footer
@@ -0,0 +1,36 @@
1
+ .container.text-center
2
+ %h2.mb-4.font-weight-bold
3
+ = block.title
4
+ %p.grey-text
5
+ = block.description
6
+ .row{ id: block.anchor }
7
+ -# FIXME bad guy mode ON
8
+ - eval("@collection_#{block.anchor}").each do |item|
9
+ .col-lg-4.col-md-12.mb-4
10
+ - if item.path.present?
11
+ = link_to item.path do
12
+ .card.link
13
+ .view.overlay.hm-white-slight
14
+ = image_tag item.image, class: 'img-fluid'
15
+ = link_to '#' do
16
+ .mask
17
+ .card-body
18
+ %h4.card-title
19
+ = item.title
20
+ %p.card-text
21
+ = item.description
22
+ - if item.button.present?
23
+ = link_to item.button.text, item.button.url, class: 'btn btn-primary'
24
+ - else
25
+ .card
26
+ .view.overlay.hm-white-slight
27
+ = image_tag item.image, class: 'img-fluid'
28
+ = link_to '#' do
29
+ .mask
30
+ .card-body
31
+ %h4.card-title
32
+ = item.title
33
+ %p.card-text
34
+ = item.description
35
+ - if item.button.present?
36
+ = link_to item.button.text, item.button.url, class: 'btn btn-primary'
@@ -0,0 +1,48 @@
1
+ %script{ src: 'https://maps.google.com/maps/api/js?key=AIzaSyDC054dWb7cQ_mULJk3d1UBK6pN8msCx1g' }
2
+ :javascript
3
+ function regular_map() {
4
+ var var_location = new google.maps.LatLng(#{yield(:latitude)}, #{yield(:longtitude)});
5
+
6
+ var var_mapoptions = {
7
+ center: var_location,
8
+ zoom: 14
9
+ };
10
+
11
+ var var_map = new google.maps.Map(document.getElementById("map-container"),
12
+ var_mapoptions);
13
+
14
+ var var_marker = new google.maps.Marker({
15
+ position: var_location,
16
+ map: var_map,
17
+ title: "New York"
18
+ });
19
+ }
20
+ google.maps.event.addDomListener(window, 'load', regular_map);
21
+ #contact
22
+ %h2.mb-5.font-weight-bold.text-center
23
+ = block.title
24
+ .row
25
+ .col-lg-5.col-md-12
26
+ - @application.social_networks.each do |profile|
27
+ %ul.list-group
28
+ %li.list-group-item
29
+ = profile_link profile
30
+ .col-lg-7.col-md-12
31
+ .row.text-center
32
+ - if yield(:address).present?
33
+ .col-lg-4.col-md-12.mb-3
34
+ %p
35
+ = fa_icon :map, class: 'fa-lx mr-2 grey-text'
36
+ = yield :address
37
+ - if yield(:schedule).present?
38
+ .col-lg-4.col-md-6.mb-3
39
+ %p
40
+ = fa_icon :building, class: 'fa-lx mr-2 grey-text'
41
+ = yield :schedule
42
+ - if yield(:phone).present?
43
+ .col-lg-4.col-md-6.mb-3
44
+ %p
45
+ = tel_tag yield(:phone) do
46
+ = fa_icon :phone, class: 'fa-lx mr-2 grey-text'
47
+ = yield :phone
48
+ #map-container.z-depth-1-half.map-container{ style: 'height: 400px' }
@@ -0,0 +1,26 @@
1
+ %main.mt-5
2
+ .container
3
+ %section#best-features.text-center{ id: block.anchor }
4
+ %h2.mb-4.font-weight-bold
5
+ = block.title
6
+ .row.d-flex.justify-content-center.mb-4
7
+ .col-md-8
8
+ %p.grey-text
9
+ = block.description
10
+ .row
11
+ - eval("@collection_#{block.anchor}").each do |item|
12
+ .col-md-4.mb-1
13
+ - if item.icon.present?
14
+ %i.fa.fa-camera-retro.fa-4x.orange-text{ class: "fa-#{item.icon}" }
15
+ - else
16
+ = image_tag item.image
17
+ %h4.my-4
18
+ = item.title
19
+ %p.grey-text
20
+ = item.text
21
+ %hr.my-5/
22
+ %section#examples
23
+ %hr.my-5/
24
+ %section#gallery
25
+ %hr.my-5/
26
+ %section#contact
@@ -0,0 +1,16 @@
1
+ = javascript_include_tag 'tramway/landing/footer'
2
+ %footer.page-footer.indigo.center-on-small-only
3
+ .container-fluid
4
+ .row
5
+ .col-md-6
6
+ %h5.title
7
+ = yield :application_name
8
+ %p
9
+ = yield :application_tagline
10
+ .logo_collage.effect-parent
11
+ = yield :footer_logos
12
+ .col-md-6
13
+ = yield :footer_links
14
+ .footer-copyright
15
+ .container-fluid
16
+ = link_to copyright(2018, yield(:application_name)), yield(:application_url)
@@ -0,0 +1,22 @@
1
+ %header
2
+ %nav.navbar.navbar-expand-lg.navbar-dark.indigo.scrolling-navbar.fixed-top
3
+ = link_to yield(:application_name), '#', class: 'navbar-brand'
4
+
5
+ %button.navbar-toggler{ type: :button, data: { toggle: :collapse, target: '#navbarSupportedContent' }, aria: { controls: 'navbarSupportedContent', expanded: 'false', label: 'Toggle navigation' } }
6
+ = fa_icon :bars
7
+ .collapse.navbar-collapse#navbarSupportedContent
8
+ %ul.navbar-nav.mr-auto
9
+ - @blocks.with_navbar_link.each do |block|
10
+ = menu_item block.title, "##{block.anchor}"
11
+ #intro.view.hm-black-strong{ style: "background-image: url('#{block.background.url}')" }
12
+ .container-fluid.full-bg-img.d-flex.align-items-center.justify-content-center
13
+ .row.d-flex.justify-content-center
14
+ .col-md-10.text-center
15
+ %h2.display-3.font-bold.white-text.mb-2
16
+ = yield(:application_name)
17
+ %hr.hr-light
18
+ %h4.white-text.my-4
19
+ = yield(:application_tagline)
20
+ - @blocks.with_navbar_link.each do |block|
21
+ %button.btn.btn-outline-white.waves-effect.waves-light.header-buttons{ type: :button, data: { anchor: "##{block.anchor}" } }
22
+ = block.title
@@ -0,0 +1,9 @@
1
+ .row
2
+ .col-md-7
3
+ = image_tag block.background, class: 'img-fluid'
4
+ .col-md-5
5
+ %h2
6
+ = block.title
7
+ %hr
8
+ %p
9
+ = block.description
@@ -0,0 +1 @@
1
+ Rails.application.config.assets.precompile += %w( tramway/landing/footer.js )
@@ -0,0 +1 @@
1
+ ::Tramway::Admin.set_available_models ::Tramway::Landing::Block
@@ -0,0 +1,19 @@
1
+ ru:
2
+ activerecord:
3
+ models:
4
+ tramway/landing/block: Блок
5
+ attributes:
6
+ tramway/landing/block:
7
+ title: Название
8
+ background: Изображение на фоне
9
+ position: Позиция на странице
10
+ block_type: Тип блока
11
+ view_state: Видимость на сайте
12
+ cases:
13
+ tramway/landing/block:
14
+ plural: Блоки
15
+ genitive: блок
16
+ enumerize:
17
+ tramway/landing/block:
18
+ block_type:
19
+ header: Начальный
@@ -0,0 +1,15 @@
1
+ ru:
2
+ collections:
3
+ tramway/landing/block:
4
+ published: Опубликованные
5
+ hidden: Скрытые
6
+ activerecord:
7
+ state_machines:
8
+ tramway/landing/block:
9
+ view_state:
10
+ states:
11
+ published: Виден
12
+ hidden: Скрытый
13
+ events:
14
+ publish: Показать на сайте
15
+ hide: Скрыть с сайта
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Tramway::Landing::Engine.routes.draw do
2
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :tramway_landing do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,7 @@
1
+ require "tramway/landing/engine"
2
+ require 'tramway/landing/generates/install_generator'
3
+
4
+ module Tramway
5
+ module Landing
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Tramway
2
+ module Landing
3
+ class Engine < ::Rails::Engine
4
+ isolate_namespace Tramway::Landing
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ require 'rails/generators'
2
+ require 'tramway/core/generators/install_generator'
3
+
4
+ module Tramway::Landing::Generators
5
+ class InstallGenerator < ::Tramway::Core::Generators::InstallGenerator
6
+ include Rails::Generators::Migration
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def self.next_migration_number(path)
10
+ next_migration_number = current_migration_number(path) + 1
11
+ ActiveRecord::Migration.next_migration_number next_migration_number
12
+ end
13
+
14
+ def copy_migrations
15
+ migration_template 'create_tramway_landing_blocks.rb', 'db/migrate/create_tramway_landing_blocks.rb'
16
+ migration_template 'add_navbar_link_to_tramway_landing_blocks.rb', 'db/migrate/add_navbar_link_to_tramway_landing_blocks.rb'
17
+ migration_template 'add_anchor_to_tramway_landing_blocks.rb', 'db/migrate/add_anchor_to_tramway_landing_blocks.rb'
18
+ migration_template 'add_description_to_tramway_landing_blocks.rb', 'db/migrate/add_description_to_tramway_landing_blocks.rb'
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ class AddAnchorToTramwayLandingBlocks < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :tramway_landing_blocks, :anchor, :text
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddDescriptionToTramwayLandingBlocks < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :tramway_landing_blocks, :description, :text
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddNavbarLinkToTramwayLandingBlocks < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :tramway_landing_blocks, :navbar_link, :text, default: :not_exist
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ class CreateTramwayLandingBlocks < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :tramway_landing_blocks do |t|
4
+ t.text :title
5
+ t.text :background
6
+ t.text :block_type
7
+ t.integer :position
8
+ t.text :state, default: :active
9
+ t.text :view_state, default: :hidden
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ module Tramway
2
+ module Landing
3
+ VERSION = '1.0'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tramway-landing
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Pavel Kalashnikov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-02-21 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Landing Engine for your Rails projects
14
+ email:
15
+ - kalashnikovisme@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - MIT-LICENSE
21
+ - README.md
22
+ - Rakefile
23
+ - app/assets/config/tramway_landing_manifest.js
24
+ - app/assets/javascripts/justified_images.js
25
+ - app/assets/javascripts/tramway/landing/application.js.coffee
26
+ - app/assets/javascripts/tramway/landing/footer.js.coffee
27
+ - app/assets/stylesheets/tramway/landing/application.css.sass
28
+ - app/assets/stylesheets/tramway/landing/collage.css.sass
29
+ - app/assets/stylesheets/tramway/landing/justified.css
30
+ - app/controllers/tramway/landing/application_controller.rb
31
+ - app/decorators/tramway/landing/block_decorator.rb
32
+ - app/decorators/tramway/landing/block_types/cards_decorator.rb
33
+ - app/decorators/tramway/landing/block_types/features_decorator.rb
34
+ - app/forms/tramway/landing/block_form.rb
35
+ - app/helpers/tramway/landing/application_helper.rb
36
+ - app/jobs/tramway/landing/application_job.rb
37
+ - app/mailers/tramway/landing/application_mailer.rb
38
+ - app/models/tramway/landing/application_record.rb
39
+ - app/models/tramway/landing/block.rb
40
+ - app/uploaders/tramway/landing/photo_versions.rb
41
+ - app/views/layouts/tramway/landing/application.html.haml
42
+ - app/views/tramway/landing/blocks/block_types/_cards.html.haml
43
+ - app/views/tramway/landing/blocks/block_types/_contacts.html.haml
44
+ - app/views/tramway/landing/blocks/block_types/_features.html.haml
45
+ - app/views/tramway/landing/blocks/block_types/_footer.html.haml
46
+ - app/views/tramway/landing/blocks/block_types/_header.html.haml
47
+ - app/views/tramway/landing/blocks/block_types/_page.html.haml
48
+ - config/initializers/assets.rb
49
+ - config/initializers/tramway.rb
50
+ - config/locales/models.yml
51
+ - config/locales/state_machines.yml
52
+ - config/routes.rb
53
+ - lib/tasks/tramway/landing_tasks.rake
54
+ - lib/tramway/landing.rb
55
+ - lib/tramway/landing/engine.rb
56
+ - lib/tramway/landing/generates/install_generator.rb
57
+ - lib/tramway/landing/generates/templates/add_anchor_to_tramway_landing_blocks.rb
58
+ - lib/tramway/landing/generates/templates/add_description_to_tramway_landing_blocks.rb
59
+ - lib/tramway/landing/generates/templates/add_navbar_link_to_tramway_landing_blocks.rb
60
+ - lib/tramway/landing/generates/templates/create_tramway_landing_blocks.rb
61
+ - lib/tramway/landing/version.rb
62
+ homepage: https://github.com/kalashnikovisme/tramway-landing
63
+ licenses:
64
+ - MIT
65
+ metadata: {}
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 2.7.3
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: Landing Engine for your Rails projects
86
+ test_files: []