Skip to content

Instantly share code, notes, and snippets.

@stijlist
Created October 18, 2013 06:16
Show Gist options
  • Save stijlist/7037203 to your computer and use it in GitHub Desktop.
Save stijlist/7037203 to your computer and use it in GitHub Desktop.
<section class='retreat-theme'>
<div class="row">
<div class="large-12 columns center">
<div class="retreat-heading">
<p class="retreat-date">January 10-12, 2014</p>
<h1 class="retreat-logo">Whatcha Gonna Do?</h1>
<h4 class="retreat-verse">"Do not merely listen to the word, and so deceive yourselves. Do what it says." - James 1:22</h4>
<span class="retreat-amount">$85</span>
</div>
</div>
</div>
</section>
<section class='retreat-description'>
<div class="retreat-banner">
<h6>To hear the Word of God is a good thing, but it is not enough; so James says, “Do not merely listen to the word”. Rather than just hearing the Word, we are to “Do what it says”. Now, what does the Word says that we are to do?</h6>
</div>
<div class="retreat-desc">
<div class="row">
<div class="large-12 columns">
<div class="retreat-desc-heading">
<h2>About The Retreat</h2>
</div>
<div class="large-6 columns retreat-desc-body"><p><b>what the retreat is about</b>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum, ratione, porro voluptatem nihil fuga sapiente doloribus sed temporibus excepturi consectetur ad quasi veniam. Facere adipisci dolores repellendus dicta repudiandae quo?</p></div>
<div class="large-6 columns retreat-desc-body"><p><b>what we hope youth will get out of this retreat</b>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit, maxime, sed, rerum, numquam dolor quisquam amet repellendus at recusandae nam repudiandae rem quibusdam magni aperiam facere veritatis iure ad nulla?</p></div>
<div class="large-12 columns retreat-desc-body"><p><b>what're the topics we're covering at retreat.</b>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque, fugit ut quo eaque hic perspiciatis reprehenderit. Ut, perspiciatis, enim in vitae aperiam earum architecto nostrum praesentium repellendus adipisci fugit ad! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Explicabo, animi dignissimos adipisci provident ut quam architecto voluptas voluptate. Eum, tempora, ipsum tenetur doloribus sed quaerat ducimus nulla assumenda porro obcaecati.</p></div>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<div class="retreat-desc-heading">
<h3>Promotional Videos</h3>
</div>
<img src="http://placehold.it/1280x720&text=promovid1" alt="video-placeholder">
<hr />
<img src="http://placehold.it/1280x720&text=promovid2" alt="video-placeholder">
</div>
</div>
</div>
</section>
<section class="retreat-location">
<div class="retreat-location-wrap">
<a href="http://goo.gl/maps/MlrcU" target="_blank" class="retreat-location-image"></a>
<h6>Retreat Will Be At The</h6>
<a href="http://goo.gl/maps/MlrcU" target="_blank"><h2>Frontier Camp</h2></a>
<h6>Grapeland, Texas</h6>
</div>
</section>
<section class='retreat-details'>
<div class="row">
<div class="large-12 columns">
<div class="retreat-details-heading">
<h2>Schedule</h2>
</div>
<div class="retreat-schedule">
<ul>
<li>
<h5>Friday, January 10th</h5>
<ul>
<li>
<time>9:30 pm</time>
<h6>Welcome & Dinner</h6>
</li>
</ul>
</li>
<li>
<h5>Saturday, January 11th</h5>
<ul>
<li>
<time>9:30 pm</time>
<h6>Welcome & Dinner</h6>
</li>
</ul>
</li>
<li>
<h5>Sunday, January 12th</h5>
<ul>
<li>
<time>9:30 pm</time>
<h6>Welcome & Dinner</h6>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</section>
<section class='retreat-calltoaction'>
<% binding.pry %>
<% if current_user and current_user.registered_for_retreat? %>
<p> gj bb </b>
<% elsif current_user %>
<%= render 'retreat_registrations/form' %>
<% else %>
<p> plz sign in bb </p>
<% end %>
</section>
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :timeoutable
has_many :payments
has_many :retreat_registrations
def fullname
self.fname ? self.fname + " " + self.lname : nil
end
def address
self.line1 + self.city + self.state + self.zip
end
def new_card(stripe_token)
begin
raise "No stripe token submitted" unless stripe_token
if self.stripe_id
customer = Stripe::Customer.retrieve(self.stripe_id)
customer.default_card = customer.cards.create(card: stripe_token)
customer.save
else
customer = Stripe::Customer.create(
description: self.fullname,
card: stripe_token
)
self.stripe_id = customer.id
end
self.save
customer
rescue Stripe::CardError => e
# catch stripe error here
# can we console.log an exception?
# should we raise the exception again to allow it to be passed on to the
# controller or the view?
logger.info(e)
raise
end
end
def charge(amount: nil, description: nil)
# TODO: validate that there are no decimals in the amount
raise "There is no credit card saved for this account" unless self.stripe_id
begin
Stripe::Charge.create(
amount: amount, # amount in cents, again
currency: "usd",
customer: self.stripe_id,
description: description
)
rescue => e
logger.info(e)
end
end
def credit_card
# instead of saving this in the database, we query Stripe each time we want
# to get the value of the user's current card
Stripe::Customer.retrieve(id: self.stripe_id, expand: ['default_card']).default_card if self.stripe_id
end
def email_subscribe
gibbon = Gibbon::API.new
Gibbon::API.throws_exceptions = false
self.email_contact = true
if gibbon.lists.members(id: ENV['MAILCHIMP_CAMPAIGN_ID'], email: self.email)
gibbon.lists.subscribe(id: ENV['MAILCHIMP_CAMPAIGN_ID'],
email: {email: self.email},
merge_vars: {FNAME: self.fname, LNAME: self.lname},
double_optin: false)
end
end
def email_unsubscribe
gibbon = Gibbon::API.new
Gibbon::API.throws_exceptions = false
self.email_contact = false
if gibbon.lists.members(id: ENV['MAILCHIMP_CAMPAIGN_ID'], email: self.email)
gibbon.lists.unsubscribe(id: ENV['MAILCHIMP_CAMPAIGN_ID'],
email: {email: self.email},
merge_vars: {FNAME: self.fname, LNAME: self.lname},
double_optin: false)
end
end
def sms_subscribe
self.phone? ? self.sms_contact = true : false
end
def sms_unsubscribe
self.sms_contact=false
end
# TODO:
def registered_for_retreat?
puts self.retreat_registrations
self.retreat_registrations.any? {|r|
puts "Registration: ", r, "Retreat: ", r.retreat, "Retreat id: ", r.retreat.id
r.retreat.id.equal? Retreat.current.id }
end
# TODO:
def paid_for_retreat?
self.payments.any? {|p| p.event.id.equal? Retreat.current.id }
end
# TODO:
def retreat_paid_out_of_band
end
# Temporary fix for now
def dues_paid_out_of_band
if this_years_dues
if self.payments.build({event_id: this_years_dues.id}).save!
logger.info "Successfully updated dues status for #{self.fullname}"
else
logger.info "Saving the updated dues payment failed for some reason. Try again?"
end
else
logger.info "This year's dues event has not been created yet, create it first!"
end
end
def dues_paid?
self.paid_events.include? this_years_dues
end
def unpaid_events
paid_events = self.paid_events
events_requiring_payment = Event.where.not(cost: nil)
# the set difference of two arrays a & b in ruby is (a - b) | (b - a)
events_requiring_payment - paid_events | paid_events - events_requiring_payment
end
def paid_events
# TODO: the delete_if call is required to trim payments that have been made
# for events which have since been deleted. It's important to keep record
# of these payments, so they shouldn't be destroyed in the database, but
# their associated events return nil in the database. I'll keep thinking
# about the best way to handle this.
self.payments.collect { |p| p.event }.delete_if { |event| event.nil? }
end
def has_selected_contact_preference?
[ :email_contact, :facebook_contact, :sms_contact ].any? do |c|
self[c]
end
end
def profile_completion_percentage
# TODO: We want to avoid hardcoding this; how do we link the elements of
# the required profile items array to the contents of the profile form?
# If we keep this hardcoded, every update of the profile form will require
# this to be updated, or else we'll break the profile_completion_percentage
# indicator
required_profile_items = [ :email, :fname, :lname, :phone, :gender, :birthday, :city, :state, :zip, :shirtsize, :email_contact, :facebook_contact, :sms_contact ]
total = required_profile_items.size
completed = 0.0
# This method is tricky because the database does not reliably return "nil" from
# profile items that are semantically "empty."
# This debugging code helped me understand which profile items I can't reliably use nil
# to detect.
required_profile_items.each do |k|
logger.info self[k]
logger.info self[k].class
logger.info "#{k} #{ self[k].nil? ? "is nil" : "is not nil" }"
end
# TODO: there is DEFINITELY a cleaner way to do this
required_profile_items.each do |k|
item = self[k]
# TODO: annoyingly, the DateTime class does not respond to the .empty?
# method, hence this stupid special case check. Figure out a better way
# to do this.
if item.respond_to? :empty?
completed += 1 unless item.empty? or item.nil?
else
completed += 1 unless item.nil?
end
end
# calculate the average, round the result
((completed / total)* 100).round
end
private
def this_years_dues
this_years_dues = Event.where(dues: true).detect do |dues|
dues.startdt.year.equal? DateTime.now.year
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment