From cb51e08cefff960a48bfae1e1702ecdccb0bb868 Mon Sep 17 00:00:00 2001 From: Levi Date: Tue, 19 Apr 2016 01:04:15 -0500 Subject: [PATCH] Added serializer to VM model, Rewrite django hosting view , Created price selection templates , Added price selector with automatic price change --- hosting/models.py | 18 ++- hosting/static/hosting/css/pricing.css | 95 +++++++++++++ hosting/static/hosting/js/pricing.js | 58 ++++++++ hosting/templates/hosting/base.html | 26 +++- hosting/templates/hosting/pricing.html | 186 +++++++++++++++++++++++++ hosting/urls.py | 4 +- hosting/views.py | 30 +++- 7 files changed, 412 insertions(+), 5 deletions(-) create mode 100644 hosting/static/hosting/css/pricing.css create mode 100644 hosting/static/hosting/js/pricing.js create mode 100644 hosting/templates/hosting/pricing.html diff --git a/hosting/models.py b/hosting/models.py index e66dbe28..ba38219a 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -1,6 +1,7 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from django.core import serializers +import json class RailsBetaUser(models.Model): @@ -37,5 +38,20 @@ class VirtualMachineType(models.Model): def __str__(self): return "%s" % (self.get_hosting_company_display()) + @classmethod + def get_serialized_vm_types(cls): + return [vm.get_serialized_data() + for vm in cls.objects.all()] + # return serializers.serialize("json",) + def get_serialized_data(self): - return serializers("json", self) + return { + 'description': self.description, + 'base_price': self.base_price, + 'core_price': self.core_price, + 'disk_size_price': self.disk_size_price, + 'memory_price': self.memory_price, + 'hosting_company_name': self.get_hosting_company_display(), + 'hosting_company': self.hosting_company, + 'id': self.id, + } diff --git a/hosting/static/hosting/css/pricing.css b/hosting/static/hosting/css/pricing.css new file mode 100644 index 00000000..870b3cf9 --- /dev/null +++ b/hosting/static/hosting/css/pricing.css @@ -0,0 +1,95 @@ +.pricing { + text-align: center; + border: 1px solid #f0f0f0; + color: #777; + font-size: 14px; + padding-left: 0; + margin-bottom: 30px; + font-family: 'Lato'; +} +.pricing img { + display: block; + margin: auto; + width: 32px; +} +.pricing li:first-child, +.pricing li:last-child { + padding: 20px 13px; +} +.pricing li { + list-style: none; + padding: 13px; +} +.pricing li + li { + border-top: 1px solid #f0f0f0; +} +.pricing big { + font-size: 32px; +} +.pricing h3 { + margin-bottom: 0; + font-size: 36px; +} +.pricing span { + font-size: 12px; + color: #999; + font-weight: normal; +} +.pricing li:nth-last-child(2) { + padding: 30px 13px; +} +.pricing button { + width: auto; + margin: auto; + font-size: 15px; + font-weight: bold; + border-radius: 50px; + color: #fff; + padding: 9px 24px; + background: #aaa; + opacity: 1; + transition: opacity .2s ease; + border: none; + outline: none; +} +.pricing button:hover { + opacity: .9; +} +.pricing button:active { + box-shadow: inset 0px 2px 2px rgba(0, 0, 0, 0.1); +} +/* pricing color */ +.p-green big, +.p-green h3 { + color: #4c7737; +} +.p-green button { + background: #4c7737; +} +.p-yel big, +.p-yel h3 { + color: #ffbb42; +} +.p-yel button { + background: #ffbb42; +} +.p-red big, +.p-red h3 { + color: #e13c4c; +} + +.pricing .short-input{ + min-width: 0; + width: 90px; +} + +.p-red button { + background: #e13c4c; +} +.p-blue big, +.p-blue h3 { + color: #3f4bb8; +} +.p-blue button { + background: #3f4bb8; +} \ No newline at end of file diff --git a/hosting/static/hosting/js/pricing.js b/hosting/static/hosting/js/pricing.js new file mode 100644 index 00000000..667239ab --- /dev/null +++ b/hosting/static/hosting/js/pricing.js @@ -0,0 +1,58 @@ +$( document ).ready(function() { + + //we need to load first VMTypesData from base.html django template + var pricingData = window.VMTypesData; + + + // Function to calculate the price given a vm type + function calculate_price(vm_type){ + + var ID_SELECTOR = "#"; + var CURRENCY = "$"; + var final_price_selector = ID_SELECTOR.concat(vm_type.concat('-final-price')); + var core_selector = ID_SELECTOR.concat(vm_type.concat('-cores')); + var memory_selector = ID_SELECTOR.concat(vm_type.concat('-memory')); + var disk_size_selector = ID_SELECTOR.concat(vm_type.concat('-disk_space')); + + //Get vm type prices + var cores = $(core_selector).val(); + var memory = $(memory_selector).val(); + var disk_size = $(disk_size_selector).val(); + var pricingData = eval(window.VMTypesData); + var company_prices = _.head(_.filter(pricingData, {hosting_company: vm_type})); + + //Calculate final price + var price = company_prices.base_price; + price += company_prices.core_price*cores; + price += company_prices.memory_price*memory; + price += company_prices.disk_size_price*disk_size; + + console.log(final_price_selector); + $(final_price_selector).text(price.toString().concat(CURRENCY)); + + + + + + + } + + //Listener function + function change_attribute(e){ + + var vm_type = this.getAttribute('data-vm-type'); + calculate_price(vm_type); + } + + + //Listeners + $('.cores-selector').on('change',change_attribute); + + $('.memory-selector').on('change',change_attribute); + + $('.disk-space-selector').on('change',change_attribute); + + console.log("mirame",window.VMTypesData); + + +}); \ No newline at end of file diff --git a/hosting/templates/hosting/base.html b/hosting/templates/hosting/base.html index d0d567c1..4c80530a 100644 --- a/hosting/templates/hosting/base.html +++ b/hosting/templates/hosting/base.html @@ -13,12 +13,17 @@ {{ domain }} - {{ hosting }} hosting as easy as possible + + + + + @@ -215,7 +220,9 @@
-
+ {% include "hosting/pricing.html" %} + +
@@ -384,9 +391,24 @@ + + {% if vm_types %} + + {%endif%} + + + + + + + + + diff --git a/hosting/templates/hosting/pricing.html b/hosting/templates/hosting/pricing.html new file mode 100644 index 00000000..95e8cc83 --- /dev/null +++ b/hosting/templates/hosting/pricing.html @@ -0,0 +1,186 @@ +
+
+ + {% for vm in vm_types %} +
+
+
+
+ + + {{vm.hosting_company_name}} + + +

