Created
October 18, 2013 06:16
-
-
Save stijlist/7037204 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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