Initial Commit
31
.gitignore
vendored
@@ -1,16 +1,19 @@
|
||||
*.rbc
|
||||
*.sassc
|
||||
.sass-cache
|
||||
capybara-*.html
|
||||
.rspec
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
#
|
||||
# If you find yourself ignoring temporary files generated by your text editor
|
||||
# or operating system, you probably want to add a global ignore instead:
|
||||
# git config --global core.excludesfile ~/.gitignore_global
|
||||
|
||||
# Ignore bundler config
|
||||
/.bundle
|
||||
/vendor/bundle
|
||||
/log/*
|
||||
/tmp/*
|
||||
|
||||
# Ignore the default SQLite database.
|
||||
/db/*.sqlite3
|
||||
/public/system/*
|
||||
/coverage/
|
||||
/spec/tmp/*
|
||||
**.orig
|
||||
rerun.txt
|
||||
pickle-email-*.html
|
||||
|
||||
# Ignore all logfiles and tempfiles.
|
||||
/log/*.log
|
||||
/tmp
|
||||
|
||||
config/settings.local.yml
|
||||
config/settings/*.local.yml
|
||||
config/environments/*.local.yml
|
||||
|
||||
30
Gemfile
Normal file
@@ -0,0 +1,30 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rails', '3.2.8'
|
||||
|
||||
group :development do
|
||||
gem 'sqlite3'
|
||||
end
|
||||
|
||||
group :production do
|
||||
gem 'thin'
|
||||
gem 'pg'
|
||||
end
|
||||
|
||||
# Gems used only for assets and not required
|
||||
# in production environments by default.
|
||||
group :assets do
|
||||
gem 'sass-rails', '~> 3.2.3'
|
||||
gem 'coffee-rails', '~> 3.2.1'
|
||||
gem 'therubyracer', :platforms => :ruby
|
||||
gem 'uglifier', '>= 1.0.3'
|
||||
end
|
||||
|
||||
# jQuery
|
||||
gem 'jquery-rails'
|
||||
|
||||
# Kickstarter's awesome Amazon Flexible Payments gem
|
||||
gem 'amazon_flex_pay'
|
||||
|
||||
# Configuration File
|
||||
gem 'rails_config'
|
||||
138
Gemfile.lock
Normal file
@@ -0,0 +1,138 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.8)
|
||||
actionpack (= 3.2.8)
|
||||
mail (~> 2.4.4)
|
||||
actionpack (3.2.8)
|
||||
activemodel (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.0)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.1.3)
|
||||
activemodel (3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.8)
|
||||
activemodel (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.8)
|
||||
activemodel (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
activesupport (3.2.8)
|
||||
i18n (~> 0.6)
|
||||
multi_json (~> 1.0)
|
||||
amazon_flex_pay (0.9.13)
|
||||
activesupport (>= 3.0.14)
|
||||
multi_xml (~> 0.2.0)
|
||||
rest-client (~> 1.6.1)
|
||||
arel (3.0.2)
|
||||
builder (3.0.3)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
coffee-script (2.2.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.3.3)
|
||||
daemons (1.1.9)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.0.0)
|
||||
execjs (1.4.0)
|
||||
multi_json (~> 1.0)
|
||||
foreman (0.60.2)
|
||||
thor (>= 0.13.6)
|
||||
hike (1.2.1)
|
||||
i18n (0.6.1)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.1.3)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
json (1.7.5)
|
||||
libv8 (3.3.10.4)
|
||||
mail (2.4.4)
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
mime-types (1.19)
|
||||
multi_json (1.3.6)
|
||||
multi_xml (0.2.2)
|
||||
pg (0.14.1)
|
||||
polyglot (0.3.3)
|
||||
rack (1.4.1)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-ssl (1.3.2)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.8)
|
||||
actionmailer (= 3.2.8)
|
||||
actionpack (= 3.2.8)
|
||||
activerecord (= 3.2.8)
|
||||
activeresource (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.8)
|
||||
rails_config (0.3.1)
|
||||
activesupport (>= 3.0)
|
||||
railties (3.2.8)
|
||||
actionpack (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
rake (0.9.2.2)
|
||||
rdoc (3.12)
|
||||
json (~> 1.4)
|
||||
rest-client (1.6.7)
|
||||
mime-types (>= 1.16)
|
||||
sass (3.2.1)
|
||||
sass-rails (3.2.5)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
sprockets (2.1.3)
|
||||
hike (~> 1.2)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sqlite3 (1.3.6)
|
||||
therubyracer (0.10.2)
|
||||
libv8 (~> 3.3.10)
|
||||
thin (1.5.0)
|
||||
daemons (>= 1.0.9)
|
||||
eventmachine (>= 0.12.6)
|
||||
rack (>= 1.0.0)
|
||||
thor (0.16.0)
|
||||
tilt (1.3.3)
|
||||
treetop (1.4.10)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.33)
|
||||
uglifier (1.3.0)
|
||||
execjs (>= 0.3.0)
|
||||
multi_json (~> 1.0, >= 1.0.2)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
amazon_flex_pay
|
||||
coffee-rails (~> 3.2.1)
|
||||
foreman
|
||||
jquery-rails
|
||||
pg
|
||||
rails (= 3.2.8)
|
||||
rails_config
|
||||
sass-rails (~> 3.2.3)
|
||||
sqlite3
|
||||
therubyracer
|
||||
thin
|
||||
uglifier (>= 1.0.3)
|
||||
1
Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: bundle exec rails server thin -p $PORT -e $RACK_ENV
|
||||
66
README.rdoc
Normal file
@@ -0,0 +1,66 @@
|
||||
# Selfstarter
|
||||
Selfstarter makes it easy to roll your own crowdfunding site. To get started, fork this repository and change around ```config/settings.yml``` to suit your needs.
|
||||
|
||||
## Background
|
||||
|
||||
[Kickstarter rejected us](http://techcrunch.com/2012/10/07/the-story-of-lockitron-crowdfunding-without-kickstarter/), so we made our own crowdfunding for [Lockitron](https://lockitron.com). Feel free to [give us feedback](mailto:hello@lockitron.com)!
|
||||
|
||||
Over the past week, a lot of people asked us for help with building their own crowdfunding app. This is it.
|
||||
|
||||
Selfstarter is starting point. We made some specific choices with Selfstarter for Lockitron and we recommend you tailor it for your project:
|
||||
|
||||
* We use Amazon Payments for payments. You can use Stripe or WePay. We used Kickstarter's awesome ```amazon_flex_pay``` gem.
|
||||
* We collect multi-use tokens from customers with Amazon Payments - this let's us collect payment information without charging the customer until we are ready to ship
|
||||
* Selfstarter doesn't come with any authentication, administration, mailers or analytics tools. We recommend adding a basic set of these so that you can message backers and manage orders.
|
||||
|
||||
## Getting Started
|
||||
|
||||
First you'll need to fork and clone this repo
|
||||
|
||||
Let's get all our dependencies setup:
|
||||
```bash
|
||||
bundle install --without production
|
||||
```
|
||||
|
||||
Now let's create the database:
|
||||
```bash
|
||||
rake db:migrate
|
||||
```
|
||||
|
||||
Let's get it running:
|
||||
```bash
|
||||
rails s
|
||||
```
|
||||
|
||||
### Customizing
|
||||
|
||||
While it is *just* a skeleton, we did make it a little quicker to change around things like your product name, the colors, pricing, etc.
|
||||
|
||||
To change around the product name, tweet text, and more, open this file:
|
||||
|
||||
```
|
||||
config/settings.yml
|
||||
```
|
||||
|
||||
To change around the colors and fonts, open this file:
|
||||
|
||||
```
|
||||
app/assets/stylesheets/variables.css.scss
|
||||
```
|
||||
|
||||
To dive into the code, open this file:
|
||||
|
||||
```
|
||||
app/controllers/preorder_controller.rb
|
||||
```
|
||||
|
||||
### Deploying to Production
|
||||
|
||||
We recommend using Heroku, and we even include a ```Procfile``` for you. All you need to do is run:
|
||||
|
||||
```bash
|
||||
gem install heroku
|
||||
heroku create
|
||||
git push heroku master
|
||||
heroku run rake db:migrate
|
||||
```
|
||||
7
Rakefile
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env rake
|
||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||
|
||||
require File.expand_path('../config/application', __FILE__)
|
||||
|
||||
Selfstarter::Application.load_tasks
|
||||
BIN
app/assets/images/1-background.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
app/assets/images/2-background.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
app/assets/images/3-background.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
app/assets/images/4-background.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
app/assets/images/background.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
app/assets/images/bullet.png
Normal file
|
After Width: | Height: | Size: 148 B |
BIN
app/assets/images/rails.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
19
app/assets/javascripts/application.js
Normal file
@@ -0,0 +1,19 @@
|
||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
// listed below.
|
||||
//
|
||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
||||
//
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// the compiled file.
|
||||
//
|
||||
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
||||
// GO AFTER THE REQUIRES BELOW.
|
||||
//
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require jquery-ui
|
||||
//= require jquery.details
|
||||
//= require jquery.textchange
|
||||
//= require preorder
|
||||
//= require_tree .
|
||||
6
app/assets/javascripts/jquery.details.js
Normal file
@@ -0,0 +1,6 @@
|
||||
(function(b){var d="open"in document.createElement("details"),e;b.fn.details=function(a){"open"===a&&(d?this.prop("open",!0):this.trigger("open"));"close"===a&&(d?this.prop("open",!1):this.trigger("close"));"init"===a&&e(b(this));if(!a){if(!d)return this.hasClass("open");var c=!1;this.each(function(){if(this.open)return c=!0,!1});return c}};e=function(a){a=a.not(".details-inited").addClass("details-inited");a.filter(".animated").each(function(){var a=b(this),d=a.children("summary").remove(),e=b("<div>").addClass("details-wrapper").append(a.children());
|
||||
a.append(e).prepend(d)});d||(a.each(function(){var a=b(this);a.children("summary").length||a.prepend("<summary>Details</summary>")}).children("summary").filter(":not(tabindex)").attr("tabindex",0).end().end().contents(":not(summary)").filter(function(){return 3===this.nodeType&&/[^\t\n\r ]/.test(this.data)}).wrap("<span>").end().end().filter(":not([open])").prop("open",!1).end().filter("[open]").addClass("open").prop("open",!0).end(),b.browser.msie&&9>b.browser.msie&&a.filter(":not(.open)").children().not("summary").hide())};
|
||||
b(function(){b("body").on("open.details","details.animated",function(){var a=b(this),c=a.children(".details-wrapper");c.hide();setTimeout(function(){c.slideDown(a.data("animation-speed"))},0)}).on("close.details","details.animated",function(){var a=b(this),c=a.children(".details-wrapper");setTimeout(function(){a.prop("open",!0).addClass("open");c.slideUp(a.data("animation-speed"),function(){a.prop("open",!1).removeClass("open")})},0)});if(d)b("body").on("click","summary",function(){var a=b(this).parent();
|
||||
a.prop("open")?a.trigger("close"):a.trigger("open")});else if(b("html").addClass("no-details"),b("head").prepend('<style>details{display:block}summary{cursor:pointer}details>summary::before{content:"\u25ba"}details.open>summary::before{content:"\u25bc"}details:not(.open)>:not(summary){display:none}</style>'),b("body").on("open.details","details",function(a){b(this).addClass("open").trigger("change.details");a.stopPropagation()}).on("close.details","details",function(a){b(this).removeClass("open").trigger("change.details");
|
||||
a.stopPropagation()}).on("toggle.details","details",function(a){var c=b(this);c.hasClass("open")?c.trigger("close"):c.trigger("open");a.stopPropagation()}).on("click","summary",function(){b(this).parent().trigger("toggle")}).on("keyup","summary",function(a){(32===a.keyCode||13===a.keyCode&&!b.browser.opera)&&b(this).parent().trigger("toggle")}),b.browser.msie&&9>b.browser.msie)b("body").on("open.details","details",function(){b(this).children().not("summary").show()}).on("close.details","details",
|
||||
function(){b(this).children().not("summary").hide()});e(b("details"))})})(jQuery);
|
||||
10
app/assets/javascripts/jquery.textchange.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/*!
|
||||
* jQuery TextChange Plugin
|
||||
* http://www.zurb.com/playground/jquery-text-change-custom-event
|
||||
*
|
||||
* Copyright 2010, ZURB
|
||||
* Released under the MIT License
|
||||
*/
|
||||
(function(a){a.event.special.textchange={setup:function(){a(this).data("lastValue",this.contentEditable==="true"?a(this).html():a(this).val());a(this).bind("keyup.textchange",a.event.special.textchange.handler);a(this).bind("cut.textchange paste.textchange input.textchange",a.event.special.textchange.delayedHandler)},teardown:function(){a(this).unbind(".textchange")},handler:function(){a.event.special.textchange.triggerIfChanged(a(this))},delayedHandler:function(){var c=a(this);setTimeout(function(){a.event.special.textchange.triggerIfChanged(c)},
|
||||
25)},triggerIfChanged:function(a){var b=a[0].contentEditable==="true"?a.html():a.val();b!==a.data("lastValue")&&(a.trigger("textchange",[a.data("lastValue")]),a.data("lastValue",b))}};a.event.special.hastext={setup:function(){a(this).bind("textchange",a.event.special.hastext.handler)},teardown:function(){a(this).unbind("textchange",a.event.special.hastext.handler)},handler:function(c,b){b===""&&b!==a(this).val()&&a(this).trigger("hastext")}};a.event.special.notext={setup:function(){a(this).bind("textchange",
|
||||
a.event.special.notext.handler)},teardown:function(){a(this).unbind("textchange",a.event.special.notext.handler)},handler:function(c,b){a(this).val()===""&&a(this).val()!==b&&a(this).trigger("notext")}}})(jQuery);
|
||||
28
app/assets/javascripts/preorder.js.coffee
Normal file
@@ -0,0 +1,28 @@
|
||||
Selfstarter =
|
||||
firstTime: true
|
||||
validateEmail: ->
|
||||
# The regex we use for validating email
|
||||
# It probably should be a parser, but there isn't enough time for that (Maybe in the future though!)
|
||||
if /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/.test($("#email").val())
|
||||
$("#email").removeClass("highlight")
|
||||
$("#amazon_button").removeClass("disabled")
|
||||
else
|
||||
$("#email").addClass("highlight") unless Selfstarter.firstTime
|
||||
$("#amazon_button").addClass("disabled") unless $("#amazon_button").hasClass("disabled")
|
||||
init: ->
|
||||
$("#email").bind "textchange", ->
|
||||
Selfstarter.validateEmail()
|
||||
$("#email").bind "hastext", ->
|
||||
Selfstarter.validateEmail()
|
||||
# The first time they type in their email, we don't want it to throw a validation error
|
||||
$("#email").change ->
|
||||
Selfstarter.firstTime = false
|
||||
$ ->
|
||||
Selfstarter.init()
|
||||
$("#email").focus()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
14
app/assets/stylesheets/application.css
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
||||
* listed below.
|
||||
*
|
||||
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
||||
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
||||
*
|
||||
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
||||
* compiled file, but it's generally better to create a new file per style scope.
|
||||
*
|
||||
*= require_self
|
||||
*= require reset
|
||||
*= require main
|
||||
*/
|
||||
48
app/assets/stylesheets/checkout.css.scss
Normal file
@@ -0,0 +1,48 @@
|
||||
.main_content
|
||||
{
|
||||
width: 560px;
|
||||
float: left;
|
||||
h3
|
||||
{
|
||||
margin-bottom: 30px;
|
||||
color: #4b4b4b;
|
||||
line-height: 1;
|
||||
}
|
||||
p
|
||||
{
|
||||
line-height: 1.5;
|
||||
}
|
||||
#checkout
|
||||
{
|
||||
#email
|
||||
{
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #CCC;
|
||||
width: 350px;
|
||||
outline: none;
|
||||
}
|
||||
.invalid
|
||||
{
|
||||
border: 1px solid orange;
|
||||
}
|
||||
#amazon_button
|
||||
{
|
||||
margin-top: 5px;
|
||||
padding: 15px;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar
|
||||
{
|
||||
float: right;
|
||||
width: 300px;
|
||||
p
|
||||
{
|
||||
font-size: 18px;
|
||||
margin-bottom: 30px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
23
app/assets/stylesheets/footer.css.scss
Normal file
@@ -0,0 +1,23 @@
|
||||
.footer
|
||||
{
|
||||
padding: 40px 0;
|
||||
ul
|
||||
{
|
||||
float: left;
|
||||
}
|
||||
li
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
a
|
||||
{
|
||||
font-size: 18px;
|
||||
color: #525252;
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
}
|
||||
p
|
||||
{
|
||||
float: right;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
19
app/assets/stylesheets/header.css.scss
Normal file
@@ -0,0 +1,19 @@
|
||||
#lockitron_header
|
||||
{
|
||||
border: none;
|
||||
a
|
||||
{
|
||||
border: none !important;
|
||||
font-size: inherit !important;
|
||||
}
|
||||
}
|
||||
#header
|
||||
{
|
||||
width: 100%;
|
||||
padding: 26px 0;
|
||||
-moz-box-shadow: 0px 1px 3px 0px #acacac;
|
||||
-webkit-box-shadow: 0px 1px 3px 0px #acacac;
|
||||
box-shadow: 0px 1px 3px 0px #acacac;
|
||||
background: #fcfcfc;
|
||||
position: relative;
|
||||
}
|
||||
33
app/assets/stylesheets/homepage.css.scss
Normal file
@@ -0,0 +1,33 @@
|
||||
@import "homepage/stats";
|
||||
@import "homepage/call_to_action";
|
||||
@import "homepage/key_points";
|
||||
@import "homepage/other_points";
|
||||
@import "homepage/press";
|
||||
@import "homepage/faq";
|
||||
|
||||
#tweet_button
|
||||
{
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.fb-like
|
||||
{
|
||||
margin-left: 5px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
#video
|
||||
{
|
||||
float: left;
|
||||
width: 512px;
|
||||
height: 385px;
|
||||
background: #fff;
|
||||
-moz-box-shadow: 0 2px 6px rgba(0,0,0,.39); /* drop shadow */
|
||||
-webkit-box-shadow: 0 2px 6px rgba(0,0,0,.39); /* drop shadow */
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,.39); /* drop shadow */
|
||||
img:hover
|
||||
{
|
||||
opacity: 0.5;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
56
app/assets/stylesheets/homepage/call_to_action.css.scss
Normal file
@@ -0,0 +1,56 @@
|
||||
#reserve_container
|
||||
{
|
||||
float: left;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #fff;
|
||||
-moz-box-shadow: 0 -1px 0 #cbcbcb; /* drop shadow */
|
||||
-webkit-box-shadow: 0 -1px 0 #cbcbcb; /* drop shadow */
|
||||
box-shadow: 0 -1px 0 #cbcbcb; /* drop shadow */
|
||||
margin-top: 30px;
|
||||
text-align: center;
|
||||
p
|
||||
{
|
||||
color: #8b8a8a;
|
||||
font-size: 18px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
#ship_date
|
||||
{
|
||||
color: #4c4c4c;
|
||||
font-size: 22px;
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
line-height: 1.3;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 300px;
|
||||
}
|
||||
#price
|
||||
{
|
||||
color: #4c4c4c;
|
||||
font-size: 22px;
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
line-height: 1.3;
|
||||
display: block;
|
||||
margin: 0 auto 10px auto;
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
.reserve
|
||||
{
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
padding: 20px 0;
|
||||
width: 274px;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
#middle_reserve
|
||||
{
|
||||
padding: 60px;
|
||||
h2
|
||||
{
|
||||
margin-bottom: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
21
app/assets/stylesheets/homepage/faq.css.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
#faqs {
|
||||
padding-bottom: 30px;
|
||||
border-bottom: 1px solid #dfdfdf;
|
||||
ul {
|
||||
margin-top: 50px;
|
||||
float: left;
|
||||
width: 50%;
|
||||
li
|
||||
{
|
||||
width: 400px;
|
||||
margin: 0 49px 30px 0;
|
||||
padding-left: 18px;
|
||||
background: url(image_path("bullet.png")) no-repeat left 8px;
|
||||
p {
|
||||
margin-top: 10px;
|
||||
line-height: 1.4;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
app/assets/stylesheets/homepage/key_points.css.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
.big_wrapper {
|
||||
border-bottom: 1px solid #d2d2d2;
|
||||
background: #fff;
|
||||
}
|
||||
.big_wrapper .wrapper {
|
||||
padding: 35px 0;
|
||||
}
|
||||
|
||||
.point_copy {
|
||||
width: 440px;
|
||||
h3 {
|
||||
margin: 20px 0 30px 0;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 42px;
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
color: #292929;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.point_copy p, #other_points li p {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
#one {
|
||||
background: url(image_path("1-background.png")) no-repeat bottom left;
|
||||
height: 320px;
|
||||
width: 936px;
|
||||
}
|
||||
|
||||
#two {
|
||||
background: url(image_path("2-background.png")) no-repeat bottom left;
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
#three {
|
||||
background: url(image_path("3-background.png")) no-repeat bottom left;
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
#four {
|
||||
background: url(image_path("4-background.png")) no-repeat bottom left;
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: 500px;
|
||||
}
|
||||
28
app/assets/stylesheets/homepage/other_points.css.scss
Normal file
@@ -0,0 +1,28 @@
|
||||
#other_points
|
||||
{
|
||||
li
|
||||
{
|
||||
width: 400px;
|
||||
float: left;
|
||||
margin: 0 120px 50px 0;
|
||||
padding-top: 60px;
|
||||
}
|
||||
#section-1 {
|
||||
background: url(asset-path("", "images")) no-repeat center top;
|
||||
}
|
||||
#section-2 {
|
||||
background: url(asset-path("", "images")) no-repeat center top;
|
||||
margin-right: 0px;
|
||||
}
|
||||
#section-3 {
|
||||
background: url(asset-path("", "images")) no-repeat center top;
|
||||
}
|
||||
#section-4 {
|
||||
background: url(asset-path("", "images")) no-repeat center top;
|
||||
margin-right: 0px;
|
||||
}
|
||||
h4 {
|
||||
width: 400px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
47
app/assets/stylesheets/homepage/press.css.scss
Normal file
@@ -0,0 +1,47 @@
|
||||
#logos {
|
||||
padding: 40px 0;
|
||||
background: #f3f3f3;
|
||||
-moz-box-shadow: 0px 1px 3px 0px #acacac;
|
||||
-webkit-box-shadow: 0px 1px 3px 0px #acacac;
|
||||
box-shadow: 0px 1px 3px 0px #acacac;
|
||||
li
|
||||
{
|
||||
float: left;
|
||||
margin: 0 16px;
|
||||
a {
|
||||
display: block;
|
||||
height: 48px;
|
||||
opacity: 0.2;
|
||||
text-indent: -10000px;
|
||||
}
|
||||
a:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
#awesomeblog a
|
||||
{
|
||||
background: url(image-path("")) no-repeat left center;
|
||||
width: 176px;
|
||||
}
|
||||
#coolpaper a
|
||||
{
|
||||
background: url(image-path("")) no-repeat left center;
|
||||
width: 109px;
|
||||
}
|
||||
#nicemag a
|
||||
{
|
||||
background: url(image-path("")) no-repeat left center;
|
||||
width: 149px;
|
||||
}
|
||||
#readcrunch a
|
||||
{
|
||||
background: url(image-path("")) no-repeat left center;
|
||||
width: 81px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
96
app/assets/stylesheets/homepage/stats.css.scss
Normal file
@@ -0,0 +1,96 @@
|
||||
#backing
|
||||
{
|
||||
float: left;
|
||||
width: 383px;
|
||||
margin: 20px 0 0 40px;
|
||||
#backers
|
||||
{
|
||||
border-left: none;
|
||||
padding-left: 0;
|
||||
ul
|
||||
{
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
#days {
|
||||
border-right: none;
|
||||
padding-right: 0;
|
||||
}
|
||||
ul {
|
||||
text-align: center;
|
||||
}
|
||||
.stats
|
||||
{
|
||||
margin: 0 auto;
|
||||
color: #3f3f3f;
|
||||
font-size: 24px;
|
||||
display: block;
|
||||
display: inline-block;
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
border-right: 1px solid #cbcbcb;
|
||||
padding-right: 26px;
|
||||
padding-left: 26px;
|
||||
text-align: left;
|
||||
span
|
||||
{
|
||||
color: #868686;
|
||||
font-size: 18px;
|
||||
margin-top: 5px;
|
||||
display: block;
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
}
|
||||
}
|
||||
}
|
||||
#progress_bg
|
||||
{
|
||||
margin-top: 20px;
|
||||
float: left;
|
||||
height: 40px;
|
||||
-moz-box-shadow: 0 1px 1px rgba(0,0,0,.41); /* drop shadow */
|
||||
-webkit-box-shadow: 0 1px 1px rgba(0,0,0,.41); /* drop shadow */
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.41); /* drop shadow */
|
||||
-webkit-border-radius: 30px;
|
||||
-moz-border-radius: 30px;
|
||||
border-radius: 30px;
|
||||
width: 383px;
|
||||
background: #dbdbdb;
|
||||
#progress
|
||||
{
|
||||
height: 40px;
|
||||
-moz-box-shadow: 0 1px 1px rgba(0,0,0,.59); /* drop shadow */
|
||||
-webkit-box-shadow: 0 1px 1px rgba(0,0,0,.59); /* drop shadow */
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.59); /* drop shadow */
|
||||
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PGxpbmVhckdyYWRpZW50IGlkPSJoYXQwIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjEwMCUiIHgyPSI1MCUiIHkyPSIwJSI+CjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiMxMzkyZGMiIHN0b3Atb3BhY2l0eT0iMSIvPgo8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwNjlkZjQiIHN0b3Atb3BhY2l0eT0iMSIvPgogICA8L2xpbmVhckdyYWRpZW50PgoKPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNoYXQwKSIgLz4KPC9zdmc+); /* gradient fill */
|
||||
background-image: -moz-linear-gradient(90deg, #1392dc 0%, #069df4 100%); /* gradient fill */
|
||||
background-image: -o-linear-gradient(90deg, #1392dc 0%, #069df4 100%); /* gradient fill */
|
||||
background-image: -webkit-linear-gradient(90deg, #1392dc 0%, #069df4 100%); /* gradient fill */
|
||||
background-image: linear-gradient(90deg, #1392dc 0%, #069df4 100%); /* gradient fill */
|
||||
-webkit-border-radius: 30px;
|
||||
-moz-border-radius: 30px;
|
||||
border-radius: 30px;
|
||||
min-width: 2%;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
#progress_text
|
||||
{
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
font-size: 14pt;
|
||||
display: inline-block;
|
||||
color: white;
|
||||
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.37);
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: -35px;
|
||||
}
|
||||
}
|
||||
.small
|
||||
{
|
||||
height: 20px !important;
|
||||
#progress
|
||||
{
|
||||
height: 20px !important;
|
||||
}
|
||||
}
|
||||
8
app/assets/stylesheets/main.css.scss
Normal file
@@ -0,0 +1,8 @@
|
||||
@import "variables";
|
||||
@import "primitives";
|
||||
@import "header";
|
||||
@import "footer";
|
||||
|
||||
@import "homepage";
|
||||
@import "share";
|
||||
@import "checkout";
|
||||
0
app/assets/stylesheets/preorder.css.scss
Normal file
232
app/assets/stylesheets/primitives.css.scss
Normal file
@@ -0,0 +1,232 @@
|
||||
|
||||
/* For modern browsers */
|
||||
.clearfix:before,
|
||||
.clearfix:after
|
||||
{
|
||||
content:"";
|
||||
display:table;
|
||||
}
|
||||
.clearfix:after
|
||||
{
|
||||
clear:both;
|
||||
}
|
||||
/* For IE 6/7 (trigger hasLayout) */
|
||||
.clearfix {
|
||||
zoom:1;
|
||||
}
|
||||
|
||||
code
|
||||
{
|
||||
border: 1px solid #CCC;
|
||||
padding: 1px;
|
||||
vertical-align: middle;
|
||||
font-family: "Consolas", "Inconsolata", "Meslo", "Inconsolata-dz", monospace;
|
||||
text-shadow: none;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: $body_background;
|
||||
}
|
||||
|
||||
.disabled
|
||||
{
|
||||
opacity: 0.65;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
form
|
||||
{
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
body, input, textarea
|
||||
{
|
||||
font-size: $font_size;
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
color: $text_color;
|
||||
text-shadow: $text_shadow;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
text-decoration: none;
|
||||
color: $link_color;
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
i
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Used in the FAQ
|
||||
details, summary
|
||||
{
|
||||
outline: none;
|
||||
}
|
||||
summary
|
||||
{
|
||||
text-decoration: none;
|
||||
color: $summary_color;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
font-size: 20px;
|
||||
line-height: 1.3;
|
||||
|
||||
}
|
||||
summary:hover
|
||||
{
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
details summary::-webkit-details-marker { display:none; content: ""; }
|
||||
// Styling the polyfill for browsers that don't support details/summary tags
|
||||
.no-details details { display: block }
|
||||
.no-details details > summary::before { content:none }
|
||||
.no-details details.open > summary::before { content:none }
|
||||
|
||||
|
||||
|
||||
h1 {
|
||||
margin: 0 auto;
|
||||
margin-left: 380px;
|
||||
width: 174px;
|
||||
font-family: Helvetica;
|
||||
font-size: 42px;
|
||||
font-weight: bold;
|
||||
color: $h1_color;
|
||||
letter-spacing: -.05em;
|
||||
float: left;
|
||||
a
|
||||
{
|
||||
color: $h1_color;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover
|
||||
{
|
||||
color: $h1_color;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
font-size: 45px;
|
||||
color: $h2_color;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 36px;
|
||||
color: $h4_color;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
margin-bottom: 10px;
|
||||
color: $h5_color;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 935px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.gray_background
|
||||
{
|
||||
width: 100%;
|
||||
padding: 50px 0;
|
||||
background: $gray_background_top_color; /* Old browsers */
|
||||
background: -moz-linear-gradient(top, $gray_background_top_color 0%, $gray_background_middle_color 50%, $gray_background_bottom_color 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,$gray_background_top_color), color-stop(50%,$gray_background_middle_color), color-stop(100%,$gray_background_bottom_color)); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, $gray_background_top_color 0%,$gray_background_middle_color 50%,$gray_background_bottom_color 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, $gray_background_top_color 0%,$gray_background_middle_color 50%,$gray_background_bottom_color 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, $gray_background_top_color 0%,$gray_background_middle_color 50%,$gray_background_bottom_color 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, $gray_background_top_color 0%,$gray_background_middle_color 50%,$gray_background_bottom_color 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$gray_background_top_color', endColorstr='$gray_background_bottom_color',GradientType=0 ); /* IE6-9 */
|
||||
border-bottom: 1px solid $gray_background_border_color;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
text-decoration: none;
|
||||
color: $button_hovered_color;
|
||||
}
|
||||
|
||||
.button:active {
|
||||
background: $button_active_background;
|
||||
border: 1px solid $button_active_border;
|
||||
}
|
||||
|
||||
.blue_button {
|
||||
display: block;
|
||||
color: $button_color; /* text color */
|
||||
text-shadow: 0 -1px 1px $button-text_shadow_color; /* drop shadow */
|
||||
-moz-box-shadow:
|
||||
0 1px 1px $button_box_shadow_color /* drop shadow */,
|
||||
inset 0 -1px $button_box_shadow_inset_color /* inner shadow */;
|
||||
-webkit-box-shadow:
|
||||
0 1px 1px $button_box_shadow_color /* drop shadow */,
|
||||
inset 0 -1px 1px $button_box_shadow_inset_color /* inner shadow */;
|
||||
background-image: $button_top_gradient; /* gradient fill */
|
||||
background-image: -moz-linear-gradient(90deg, $button_top_gradient 0%, $button_bottom_gradient 100%); /* gradient fill */
|
||||
background-image: -o-linear-gradient(90deg, $button_top_gradient 0%, $button_bottom_gradient 100%); /* gradient fill */
|
||||
background-image: -webkit-linear-gradient(90deg, $button_top_gradient 0%, $button_bottom_gradient 100%); /* gradient fill */
|
||||
background-image: linear-gradient(90deg, $button_top_gradient 0%, $button_bottom_gradient 100%); /* gradient fill */
|
||||
-webkit-border-radius: $button_border_radius;
|
||||
-moz-border-radius: $button_border_radius;
|
||||
border-radius: $button_border_radius;
|
||||
font-family: $primary_font, $secondary_font, $tertiary_font;
|
||||
}
|
||||
.blue_button:hover {
|
||||
-moz-box-shadow:
|
||||
0 1px 1px $button_box_shadow_color /* drop shadow */,
|
||||
inset 0 -1px 1px $button_box_shadow_inset_color /* inner shadow */;
|
||||
-webkit-box-shadow:
|
||||
0 1px 1px$button_box_shadow_color /* drop shadow */,
|
||||
inset 0 -1px 1px $button_box_shadow_inset_color /* inner shadow */;
|
||||
box-shadow:
|
||||
0 1px 1px $button_box_shadow_color /* drop shadow */,
|
||||
inset 0 -1px 1px $button_box_shadow_inset_color /* inner shadow */;
|
||||
background-image: $button_ie9_gradient_hover; /* gradient fill */
|
||||
background-image: -moz-linear-gradient(90deg, $button_top_gradient_hover 0%, $button_bottom_gradient_hover 100%); /* gradient fill */
|
||||
background-image: -o-linear-gradient(90deg, $button_top_gradient_hover 0%, $button_bottom_gradient_hover 100%); /* gradient fill */
|
||||
background-image: -webkit-linear-gradient(90deg, $button_top_gradient_hover 0%, $button_bottom_gradient_hover 100%); /* gradient fill */
|
||||
background-image: linear-gradient(90deg, $button_top_gradient_hover 0%, $button_bottom_gradient_hover 100%); /* gradient fill */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.blue_button:active {
|
||||
-moz-box-shadow:
|
||||
0 1px 1px $button_box_shadow_color /* drop shadow */,
|
||||
inset 0 3px 5px $button_box_shadow_inset_color /* inner shadow */;
|
||||
-webkit-box-shadow:
|
||||
0 1px 1px $button_box_shadow_color /* drop shadow */,
|
||||
inset 0 3px 5px $button_box_shadow_inset_color /* inner shadow */;
|
||||
box-shadow:
|
||||
0 1px 1px $button_box_shadow_color /* drop shadow */,
|
||||
inset 0 3px 5px $button_box_shadow_inset_color /* inner shadow */;
|
||||
background-image: $button_ie9_gradient_active /* gradient fill */;
|
||||
background-image: -moz-linear-gradient(90deg, $button_top_gradient_active 0%, $button_bottom_gradient_active 100%); /* gradient fill */
|
||||
background-image: -o-linear-gradient(90deg, $button_top_gradient_active 0%, $button_bottom_gradient_active 100%); /* gradient fill */
|
||||
background-image: -webkit-linear-gradient(90deg, $button_top_gradient_active 0%, $button_bottom_gradient_active 100%); /* gradient fill */
|
||||
background-image: linear-gradient(90deg, $button_top_gradient_active 0%, $button_bottom_gradient_active 100%); /* gradient fill */
|
||||
}
|
||||
48
app/assets/stylesheets/reset.css
Normal file
@@ -0,0 +1,48 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
50
app/assets/stylesheets/share.css.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
#share_container
|
||||
{
|
||||
#congrats
|
||||
{
|
||||
padding: 70px 0;
|
||||
h2
|
||||
{
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
p
|
||||
{
|
||||
margin-bottom: 30px;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
#share
|
||||
{
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
#facebook_button_container
|
||||
{
|
||||
margin: 0 auto;
|
||||
display: inline-block;
|
||||
}
|
||||
#pin_button_container
|
||||
{
|
||||
margin: 0 auto;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
.pin-it-button
|
||||
{
|
||||
}
|
||||
}
|
||||
#tweet_button_container
|
||||
{
|
||||
margin: 0 auto;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
#order_id
|
||||
{
|
||||
margin: 0 auto;
|
||||
margin-top: 15px;
|
||||
padding: 0px;
|
||||
opacity: 0.3;
|
||||
z-index: 9999;
|
||||
}
|
||||
}
|
||||
63
app/assets/stylesheets/variables.css.scss
Normal file
@@ -0,0 +1,63 @@
|
||||
// Hi!
|
||||
// Please change around the settings as you need. These are all the defaults
|
||||
// These only affect the primitives -- inputs, divs, h1-h5, etc (not classes/IDs, with one exception)
|
||||
|
||||
// If you have any questions, create a GitHub issue, or email me us -- hello@lockitron.com
|
||||
|
||||
$body_background: #E6E6E6;
|
||||
|
||||
// Right now, we don't really use h1 and h2's correctly.
|
||||
// We'll fix it soon!
|
||||
|
||||
$h1_color: #323232;
|
||||
$h2_color: #4B4B4B;
|
||||
$h4_color: #292929;
|
||||
$h5_color: #4B4B4B;
|
||||
|
||||
$text_color: #6B6B6B;
|
||||
$link_color: #0008D6;
|
||||
$text_shadow: 0 1px 0px #fff;
|
||||
$font_size: 22px;
|
||||
|
||||
// Lockitron uses ProximaNova Regular, but that costs money, so we're defaulting to Helveitca Neue instead.
|
||||
$primary_font: "Helvetica Neue";
|
||||
$secondary_font: "Helvetica";
|
||||
$tertiary_font: "Arial";
|
||||
|
||||
// Gray background is a gradient -- top == 0%, middle == 50%, bottom == 100%
|
||||
$gray_background_top_color: #F6F6F6;
|
||||
$gray_background_middle_color: #FAFAFA;
|
||||
$gray_background_bottom_color: #FAFAFA;
|
||||
|
||||
// The bottom border on the gray backgrounds
|
||||
$gray_background_border_color: #C4C4C4;
|
||||
|
||||
// Button colors/background/border
|
||||
$button_color: white;
|
||||
$button_hovered_color: #0088d6;
|
||||
$button_active_background: #FAFAFA;
|
||||
$button_active_border: #C8C8C8;
|
||||
|
||||
// This only affects .blue_button, which is the "Reserve Now" button you see on Lockitron's homepage
|
||||
$button_text_shadow_color: rgba(0,0,0,.37);
|
||||
$button_box_shadow_color: rgba(255,255,255,.92);
|
||||
$button_box_shadow_inset_color: rgba(0,0,0,.22);
|
||||
$button_border_radius: 10px;
|
||||
|
||||
// Default State
|
||||
$button_ie9_gradient: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PGxpbmVhckdyYWRpZW50IGlkPSJoYXQwIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjEwMCUiIHgyPSI1MCUiIHkyPSIwJSI+CjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiMwZTk2ZTQiIHN0b3Atb3BhY2l0eT0iMSIvPgo8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMmEwZmEiIHN0b3Atb3BhY2l0eT0iMSIvPgogICA8L2xpbmVhckdyYWRpZW50PgoKPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNoYXQwKSIgLz4KPC9zdmc+);
|
||||
$button_top_gradient: #0E96E4;
|
||||
$button_bottom_gradient: #02A0FA;
|
||||
|
||||
// Hover State
|
||||
$button_ie9_gradient_hover: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PGxpbmVhckdyYWRpZW50IGlkPSJoYXQwIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjEwMCUiIHgyPSI1MCUiIHkyPSIwJSI+CjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiMyZGE0ZTkiIHN0b3Atb3BhY2l0eT0iMSIvPgo8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMyMWFlZmYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICA8L2xpbmVhckdyYWRpZW50PgoKPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNoYXQwKSIgLz4KPC9zdmc+);
|
||||
$button_top_gradient_hover: #2DA4E9;
|
||||
$button_bottom_gradient_hover: #21AEFF;
|
||||
|
||||
// Active State
|
||||
$button_ie9_gradient_active: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PGxpbmVhckdyYWRpZW50IGlkPSJoYXQwIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjEwMCUiIHgyPSI1MCUiIHkyPSIwJSI+CjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiMwMzlmZjciIHN0b3Atb3BhY2l0eT0iMSIvPgo8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMzlmZjciIHN0b3Atb3BhY2l0eT0iMSIvPgogICA8L2xpbmVhckdyYWRpZW50PgoKPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNoYXQwKSIgLz4KPC9zdmc+);
|
||||
$button_top_gradient_active: #039FF7;
|
||||
$button_bottom_gradient_active: #039ff7;
|
||||
|
||||
// FAQ Entry
|
||||
$summary_color: #0088D6;
|
||||
3
app/controllers/application_controller.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
class ApplicationController < ActionController::Base
|
||||
protect_from_forgery
|
||||
end
|
||||
42
app/controllers/preorder_controller.rb
Normal file
@@ -0,0 +1,42 @@
|
||||
class PreorderController < ApplicationController
|
||||
skip_before_filter :verify_authenticity_token, :only => :ipn
|
||||
|
||||
def index
|
||||
|
||||
end
|
||||
|
||||
def checkout
|
||||
|
||||
end
|
||||
|
||||
def prefill
|
||||
@user = User.find_or_create_by_email!(params[:email])
|
||||
@order = Order.prefill!(:name => Settings.product_name, :price => Settings.price, :user_id => @user.id)
|
||||
|
||||
# This is where all the magic happens. We create a multi-use token with Amazon, letting us charge the user's Amazon account
|
||||
# Then, if they confirm the payment, Amazon POSTs us their shipping details and phone number
|
||||
# From there, we save it, and voila, we got ourselves a preorder!
|
||||
@pipeline = AmazonFlexPay.multi_use_pipeline(@order.uuid, :transaction_amount => Settings.price, :global_amount_limit => Settings.charge_limit, :collect_shipping_address => "True", :payment_reason => Settings.payment_description)
|
||||
redirect_to @pipeline.url("#{request.scheme}://#{request.host}/preorder/postfill")
|
||||
end
|
||||
|
||||
def postfill
|
||||
unless params[:callerReference].blank?
|
||||
@order = Order.postfill!(params)
|
||||
end
|
||||
# "A" means the user cancelled the preorder before clicking "Confirm" on Amazon Payments.
|
||||
if params['status'] != 'A' && @order.present?
|
||||
redirect_to :action => :share, :uuid => @order.uuid
|
||||
else
|
||||
redirect_to root_url
|
||||
end
|
||||
end
|
||||
|
||||
def share
|
||||
@order = Order.find_by_uuid(params[:uuid])
|
||||
end
|
||||
|
||||
def ipn
|
||||
end
|
||||
|
||||
end
|
||||
2
app/helpers/application_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module ApplicationHelper
|
||||
end
|
||||
17
app/helpers/preorder_helper.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
module PreorderHelper
|
||||
def like_button(width = 70, show_faces = false)
|
||||
raw "<div class=\"fb-like\" data-send=\"false\" data-width=\"#{width}\" data-layout=\"box_count\" data-show-faces=\"true\"></div>"
|
||||
end
|
||||
def pin_it_button
|
||||
image_url = URI.encode("#{request.scheme}://#{request.host}#{image_path(Settings.product_image_url)}")
|
||||
raw "<a href='http://pinterest.com/pin/create/button/?url=#{encoded_root_url}&media=#{image_url}' class='pin-it-button' count-layout='vertical'><img border='0' src='//assets.pinterest.com/images/PinExt.png' title='Pin It' /></a>"
|
||||
end
|
||||
def tweet_button
|
||||
tweet_text = "I'm #{Settings.primary_stat_verb} number #{number_with_delimiter @order.number, :delimiter => ","} #{Settings.tweet_text}!"
|
||||
raw "<a href='https://twitter.com/share?url=/' id='tweet_button' class='twitter-share-button twitter-button' data-url=#{request.scheme}//#{request.host}' data-via='#{Settings.product_name}' data-lang='en' data-count='vertical' data-text=\"#{tweet_text}\">Tweet</a>"
|
||||
end
|
||||
|
||||
def encoded_root_url
|
||||
raw URI.encode "#{request.scheme}://#{request.host}/preorder"
|
||||
end
|
||||
end
|
||||
0
app/mailers/.gitkeep
Normal file
0
app/models/.gitkeep
Normal file
68
app/models/order.rb
Normal file
@@ -0,0 +1,68 @@
|
||||
class Order < ActiveRecord::Base
|
||||
attr_accessible :address_one, :address_two, :city, :country, :number, :state, :status, :token, :transaction_id, :zip, :shipping, :tracking_number, :name, :price, :phone, :expiration
|
||||
attr_readonly :uuid
|
||||
before_validation :generate_uuid!, :on => :create
|
||||
belongs_to :user
|
||||
self.primary_key = 'uuid'
|
||||
|
||||
|
||||
# This is where we create our Caller Reference for Amazon Payments, and prefill some other information.
|
||||
def self.prefill!(options = {})
|
||||
@order = Order.new
|
||||
@order.name = options[:name]
|
||||
@order.user_id = options[:user_id]
|
||||
@order.price = options[:price]
|
||||
@order.number = Order.next_order_number || 1
|
||||
@order.save!
|
||||
|
||||
return @order
|
||||
end
|
||||
|
||||
# After authenticating with Amazon, we get the rest of the details
|
||||
def self.postfill!(options = {})
|
||||
@order = Order.find_by_uuid!(options[:callerReference])
|
||||
@order.token = options[:tokenID]
|
||||
if !@order.token.blank?
|
||||
@order.address_one = options[:addressLine1]
|
||||
@order.address_two = options[:addressLine2]
|
||||
@order.city = options[:city]
|
||||
@order.state = options[:state]
|
||||
@order.status = options[:status]
|
||||
@order.zip = options[:zip]
|
||||
@order.phone = options[:phoneNumber]
|
||||
@order.country = options[:country]
|
||||
@order.expiration = Date.parse(options[:expiry])
|
||||
@order.save!
|
||||
|
||||
@order
|
||||
end
|
||||
end
|
||||
|
||||
def self.next_order_number
|
||||
Order.order("number DESC").limit(1).first.number.to_i + 1 if Order.count > 0
|
||||
end
|
||||
|
||||
def generate_uuid!
|
||||
self.uuid = SecureRandom.hex(16)
|
||||
end
|
||||
|
||||
# Implement these three methods to
|
||||
def self.goal
|
||||
Settings.project_goal
|
||||
end
|
||||
|
||||
def self.percent
|
||||
(Order.current.to_f / Order.goal.to_f) * 100.to_f
|
||||
end
|
||||
|
||||
# See what it looks like when you have some backers! Drop in a number instead of Order.count
|
||||
def self.current
|
||||
Order.count
|
||||
end
|
||||
|
||||
def self.revenue
|
||||
Order.current.to_f * Settings.price
|
||||
end
|
||||
|
||||
validates_presence_of :name, :price, :user_id
|
||||
end
|
||||
4
app/models/user.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
class User < ActiveRecord::Base
|
||||
attr_accessible :email
|
||||
has_many :orders
|
||||
end
|
||||
22
app/views/layouts/_footer.html.erb
Normal file
@@ -0,0 +1,22 @@
|
||||
<div class="footer">
|
||||
<div class="wrapper clearfix">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#" %>/faq">Help & FAQs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Press & Media</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://blog.lockitron.com/">Blog</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Privacy Policy</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/account/login">Login</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p>© 2009-2012 Apigy Inc. All rights reserved. Patents pending.</p>
|
||||
</div>
|
||||
</div>
|
||||
14
app/views/layouts/application.html.erb
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<title><%= Settings.product_name %></title>
|
||||
<%= stylesheet_link_tag "application" %>
|
||||
<%= javascript_include_tag "application" %>
|
||||
</head>
|
||||
<body>
|
||||
<%= render 'header' %>
|
||||
<%= yield %>
|
||||
<%= render 'footer' %>
|
||||
</body>
|
||||
</html>
|
||||
1
app/views/preorder/_copyright.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<p>© You. Made by the guys at <a href="https://lockitron.com">Lockitron</a>. MIT License.</p>
|
||||
6
app/views/preorder/_footer.html.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class="footer">
|
||||
<div class="wrapper clearfix">
|
||||
<%= render 'copyright' %>
|
||||
</div>
|
||||
</div>
|
||||
<%= render 'google_analytics' %>
|
||||
13
app/views/preorder/_google_analytics.html.erb
Normal file
@@ -0,0 +1,13 @@
|
||||
<script type="text/javascript">
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', '<%= Settings.google_id %>']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
|
||||
</script>
|
||||
5
app/views/preorder/_header.html.erb
Normal file
@@ -0,0 +1,5 @@
|
||||
<div id="header">
|
||||
<div class="wrapper clearfix">
|
||||
<h1 id="lockitron_header"><a href="/"><%= Settings.product_name %></a></h1>
|
||||
</div>
|
||||
</div>
|
||||
20
app/views/preorder/checkout.html.erb
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="gray_background">
|
||||
<div class="wrapper clearfix">
|
||||
<div class="main_content">
|
||||
<h3>Check out</h3>
|
||||
<p>
|
||||
Let your backers know how their payment information will be handled.
|
||||
<br />
|
||||
<br />
|
||||
Enter your email address below.
|
||||
</p>
|
||||
<%= form_tag "/preorder/prefill", :id => "checkout" do %>
|
||||
<%= email_field_tag "email", nil, :placeholder => "hello@lockitron.com", :required => "required", :id => "email" %>
|
||||
<%= hidden_field_tag "preorder", true %>
|
||||
<%= hidden_field_tag "quantity", params[:quantity] %>
|
||||
<%= submit_tag "Checkout", :class => "blue_button disabled", :id => "amazon_button" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render 'preorder/checkout/sidebar' %>
|
||||
</div>
|
||||
</div>
|
||||
6
app/views/preorder/checkout/_sidebar.html.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class="sidebar">
|
||||
<h5>When will I be charged?</h5>
|
||||
<p>
|
||||
We recommend that you only charge backers when you can ship, otherwise your payment provider won't be happy.
|
||||
</p>
|
||||
</div>
|
||||
71
app/views/preorder/homepage/_faqs.html.erb
Normal file
@@ -0,0 +1,71 @@
|
||||
<div class="gray_background" id="faqs">
|
||||
<div class="wrapper clearfix">
|
||||
<h4>Frequently Asked Questions</h4>
|
||||
<ul>
|
||||
<li class=''>
|
||||
<details class=''>
|
||||
<summary class=''>How do I setup Amazon Payments?</summary>
|
||||
<p>You'll need to <a href="https://payments.amazon.com/sdui/sdui/accountstatus">create an Amazon Seller Central account</a>. Afterwards, get your access key and secret key from the "Integration" tab on your AWS account. <a href="https://payments.amazon.com/sdui/sdui/helpTab/Checkout-by-Amazon/Advanced-Integration-Help/Using-Your-Access-Key">Click here for more info</a>.
|
||||
<br />
|
||||
<br />
|
||||
Once you have your access key and secret key, head over to <code>config/settings.yml</code>. Change <code>amazon_access_key</code> and <code>amazon_secret_key</code> appropriately.</p>
|
||||
</details>
|
||||
</li>
|
||||
<li>
|
||||
<details class=''>
|
||||
<summary>Can I use another payments provider?</summary>
|
||||
<p>Of course. We haven't built in support for other providers, but we recommend that you take a look at <a href="https://stripe.com">Stripe</a> or <a href="https://wepay.com">WePay</a>.</p>
|
||||
</details>
|
||||
</li>
|
||||
<li>
|
||||
<details class=''>
|
||||
<summary>How do I edit the FAQ?</summary>
|
||||
<p>The faq is a partial located in <code>app/views/preorder/homepage/_faq.html.erb</code> The <code>summary</code> tag is the title, the <code>p</code> is the body. Make sure to add an <code>li</code> tag for each FAQ entry.</p>
|
||||
</details>
|
||||
</li>
|
||||
<li>
|
||||
<details class=''>
|
||||
<summary>How do I change around the images, product name, etc?</summary>
|
||||
<p>The best way is in <code>config/settings.yml</code>. It has variables for several different parts, the YouTube video, the product name, the call to action button ("Fork Now"), and several more.
|
||||
</p>
|
||||
</details>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class='col2'>
|
||||
<li>
|
||||
<details class=''>
|
||||
<summary>How do I change the CSS?</summary>
|
||||
<p>Head over to <code>app/assets/stylesheets/variables.css.scss</code>. It makes it easy to change around the elements used throughout the HTML.
|
||||
<br />
|
||||
<br />
|
||||
Alternatively, you can dive right into the CSS, have a look at <code>app/assets/stylesheets/main.css.scss</code>.</p>
|
||||
</details>
|
||||
</li>
|
||||
<li class=''>
|
||||
<details class=''>
|
||||
<summary>Why did you release this?</summary>
|
||||
<p>Hardware startups are less welcome on Kickstarter than they were 6 months ago. We needed to roll our own kickstarter, so we did. Other hardware startups probably will too, so we made it easier for them by open sourcing our way of doing it.</p>
|
||||
</details>
|
||||
</li>
|
||||
<li class=''>
|
||||
<details class=''>
|
||||
<summary class=''>What software stack does this use?</summary>
|
||||
<p>It's a Ruby on Rails app that makes heavy use of SCSS, Kickstarter's wonderful <code>amazon_flex_pay</code> gem, and a hint of CoffeeScript.</p>
|
||||
</details>
|
||||
</li>
|
||||
<li class=''>
|
||||
<details class=''>
|
||||
<summary class=''>How do I deploy it?</summary>
|
||||
<p>We recommend using Heroku. We include a Procfile for you, so all you need to do is:
|
||||
<p>
|
||||
<p>Install the <a href="https://toolbelt.heroku.com/">Heroku Toolbelt</a></p>
|
||||
<p>Run <code>heroku create</code> in Selfstarter's folder</code></p>
|
||||
<p>Run <code>git push heroku master</code> in Selfstarter's folder</p>
|
||||
</p>
|
||||
</p>
|
||||
</details>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
51
app/views/preorder/homepage/_key_points.html.erb
Normal file
@@ -0,0 +1,51 @@
|
||||
<div class="big_wrapper">
|
||||
<div class="wrapper" id="one">
|
||||
<div class="point_copy">
|
||||
<h3>
|
||||
What is Selfstarter?
|
||||
</h3>
|
||||
<p>
|
||||
Selfstarter is an open source starting point for building your own ad-hoc crowdfunding site. It was put together by <a href="https://lockitron.com">Lockitron</a> after they were <a href="http://techcrunch.com/2012/10/07/the-story-of-lockitron-crowdfunding-without-kickstarter/">turned down from Kickstarter</a>.
|
||||
<p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="big_wrapper">
|
||||
<div class="wrapper" id="two">
|
||||
<div class="point_copy right">
|
||||
<h3>
|
||||
How do I use it?
|
||||
</h3>
|
||||
<p>
|
||||
Selftstarter is a starting point for you to build your own solution. It is set up to collect reservations using Amazon Payments, but you can choose you own provider too.
|
||||
<p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="big_wrapper">
|
||||
<div class="wrapper" id="three">
|
||||
<div class="point_copy">
|
||||
<h3>
|
||||
It's just a skeleton
|
||||
</h3>
|
||||
<p>
|
||||
We've kept Selfstarter really simple, but that also means that you should beef it up with your own authentication, administration and product management code.
|
||||
<p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="big_wrapper">
|
||||
<div class="wrapper" id="four">
|
||||
<div class="point_copy right">
|
||||
<h3>
|
||||
Let's get started
|
||||
</h3>
|
||||
<p>
|
||||
Most of what you need to get started is in the Readme. Selfstarter is based on Ruby on Rails, and we've tried to break up all of the different parts in a sensible fashion.
|
||||
<p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
6
app/views/preorder/homepage/_middle_reserve.html.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class="big_wrapper">
|
||||
<div class="wrapper center" id="middle_reserve">
|
||||
<h2><%= Settings.ships %></h2>
|
||||
<a href="/preorder/checkout" class="blue_button reserve"><%= Settings.middle_reserve_text %></a>
|
||||
</div>
|
||||
</div>
|
||||
20
app/views/preorder/homepage/_other_points.html.erb
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="gray_background">
|
||||
<ul class="wrapper clearfix" id="other_points">
|
||||
<li id="section-1">
|
||||
<h4>Section 1</h4>
|
||||
<p>Morbi tempus dapibus egestas. Nullam accumsan dolor ut purus ornare congue. Phasellus ac commodo neque. Quisque non ligula lacus, id hendrerit eros.</p>
|
||||
</li>
|
||||
<li id="section-2">
|
||||
<h4>Section 2</h4>
|
||||
<p>Vivamus nec posuere mauris. Suspendisse mi sem, egestas ac tristique ac, varius ac lectus. Sed porttitor dolor adipiscing mauris sagittis.</p>
|
||||
</li>
|
||||
<li id="section-3">
|
||||
<h4>Section 3</h4>
|
||||
<p>Curabitur dolor elit, placerat et malesuada et, tristique vel nulla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
</li>
|
||||
<li id="section-4">
|
||||
<h4>Section 4</h4>
|
||||
<p>Curabitur ac mi elit, nec tempor odio. Nam sollicitudin, sapien sit amet elementum pretium, turpis mi fermentum nisl, ac vehicula purus lacus non velit.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
8
app/views/preorder/homepage/_press.html.erb
Normal file
@@ -0,0 +1,8 @@
|
||||
<div id='logos'>
|
||||
<ul class="wrapper clearfix">
|
||||
<li id="awesomeblog"><a href=""></a></li>
|
||||
<li id="coolpaper"><a href=""></a></li>
|
||||
<li id="nicemag"><a href=""></a></li>
|
||||
<li id="readcrunch"><a href=""></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
4
app/views/preorder/homepage/_show_dont_tell.html.erb
Normal file
@@ -0,0 +1,4 @@
|
||||
<div class="gray_background">
|
||||
<%= render 'preorder/homepage/value_proposition' %>
|
||||
<%= render 'preorder/homepage/stats' %>
|
||||
</div>
|
||||
53
app/views/preorder/homepage/_stats.html.erb
Normal file
@@ -0,0 +1,53 @@
|
||||
<div class="wrapper clearfix">
|
||||
<div id="video">
|
||||
<iframe width='512' height='385' src="<%= Settings.youtube_embed_url %>?autohide=1&showinfo=0&rel=0&autoplay=0"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="backing">
|
||||
<ul>
|
||||
<li class="stats" id="backers">
|
||||
<%= number_with_delimiter Order.current, :delimiter => "," %>
|
||||
<span><%= Settings.primary_stat %></span>
|
||||
</li>
|
||||
<li class="stats">
|
||||
<%= number_to_currency Order.revenue, :precision => 0 %>
|
||||
<span>of <%= number_to_currency Settings.project_goal.to_f * Settings.price.to_f, :precision => 0 %></span>
|
||||
</li>
|
||||
|
||||
<% if Settings.expiration_date.present? %>
|
||||
<li class="stats" id="days">
|
||||
<%= distance_of_time_in_words_to_now(Settings.expiration_date).gsub(/\D/, "") %>
|
||||
<span><%= distance_of_time_in_words_to_now(Settings.expiration_date).gsub(/\d/, "").gsub("about", "") %> left</span>
|
||||
</li>
|
||||
<% else %>
|
||||
<li class="stats" id="days">
|
||||
∞
|
||||
<span>days left</span>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<% if Order.current < Order.goal %>
|
||||
<div id='progress_bg' class='small'>
|
||||
<div id='progress' class='' style='width: <%= Order.percent %>%;'>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div id="progress_bg">
|
||||
<div id="progress">
|
||||
</div>
|
||||
<div id='progress_text'><%= Order.percent %>% <%= Settings.progress_text %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div id="reserve_container">
|
||||
<p id="ship_date"><%= Settings.ships %></p>
|
||||
<a href="/preorder/checkout" class="blue_button reserve"><%= Settings.call_to_action %></a>
|
||||
<p id="price"><%= Settings.price_human %></p>
|
||||
<p><%= Settings.dont_give_them_a_reason_to_say_no %></p>
|
||||
<%= like_button %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
3
app/views/preorder/homepage/_value_proposition.html.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
<div class="wrapper center">
|
||||
<h2><%= Settings.value_proposition %></h2>
|
||||
</div>
|
||||
6
app/views/preorder/index.html.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
<%= render 'preorder/homepage/show_dont_tell' %>
|
||||
<%= render 'preorder/homepage/key_points' %>
|
||||
<%= render 'preorder/homepage/other_points' %>
|
||||
<%= render 'preorder/homepage/middle_reserve' %>
|
||||
<%= render 'preorder/homepage/faqs' %>
|
||||
<%= render 'preorder/homepage/press' %>
|
||||
26
app/views/preorder/share.html.erb
Normal file
@@ -0,0 +1,26 @@
|
||||
<div class="gray_background" id='share_container'>
|
||||
<div class="wrapper center" id="congrats">
|
||||
<h2>
|
||||
Hooray! You've just reserved a <%= Settings.product_name %>!
|
||||
</h2>
|
||||
<p>Congratulations, you're <%= Settings.primary_stat_verb %> number <span id="backer_number"><%= number_with_delimiter @order.number, :delimiter => "," %></span>, in supporting <%= Settings.product_name %>. Share the great news!</p>
|
||||
<br />
|
||||
<br />
|
||||
<div id="share" class="clearfix">
|
||||
<div id='pin_button_container'>
|
||||
<%= pin_it_button %>
|
||||
</div>
|
||||
<div id='tweet_button_container'>
|
||||
<%= tweet_button %>
|
||||
</div>
|
||||
<div id='facebook_button_container'>
|
||||
<%= like_button(450, true) %>
|
||||
</div>
|
||||
</div>
|
||||
<div id="order_id">Reservation ID: <%= @order.uuid %>. You can bookmark or print this page for your records.</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<%= render 'preorder/share/twitter_js' %>
|
||||
<%= render 'preorder/share/facebook_js' %>
|
||||
8
app/views/preorder/share/_facebook_js.html.erb
Normal file
@@ -0,0 +1,8 @@
|
||||
<div id="fb-root"></div>
|
||||
<script>(function(d, s, id) {
|
||||
var js, fjs = d.getElementsByTagName(s)[0];
|
||||
if (d.getElementById(id)) return;
|
||||
js = d.createElement(s); js.id = id;
|
||||
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=<%= Settings.facebook_app_id %>";
|
||||
fjs.parentNode.insertBefore(js, fjs);
|
||||
}(document, 'script', 'facebook-jssdk'));</script>
|
||||
1
app/views/preorder/share/_twitter_js.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
||||
4
config.ru
Normal file
@@ -0,0 +1,4 @@
|
||||
# This file is used by Rack-based servers to start the application.
|
||||
|
||||
require ::File.expand_path('../config/environment', __FILE__)
|
||||
run Selfstarter::Application
|
||||
24
config/application.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
require File.expand_path('../boot', __FILE__)
|
||||
|
||||
require 'rails/all'
|
||||
|
||||
if defined?(Bundler)
|
||||
Bundler.require(*Rails.groups(:assets => %w(development test)))
|
||||
end
|
||||
|
||||
module Selfstarter
|
||||
|
||||
class Application < Rails::Application
|
||||
|
||||
# --- Standard Rails Config ---
|
||||
config.time_zone = 'Pacific Time (US & Canada)'
|
||||
config.encoding = "utf-8"
|
||||
config.filter_parameters += [:password]
|
||||
config.active_record.whitelist_attributes = true
|
||||
# Enable the asset pipeline
|
||||
config.assets.enabled = true
|
||||
# Version of your assets, change this if you want to expire all your assets
|
||||
config.assets.version = '1.0'
|
||||
# --- Standard Rails Config ---
|
||||
end
|
||||
end
|
||||
6
config/boot.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
require 'rubygems'
|
||||
|
||||
# Set up gems listed in the Gemfile.
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
||||
|
||||
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
|
||||
25
config/database.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
# SQLite version 3.x
|
||||
# gem install sqlite3
|
||||
#
|
||||
# Ensure the SQLite 3 gem is defined in your Gemfile
|
||||
# gem 'sqlite3'
|
||||
development:
|
||||
adapter: sqlite3
|
||||
database: db/development.sqlite3
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
|
||||
# Warning: The database defined as "test" will be erased and
|
||||
# re-generated from your development database when you run "rake".
|
||||
# Do not set this db to the same as development or production.
|
||||
test:
|
||||
adapter: sqlite3
|
||||
database: db/test.sqlite3
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
|
||||
production:
|
||||
adapter: sqlite3
|
||||
database: db/production.sqlite3
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
5
config/environment.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
# Load the rails application
|
||||
require File.expand_path('../application', __FILE__)
|
||||
|
||||
# Initialize the rails application
|
||||
Selfstarter::Application.initialize!
|
||||
37
config/environments/development.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
Selfstarter::Application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb
|
||||
|
||||
# In the development environment your application's code is reloaded on
|
||||
# every request. This slows down response time but is perfect for development
|
||||
# since you don't have to restart the web server when you make code changes.
|
||||
config.cache_classes = false
|
||||
|
||||
# Log error messages when you accidentally call methods on nil.
|
||||
config.whiny_nils = true
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
# Don't care if the mailer can't send
|
||||
config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
# Print deprecation notices to the Rails logger
|
||||
config.active_support.deprecation = :log
|
||||
|
||||
# Only use best-standards-support built into browsers
|
||||
config.action_dispatch.best_standards_support = :builtin
|
||||
|
||||
# Raise exception on mass assignment protection for Active Record models
|
||||
config.active_record.mass_assignment_sanitizer = :strict
|
||||
|
||||
# Log the query plan for queries taking more than this (works
|
||||
# with SQLite, MySQL, and PostgreSQL)
|
||||
config.active_record.auto_explain_threshold_in_seconds = 0.5
|
||||
|
||||
# Do not compress assets
|
||||
config.assets.compress = false
|
||||
|
||||
# Expands the lines which load the assets
|
||||
config.assets.debug = true
|
||||
end
|
||||
67
config/environments/production.rb
Normal file
@@ -0,0 +1,67 @@
|
||||
Selfstarter::Application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb
|
||||
|
||||
# Code is not reloaded between requests
|
||||
config.cache_classes = true
|
||||
|
||||
# Full error reports are disabled and caching is turned on
|
||||
config.consider_all_requests_local = false
|
||||
config.action_controller.perform_caching = true
|
||||
|
||||
# Disable Rails's static asset server (Apache or nginx will already do this)
|
||||
config.serve_static_assets = false
|
||||
|
||||
# Compress JavaScripts and CSS
|
||||
config.assets.compress = true
|
||||
|
||||
# Don't fallback to assets pipeline if a precompiled asset is missed
|
||||
config.assets.compile = false
|
||||
|
||||
# Generate digests for assets URLs
|
||||
config.assets.digest = true
|
||||
|
||||
# Defaults to nil and saved in location specified by config.assets.prefix
|
||||
# config.assets.manifest = YOUR_PATH
|
||||
|
||||
# Specifies the header that your server uses for sending files
|
||||
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
|
||||
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
|
||||
|
||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||
# config.force_ssl = true
|
||||
|
||||
# See everything in the log (default is :info)
|
||||
# config.log_level = :debug
|
||||
|
||||
# Prepend all log lines with the following tags
|
||||
# config.log_tags = [ :subdomain, :uuid ]
|
||||
|
||||
# Use a different logger for distributed setups
|
||||
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
|
||||
|
||||
# Use a different cache store in production
|
||||
# config.cache_store = :mem_cache_store
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server
|
||||
# config.action_controller.asset_host = "http://assets.example.com"
|
||||
|
||||
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
||||
config.assets.precompile += %w( application.js application.css )
|
||||
|
||||
# Disable delivery errors, bad email addresses will be ignored
|
||||
# config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
# Enable threaded mode
|
||||
# config.threadsafe!
|
||||
|
||||
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
||||
# the I18n.default_locale when a translation can not be found)
|
||||
config.i18n.fallbacks = true
|
||||
|
||||
# Send deprecation notices to registered listeners
|
||||
config.active_support.deprecation = :notify
|
||||
|
||||
# Log the query plan for queries taking more than this (works
|
||||
# with SQLite, MySQL, and PostgreSQL)
|
||||
# config.active_record.auto_explain_threshold_in_seconds = 0.5
|
||||
end
|
||||
37
config/environments/test.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
Selfstarter::Application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb
|
||||
|
||||
# The test environment is used exclusively to run your application's
|
||||
# test suite. You never need to work with it otherwise. Remember that
|
||||
# your test database is "scratch space" for the test suite and is wiped
|
||||
# and recreated between test runs. Don't rely on the data there!
|
||||
config.cache_classes = true
|
||||
|
||||
# Configure static asset server for tests with Cache-Control for performance
|
||||
config.serve_static_assets = true
|
||||
config.static_cache_control = "public, max-age=3600"
|
||||
|
||||
# Log error messages when you accidentally call methods on nil
|
||||
config.whiny_nils = true
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
# Raise exceptions instead of rendering exception templates
|
||||
config.action_dispatch.show_exceptions = false
|
||||
|
||||
# Disable request forgery protection in test environment
|
||||
config.action_controller.allow_forgery_protection = false
|
||||
|
||||
# Tell Action Mailer not to deliver emails to the real world.
|
||||
# The :test delivery method accumulates sent emails in the
|
||||
# ActionMailer::Base.deliveries array.
|
||||
config.action_mailer.delivery_method = :test
|
||||
|
||||
# Raise exception on mass assignment protection for Active Record models
|
||||
config.active_record.mass_assignment_sanitizer = :strict
|
||||
|
||||
# Print deprecation notices to the stderr
|
||||
config.active_support.deprecation = :stderr
|
||||
end
|
||||
3
config/initializers/amazon_flexible_payments.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
AmazonFlexPay.access_key = Settings.amazon_access_key
|
||||
AmazonFlexPay.secret_key = Settings.amazon_secret_key
|
||||
AmazonFlexPay.go_live! if Rails.env.production?
|
||||
7
config/initializers/backtrace_silencers.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
||||
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
|
||||
|
||||
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
|
||||
# Rails.backtrace_cleaner.remove_silencers!
|
||||
15
config/initializers/inflections.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Add new inflection rules using the following format
|
||||
# (all these examples are active by default):
|
||||
# ActiveSupport::Inflector.inflections do |inflect|
|
||||
# inflect.plural /^(ox)$/i, '\1en'
|
||||
# inflect.singular /^(ox)en/i, '\1'
|
||||
# inflect.irregular 'person', 'people'
|
||||
# inflect.uncountable %w( fish sheep )
|
||||
# end
|
||||
#
|
||||
# These inflection rules are supported but not enabled by default:
|
||||
# ActiveSupport::Inflector.inflections do |inflect|
|
||||
# inflect.acronym 'RESTful'
|
||||
# end
|
||||
5
config/initializers/mime_types.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Add new mime types for use in respond_to blocks:
|
||||
# Mime::Type.register "text/richtext", :rtf
|
||||
# Mime::Type.register_alias "text/html", :iphone
|
||||
3
config/initializers/rails_config.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
RailsConfig.setup do |config|
|
||||
config.const_name = "Settings"
|
||||
end
|
||||
7
config/initializers/secret_token.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Your secret key for verifying the integrity of signed cookies.
|
||||
# If you change this key, all old signed cookies will become invalid!
|
||||
# Make sure the secret is at least 30 characters and all random,
|
||||
# no regular words or you'll be exposed to dictionary attacks.
|
||||
Selfstarter::Application.config.secret_token = '686a073cf783e29dee02cb7544762d17a7c769acf7baa148a0d9726a39e45123532418f9ce7cd3def2ca0e3d5bff9d0b9ffd41f19b0c6b6dd9d0cc10b77fc5ae'
|
||||
8
config/initializers/session_store.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
Selfstarter::Application.config.session_store :cookie_store, key: '_Selfstarter_session'
|
||||
|
||||
# Use the database for sessions instead of the cookie-based default,
|
||||
# which shouldn't be used to store highly confidential information
|
||||
# (create the session table with "rails generate session_migration")
|
||||
# Selfstarter::Application.config.session_store :active_record_store
|
||||
14
config/initializers/wrap_parameters.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
#
|
||||
# This file contains settings for ActionController::ParamsWrapper which
|
||||
# is enabled by default.
|
||||
|
||||
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
wrap_parameters format: [:json]
|
||||
end
|
||||
|
||||
# Disable root element in JSON by default.
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
self.include_root_in_json = false
|
||||
end
|
||||
5
config/locales/en.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
# Sample localization file for English. Add more files in this directory for other locales.
|
||||
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
|
||||
|
||||
en:
|
||||
hello: "Hello world"
|
||||
11
config/routes.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
Selfstarter::Application.routes.draw do
|
||||
root :to => "preorder#index"
|
||||
|
||||
match '/preorder' => 'preorder#index'
|
||||
get "preorder/checkout"
|
||||
match '/preorder/share/:uuid' => 'preorder#share', :via => :get
|
||||
match '/preorder/ipn' => 'preorder#ipn', :via => :post
|
||||
match '/preorder/prefill' => 'preorder#prefill'
|
||||
match '/preorder/postfill' => 'preorder#postfill'
|
||||
|
||||
end
|
||||
80
config/settings.yml
Normal file
@@ -0,0 +1,80 @@
|
||||
# Hi there!
|
||||
# These are the settings for Selfstarter.
|
||||
# This is more tidy than changing the HTML if all you want to do is rename things and swap out images
|
||||
|
||||
# You should totally change the HTML and CSS though
|
||||
# Checkout app/assets/stylesheets/variables.css.scss to change around the CSS quickly
|
||||
|
||||
# Set your project goal here - if you manually want to adjust your progress to test the site, head over to the Order model (app/models/order.rb)
|
||||
project_goal: 100
|
||||
# If you want to edit the FAQ, head over to app/views/preorder/homepage/_faqs.html.erb
|
||||
|
||||
# This'll be both the page title (<title></title>) and the name in the header
|
||||
product_name: "Selfstarter"
|
||||
|
||||
# An image showcasing your product -- it'll show up when you pin your product
|
||||
# It should be in app/assets/images
|
||||
product_image_path: "my-product-image.png"
|
||||
|
||||
# The message on the preorder page, Lockitron's
|
||||
value_proposition: "Roll your own crowdfunding"
|
||||
|
||||
# YouTube Video URL (The embed URL, without the query string options)
|
||||
# There's no Vimeo support at the moment, but feel free to implement it and send a pull request!
|
||||
youtube_embed_url: "https://www.youtube.com/v/D1L3o88GKew"
|
||||
|
||||
# Amazon settings -- you'll need an Amazon Payments account, sign up here --> http://bit.ly/SGksTv
|
||||
|
||||
# To find your access key and secret key, head over to here --> http://bit.ly/R4I4ky (Follow that guide in the Seller Central page)
|
||||
amazon_access_key: "YOUR_AMAZON_ACCESS_KEY"
|
||||
amazon_secret_key: "YOUR_AMAZON_SECRET_KEY"
|
||||
price: 19.95
|
||||
|
||||
payment_description: "You really should change this text because people will see it on Amazon's order page!!!!!"
|
||||
|
||||
# Amazon limits how much we can charge people with their Multi-Use tokens.
|
||||
# You probably should add some leeway to account for international shipping
|
||||
charge_limit: 25.00
|
||||
|
||||
# Stats settings
|
||||
|
||||
# On Lockitron, it's "backers"
|
||||
primary_stat: "backers"
|
||||
# This'll show up in the tweet as, "I'm forker number ..."
|
||||
primary_stat_verb: 'backer'
|
||||
|
||||
# The 2nd call to action button, towards the middle-ish of the page
|
||||
middle_reserve_text: "Reserve Now"
|
||||
|
||||
# When the project should end
|
||||
expiration_date: <%= DateTime.now + 29 %>
|
||||
|
||||
# Text to show inside the progress bar, when the goal reaches/exceeds 100%
|
||||
progress_text: "Implemented"
|
||||
|
||||
# Call to action section
|
||||
|
||||
# On Lockitron, it's "First Batch Ships in March 2013"
|
||||
ships: "Ships...sometime"
|
||||
|
||||
# On Lockitron, it's "Reserve Now"
|
||||
call_to_action: "Reserve Now"
|
||||
# On Lockitron, this is "Only $149 for a limited time"
|
||||
price_human: "It costs money!"
|
||||
|
||||
# The paragraph below the price. You'd probably say something about how you're not going to charge them before it ships (so it's less risky).
|
||||
dont_give_them_a_reason_to_say_no: "You'll get this exact site. All you'll need to get started is a great product."
|
||||
|
||||
# Social Stuff
|
||||
facebook_app_id: "1234567890"
|
||||
# Tweets are prefixed with "I'm #{Settings.primary_stat} number X for #{Settings.product_name}"
|
||||
# Maybe mention something about your product vision -- e.g. "to replace keys with my phone"
|
||||
tweet_text: "to crowdfund"
|
||||
|
||||
# Google Analytics
|
||||
google_id: "1234567890"
|
||||
|
||||
# If you want to change the images for the key points (e.g. "Kickstarter is not a store")
|
||||
# They're in app/assets/images/#{pointer_number}-background.png
|
||||
# So, the first key point, it's at app/assets/images/1-background.png
|
||||
# Alternatively, change it up in app/assets/stylesheets/homepage/key_points.css.scss
|
||||
0
config/settings/development.yml
Normal file
0
config/settings/production.yml
Normal file
0
config/settings/test.yml
Normal file
9
db/migrate/20121004072615_create_users.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class CreateUsers < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :users do |t|
|
||||
t.string :email
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
26
db/migrate/20121004072706_create_orders.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
class CreateOrders < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :orders, :id => false do |t|
|
||||
t.string :token
|
||||
t.string :transaction_id
|
||||
t.string :address_one
|
||||
t.string :address_two
|
||||
t.string :city
|
||||
t.string :state
|
||||
t.string :zip
|
||||
t.string :country
|
||||
t.string :status
|
||||
t.string :number
|
||||
t.string :uuid
|
||||
t.string :user_id
|
||||
t.decimal :price
|
||||
t.decimal :shipping
|
||||
t.string :tracking_number
|
||||
t.string :phone
|
||||
t.string :name
|
||||
t.date :expiration
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
45
db/schema.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
# encoding: UTF-8
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
#
|
||||
# Note that this schema.rb definition is the authoritative source for your
|
||||
# database schema. If you need to create the application database on another
|
||||
# system, you should be using db:schema:load, not running all the migrations
|
||||
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
||||
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20121004072706) do
|
||||
|
||||
create_table "orders", :id => false, :force => true do |t|
|
||||
t.string "token"
|
||||
t.string "transaction_id"
|
||||
t.string "address_one"
|
||||
t.string "address_two"
|
||||
t.string "city"
|
||||
t.string "state"
|
||||
t.string "zip"
|
||||
t.string "country"
|
||||
t.string "status"
|
||||
t.string "number"
|
||||
t.string "uuid"
|
||||
t.string "user_id"
|
||||
t.decimal "price"
|
||||
t.decimal "shipping"
|
||||
t.string "tracking_number"
|
||||
t.string "phone"
|
||||
t.string "name"
|
||||
t.date "expiration"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "users", :force => true do |t|
|
||||
t.string "email"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
end
|
||||
7
db/seeds.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file should contain all the record creation needed to seed the database with its default values.
|
||||
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
|
||||
# Mayor.create(name: 'Emanuel', city: cities.first)
|
||||
2
doc/README_FOR_APP
Normal file
@@ -0,0 +1,2 @@
|
||||
Use this README file to introduce your application and point to useful places in the API for learning more.
|
||||
Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
|
||||
0
lib/assets/.gitkeep
Normal file
0
lib/tasks/.gitkeep
Normal file
0
log/.gitkeep
Normal file
26
public/404.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>The page you were looking for doesn't exist (404)</title>
|
||||
<style type="text/css">
|
||||
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
||||
div.dialog {
|
||||
width: 25em;
|
||||
padding: 0 4em;
|
||||
margin: 4em auto 0 auto;
|
||||
border: 1px solid #ccc;
|
||||
border-right-color: #999;
|
||||
border-bottom-color: #999;
|
||||
}
|
||||
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- This file lives in public/404.html -->
|
||||
<div class="dialog">
|
||||
<h1>The page you were looking for doesn't exist.</h1>
|
||||
<p>You may have mistyped the address or the page may have moved.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
26
public/422.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>The change you wanted was rejected (422)</title>
|
||||
<style type="text/css">
|
||||
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
||||
div.dialog {
|
||||
width: 25em;
|
||||
padding: 0 4em;
|
||||
margin: 4em auto 0 auto;
|
||||
border: 1px solid #ccc;
|
||||
border-right-color: #999;
|
||||
border-bottom-color: #999;
|
||||
}
|
||||
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- This file lives in public/422.html -->
|
||||
<div class="dialog">
|
||||
<h1>The change you wanted was rejected.</h1>
|
||||
<p>Maybe you tried to change something you didn't have access to.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
25
public/500.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>We're sorry, but something went wrong (500)</title>
|
||||
<style type="text/css">
|
||||
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
||||
div.dialog {
|
||||
width: 25em;
|
||||
padding: 0 4em;
|
||||
margin: 4em auto 0 auto;
|
||||
border: 1px solid #ccc;
|
||||
border-right-color: #999;
|
||||
border-bottom-color: #999;
|
||||
}
|
||||
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- This file lives in public/500.html -->
|
||||
<div class="dialog">
|
||||
<h1>We're sorry, but something went wrong.</h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
0
public/favicon.ico
Normal file
5
public/robots.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
|
||||
#
|
||||
# To ban all spiders from the entire site uncomment the next two lines:
|
||||
# User-Agent: *
|
||||
# Disallow: /
|
||||
6
script/rails
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env ruby
|
||||
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
||||
|
||||
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
||||
require File.expand_path('../../config/boot', __FILE__)
|
||||
require 'rails/commands'
|
||||