Base code for campaigns and users
parent
17f7ea929c
commit
6f94521d51
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* ReDonate is more free software. It is licensed under the WTFPL, which
|
||||||
|
* allows you to do pretty much anything with it, without having to
|
||||||
|
* ask permission. Commercial use is allowed, and no attribution is
|
||||||
|
* required. We do politely request that you share your modifications
|
||||||
|
* to benefit other developers, but you are under no enforced
|
||||||
|
* obligation to do so :)
|
||||||
|
*
|
||||||
|
* Please read the accompanying LICENSE document for the full WTFPL
|
||||||
|
* licensing text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(!isset($_APP)) { die("Unauthorized."); }
|
||||||
|
|
||||||
|
class Campaign extends CPHPDatabaseRecordClass
|
||||||
|
{
|
||||||
|
public $table_name = "campaigns";
|
||||||
|
public $fill_query = "SELECT * FROM campaigns WHERE `Id` = :Id";
|
||||||
|
public $verify_query = "SELECT * FROM campaigns WHERE `Id` = :Id";
|
||||||
|
|
||||||
|
public $prototype = array(
|
||||||
|
'string' => array(
|
||||||
|
'Name' => "Name",
|
||||||
|
'UrlName' => "UrlName"
|
||||||
|
),
|
||||||
|
'numeric' => array(
|
||||||
|
'OwnerId' => "UserId"
|
||||||
|
),
|
||||||
|
'boolean' => array(
|
||||||
|
'AllowOneTime' => "AllowOneTime"
|
||||||
|
),
|
||||||
|
'user' => array(
|
||||||
|
'Owner' => "Owner"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static function CheckIfUrlNameExists($urlname)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$result = Campaign::FindByUrlName($urlname);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (NotFoundException $e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function FindByUrlName($urlname)
|
||||||
|
{
|
||||||
|
return self::CreateFromQuery("SELECT * FROM campaigns WHERE `UrlName` = :UrlName", array(':UrlName' => $urlname), 0, true);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,155 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||||
|
* allows you to do pretty much anything with it, without having to
|
||||||
|
* ask permission. Commercial use is allowed, and no attribution is
|
||||||
|
* required. We do politely request that you share your modifications
|
||||||
|
* to benefit other developers, but you are under no enforced
|
||||||
|
* obligation to do so :)
|
||||||
|
*
|
||||||
|
* Please read the accompanying LICENSE document for the full WTFPL
|
||||||
|
* licensing text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(!isset($_APP)) { die("Unauthorized."); }
|
||||||
|
|
||||||
|
class User extends CPHPDatabaseRecordClass
|
||||||
|
{
|
||||||
|
public $table_name = "users";
|
||||||
|
public $fill_query = "SELECT * FROM users WHERE `Id` = :Id";
|
||||||
|
public $verify_query = "SELECT * FROM users WHERE `Id` = :Id";
|
||||||
|
|
||||||
|
public $prototype = array(
|
||||||
|
'string' => array(
|
||||||
|
'Username' => "Username",
|
||||||
|
'DisplayName' => "DisplayName",
|
||||||
|
'EmailAddress' => "EmailAddress",
|
||||||
|
'Hash' => "Hash",
|
||||||
|
'Salt' => "Salt",
|
||||||
|
'ActivationKey' => "ActivationKey"
|
||||||
|
),
|
||||||
|
'boolean' => array(
|
||||||
|
'IsAdmin' => "Admin",
|
||||||
|
'IsActivated' => "Activated"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public function GenerateSalt()
|
||||||
|
{
|
||||||
|
$this->uSalt = random_string(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GenerateHash()
|
||||||
|
{
|
||||||
|
if(!empty($this->uSalt))
|
||||||
|
{
|
||||||
|
if(!empty($this->uPassword))
|
||||||
|
{
|
||||||
|
$this->uHash = $this->CreateHash($this->uPassword);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("User object is missing a password.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("User object is missing a salt.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function CreateHash($input)
|
||||||
|
{
|
||||||
|
global $cphp_config;
|
||||||
|
$hash = crypt($input, "$5\$rounds=50000\${$this->uSalt}{$cphp_config->salt}$");
|
||||||
|
$parts = explode("$", $hash);
|
||||||
|
return $parts[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function VerifyPassword($password)
|
||||||
|
{
|
||||||
|
if($this->CreateHash($password) == $this->sHash)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Authenticate()
|
||||||
|
{
|
||||||
|
$_SESSION['user_id'] = $this->sId;
|
||||||
|
$_SESSION['logout_key'] = random_string(32);
|
||||||
|
$_SESSION['is_admin'] = $this->sIsAdmin;
|
||||||
|
|
||||||
|
NewTemplater::SetGlobalVariable("logged-in", true);
|
||||||
|
|
||||||
|
$this->SetGlobalVariables();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetGlobalVariables()
|
||||||
|
{
|
||||||
|
NewTemplater::SetGlobalVariable("my-displayname", $this->sDisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function CheckIfEmailValid($email)
|
||||||
|
{
|
||||||
|
return preg_match("/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$/i", $email);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function CheckIfEmailExists($email)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$result = User::FindByEmail($email);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (NotFoundException $e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function CheckIfUsernameExists($username)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$result = User::FindByUsername($username);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (NotFoundException $e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function CheckIfDisplayNameExists($displayname)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$result = User::FindByDisplayName($displayname);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (NotFoundException $e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function FindByEmail($email)
|
||||||
|
{
|
||||||
|
return self::CreateFromQuery("SELECT * FROM users WHERE `EmailAddress` = :EmailAddress", array(':EmailAddress' => $email), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function FindByUsername($username)
|
||||||
|
{
|
||||||
|
return self::CreateFromQuery("SELECT * FROM users WHERE `Username` = :Username", array(':Username' => $username), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function FindByDisplayName($displayname)
|
||||||
|
{
|
||||||
|
return self::CreateFromQuery("SELECT * FROM users WHERE `DisplayName` = :DisplayName", array(':DisplayName' => $displayname), 0);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* ReDonate is more free software. It is licensed under the WTFPL, which
|
||||||
|
* allows you to do pretty much anything with it, without having to
|
||||||
|
* ask permission. Commercial use is allowed, and no attribution is
|
||||||
|
* required. We do politely request that you share your modifications
|
||||||
|
* to benefit other developers, but you are under no enforced
|
||||||
|
* obligation to do so :)
|
||||||
|
*
|
||||||
|
* Please read the accompanying LICENSE document for the full WTFPL
|
||||||
|
* licensing text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(!isset($_APP)) { die("Unauthorized."); }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$sCampaign = Campaign::FindByUrlName($router->uParameters[1]);
|
||||||
|
|
||||||
|
$sPageTitle = "Contribute to {$sCampaign->sName}";
|
||||||
|
$sPageContents = NewTemplater::Render("landing", $locale->strings, array("can-donate-once" => true, "project-name" => $sCampaign->sName));
|
||||||
|
}
|
||||||
|
catch (NotFoundException $e)
|
||||||
|
{
|
||||||
|
$sPageContents = NewTemplater::Render("404", $locale->strings, array());
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* ReDonate is more free software. It is licensed under the WTFPL, which
|
||||||
|
* allows you to do pretty much anything with it, without having to
|
||||||
|
* ask permission. Commercial use is allowed, and no attribution is
|
||||||
|
* required. We do politely request that you share your modifications
|
||||||
|
* to benefit other developers, but you are under no enforced
|
||||||
|
* obligation to do so :)
|
||||||
|
*
|
||||||
|
* Please read the accompanying LICENSE document for the full WTFPL
|
||||||
|
* licensing text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$_CPHP = true;
|
||||||
|
$_CPHP_CONFIG = "../config.json";
|
||||||
|
require("cphp/base.php");
|
||||||
|
$_APP = true;
|
||||||
|
|
||||||
|
function __autoload($class_name)
|
||||||
|
{
|
||||||
|
global $_APP;
|
||||||
|
|
||||||
|
$class_name = str_replace("\\", "/", strtolower($class_name));
|
||||||
|
require_once("classes/{$class_name}.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
$sPageTitle = "";
|
||||||
|
$sPageContents = "";
|
||||||
|
|
||||||
|
$router = new CPHPRouter();
|
||||||
|
$router->allow_slash = true;
|
||||||
|
$router->ignore_query = true;
|
||||||
|
|
||||||
|
$router->routes = array(
|
||||||
|
0 => array(
|
||||||
|
"^/$" => "modules/index.php",
|
||||||
|
"^/register/$" => "modules/register.php",
|
||||||
|
"^/login/$" => "modules/login.php",
|
||||||
|
"^/campaign/([a-zA-Z0-9-]+)" => "modules/landing.php",
|
||||||
|
"^/campaign/([a-zA-Z0-9-]+)/subscribe" => "modules/subscribe.php",
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$router->RouteRequest();
|
||||||
|
|
||||||
|
echo(NewTemplater::Render("layout", $locale->strings, array("contents" => $sPageContents, "title" => $sPageTitle)));
|
@ -0,0 +1,196 @@
|
|||||||
|
body
|
||||||
|
{
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
background-color: #E5EFD7;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear
|
||||||
|
{
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper
|
||||||
|
{
|
||||||
|
width: 960px;
|
||||||
|
margin: 0px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1
|
||||||
|
{
|
||||||
|
color: #7AAA3E;
|
||||||
|
font-family: Roboto, sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 46px;
|
||||||
|
margin: 8px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 .highlight
|
||||||
|
{
|
||||||
|
color: #587532;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main
|
||||||
|
{
|
||||||
|
background-color: #FCFFF7;
|
||||||
|
box-shadow: 0px 0px 10px 1px #b0b0b0;
|
||||||
|
-webkit-box-shadow: 0px 0px 10px 1px #b0b0b0;
|
||||||
|
-moz-box-shadow: 0px 0px 10px 1px #b0b0b0;
|
||||||
|
-o-box-shadow: 0px 0px 10px 1px #b0b0b0;
|
||||||
|
-ms-box-shadow: 0px 0px 10px 1px #b0b0b0;
|
||||||
|
padding: 16px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main h2
|
||||||
|
{
|
||||||
|
font-size: 32px;
|
||||||
|
margin: 0px 0px 6px 0px;
|
||||||
|
color: #3B4A28;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .details, .main .subscribe
|
||||||
|
{
|
||||||
|
margin-top: 16px;
|
||||||
|
width: 46%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .details
|
||||||
|
{
|
||||||
|
float: left;
|
||||||
|
padding-right: 4%;
|
||||||
|
text-align: justify;
|
||||||
|
border-right: 1px solid silver;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .subscribe
|
||||||
|
{
|
||||||
|
float: right;
|
||||||
|
padding-left: 3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main h3
|
||||||
|
{
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .subscribe h3
|
||||||
|
{
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .leader
|
||||||
|
{
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .more
|
||||||
|
{
|
||||||
|
margin-top: 16px;
|
||||||
|
border-top: 1px solid silver;
|
||||||
|
padding-top: 32px;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .more .wrapper
|
||||||
|
{
|
||||||
|
width: 730px;
|
||||||
|
margin: 0px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main h3.section
|
||||||
|
{
|
||||||
|
margin-top: 16px;
|
||||||
|
border-top: 1px solid silver;
|
||||||
|
padding-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subscribe p
|
||||||
|
{
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#field_currency
|
||||||
|
{
|
||||||
|
text-align: right;
|
||||||
|
border: 1px solid #6CA825;
|
||||||
|
border-radius: 1px;
|
||||||
|
background-color: transparent;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#field_amount, #field_email
|
||||||
|
{
|
||||||
|
border: 1px solid #6CA825;
|
||||||
|
border-radius: 1px;
|
||||||
|
background-color: transparent;
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 1px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#field_amount
|
||||||
|
{
|
||||||
|
width: 55px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#field_email
|
||||||
|
{
|
||||||
|
margin-top: 6px;
|
||||||
|
width: 335px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.green-button
|
||||||
|
{
|
||||||
|
margin-top: 0px;
|
||||||
|
background: #66CC00;
|
||||||
|
border-top: 1px solid #529d26;
|
||||||
|
border-right: 1px solid #2c5615;
|
||||||
|
border-bottom: 1px solid #1d390e;
|
||||||
|
border-left: 1px solid #2c5615;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: inset 0 1px 10px 1px #8eff4b,
|
||||||
|
0px 1px 0 #2c5713,
|
||||||
|
0 6px 0px #305e14,
|
||||||
|
0 8px 4px 1px #111111;
|
||||||
|
color: #fff;
|
||||||
|
font: bold 20px/1 "helvetica neue",
|
||||||
|
helvetica,
|
||||||
|
arial,
|
||||||
|
sans-serif;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
padding: 10px 15px 12px 15px;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: 0px -1px 1px #1e2d4d;
|
||||||
|
-webkit-background-clip: padding-box; }
|
||||||
|
|
||||||
|
.green-button:hover
|
||||||
|
{
|
||||||
|
box-shadow: inset 0 0px 20px 1px #bdff87,
|
||||||
|
0px 1px 0 #324d1d,
|
||||||
|
0 6px 0px #37531f,
|
||||||
|
0 8px 4px 1px #111111;
|
||||||
|
cursor: pointer; }
|
||||||
|
|
||||||
|
.green-button:active
|
||||||
|
{
|
||||||
|
box-shadow: inset 0 1px 10px 1px #a5df76,
|
||||||
|
0 1px 0 #203213,
|
||||||
|
0 2px 0 #223413,
|
||||||
|
0 4px 3px 0 #111111;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.green-button:disabled
|
||||||
|
{
|
||||||
|
-webkit-filter: grayscale(100%);
|
||||||
|
-moz-filter: grayscale(100%);
|
||||||
|
-ms-filter: grayscale(100%);
|
||||||
|
filter: grayscale(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.pledge
|
||||||
|
{
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
<h2>Page not found.</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Sorry, we could not find the page you requested.</strong> But while you're here anyway, why not introduce ourselves?
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
ReDonate is recurring contributions, done right. Set up a campaign, and accept monthly donations from contributors that wish
|
||||||
|
to support you, without <em>ever</em> automatically charging an account. ReDonate is friendly to you, <em>and</em> your
|
||||||
|
donors.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Gotten curious? <a href="/">Visit our homepage to learn more...</a>
|
||||||
|
</p>
|
@ -1,296 +1,85 @@
|
|||||||
<!doctype html>
|
<h2>Contribute to {%?project-name} monthly, no automatic charges.</h2>
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
||||||
<link href='http://fonts.googleapis.com/css?family=Lato:400,700|Cantarell:400,700|Roboto:500' rel='stylesheet' type='text/css'>
|
|
||||||
<style>
|
|
||||||
body
|
|
||||||
{
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
background-color: #E5EFD7;
|
|
||||||
font-family: Lato, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear
|
|
||||||
{
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper
|
|
||||||
{
|
|
||||||
width: 960px;
|
|
||||||
margin: 0px auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header h1
|
|
||||||
{
|
|
||||||
color: #7AAA3E;
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 46px;
|
|
||||||
margin: 8px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header h1 .highlight
|
|
||||||
{
|
|
||||||
color: #587532;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main
|
|
||||||
{
|
|
||||||
background-color: #FCFFF7;
|
|
||||||
box-shadow: 0px 0px 10px 1px #b0b0b0;
|
|
||||||
-webkit-box-shadow: 0px 0px 10px 1px #b0b0b0;
|
|
||||||
-moz-box-shadow: 0px 0px 10px 1px #b0b0b0;
|
|
||||||
-o-box-shadow: 0px 0px 10px 1px #b0b0b0;
|
|
||||||
-ms-box-shadow: 0px 0px 10px 1px #b0b0b0;
|
|
||||||
padding: 16px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main h2
|
|
||||||
{
|
|
||||||
font-size: 32px;
|
|
||||||
margin: 0px 0px 6px 0px;
|
|
||||||
color: #3B4A28;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main .details, .main .subscribe
|
|
||||||
{
|
|
||||||
margin-top: 16px;
|
|
||||||
width: 46%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main .details
|
|
||||||
{
|
|
||||||
float: left;
|
|
||||||
padding-right: 4%;
|
|
||||||
text-align: justify;
|
|
||||||
border-right: 1px solid silver;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main .subscribe
|
|
||||||
{
|
|
||||||
float: right;
|
|
||||||
padding-left: 3%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main h3
|
|
||||||
{
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main .subscribe h3
|
|
||||||
{
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main .leader
|
|
||||||
{
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main .more
|
|
||||||
{
|
|
||||||
margin-top: 16px;
|
|
||||||
border-top: 1px solid silver;
|
|
||||||
padding-top: 32px;
|
|
||||||
text-align: justify;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main .more .wrapper
|
|
||||||
{
|
|
||||||
width: 730px;
|
|
||||||
margin: 0px auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subscribe p
|
|
||||||
{
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#field_currency
|
|
||||||
{
|
|
||||||
text-align: right;
|
|
||||||
border: 1px solid #6CA825;
|
|
||||||
border-radius: 1px;
|
|
||||||
background-color: transparent;
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#field_amount, #field_email
|
|
||||||
{
|
|
||||||
border: 1px solid #6CA825;
|
|
||||||
border-radius: 1px;
|
|
||||||
background-color: transparent;
|
|
||||||
font-size: 18px;
|
|
||||||
padding: 1px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#field_amount
|
|
||||||
{
|
|
||||||
width: 55px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#field_email
|
|
||||||
{
|
|
||||||
margin-top: 6px;
|
|
||||||
width: 335px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Thanks, Ari! */
|
|
||||||
|
|
||||||
.green-button
|
|
||||||
{
|
|
||||||
margin-top: 0px;
|
|
||||||
background: #66CC00;
|
|
||||||
border-top: 1px solid #529d26;
|
|
||||||
border-right: 1px solid #2c5615;
|
|
||||||
border-bottom: 1px solid #1d390e;
|
|
||||||
border-left: 1px solid #2c5615;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: inset 0 1px 10px 1px #8eff4b,
|
|
||||||
0px 1px 0 #2c5713,
|
|
||||||
0 6px 0px #305e14,
|
|
||||||
0 8px 4px 1px #111111;
|
|
||||||
color: #fff;
|
|
||||||
font: bold 20px/1 "helvetica neue",
|
|
||||||
helvetica,
|
|
||||||
arial,
|
|
||||||
sans-serif;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
padding: 10px 15px 12px 15px;
|
|
||||||
text-align: center;
|
|
||||||
text-shadow: 0px -1px 1px #1e2d4d;
|
|
||||||
-webkit-background-clip: padding-box; }
|
|
||||||
|
|
||||||
.green-button:hover
|
<div class="details">
|
||||||
{
|
<h3>How does it work?</h3>
|
||||||
box-shadow: inset 0 0px 20px 1px #bdff87,
|
<p class="leader">
|
||||||
0px 1px 0 #324d1d,
|
Most recurring services - even charities! - will automatically charge your account every month.
|
||||||
0 6px 0px #37531f,
|
ReDonate is different.
|
||||||
0 8px 4px 1px #111111;
|
</p>
|
||||||
cursor: pointer; }
|
<p>
|
||||||
|
When you subscribe to a ReDonate campaign, you only have to tell us how much you want to donate, and
|
||||||
.green-button:active
|
your e-mail address. Every month, we will e-mail you to remind you of your pledge. The e-mail you
|
||||||
{
|
receive will include a list of payment methods, and an unsubscribe link.
|
||||||
box-shadow: inset 0 1px 10px 1px #a5df76,
|
</p>
|
||||||
0 1px 0 #203213,
|
<p>
|
||||||
0 2px 0 #223413,
|
What this means in simple terms is that you'll <strong>never</strong> be automatically charged for a donation -
|
||||||
0 4px 3px 0 #111111;
|
you can decide to cancel your subscription at any time, without hassle, and without "oops, I forgot to cancel"
|
||||||
margin-top: 5px;
|
moments!
|
||||||
margin-bottom: 10px;
|
</p>
|
||||||
}
|
|
||||||
|
{%if can-donate-once == true}
|
||||||
.green-button:disabled
|
<h3>Why use ReDonate?</h3>
|
||||||
{
|
<p>
|
||||||
-webkit-filter: grayscale(100%);
|
Many donors wish to donate to a cause at regular intervals, but do not want to have their account charged automatically.
|
||||||
-moz-filter: grayscale(100%);
|
To take away the hassle of having to remember to donate every month, ReDonate was born. No need to remember a
|
||||||
-ms-filter: grayscale(100%);
|
donation schedule, and no automatic charges either!
|
||||||
filter: grayscale(100%);
|
</p>
|
||||||
}
|
{%/if}
|
||||||
|
</div>
|
||||||
p.pledge
|
<div class="subscribe">
|
||||||
{
|
<h3>Subscribe to a recurring donation</h3>
|
||||||
padding-left: 15px;
|
<p>
|
||||||
padding-top: 10px;
|
My e-mail address is...
|
||||||
}
|
<input type="text" id="field_email" placeholder="you@provider.com">
|
||||||
</style>
|
</p>
|
||||||
</head>
|
<p>
|
||||||
<body>
|
... and I'd like to pledge
|
||||||
<div class="wrapper">
|
<select id="field_currency">
|
||||||
<div class="header">
|
<option value="usd">$</option>
|
||||||
<h1>
|
<option value="eur">€</option>
|
||||||
Re<span class="highlight">Donate</span>
|
<option value="btc">BTC</option>
|
||||||
</h1>
|
</select>
|
||||||
</div>
|
<input type="text" id="field_amount" value="5.00">
|
||||||
<div class="main">
|
a month.
|
||||||
<h2>Contribute to AnonNews monthly, no automatic charges.</h2>
|
</p>
|
||||||
|
<p class="pledge">
|
||||||
<div class="details">
|
<button class="green-button" id="button_subscribe">Pledge!</button>
|
||||||
<h3>How does it work?</h3>
|
</p>
|
||||||
<p class="leader">
|
|
||||||
Most recurring services - even charities! - will automatically charge your account every month.
|
{%if can-donate-once == true}
|
||||||
ReDonate is different.
|
<h3 class="section">One-off donation</h3>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
<img src="/static/images/paypal.png">
|
||||||
When you subscribe to a ReDonate campaign, you only have to tell us how much you want to donate, and provide
|
<img src="/static/images/bitcoin.png" style="margin-left: 16px;">
|
||||||
your e-mail address. Every month, we will e-mail you to remind you of your pledge. The e-mail you receive will
|
</p>
|
||||||
include a list of payment methods, and an unsubscribe link.
|
{%/if}
|
||||||
</p>
|
</div>
|
||||||
<p>
|
<div class="clear"></div>
|
||||||
What this means in simple terms is that you'll <strong>never</strong> be automatically charged for a donation -
|
<div class="more">
|
||||||
you can decide to cancel your subscription at any time, without hassle, and without "oops, I forgot to cancel"
|
<div class="wrapper">
|
||||||
moments!
|
{%if can-donate-once == false}
|
||||||
</p>
|
<h3>Why use ReDonate?</h3>
|
||||||
|
<p>
|
||||||
{%if can-donate-once == true}
|
Many donors wish to donate to a cause at regular intervals, but do not want to have their account charged automatically.
|
||||||
<h3>Why use ReDonate?</h3>
|
To take away the hassle of having to remember to donate every month, ReDonate was born. No need to remember a
|
||||||
<p>
|
donation schedule, and no automatic charges either!
|
||||||
Many donors wish to donate to a cause at regular intervals, but do not want to have their account charged automatically.
|
</p>
|
||||||
To take away the hassle of having to remember to donate every month, ReDonate was born. No need to remember a
|
{%/if}
|
||||||
donation schedule, and no automatic charges either!
|
|
||||||
</p>
|
<h3>Is this safe?</h3>
|
||||||
{%/if}
|
<p class="leader">
|
||||||
</div>
|
Short answer: Yes.
|
||||||
<div class="subscribe">
|
</p>
|
||||||
<h3>Subscribe to a recurring donation</h3>
|
<p>
|
||||||
<p>
|
The longer answer: ReDonate does not actually process any payments. You'll be using the same payment processor
|
||||||
My e-mail address is...
|
that you'd be using to donate otherwise - we're just here to remind you. We do not have access to any of your
|
||||||
<input type="text" id="field_email" placeholder="you@provider.com">
|
accounts, nor can we control where donations go.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
... and I'd like to pledge
|
We also have no reason to sell or otherwise misuse your data. ReDonate is an entirely non-profit project. It's
|
||||||
<select id="field_currency">
|
supported by the <a href="http://cryto.net/">Cryto Coding Collective</a>, a collective of developers that has
|
||||||
<option value="usd">$</option>
|
been running off <a href="http://cryto.net/donate">donations</a> for nearly two years now. We won't use your
|
||||||
<option value="eur">€</option>
|
e-mail address for anything other than sending you reminders, and every e-mail includes an unsubscribe link.
|
||||||
<option value="btc">BTC</option>
|
</p>
|
||||||
</select>
|
</div>
|
||||||
<input type="text" id="field_amount" value="5.00">
|
</div>
|
||||||
a month.
|
|
||||||
</p>
|
|
||||||
<p class="pledge">
|
|
||||||
<button class="green-button" id="button_subscribe">Pledge!</button>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{%if can-donate-once == true}
|
|
||||||
<h3 class="section">One-off donation</h3>
|
|
||||||
<p>
|
|
||||||
<img src="/static/images/paypal.png">
|
|
||||||
<img src="/static/images/bitcoin.png" style="margin-left: 16px;">
|
|
||||||
</p>
|
|
||||||
{%/if}
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="more">
|
|
||||||
<div class="wrapper">
|
|
||||||
{%if can-donate-once == false}
|
|
||||||
<h3>Why use ReDonate?</h3>
|
|
||||||
<p>
|
|
||||||
Many donors wish to donate to a cause at regular intervals, but do not want to have their account charged automatically.
|
|
||||||
To take away the hassle of having to remember to donate every month, ReDonate was born. No need to remember a
|
|
||||||
donation schedule, and no automatic charges either!
|
|
||||||
</p>
|
|
||||||
{%/if}
|
|
||||||
|
|
||||||
<h3>Is this safe?</h3>
|
|
||||||
<p class="leader">
|
|
||||||
Short answer: Yes.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The longer answer: ReDonate does not actually process any payments. You'll be using the same payment processor
|
|
||||||
that you'd be using to donate otherwise - we're just here to remind you. We do not have access to any of your
|
|
||||||
accounts, nor can we control where donations go.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We also have no reason to sell or otherwise misuse your data. ReDonate is an entirely non-profit project. It's
|
|
||||||
supported by the <a href="http://cryto.net/">Cryto Coding Collective</a>, a collective of developers that has
|
|
||||||
been running off <a href="http://cryto.net/donate">donations</a> for nearly two years now. We won't use your
|
|
||||||
e-mail address for anything other than sending you reminders, and every e-mail includes an unsubscribe link.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<link href='http://fonts.googleapis.com/css?family=Lato:400,700|Cantarell:400,700|Roboto:500' rel='stylesheet' type='text/css'>
|
||||||
|
<link href="/static/css/style.css" rel="stylesheet">
|
||||||
|
<title>ReDonate :: {%?title}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="header">
|
||||||
|
<h1>
|
||||||
|
Re<span class="highlight">Donate</span>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
{%?contents}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue