Skip to content

Commit

Permalink
Merge pull request #10686 from loomio/new-plans
Browse files Browse the repository at this point in the history
New plans
  • Loading branch information
robguthrie committed Apr 26, 2024
2 parents a733de3 + 18ec6be commit 42246f3
Show file tree
Hide file tree
Showing 81 changed files with 962 additions and 174 deletions.
10 changes: 2 additions & 8 deletions app/assets/stylesheets/basic/_layout.scss
Expand Up @@ -2,8 +2,9 @@ html {
font-family: "Roboto", sans-serif;
}


body {
background-color: #f7f7ed;
background-color: rgb(252,246,235);
color: rgba(0,0,0,0.9);
margin: 1em auto;
line-height: 1.5;
Expand Down Expand Up @@ -53,10 +54,3 @@ footer {
}
}

main {
background-color: #fff;
padding: 1em;
margin: 1em;
border-radius: 5px;
border: 1px solid #ccc;
}
12 changes: 1 addition & 11 deletions app/assets/stylesheets/marketing/buttons.scss
Expand Up @@ -7,19 +7,10 @@
text-decoration: none;
text-align: center;
background: transparent;
// white-space: nowrap;
// line-height: 3;
}

.btn {
@extend %btn--base;

&:hover,
&:focus,
&:active {
background-color: rgba(0,0,0,0.05);
color: darken($font-color, 20%);
}
}

.btn--blue {
Expand Down Expand Up @@ -47,8 +38,7 @@
&:hover,
&:focus,
&:active {
color: $white;
background-color: lighten($primary-color, 5%);
opacity: 0.9;
}
}

Expand Down
94 changes: 76 additions & 18 deletions app/assets/stylesheets/marketing/landing.scss
@@ -1,3 +1,49 @@
.ribbon-parent {
overflow: hidden; /* required */
position: relative; /* required for demo*/
}

.ribbon {
margin: 0;
padding: 0;
background: #DCA034;
color:white;
padding:0.6em 0;
position: absolute;
top:0;
right:0;
transform: translateX(30%) translateY(0%) rotate(45deg);
transform-origin: top left;
}

.ribbon-grey {
background: rgb(41, 60, 74) !important;
}

.ribbon-grey:before,
.ribbon-grey:after {
background: rgb(41, 60, 74) !important;
}

.ribbon:before,
.ribbon:after {
content: '';
position: absolute;
top:0;
margin: 0 -1px; /* tweak */
width: 100%;
height: 100%;
background: #DCA034;
}

.ribbon:before {
right:100%;
}

.ribbon:after {
left:100%;
}

.main--landing {
section {
margin-left: auto;
Expand Down Expand Up @@ -28,15 +74,26 @@
@extend .btn--primary;

border-radius: 6px;
text-transform: uppercase;
padding: 15px 20px;
font-size: 16px;
font-weight: normal;
letter-spacing: .75px;
display: inline-block;

}

.btn--ink {
@extend .btn--base--landing;
border-color: transparent;
background-color: #293c4a;
color: #fff;
}

.btn--gold {
@extend .btn--base--landing;
border-color: transparent;
background-color: #dca034;
color: #fff;
}

.btn--primary--landing {
@extend .btn--base--landing;
}
Expand All @@ -58,30 +115,31 @@
}
}

.nonprofit-warning {
border: 2px solid #293c4a;
border-radius: 1.5rem;
margin-left: auto;
margin-right: auto;
}

