cloudrider 0.3.21 → 0.3.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/generica/Gemfile +1 -1
- data/generica/Gemfile.lock +91 -51
- data/generica/app/assets/javascripts/components/product-display.js.em +4 -1
- data/generica/app/assets/javascripts/components/product-listing.js.em +4 -1
- data/generica/app/assets/javascripts/components/site-footer.js.em +12 -0
- data/generica/app/assets/javascripts/components/site-nav.js.em +15 -0
- data/generica/app/assets/javascripts/config/router.js.ls +18 -2
- data/generica/app/assets/javascripts/controllers/modals/fork_controller.js.em +4 -0
- data/generica/app/assets/javascripts/controllers/modals/login_controller.js.em +1 -4
- data/generica/app/assets/javascripts/controllers/modals/register_controller.js.em +1 -1
- data/generica/app/assets/javascripts/controllers/users/contact/edit_controller.js.em +16 -0
- data/generica/app/assets/javascripts/controllers/users/contacts/index_controller.js.em +21 -0
- data/generica/app/assets/javascripts/controllers/users/contacts/new_controller.js.em +16 -0
- data/generica/app/assets/javascripts/controllers/users/index_controller.js.em +19 -0
- data/generica/app/assets/javascripts/models/contact.js.em +11 -0
- data/generica/app/assets/javascripts/routes/users/contact_route.js.em +3 -0
- data/generica/app/assets/javascripts/routes/users/contacts/index_route.js.em +7 -0
- data/generica/app/assets/javascripts/routes/users/contacts/new_route.js.em +3 -0
- data/generica/app/assets/javascripts/routes/users/index_route.js.em +3 -0
- data/generica/app/assets/javascripts/templates/components/site-footer.emblem +18 -9
- data/generica/app/assets/javascripts/templates/users.emblem +11 -3
- data/generica/app/assets/javascripts/templates/users/contact/edit.emblem +16 -0
- data/generica/app/assets/javascripts/templates/users/contacts/_form-core.emblem +19 -0
- data/generica/app/assets/javascripts/templates/users/contacts/index.emblem +62 -0
- data/generica/app/assets/javascripts/templates/users/contacts/new.emblem +16 -0
- data/generica/app/assets/javascripts/templates/users/index.emblem +36 -2
- data/generica/app/assets/stylesheets/apiv1/components/_product-display.css.scss +7 -2
- data/generica/app/assets/stylesheets/apiv1/shared/_constants.css.scss +3 -0
- data/generica/app/controllers/apiv1/contacts/create_controller.rb +26 -0
- data/generica/app/controllers/apiv1/contacts/destroy_controller.rb +9 -0
- data/generica/app/controllers/apiv1/contacts/index_controller.rb +27 -0
- data/generica/app/controllers/apiv1/contacts/show_controller.rb +9 -0
- data/generica/app/controllers/apiv1/contacts/update_controller.rb +51 -0
- data/generica/app/controllers/apiv1/products/destroy_controller.rb +1 -1
- data/generica/app/models/admin/user.rb +20 -1
- data/generica/app/models/apiv1/user_contact.rb +51 -0
- data/generica/app/varissets/javascripts/templates/components/product-display.emblem.erb +34 -40
- data/generica/app/varissets/javascripts/templates/components/product-listing.emblem.erb +24 -16
- data/generica/app/varissets/javascripts/templates/components/site-nav.emblem.erb +12 -2
- data/generica/app/varissets/stylesheets/apiv1/components/_product-display.css.scss.erb +68 -31
- data/generica/app/varissets/stylesheets/apiv1/components/_product-listing.css.scss.erb +52 -14
- data/generica/config/routes.rb +5 -0
- data/generica/db/migrate/20141209185352_create_apiv1_user_contacts.rb +14 -0
- data/generica/spec/controllers/apiv1/contacts/update_controller_spec.rb +59 -0
- data/generica/spec/factories/admin/user_factory.rb +22 -4
- data/generica/spec/models/apiv1/user_contact_spec.rb +70 -0
- data/lib/cloudrider/version.rb +1 -1
- metadata +25 -2
@@ -35,6 +35,20 @@ class Admin::User < ActiveRecord::Base
|
|
35
35
|
class_name: 'Apiv1::Product',
|
36
36
|
through: :product_relationships
|
37
37
|
|
38
|
+
has_many :raw_contacts,
|
39
|
+
class_name: 'Apiv1::UserContact',
|
40
|
+
foreign_key: 'user_id'
|
41
|
+
|
42
|
+
has_many :contacts,
|
43
|
+
-> { order_by_primality },
|
44
|
+
class_name: 'Apiv1::UserContact',
|
45
|
+
foreign_key: 'user_id'
|
46
|
+
|
47
|
+
has_one :primary_contact,
|
48
|
+
-> { is_primary.order_by_primality },
|
49
|
+
class_name: 'Apiv1::UserContact',
|
50
|
+
foreign_key: 'user_id'
|
51
|
+
|
38
52
|
has_many :offers,
|
39
53
|
-> { order "#{Apiv1::OfferMessage.table_name}.created_at desc" },
|
40
54
|
through: :products,
|
@@ -49,7 +63,7 @@ class Admin::User < ActiveRecord::Base
|
|
49
63
|
phone_number: phone_number,
|
50
64
|
address: address,
|
51
65
|
about_me: about_me
|
52
|
-
}
|
66
|
+
}.merge _primary_contact_hash
|
53
67
|
end
|
54
68
|
|
55
69
|
def admin?
|
@@ -63,4 +77,9 @@ class Admin::User < ActiveRecord::Base
|
|
63
77
|
def owns?(product)
|
64
78
|
product_relationships.exists?(product_id: product.id)
|
65
79
|
end
|
80
|
+
|
81
|
+
private
|
82
|
+
def _primary_contact_hash
|
83
|
+
primary_contact.try(:to_user_hash) || {}
|
84
|
+
end
|
66
85
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: apiv1_user_contacts
|
4
|
+
#
|
5
|
+
# id :integer not null, primary key
|
6
|
+
# user_id :integer
|
7
|
+
# name :string(255)
|
8
|
+
# phone :string(255)
|
9
|
+
# email :string(255)
|
10
|
+
# address :string(255)
|
11
|
+
# status :string(255)
|
12
|
+
# deleted_at :datetime
|
13
|
+
# created_at :datetime
|
14
|
+
# updated_at :datetime
|
15
|
+
#
|
16
|
+
|
17
|
+
class Apiv1::UserContact < ActiveRecord::Base
|
18
|
+
KnownStatuses = ['primary']
|
19
|
+
acts_as_paranoid
|
20
|
+
belongs_to :user,
|
21
|
+
class_name: 'Admin::User'
|
22
|
+
|
23
|
+
scope :is_primary,
|
24
|
+
-> { where "#{self.table_name}.status" => 'primary' }
|
25
|
+
|
26
|
+
validates :user,
|
27
|
+
presence: true
|
28
|
+
|
29
|
+
def make_primary!
|
30
|
+
return if user.primary_contact == self
|
31
|
+
user.primary_contact.try :demote_to_secondary!
|
32
|
+
update status: 'primary'
|
33
|
+
end
|
34
|
+
|
35
|
+
def demote_to_secondary!
|
36
|
+
update status: nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_user_hash
|
40
|
+
{
|
41
|
+
email: email,
|
42
|
+
company_name: name,
|
43
|
+
phone_number: phone,
|
44
|
+
address: address
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_ember_hash
|
49
|
+
attributes
|
50
|
+
end
|
51
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
if product
|
4
4
|
.media-object
|
5
5
|
link-to "products.product.show" product.id
|
6
|
-
|
6
|
+
.product-image style=productImageStyle
|
7
7
|
.media-texts
|
8
8
|
link-to "products.product.show" product.id class="product-title"
|
9
9
|
tr-span en=product.material
|
@@ -27,48 +27,41 @@ else
|
|
27
27
|
|
28
28
|
<% when :media_one %>
|
29
29
|
if product
|
30
|
-
.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
link-to "products.product.show" product.id class="flex-start"
|
31
|
+
.media-object
|
32
|
+
.product-image style=productImageStyle
|
33
|
+
.media-texts
|
34
|
+
.product-title
|
35
|
+
i.fa.fa-star
|
36
36
|
tr-span en=product.material
|
37
37
|
if product.sku
|
38
38
|
span.predash= product.sku
|
39
|
-
|
40
|
-
.
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
span.spacebar=
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
dd
|
66
|
-
span= product.place
|
67
|
-
if product.quality
|
68
|
-
dt.upcase
|
69
|
-
tr-span en="quality"
|
70
|
-
dd
|
71
|
-
span= product.quality
|
39
|
+
|
40
|
+
.product-specs
|
41
|
+
if product.amount
|
42
|
+
.line
|
43
|
+
span.upcase.colon
|
44
|
+
tr-span en="quantity"
|
45
|
+
span.spec.spacebar= product.amount
|
46
|
+
if product.price
|
47
|
+
.line
|
48
|
+
span.upcase.colon
|
49
|
+
tr-span en="price"
|
50
|
+
span.spec.spacebar= product.price
|
51
|
+
if product.place
|
52
|
+
.line
|
53
|
+
span.upcase.colon
|
54
|
+
tr-span en="origin"
|
55
|
+
span.spec.spacebar= product.place
|
56
|
+
if product.quality
|
57
|
+
.line
|
58
|
+
span.upcase.colon
|
59
|
+
tr-span en="quality"
|
60
|
+
span.spec.spacebar= product.quality
|
61
|
+
.line
|
62
|
+
span.upcase.colon
|
63
|
+
tr-span en="creation date"
|
64
|
+
span.spec.spacebar= product.createdAt
|
72
65
|
else
|
73
66
|
.media-object.align-right
|
74
67
|
i.fa.fa-circle-o.fa-4x
|
@@ -77,5 +70,6 @@ else
|
|
77
70
|
tr-span en="no results"
|
78
71
|
p.product-summary
|
79
72
|
tr-span en="or perhaps there are no products to load yet"
|
73
|
+
|
80
74
|
<% when :square_tiles %>
|
81
75
|
<% end %>
|
@@ -3,29 +3,36 @@
|
|
3
3
|
if product
|
4
4
|
link-to "products.product.show" product.id class="product-header"
|
5
5
|
.media-object
|
6
|
-
|
6
|
+
.product-image.th style=productImageStyle
|
7
7
|
.media-texts
|
8
8
|
.big-title
|
9
9
|
tr-span en=product.material
|
10
|
-
if product.
|
11
|
-
span.predash
|
12
|
-
|
13
|
-
|
14
|
-
if product.hasShowOrder
|
15
|
-
span #
|
16
|
-
span.spacebar= product.showcaseOrder
|
17
|
-
|
18
|
-
.smaller-details
|
10
|
+
if product.sku
|
11
|
+
span.predash= product.sku
|
12
|
+
.dateline= product.createdAt
|
13
|
+
p.smaller-details
|
19
14
|
if product.price
|
20
15
|
span= product.price
|
21
16
|
if product.place
|
22
|
-
span @
|
17
|
+
span.decent-prespace @
|
23
18
|
tr-span en=product.place
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
if product.amount
|
20
|
+
span.upcase.colon.decent-prespace
|
21
|
+
tr-span en="quantity"
|
22
|
+
span.spec.spacebar= product.amount
|
23
|
+
if product.price
|
24
|
+
span.upcase.colon.decent-prespace
|
25
|
+
tr-span en="price"
|
26
|
+
span.spec.spacebar= product.price
|
27
|
+
if product.place
|
28
|
+
span.upcase.colon.decent-prespace
|
29
|
+
tr-span en="origin"
|
30
|
+
span.spec.spacebar= product.place
|
31
|
+
if product.quality
|
32
|
+
span.upcase.colon.decent-prespace
|
33
|
+
tr-span en="quality"
|
34
|
+
span.spec.spacebar= product.quality
|
35
|
+
|
29
36
|
else
|
30
37
|
.product-header
|
31
38
|
.media-object
|
@@ -35,4 +42,5 @@ else
|
|
35
42
|
tr-span en="no results"
|
36
43
|
.product-summary
|
37
44
|
tr-span en="or perhaps there are no products to load yet"
|
45
|
+
|
38
46
|
<% end %>
|
@@ -5,8 +5,18 @@
|
|
5
5
|
.space-between
|
6
6
|
link-to "index" class="button-like"
|
7
7
|
span <%= my_company_name %>
|
8
|
-
|
9
|
-
|
8
|
+
if adminLoggedIn
|
9
|
+
link-to "admin.index"
|
10
|
+
tr-span en="admin"
|
11
|
+
|
12
|
+
if userLoggedIn
|
13
|
+
link-to "users.index" class="button-like"
|
14
|
+
tr-span en="my account"
|
15
|
+
|
16
|
+
if notLoggedIn
|
17
|
+
a.pointer.button-like click="displayModal 'login'"
|
18
|
+
tr-span en="login or register"
|
19
|
+
|
10
20
|
<% when :left %>
|
11
21
|
.nav-button
|
12
22
|
link-to "index" (query-params anchor="") class="side-nav"
|
@@ -70,57 +70,94 @@ $material-orange: #FF9800;
|
|
70
70
|
}
|
71
71
|
<% when :media_one %>
|
72
72
|
.product-display {
|
73
|
-
|
74
|
-
|
73
|
+
background: {
|
74
|
+
color: #eeeeee;
|
75
|
+
}
|
76
|
+
&:nth-child(even) {
|
77
|
+
background: {
|
78
|
+
color: #e5e5e5;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
&:hover {
|
82
|
+
background: {
|
83
|
+
color: #f1f1f1;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
.flex-start {
|
87
|
+
@include display-flex;
|
75
88
|
@media #{$small-only} {
|
76
|
-
|
89
|
+
@include flex-direction(column);
|
90
|
+
@include justify-content(flex-start);
|
91
|
+
@include align-items(center);
|
77
92
|
}
|
78
93
|
@media #{$medium-up} {
|
79
|
-
|
94
|
+
@include flex-direction(row);
|
95
|
+
@include justify-content(flex-start);
|
80
96
|
}
|
81
97
|
}
|
82
98
|
.media-texts {
|
83
|
-
padding-left: 15px;
|
84
99
|
@media #{$small-only} {
|
85
100
|
width: 100%;
|
101
|
+
@include order(-1);
|
86
102
|
}
|
87
|
-
@media #{$medium-
|
88
|
-
width:
|
103
|
+
@media #{$medium-only} {
|
104
|
+
width: 100%;
|
89
105
|
}
|
90
106
|
}
|
91
|
-
|
92
|
-
|
107
|
+
.product-image {
|
108
|
+
@media #{$small-only} {
|
109
|
+
width: 175px;
|
110
|
+
height: 175px;
|
111
|
+
}
|
112
|
+
@media #{$medium-only} {
|
113
|
+
width: 75px;
|
114
|
+
height: 75px;
|
115
|
+
}
|
116
|
+
@media #{$large-up} {
|
117
|
+
width: 125px;
|
118
|
+
height: 125px;
|
119
|
+
}
|
120
|
+
background: {
|
121
|
+
size: cover;
|
122
|
+
position: center center;
|
123
|
+
}
|
93
124
|
}
|
94
125
|
.product-title {
|
95
|
-
font-size: 1.
|
96
|
-
|
126
|
+
font-size: 1.15rem;
|
127
|
+
font-weight: bold;
|
128
|
+
}
|
129
|
+
.product-summary {
|
130
|
+
font-size: 0.85rem;
|
131
|
+
margin-bottom: 0.5rem;
|
132
|
+
color: #333;
|
133
|
+
}
|
134
|
+
.media-texts {
|
135
|
+
margin-left: 1rem;
|
136
|
+
padding-bottom: 1rem;
|
137
|
+
padding-top: 1rem;
|
138
|
+
}
|
139
|
+
.spec {
|
140
|
+
margin-right: 1rem;
|
97
141
|
}
|
98
|
-
|
99
|
-
font-size: 0.
|
142
|
+
.product-specs {
|
143
|
+
font-size: 0.8rem;
|
144
|
+
color: #333;
|
100
145
|
}
|
101
146
|
.taxon-tags {
|
102
|
-
|
147
|
+
margin-top: 5px;
|
148
|
+
padding-top: 5px;
|
149
|
+
padding-bottom: 5px;
|
103
150
|
}
|
104
151
|
.tag {
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
background: {
|
109
|
-
color: darken(red, 25%);
|
110
|
-
}
|
111
|
-
&:hover {
|
112
|
-
background-color: darken(red, 15%);
|
113
|
-
}
|
114
|
-
&:before {
|
152
|
+
margin-left: 5px;
|
153
|
+
margin-right: 10px;
|
154
|
+
&::before {
|
115
155
|
content: "+";
|
116
156
|
}
|
117
|
-
|
118
|
-
|
119
|
-
padding-left: 5px;
|
120
|
-
padding-right: 10px;
|
121
|
-
padding-top: 5px;
|
122
|
-
padding-bottom: 5px;
|
123
|
-
margin-right: 10px;
|
157
|
+
color: #666;
|
158
|
+
font-weight: bold;
|
124
159
|
}
|
125
160
|
}
|
161
|
+
|
162
|
+
|
126
163
|
<% end %>
|
@@ -5,37 +5,72 @@
|
|
5
5
|
@include transition-duration(300ms);
|
6
6
|
@include transition-timing-function(ease-out);
|
7
7
|
background: {
|
8
|
-
color: #
|
8
|
+
color: #eeeeee;
|
9
9
|
}
|
10
10
|
&:hover {
|
11
11
|
background: {
|
12
|
-
color: #
|
12
|
+
color: #f1f1f1;
|
13
13
|
}
|
14
14
|
}
|
15
|
+
|
15
16
|
.product-image {
|
16
|
-
|
17
|
-
|
17
|
+
@media #{$small-only} {
|
18
|
+
width: 175px;
|
19
|
+
height: 175px;
|
20
|
+
}
|
21
|
+
@media #{$medium-up} {
|
22
|
+
width: 100px;
|
23
|
+
height: 100px;
|
24
|
+
}
|
25
|
+
@media #{$large-up} {
|
26
|
+
width: 125px;
|
27
|
+
height: 125px;
|
28
|
+
}
|
29
|
+
background: {
|
30
|
+
size: cover;
|
31
|
+
position: center center;
|
32
|
+
}
|
18
33
|
}
|
19
34
|
.media-texts {
|
20
35
|
font-size: 1.45rem;
|
21
36
|
width: 100%;
|
37
|
+
@media #{$small-only} {
|
38
|
+
@include order(-1);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
.big-title {
|
42
|
+
padding-top: 10px;
|
43
|
+
padding-bottom: 10px;
|
44
|
+
}
|
45
|
+
.dateline {
|
46
|
+
font-size: 0.9rem;
|
47
|
+
font-weight: bold;
|
48
|
+
margin-bottom: 10px;
|
49
|
+
color: #777;
|
22
50
|
}
|
23
51
|
.smaller-details {
|
24
52
|
font-size: 0.8rem;
|
53
|
+
color: #444;
|
25
54
|
}
|
26
55
|
.media-object {
|
27
56
|
margin-right: 15px;
|
28
57
|
}
|
29
58
|
.product-header {
|
30
59
|
@include display-flex;
|
31
|
-
@include flex-direction(row);
|
32
|
-
@include justify-content(flex-start);
|
33
60
|
@include align-items(center);
|
61
|
+
@media #{$small-only} {
|
62
|
+
@include flex-direction(column);
|
63
|
+
@include justify-content(flex-start);
|
64
|
+
}
|
65
|
+
@media #{$medium-up} {
|
66
|
+
@include flex-direction(row);
|
67
|
+
@include justify-content(flex-start);
|
68
|
+
}
|
34
69
|
border-bottom: 1px solid #bbb;
|
35
70
|
}
|
36
71
|
.taxon-tags {
|
37
|
-
margin-top: 5px;
|
38
|
-
margin-bottom: 5px;
|
72
|
+
margin-top: 2.5px;
|
73
|
+
margin-bottom: 2.5px;
|
39
74
|
}
|
40
75
|
.tag {
|
41
76
|
@include transition-property(background-color);
|
@@ -50,13 +85,16 @@
|
|
50
85
|
&:before {
|
51
86
|
content: "+";
|
52
87
|
}
|
53
|
-
font-size:
|
88
|
+
font-size: 0.8rem;
|
54
89
|
color: #ddd;
|
55
|
-
padding-left: 5px;
|
56
|
-
padding-right:
|
57
|
-
padding-top: 5px;
|
58
|
-
padding-bottom: 5px;
|
59
|
-
margin-right:
|
90
|
+
padding-left: 2.5px;
|
91
|
+
padding-right: 5px;
|
92
|
+
padding-top: 2.5px;
|
93
|
+
padding-bottom: 2.5px;
|
94
|
+
margin-right: 5px;
|
95
|
+
}
|
96
|
+
.decent-prespace {
|
97
|
+
padding-left: 1.2rem;
|
60
98
|
}
|
61
99
|
<% end %>
|
62
100
|
}
|