Merge branch 'develop' into order_now
This commit is contained in:
commit
df0b4f2629
15 changed files with 636 additions and 67 deletions
|
@ -7,7 +7,7 @@ class BetaAccessForm(forms.ModelForm):
|
|||
email = forms.CharField(widget=forms.EmailInput())
|
||||
|
||||
class Meta:
|
||||
fields = ['email']
|
||||
fields = ['name', 'email']
|
||||
model = BetaAccess
|
||||
|
||||
|
||||
|
|
|
@ -84,6 +84,11 @@ h6 {
|
|||
background-color: rgba(90, 116, 175, 0.8);
|
||||
border-color: #5A74AF;
|
||||
}
|
||||
.btn-info:focus {
|
||||
color: #fff;
|
||||
background-color: rgba(90, 116, 175, 0.8);
|
||||
border-color: #5A74AF;
|
||||
}
|
||||
.btn-lg{
|
||||
min-width: 180px;
|
||||
}
|
||||
|
@ -131,6 +136,9 @@ h6 {
|
|||
padding: 10px 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.navbar-right {
|
||||
margin-right: 0px;
|
||||
}
|
||||
.intro-header {
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
|
@ -217,6 +225,33 @@ h6 {
|
|||
font-weight: 300;
|
||||
font-family: 'Montserrat-Light';
|
||||
}
|
||||
|
||||
.intro-pricing{
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background: url(../img/pattern.jpg) no-repeat center center;
|
||||
background-size: cover;
|
||||
height: 70vh;
|
||||
max-height: 400px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
.intro-pricing::before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(90, 116, 175, 0.7);
|
||||
}
|
||||
.intro-pricing .intro-message .section-heading{
|
||||
font-size: 45px;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.split-section {
|
||||
padding: 70px 0;
|
||||
}
|
||||
|
@ -472,6 +507,115 @@ h6 {
|
|||
right: 0;
|
||||
}
|
||||
|
||||
/*Pricing page*/
|
||||
|
||||
.price-calc-section{
|
||||
padding: 80px 40px !important;
|
||||
background: -webkit-linear-gradient(top, #f0f4f7, #fff) no-repeat;
|
||||
background: linear-gradient(to bottom, #f0f4f7, #fff) no-repeat;
|
||||
display: flex;
|
||||
}
|
||||
.price-calc-section .text{
|
||||
width: 50%;
|
||||
}
|
||||
.price-calc-section .text .section-heading{
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-size: 50px;
|
||||
line-height: 50px;
|
||||
padding-bottom: 25px;
|
||||
color: #3a3a3a;
|
||||
letter-spacing: 1px;
|
||||
position: relative;
|
||||
text-align: right;
|
||||
}
|
||||
.price-calc-section .text .description{
|
||||
font-size: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
.price-calc-section .text .section-heading::before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
background: #29427A;
|
||||
height: 7px;
|
||||
width: 70px;
|
||||
right: 0;
|
||||
}
|
||||
.price-calc-section .card{
|
||||
width: 50%;
|
||||
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;
|
||||
text-align: center;
|
||||
/* margin-right: auto; */
|
||||
max-width: 400px;
|
||||
}
|
||||
.price-calc-section .card .title{
|
||||
padding: 15px 40px;
|
||||
font-family: 'Montserrat-Medium';
|
||||
}
|
||||
.price-calc-section .card .title h3{
|
||||
font-family: 'Montserrat-Medium';
|
||||
}
|
||||
.price-calc-section .card .price{
|
||||
background: #5A74AF;
|
||||
padding: 22px;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
}
|
||||
.price-calc-section .card .description{
|
||||
padding: 12px;
|
||||
border-bottom: 1px solid rgba(128, 128, 128, 0.3);
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.price-calc-section .card .description span{
|
||||
font-size: 20px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.price-calc-section .card .description i{
|
||||
color: #29427A;
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
}
|
||||
.price-calc-section .card .description .left{
|
||||
margin-right: 7px;
|
||||
}
|
||||
.price-calc-section .card .description .right{
|
||||
margin-left: 7px;
|
||||
}
|
||||
.price-calc-section .card .descriptions{
|
||||
padding: 10px 30px;
|
||||
}
|
||||
.price-calc-section .card .description p{
|
||||
margin: 0;
|
||||
}
|
||||
.price-calc-section .card .btn{
|
||||
margin-top: 20px;
|
||||
font-size: 20px;
|
||||
width: 200px;
|
||||
}
|
||||
.price-calc-section .card .select-configuration select{
|
||||
outline: none;
|
||||
background: #fff;
|
||||
border-color: #d0d0d0;
|
||||
height: 40px;
|
||||
width: 200px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
.price-calc-section .card .check-ip{
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.price-calc-section .card .check-ip input[type=checkbox]{
|
||||
font-size: 17px;
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
@media(max-width:990px) {
|
||||
.pricing-section .text {
|
||||
|
@ -481,6 +625,10 @@ h6 {
|
|||
.navbar-transparent .navbar-nav>li>a {
|
||||
font-size: 14px;
|
||||
}
|
||||
.pricing-section .text .section-heading::before {
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@media(max-width:768px) {
|
||||
|
|
BIN
datacenterlight/static/datacenterlight/img/pattern.jpg
Executable file
BIN
datacenterlight/static/datacenterlight/img/pattern.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 181 KiB |
12
datacenterlight/static/datacenterlight/js/form.js
Normal file
12
datacenterlight/static/datacenterlight/js/form.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -5,7 +5,23 @@
|
|||
/* ---------------------------------------------
|
||||
Scripts initialization
|
||||
--------------------------------------------- */
|
||||
|
||||
var cardPricing ={
|
||||
'cpu': {
|
||||
'id': 'coreValue',
|
||||
'value': 1,
|
||||
'limit': 48
|
||||
},
|
||||
'ram': {
|
||||
'id': 'ramValue',
|
||||
'value': 1,
|
||||
'limit': 200
|
||||
},
|
||||
'storage': {
|
||||
'id': 'storageValue',
|
||||
'value': 1,
|
||||
'limit': 500
|
||||
}
|
||||
}
|
||||
$(window).load(function(){
|
||||
|
||||
|
||||
|
@ -16,6 +32,7 @@
|
|||
_navScroll();
|
||||
_initScroll();
|
||||
_initNavUrl();
|
||||
_initPricing();
|
||||
|
||||
});
|
||||
|
||||
|
@ -41,7 +58,6 @@
|
|||
|
||||
function _navScroll(){
|
||||
if($(window).scrollTop() > 10 ){
|
||||
console.log($(window).scrollTop());
|
||||
$(".navbar").removeClass("navbar-transparent");
|
||||
$(".navbar-default .btn-link").css("color", "#777");
|
||||
}else{
|
||||
|
@ -65,6 +81,39 @@
|
|||
}
|
||||
}
|
||||
|
||||
function _initPricing(){
|
||||
_fetchPricing();
|
||||
|
||||
$('.fa-minus-circle.left').click(function(event){
|
||||
var data = $(this).data('minus');
|
||||
|
||||
if(cardPricing[data].value > 1){
|
||||
cardPricing[data].value --;
|
||||
}
|
||||
_fetchPricing();
|
||||
});
|
||||
$('.fa-plus-circle.right').click(function(event){
|
||||
var data = $(this).data('plus');
|
||||
if(cardPricing[data].value < cardPricing[data].limit){
|
||||
cardPricing[data].value ++;
|
||||
}
|
||||
_fetchPricing();
|
||||
});
|
||||
}
|
||||
function _fetchPricing(){
|
||||
Object.keys(cardPricing).map(function(element){
|
||||
$('#'+cardPricing[element].id).text(cardPricing[element].value);
|
||||
$('input[name='+element+']').val(cardPricing[element].value);
|
||||
});
|
||||
_calcPricing();
|
||||
}
|
||||
|
||||
function _calcPricing(){
|
||||
var total = (cardPricing['cpu'].value * 5) + (2* cardPricing['ram'].value) + (0.6* cardPricing['storage'].value)
|
||||
|
||||
$("#total").text(total);
|
||||
$('input[name=total]').val(total);
|
||||
}
|
||||
function form_success(){
|
||||
$('#sucessModal').modal('show');
|
||||
}
|
||||
|
|
27
datacenterlight/templates/datacenterlight/beta_access.html
Normal file
27
datacenterlight/templates/datacenterlight/beta_access.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
{% load i18n %}
|
||||
|
||||
<form novalidate id ="beta_access" class="form-beta" method="POST" action="{% url 'datacenterlight:beta_access'%}">
|
||||
{% csrf_token %}
|
||||
{{ form.non_field_errors }}
|
||||
<div>
|
||||
{% for message in messages %}
|
||||
<strong>{{ message }}</strong>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="inputs">
|
||||
<div class="form-group">
|
||||
<input type="text" name="name" class="form-control" id="name" placeholder="Enter name">
|
||||
<span style="color: white">{{ form.name.errors|striptags}}</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="email" name="email" class="form-control" id="email" placeholder="Enter email">
|
||||
<span style="color: white">{{ form.email.errors|striptags}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-default btn-transparent btn-lg">{% trans "Request Beta Access" %}</button>
|
||||
</form>
|
||||
<script>
|
||||
$('#beta_access').ajaxForm({
|
||||
target: '#beta_access_form', success: function(response) { }
|
||||
});
|
||||
</script>
|
47
datacenterlight/templates/datacenterlight/beta_success.html
Normal file
47
datacenterlight/templates/datacenterlight/beta_success.html
Normal file
|
@ -0,0 +1,47 @@
|
|||
{% load i18n %}
|
||||
|
||||
<div class="modal fade bs-example-modal-sm" style="color:black;" id="successModal" tabindex="-1" role="dialog">
|
||||
<div class="vertical-alignment-helper">
|
||||
<div class="modal-dialog vertical-align-center">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">{% trans "Request Sent" %}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{% trans "Thank you, we will contact you as soon as possible" %}</p>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /.modal -->
|
||||
<script>
|
||||
// Show modal
|
||||
$('#successModal').modal('show');
|
||||
// close the modal after 3 seconds
|
||||
setTimeout(function() {
|
||||
$('#successModal').modal('hide');
|
||||
}, 5000);
|
||||
</script>
|
||||
<style>
|
||||
.vertical-alignment-helper {
|
||||
display:table;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
pointer-events:none; /* This makes sure that we can still click outside of the modal to close it */
|
||||
}
|
||||
.vertical-align-center {
|
||||
/* To center vertically */
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
pointer-events:none;
|
||||
}
|
||||
.modal-content {
|
||||
/* Bootstrap sets the size of the modal in the modal-dialog class, we need to inherit it */
|
||||
width:inherit;
|
||||
height:inherit;
|
||||
/* To center horizontally */
|
||||
margin: 0 auto;
|
||||
pointer-events: all;
|
||||
}
|
||||
</style>
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar navbar-default navbar-fixed-top topnav" role="navigation">
|
||||
<div class="container 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">
|
||||
|
@ -113,7 +113,7 @@
|
|||
<a href="#how" class="btn btn-default btn-lg btn-transparent"><i class="#Services"></i> <span class="network-name">{% trans "What is it?" %}</span></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#requestform" class="btn btn-primary btn-lg page-scroll"><span class="network-name">{% trans "I want it!" %}</span></a>
|
||||
<a class="btn btn-primary btn-lg page-scroll url" href="javascript:void(0)" data-url="#request" ><span class="network-name">{% trans "I want it!" %}</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -227,7 +227,7 @@
|
|||
<h3>{% trans "VM hosting" %} </h3>
|
||||
</div>
|
||||
<div class="price">
|
||||
<span>15CHF</span>
|
||||
<span>15CHF/month</span>
|
||||
</div>
|
||||
<div class="descriptions">
|
||||
<div class="description">
|
||||
|
@ -243,7 +243,7 @@
|
|||
<p>{% trans "15 GiB storage(SSD)" %}</p>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{% url 'hosting:payment' %}" class="btn btn-primary">{% trans "Order Now!" %}</a>
|
||||
<a href="{% url 'datacenterlight:pricing' %}" class="btn btn-primary">{% trans "Order Now!" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -252,7 +252,7 @@
|
|||
|
||||
</div>
|
||||
<!-- Configure -->
|
||||
<div class="request-section" >
|
||||
<div class="request-section" id="request">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-6">
|
||||
|
@ -261,43 +261,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-6">
|
||||
<div class="form">
|
||||
<form class="form-beta" method="POST" action="">
|
||||
{% csrf_token %}
|
||||
{{ form.non_field_errors }}
|
||||
{{ form.email.errors|striptags}}
|
||||
<div>
|
||||
{% for message in messages %}
|
||||
<strong>{{ message }}</strong>
|
||||
{% endfor %}
|
||||
<!-- Beta access form, will be loaded via ajax -->
|
||||
<div class="form" id="beta_access_form">
|
||||
</div>
|
||||
<div class="inputs">
|
||||
<div class="form-group">
|
||||
<input type="text" name="name" class="form-control" id="name" placeholder="Enter name">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="email" name="email" class="form-control" id="email" placeholder="Enter email">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-default btn-transparent btn-lg">{% trans "Request Beta Access" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal fade bs-example-modal-sm" style="color:black;" id="sucessModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">{% trans "Request Sent" %}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{% trans "Thank you, we will contact you as soon as possible" %}</p>
|
||||
</div>
|
||||
<div class="modal-footer text-center">
|
||||
<button type="submit" class="btn btn-primary" data-dismiss="modal">Ok</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -389,12 +355,12 @@
|
|||
windowPadding: 10,
|
||||
});
|
||||
|
||||
var hash = window.location.hash.substr(1);
|
||||
console.log(hash);
|
||||
if (hash == 'requestform'){
|
||||
$('#reques-success-message').modal('show');
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "{% url 'datacenterlight:beta_access' %}",
|
||||
context: document.body
|
||||
}).done(function(response) {
|
||||
$('#beta_access_form').html(response);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -403,6 +369,8 @@
|
|||
<!-- Bootstrap Core JavaScript -->
|
||||
<script src="{% static 'datacenterlight/js/bootstrap.min.js' %}"></script>
|
||||
<script src="{% static 'datacenterlight/js/main.js' %}"></script>
|
||||
<!-- Load form js -->
|
||||
<script src="{% static 'datacenterlight/js/form.js' %}"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
|
234
datacenterlight/templates/datacenterlight/pricing.html
Normal file
234
datacenterlight/templates/datacenterlight/pricing.html
Normal file
|
@ -0,0 +1,234 @@
|
|||
{% load staticfiles i18n%}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>datacenterlight.ch - Featherlight Swiss VM</title>
|
||||
|
||||
<!-- Bootstrap Core CSS -->
|
||||
<link href="{% static 'datacenterlight/css/bootstrap.min.css' %}" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Custom Fonts -->
|
||||
<!--Import Google Icon Font-->
|
||||
<link href="//fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link href="{% static 'datacenterlight/font-awesome/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css">
|
||||
<link href="//fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css">
|
||||
<link rel="shortcut icon" href="{% static 'datacenterlight/img/favicon.ico' %}" type="image/x-icon" />
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.min.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link href="{% static 'datacenterlight/css/landing-page.css' %}" rel="stylesheet">
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<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]-->
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar navbar-default navbar-fixed-top topnav" role="navigation">
|
||||
<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>
|
||||
<a id="logoBlack" class="navbar-brand topnav url" href="{% url 'datacenterlight:index' %}" ><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a>
|
||||
<a id="logoWhite" class="navbar-brand topnav url" href="{% url 'datacenterlight:index' %}" ><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
|
||||
</div>
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<!-- <li>
|
||||
<a class="url" href="javascript:void(0)" data-url="#how" >{% trans "What is it" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="url" href="javascript:void(0)" data-url="#your" >{% trans "Scale out" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="url" href="javascript:void(0)" data-url="#our">{% trans "Reliable and light" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="url" href="javascript:void(0)" data-url="#price" >{% trans "Buy VM" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="url" href="javascript:void(0)" data-url="#contact" >{% trans "Contact" %}</a>
|
||||
</li> -->
|
||||
|
||||
<select class="selectpicker" data-width="fit" onchange="location = this.value;" style="margin-top:10px;">
|
||||
{% if LANGUAGE_CODE == 'en-us'%}
|
||||
<option selected="selected" value="{{base_url}}/en-us/datacenterlight/">English</option>
|
||||
{% else %}
|
||||
<option value="{{base_url}}/en-us/datacenterlight/">English</option>
|
||||
{% endif %}
|
||||
{% if LANGUAGE_CODE == 'de'%}
|
||||
<option selected="selected" value="{{base_url}}/de/datacenterlight/">Deutsch</option>
|
||||
{% else %}
|
||||
<option value="{{base_url}}/de/datacenterlight/">Deutsch</option>
|
||||
{% endif %}
|
||||
|
||||
</select>
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
<!-- /.navbar-collapse -->
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
</nav>
|
||||
<div class="intro-pricing">
|
||||
|
||||
<div class="intro-message">
|
||||
<h2 class="section-heading">{% trans "We are cutting down the costs significantly!" %}</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="price-calc-section">
|
||||
<div class="card">
|
||||
<div class="caption">
|
||||
<form action="POST">
|
||||
|
||||
<div class="title">
|
||||
<h3>{% trans "VM hosting" %} </h3>
|
||||
</div>
|
||||
<div class="price">
|
||||
<span id="total">15</span>
|
||||
<span>CHF</span>
|
||||
</div>
|
||||
<div class="descriptions">
|
||||
<div class="description">
|
||||
<p>{% trans "Based in Switzerland" %}</p>
|
||||
</div>
|
||||
<div class="description">
|
||||
<i class="fa fa-minus-circle left" data-minus="cpu" aria-hidden="true"></i>
|
||||
<span id="coreValue">1</span><span> core</span>
|
||||
<i class="fa fa-plus-circle right" data-plus="cpu" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="description">
|
||||
<i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i>
|
||||
<span id="ramValue">2</span><span> GiB RAM</span>
|
||||
<i class="fa fa-plus-circle right" data-plus="ram" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="description">
|
||||
<i class="fa fa-minus-circle left" data-minus="storage" aria-hidden="true"></i>
|
||||
<span id="storageValue">15</span><span>{% trans "GiB storage(SSD)" %}</span>
|
||||
<i class="fa fa-plus-circle right" data-plus="storage" aria-hidden="true"></i>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="description select-configuration">
|
||||
<select name="config" id="">
|
||||
<option value="" disabled selected>Configuration</option>
|
||||
<option value="CentOS 7">CentOS 7</option>
|
||||
<option value="Debian 8">Debian 8</option>
|
||||
<option value="Ubuntu 14.04">Ubuntu 14.04</option>
|
||||
<option value="Ubuntu 16.04">Ubuntu 16.04</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="hidden" name="cpu">
|
||||
<input type="hidden" name="ram">
|
||||
<input type="hidden" name="storage">
|
||||
<input type="hidden" name="total">
|
||||
<div class="description check-ip">
|
||||
<input type="checkbox" name="ipv6"> Ipv6 Only<br>
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-primary" value="{% trans 'Buy Now!' %}"></input>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text">
|
||||
<h2 class="section-heading">{% trans "Simple and affordable: Try our virtual machine with featherlight price." %}</h2>
|
||||
|
||||
<div class="description">
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab laudantium quis quam nostrum ipsum est nisi asperiores provident recusandae aliquid, reiciendis vitae quisquam error, porro fuga obcaecati maiores dolores repudiandae?</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- /.banner -->
|
||||
|
||||
<!-- Footer -->
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<ul class="list-inline">
|
||||
<li>
|
||||
<a href="#">{% trans "Home" %}</a>
|
||||
</li>
|
||||
<li class="footer-menu-divider">⋅</li>
|
||||
<li>
|
||||
<a href="#about">{% trans "How it works" %}</a></li>
|
||||
<li class="footer-menu-divider">⋅</li>
|
||||
<li>
|
||||
<a href="#about">{% trans "Scale out" %}</a></li>
|
||||
<li>⋅</li>
|
||||
<li>
|
||||
<a href="#about">{% trans "Reliable and light" %}</a></li>
|
||||
<li class="footer-menu-divider">⋅</li>
|
||||
<li>
|
||||
<a href="#services">{% trans "Pricing" %}</a>
|
||||
</li>
|
||||
<li class="footer-menu-divider">⋅</li>
|
||||
<li>
|
||||
<a href="#contact">{% trans "Contact" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="copyright text-muted small">Copyright © ungleich GmbH {% now "Y" %}. All Rights Reserved</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="{% static 'datacenterlight/js/jquery.js' %}"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.onload=function(){
|
||||
$('.selectpicker').selectpicker({
|
||||
style: 'btn-link',
|
||||
windowPadding: 10,
|
||||
});
|
||||
|
||||
var hash = window.location.hash.substr(1);
|
||||
console.log(hash);
|
||||
if (hash == 'requestform'){
|
||||
$('#reques-success-message').modal('show');
|
||||
}
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.5.4/bootstrap-select.js"></script>
|
||||
|
||||
<!-- Bootstrap Core JavaScript -->
|
||||
<script src="{% static 'datacenterlight/js/bootstrap.min.js' %}"></script>
|
||||
<script src="{% static 'datacenterlight/js/main.js' %}"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,10 +1,12 @@
|
|||
from django.conf.urls import url
|
||||
|
||||
from .views import IndexView, BetaProgramView, LandingProgramView
|
||||
from .views import IndexView, BetaProgramView, LandingProgramView, BetaAccessView, PricingView
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^/?$', IndexView.as_view(), name='index'),
|
||||
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'^/beta_access?$', BetaAccessView.as_view(), name='beta_access'),
|
||||
]
|
||||
|
|
|
@ -5,6 +5,7 @@ from .models import BetaAccess, BetaAccessVMType, BetaAccessVM
|
|||
from django.contrib import messages
|
||||
from django.core.urlresolvers import reverse_lazy, reverse
|
||||
from utils.mailer import BaseEmail
|
||||
from django.shortcuts import render
|
||||
|
||||
from opennebula_api.models import OpenNebulaManager
|
||||
from opennebula_api.serializers import VirtualMachineTemplateSerializer
|
||||
|
@ -12,6 +13,46 @@ from opennebula_api.serializers import VirtualMachineTemplateSerializer
|
|||
class LandingProgramView(TemplateView):
|
||||
template_name = "datacenterlight/landing.html"
|
||||
|
||||
class PricingView(TemplateView):
|
||||
template_name = "datacenterlight/pricing.html"
|
||||
|
||||
class BetaAccessView(FormView):
|
||||
template_name = "datacenterlight/beta_access.html"
|
||||
form_class = BetaAccessForm
|
||||
success_message = "Thank you, we will contact you as soon as possible"
|
||||
|
||||
def form_valid(self, form):
|
||||
|
||||
context = {
|
||||
'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host())
|
||||
}
|
||||
|
||||
email_data = {
|
||||
'subject': 'DatacenterLight Beta Access Request',
|
||||
'to': form.cleaned_data.get('email'),
|
||||
'context': context,
|
||||
'template_name': 'request_access_confirmation',
|
||||
'template_path': 'datacenterlight/emails/'
|
||||
}
|
||||
email = BaseEmail(**email_data)
|
||||
email.send()
|
||||
|
||||
context.update({
|
||||
'email': form.cleaned_data.get('email')
|
||||
})
|
||||
|
||||
email_data = {
|
||||
'subject': 'DatacenterLight Beta Access Request',
|
||||
'to': 'info@ungleich.ch',
|
||||
'context': context,
|
||||
'template_name': 'request_access_notification',
|
||||
'template_path': 'datacenterlight/emails/'
|
||||
}
|
||||
email = BaseEmail(**email_data)
|
||||
email.send()
|
||||
|
||||
messages.add_message(self.request, messages.SUCCESS, self.success_message)
|
||||
return render(self.request, 'datacenterlight/beta_success.html', {})
|
||||
|
||||
class BetaProgramView(CreateView):
|
||||
template_name = "datacenterlight/beta.html"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
CORE: {{config.cpu|floatformat}},
|
||||
RAM: {{config.memory|floatformat}} GiB,
|
||||
SSD: {{config.disk_size|floatformat}} GiB,
|
||||
PRICE: {{config.price|floatformat}} CHF
|
||||
PRICE: {{config.price|floatformat}} CHF/Month
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
|
|
@ -41,11 +41,17 @@
|
|||
<div class="col-md-12 inline-headers">
|
||||
<h3>{{virtual_machine.hosting_company_name}}</h3>
|
||||
|
||||
{% if virtual_machine.ip %}
|
||||
{% if virtual_machine.ipv6 %}
|
||||
<div class="pull-right right-place">
|
||||
<button type="link" data-clipboard-text="{{virtual_machine.ip}}" id="copy_vm_id" class="to_copy btn btn-link"
|
||||
<button type="link"
|
||||
data-clipboard-text="{{virtual_machine.ipv4}}" id="copy_vm_id" class="to_copy btn btn-link"
|
||||
data-toggle="tooltip" data-placement="bottom" title="Copied" data-trigger="click">
|
||||
Ip: {{virtual_machine.ip}} <i class="fa fa-files-o" aria-hidden="true"></i>
|
||||
Ipv4: {{virtual_machine.ipv4}} <i class="fa fa-files-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button type="link"
|
||||
data-clipboard-text="{{virtual_machine.ipv6}}" id="copy_vm_id" class="to_copy btn btn-link"
|
||||
data-toggle="tooltip" data-placement="bottom" title="Copied" data-trigger="click">
|
||||
Ipv6: {{virtual_machine.ipv6}} <i class="fa fa-files-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
{% else %}
|
||||
|
@ -98,7 +104,7 @@
|
|||
<div class="row ">
|
||||
<div class="col-md-12 inline-headers">
|
||||
<h3>{% trans "Current pricing"%}</h3>
|
||||
<span class="h3 pull-right"><strong>{{virtual_machine.price|floatformat}} CHF</strong>/mo</span>
|
||||
<span class="h3 pull-right"><strong>{{virtual_machine.price|floatformat}} CHF</strong>/month</span>
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "ID"%}</th>
|
||||
<th>{% trans "Amount"%}</th>
|
||||
<th>{% trans "Ipv4"%}</th>
|
||||
<th>{% trans "Ipv6"%}</th>
|
||||
<th>{% trans "Status"%}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
@ -35,7 +36,12 @@
|
|||
{% for vm in vms %}
|
||||
<tr>
|
||||
<td scope="row">{{vm.vm_id}}</td>
|
||||
<td>{{vm.price}} CHF</td>
|
||||
{% if vm.ipv6 %}
|
||||
<td>{{vm.ipv4}}</td>
|
||||
|
||||
<td>{{vm.ipv6}}</td>
|
||||
{% endif %}
|
||||
|
||||
<td>
|
||||
|
||||
{% if vm.state == 'ACTIVE' %}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import oca
|
||||
import ipaddress
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
|
@ -73,8 +74,7 @@ class VirtualMachineTemplateSerializer(serializers.Serializer):
|
|||
return int(obj.template.memory)/1024
|
||||
|
||||
def get_name(self, obj):
|
||||
# TODO: Filter public- away
|
||||
return obj.name
|
||||
return obj.name.strip('public-')
|
||||
|
||||
class VirtualMachineSerializer(serializers.Serializer):
|
||||
"""Serializer to map the virtual machine instance into JSON format."""
|
||||
|
@ -87,9 +87,8 @@ class VirtualMachineSerializer(serializers.Serializer):
|
|||
|
||||
|
||||
disk_size = serializers.SerializerMethodField()
|
||||
ip = serializers.CharField(read_only=True,
|
||||
source='user_template.ungleich_public_ip',
|
||||
default='-')
|
||||
ipv4 = serializers.SerializerMethodField()
|
||||
ipv6 = serializers.SerializerMethodField()
|
||||
vm_id = serializers.IntegerField(read_only=True, source='id')
|
||||
state = serializers.CharField(read_only=True, source='str_state')
|
||||
price = serializers.SerializerMethodField()
|
||||
|
@ -152,4 +151,34 @@ class VirtualMachineSerializer(serializers.Serializer):
|
|||
def get_configuration(self, obj):
|
||||
template_id = obj.template.template_id
|
||||
template = OpenNebulaManager().get_template(template_id)
|
||||
return template.name
|
||||
return template.name.strip('public-')
|
||||
|
||||
def get_ipv4(self, obj):
|
||||
nic = obj.template.nics[0]
|
||||
if 'vm-ipv6-nat64-ipv4' in nic.network and is_in_v4_range(nic.mac):
|
||||
return str(v4_from_mac(nic.mac))
|
||||
else:
|
||||
return '-'
|
||||
|
||||
def get_ipv6(self, obj):
|
||||
nic = obj.template.nics[0]
|
||||
return nic.ip6_global
|
||||
|
||||
|
||||
def hexstr2int(string):
|
||||
return int(string.replace(':', ''), 16)
|
||||
|
||||
FIRST_MAC = hexstr2int('02:00:b3:39:79:4d')
|
||||
FIRST_V4 = ipaddress.ip_address('185.203.112.2')
|
||||
COUNT = 1000
|
||||
|
||||
def v4_from_mac(mac):
|
||||
"""Calculates the IPv4 address from a MAC address.
|
||||
|
||||
mac: string (the colon-separated representation)
|
||||
returns: ipaddress.ip_address object with the v4 address
|
||||
"""
|
||||
return FIRST_V4 + (hexstr2int(mac) - FIRST_MAC)
|
||||
|
||||
def is_in_v4_range(mac):
|
||||
return FIRST_MAC <= hexstr2int(mac) < FIRST_MAC + 1000
|
||||
|
|
Loading…
Reference in a new issue