diff --git a/Changelog b/Changelog index 6d1dfd5d..1f5b70e6 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,8 @@ +1.1.1: 2017-08-29 + * #3709: [datacenterlight] Added faq tos cms template + * #3657: [datacenterlight] Added a new contact section at landing + * #3740: [datacenterlight] Made contact section to send email to info when user submits a message + * #3757: [datacenterlight] Added new routes to dcl 1.1: 2017-08-24 * #3637: [datacenterlight, hosting] Added Stripe error handler * #3695: [hosting] Applied new design for VM list in hosting diff --git a/datacenterlight/forms.py b/datacenterlight/forms.py index 33d95c29..3ffe403c 100644 --- a/datacenterlight/forms.py +++ b/datacenterlight/forms.py @@ -1,6 +1,6 @@ from django import forms -from .models import BetaAccess +from .models import BetaAccess, ContactUs class BetaAccessForm(forms.ModelForm): @@ -11,6 +11,13 @@ class BetaAccessForm(forms.ModelForm): model = BetaAccess +class ContactForm(forms.ModelForm): + + class Meta: + fields = ['name', 'email', 'message'] + model = ContactUs + + # class BetaAccessVMForm(forms.ModelForm): # type = forms.CharField(widget=forms.EmailInput()) diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 3853d4e3..c0dc55ca 100644 --- a/datacenterlight/locale/de/LC_MESSAGES/django.po +++ b/datacenterlight/locale/de/LC_MESSAGES/django.po @@ -82,6 +82,24 @@ msgstr "Bitte gib eine gültige E-Mailadresse ein." msgid "Continue" msgstr "Weiter" +msgid "Thank you for contacting us." +msgstr "Nachricht gesendet." + +msgid "Your message was successfully sent to our team." +msgstr "Vielen Dank für Deine Nachricht." + +msgid "Get in touch with us!" +msgstr "Sende uns eine Nachricht." + +msgid "Message" +msgstr "Nachricht" + +msgid "Sorry, there was an unexpected error. Kindly retry." +msgstr "Bitte entschuldige, es scheint ein unerwarteter Fehler aufgetreten zu sein. Versuche es doch bitte noch einmal." + +msgid "SUBMIT" +msgstr "ABSENDEN" + msgid "Thank you for your request." msgstr "Vielen Dank für Ihre Anfrage." @@ -234,15 +252,12 @@ msgstr "" msgid "Affordable VM hosting based in Switzerland" msgstr "Bezahlbares VM Hosting in der Schweiz" +msgid "Contact us" +msgstr "Kontaktiere uns" + msgid "Switzerland " msgstr "Schweiz" -msgid "Questions?" -msgstr "Fragen?" - -msgid "Contact us!" -msgstr "Kontaktiere uns!" - msgid "Confirm Order" msgstr "Bestellung Bestätigen" @@ -412,6 +427,9 @@ msgstr "ist kein gültiger Name" msgid "is not a proper email" msgstr "ist keine gültige E-Mailadresse" +#~ msgid "Questions?" +#~ msgstr "Fragen?" + #~ msgid "Please enter a value greater than or equal to 1." #~ msgstr "Bitte gib einen Wert größer oder gleich 1 ein." diff --git a/datacenterlight/migrations/0007_contactus.py b/datacenterlight/migrations/0007_contactus.py new file mode 100644 index 00000000..12af594c --- /dev/null +++ b/datacenterlight/migrations/0007_contactus.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-08-19 21:08 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('datacenterlight', '0006_vmtemplate'), + ] + + operations = [ + migrations.CreateModel( + name='ContactUs', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=250)), + ('email', models.CharField(max_length=250)), + ('message', models.TextField()), + ], + ), + ] diff --git a/datacenterlight/migrations/0008_contactus_field.py b/datacenterlight/migrations/0008_contactus_field.py new file mode 100644 index 00000000..ceea8f8f --- /dev/null +++ b/datacenterlight/migrations/0008_contactus_field.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-08-23 13:06 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ('datacenterlight', '0007_contactus'), + ] + + operations = [ + migrations.AddField( + model_name='contactus', + name='field', + field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2017, 8, 23, 13, 6, 24, 650869, tzinfo=utc)), + preserve_default=False, + ), + ] diff --git a/datacenterlight/migrations/0009_merge.py b/datacenterlight/migrations/0009_merge.py new file mode 100644 index 00000000..1f5d5bad --- /dev/null +++ b/datacenterlight/migrations/0009_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-08-27 07:55 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('datacenterlight', '0007_contactus'), + ('datacenterlight', '0008_auto_20170821_2024'), + ] + + operations = [ + ] diff --git a/datacenterlight/migrations/0010_merge.py b/datacenterlight/migrations/0010_merge.py new file mode 100644 index 00000000..72feedf5 --- /dev/null +++ b/datacenterlight/migrations/0010_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-08-27 08:02 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('datacenterlight', '0009_merge'), + ('datacenterlight', '0008_contactus_field'), + ] + + operations = [ + ] diff --git a/datacenterlight/models.py b/datacenterlight/models.py index f7b50a01..e2de41e1 100644 --- a/datacenterlight/models.py +++ b/datacenterlight/models.py @@ -57,7 +57,8 @@ class VMTemplate(models.Model): @classmethod def create(cls, name, opennebula_vm_template_id): - vm_template = cls(name=name, opennebula_vm_template_id=opennebula_vm_template_id) + vm_template = cls( + name=name, opennebula_vm_template_id=opennebula_vm_template_id) return vm_template @@ -71,3 +72,10 @@ class StripePlan(models.Model): def create(cls, stripe_plan_id): stripe_plan = cls(stripe_plan_id=stripe_plan_id) return stripe_plan + + +class ContactUs(models.Model): + name = models.CharField(max_length=250) + email = models.CharField(max_length=250) + message = models.TextField() + field = models.DateTimeField(auto_now_add=True) diff --git a/datacenterlight/static/datacenterlight/css/cms.css b/datacenterlight/static/datacenterlight/css/cms.css new file mode 100644 index 00000000..abf06501 --- /dev/null +++ b/datacenterlight/static/datacenterlight/css/cms.css @@ -0,0 +1,47 @@ +.dcl-cms_page-full-width { + color: #fff; + text-align: center; + background-image: -ms-linear-gradient(right, #29427A 50%, #4F6699 100%); + background-image: -moz-linear-gradient(right, #29427A 50%, #4F6699 100%); + background-image: -o-linear-gradient(right, #29427A 50%, #4F6699 100%); + background-image: -webkit-gradient(linear, right top, left top, color-stop(50, #29427A), color-stop(100, #4F6699)); + background-image: -webkit-linear-gradient(right, #29427A 50%, #4F6699 100%); + background-image: linear-gradient(to left, #29427A 50%, #4F6699 100%); +} + +.dcl-cms_page-header { + padding: 150px 0 150px 0; + text-align: center; + color: #f8f8f8; + background: url(../img/pattern.jpg) no-repeat center center; + background-size: cover; + position: relative; + background-attachment: fixed; +} + +.dcl-cms_page-header::before { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background: rgba(90, 116, 175, 0.85); +} + +#dcl-cms_page-text { + background: #fff; +} + +#dcl-cms_page-text h3 { + font-size: 42px; + width: 70%; +} + +@media (max-width: 767px) { + #dcl-cms_page-text h3 { + font-size: 30px; + line-height: 40px; + width: 100%; + } +} \ No newline at end of file diff --git a/datacenterlight/static/datacenterlight/css/landing-page.css b/datacenterlight/static/datacenterlight/css/landing-page.css index a5562710..9d83a88f 100755 --- a/datacenterlight/static/datacenterlight/css/landing-page.css +++ b/datacenterlight/static/datacenterlight/css/landing-page.css @@ -323,9 +323,9 @@ button, input, optgroup, select, textarea { padding-top: 50px; /* If you're making other pages, make sure there is 50px of padding to make sure the navbar doesn't overlap content! */ padding-bottom: 50px; - text-align: center; +/* text-align: center; */ color: #f8f8f8; - background: url(../img/banner-bg.jpg) no-repeat center center; + background: url(../img/pattern.jpg) no-repeat center center; background-size: cover; position: relative; } @@ -654,74 +654,161 @@ button, input, optgroup, select, textarea { position: relative; } -.full-contact-section { - background-image: -ms-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: -moz-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: -o-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: -webkit-gradient(linear, right top, left top, color-stop(50, #29427A), color-stop(100, #4F6699)); - background-image: -webkit-linear-gradient(right, #29427A 50%, #4F6699 100%); - background-image: linear-gradient(to left, #29427A 50%, #4F6699 100%); -} - .contact-section { - padding: 60px 0; - color: #fff; + padding: 80px 0; + color: rgba(255,255,255,0.9); background-attachment: fixed; } -.contact-section .card { - text-align: center; - width: 350px; - margin: 0 auto; - background: #fff; - box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); - padding-bottom: 40px; - border-radius: 7px; - color: #4c4444; - box-sizing: border-box; - padding: 45px; - margin-top: -115px; +.contact-section .modal { + color: #333; } -.contact-section .card .social a { - color: #29427A; +.contact-details { + padding-left: 5px; +} + +.contact-section .description{ + font-size: 20px; +} + +.contact-section .social a { + color: #fff; font-size: 45px; } -.contact-section .card .subtitle h3 { - font-size: 30px; - margin-bottom: 23px; +.contact-section .social .fa-facebook { + font-size: 40px; + background: #fff; + border-radius: 100%; + color: #425d89; + width: 40px; + text-align: center; + top: -2px; + position: relative; + left: 10px; +} +.contact-section .social .fa-facebook:before { + font-size: 32px; + position: relative; + top: -1px; + left: -1px; } -.contact-section .card .social a:hover { +.contact-section .social a:hover { text-decoration: none; } -.contact-section .title { - margin-right: auto; - width: 80%; - max-width: 468px; +.contact-section .subtitle h3 { + font-size: 30px; + margin-bottom: 15px; +} + +.contact-section .contact-form-success { + font-size: 18px; + text-align: center; + background-color: rgba(0,0,0,0.2); + padding: 0 15px 35px; + margin-top: 25px; } .contact-section .title h2 { font-size: 65px; margin: 0; - color: #fff; - padding-bottom: 25px; position: relative; - text-align: right; +/* color: #eee; + padding-bottom: 25px; + text-align: right; */ } -.contact-section .title h2::before { - content: ""; +.contact-form .form-group { + border: 0; + margin-bottom: 20px; +} + +.contact-form .form-group label { + letter-spacing: 0.6px; + font-weight: 400; +} + +.contact-form .btn { + min-width: 140px; + background: rgba(23, 23, 23, 0.18); + color: #fff; + border-radius: 4px; + border-width: 2px; + box-shadow: none; + letter-spacing: 2px; + border-color: #fff; +} + +.contact-form .btn.sending { + cursor: wait; +} + +@keyframes sending { + 0% {content: '.';} + 50% {content: '..';} + 100% {content: '...';} +} + +.contact-form .btn.sending:after { + content: '.'; position: absolute; - bottom: 0; - background: #fff; - height: 7px; - width: 70px; - right: 0; + display: inline-block; + text-align: left; + margin-left: 5px; + width: 20px; + animation: sending 1s linear infinite; } +.contact-form .btn:hover, +.contact-form .btn:focus { + background: rgba(23, 23, 23, 0.28); + border-color: #fff; + box-shadow: none; + outline: 0; +} + +.contact-form .form-control { + box-shadow: none; + border-color: #ccc; +} + +.contact-form .errorlist { + list-style: none; + padding: 5px; + margin: 0; + color: rgb(255, 164, 164); + font-weight: 600; + letter-spacing: 0.4px; +} + +.contact-form .form-error { + background: rgba(255,255,255,0.9); + color: #eb4d5c; + padding: 10px; + text-align: center; + margin-bottom: 20px; + border-radius: 5px; +} + +.contact-form .has-error label { + color: #fff; +} + +.contact-form .has-error .form-control { + border: 2px solid #e8534b; + box-shadow: none; +} + +.contact-form .subtitle { + padding: 22px 0 15px; +} + +.contact-form textarea { + resize: none; +} /*Why DCL*/ @@ -1311,9 +1398,9 @@ tech-sub-sec h2 { margin: 0 auto; } .contact-section .title h2 { - font-size: 35px; + font-size: 45px; line-height: 40px; - text-align: center; +/* text-align: center; */ margin-top: 35px; } .contact-section .title h2::before { @@ -1558,4 +1645,4 @@ a.list-group-item-danger.active:focus { } .panel-danger > .panel-heading .badge { background-color: #eb4d5c; -} \ No newline at end of file +} diff --git a/datacenterlight/static/datacenterlight/img/facebook_logo.svg b/datacenterlight/static/datacenterlight/img/facebook_logo.svg new file mode 100644 index 00000000..c2ab1b51 --- /dev/null +++ b/datacenterlight/static/datacenterlight/img/facebook_logo.svg @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="57px" height="66px" viewBox="0 0 57 66" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch --> + <title>Slice 20</title> + <desc>Created with Sketch.</desc> + <defs></defs> + <g id="contact-us" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <ellipse id="Oval-2" fill="#FFFFFF" cx="28.7865939" cy="33.4691264" rx="19.7865939" ry="19.4691264"></ellipse> + <path d="M35.3784886,34.6387051 L30.2336176,34.6387051 L30.2336176,50.2467762 L22.6226844,50.2467762 L22.6226844,34.6387051 L19,34.6387051 L19,29.1194625 L22.6226844,29.1194625 L22.6226844,25.5403791 C22.6226844,22.9849851 24.0459888,19 30.3115248,19 L35.9567996,19.0178699 L35.9567996,24.3762836 L31.8546864,24.3762836 C31.1894789,24.3762836 30.2426069,24.6596489 30.2426069,25.8824599 L30.2426069,29.1194625 L36.0436961,29.1194625 L35.3784886,34.6387051 Z" id="Shape" fill="#5E79AD" fill-rule="nonzero"></path> + </g> +</svg> \ No newline at end of file diff --git a/datacenterlight/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js index 5594fe11..2e928955 100644 --- a/datacenterlight/static/datacenterlight/js/main.js +++ b/datacenterlight/static/datacenterlight/js/main.js @@ -39,7 +39,7 @@ _initScroll(); _initNavUrl(); _initPricing(); - + ajaxForms(); }); $(window).resize(function() { @@ -157,4 +157,27 @@ $('#valueTotal').text(numbers * price * 31); } -})(jQuery); + function ajaxForms() { + $('body').on('submit', '.ajax-form', function(e){ + e.preventDefault(); + var $form = $(this); + $form.find('[type=submit]').addClass('sending'); + $.ajax({ + url: $form.attr('action'), + type: $form.attr('method'), + data: $form.serialize(), + + success: function(response) { + var responseContain = $($form.attr('data-response')); + responseContain.html(response); + $form.find('[type=submit]').removeClass('sending'); + }, + + error: function() { + $form.find('[type=submit]').removeClass('sending'); + $form.find('.form-error').removeClass('hide'); + } + }); + }) + } +})(jQuery); \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/base.html b/datacenterlight/templates/datacenterlight/base.html index fc69a2d5..671d894e 100644 --- a/datacenterlight/templates/datacenterlight/base.html +++ b/datacenterlight/templates/datacenterlight/base.html @@ -1,4 +1,4 @@ -{% load staticfiles i18n%} +{% load staticfiles i18n cms_tags sekizai_tags %} {% get_current_language as LANGUAGE_CODE %} <!DOCTYPE html> <html lang="{{LANGUAGE_CODE}}"> @@ -33,13 +33,15 @@ <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]--> + {% render_block "css" postprocessor "compressor.contrib.sekizai.compress" %} + {% render_block "js" postprocessor "compressor.contrib.sekizai.compress" %} <!-- Google analytics --> {% include "google_analytics.html" %} <!-- End Google Analytics --> </head> <body> - + {% cms_toolbar %} <!-- Navigation --> {% include "datacenterlight/includes/_navbar.html" %} diff --git a/datacenterlight/templates/datacenterlight/cms_page.html b/datacenterlight/templates/datacenterlight/cms_page.html new file mode 100644 index 00000000..f42528e4 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/cms_page.html @@ -0,0 +1,33 @@ +{% extends "datacenterlight/base.html" %} +{% load staticfiles cms_tags sekizai_tags %} +{% block content %} +{% addtoblock "css" %} +<link href="{% static 'datacenterlight/css/cms.css' %}" media="screen" rel="stylesheet" type="text/css"/> +{% endaddtoblock %} + +<div class="dcl-cms_page-full-width"> + <div class="dcl-cms_page-header"> + <div class="container"> + <div class="row"> + <div class="col-sm-12 col-md-12"> + <div class="single-heading"> + <h2>{% placeholder 'datacenterlight_cms_page_title' %}</h2> + </div> + </div> + </div> + </div> + </div> +</div> + +<div class="split-section left" id="dcl-cms_page-text"> + <div class="space"> + <div class="container"> + <div class="row"> + <div class="col-md-12"> + {% placeholder 'datacenterlight_cms_page_text' %} + </div> + </div> + </div> + </div> +</div> +{% endblock %} diff --git a/datacenterlight/templates/datacenterlight/contact_form.html b/datacenterlight/templates/datacenterlight/contact_form.html new file mode 100644 index 00000000..458d6168 --- /dev/null +++ b/datacenterlight/templates/datacenterlight/contact_form.html @@ -0,0 +1,50 @@ +{% load i18n %} + +{% if success %} + <div class="contact-form-success"> + <div class="subtitle text-center"> + <h3>{% trans "Thank you for contacting us." %}</h3> + </div> + <p> + {% trans "Your message was successfully sent to our team." %} + </p> + </div> +{% else %} + <div class="row"> + <div class="col-sm-offset-2 col-sm-10"> + <div class="subtitle"> + <h3>{% trans "Get in touch with us!" %}</h3> + </div> + </div> + </div> + <form class="form-horizontal ajax-form" method="POST" action="{% url 'datacenterlight:contact_us' %}" data-toggle="validator" data-response="#contact-form"> + {% csrf_token %} + <div class="form-group"> + <label class="control-label col-sm-2" for="name">{% trans "Name" %}</label> + <div class="col-sm-10"> + <input type="text" name="name" class="form-control" data-minlength="3" data-error="{% trans 'Please enter your name.' %}" required> + {{contact_form.name.errors}} + </div> + </div> + <div class="form-group"> + <label class="control-label col-sm-2" for="email">{% trans "Email" %}</label> + <div class="col-sm-10"> + <input name="email" type="email" pattern="^[^@\s]+@([^@\s]+\.)+[^@\s]+$" class="form-control" data-error="{% trans 'Please enter a valid email address.' %}" required> + {{contact_form.email.errors}} + </div> + </div> + <div class="form-group"> + <label class="control-label col-sm-2" for="message">{% trans "Message" %}</label> + <div class="col-sm-10"> + <textarea class="form-control" name="message" id="message" rows="6" required></textarea> + {{contact_form.message.errors}} + </div> + </div> + <div class="form-group"> + <div class="col-sm-offset-2 col-sm-10 text-right"> + <div class="form-error hide">{% trans "Sorry, there was an unexpected error. Kindly retry." %}</div> + <button type="submit" class="btn btn-default">{% trans "SUBMIT" %}</button> + </div> + </div> + </form> +{% endif %} \ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/includes/_navbar.html b/datacenterlight/templates/datacenterlight/includes/_navbar.html index 99f6a4a8..9df9e227 100644 --- a/datacenterlight/templates/datacenterlight/includes/_navbar.html +++ b/datacenterlight/templates/datacenterlight/includes/_navbar.html @@ -1,74 +1,113 @@ {% load staticfiles i18n%} {% get_current_language as LANGUAGE_CODE %} {% load custom_tags %} <nav class="navbar navbar-default navbar-fixed-top topnav"> - <div class="topnav"> - <!-- Brand and toggle get grouped for better mobile display --> - <div class="navbar-header"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> - <span class="sr-only">Toggle navigation</span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - {% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %} - <a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav" data-url="#home"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a> - <a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav" data-url="#home"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a> + <div class="topnav"> + <!-- Brand and toggle get grouped for better mobile display --> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" + data-target="#bs-example-navbar-collapse-1"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + {% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %} + <a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav" data-url="#home"><img + src="{% static 'datacenterlight/img/logo_black.svg' %}"></a> + <a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav" data-url="#home"><img + src="{% static 'datacenterlight/img/logo_white.svg' %}"></a> + {% else %} + <a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav"><img + src="{% static 'datacenterlight/img/logo_black.svg' %}"></a> + <a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav"><img + src="{% static 'datacenterlight/img/logo_white.svg' %}"></a> + {% endif %} + + </div> + <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><!-- Start Navbar collapse--> + <ul class="nav navbar-nav navbar-right"> + {% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %} + <li class="dropdown"> + <a class="dropdown-toggle visible-mobile" href="#" data-toggle="dropdown" role="button" + aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span + class="caret"></span></a> + <a class="dropdown-toggle url disabled visible-desktop menu-url" data-url="#how" + data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %} + <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a class="url menu-url" data-url="#your" href="#your">{% trans "Scale out" %}</a></li> + <li><a class="url menu-url" data-url="#our" href="#our">{% trans "Reliable and light" %}</a> + </li> + <li><a class="url menu-url" data-url="#price" href="#price">{% trans "Order VM" %}</a></li> + </ul> + </li> + <li> + <a href="{% url 'datacenterlight:whydatacenterlight' %}">{% trans "Why Data Center Light?" %}</a> + </li> + <li> + <a class="url" href="{% url 'datacenterlight:index' %}#contact" data-url="#contact">{% trans "Contact" %}</a> + </li> {% else %} - <a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a> - <a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a> + <li class="dropdown"> + <a class="dropdown-toggle visible-mobile" href="#" data-toggle="dropdown" role="button" + aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span + class="caret"></span></a> + <a class="dropdown-toggle url disabled visible-desktop menu-url" data-url="#how" + data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %} + <span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a class="url menu-url" data-url="#your" + href="{% url 'datacenterlight:whydatacenterlight' %}#your">{% trans "Scale out" %}</a> + </li> + <li><a class="url menu-url" data-url="#our" + href="{% url 'datacenterlight:whydatacenterlight' %}#our">{% trans "Reliable and light" %} + </a></li> + <li><a class="url menu-url" data-url="#price" + href="{% url 'datacenterlight:whydatacenterlight' %}#price">{% trans "Order VM" %}</a> + </li> + </ul> + </li> + <li> + <a href="{% url 'datacenterlight:whydatacenterlight' %}">{% trans "Why Data Center Light?" %}</a> + </li> + <li> + <a class="url" href="{% url 'datacenterlight:index' %}#contact" data-url="#contact">{% trans "Contact" %}</a> + </li> {% endif %} - </div> - <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><!-- Start Navbar collapse--> - <ul class="nav navbar-nav navbar-right"> - {% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %} - <li class="dropdown"> - <a class="dropdown-toggle visible-mobile" href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span class="caret"></span></a> - <a class="dropdown-toggle url disabled visible-desktop menu-url" data-url="#how" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span class="caret"></span></a> - <ul class="dropdown-menu"> - <li><a class="url menu-url" data-url="#your" href="#your">{% trans "Scale out" %}</a></li> - <li><a class="url menu-url" data-url="#our" href="#our">{% trans "Reliable and light" %}</a></li> - <li> <a class="url menu-url" data-url="#price" href="#price">{% trans "Order VM" %}</a></li> + <li> + {% if LANGUAGE_CODE == 'en-us'%} + <a class="on-hover-border" href="{% change_lang 'de' %}">Deutsch <i class="fa fa-globe" + aria-hidden="true"></i></a> + {% else %} + <a class="on-hover-border" href="{% change_lang 'en-us' %}">English <i + class="fa fa-globe" aria-hidden="true"></i></a> + {% endif %} + </li> + {% comment %} + <!-- to be used when more than one option for language --> + <li class="nav-language"> + <div class="dropdown"> + <div class="dropdown-toggle select-language" data-toggle="dropdown" role="button" + aria-haspopup="true" aria-expanded="false"> + {% if LANGUAGE_CODE == 'en-us'%} + <span>English</span> + {% else %} + <span>Deutsch</span> + {% endif %} + <i class="fa fa-globe" aria-hidden="true"></i> + </div> + <ul class="dropdown-menu drop-language dropdown-menu-right"> + {% if LANGUAGE_CODE == 'en-us'%} + <li><a class="url" href="{% change_lang 'de' %}">Deutsch</a></li> + {% else %} + <li><a class="url" href="{% change_lang 'en-us' %}">English</a></li> + {% endif %} + </ul> + </div> + </li> + {% endcomment %} </ul> - </li> - <li> - <a href="{% url 'datacenterlight:whydatacenterlight' %}" >{% trans "Why Data Center Light?" %}</a> - </li> - <li> - <a class="url" href="{% url 'datacenterlight:index' %}#contact" data-url="#contact" >{% trans "Contact" %}</a> - </li> - {% endif %} - - <li> - {% if LANGUAGE_CODE == 'en-us'%} - <a class="on-hover-border" href="{% change_lang 'de' %}">Deutsch <i class="fa fa-globe" aria-hidden="true"></i></a> - {% else %} - <a class="on-hover-border" href="{% change_lang 'en-us' %}">English <i class="fa fa-globe" aria-hidden="true"></i></a> - {% endif %} - </li> - {% comment %} - <!-- to be used when more than one option for language --> - <li class="nav-language"> - <div class="dropdown"> - <div class="dropdown-toggle select-language" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> - {% if LANGUAGE_CODE == 'en-us'%} - <span>English</span> - {% else %} - <span>Deutsch</span> - {% endif %} - <i class="fa fa-globe" aria-hidden="true"></i> - </div> - <ul class="dropdown-menu drop-language dropdown-menu-right"> - {% if LANGUAGE_CODE == 'en-us'%} - <li><a class="url" href="{% change_lang 'de' %}">Deutsch</a></li> - {% else %} - <li><a class="url" href="{% change_lang 'en-us' %}">English</a></li> - {% endif %} - </ul> - </div> - </li> - {% endcomment %} - </ul> + </div> + <!-- /.navbar-collapse --> </div> - <!-- /.navbar-collapse --> - </div> -</nav> \ No newline at end of file +</nav> diff --git a/datacenterlight/templates/datacenterlight/index.html b/datacenterlight/templates/datacenterlight/index.html index 3ddb516d..3f89055c 100755 --- a/datacenterlight/templates/datacenterlight/index.html +++ b/datacenterlight/templates/datacenterlight/index.html @@ -1,5 +1,5 @@ {% extends "datacenterlight/base.html" %} -{% load staticfiles i18n%} +{% load staticfiles i18n %} {% block content %} @@ -149,32 +149,34 @@ </div> - <!-- / contact section --> + <!-- / contact section --> <div class="full-contact-section"> <div class="intro-header-2 contact-section" id="contact"> <div class="container"> <div class="row"> - - <div class="col-sm-6 col-md-6"> - <div class="card"> + <div class="col-sm-6"> + <div class="title"> + <h2>{% trans "Contact us" %}</h2> + </div> + <div class="contact-details"> <div class="subtitle"> - <h3>ungleich GmbH </h3> + <h3>ungleich GmbH</h3> </div> <div class="description"> - <p><i class="fa fa-envelope-o"></i> info@datacenterlight.ch</p> + <p>info@datacenterlight.ch</p> <p>In der Au 7, Schwanden 8762</p> <p>{% trans "Switzerland " %}</p> </div> - <div class="social"> - <a target="_blank" class="" href="https://twitter.com/datacenterlight"><i class="fa fa-twitter fa-fw"></i></a> - <a target="_blank" class="" href="https://github.com/ungleich"><i class="fa fa-github fa-fw"></i></a> - <a target="_blank" class="" href="https://www.facebook.com/ungleich.ch/"><i class="fa fa-facebook fa-fw"></i></a> - </div> + </div> + <div class="social"> + <a target="_blank" class="" href="https://twitter.com/datacenterlight"><i class="fa fa-twitter fa-fw"></i></a> + <a target="_blank" class="" href="https://github.com/ungleich"><i class="fa fa-github fa-fw"></i></a> + <a target="_blank" class="" href="https://www.facebook.com/ungleich.ch/"><i class="fa fa-facebook"></i></a> </div> </div> - <div class="col-sm-6 col-md-6"> - <div class="title"> - <h2>{% trans "Questions?" %} {% trans "Contact us!" %}</h2> + <div class="col-sm-6"> + <div id="contact-form" class="contact-form"> + {% include "datacenterlight/contact_form.html" %} </div> </div> </div> diff --git a/datacenterlight/tests.py b/datacenterlight/tests.py index 602fb403..7c2f7353 100644 --- a/datacenterlight/tests.py +++ b/datacenterlight/tests.py @@ -6,10 +6,8 @@ import stripe from celery.result import AsyncResult from django.conf import settings from django.core.management import call_command -# Create your tests here. from django.test import TestCase, override_settings from model_mommy import mommy - from datacenterlight.models import VMTemplate from datacenterlight.tasks import create_vm_task from membership.models import StripeCustomer diff --git a/datacenterlight/urls.py b/datacenterlight/urls.py index a3aed7a6..5c9ffcd7 100644 --- a/datacenterlight/urls.py +++ b/datacenterlight/urls.py @@ -1,17 +1,24 @@ from django.conf.urls import url -from .views import IndexView, BetaProgramView, LandingProgramView, BetaAccessView, PricingView, SuccessView, \ - PaymentOrderView, OrderConfirmationView, WhyDataCenterLightView - +from .views import IndexView, BetaProgramView, LandingProgramView, \ + BetaAccessView, PricingView, SuccessView, \ + PaymentOrderView, OrderConfirmationView, \ + WhyDataCenterLightView, ContactUsView urlpatterns = [ url(r'^$', IndexView.as_view(), name='index'), - url(r'^whydatacenterlight/?$', WhyDataCenterLightView.as_view(), name='whydatacenterlight'), + url(r'^t$', IndexView.as_view(), name='index_t'), + url(r'^g$', IndexView.as_view(), name='index_g'), + url(r'^f$', IndexView.as_view(), name='index_f'), + url(r'^whydatacenterlight/?$', WhyDataCenterLightView.as_view(), + name='whydatacenterlight'), url(r'^beta-program/?$', BetaProgramView.as_view(), name='beta'), url(r'^landing/?$', LandingProgramView.as_view(), name='landing'), url(r'^pricing/?$', PricingView.as_view(), name='pricing'), url(r'^payment/?$', PaymentOrderView.as_view(), name='payment'), - url(r'^order-confirmation/?$', OrderConfirmationView.as_view(), name='order_confirmation'), + url(r'^order-confirmation/?$', OrderConfirmationView.as_view(), + name='order_confirmation'), url(r'^order-success/?$', SuccessView.as_view(), name='order_success'), url(r'^beta_access?$', BetaAccessView.as_view(), name='beta_access'), + url(r'^contact/?$', ContactUsView.as_view(), name='contact_us'), ] diff --git a/datacenterlight/views.py b/datacenterlight/views.py index fd1435a1..25c2b87f 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -1,26 +1,67 @@ -from django.views.generic import FormView, CreateView, TemplateView, DetailView -from django.http import HttpResponseRedirect -from .forms import BetaAccessForm -from .models import BetaAccess, BetaAccessVMType, BetaAccessVM, VMTemplate -from django.contrib import messages -from django.core.urlresolvers import reverse -from utils.mailer import BaseEmail -from django.shortcuts import render -from django.shortcuts import redirect from django import forms -from django.core.exceptions import ValidationError -from django.views.decorators.cache import cache_control from django.conf import settings +from django.contrib import messages +from django.core.exceptions import ValidationError +from django.core.urlresolvers import reverse +from django.http import HttpResponseRedirect +from django.shortcuts import redirect +from django.shortcuts import render from django.utils.translation import ugettext_lazy as _ -from utils.forms import BillingAddressForm -from utils.models import BillingAddress +from django.views.decorators.cache import cache_control +from django.views.generic import FormView, CreateView, TemplateView, DetailView + +from datacenterlight.tasks import create_vm_task from hosting.models import HostingOrder -from utils.stripe_utils import StripeUtils from membership.models import CustomUser, StripeCustomer from opennebula_api.models import OpenNebulaManager from opennebula_api.serializers import VirtualMachineTemplateSerializer, \ VMTemplateSerializer -from datacenterlight.tasks import create_vm_task +from utils.forms import BillingAddressForm +from utils.mailer import BaseEmail +from utils.stripe_utils import StripeUtils +from utils.tasks import send_plain_email_task +from .forms import BetaAccessForm, ContactForm +from .models import BetaAccess, BetaAccessVMType, BetaAccessVM, VMTemplate + + +class ContactUsView(FormView): + template_name = "datacenterlight/contact_form.html" + form_class = ContactForm + + def get(self, request, *args, **kwargs): + return HttpResponseRedirect(reverse('datacenterlight:index')) + + def form_invalid(self, form): + if self.request.is_ajax(): + return self.render_to_response( + self.get_context_data(contact_form=form)) + else: + return render(self.request, + 'datacenterlight/index.html', + self.get_context_data(contact_form=form)) + + def form_valid(self, form): + form.save() + email_data = { + 'subject': "{dcl_text} Message from {sender}".format( + dcl_text=settings.DCL_TEXT, + sender=form.cleaned_data.get('email') + ), + 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS, + 'to': ['info@ungleich.ch'], + 'body': "\n".join( + ["%s=%s" % (k, v) for (k, v) in form.cleaned_data.items()]), + 'reply_to': [form.cleaned_data.get('email')], + } + send_plain_email_task.delay(email_data) + if self.request.is_ajax(): + return self.render_to_response( + self.get_context_data(success=True, contact_form=form)) + else: + return render(self.request, + 'datacenterlight/index.html', + self.get_context_data(success=True, + contact_form=form)) class LandingProgramView(TemplateView): @@ -315,7 +356,8 @@ class IndexView(CreateView): context = super(IndexView, self).get_context_data(**kwargs) context.update({ 'base_url': "{0}://{1}".format(self.request.scheme, - self.request.get_host()) + self.request.get_host()), + 'contact_form': ContactForm }) return context @@ -419,7 +461,8 @@ class PaymentOrderView(FormView): token=token) if not customer: form.add_error("__all__", "Invalid credit card") - return self.render_to_response(self.get_context_data(form=form)) + return self.render_to_response( + self.get_context_data(form=form)) # Create Billing Address billing_address = form.save() diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index f3d00e47..08ce457d 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -213,6 +213,8 @@ CMS_TEMPLATES = ( # ungleich ('blog_ungleich.html', gettext('Blog')), ('page.html', gettext('Page')), + # dcl + ('datacenterlight/cms_page.html', gettext('Data Center Light')), ) DATABASES = { diff --git a/utils/tasks.py b/utils/tasks.py index ad0a0e53..1c6dd449 100644 --- a/utils/tasks.py +++ b/utils/tasks.py @@ -3,12 +3,27 @@ import tempfile from cdist.integration import configure_hosts_simple from celery.utils.log import get_task_logger from django.conf import settings +from django.core.mail import EmailMessage from dynamicweb.celery import app logger = get_task_logger(__name__) +@app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES) +def send_plain_email_task(self, email_data): + """ + This is a generic celery task to be used for sending emails. + A celery wrapper task for EmailMessage + + :param self: + :param email_data: A dict of all needed email headers + :return: + """ + email = EmailMessage(**email_data) + email.send() + + @app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES) def save_ssh_key(self, hosts, keys): """