+ {{vm.description}} +

+
+
+
+
+ + +
+
+
+ +
+ + + GiB +
+
+
+ + + GiB +
+
+

$199

+
+
+ +
+ + + + + +
+
+ {% endfor %} + {% for vm in vm_types %} +
+
+
    +
  • + +

    {{vm.hosting_company_name}}

    +
  • +
  • + +
    +
    + + +
    +
    + +
  • +
  • +
    +
    + + + GiB +
    +
    +
  • +
  • +
    + + + GiB +
    +
  • +
  • +

    select

    + per month +
  • +
  • + +
  • +
+
+
+ {% endfor %} + + + + + +
+
diff --git a/hosting/urls.py b/hosting/urls.py index 105c0ce9..ee79deb9 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -1,10 +1,12 @@ from django.conf.urls import url from . import views +from .views import VMPricingView, DjangoHostingView urlpatterns = [ url(r'beta$', views.beta, name='beta'), - url(r'django$', views.djangohosting, name='djangohosting'), + url(r'pricing/?$', VMPricingView.as_view(), name='pricing'), + url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'), url(r'nodejs$', views.nodejshosting, name='nodejshosting'), url(r'rails$', views.railshosting, name='railshosting'), ] diff --git a/hosting/views.py b/hosting/views.py index fc687b60..7bbb2b85 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -7,8 +7,36 @@ from django.core.urlresolvers import reverse from django.core.mail import send_mail from django.core.mail import mail_managers +from django.views.generic import View, DetailView + + +from .models import RailsBetaUser, VirtualMachineType + + +class VMPricingView(View): + template_name = "hosting/pricing.html" + + def get(self, request, *args, **kwargs): + return render(request, self.template_name, request) + + +class DjangoHostingView(View): + template_name = "hosting/django.html" + + def get_context_data(self, **kwargs): + context = {} + context["hosting"] = "django" + context["hosting_long"] = "Django" + context["domain"] = "django-hosting.ch" + context["google_analytics"] = "UA-62285904-6" + context["email"] = "info@django-hosting.ch" + context["vm_types"] = VirtualMachineType.get_serialized_vm_types() + return context + + def get(self, request, *args, **kwargs): + context = self.get_context_data() + return render(request, self.template_name, context) -from .models import RailsBetaUser class RailsBetaUserForm(ModelForm): required_css_class = 'form-control'