.price-box {
background-color: rgba($accent-color, 0.15);
border: 2px solid #293c4a;
border-radius: 1.5rem;
margin: 0 20px 20px;
padding-bottom: 20px;
border-radius: 6px;
width: 300px;
width: 325px;
padding: 24px;

h2 {
margin: 0;
background-color: $accent-color;
border-radius: 6px 6px 0 0;
text-align: center;
color: white;
text-transform: uppercase;
font-size: 18px;
padding: 10px;
font-size: 1.875rem;
line-height: 2.25rem;
color: #000;
font-weight: 400
}

&.primary {
background-color: rgba($primary-color, 0.15);

h2 {
background-color: $primary-color;
}
border-color: #dca034;
}

.invitation {
Expand Down
9 changes: 9 additions & 0 deletions app/assets/stylesheets/vtfy/typography.css
Expand Up @@ -23,6 +23,15 @@ kbd{
padding:.2em .4rem;
box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)
}

.text-ink, .text-ink a {
color: rgb(41, 60, 74);
}

.text-slate-700, .text-slate-700 a {
color: rgb(51, 65, 85);
}

.theme--light.heading{
color:rgba(0,0,0,.87)
}
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/api/v1/snorlax_base.rb
Expand Up @@ -276,7 +276,7 @@ def resource_class
end

def respond_with_standard_error(error, status)
render json: {exception: "#{error.class} #{error.to_s}"}, root: false, status: status
render json: {exception: error.class, error: error.to_s}, root: false, status: status
end

def respond_with_error(status, message = "error")
Expand Down
33 changes: 33 additions & 0 deletions app/controllers/api/v1/trials_controller.rb
@@ -0,0 +1,33 @@
class API::V1::TrialsController < API::V1::RestfulController
def create
email = params[:user_email].strip

user = User.verified.find_by(email: email)
if !user
user = User.where(email_verified: false, email: email).first_or_create
user.name = params[:user_name].strip
user.recaptcha = params[:recaptcha]
user.legal_accepted = true
user.email_newsletter = !!params[:newsletter]
# user.require_valid_signup = true
# user.require_recaptcha = true
user.save!
end

raise "you said I'd have a user by now" unless user && user.valid?

group = Group.new(
name: params[:group_name].strip,
description: MarkdownService.render_html(params[:group_intention].strip),
description_format: 'html',
group_privacy: "secret",
category: params[:group_category],
)
group.handle = GroupService.suggest_handle(name: group.name, parent_handle: nil)
GroupService.create(group: group, actor: user, skip_authorize: true)

raise "start trial failed" unless group.valid?

render json: {success: :ok, group_path: group_handle_path(group.handle)}
end
end
1 change: 1 addition & 0 deletions app/extras/app_config.rb
Expand Up @@ -91,6 +91,7 @@ def self.app_features
subscriptions: !!ENV.fetch('CHARGIFY_API_KEY', false),
demos: ENV.fetch('FEATURES_DEMO_GROUPS', false),
trials: ENV.fetch('FEATURES_TRIALS', false),
trial_days: ENV.fetch('TRIAL_DAYS', nil),
new_thread_button: !!ENV.fetch('FEATURES_NEW_THREAD_BUTTON', false),
email_login: !ENV['FEATURES_DISABLE_EMAIL_LOGIN'],
create_user: !ENV['FEATURES_DISABLE_CREATE_USER'],
Expand Down
3 changes: 3 additions & 0 deletions app/extras/user_inviter.rb
Expand Up @@ -58,6 +58,9 @@ def self.authorize!(emails: , user_ids:, audience:, model:, actor:)

# members belong to group
member_ids = model.members.where(id: user_ids).pluck(:id)
member_ids += model.members.where(email: emails).pluck(:id)

emails -= User.where(email: emails, id: member_ids).pluck(:email)

# guests are outside of the group, but allowed to be referenced by user query
guest_ids = UserQuery.invitable_user_ids(model: model, actor: actor, user_ids: user_ids - member_ids)
Expand Down
1 change: 0 additions & 1 deletion app/mailers/event_mailer.rb
Expand Up @@ -28,7 +28,6 @@ def event(recipient_id, event_id)
# if someone does not respond to the invitation, don't send them more emails
return if @membership &&
!@recipient.email_verified &&
!@membership.accepted_at &&
!["membership_created", "membership_resent"].include?(@event.kind)
end

Expand Down
4 changes: 2 additions & 2 deletions app/models/ability/discussion.rb
Expand Up @@ -41,8 +41,8 @@ def initialize(user)

can [:add_guests], ::Discussion do |discussion|
if discussion.group_id
discussion.group.admins.exists?(user.id) ||
(discussion.group.members_can_add_guests && discussion.members.exists?(user.id))
Subscription.for(discussion.group).allow_guests &&
(discussion.group.admins.exists?(user.id) || (discussion.group.members_can_add_guests && discussion.members.exists?(user.id)))
else
!discussion.id || discussion.admins.exists?(user.id)
end
Expand Down
4 changes: 2 additions & 2 deletions app/models/ability/poll.rb
Expand Up @@ -51,8 +51,8 @@ def initialize(user)

can [:add_guests], ::Poll do |poll|
if poll.group_id
poll.group.admins.exists?(user.id) ||
(poll.group.members_can_add_guests && poll.admins.exists?(user.id))
Subscription.for(poll.group).allow_guests &&
(poll.group.admins.exists?(user.id) || (poll.group.members_can_add_guests && poll.admins.exists?(user.id)))
else
poll.admins.exists?(user.id)
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/group.rb
Expand Up @@ -290,7 +290,7 @@ def org_memberships_count
end

def org_members_count
Membership.active.where(group_id: id_and_subgroup_ids).count('distinct user_id')
Membership.active.accepted.where(group_id: id_and_subgroup_ids).count('distinct user_id')
end

def org_discussions_count
Expand Down
2 changes: 1 addition & 1 deletion app/models/stance.rb
Expand Up @@ -82,7 +82,7 @@ def self.pg_search_insert_statement(id: nil, author_id: nil, discussion_id: nil,
scope :oldest_first, -> { order(created_at: :asc) }
scope :priority_first, -> { joins(:poll_options).order('poll_options.priority ASC') }
scope :priority_last, -> { joins(:poll_options).order('poll_options.priority DESC') }
scope :with_reason, -> { where("reason IS NOT NULL AND reason != ''") }
scope :with_reason, -> { where("reason IS NOT NULL AND reason != '' AND reason != '<p></p>'") }
scope :in_organisation, ->(group) { joins(:poll).where("polls.group_id": group.id_and_subgroup_ids) }
scope :decided, -> { where("stances.cast_at IS NOT NULL") }
scope :undecided, -> { where("stances.cast_at IS NULL") }
Expand Down
2 changes: 1 addition & 1 deletion app/queries/user_query.rb
Expand Up @@ -65,7 +65,7 @@ def self.invitable_user_ids(model: , actor:, user_ids: )

def self.invitable_search(model:, actor:, q: nil, limit: 50)
ids = relations(model: model, actor: actor).map do |rel|
rel.active.verified.search_for(q).limit(limit).pluck(:id)
rel.active.search_for(q).limit(limit).pluck(:id)
end.flatten.uniq.compact
User.where(id: ids).order(:memberships_count).limit(50)
end
Expand Down
2 changes: 2 additions & 0 deletions app/serializers/group_serializer.rb
Expand Up @@ -74,6 +74,7 @@ def subscription
{
max_members: sub.max_members,
max_threads: sub.max_threads,
allow_subgroups: sub.allow_subgroups,
plan: sub.plan,
active: sub.is_active?,
renews_at: sub.renews_at,
Expand All @@ -84,6 +85,7 @@ def subscription
{
max_members: sub.max_members,
max_threads: sub.max_threads,
allow_subgroups: sub.allow_subgroups,
plan: sub.plan,
active: sub.is_active?,
members_count: sub.members_count
Expand Down
4 changes: 2 additions & 2 deletions app/services/group_service.rb
Expand Up @@ -85,8 +85,8 @@ def self.invite(group:, params:, actor:)
Membership.active.where(group_id: group.id, user_id: users.pluck(:id))
end

def self.create(group:, actor: )
actor.ability.authorize! :create, group
def self.create(group:, actor: , skip_authorize: false)
actor.ability.authorize!(:create, group) unless skip_authorize

return false unless group.valid?

Expand Down
7 changes: 4 additions & 3 deletions app/views/layouts/basic.html.haml
Expand Up @@ -10,9 +10,10 @@
= stylesheet_link_tag 'marketing/all'
= render 'plausible'
%body
%header
%a{href: '/'}
%img{style: 'max-width: 256px', src: AppConfig.theme[:app_logo_src]}
.container
%header.d-flex.justify-center
%a{href: '/'}
%img{style: 'max-width: 128px', src: AppConfig.theme[:app_logo_src]}
.container
= yield

Expand Down
3 changes: 2 additions & 1 deletion config/initializers/rack_attack.rb
Expand Up @@ -15,8 +15,9 @@ def remote_ip
# req.remote_ip
# end
IP_POST_LIMITS = {
'/api/v1/trails' => 10,
'/api/v1/announcements' => 100,
'/api/v1/groups' => 30,
'/api/v1/groups' => 20,
'/api/v1/templates' => 10,
'/api/v1/login_tokens' => 10,
'/api/v1/membership_requests' => 100,
Expand Down

0 comments on commit 42246f3

Please sign in to comment.