mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-08-01 18:27:57 -04:00
Material design changes
This commit is contained in:
3
Gemfile
3
Gemfile
@@ -17,6 +17,9 @@ gem 'jsonapi-resources'
|
||||
|
||||
# CSS framework
|
||||
gem 'bootstrap-sass'
|
||||
gem 'bootstrap', '4.1.1'
|
||||
gem 'material-sass', '4.1.1'
|
||||
gem 'material_icons'
|
||||
gem 'font-awesome-sass'
|
||||
|
||||
gem 'uglifier' # JavaScript compressor
|
||||
|
||||
13
Gemfile.lock
13
Gemfile.lock
@@ -66,6 +66,10 @@ GEM
|
||||
bonsai-elasticsearch-rails (7.0.1)
|
||||
elasticsearch-model (< 8)
|
||||
elasticsearch-rails (< 8)
|
||||
bootstrap (4.1.1)
|
||||
autoprefixer-rails (>= 6.0.3)
|
||||
popper_js (>= 1.12.9, < 2)
|
||||
sass (>= 3.5.2)
|
||||
bootstrap-datepicker-rails (1.8.0.1)
|
||||
railties (>= 3.0)
|
||||
bootstrap-kaminari-views (0.0.5)
|
||||
@@ -280,6 +284,11 @@ GEM
|
||||
mini_mime (>= 0.1.1)
|
||||
marcel (0.3.3)
|
||||
mimemagic (~> 0.3.2)
|
||||
material-sass (4.1.1)
|
||||
autoprefixer-rails (>= 6.0.3)
|
||||
sass (>= 3.5.2)
|
||||
material_icons (2.2.1)
|
||||
railties (>= 3.2)
|
||||
memcachier (0.0.2)
|
||||
method_source (0.9.2)
|
||||
mime-types (3.2.2)
|
||||
@@ -336,6 +345,7 @@ GEM
|
||||
capybara (>= 2.1, < 4)
|
||||
cliver (~> 0.3.1)
|
||||
websocket-driver (>= 0.2.0)
|
||||
popper_js (1.14.5)
|
||||
powerpack (0.1.2)
|
||||
public_suffix (3.0.3)
|
||||
puma (3.12.0)
|
||||
@@ -510,6 +520,7 @@ DEPENDENCIES
|
||||
better_errors
|
||||
bluecloth
|
||||
bonsai-elasticsearch-rails
|
||||
bootstrap (= 4.1.1)
|
||||
bootstrap-datepicker-rails
|
||||
bootstrap-kaminari-views
|
||||
bootstrap-sass
|
||||
@@ -556,6 +567,8 @@ DEPENDENCIES
|
||||
letter_opener
|
||||
listen
|
||||
loofah (>= 2.2.1)
|
||||
material-sass (= 4.1.1)
|
||||
material_icons
|
||||
memcachier
|
||||
newrelic_rpm
|
||||
omniauth (~> 1.3)
|
||||
|
||||
@@ -18,4 +18,8 @@
|
||||
// = require jquery-ui/widgets/autocomplete
|
||||
// = require bootstrap-sprockets
|
||||
// = require bootstrap-datepicker
|
||||
// = require jquery
|
||||
// = require popper
|
||||
// = require bootstrap
|
||||
// = require material
|
||||
// = require_tree .
|
||||
|
||||
212
app/assets/javascripts/jquery-roadmap.js
vendored
Normal file
212
app/assets/javascripts/jquery-roadmap.js
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
;(function(factory) {
|
||||
"use strict";
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports !== 'undefined') {
|
||||
module.exports = factory(require('jquery'), window, document);
|
||||
} else {
|
||||
factory(jQuery, window, document);
|
||||
}
|
||||
|
||||
}(function($, window, document, undefined ) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// undefined is used here as the undefined global variable in ECMAScript 3 is
|
||||
// mutable (ie. it can be changed by someone else). undefined isn't really being
|
||||
// passed in so we can ensure the value of it is truly undefined. In ES5, undefined
|
||||
// can no longer be modified.
|
||||
|
||||
// window and document are passed through as local variables rather than global
|
||||
// as this (slightly) quickens the resolution process and can be more efficiently
|
||||
// minified (especially when both are regularly referenced in your plugin).
|
||||
|
||||
/**
|
||||
* jQuery custom plugin implement the roadmap functionality
|
||||
*/
|
||||
$.fn.roadmap = function(events, opts) {
|
||||
if ( !events instanceof Array ) {
|
||||
events = [];
|
||||
}
|
||||
|
||||
var defaults = {
|
||||
slide: 1,
|
||||
eventsPerSlide: 6,
|
||||
rootClass: 'roadmap',
|
||||
prevArrow: 'prev',
|
||||
nextArrow: 'next',
|
||||
orientation: 'auto',
|
||||
eventTemplate: '<div class="event">' +
|
||||
'<div class="event__date">####DATE###</div>' +
|
||||
'<div class="event__content">####CONTENT###</div>' +
|
||||
'</div>'
|
||||
};
|
||||
|
||||
var settings = $.extend({}, defaults, opts);
|
||||
|
||||
var buildEvent = function(event, key) {
|
||||
var html = '<li class="' + settings.rootClass + '__events__event">' + settings.eventTemplate + '</li>';
|
||||
html = html.replace('####DATE###', event.date);
|
||||
html = html.replace('####CONTENT###', event.content);
|
||||
|
||||
var left = (100/(settings.eventsPerSlide-1))*key;
|
||||
|
||||
return $(html).css('left', left + '%');
|
||||
}
|
||||
|
||||
return this.each(function() {
|
||||
var _this = this;
|
||||
var $this = $(this);
|
||||
var currentSlide = settings.slide - 1;
|
||||
|
||||
/**
|
||||
* Store events and settings
|
||||
*/
|
||||
$this.data({
|
||||
events: events,
|
||||
settings: settings,
|
||||
currentSlide: currentSlide
|
||||
}).addClass(settings.rootClass);
|
||||
|
||||
var clear = function() {
|
||||
$this.removeClass(settings.rootClass + '--initialized');
|
||||
|
||||
$this.find('.' + settings.rootClass + '__events').remove();
|
||||
$this.find('.' + settings.rootClass + '__navigation').remove();
|
||||
}
|
||||
|
||||
var buildEvents = function() {
|
||||
var currentSlide = $this.data('currentSlide');
|
||||
var settings = $this.data('settings');
|
||||
var events = $this.data('events');
|
||||
|
||||
$('<ol/>', {class: settings.rootClass + '__events'}).append(events.slice((currentSlide*settings.eventsPerSlide), ((currentSlide+1)*settings.eventsPerSlide)).map(buildEvent)).appendTo(_this);
|
||||
}
|
||||
|
||||
var buildNavigation = function() {
|
||||
var currentSlide = $this.data('currentSlide');
|
||||
|
||||
var buildNav = function(nav) {
|
||||
switch (nav) {
|
||||
case 'prev':
|
||||
if ( currentSlide > 0 ) {
|
||||
return $('<li><a href="#" class="' + nav + '">' + settings.prevArrow + '</a></li>');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'next':
|
||||
if ( (currentSlide+1)*settings.eventsPerSlide < events.length ) {
|
||||
return $('<li><a href="#" class="' + nav + '">' + settings.nextArrow + '</a></li>');
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $('<li></li>');
|
||||
}
|
||||
|
||||
$('<ul/>', {class: settings.rootClass + '__navigation'}).append(['prev', 'next'].map(buildNav)).appendTo(_this);
|
||||
}
|
||||
|
||||
var setOrientation = function() {
|
||||
|
||||
var getOrientation = function() {
|
||||
switch (settings.orientation) {
|
||||
case 'horizontal':
|
||||
case 'vertical':
|
||||
case 'auto':
|
||||
return settings.orientation;
|
||||
break;
|
||||
}
|
||||
|
||||
return 'auto';
|
||||
}
|
||||
|
||||
$this.addClass(settings.rootClass + '--orientation-' + getOrientation());
|
||||
}
|
||||
|
||||
var build = function() {
|
||||
|
||||
clear();
|
||||
|
||||
/**
|
||||
* Init events
|
||||
*/
|
||||
buildEvents();
|
||||
|
||||
/**
|
||||
* Init navigation
|
||||
*/
|
||||
buildNavigation();
|
||||
|
||||
/**
|
||||
* Set orientation
|
||||
*/
|
||||
setOrientation();
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
setTimeout(function() {
|
||||
$this.addClass(settings.rootClass + '--initialized');
|
||||
}, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build roadmap
|
||||
*/
|
||||
build();
|
||||
|
||||
/**
|
||||
* Event Listeners
|
||||
*/
|
||||
$('body').on('click', '.' + settings.rootClass + ' .' + settings.rootClass + '__navigation li > *', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
/**
|
||||
* Handle prev click
|
||||
*/
|
||||
if ( $(this).hasClass('prev') ) {
|
||||
|
||||
var currentSlide = $this.data('currentSlide');
|
||||
if ( currentSlide < 1 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this.data({
|
||||
events: events,
|
||||
settings: settings,
|
||||
currentSlide: currentSlide-1
|
||||
});
|
||||
|
||||
build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle next click
|
||||
*/
|
||||
else {
|
||||
|
||||
var currentSlide = $this.data('currentSlide');
|
||||
if ( (currentSlide+1)*settings.eventsPerSlide >= events.length ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this.data({
|
||||
events: events,
|
||||
settings: settings,
|
||||
currentSlide: currentSlide+1
|
||||
});
|
||||
|
||||
build();
|
||||
}
|
||||
});
|
||||
|
||||
$(window).on('resize', function () {
|
||||
$this.removeClass(settings.rootClass + '--initialized');
|
||||
build();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
||||
@@ -1,9 +1,19 @@
|
||||
@import 'material'
|
||||
@import 'material_icons'
|
||||
@import 'variables'
|
||||
@import 'overrides'
|
||||
|
||||
|
||||
@import 'jquery-ui/autocomplete'
|
||||
@import 'bootstrap-datepicker'
|
||||
@import 'leaflet'
|
||||
@import 'leaflet.markercluster'
|
||||
@import 'custom_bootstrap/custom_bootstrap'
|
||||
@import 'overrides'
|
||||
@import 'graphs'
|
||||
@import 'predictions'
|
||||
@import 'plantings'
|
||||
@import 'plantings'
|
||||
@import 'members'
|
||||
@import 'homepage'
|
||||
|
||||
// Font Awesome
|
||||
@import 'font-awesome-sprockets'
|
||||
@import 'font-awesome'
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
.btn:focus {
|
||||
outline: dotted 2px #000;
|
||||
}
|
||||
div.active:focus {
|
||||
outline: dotted 1px #000;
|
||||
}
|
||||
a:focus {
|
||||
outline: dotted 1px #000;
|
||||
}
|
||||
.close:hover,
|
||||
.close:focus {
|
||||
outline: dotted 1px #000;
|
||||
}
|
||||
.nav > li > a:hover,
|
||||
.nav > li > a:focus {
|
||||
outline: dotted 1px #000;
|
||||
}
|
||||
.carousel-indicators li,
|
||||
.carousel-indicators li.active {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
border-width: 2px;
|
||||
position: relative;
|
||||
box-shadow: 0px 0px 0px 1px #808080;
|
||||
}
|
||||
.carousel-indicators.active li {
|
||||
background-color: rgba(100, 149, 253, 0.6);
|
||||
}
|
||||
.carousel-indicators.active li.active {
|
||||
background-color: white;
|
||||
}
|
||||
.carousel-tablist-highlight {
|
||||
display: block;
|
||||
position: absolute;
|
||||
outline: 2px solid transparent;
|
||||
background-color: transparent;
|
||||
box-shadow: 0px 0px 0px 1px transparent;
|
||||
}
|
||||
.carousel-tablist-highlight.focus {
|
||||
outline: 2px solid #6495ed;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
a.carousel-control:focus {
|
||||
outline: 2px solid #6495ed;
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
transparent 0px,
|
||||
rgba(0, 0, 0, 0.5) 100%
|
||||
);
|
||||
box-shadow: 0px 0px 0px 1px #000000;
|
||||
}
|
||||
.carousel-pause-button {
|
||||
position: absolute;
|
||||
top: -30em;
|
||||
left: -300em;
|
||||
display: block;
|
||||
}
|
||||
.carousel-pause-button.focus {
|
||||
top: 0.5em;
|
||||
left: 0.5em;
|
||||
}
|
||||
.carousel:hover .carousel-caption,
|
||||
.carousel.contrast .carousel-caption {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 10;
|
||||
}
|
||||
.alert-success {
|
||||
color: #2d4821;
|
||||
}
|
||||
.alert-info {
|
||||
color: #214c62;
|
||||
}
|
||||
.alert-warning {
|
||||
color: #6c4a00;
|
||||
background-color: #f9f1c6;
|
||||
}
|
||||
.alert-danger {
|
||||
color: #d2322d;
|
||||
}
|
||||
.alert-danger:hover {
|
||||
color: #a82824;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!! AUTOMATICALLY GENERATED FILE. DO NOT MODIFY !!!
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// Core variables and mixins
|
||||
@import "bootstrap-sprockets"
|
||||
@import "bootstrap/variables"
|
||||
// Modify this for custom colors, font-sizes, etc
|
||||
@import "custom_bootstrap/variables"
|
||||
@import "bootstrap/mixins"
|
||||
// Modify this for custom mixins
|
||||
@import "custom_bootstrap/mixins"
|
||||
|
||||
// Reset and dependencies
|
||||
@import "bootstrap/normalize"
|
||||
@import "bootstrap/print"
|
||||
@import "bootstrap/glyphicons"
|
||||
|
||||
// Core CSS
|
||||
@import "bootstrap/scaffolding"
|
||||
@import "bootstrap/type"
|
||||
@import "bootstrap/code"
|
||||
@import "bootstrap/grid"
|
||||
@import "bootstrap/tables"
|
||||
@import "bootstrap/forms"
|
||||
@import "bootstrap/buttons"
|
||||
|
||||
// Components
|
||||
@import "bootstrap/component-animations"
|
||||
@import "bootstrap/dropdowns"
|
||||
@import "bootstrap/button-groups"
|
||||
@import "bootstrap/input-groups"
|
||||
@import "bootstrap/navs"
|
||||
@import "bootstrap/navbar"
|
||||
@import "bootstrap/breadcrumbs"
|
||||
@import "bootstrap/pagination"
|
||||
@import "bootstrap/pager"
|
||||
@import "bootstrap/labels"
|
||||
@import "bootstrap/badges"
|
||||
@import "bootstrap/jumbotron"
|
||||
@import "bootstrap/thumbnails"
|
||||
@import "bootstrap/alerts"
|
||||
@import "bootstrap/progress-bars"
|
||||
@import "bootstrap/media"
|
||||
@import "bootstrap/list-group"
|
||||
@import "bootstrap/panels"
|
||||
@import "bootstrap/responsive-embed"
|
||||
@import "bootstrap/wells"
|
||||
@import "bootstrap/close"
|
||||
|
||||
// Components w/ JavaScript
|
||||
@import "bootstrap/modals"
|
||||
@import "bootstrap/tooltip"
|
||||
@import "bootstrap/popovers"
|
||||
@import "bootstrap/carousel"
|
||||
|
||||
// Utility classes
|
||||
@import "bootstrap/utilities"
|
||||
@import "bootstrap/responsive-utilities"
|
||||
@@ -1 +0,0 @@
|
||||
// Use this file to override Twitter Bootstrap mixins or define own mixins.
|
||||
17
app/assets/stylesheets/homepage.sass
Normal file
17
app/assets/stylesheets/homepage.sass
Normal file
@@ -0,0 +1,17 @@
|
||||
// let's condense the hero unit a little
|
||||
.jumbotron
|
||||
//padding-top: 30px
|
||||
//padding-bottom: 30px
|
||||
|
||||
// info under the main heading on homepage
|
||||
.jumbotron .info
|
||||
// padding-top: 15px
|
||||
|
||||
// signup widget on homepage
|
||||
.jumbotron .signup
|
||||
background-color: lighten($green, 40%)
|
||||
border: 1px solid lighten($green, 20%)
|
||||
border-radius: 6px
|
||||
line-height: 200%
|
||||
padding: 15px
|
||||
text-align: center
|
||||
381
app/assets/stylesheets/jquery-roadmap.scss
Normal file
381
app/assets/stylesheets/jquery-roadmap.scss
Normal file
@@ -0,0 +1,381 @@
|
||||
// Config
|
||||
@import 'base/variables';
|
||||
@import 'base/mixins';
|
||||
|
||||
@mixin roadmap-default {
|
||||
position: relative;
|
||||
width: 95%;
|
||||
margin: 0 auto;
|
||||
|
||||
.roadmap__events {
|
||||
position: relative;
|
||||
width: calc(100% - 200px);
|
||||
margin: 0 auto;
|
||||
padding: 200px 0;
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
display: block;
|
||||
content: "";
|
||||
width: 0%;
|
||||
height: 4px;
|
||||
background-color: $primary-color;
|
||||
// box-shadow: 0 0 30px -1px rgba($primary-color, 0.2);
|
||||
border-radius: 2px;
|
||||
|
||||
transition: all 0.5s linear;
|
||||
}
|
||||
|
||||
&__event {
|
||||
position: absolute;
|
||||
width: 280px;
|
||||
height: 200px;
|
||||
margin-left: -140px;
|
||||
list-style: none;
|
||||
font-size: 16px;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
display: block;
|
||||
background-color: $primary-color;
|
||||
// box-shadow: 0 0 30px -1px rgba($primary-color, 0.2);
|
||||
|
||||
transition: all 0.3s $transition-function;
|
||||
}
|
||||
|
||||
&:before {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
&:after {
|
||||
width: 4px;
|
||||
// height: 62px;
|
||||
height: 0;
|
||||
border-radius: 2px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.event {
|
||||
position: absolute;
|
||||
display: block;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
|
||||
transition: all 0.3s $transition-function;
|
||||
transform: scale(0);
|
||||
|
||||
.event__date {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.event__content {
|
||||
|
||||
small {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Events showing on the bottom of the timeline
|
||||
*/
|
||||
&:nth-child(odd) {
|
||||
bottom: 0;
|
||||
|
||||
&:before {
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.event {
|
||||
top: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Events showing on the top of the timeline
|
||||
*/
|
||||
&:nth-child(even) {
|
||||
top: 0;
|
||||
|
||||
&:before {
|
||||
bottom: -12px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
bottom: -4px;
|
||||
}
|
||||
|
||||
.event {
|
||||
bottom: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
@for $i from 1 through 15 {
|
||||
&:nth-child(#{$i}n) {
|
||||
|
||||
&:before,
|
||||
&:after,
|
||||
.event {
|
||||
transition-delay: #{$i * 0.13}s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.roadmap__navigation {
|
||||
margin: 0;
|
||||
|
||||
&>* {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-46%);
|
||||
z-index: 100;
|
||||
list-style: none;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
color: #000;
|
||||
line-height: 0;
|
||||
|
||||
i {
|
||||
font-size: 44px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
left: 40px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
right: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.prev {}
|
||||
.next {}
|
||||
}
|
||||
|
||||
&.roadmap--initialized {
|
||||
|
||||
.roadmap__events {
|
||||
|
||||
&:after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.roadmap__events__event {
|
||||
|
||||
/**
|
||||
* Dot
|
||||
*/
|
||||
&:before {
|
||||
transform: scale(1) translateX(-50%);
|
||||
}
|
||||
|
||||
/**
|
||||
* Line
|
||||
*/
|
||||
&:after {
|
||||
height: 62px;
|
||||
}
|
||||
|
||||
.event {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin roadmap-vertical {
|
||||
margin: $gap*2 auto;
|
||||
|
||||
.roadmap__events {
|
||||
padding: 0;
|
||||
width: 80%;
|
||||
max-width: 640px;
|
||||
min-height: 400px;
|
||||
|
||||
&:after {
|
||||
left: 50%;
|
||||
top: 0;
|
||||
width: 4px;
|
||||
height: calc(0% - 0px);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
&__event {
|
||||
position: relative;
|
||||
left: auto !important;
|
||||
top: auto;
|
||||
bottom: auto;
|
||||
margin-left: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
min-height: 120px;
|
||||
|
||||
&:before {
|
||||
top: -8px;
|
||||
bottom: auto;
|
||||
}
|
||||
|
||||
&:after {
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
// width: 48px;
|
||||
width: 0;
|
||||
height: 4px !important;
|
||||
}
|
||||
|
||||
.event {
|
||||
top: -15px;
|
||||
bottom: auto;
|
||||
width: 40%;
|
||||
|
||||
@include sm-down {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Events showing on the left of the timeline
|
||||
*/
|
||||
&:nth-child(odd) {
|
||||
|
||||
&:before {}
|
||||
|
||||
&:after {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.event {
|
||||
@include sm-down {
|
||||
margin-left: -10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Events showing on the right of the timeline
|
||||
*/
|
||||
&:nth-child(even) {
|
||||
|
||||
&:before {
|
||||
// margin-left: -12px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
transform: translateX(0%);
|
||||
}
|
||||
|
||||
.event {
|
||||
right: 0;
|
||||
|
||||
@include sm-down {
|
||||
margin-right: -10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.roadmap--initialized {
|
||||
|
||||
.roadmap__events {
|
||||
|
||||
&:after {
|
||||
width: 4px;
|
||||
height: calc(100% - 120px);
|
||||
}
|
||||
|
||||
.roadmap__events__event {
|
||||
|
||||
/**
|
||||
* Dot
|
||||
*/
|
||||
&:before {}
|
||||
|
||||
/**
|
||||
* Line
|
||||
*/
|
||||
&:after {
|
||||
width: 48px;
|
||||
|
||||
@include sm-down {
|
||||
width: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.event {}
|
||||
|
||||
/**
|
||||
* Events showing on the left of the timeline
|
||||
*/
|
||||
&:nth-child(odd) {
|
||||
|
||||
&:before {}
|
||||
|
||||
&:after {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.event {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Events showing on the right of the timeline
|
||||
*/
|
||||
&:nth-child(even) {
|
||||
|
||||
&:before {}
|
||||
|
||||
&:after {
|
||||
transform: translateX(0%);
|
||||
}
|
||||
|
||||
.event {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.roadmap {
|
||||
|
||||
&.roadmap--orientation-auto {
|
||||
@include roadmap-default;
|
||||
|
||||
@include md-down {
|
||||
@include roadmap-vertical;
|
||||
}
|
||||
}
|
||||
|
||||
&.roadmap--orientation-horizontal {
|
||||
@include roadmap-default;
|
||||
}
|
||||
|
||||
&.roadmap--orientation-vertical {
|
||||
@include roadmap-default;
|
||||
@include roadmap-vertical;
|
||||
}
|
||||
}
|
||||
19
app/assets/stylesheets/members.sass
Normal file
19
app/assets/stylesheets/members.sass
Normal file
@@ -0,0 +1,19 @@
|
||||
.member-cards
|
||||
display: flex
|
||||
flex: none
|
||||
flex-wrap: wrap
|
||||
|
||||
.member-thumbnail
|
||||
padding: .25em
|
||||
margin: 1em
|
||||
border-radius: 12px
|
||||
height: 200px
|
||||
|
||||
div
|
||||
width: 5em
|
||||
display: inline-block
|
||||
vertical-align: top
|
||||
|
||||
.member-thumbnail div~div
|
||||
padding-left: 1em
|
||||
width: 15em
|
||||
@@ -1,6 +1,5 @@
|
||||
@import "bootstrap-sprockets"
|
||||
@import "bootstrap"
|
||||
@import "custom_bootstrap/variables"
|
||||
// this padding needs to be done before the responsive stuff is imported
|
||||
body
|
||||
padding-top: $navbar-height
|
||||
@@ -72,7 +71,13 @@ h3
|
||||
|
||||
// info under the main heading on homepage
|
||||
.jumbotron .info
|
||||
padding-top: 15px
|
||||
//padding-top: 15px
|
||||
padding: 0.5em
|
||||
text-align: center
|
||||
|
||||
p
|
||||
|
||||
|
||||
|
||||
// signup widget on homepage
|
||||
.jumbotron .signup
|
||||
@@ -87,29 +92,12 @@ h3
|
||||
p.stats
|
||||
font-weight: bold
|
||||
|
||||
.member-cards
|
||||
display: flex
|
||||
flex: none
|
||||
flex-wrap: wrap
|
||||
|
||||
.card-row
|
||||
display: grid
|
||||
grid-template-columns: 50% 50%
|
||||
grid-gap: 25px
|
||||
grid-row-gap: 5px
|
||||
|
||||
.member-thumbnail
|
||||
padding: .25em
|
||||
margin: 1em
|
||||
|
||||
div
|
||||
width: 5em
|
||||
display: inline-block
|
||||
vertical-align: top
|
||||
|
||||
.member-thumbnail div~div
|
||||
padding-left: 1em
|
||||
width: 15em
|
||||
|
||||
.progress
|
||||
border-radius: 0
|
||||
@@ -117,7 +105,6 @@ p.stats
|
||||
text-align: center
|
||||
|
||||
.layout-actions
|
||||
width: 100%
|
||||
|
||||
#placesmap, #cropmap
|
||||
height: 500px
|
||||
@@ -141,6 +128,8 @@ p.stats
|
||||
.member-location a
|
||||
color: $brown
|
||||
|
||||
.associations
|
||||
list-style-type: none
|
||||
|
||||
.photo-thumbnail
|
||||
padding: 0
|
||||
@@ -168,11 +157,20 @@ p.stats
|
||||
display: block
|
||||
|
||||
.thumbnail
|
||||
border: none
|
||||
// border: 1px solid lighten($green, 20%)
|
||||
text-align: center
|
||||
margin-bottom: 1.5em
|
||||
max-width: 160px
|
||||
max-height: 200px
|
||||
//max-height: 220px
|
||||
//height: 180px
|
||||
|
||||
.seed-thumbnail
|
||||
height: 220px
|
||||
.seedinfo
|
||||
.seed-name
|
||||
font-size: 120%
|
||||
overflow: hidden
|
||||
|
||||
|
||||
.member-thumbnail
|
||||
text-align: left
|
||||
@@ -182,8 +180,8 @@ p.stats
|
||||
max-width: 85px
|
||||
|
||||
.crop-thumbnail
|
||||
height: 220px
|
||||
.cropinfo
|
||||
margin-top: 0.5em
|
||||
display: inline-block
|
||||
max-width: 100%
|
||||
white-space: nowrap
|
||||
@@ -193,15 +191,21 @@ p.stats
|
||||
.cropname
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
font-size: 120%
|
||||
|
||||
|
||||
.scientificname
|
||||
font-size: small
|
||||
font-style: italic
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
font-size: 70%
|
||||
|
||||
|
||||
.plantingcount
|
||||
font-size: small
|
||||
.planting-lifespan
|
||||
font-size: 70%
|
||||
|
||||
.crop-name a
|
||||
padding-top: 2px
|
||||
@@ -257,11 +261,9 @@ html, body
|
||||
height: 100%
|
||||
|
||||
.crop-image, .member-image
|
||||
width: 100%
|
||||
height: 100%
|
||||
border-radius: 50%
|
||||
|
||||
// Autosuggest
|
||||
|
||||
.ui-autocomplete
|
||||
background: white
|
||||
z-index: $zindex-tooltip
|
||||
@@ -363,8 +365,6 @@ ul.thumbnail-buttons
|
||||
.homepage
|
||||
.thumbnail
|
||||
height: 180px
|
||||
.seed-thumbnail
|
||||
height: 220px
|
||||
|
||||
#maincontainer
|
||||
padding: 10px
|
||||
|
||||
@@ -26,8 +26,9 @@
|
||||
top: -0.5em
|
||||
.planting-quick-actions
|
||||
position: absolute
|
||||
left: 142px
|
||||
top: 6px
|
||||
top: 0px
|
||||
left: 130px
|
||||
|
||||
.planting-thumbnail-photo
|
||||
height: 150px
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
.predictions
|
||||
.prediction-metric
|
||||
text-align: center
|
||||
height: 180px
|
||||
border: 1px solid lighten($green, 20%)
|
||||
border-radius: 5%
|
||||
background: $white
|
||||
margin: 4px
|
||||
margin: 1em
|
||||
strong
|
||||
font-size: 4em
|
||||
font-align: center
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Use this file to override Twitter Bootstrap variables or define own variables.
|
||||
|
||||
// Import original variables so they can be used in overrides
|
||||
@import 'bootstrap/variables.scss'
|
||||
//@import 'bootstrap/variables.scss'
|
||||
//$screen-md-min: 1028px
|
||||
|
||||
// Base colours
|
||||
|
||||
$beige: #f3f1ee
|
||||
$brown: #413f3b
|
||||
|
||||
@@ -22,7 +22,7 @@ $graph-hover: $orange
|
||||
|
||||
$brand-primary: $green
|
||||
|
||||
$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||
$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||
$font-family-serif: Georgia, "Times New Roman", Times, serif
|
||||
$font-family-mono: Monaco, Menlo, Consolas, "Courier New", monospace
|
||||
|
||||
@@ -33,7 +33,7 @@ $alt-font-family: $font-family-serif
|
||||
|
||||
$headings-font-family: $font-family-sans-serif
|
||||
$headings-font-weight: bold // instead of browser default, bold
|
||||
$headings-color: inherit // empty to use BS default, $textColor
|
||||
$headings-color: inherit // empty to use BS default, $textColor
|
||||
|
||||
// Hero unit
|
||||
$jumbotron-bg: darken($body-bg, 10%)
|
||||
@@ -48,9 +48,10 @@ $navbar-default-link-active-color: darken($beige,80%)
|
||||
$navbar-default-brand-color: lighten($green, 20%)
|
||||
|
||||
// Top nav collapse threshold
|
||||
$grid-float-breakpoint: $screen-md-min
|
||||
//$grid-float-breakpoint: $screen-md-min
|
||||
|
||||
$dropdown-bg: lighten($beige, 10%)
|
||||
$dropdown-link-color: $brown
|
||||
$dropdown-link-hover-color: $brown
|
||||
$dropdown-link-hover-bg: lighten($green, 50%)
|
||||
|
||||
@@ -27,11 +27,9 @@ module ApplicationHelper
|
||||
end
|
||||
|
||||
def required_field_help_text
|
||||
# rubocop:disable Rails/OutputSafety
|
||||
asterisk = content_tag :span, '*', class: ['red']
|
||||
text = content_tag :em, 'denotes a required field'
|
||||
content_tag :div, asterisk + ' '.html_safe + text, class: ['margin-bottom']
|
||||
# rubocop:enable Rails/OutputSafety
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module ButtonsHelper
|
||||
include IconsHelper
|
||||
def garden_plant_something_button(garden)
|
||||
link_to new_planting_path(garden_id: garden.id), class: "btn btn-default btn-xs btn-primary" do
|
||||
link_to new_planting_path(garden_id: garden.id), class: "btn btn-default" do
|
||||
planting_icon + ' ' + t('buttons.plant_something_here')
|
||||
end
|
||||
end
|
||||
@@ -9,13 +9,13 @@ module ButtonsHelper
|
||||
def garden_mark_active_button(garden)
|
||||
link_to t('buttons.mark_as_active'),
|
||||
garden_path(garden, garden: { active: 1 }),
|
||||
method: :put, class: 'btn btn-default btn-xs'
|
||||
method: :put, class: 'btn'
|
||||
end
|
||||
|
||||
def garden_mark_inactive_button(garden)
|
||||
link_to t('buttons.mark_as_inactive'),
|
||||
garden_path(garden, garden: { active: 0 }),
|
||||
method: :put, class: 'btn btn-default btn-xs',
|
||||
method: :put, class: 'btn',
|
||||
data: { confirm: 'All plantings associated with this garden will be marked as finished. Are you sure?' }
|
||||
end
|
||||
|
||||
@@ -43,7 +43,15 @@ module ButtonsHelper
|
||||
return unless can?(:edit, planting) || planting.finished
|
||||
|
||||
link_to planting_path(planting, planting: { finished: 1 }),
|
||||
method: :put, class: 'btn btn-default btn-xs append-date' do
|
||||
method: :put, class: 'btn btn-default btn-secondary append-date' do
|
||||
finished_icon + ' ' + t('buttons.mark_as_finished')
|
||||
end
|
||||
end
|
||||
|
||||
def seed_finish_button(seed)
|
||||
return unless can?(:create, Planting) && seed.active?
|
||||
|
||||
link_to seed_path(seed, seed: { finished: 1 }), method: :put, class: 'btn btn-default append-date' do
|
||||
finished_icon + ' ' + t('buttons.mark_as_finished')
|
||||
end
|
||||
end
|
||||
@@ -51,7 +59,7 @@ module ButtonsHelper
|
||||
def planting_harvest_button(planting)
|
||||
return unless planting.active? && can?(:create, Harvest) && can?(:edit, planting)
|
||||
|
||||
link_to new_planting_harvest_path(planting), class: "btn btn-default btn-xs" do
|
||||
link_to new_planting_harvest_path(planting), class: "btn btn-default" do
|
||||
harvest_icon + ' ' + t('buttons.harvest')
|
||||
end
|
||||
end
|
||||
@@ -59,7 +67,7 @@ module ButtonsHelper
|
||||
def planting_save_seeds_button(planting)
|
||||
return unless can?(:edit, planting)
|
||||
|
||||
link_to new_planting_seed_path(planting), class: "btn btn-default btn-xs" do
|
||||
link_to new_planting_seed_path(planting), class: "btn btn-default" do
|
||||
seed_icon + ' ' + t('buttons.save_seeds')
|
||||
end
|
||||
end
|
||||
@@ -68,13 +76,13 @@ module ButtonsHelper
|
||||
return unless can?(:edit, model) && can?(:create, Photo)
|
||||
|
||||
link_to new_photo_path(id: model.id, type: model_type_for_photo(model)),
|
||||
class: "btn btn-default btn-xs" do
|
||||
class: "btn btn-default" do
|
||||
photo_icon + ' ' + t('buttons.add_photo')
|
||||
end
|
||||
end
|
||||
|
||||
def edit_button(path)
|
||||
link_to path, class: "btn btn-default btn-xs" do
|
||||
link_to path, class: "btn btn-raised btn-info" do
|
||||
edit_icon + ' ' + t('buttons.edit')
|
||||
end
|
||||
end
|
||||
@@ -82,7 +90,7 @@ module ButtonsHelper
|
||||
def delete_button(model, message: 'are_you_sure')
|
||||
return unless can? :destroy, model
|
||||
|
||||
link_to model, method: :delete, data: { confirm: t(message) }, class: 'btn btn-default btn-xs' do
|
||||
link_to model, method: :delete, data: { confirm: t(message) }, class: 'btn btn-danger' do
|
||||
delete_icon + ' ' + t('buttons.delete')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,9 +15,10 @@ module PhotosHelper
|
||||
end
|
||||
end
|
||||
|
||||
def planting_image_path(planting)
|
||||
def planting_image_path(planting, full_size: false)
|
||||
if planting.photos.present?
|
||||
planting.photos.order(date_taken: :desc).first.thumbnail_url
|
||||
photo = planting.photos.order(date_taken: :desc).first
|
||||
full_size ? photo.fullsize_url : photo.thumbnail_url
|
||||
else
|
||||
placeholder_image
|
||||
end
|
||||
@@ -33,11 +34,13 @@ module PhotosHelper
|
||||
end
|
||||
end
|
||||
|
||||
def seed_image_path(seed)
|
||||
def seed_image_path(seed, full_size: false)
|
||||
if seed.default_photo.present?
|
||||
seed.default_photo.thumbnail_url
|
||||
photo = seed.default_photo
|
||||
full_size ? photo.fullsize_url : photo.thumbnail_url
|
||||
elsif seed.crop.default_photo.present?
|
||||
seed.crop.default_photo.thumbnail_url
|
||||
photo = seed.crop.default_photo
|
||||
full_size ? photo.fullsize_url : photo.thumbnail_url
|
||||
else
|
||||
placeholder_image
|
||||
end
|
||||
|
||||
@@ -23,7 +23,7 @@ class Planting < ApplicationRecord
|
||||
# Ancestry of food
|
||||
belongs_to :parent_seed, class_name: 'Seed', # parent
|
||||
foreign_key: 'parent_seed_id',
|
||||
required: false,
|
||||
optional: true,
|
||||
inverse_of: :child_plantings
|
||||
has_many :child_seeds, class_name: 'Seed', # children
|
||||
foreign_key: 'parent_planting_id',
|
||||
|
||||
@@ -14,7 +14,7 @@ class Seed < ApplicationRecord
|
||||
# Relationships
|
||||
belongs_to :crop
|
||||
belongs_to :parent_planting, class_name: 'Planting', foreign_key: 'parent_planting_id',
|
||||
required: false, inverse_of: :child_seeds # parent
|
||||
optional: true, inverse_of: :child_seeds # parent
|
||||
has_many :child_plantings, class_name: 'Planting',
|
||||
foreign_key: 'parent_seed_id', dependent: :nullify,
|
||||
inverse_of: :parent_seed # children
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
.crop-actions
|
||||
.btn-group
|
||||
- if can? :create, Planting
|
||||
= link_to new_planting_path(crop_id: crop.id), class: 'btn btn-default' do
|
||||
= planting_icon
|
||||
= t('buttons.plant_crop', crop_name: crop.name)
|
||||
- if signed_in?
|
||||
|
||||
- if can? :create, Harvest
|
||||
= link_to new_harvest_path(crop_id: crop.id), class: 'btn btn-default' do
|
||||
= harvest_icon
|
||||
= t('buttons.harvest_crop', crop_name: crop.name)
|
||||
|
||||
- if can? :create, Seed
|
||||
= link_to new_seed_path(crop_id: crop.id), class: 'btn btn-default' do
|
||||
= seed_icon
|
||||
= t('buttons.add_seed_to_stash', crop_name: crop.name)
|
||||
.crop-actions
|
||||
.btn-group
|
||||
- if can? :create, Planting
|
||||
= link_to new_planting_path(crop_id: crop.id), class: 'btn btn-default' do
|
||||
= planting_icon
|
||||
= t('buttons.plant_crop', crop_name: crop.name)
|
||||
|
||||
- if can? :create, Harvest
|
||||
= link_to new_harvest_path(crop_id: crop.id), class: 'btn btn-default' do
|
||||
= harvest_icon
|
||||
= t('buttons.harvest_crop', crop_name: crop.name)
|
||||
|
||||
- if can? :create, Seed
|
||||
= link_to new_seed_path(crop_id: crop.id), class: 'btn btn-default' do
|
||||
= seed_icon
|
||||
= t('buttons.add_seed_to_stash', crop_name: crop.name)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
- [Planting, Harvest, Seed].each do |model_name|
|
||||
.row
|
||||
.col-md-12
|
||||
%h3
|
||||
= @crop.name
|
||||
= t("activerecord.models.#{model_name.to_s.downcase}.other")
|
||||
.row
|
||||
- photos.by_model(model_name).limit(6).each do |photo|
|
||||
.col-md-2.six-across
|
||||
.thumbnail= link_to image_tag(photo.thumbnail_url, alt: photo.title, class: 'img'), photo
|
||||
- if @crop.photos.size.positive?
|
||||
%h2 Photos
|
||||
- [Planting, Harvest, Seed].each do |model_name|
|
||||
- if photos.by_model(model_name).size.positive?
|
||||
%h3 #{@crop.name} #{t("activerecord.models.#{model_name.to_s.downcase}.other")}
|
||||
.row
|
||||
- photos.by_model(model_name).limit(6).each do |photo|
|
||||
.col-md-2.six-across
|
||||
.thumbnail= link_to image_tag(photo.thumbnail_url, alt: photo.title, class: 'img'), photo
|
||||
|
||||
%p.text-right= link_to 'more photos »', crop_photos_path(@crop), class: 'btn'
|
||||
|
||||
@@ -1,32 +1,51 @@
|
||||
%h3 Predictions
|
||||
.predictions
|
||||
- unless crop.perennial.nil?
|
||||
.row
|
||||
.col-md-12
|
||||
%p
|
||||
#{crop.name} is
|
||||
- if crop.perennial == true
|
||||
= link_to 'https://en.wikipedia.org/wiki/Annual_vs._perennial_plant_evolution' do
|
||||
a perennial crop
|
||||
(living more than two years)
|
||||
- elsif crop.perennial == false
|
||||
= link_to 'https://en.wikipedia.org/wiki/Annual_vs._perennial_plant_evolution' do
|
||||
an annual crop
|
||||
(living and reproducing in a single year or less)
|
||||
.row
|
||||
- unless crop.perennial.nil?
|
||||
.col-md-3.col-xs-5
|
||||
.card
|
||||
.card-body.text-center
|
||||
%h3
|
||||
= link_to 'https://en.wikipedia.org/wiki/Annual_vs._perennial_plant_evolution' do
|
||||
- if crop.perennial == true
|
||||
Perennial
|
||||
- elsif crop.perennial == false
|
||||
Annual
|
||||
|
||||
.d-flex.justify-content-between
|
||||
%p.display-1
|
||||
%i.far.fa-calendar
|
||||
|
||||
|
||||
- if crop.perennial == true
|
||||
%small living more than two years
|
||||
- elsif crop.perennial == false
|
||||
%small living and reproducing in a single year or less
|
||||
|
||||
- if crop.annual? && crop.median_lifespan.present?
|
||||
.prediction-metric.col-md-3.col-xs-5
|
||||
%h3 Median lifespan
|
||||
%strong= crop.median_lifespan
|
||||
%span days
|
||||
.col-md-3.col-xs-5
|
||||
.card
|
||||
.card-body.text-center
|
||||
%h3 Median lifespan
|
||||
.d-flex.justify-content-between
|
||||
%p.display-1= crop.median_lifespan
|
||||
%i.fas.fa-sun-o.fa-5x.pt-3.amber-text
|
||||
%span days
|
||||
|
||||
|
||||
- if crop.median_days_to_first_harvest.present?
|
||||
.prediction-metric.col-md-3.col-xs-5
|
||||
%h3 First harvest expected
|
||||
%strong= crop.median_days_to_first_harvest
|
||||
%span days after planting
|
||||
.col-md-3.col-xs-5
|
||||
.card
|
||||
.card-body.text-center
|
||||
%h3 First harvest expected
|
||||
%p.display-1= crop.median_days_to_first_harvest
|
||||
%span days after planting
|
||||
|
||||
- if crop.annual? && crop.median_days_to_last_harvest.present?
|
||||
.prediction-metric.col-md-3.col-xs-5
|
||||
%h3 Last harvest expected
|
||||
%strong= crop.median_days_to_last_harvest
|
||||
%span days after planting
|
||||
.col-md-3.col-xs-5
|
||||
.card
|
||||
.card-body.text-center
|
||||
%h3 Last harvest expected
|
||||
%p.display-1= crop.median_days_to_last_harvest
|
||||
%span days after planting
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
= form_tag search_crops_path, method: :get, id: 'navbar-search' do
|
||||
= form_tag 'search' do
|
||||
-# , method: :get, id: 'navbar-search' do
|
||||
= label_tag :term, "Search crop database:", class: 'sr-only'
|
||||
.input
|
||||
.input-group
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
- cache cache_key_for(Crop, crop.id) do
|
||||
.thumbnail
|
||||
.crop-thumbnail
|
||||
- if crop
|
||||
= link_to image_tag(crop_image_path(crop),
|
||||
alt: crop.name, class: 'img'),
|
||||
crop
|
||||
.cropinfo
|
||||
.cropname
|
||||
= link_to crop.name, crop
|
||||
- unless crop.scientific_names.empty?
|
||||
.scientificname
|
||||
= crop.scientific_names.first.name
|
||||
- if crop.annual? && crop.median_lifespan.present?
|
||||
.planting-lifespan
|
||||
lifespan
|
||||
%strong= crop.median_lifespan
|
||||
days
|
||||
= link_to image_tag(crop_image_path(crop),
|
||||
alt: crop.name, class: 'img'),
|
||||
crop
|
||||
.cropinfo
|
||||
.cropname
|
||||
= link_to crop.name, crop
|
||||
- unless crop.scientific_names.empty?
|
||||
.scientificname
|
||||
= crop.scientific_names.first.name
|
||||
- if crop.annual? && crop.median_lifespan.present?
|
||||
.planting-lifespan
|
||||
lifespan
|
||||
%strong= crop.median_lifespan
|
||||
days
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
- content_for :title, t('.title')
|
||||
- content_for :subtitle, t('.subtitle', crops_size: @crops.size)
|
||||
|
||||
- if can? :wrangle, Crop
|
||||
= link_to 'Wrangle Crops', wrangle_crops_path, class: 'btn btn-primary'
|
||||
- content_for :buttonbar do
|
||||
- if can? :wrangle, Crop
|
||||
= link_to 'Wrangle Crops', wrangle_crops_path, class: 'btn btn-secondary'
|
||||
- if can? :create, Crop
|
||||
= link_to 'Add new Crop', new_crop_path, class: 'btn btn-primary'
|
||||
|
||||
|
||||
- if @num_requested_crops && @num_requested_crops.positive?
|
||||
= link_to(I18n.t('crops.requested.link', number_crops: @num_requested_crops), requested_crops_path)
|
||||
@@ -30,9 +34,6 @@
|
||||
.col-md-2.six-across
|
||||
= render partial: "thumbnail", locals: { crop: crop }
|
||||
|
||||
- if can? :create, Crop
|
||||
%div
|
||||
= link_to 'New Crop', new_crop_path, class: 'btn btn-primary'
|
||||
|
||||
.pagination
|
||||
= will_paginate @crops
|
||||
|
||||
@@ -21,34 +21,35 @@
|
||||
.col-md-9
|
||||
%h2
|
||||
- if !@crop.plantings.empty?
|
||||
= @crop.name.titleize
|
||||
has been planted
|
||||
#{@crop.name.titleize} has been planted
|
||||
= pluralize(@crop.plantings.size, "time")
|
||||
by #{ENV['GROWSTUFF_SITE_NAME']} members.
|
||||
- else
|
||||
Nobody is growing this yet. You could be the first!
|
||||
%hr/
|
||||
|
||||
|
||||
%h3 Predictions
|
||||
= render 'predictions', crop: @crop
|
||||
%hr/
|
||||
|
||||
= render 'crops/photos', photos: @photos
|
||||
%hr/
|
||||
|
||||
%h2 Photos
|
||||
%p= render 'crops/photos', photos: @photos
|
||||
%p= link_to 'more photos', crop_photos_path(@crop)
|
||||
|
||||
|
||||
.row
|
||||
.col-md-3
|
||||
%h3 Sunniness
|
||||
= pie_chart crop_sunniness_path(@crop, format: :json), legend: "bottom"
|
||||
.col-md-3
|
||||
%h3 Planted from
|
||||
= pie_chart crop_planted_from_path(@crop, format: :json), legend: "bottom"
|
||||
.col-md-3
|
||||
%h3 Harvested for
|
||||
= pie_chart crop_harvested_for_path(@crop, format: :json), legend: "bottom"
|
||||
|
||||
.row.text-center
|
||||
.col-md-4
|
||||
.card
|
||||
.card-body
|
||||
%h3.section-heading.h3.pt-4 Sunniness
|
||||
= pie_chart crop_sunniness_path(@crop, format: :json), legend: "bottom"
|
||||
.col-md-4
|
||||
.card
|
||||
.card-body
|
||||
%h3.section-heading.h3.pt-4 Planted from
|
||||
= pie_chart crop_planted_from_path(@crop, format: :json), legend: "bottom"
|
||||
.col-md-4
|
||||
.card
|
||||
.card-body
|
||||
%h3.section-heading.h3.pt-4 Harvested for
|
||||
= pie_chart crop_harvested_for_path(@crop, format: :json), legend: "bottom"
|
||||
|
||||
= render 'varieties', crop: @crop
|
||||
|
||||
@@ -59,27 +60,18 @@
|
||||
= link_to "Set your location.", edit_member_registration_path
|
||||
#cropmap
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
= render 'crops/posts', crop: @crop
|
||||
= render 'crops/posts', crop: @crop
|
||||
|
||||
.col-md-3
|
||||
|
||||
= render partial: 'wrangle', locals: { crop: @crop }
|
||||
|
||||
%p
|
||||
%li
|
||||
= link_to crop_seeds_path(@crop) do
|
||||
View all #{@crop.name} seeds
|
||||
(#{@crop.seeds.size})
|
||||
%li
|
||||
= link_to crop_plantings_path(@crop) do
|
||||
View all #{@crop.name} plantings
|
||||
(#{@crop.plantings.size})
|
||||
%li
|
||||
= link_to crop_harvests_path(@crop) do
|
||||
View all #{@crop.name} harvests
|
||||
(#{@crop.harvests.size})
|
||||
= link_to crop_plantings_path(@crop) do
|
||||
View all #{@crop.name} plantings
|
||||
(#{@crop.plantings.size})
|
||||
%p
|
||||
= link_to crop_harvests_path(@crop) do
|
||||
View all #{@crop.name} harvests
|
||||
(#{@crop.harvests.size})
|
||||
- if member_signed_in?
|
||||
%p
|
||||
= link_to member_seeds_path(current_member, crop_slug: @crop.slug) do
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
.col-md-2.col-xs-12.garden-info
|
||||
%p= render 'gardens/photo', garden: garden
|
||||
%p= display_garden_description(garden)
|
||||
- if can?(:edit, garden)
|
||||
= render 'gardens/actions', garden: garden
|
||||
|
||||
.col-md-10
|
||||
- if garden.plantings.current.size.positive?
|
||||
.row
|
||||
@@ -15,5 +18,3 @@
|
||||
= render "plantings/thumbnail", planting: planting
|
||||
- else
|
||||
no plantings
|
||||
- if can?(:edit, garden)
|
||||
.panel-footer= render 'gardens/actions', garden: garden
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
|
||||
- if can?(:edit, @garden) && can?(:create, Photo)
|
||||
%p
|
||||
=
|
||||
= link_to new_photo_path(type: "garden", id: @garden.id),
|
||||
class: 'btn btn-primary' do
|
||||
%span.glyphicon.glyphicon-camera{ title: "Add photo" }
|
||||
@@ -108,5 +109,4 @@
|
||||
%h3= localize_plural(@garden.photos, Photo)
|
||||
.row
|
||||
- @garden.photos.includes(:owner).each do |photo|
|
||||
.col-xs-6
|
||||
= render partial: 'photos/thumbnail', locals: { photo: photo }
|
||||
.col-xs-6= render partial: 'photos/thumbnail', locals: { photo: photo }
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
- harvests.each do |h|
|
||||
- cache h do
|
||||
.row
|
||||
.col-lg-6.col-md-3.col-xs-4.homepage-listing
|
||||
= render 'harvests/image_with_popover', harvest: h
|
||||
.col-lg-3.col-md-9.col-xs-4
|
||||
= link_to h.crop, crop_path(h.crop)
|
||||
%br/
|
||||
- harvests.each do |harvest|
|
||||
- cache harvest do
|
||||
.card
|
||||
.view.overlay
|
||||
= link_to harvest do
|
||||
%img.card-img-top.img-responsive{alt: harvest, src: harvest.default_photo.fullsize_url}/
|
||||
.card-body.p-3
|
||||
%h5.card-title.font-weight-bold.fuchsia-rose-text.mb-0
|
||||
= link_to harvest, harvest
|
||||
%small
|
||||
%i= h.owner.location
|
||||
%i= harvest.owner.location
|
||||
%hr/
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
.container
|
||||
.row
|
||||
.col-md-12
|
||||
%h1= ENV['GROWSTUFF_SITE_NAME']
|
||||
.col-md-8.info
|
||||
%p= t('.intro', site_name: ENV['GROWSTUFF_SITE_NAME'])
|
||||
= render partial: 'stats'
|
||||
.col-md-4.signup
|
||||
.row
|
||||
.col-md-8.info
|
||||
%h1= ENV['GROWSTUFF_SITE_NAME']
|
||||
%p= t('.intro', site_name: ENV['GROWSTUFF_SITE_NAME'])
|
||||
= render partial: 'stats'
|
||||
.col-md-4
|
||||
.signup
|
||||
%p= t('.perks')
|
||||
%p= link_to(t('.sign_up'), new_member_registration_path, class: 'btn btn-primary btn-lg')
|
||||
%p
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
- cache cache_key_for(Crop, 'interesting'), expires_in: 1.day do
|
||||
%h2.section-heading.h1.pt-4= t('.our_crops')
|
||||
.row
|
||||
%h2= t('.our_crops')
|
||||
- Crop.interesting.includes(:scientific_names, :photos).shuffle.first(12).each do |c|
|
||||
- Crop.interesting.includes(:scientific_names, :photos).shuffle.first(36).each do |c|
|
||||
.col-lg-2.col-md-4.col-sm-3.col-xs-6
|
||||
= render 'crops/thumbnail', crop: c
|
||||
|
||||
.align-bottom
|
||||
%p.text-right= link_to "#{t('home.crops.view_all')} »", crops_path, class: 'btn'
|
||||
@@ -1,17 +1,34 @@
|
||||
%h2= t('.discussion')
|
||||
|
||||
- posts = Post.order(created_at: :desc).limit(6)
|
||||
- if posts
|
||||
= render "posts/summary", posts: posts, howmany: 6
|
||||
-# - Post.order(created_at: :desc).limit(6).each do |post|
|
||||
|
||||
- cache cache_key_for(Forum) do
|
||||
- forums = Forum.all.order(:name)
|
||||
- if forums
|
||||
%ul.list-inline
|
||||
%li
|
||||
%strong #{t('.forums')}:
|
||||
- forums.each do |f|
|
||||
%li= link_to f.name, f
|
||||
-# = link_to truncate(strip_tags(post.subject), length: 40, separator: ' '), post
|
||||
-# by
|
||||
-# = link_to post.author, post.author
|
||||
|
||||
-# - cache cache_key_for(Forum) do
|
||||
-# - forums = Forum.all.order(:name)
|
||||
-# - if forums
|
||||
-# %ul.list-inline
|
||||
-# %li
|
||||
-# %strong #{t('.forums')}:
|
||||
-# - forums.each do |f|
|
||||
-# %li= link_to f.name, f
|
||||
|
||||
|
||||
|
||||
.list-group
|
||||
- Post.order(created_at: :desc).limit(3).each do |post|
|
||||
%a.list-group-item.list-group-item-action.flex-column.align-items-start{:href => post_path(post)}
|
||||
.d-flex.w-100.justify-content-between
|
||||
%h5.mb-2.h5= truncate(strip_tags(post.subject))
|
||||
%small
|
||||
= time_ago_in_words(post.created_at)
|
||||
ago
|
||||
%p.mb-2
|
||||
= truncate(strip_tags(post.body), length: 200)
|
||||
%small
|
||||
= post.comments.size
|
||||
comments
|
||||
%p.text-right
|
||||
= link_to "#{t('.view_all')} »", posts_path
|
||||
= link_to "#{t('.view_all')} »", posts_path, class: 'btn'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
- cache cache_key_for(Harvest) do
|
||||
%h2 Recently Harvested
|
||||
= render 'harvests/list', harvests: Harvest.includes(:crop, :owner, :photos).has_photos.recent.first(6)
|
||||
%h2.section-heading.h1.pt-4 Recently Harvested
|
||||
= render 'harvests/list', harvests: Harvest.includes(:crop, :owner, :photos).has_photos.recent.first(3)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
- cache cache_key_for(Member) do
|
||||
.hidden-xs
|
||||
- members = Member.includes(plantings: :crop).interesting.first(6)
|
||||
- if members.present?
|
||||
%section
|
||||
%h2= t('.title')
|
||||
%section.section.pb-3.text-center
|
||||
- members = Member.includes(plantings: :crop).interesting.first(6)
|
||||
- if members.present?
|
||||
%h2.section-heading.h1.pt-4= t('.title')
|
||||
.row.member-cards
|
||||
- members.each do |m|
|
||||
.col-md-3.col.sm-2= render "members/thumbnail", member: m
|
||||
|
||||
.member-cards
|
||||
- members.each do |m|
|
||||
= render "members/thumbnail", member: m
|
||||
|
||||
%p.text-right
|
||||
= link_to "#{t('.view_all')} »", members_path
|
||||
%p.text-right
|
||||
= link_to "#{t('.view_all')} »", members_path, class: 'btn'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
- cache cache_key_for(Planting, 'home'), expires_in: 1.day do
|
||||
%h2= t('.recently_planted')
|
||||
= render 'plantings/list', plantings: Planting.includes(:crop, garden: :owner).has_photos.recent.limit(6)
|
||||
%h2.section-heading.h2.pt-4= t('.recently_planted')
|
||||
= render 'plantings/list', plantings: Planting.includes(:crop, garden: :owner).has_photos.recent.limit(3)
|
||||
|
||||
@@ -1,22 +1,5 @@
|
||||
- cache cache_key_for(Seed, 'interesting'), expires_in: 1.day do
|
||||
%h2= t('.title')
|
||||
.row
|
||||
- Seed.current.tradable.includes(:owner, :crop).order(created_at: :desc).limit(6).each do |seed|
|
||||
.col-md-2.col-sm-2.col-xs-6
|
||||
.thumbnail.seed-thumbnail
|
||||
- cache cache_key_for(Crop, seed.id) do
|
||||
= link_to image_tag(seed_image_path(seed),
|
||||
alt: seed.crop.name, class: 'img'),
|
||||
seed
|
||||
.seedinfo
|
||||
= link_to seed.crop.name, seed
|
||||
.trade-to
|
||||
%p= seed.owner.location
|
||||
%p
|
||||
%small
|
||||
Will trade to:
|
||||
%br/
|
||||
%em= seed.tradable_to
|
||||
|
||||
%p.text-right
|
||||
= link_to "#{t('.view_all')} »", seeds_path
|
||||
- cache cache_key_for(Seed) do
|
||||
- seeds = Seed.current.tradable.includes(:owner, :crop).order(created_at: :desc).limit(6)
|
||||
- if seeds.size.positive?
|
||||
%h2.section-heading.h1.pt-4.text-center= t('.title')
|
||||
= render 'seeds/list', seeds: seeds
|
||||
|
||||
@@ -1,36 +1,32 @@
|
||||
.homepage.row
|
||||
.col-md-12
|
||||
- if member_signed_in?
|
||||
- content_for :title, t('.welcome', site_name: ENV['GROWSTUFF_SITE_NAME'], member_name: current_member)
|
||||
.homepage
|
||||
.row
|
||||
.col-md-12
|
||||
- if member_signed_in?
|
||||
- content_for :title, t('.welcome', site_name: ENV['GROWSTUFF_SITE_NAME'], member_name: current_member)
|
||||
|
||||
= render 'stats'
|
||||
- else
|
||||
.hidden-xs
|
||||
.jumbotron
|
||||
= render 'blurb'
|
||||
.visible-xs
|
||||
= render 'blurb'
|
||||
= render 'stats'
|
||||
- else
|
||||
.hidden-xs
|
||||
.jumbotron= render 'blurb'
|
||||
-# .visible-xs= render 'blurb'
|
||||
|
||||
.row
|
||||
.col-lg-8.col-md-6.col-sm-12
|
||||
= render 'crops'
|
||||
.col-lg-2.col-md-3.col-sm-6
|
||||
= render 'plantings'
|
||||
.col-lg-2.col-md-3.col-sm-6
|
||||
= render 'harvests'
|
||||
.col-md-12
|
||||
- cache cache_key_for(Crop, 'recent') do
|
||||
%p{ style: 'margin-top: 11.25px' }
|
||||
%strong
|
||||
#{t('.recently_added')}:
|
||||
!= Crop.recent.limit(30).map { |c| link_to(c, c) }.join(", ")
|
||||
.row
|
||||
.col-lg-8.col-md-6.col-sm-12.well
|
||||
= render 'crops'
|
||||
.col-lg-2.col-md-3.col-sm-6
|
||||
= render 'plantings'
|
||||
.col-lg-2.col-md-3.col-sm-6
|
||||
= render 'harvests'
|
||||
.col-md-12
|
||||
- cache cache_key_for(Crop, 'recent') do
|
||||
%p{ style: 'margin-top: 11.25px' }
|
||||
%strong
|
||||
#{t('.recently_added')}:
|
||||
!= Crop.recent.limit(30).map { |c| link_to(c, c) }.join(", ")
|
||||
|
||||
%p.text-right
|
||||
= link_to "#{t('home.crops.view_all')} »", crops_path
|
||||
.row
|
||||
.col-md-12
|
||||
= render 'seeds'
|
||||
= render 'members'
|
||||
.row
|
||||
.col-md-12
|
||||
= render 'discuss'
|
||||
.row
|
||||
.col-lg-8.col-md-6.col-sm-12
|
||||
= render 'seeds'
|
||||
.col-lg-4.col-md-6.col-sm-12
|
||||
= render 'discuss'
|
||||
= render 'members'
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
.sr-only
|
||||
= link_to t(".skip"), "#skipnav"
|
||||
.navbar.navbar-default.navbar-fixed-top{ role: "navigation" }
|
||||
.container
|
||||
.container-fluid
|
||||
.navbar-header
|
||||
%button.navbar-toggle{ 'data-target': "#navbar-collapse", 'data-toggle': "collapse" }
|
||||
%span.sr-only= t('.toggle_navigation')
|
||||
%button.navbar-toggle{"data-target" => ".navbar-responsive-collapse", "data-toggle" => "collapse", type: "button"}
|
||||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
@@ -16,15 +15,36 @@
|
||||
class: "img-responsive",
|
||||
alt: ENV['GROWSTUFF_SITE_NAME'])
|
||||
|
||||
.form.navbar-form.pull-left
|
||||
.navbar-collapse.collapse.navbar-responsive-collapse
|
||||
-# %ul.nav.navbar-nav
|
||||
-# %li.active
|
||||
-# %a{href: "javascript:void(0)"} Active
|
||||
-# %li
|
||||
-# %a{href: "javascript:void(0)"} Link
|
||||
-# %li.dropdown
|
||||
-# %a.dropdown-toggle{"data-target" => "#", "data-toggle" => "dropdown", href: "http://fezvrasta.github.io/bootstrap-material-design/bootstrap-elements.html"}
|
||||
-# Dropdown
|
||||
-# %b.caret
|
||||
-# %ul.dropdown-menu
|
||||
-# %li
|
||||
-# %a{href: "javascript:void(0)"} Action
|
||||
-# %li
|
||||
-# %a{href: "javascript:void(0)"} Another action
|
||||
-# %li
|
||||
-# %a{href: "javascript:void(0)"} Something else here
|
||||
-# %li.divider
|
||||
-# %li.dropdown-header Dropdown header
|
||||
-# %li
|
||||
-# %a{href: "javascript:void(0)"} Separated link
|
||||
-# %li
|
||||
-# %a{href: "javascript:void(0)"} One more separated link
|
||||
%form.navbar-form.navbar-left
|
||||
= render 'crops/search_bar'
|
||||
|
||||
.navbar-collapse.collapse#navbar-collapse
|
||||
-# .form-group
|
||||
-# %input.form-control.col-sm-8{placeholder: "Search", type: "text"}/
|
||||
%ul.nav.navbar-nav.navbar-right
|
||||
%li.dropdown<
|
||||
%a.dropdown-toggle{ 'data-toggle': 'dropdown', href: crops_path }
|
||||
= t('.crops')
|
||||
%b.caret
|
||||
%a.dropdown-toggle{ 'data-toggle': 'dropdown', href: crops_path }= t('.crops')
|
||||
%ul.dropdown-menu
|
||||
%li= link_to t('.browse_crops'), crops_path
|
||||
%li= link_to t('.seeds'), seeds_path
|
||||
@@ -33,13 +53,11 @@
|
||||
%li.dropdown<
|
||||
%a.dropdown-toggle{ 'data-toggle': 'dropdown', href: members_path }
|
||||
= t('.community')
|
||||
%b.caret
|
||||
%ul.dropdown-menu
|
||||
%li= link_to t('.community_map'), places_path
|
||||
%li= link_to t('.browse_members'), members_path
|
||||
%li= link_to t('.posts'), posts_path
|
||||
%li= link_to t('.forums'), forums_path
|
||||
|
||||
- if member_signed_in?
|
||||
%li.dropdown<
|
||||
%a.dropdown-toggle{ 'data-toggle': 'dropdown', href: root_path }
|
||||
@@ -47,7 +65,6 @@
|
||||
= t('.your_stuff', unread_count: current_member.notifications.unread_count)
|
||||
- else
|
||||
= t('.current_memberlogin_name', current_memberlogin_name: current_member.login_name)
|
||||
%b.caret
|
||||
%ul.dropdown-menu
|
||||
%li= link_to t('.profile'), member_path(current_member)
|
||||
%li= link_to t('.gardens'), member_gardens_path(current_member)
|
||||
@@ -68,13 +85,11 @@
|
||||
- if current_member.role?(:admin)
|
||||
%li= link_to t('.admin'), admin_path
|
||||
|
||||
|
||||
%li= link_to t('.sign_out'), destroy_member_session_path, method: :delete
|
||||
|
||||
- else
|
||||
%li= link_to t('.sign_in'), new_member_session_path, id: 'navbar-signin'
|
||||
%li= link_to t('.sign_up'), new_member_registration_path, id: 'navbar-signup'
|
||||
|
||||
|
||||
-# anchor tag for accessibility link to skip the navigation menu
|
||||
%a{ name: 'skipnav' }
|
||||
%a{ name: 'skipnav' }
|
||||
@@ -1,13 +1,13 @@
|
||||
- content_for :buttonbar do
|
||||
- if current_member.present?
|
||||
= link_to url_for([current_member, model]), class: 'btn btn-default' do
|
||||
= link_to url_for([current_member, model]), class: 'btn' do
|
||||
My #{model.model_name.human.pluralize}
|
||||
|
||||
= link_to model, class: 'btn btn-default' do
|
||||
= link_to model, class: 'btn' do
|
||||
Everyone's #{model.model_name.human.pluralize}
|
||||
|
||||
- if can?(:create, model)
|
||||
= link_to url_for([model, action: :new]), class: 'btn btn-default' do
|
||||
= link_to url_for([model, action: :new]), class: 'btn' do
|
||||
Add a #{model.model_name.human}
|
||||
|
||||
- unless current_member
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
#maincontainer
|
||||
.row
|
||||
.col-md-6
|
||||
|
||||
- if content_for?(:buttonbar)
|
||||
= yield(:buttonbar)
|
||||
|
||||
- if content_for?(:title)
|
||||
%h1#title
|
||||
= yield(:title)
|
||||
- if content_for?(:subtitle)
|
||||
%small= yield(:subtitle)
|
||||
|
||||
- if content_for?(:buttonbar)
|
||||
.btn-group.layout-actions
|
||||
= yield(:buttonbar)
|
||||
|
||||
.col-md-6
|
||||
= render 'shared/global_actions'
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
- if member
|
||||
= link_to image_tag(avatar_uri(member, 150),
|
||||
alt: '',
|
||||
class: 'img img-responsive avatar'),
|
||||
member_path(member)
|
||||
= link_to image_tag(avatar_uri(member, 150),
|
||||
alt: member,
|
||||
class: 'img img-responsive avatar mr-3'),
|
||||
member_path(member)
|
||||
|
||||
@@ -1,26 +1,38 @@
|
||||
-# .member-thumbnail.well
|
||||
-# %div
|
||||
-# = render "members/avatar", member: member
|
||||
-# %div
|
||||
-# %p.login-name
|
||||
-# = link_to member.login_name, member
|
||||
-# - unless member.location.blank?
|
||||
-# %small
|
||||
-# %br/
|
||||
-# %i= member.location
|
||||
-# - unless member.plantings.empty?
|
||||
-# %small
|
||||
-# %br/
|
||||
-# Recently planted:
|
||||
-# != member.plantings.order(created_at: :desc).first(3).map { |p| link_to p.crop_name, p }.join(", ")
|
||||
- cache member do
|
||||
.member-thumbnail.panel
|
||||
%div
|
||||
= render partial: "members/avatar", locals: { member: member }
|
||||
%div
|
||||
%p.login-name
|
||||
= link_to member.login_name, member
|
||||
- unless member.location.blank?
|
||||
%small
|
||||
%br/
|
||||
%i= member.location
|
||||
- unless member.plantings.empty?
|
||||
%small
|
||||
%br/
|
||||
Recently planted:
|
||||
!= member.plantings.order(created_at: :desc).first(3).map { |p| link_to p.crop_name, p }.join(", ")
|
||||
.card.text-center
|
||||
/ Background color
|
||||
.card-up.teal.lighten-2
|
||||
/ Avatar
|
||||
.avatar.mx-auto.white
|
||||
= link_to member do
|
||||
= image_tag(avatar_uri(member, 150), class: 'rounded-circle img-fluid', alt: member)
|
||||
.card-body
|
||||
/ Name
|
||||
%h4.card-title
|
||||
= link_to member, member
|
||||
%hr/
|
||||
%p
|
||||
%small
|
||||
Joined
|
||||
= distance_of_time_in_words(member.created_at, Time.zone.now)
|
||||
ago.
|
||||
%p
|
||||
%small
|
||||
= [localize_plural(member.gardens, Garden),
|
||||
localize_plural(member.plantings, Planting),
|
||||
localize_plural(member.seeds, Seed)].join(", ")
|
||||
%ul.nav.md-pills.nav-justified.pills-pink.small
|
||||
%li.nav-item= link_to localize_plural(member.plantings, Planting), member_plantings_path(member)
|
||||
%li.nav-item= link_to localize_plural(member.harvests, Harvest), member_harvests_path(member)
|
||||
%li.nav-item= link_to localize_plural(member.seeds, Seed), member_seeds_path(member)
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
- if can?(:edit, @photo) && can?(:destroy, @photo)
|
||||
%p
|
||||
- if can?(:edit, @photo)
|
||||
= edit_button(@photo)
|
||||
= edit_button(edit_photo_path(@photo))
|
||||
- if can?(:destroy, @photo)
|
||||
= delete_button(@photo)
|
||||
|
||||
@@ -8,7 +8,4 @@
|
||||
- photos.each do |photo|
|
||||
.col-xs-6.col-md-3.six-across= render 'photos/thumbnail', photo: photo
|
||||
|
||||
- if can?(:create, Photo) && can?(:edit, item)
|
||||
= link_to new_photo_path(type: type, id: item.id), class: 'btn btn-primary' do
|
||||
%span.glyphicon.glyphicon-camera{ title: "Add photo" }
|
||||
Add photo
|
||||
= add_photo_button(item)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
- if can? :edit, photo
|
||||
= link_to photo_associations_path(photo_id: photo.id, type: type, id: thing.id),
|
||||
method: 'delete', class: 'btn btn-default btn-xs' do
|
||||
= delete_icon
|
||||
method: 'delete', class: 'btn btn-danger btn-xs' do
|
||||
%i.fas.fa-backspace
|
||||
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
%h4 This photo depicts:
|
||||
%ul
|
||||
- @photo.plantings.each do |planting|
|
||||
%li
|
||||
= link_to t('photos.show.planting', planting: planting.to_s, owner: planting.owner.to_s), planting_path(planting)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'planting', thing: planting }
|
||||
%p
|
||||
%ul.associations
|
||||
- @photo.plantings.each do |planting|
|
||||
%li
|
||||
= planting_icon
|
||||
= link_to t('photos.show.planting', planting: planting.to_s, owner: planting.owner.to_s), planting_path(planting)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'planting', thing: planting }
|
||||
|
||||
- @photo.harvests.each do |harvest|
|
||||
%li
|
||||
= link_to t('photos.show.harvest', crop: harvest.crop.name, owner: harvest.owner.to_s), harvest_path(harvest)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'harvest', thing: harvest }
|
||||
- @photo.harvests.each do |harvest|
|
||||
%li
|
||||
= harvest_icon
|
||||
= link_to t('photos.show.harvest', crop: harvest.crop.name, owner: harvest.owner.to_s), harvest_path(harvest)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'harvest', thing: harvest }
|
||||
|
||||
- @photo.gardens.each do |garden|
|
||||
%li
|
||||
= link_to t('photos.show.garden', garden: garden.to_s, owner: garden.owner.to_s), garden_path(garden)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'garden', thing: garden }
|
||||
- @photo.gardens.each do |garden|
|
||||
%li
|
||||
= garden_icon
|
||||
= link_to t('photos.show.garden', garden: garden.to_s, owner: garden.owner.to_s), garden_path(garden)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'garden', thing: garden }
|
||||
|
||||
- @photo.seeds.each do |seed|
|
||||
%li
|
||||
= link_to t('photos.show.seed', seed: seed.to_s, owner: seed.owner.to_s), seed_path(seed)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'seed', thing: seed }
|
||||
- @photo.seeds.each do |seed|
|
||||
%li
|
||||
= seed_icon
|
||||
= link_to t('photos.show.seed', seed: seed.to_s, owner: seed.owner.to_s), seed_path(seed)
|
||||
= render partial: "photo_association_delete", locals: { photo: @photo, type: 'seed', thing: seed }
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
- content_for :title, "Edit Photo"
|
||||
= form_for(@photo) do |f|
|
||||
= f.label :title
|
||||
= f.text_field :title, placeholder: "title"
|
||||
= f.submit
|
||||
.rol
|
||||
.col-md-2= render 'photos/thumbnail', photo: @photo
|
||||
.col-md-10
|
||||
- content_for :title, "Edit Photo"
|
||||
= form_for(@photo) do |f|
|
||||
.form-group
|
||||
= f.label :title
|
||||
= f.text_field :title, placeholder: "title"
|
||||
.form-group
|
||||
.form-actions= f.submit 'Save', class: 'btn'
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
= tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME'])
|
||||
|
||||
.row
|
||||
.col-md-8
|
||||
%p= image_tag(@photo.fullsize_url, alt: @photo.title, class: 'img img-responsive')
|
||||
|
||||
.col-md-4
|
||||
= render 'photos/actions', photo: @photo
|
||||
.col-md-5
|
||||
- if @crops.size.positive?
|
||||
- @crops.each do |crop|
|
||||
= render 'crops/index_card', crop: crop
|
||||
%p
|
||||
%strong Posted by:
|
||||
%i.fas.fa-camera-retro
|
||||
%strong Photo by
|
||||
= link_to @photo.owner, @photo.owner
|
||||
%p
|
||||
%strong License:
|
||||
@@ -22,13 +22,13 @@
|
||||
= link_to @photo.license_name, @photo.license_url
|
||||
- else
|
||||
= succeed "." do
|
||||
= @photo.license_name
|
||||
|
||||
%p= link_to "View on Flickr", @photo.link_url
|
||||
= @photo.license_name
|
||||
|
||||
- if @photo.associations?
|
||||
= render "photo_associations", locals: { photo: @photo }
|
||||
|
||||
- if @crops.size.positive?
|
||||
- @crops.each do |crop|
|
||||
= render 'crops/index_card', crop: crop
|
||||
= render 'photos/actions', photo: @photo
|
||||
|
||||
.col-md-7
|
||||
//%img.img-fluid.z-depth-1{:alt => "1", :src => "https://mdbootstrap.com/img/Photos/Slides/img%20(54).jpg"}/
|
||||
%p= image_tag(@photo.fullsize_url, alt: @photo.title, class: 'rounded img-fluid z-depth-1 float-right ')
|
||||
%p= link_to "View on Flickr", @photo.link_url, class: 'btn'
|
||||
|
||||
@@ -8,7 +8,4 @@
|
||||
- else
|
||||
%p No seeds saved
|
||||
|
||||
- if planting.active? && can?(:create, Seed) && can?(:edit, planting)
|
||||
= link_to new_planting_seed_path(planting), class: 'btn btn-primary' do
|
||||
%span.glyphicon.glyphicon-heart{ title: "Add photo" }
|
||||
Save seeds
|
||||
= planting_save_seeds_button(planting)
|
||||
@@ -7,7 +7,4 @@
|
||||
.col-xs-6.col-sm-4.col-md-3
|
||||
= render 'harvests/thumbnail', harvest: harvest
|
||||
|
||||
- if planting.active? && can?(:edit, planting)
|
||||
= link_to new_planting_harvest_path(planting), class: 'btn btn-primary' do
|
||||
%span.glyphicon.glyphicon-leaf{ title: "Harvest" }
|
||||
Harvest
|
||||
= planting_harvest_button(planting)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
- cache planting do
|
||||
= link_to image_tag(planting_image_path(planting),
|
||||
alt: planting.to_s,
|
||||
class: 'image-responsive crop-image'),
|
||||
class: 'image-responsive'),
|
||||
planting,
|
||||
rel: "popover",
|
||||
'data-trigger': 'hover',
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
- plantings.each do |p|
|
||||
- cache p do
|
||||
.row
|
||||
.col-lg-6.col-md-3.col-xs-4.homepage-listing
|
||||
= render 'plantings/image_with_popover', planting: p
|
||||
.col-lg-3.col-md-9.col-xs-4
|
||||
= link_to p.crop, p.crop
|
||||
%br/
|
||||
%small
|
||||
%i= p.location
|
||||
- plantings.each do |planting|
|
||||
- cache planting do
|
||||
.card
|
||||
.view.overlay
|
||||
= link_to planting do
|
||||
%img.card-img-top.img-responsive{alt: planting, src: planting_image_path(planting, full_size: true)}/
|
||||
.card-body.p-3
|
||||
%h5.card-title.font-weight-bold.fuchsia-rose-text.mb-0
|
||||
= link_to planting, planting
|
||||
|
||||
%p.float-right
|
||||
= link_to planting.owner do
|
||||
= image_tag(avatar_uri(planting.owner, 50), alt: '', class: 'img img-responsive avatar rounded-circle')
|
||||
%hr/
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
- if can?(:edit, planting)
|
||||
.planting-quick-actions.pull-right
|
||||
%a.btn.btn-default.btn-xs#actionsMenu.nav-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", href: "#"}
|
||||
=icon('fas', 'bars')
|
||||
%ul.dropdown-menu{"aria-labelledby" => "actionsMenu"}
|
||||
- if can?(:edit, planting)
|
||||
%li= planting_edit_button(planting)
|
||||
%li= add_photo_button(planting)
|
||||
%a.btn#actionsMenu.nav-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", href: "#"}
|
||||
-# =icon('fas', 'ellipsis-v')
|
||||
%ul.dropdown-menu.dropdown-menu-left{"aria-labelledby" => "actionsMenu"}
|
||||
%li.btn-xs
|
||||
= link_to t('view'), planting, class: 'btn'
|
||||
%li.btn-xs= planting_edit_button(planting)
|
||||
%li.btn-xs= add_photo_button(planting)
|
||||
|
||||
- if planting.active?
|
||||
%li.btn-xs= planting_finish_button(planting)
|
||||
%li.btn-xs= planting_harvest_button(planting)
|
||||
%li.btn-xs= planting_save_seeds_button(planting)
|
||||
|
||||
|
||||
- if planting.active?
|
||||
%li= planting_finish_button(planting)
|
||||
%li= planting_harvest_button(planting)
|
||||
%li= planting_save_seeds_button(planting)
|
||||
|
||||
13
app/views/plantings/_stats.haml
Normal file
13
app/views/plantings/_stats.haml
Normal file
@@ -0,0 +1,13 @@
|
||||
.planting-stats
|
||||
%span.badge.harvest-count{'data-toggle': "tooltip", 'data-placement': "top", title: 'Harvests'}
|
||||
= harvest_icon
|
||||
= planting.harvests.size
|
||||
%span.badge.child-seeds-count{'data-toggle': "tooltip", 'data-placement': "top", title: 'Seeds saved'}
|
||||
= seed_icon
|
||||
= planting.child_seeds.size
|
||||
%span.badge.photos-count{'data-toggle': "tooltip", 'data-placement': "top", title: 'Photos'}
|
||||
= photo_icon
|
||||
= planting.photos.size
|
||||
%span.badge.photos-count{'data-toggle': "tooltip", 'data-placement': "top", title: 'Age in days'}
|
||||
= planting_icon
|
||||
= planting.age_in_days
|
||||
@@ -73,7 +73,7 @@
|
||||
%dd= render 'plantings/progress', planting: @planting, show_explanation: true
|
||||
|
||||
.col-xs-12.col-sm-6
|
||||
= render partial: "crops/index_card", locals: { crop: @planting.crop }
|
||||
= render "crops/index_card", crop: @planting.crop
|
||||
- if @planting.owner.location
|
||||
%p
|
||||
%small
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
= add_photo_button(seed)
|
||||
|
||||
- if can?(:create, Planting) && seed.active?
|
||||
= link_to new_planting_path(seed_id: seed), class: 'btn btn-default btn-xs' do
|
||||
= link_to new_planting_path(seed_id: seed), class: 'btn btn-default' do
|
||||
%span.glyphicon.glyphicon-grain{ title: "Plant seeds" }
|
||||
Plant seeds
|
||||
|
||||
= render 'shared/buttons/finish_seeds', seed: seed
|
||||
= seed_finish_button(seed)
|
||||
|
||||
= delete_button(seed) if can? :destroy, seed
|
||||
|
||||
16
app/views/seeds/_list.html.haml
Normal file
16
app/views/seeds/_list.html.haml
Normal file
@@ -0,0 +1,16 @@
|
||||
- seeds.each do |seed|
|
||||
- cache seed do
|
||||
.col-lg-3.col-md-4.col-sm-3.col-xs-6
|
||||
.card
|
||||
.view.overlay
|
||||
= link_to seed do
|
||||
= image_tag(seed_image_path(seed, full_size: true), alt: seed, class: 'card-img-top img-responsive')
|
||||
.card-body.p-3
|
||||
%h5.card-title.font-weight-bold.fuchsia-rose-text.mb-0
|
||||
= link_to seed, seed
|
||||
%p
|
||||
%i #{seed.owner.location}
|
||||
%p Will trade #{seed.tradable_to}
|
||||
%p.float-right
|
||||
= link_to seed.owner do
|
||||
= image_tag(avatar_uri(seed.owner, 50), alt: '', class: 'img img-responsive avatar rounded')
|
||||
@@ -1,14 +1,12 @@
|
||||
.thumbnail
|
||||
.seed-thumbnail
|
||||
= link_to image_tag(seed_image_path(seed),
|
||||
alt: seed.crop.name, class: 'img'),
|
||||
seed_path(seed)
|
||||
.seedinfo
|
||||
.seed-name
|
||||
= link_to seed, seed_path(seed)
|
||||
.trade-to
|
||||
%p= seed.owner.location
|
||||
%p
|
||||
Will trade to:
|
||||
%br/
|
||||
= seed.tradable_to
|
||||
- cache cache_key_for(Seed, seed.id) do
|
||||
.thumbnail
|
||||
.seed-thumbnail
|
||||
= link_to image_tag(seed_image_path(seed),
|
||||
alt: seed.name, class: 'img'),
|
||||
seed
|
||||
.seedinfo
|
||||
.seedname
|
||||
= link_to seed.name, seed
|
||||
%small.trade-to
|
||||
%p #{seed.owner.location}
|
||||
%p Will trade #{seed.tradable_to}
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
- if signed_in?
|
||||
.global-actions.pull-right
|
||||
.btn-group
|
||||
= link_to member_gardens_path(current_member), class: 'btn btn-default' do
|
||||
= garden_icon
|
||||
= t('links.my_gardens')
|
||||
|
||||
.btn-group
|
||||
= link_to new_planting_path, class: 'btn btn-default' do
|
||||
= link_to new_planting_path, class: "btn #{current_page?(new_planting_path) ? 'btn-primary' : ''}" do
|
||||
= planting_icon
|
||||
= t('plantings.plant_something')
|
||||
|
||||
= link_to new_harvest_path, class: 'btn btn-default' do
|
||||
= link_to new_harvest_path, class: "btn #{current_page?(new_harvest_path) ? 'btn-primary' : ''}" do
|
||||
= harvest_icon
|
||||
= t('harvests.harvest_something')
|
||||
|
||||
= link_to new_seed_path, class: 'btn btn-default' do
|
||||
= link_to new_seed_path, class: "btn #{current_page?(new_seed_path) ? 'btn-primary' : ''}" do
|
||||
= seed_icon
|
||||
= t('buttons.save_seeds')
|
||||
|
||||
.btn-group
|
||||
= link_to t('posts.write_blog_post'), new_post_path, class: 'btn btn-default'
|
||||
-# .btn-group
|
||||
-# = link_to t('posts.write_blog_post'), new_post_path, class: 'btn'
|
||||
|
||||
- unless current_page?(member_gardens_path(current_member))
|
||||
.btn-group
|
||||
= link_to member_gardens_path(current_member), class: "btn" do
|
||||
= garden_icon
|
||||
= t('links.my_gardens')
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
- unless seed.finished
|
||||
= link_to seed_path(seed, seed: { finished: 1 }),
|
||||
method: :put, class: 'btn btn-default btn-xs append-date' do
|
||||
= render 'shared/glyphicon', icon: 'ok', title: 'buttons.finished'
|
||||
=t('buttons.mark_as_finished')
|
||||
@@ -79,6 +79,6 @@ Rails.application.configure do
|
||||
config.after_initialize do
|
||||
Bullet.enable = true
|
||||
Bullet.rails_logger = true
|
||||
Bullet.add_footer = true
|
||||
# Bullet.add_footer = true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -118,4 +118,6 @@ Rails.application.configure do
|
||||
|
||||
# Do not dump schema after migrations.
|
||||
config.active_record.dump_schema_after_migration = false
|
||||
|
||||
config.bot_email = 'cropbot@growstuff.org'
|
||||
end
|
||||
|
||||
@@ -145,12 +145,12 @@ describe Photo do
|
||||
seed.photos << seed_photo
|
||||
end
|
||||
|
||||
it { expect(Photo.by_model(Harvest)).to eq([ harvest_photo ]) }
|
||||
it { expect(Photo.by_model(Planting)).to eq([ planting_photo ]) }
|
||||
it { expect(Photo.by_model(Seed)).to eq([ seed_photo ]) }
|
||||
it { expect(Photo.by_model(Harvest)).to eq([harvest_photo]) }
|
||||
it { expect(Photo.by_model(Planting)).to eq([planting_photo]) }
|
||||
it { expect(Photo.by_model(Seed)).to eq([seed_photo]) }
|
||||
|
||||
it { expect(Photo.by_crop(harvest_crop)).to eq([ harvest_photo ]) }
|
||||
it { expect(Photo.by_crop(planting_crop)).to eq([ planting_photo ]) }
|
||||
it { expect(Photo.by_crop(seed_crop)).to eq([ seed_photo ]) }
|
||||
it { expect(Photo.by_crop(harvest_crop)).to eq([harvest_photo]) }
|
||||
it { expect(Photo.by_crop(planting_crop)).to eq([planting_photo]) }
|
||||
it { expect(Photo.by_crop(seed_crop)).to eq([seed_photo]) }
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user