diff --git a/digitalglarus/forms.py b/digitalglarus/forms.py new file mode 100644 index 00000000..10f73b31 --- /dev/null +++ b/digitalglarus/forms.py @@ -0,0 +1,36 @@ +from django import forms +from django.utils.translation import ugettext_lazy as _ + + +from utils.models import BillingAddress +from utils.forms import LoginFormMixin, SignupFormMixin, BillingAddressForm + +from .models import MembershipType + + +class LoginForm(LoginFormMixin): + email = forms.CharField(widget=forms.EmailInput()) + password = forms.CharField(widget=forms.PasswordInput()) + + +class SignupForm(SignupFormMixin): + confirm_password = forms.CharField(widget=forms.PasswordInput()) + password = forms.CharField(widget=forms.PasswordInput()) + name = forms.CharField(label='name', + widget=forms.TextInput(attrs={'placeholder': 'Full name'})) + + +class MembershipBillingForm(BillingAddressForm): + token = forms.CharField(widget=forms.HiddenInput()) + membership_type = forms.ModelChoiceField(queryset=MembershipType.objects.all(), + widget=forms.HiddenInput()) + + class Meta: + model = BillingAddress + fields = ['membership_type', 'street_address', 'city', 'postal_code', 'country'] + labels = { + 'street_address': _('Street Address'), + 'city': _('City'), + 'postal_code': _('Postal Code'), + 'country': _('Country'), + } diff --git a/digitalglarus/migrations/0007_auto_20160820_0408.py b/digitalglarus/migrations/0007_auto_20160820_0408.py new file mode 100644 index 00000000..0c719572 --- /dev/null +++ b/digitalglarus/migrations/0007_auto_20160820_0408.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-08-20 04:08 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('digitalglarus', '0006_delete_message'), + ] + + operations = [ + migrations.CreateModel( + name='Membership', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + ), + migrations.CreateModel( + name='MembershipOrder', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('approved', models.BooleanField(default=False)), + ('last4', models.CharField(max_length=4)), + ('cc_brand', models.CharField(max_length=10)), + ('stripe_charge_id', models.CharField(max_length=100, null=True)), + ('membership', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='digitalglarus.Membership')), + ], + ), + migrations.CreateModel( + name='MembershipType', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(choices=[('standard', 'Standard')], max_length=20)), + ('price', models.FloatField()), + ], + ), + migrations.AddField( + model_name='membership', + name='type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='digitalglarus.MembershipType'), + ), + ] diff --git a/digitalglarus/models.py b/digitalglarus/models.py index 3939dac1..612e1c02 100644 --- a/digitalglarus/models.py +++ b/digitalglarus/models.py @@ -4,6 +4,35 @@ from filer.fields.image import FilerImageField from django.core.urlresolvers import reverse +class MembershipType(models.Model): + + MEMBERSHIP_TYPES = ( + ('standard', 'Standard'), + + ) + name = models.CharField(choices=MEMBERSHIP_TYPES, max_length=20) + price = models.FloatField() + + +class Membership(models.Model): + type = models.ForeignKey(MembershipType) + + @classmethod + def create(cls, data, user): + instance = cls.objects.create(**data) + instance.assign_permissions(user) + return instance + + +class MembershipOrder(models.Model): + membership = models.ForeignKey(Membership) + created_at = models.DateTimeField(auto_now_add=True) + approved = models.BooleanField(default=False) + last4 = models.CharField(max_length=4) + cc_brand = models.CharField(max_length=10) + stripe_charge_id = models.CharField(max_length=100, null=True) + + class Supporter(models.Model): name = models.CharField(max_length=200) description = models.TextField(null=True, blank=True) @@ -16,6 +45,8 @@ class Supporter(models.Model): + + class DGGallery(models.Model): parent = models.ForeignKey('self', blank=True, null=True) name = models.CharField(max_length=30) diff --git a/digitalglarus/static/digitalglarus/css/price.css b/digitalglarus/static/digitalglarus/css/price.css new file mode 100644 index 00000000..22d37b99 --- /dev/null +++ b/digitalglarus/static/digitalglarus/css/price.css @@ -0,0 +1,622 @@ +@charset "UTF-8"; +/* CSS Document */ +#membership-includes { + text-align: center; + color: #fff; + background-attachment: scroll; + background-image: url(../img/header_bg_5.png); + background-position: center center; + background-repeat: none; + -webkit-background-size: cover; + -moz-background-size: cover; + background-size: cover; + -o-background-size: cover; +} + +.intro-headline-small{ + font-family: 'Raleway' , "Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif; + font-size: 46px; + font-style: normal; + font-weight: 200; + text-transform: none; + text-transform: uppercase; + color: #FFF; +} + + +.intro-smaller { + font-family: 'Raleway' ,'Montserrat' ,"Open Sans Bold", Helvetica, Arial, "Arial Bold", sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 100; + text-transform: none; + color: #FFF; +} +.intro-price { + padding-top: 70px; + padding-bottom: 50px; +} + +.ul{ + columns: 2; + padding: 15px 0; + font-size: 18px; + font-weight: 300; + color: #fff; + margin: 40px 0; +} +.price-list{ + background-color: transparent; + font-size: 18px; + border: 0; + padding-top: 15px; + padding-bottom: 15px; +} + +.price{ + text-transform: none; +} + +#price { + background-image: url(../img/bg-price.png); + background-position: center center; + background-repeat: none; + -webkit-background-size: cover; + -moz-background-size: cover; + background-size: cover; + -o-background-size: cover; +} +.price-box{ + padding-left: 15px; + padding-right: 15px; + padding-top: 15px; + padding-bottom: 30px; + margin-top: 80px; + margin-bottom: 30px; + margin-left: 10px; + margin-right: 10px; + color: inherit; + background-color: #fff; +} + +.graph{ + padding-top: 30px; +} + +.glyphicon-ok{ + margin-right: 0.5em; +} + +.glyphicon-plus{ + font-size: 42px; + display: block; + text-align: center; + margin: 40px auto 20px; + color: #88c7d7; +} + +.signup-container { + padding: 0; + margin: 0; + overflow-x: hidden; +} + +.greyline{ + border-color: #ddd; + border-width: 1px; + max-width: 600px; +} + +.greyline-long{ + border-color: #ddd; + border-width: 1px; + max-width: 95%; +} + +.signup-form { + padding: 2em; + padding-top: 1em; + padding-bottom: 0.1em; + margin-bottom: 0px; +} + +.signup-lead { + font-size: 16px; + line-height: 1.4em; + text-transform: none; +} + +.form-control { + margin-bottom: 1em; + border-image-source: initial; + border-image-slice: initial; + border-image-width: initial; + border-image-outset: initial; + border-image-repeat: initial; + min-height: 20px; + background: rgb(255, 255, 255); + border-width: 1px; + border-style: solid; + border-color: rgba(37, 39, 41, 0.498039); + padding: 10.5px 10px; + transition: all 0.15s ease-in-out; +} + +.notice-box { + padding-top: 1.5em; + padding-bottom: 2em; +} + +.signup-text { + color: #777; + margin: 0; + line-height: 1.5; + font-size: 13px; + text-transform: none; + font-family: "Helvetica Neue" ,"Helvetica Neue" ,"Open Sans" ,"Arial" , sans-serif; + color: #999; +} + +.signup-text a { + font-weight : 400; + margin-left: 0.5em; + color: #31708f; +} + +.signup-notice a { + font-weight : 400; + margin-left: 0.5em; + color: #31708f; +} + +.signup-box { + padding-left: 15px; + padding-right: 15px; + padding-top: 15px; + padding-bottom: 15px; + margin-top: 80px; + margin-bottom: 30px; + margin-left: 10px; + margin-right: 10px; + color: inherit; + background-color: #fff; +} + +.signup-notice { + padding-top: 0.5em; + font-size: 12px; + color: #777; +} + +.glyphicon-user{ + font-size: 42px; + display: block; + text-align: center; + margin: 40px auto 20px; + color: #88c7d7; +} + +.glyphicon-ok { + font-size: 42px; + display: block; + text-align: center; + margin-bottom: 20px; + color: #88c7d7; + margin-top: 0px; +} +} + + +.membership-amount{ + font-size: 18px; + text-align: right; + width: 100%; +} +.payment-box{ + padding-top: 3em; + padding-left: 30px; + padding-right: 30px; + padding-bottom: 15px; + margin-top: 80px; + margin-bottom: 30px; + margin-left: 10px; + margin-right: 10px; + color: inherit; + background-color: #fff; +} + +.payment-head{ + font-weight: 600; + padding-left: 15px; + text-align: left; +} + +.membership-lead { + font-size: 16px; + line-height: 1.4em; + text-transform: none; + text-align: left; + padding-left: 15px; + padding-right: 15px; + font-family: helvetica neue, helvitica, open-sans, sans-serif; + font-weight: 200; +} + +.order-name{ + font-size: 18px; + text-transform: uppercase; + margin: 0; + font-weight: 700; + padding-top: 15px; + padding-bottom: 15px; + letter-spacing: 1px; +} + +.order-person{ + text-align: right; + margin-top: 0; + margin-bottom: 15px; + font-size: 20px; + color: #494949; + text-transform: none; +} + +.order-item{ + font-size: 18px; + text-transform: none; + font-weight: 400; + text-align: left; + width: 100%; + letter-spacing: 0.1px; +} + +.order-duration { + padding-bottom: 1em; + color: #999; + font-size: 16px; + text-transform: none; + font-weight: 200; + text-align: left; + width: 100%; + margin-top: 5px; +} + +.header{ + padding: 12px 15px; + margin-bottom: 0; + border-bottom: 2px solid #f7f7f7; + background-color: #a1cfd7; +} + +.payment-total{ + font-size: 16px; + text-transform: none; + margin: 0; + font-weight: 200; + letter-spacing: 1px; +} + +.order-sum { + text-align: right; + margin-top: 0; + margin-bottom: 15px; + font-size: 20px; + color: #494949; +} +.order-result { + font-family: open-sans, montserrat, Helvetica Neue, Helvetica, sans-serif; + margin-top: 0; + margin-bottom: 15px; + font-size: 28px; + color: #494949; + text-align: right; +} + +.order-bottom-text { + padding-top: 0.5em; + color: #777; + padding-left: 15px; + font-size: 13px; +} + +.order-bottom-text a { + font-weight : 400; + margin-left: 0.5em; + color: #31708f; +} + +.order-summary { + background-color:#fff; + margin-top: 80px; +} + +.order-box{ + padding-top: 0; + padding-left: 20px; + padding-right: 20px; + padding-bottom: 15px; + margin-top: 0; + margin-bottom: 30px; + margin-left: 10px; + margin-right: 10px; + color: inherit; + background-color: #fff; +} + +.billing-head { + padding-left: 15px; + margin-top: 0px; + margin-bottom: 0px; + font-weight: 400; + font-size: 21px; + text-align: left; + text-transform: none; +} + +.reset-head { + padding-left: 15px; + margin-top: 0px; + margin-bottom: 0px; + font-weight: 400; + font-size: 24px; + text-align: left; + text-transform: none; +} + +.form-control { + color: #999; + border-radius: 0px; + box-shadow: none; +} + +.custom-control-description { + color: #999; + font-weight: 300; + font-family: "helvetica neue", "helvetica", "sans-serif" ; + letter-spacing: 0.5px; + font-size: 12px; + line-height: 1; +} + +.custom-control-description a { + color: #31708f; +} + +.custom-control { + text-align: left; +} + +.button-box { + margin-top: 20px; +} + +.date-box { + padding-top: 1.5em; + padding-bottom: 0.5em; +} + +.date-oneline { + font-size: 16px; + text-transform: none; + margin: 0; + font-weight: 400; + letter-spacing: 1px; + color: #555; +} + +.btn-grey { + background-color: #b2b7b9;; + border-color: #b2b7b9;; +} + +.btn-grey:hover, +.btn-grey:focus, +.btn-grey:active, +.btn-grey.active, +.open .dropdown-toggle.btn-grey { + text-transform: uppercase; + font-weight: 400; + border-color: #ddd; + color: #fff; + background-color: #ddd; +} + +.btn-blue:hover, +.btn-blue:focus, +.btn-blue:active, +.btn-blue.active, +.open .dropdown-toggle.btn-grey { + background-color: #5699b9; + border-color: #5699b9; +} + +.loggedin-head { + padding-left: 15px; + margin-top: 0px; + margin-bottom: 0px; + font-weight: 400; + font-size: 21px; + text-align: center; + text-transform: none; + padding-top: 10px; +} + +.loggedin-lead { + font-size: 16px; + line-height: 1.4em; + text-transform: none; + text-align: center; + padding-left: 15px; + padding-right: 15px; + font-family: helvetica neue, helvitica, open-sans, sans-serif; + font-weight: 200; +} + +.activation-lead { + font-size: 15px; + line-height: 1.4em; + text-transform: none; + text-align: center; + padding-left: 15px; + padding-right: 15px; + padding-bottom: 0; + font-family: helvetica neue, helvitica, open-sans, sans-serif; + font-weight: 200; + color: #777; +} + +.button-booking-box { + margin-top: 0; +} + +.member-name{ + font-size: 16px; + text-transform: none; + font-weight: 400; + text-align: left; + width: 100%; + letter-spacing: 0.1px; + text-align: left; + padding-left: 15px; + line-height: 0.35em; +} + +.history-name{ + font-size: 16px; + text-transform: none; + font-weight: 400; + text-align: left; + width: 100%; + letter-spacing: 0.1px; + text-align: left; + padding-left: 15px; + line-height: 1.4em; +} + +.button-center-box { + margin-top: 20px; + text-align: center; +} + +.table td, .table th { + padding: .75rem; + vertical-align: top; + border-top: 1px solid #eceeef; +} + +.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td { + padding: .75rem; + vertical-align: top; + border-top: 1px solid #eceeef; + border-bottom: 1px solid #eceeef; + color: #777; + +} + +.table{ + margin-top: 1em; +} + +.order-head { + font-size: 18px; + text-transform: uppercase; + margin: 0; + font-weight: 900; + padding-top: 15px; + letter-spacing: 1px; + text-align: left; + padding-left: 15px; + color: #88c7d7; +} + +th { + text-align: center; +} + +.table td { + color: #999; +} + +.btn-edit { + font-size: 10px; + padding-left: 8px; + padding-right: 8px; + padding-top: 2px; + padding-bottom: 2px; + background-color: #b2b7b9; + border-color: #b2b7b9; + color: #fff; + font-weight: 200; + margin-left: 1em; +} + +.edit-button { + text-align:left; + padding-left: 15px; + padding-top: 10px; +} + +.btn-deactivate { + font-size: 11px; + padding-left: 10px; + padding-right: 10px; + padding-top: 4px; + padding-bottom: 4px; + + color: #fff; + font-weight: 200; +} + +.btn-darkgrey { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: 400; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; + background-color: #777; + border-color: #777; + text-transform: none; +} + +.btn-darkgrey:hover, +.btn-darkgrey:focus, +.btn-darkgrey:active, +.btn-darkgrey.active, +.open .dropdown-toggle.btn-darkgrey { + text-transform: none; + font-weight: 400; + border-color: #88c7d7; + color: #fff; + background-color: #88c7d7; +} + +.thankyou { + + font-size: 30px; + text-align: center; + padding-top: 45px; + +} + +.icon-up{ + margin-top: 30px; +} + +.price-exp-box { + padding-left: 15px; + padding-right: 15px; + padding-top: 15px; + padding-bottom: 0px; + margin-top: 0px; + margin-bottom: 30px; + margin-left: 10px; + margin-right: 10px; + color: inherit; + background-color: #fff; + text-align: left; +} \ No newline at end of file diff --git a/digitalglarus/static/digitalglarus/img/bg-price.png b/digitalglarus/static/digitalglarus/img/bg-price.png new file mode 100644 index 00000000..f4597723 Binary files /dev/null and b/digitalglarus/static/digitalglarus/img/bg-price.png differ diff --git a/digitalglarus/static/digitalglarus/img/graph.png b/digitalglarus/static/digitalglarus/img/graph.png new file mode 100644 index 00000000..74ab22a8 Binary files /dev/null and b/digitalglarus/static/digitalglarus/img/graph.png differ diff --git a/digitalglarus/static/digitalglarus/img/header_bg_5.png b/digitalglarus/static/digitalglarus/img/header_bg_5.png new file mode 100644 index 00000000..063b1642 Binary files /dev/null and b/digitalglarus/static/digitalglarus/img/header_bg_5.png differ diff --git a/digitalglarus/static/digitalglarus/js/payment.js b/digitalglarus/static/digitalglarus/js/payment.js new file mode 100644 index 00000000..dd6c64d4 --- /dev/null +++ b/digitalglarus/static/digitalglarus/js/payment.js @@ -0,0 +1,124 @@ +$( document ).ready(function() { + + $.ajaxSetup({ + beforeSend: function(xhr, settings) { + function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) { + // Only send the token to relative URLs i.e. locally. + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + } + } + }); + + + var $form = $('#payment-form'); + $form.submit(payWithStripe); + + /* If you're using Stripe for payments */ + function payWithStripe(e) { + e.preventDefault(); + + /* Visual feedback */ + $form.find('[type=submit]').html('Validating '); + + var PublishableKey = window.stripeKey; + Stripe.setPublishableKey(PublishableKey); + Stripe.card.createToken($form, function stripeResponseHandler(status, response) { + if (response.error) { + /* Visual feedback */ + $form.find('[type=submit]').html('Try again'); + /* Show Stripe errors on the form */ + $form.find('.payment-errors').text(response.error.message); + $form.find('.payment-errors').closest('.row').show(); + } else { + /* Visual feedback */ + $form.find('[type=submit]').html('Processing '); + /* Hide Stripe errors on the form */ + $form.find('.payment-errors').closest('.row').hide(); + $form.find('.payment-errors').text(""); + // response contains id and card, which contains additional card details + var token = response.id; + // AJAX + + //set token on a hidden input + $('#id_token').val(token); + $('#billing-form').submit(); + } + }); + } + + /* Form validation */ + $.validator.addMethod("month", function(value, element) { + return this.optional(element) || /^(01|02|03|04|05|06|07|08|09|10|11|12)$/.test(value); + }, "Please specify a valid 2-digit month."); + + $.validator.addMethod("year", function(value, element) { + return this.optional(element) || /^[0-9]{2}$/.test(value); + }, "Please specify a valid 2-digit year."); + + validator = $form.validate({ + rules: { + cardNumber: { + required: true, + creditcard: true, + digits: true + }, + expMonth: { + required: true, + month: true + }, + expYear: { + required: true, + year: true + }, + cvCode: { + required: true, + digits: true + } + }, + highlight: function(element) { + $(element).closest('.form-control').removeClass('success').addClass('error'); + }, + unhighlight: function(element) { + $(element).closest('.form-control').removeClass('error').addClass('success'); + }, + errorPlacement: function(error, element) { + $(element).closest('.form-group').append(error); + } + }); + + paymentFormReady = function() { + if ($form.find('[name=cardNumber]').hasClass("success") && + $form.find('[name=expMonth]').hasClass("success") && + $form.find('[name=expYear]').hasClass("success") && + $form.find('[name=cvCode]').val().length > 1) { + return true; + } else { + return false; + } + } + + $form.find('[type=submit]').prop('disabled', true); + var readyInterval = setInterval(function() { + if (paymentFormReady()) { + $form.find('[type=submit]').prop('disabled', false); + clearInterval(readyInterval); + } + }, 250); + +}); + diff --git a/digitalglarus/templates/digitalglarus/confirm_reset_password.html b/digitalglarus/templates/digitalglarus/confirm_reset_password.html new file mode 100644 index 00000000..40a93730 --- /dev/null +++ b/digitalglarus/templates/digitalglarus/confirm_reset_password.html @@ -0,0 +1,55 @@ +{% extends "new_base_glarus.html" %} +{% load staticfiles cms_tags bootstrap3%} +{% block title %}crowdfunding{% endblock %} + +{% block content %} + +
+
+
+
+
+

Set your new password

+
+ + + +
+
+
+
+
+ +
+
+
+
+
+ Digital Glarus
+ In der Au 7 Schwanden 8762 Switzerland +
info@digitalglarus.ch +
+ (044) 534-66-22 +

 

+
+
+

 

+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/digitalglarus/templates/digitalglarus/emails/password_reset_email.html b/digitalglarus/templates/digitalglarus/emails/password_reset_email.html new file mode 100644 index 00000000..20244b11 --- /dev/null +++ b/digitalglarus/templates/digitalglarus/emails/password_reset_email.html @@ -0,0 +1,13 @@ +{% load i18n %}{% autoescape off %} +{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %} + +{% trans "Please go to the following page and choose a new password:" %} + {% block reset_link %} + {{ base_url }}{% url 'digitalglarus:reset_password_confirm' uidb64=uid token=token %} + {% endblock %} + +{% trans "Thanks for using our site!" %} + +{% blocktrans %}The {{ site_name }} team{% endblocktrans %} + +{% endautoescape %} \ No newline at end of file diff --git a/digitalglarus/templates/digitalglarus/emails/password_reset_email.txt b/digitalglarus/templates/digitalglarus/emails/password_reset_email.txt new file mode 100644 index 00000000..20244b11 --- /dev/null +++ b/digitalglarus/templates/digitalglarus/emails/password_reset_email.txt @@ -0,0 +1,13 @@ +{% load i18n %}{% autoescape off %} +{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %} + +{% trans "Please go to the following page and choose a new password:" %} + {% block reset_link %} + {{ base_url }}{% url 'digitalglarus:reset_password_confirm' uidb64=uid token=token %} + {% endblock %} + +{% trans "Thanks for using our site!" %} + +{% blocktrans %}The {{ site_name }} team{% endblocktrans %} + +{% endautoescape %} \ No newline at end of file diff --git a/digitalglarus/templates/digitalglarus/login.html b/digitalglarus/templates/digitalglarus/login.html new file mode 100644 index 00000000..a3cc6b67 --- /dev/null +++ b/digitalglarus/templates/digitalglarus/login.html @@ -0,0 +1,78 @@ +{% extends "new_base_glarus.html" %} +{% load staticfiles bootstrap3 i18n %} +{% block content %} + + +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ Digital Glarus
+ In der Au 7 Schwanden 8762 Switzerland +
info@digitalglarus.ch +
+ (044) 534-66-22 +

 

+
+
+

 

+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/digitalglarus/templates/digitalglarus/membership_payment.html b/digitalglarus/templates/digitalglarus/membership_payment.html new file mode 100644 index 00000000..0345bda0 --- /dev/null +++ b/digitalglarus/templates/digitalglarus/membership_payment.html @@ -0,0 +1,177 @@ +{% extends "new_base_glarus.html" %} +{% load staticfiles bootstrap3 i18n %} +{% block content %} + + + +
+
+
+
+

Membership

+ +

Your Digital Glarus Membership enables + you to use our coworking space and it includes + 2 working days for the month you signed up. + The membership fee is a monthly subscription. + Additional day costs + 15CHF per day. More than 17 days a month it + will charge only 290CHF/month.

+
+

Member Name

+

Nico Schottelius

+
+

Billing Adress

+ +

Credit Card

+ +
+
+
+
+
+

Order Summary

+
+
+

Digital Glarus Membership

+
+

valid 2016.09.08 - 2016.10.08

+

1 person

+

Today's Total

+

0.00CHF

+
+

Total

+

35CHF

+
+ +
+ +
+ +
+

You can checkout on the next page

+
+
+
+
+
+
+ + + +
+ + + +
+
+
+
+
+ Digital Glarus
+ In der Au 7 Schwanden 8762 Switzerland +
info@digitalglarus.ch +
+ (044) 534-66-22 +

 

+
+
+

 

+
+
+
+
+ + +{% if stripe_key %} + + +{%endif%} + +{% endblock %} \ No newline at end of file diff --git a/digitalglarus/templates/digitalglarus/reset_password.html b/digitalglarus/templates/digitalglarus/reset_password.html new file mode 100644 index 00000000..265248fd --- /dev/null +++ b/digitalglarus/templates/digitalglarus/reset_password.html @@ -0,0 +1,57 @@ +{% extends "new_base_glarus.html" %} +{% load staticfiles cms_tags bootstrap3%} +{% block title %}crowdfunding{% endblock %} + +{% block content %} + +
+
+
+
+
+

Reset Password

+
+

To have your password reset, enter your email address below. + We will then send an email containing a link to reset your password.

+ + + +
+
+
+
+
+ +
+
+
+
+
+ Digital Glarus
+ In der Au 7 Schwanden 8762 Switzerland +
info@digitalglarus.ch +
+ (044) 534-66-22 +

 

+
+
+

 

+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/digitalglarus/templates/digitalglarus/signup.html b/digitalglarus/templates/digitalglarus/signup.html new file mode 100644 index 00000000..1eb00dda --- /dev/null +++ b/digitalglarus/templates/digitalglarus/signup.html @@ -0,0 +1,59 @@ +{% extends "new_base_glarus.html" %} +{% load staticfiles cms_tags bootstrap3%} +{% block title %}crowdfunding{% endblock %} + +{% block content %} + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ Digital Glarus
+ In der Au 7 Schwanden 8762 Switzerland +
info@digitalglarus.ch +
+ (044) 534-66-22 +

 

+
+
+

 

+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/digitalglarus/templates/new_base_glarus.html b/digitalglarus/templates/new_base_glarus.html index 48a65457..74bcaf1d 100644 --- a/digitalglarus/templates/new_base_glarus.html +++ b/digitalglarus/templates/new_base_glarus.html @@ -1,6 +1,5 @@ {% load static %} -{% load bootstrap3 %} -{% load staticfiles cms_tags menu_tags sekizai_tags menu_tags %} +{% load staticfiles cms_tags menu_tags sekizai_tags menu_tags bootstrap3 %} {% load i18n %} @@ -25,6 +24,7 @@ + @@ -135,16 +135,25 @@ - + + + + + + + + + + @@ -156,6 +165,8 @@ + + diff --git a/digitalglarus/urls.py b/digitalglarus/urls.py index 26f606a8..88e1ba75 100644 --- a/digitalglarus/urls.py +++ b/digitalglarus/urls.py @@ -2,14 +2,20 @@ from django.conf.urls import url from django.utils.translation import ugettext_lazy as _ from . import views -from .views import ContactView, IndexView, AboutView, HistoryView -from membership.views import LoginRegistrationView +from .views import ContactView, IndexView, AboutView, HistoryView, LoginView, SignupView,\ + PasswordResetView, PasswordResetConfirmView, MembershipPaymentView +# from membership.views import LoginRegistrationView urlpatterns = [ url(_(r'^$'), IndexView.as_view(), name='landing'), url(_(r'contact/?$'), ContactView.as_view(), name='contact'), - url(_(r'login/?$'), LoginRegistrationView.as_view(), name='login'), + url(_(r'login/?$'), LoginView.as_view(), name='login'), + url(_(r'signup/?$'), SignupView.as_view(), name='signup'), + url(r'reset-password/?$', PasswordResetView.as_view(), name='reset_password'), + url(r'reset-password-confirm/(?P[0-9A-Za-z]+)-(?P.+)/$', + PasswordResetConfirmView.as_view(), name='reset_password_confirm'), url(_(r'history/?$'), HistoryView.as_view(), name='history'), + url(_(r'membership/payment?$'), MembershipPaymentView.as_view(), name='membership_payment'), url(_(r'supporters/?$'), views.supporters, name='supporters'), url(r'calendar_api/(?P\d+)/(?P\d+)?$', views.CalendarApi.as_view(),name='calendar_api_1'), url(r'calendar_api/', views.CalendarApi.as_view(),name='calendar_api'), diff --git a/digitalglarus/views.py b/digitalglarus/views.py index c8cbf336..00d3f87e 100644 --- a/digitalglarus/views.py +++ b/digitalglarus/views.py @@ -1,11 +1,14 @@ +import json import datetime +from django.conf import settings from django.shortcuts import get_object_or_404, render from django.forms import ModelForm from django.http import HttpResponseRedirect -from django.core.urlresolvers import reverse_lazy +from django.core.urlresolvers import reverse_lazy, reverse from django.utils.translation import ugettext_lazy as _ from django.views.generic import TemplateView +from django.contrib.auth.mixins import LoginRequiredMixin from django.utils.translation import get_language from djangocms_blog.models import Post from django.contrib import messages @@ -16,11 +19,117 @@ from .models import Supporter from utils.forms import ContactUsForm from django.views.generic.edit import FormView from membership.calendar.calendar import BookCalendar -from membership.models import Calendar as CalendarModel -import json -from django.contrib.auth import logout +from membership.models import Calendar as CalendarModel, CustomUser, StripeCustomer +from utils.views import LoginViewMixin, SignupViewMixin, \ + PasswordResetViewMixin, PasswordResetConfirmViewMixin +from utils.forms import PasswordResetRequestForm +from utils.stripe_utils import StripeUtils + + +from .forms import LoginForm, SignupForm, MembershipBillingForm +from .models import MembershipType + + +class IndexView(TemplateView): + template_name = "digitalglarus/old_index.html" + + +class LoginView(LoginViewMixin): + template_name = "digitalglarus/login.html" + form_class = LoginForm + success_url = reverse_lazy('digitalglarus:landing') + + +class SignupView(SignupViewMixin): + template_name = "digitalglarus/signup.html" + form_class = SignupForm + success_url = reverse_lazy('digitalglarus:login') + + +class PasswordResetView(PasswordResetViewMixin): + template_name = 'digitalglarus/reset_password.html' + success_url = reverse_lazy('digitalglarus:login') + form_class = PasswordResetRequestForm + template_email_path = 'digitalglarus/emails/' + + +class PasswordResetConfirmView(PasswordResetConfirmViewMixin): + template_name = 'digitalglarus/confirm_reset_password.html' + success_url = reverse_lazy('digitalglarus:login') + + +class HistoryView(TemplateView): + template_name = "digitalglarus/history.html" + + def get_context_data(self, **kwargs): + context = super(HistoryView, self).get_context_data(**kwargs) + supporters = Supporter.objects.all() + context.update({ + 'supporters': supporters + }) + return context + + +class MembershipPaymentView(LoginRequiredMixin, FormView): + template_name = "digitalglarus/membership_payment.html" + login_url = reverse_lazy('digitalglarus:login') + form_class = MembershipBillingForm + + def get_form_kwargs(self): + membership_type = MembershipType.objects.get(name='standard') + form_kwargs = super(MembershipPaymentView, self).get_form_kwargs() + form_kwargs.update({ + 'initial': {'membership_type': membership_type.id} + }) + return form_kwargs + + def get_context_data(self, **kwargs): + context = super(MembershipPaymentView, self).get_context_data(**kwargs) + context.update({ + 'stripe_key': settings.STRIPE_API_PUBLIC_KEY + }) + return context + + def post(self, request, *args, **kwargs): + import pdb;pdb.set_trace() + form = self.get_form() + + if form.is_valid(): + data = form.cleaned_data + context = self.get_context_data() + token = data.get('token') + membership_type = data.get('membership_type') + + # Get or create stripe customer + customer = StripeCustomer.get_or_create(email=self.request.user.email, + token=token) + if not customer: + form.add_error("__all__", "Invalid credit card") + return self.render_to_response(self.get_context_data(form=form)) + + # Make stripe charge to a customer + stripe_utils = StripeUtils() + charge_response = stripe_utils.make_charge(amount=membership_type.price, + customer=customer.stripe_id) + charge = charge_response.get('response_object') + + # Check if the payment was approved + if not charge: + context.update({ + 'paymentError': charge_response.get('error'), + 'form': form + }) + return render(request, self.template_name, context) + + charge = charge_response.get('response_object') + else: + return self.form_invalid(form) + + + +############## OLD VIEWS class CalendarApi(View): def get(self,request,month,year): calendar = BookCalendar(request.user,requested_month=month).formatmonth(int(year),int(month)) @@ -46,21 +155,6 @@ class ContactView(FormView): return super(ContactView, self).form_valid(form) -class IndexView(TemplateView): - template_name = "digitalglarus/old_index.html" - - -class HistoryView(TemplateView): - template_name = "digitalglarus/history.html" - - def get_context_data(self, **kwargs): - context = super(HistoryView, self).get_context_data(**kwargs) - supporters = Supporter.objects.all() - context.update({ - 'supporters': supporters - }) - return context - class AboutView(TemplateView): template_name = "digitalglarus/about.html" diff --git a/hosting/static/hosting/js/payment.js b/hosting/static/hosting/js/payment.js index c431f7ce..dd6c64d4 100644 --- a/hosting/static/hosting/js/payment.js +++ b/hosting/static/hosting/js/payment.js @@ -56,7 +56,7 @@ $( document ).ready(function() { //set token on a hidden input $('#id_token').val(token); - $('#donation-form').submit(); + $('#billing-form').submit(); } }); } diff --git a/hosting/views.py b/hosting/views.py index 1a6cbeb8..6b21c91b 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -17,7 +17,7 @@ from stored_messages.api import mark_read from membership.models import CustomUser, StripeCustomer from utils.stripe_utils import StripeUtils from utils.forms import BillingAddressForm, PasswordResetRequestForm -from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin +from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin from utils.mailer import BaseEmail from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder from .forms import HostingUserSignupForm, HostingUserLoginForm @@ -137,31 +137,10 @@ class IndexView(View): return render(request, self.template_name, context) -class LoginView(FormView): - template_name = 'hosting/login.html' - success_url = reverse_lazy('hosting:orders') +class LoginView(LoginViewMixin): + template_name = "hosting/login.html" form_class = HostingUserLoginForm - moodel = CustomUser - - def get_success_url(self): - next_url = self.request.session.get('next', self.success_url) - return next_url - - def form_valid(self, form): - email = form.cleaned_data.get('email') - password = form.cleaned_data.get('password') - auth_user = authenticate(email=email, password=password) - - if auth_user: - login(self.request, auth_user) - return HttpResponseRedirect(self.get_success_url()) - - return HttpResponseRedirect(self.get_success_url()) - - def get(self, request, *args, **kwargs): - if self.request.user.is_authenticated(): - return HttpResponseRedirect(reverse('hosting:notifications')) - return super(LoginView, self).get(request, *args, **kwargs) + success_url = reverse_lazy('hosting:orders') class SignupView(CreateView): @@ -196,32 +175,6 @@ class PasswordResetConfirmView(PasswordResetConfirmViewMixin): template_name = 'hosting/confirm_reset_password.html' success_url = reverse_lazy('hosting:login') - # def post(self, request, uidb64=None, token=None, *arg, **kwargs): - # try: - # uid = urlsafe_base64_decode(uidb64) - # user = CustomUser.objects.get(pk=uid) - # except (TypeError, ValueError, OverflowError, CustomUser.DoesNotExist): - # user = None - - # form = self.form_class(request.POST) - - # if user is not None and default_token_generator.check_token(user, token): - # if form.is_valid(): - # new_password = form.cleaned_data['new_password2'] - # user.set_password(new_password) - # user.save() - # messages.success(request, 'Password has been reset.') - # return self.form_valid(form) - # else: - # messages.error(request, 'Password reset has not been unsuccessful.') - # form.add_error(None, 'Password reset has not been unsuccessful.') - # return self.form_invalid(form) - - # else: - # messages.error(request, 'The reset password link is no longer valid.') - # form.add_error(None, 'Password reset has not been unsuccessful.') - # return self.form_invalid(form) - class NotificationsView(LoginRequiredMixin, TemplateView): template_name = 'hosting/notifications.html' diff --git a/membership/templates/login.html b/membership/templates/login.html index d1f4172c..75545873 100644 --- a/membership/templates/login.html +++ b/membership/templates/login.html @@ -4,19 +4,6 @@ {% block content %} - -