diff --git a/pyconbalkan/conference/__init__.py b/pyconbalkan/conference/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/conference/admin.py b/pyconbalkan/conference/admin.py new file mode 100644 index 00000000..9cb49893 --- /dev/null +++ b/pyconbalkan/conference/admin.py @@ -0,0 +1,17 @@ +from django.contrib import admin + +from pyconbalkan.conference.models import Conference, CountDown + + +class ConferenceAdmin(admin.ModelAdmin): + class Meta: + model = Conference + + +class CountDownAdmin(admin.ModelAdmin): + class Meta: + model = CountDown + + +admin.site.register(Conference, ConferenceAdmin) +admin.site.register(CountDown, CountDownAdmin) diff --git a/pyconbalkan/conference/api_urls.py b/pyconbalkan/conference/api_urls.py new file mode 100644 index 00000000..8d3e84e8 --- /dev/null +++ b/pyconbalkan/conference/api_urls.py @@ -0,0 +1,6 @@ +from rest_framework import routers + +from pyconbalkan.conference.views import ConferenceViewSet + +router = routers.DefaultRouter() +router.register(r'conference', ConferenceViewSet) \ No newline at end of file diff --git a/pyconbalkan/conference/apps.py b/pyconbalkan/conference/apps.py new file mode 100644 index 00000000..cd92fc5c --- /dev/null +++ b/pyconbalkan/conference/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ConferenceConfig(AppConfig): + name = 'conference' diff --git a/pyconbalkan/conference/migrations/0001_initial.py b/pyconbalkan/conference/migrations/0001_initial.py new file mode 100644 index 00000000..bf02991d --- /dev/null +++ b/pyconbalkan/conference/migrations/0001_initial.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.11 on 2018-04-26 21:51 +from __future__ import unicode_literals + +from django.db import migrations, models +import django_countries.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Conference', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('active', models.BooleanField(default=False)), + ('event', models.CharField(blank=True, max_length=100, null=True)), + ('name', models.CharField(blank=True, max_length=100, null=True)), + ('year', models.PositiveIntegerField()), + ('number', models.PositiveIntegerField()), + ('city', models.CharField(blank=True, max_length=200, null=True)), + ('country', django_countries.fields.CountryField(blank=True, max_length=2, null=True)), + ('address', models.TextField(blank=True, null=True)), + ('from_date', models.DateField(blank=True, null=True)), + ('to_date', models.DateField(blank=True, null=True)), + ('max_attendees', models.PositiveIntegerField(blank=True, null=True)), + ('type', models.IntegerField(choices=[(0, 'International'), (1, 'National')])), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='CountDown', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('active', models.BooleanField(default=False)), + ('title', models.CharField(blank=True, max_length=100, null=True)), + ('count_down', models.DateTimeField(blank=True, null=True)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/pyconbalkan/conference/migrations/__init__.py b/pyconbalkan/conference/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/conference/models.py b/pyconbalkan/conference/models.py new file mode 100644 index 00000000..fb3e69cc --- /dev/null +++ b/pyconbalkan/conference/models.py @@ -0,0 +1,37 @@ +from django.db import models +from django_countries.fields import CountryField + +from pyconbalkan.core.models import SingleActiveModel + + +class Conference(SingleActiveModel): + INTERNATIONAL = 0 + NATIONAL = 1 + CONF_TYPE = ( + (INTERNATIONAL, 'International'), + (NATIONAL, 'National'), + ) + + event = models.CharField(null=True, blank=True, max_length=100) + name = models.CharField(null=True, blank=True, max_length=100) + year = models.PositiveIntegerField() + number = models.PositiveIntegerField() + city = models.CharField(null=True, blank=True, max_length=200) + country = CountryField(null=True, blank=True) + address = models.TextField(null=True, blank=True) + from_date = models.DateField(null=True, blank=True) + to_date = models.DateField(null=True, blank=True) + max_attendees = models.PositiveIntegerField(null=True, blank=True) + type = models.IntegerField(choices=CONF_TYPE) + + + def __str__(self): + return '{} {} {}'.format(self.event, self.name, self.year) + + +class CountDown(SingleActiveModel): + title = models.CharField(null=True, blank=True, max_length=100) + count_down = models.DateTimeField(null=True, blank=True) + + def __str__(self): + return self.title \ No newline at end of file diff --git a/pyconbalkan/conference/serializers.py b/pyconbalkan/conference/serializers.py new file mode 100644 index 00000000..5e8a3ed8 --- /dev/null +++ b/pyconbalkan/conference/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from pyconbalkan.conference.models import Conference + + +class ConferenceSerializer(serializers.ModelSerializer): + class Meta: + model = Conference + fields = '__all__' diff --git a/pyconbalkan/conference/templates/index.html b/pyconbalkan/conference/templates/index.html new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/conference/tests.py b/pyconbalkan/conference/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/pyconbalkan/conference/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/pyconbalkan/conference/views.py b/pyconbalkan/conference/views.py new file mode 100644 index 00000000..fbfda053 --- /dev/null +++ b/pyconbalkan/conference/views.py @@ -0,0 +1,9 @@ +from rest_framework import viewsets + +from pyconbalkan.conference.models import Conference +from pyconbalkan.conference.serializers import ConferenceSerializer + + +class ConferenceViewSet(viewsets.ModelViewSet): + queryset = Conference.objects.all() + serializer_class = ConferenceSerializer diff --git a/pyconbalkan/core/admin.py b/pyconbalkan/core/admin.py index 26f78a8e..c42474ae 100644 --- a/pyconbalkan/core/admin.py +++ b/pyconbalkan/core/admin.py @@ -3,3 +3,4 @@ class CoreConfig(AppConfig): name = 'core' + diff --git a/pyconbalkan/core/api_urls.py b/pyconbalkan/core/api_urls.py new file mode 100644 index 00000000..e69de29b diff --git a/pyconbalkan/core/models.py b/pyconbalkan/core/models.py index 71a83623..98103407 100644 --- a/pyconbalkan/core/models.py +++ b/pyconbalkan/core/models.py @@ -1,3 +1,21 @@ from django.db import models -# Create your models here. + +class SingleActiveModel(models.Model): + active = models.BooleanField(default=False) + + class Meta: + abstract = True + + def save(self, *args, **kwargs): + if self.active: + # select all other active items + qs = type(self).objects.filter(active=True) + # except self (if self already exists) + if self.pk: + qs = qs.exclude(pk=self.pk) + # and deactive them + qs.update(active=False) + + super(SingleActiveModel, self).save(*args, **kwargs) + diff --git a/pyconbalkan/core/routers.py b/pyconbalkan/core/routers.py new file mode 100644 index 00000000..a0924cdc --- /dev/null +++ b/pyconbalkan/core/routers.py @@ -0,0 +1,15 @@ +from rest_framework import routers + + +class DefaultRouter(routers.DefaultRouter): + """ + Extends `DefaultRouter` class to add a method for extending url routes from another router. + """ + def extend(self, router): + """ + Extend the routes with url routes of the passed in router. + + Args: + router: SimpleRouter instance containing route definitions. + """ + self.registry.extend(router.registry) \ No newline at end of file diff --git a/pyconbalkan/core/static/css/style.css b/pyconbalkan/core/static/css/style.css new file mode 100644 index 00000000..d9bf9cd2 --- /dev/null +++ b/pyconbalkan/core/static/css/style.css @@ -0,0 +1,246 @@ +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + src: local('Montserrat Regular'), local('Montserrat-Regular'), url(https://fonts.gstatic.com/s/montserrat/v12/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 900; + src: local('Montserrat Black'), local('Montserrat-Black'), url(https://fonts.gstatic.com/s/montserrat/v12/JTURjIg1_i6t8kCHKm45_epG3gnD_g.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + + +body { + font-family: 'Montserrat', sans-serif; + font-weight: 400; + max-width: 100%; + margin: 0; + /* The image used */ + /* Full height */ + height: 100%; + /* Center and scale the image nicely */ + background: url('/static/img/background.jpg') no-repeat no-repeat center center fixed; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.navbar-brand img { + height: auto; +} + +.round { + border-radius: 24px; +} + + +.btn-light { + background: transparent; + color: white; + border-color: transparent; +} + +.btn-light:hover, +.btn-light:focus, +.btn-light:active +{ + color: black; + border-color: #F3D66C; + outline: none !important; + box-shadow: none !important; + background: #F3D66C; +} + +.font900 { + font-family: 'Montserrat', sans-serif; + font-weight: 900; +} + +.one { + margin-bottom: -12px; + font-size: 4.5rem; +} + +h2 { + max-height: inherit; + letter-spacing: 0.01em; +} + +h3 { + font-size: 2rem; + margin-top: 5px; + margin-left: 2px; + max-height: inherit; + letter-spacing: 0.05em; +} + + +.row { + margin-left: 20px; + margin-right: 0px; +} + +hr { + width: 12%; + position: absolute; + border-width: 2px; + background: #22A4D9; +} + +.details { + margin-top: 50px; + margin-right: 10px; +} + +.font-yellow { + color: #F3D66C; +} + +.font-blue { + color: #22A4D9; +} + +.fa-calendar-alt, .fa-users, .fa-globe{ + color: #22A4D9; + display: inline-block; + width: 20px; +} + +.btn-primary { + background: #22A4D9; + border-color: #22A4D9; + color: white; + width: 200px; +} + +.sn-icons { + margin-top: 30px; + margin-right: 30px; + +} + +#days { + font-size: 3rem; + border: 10px solid white; + border-radius: 20px; + background-color: white; +} + +#days-text { + padding-left: 10px; + font-size: 3rem; +} + +.hms { + font-size: 1.8rem; +} + +.hms-text { + font-size: 0.6rem; + color: white; +} + +.countdown-timer{ + margin-top: 30px; +} + +ul.countdown { + list-style: none; + display: inline; + text-align: center; + padding-left: 15px; +} + +ul.countdown li { + display: inline-block; + vertical-align: -12px; + margin-right: 5px; +} + +ul.countdown li div { + margin-top: -5px; +} + +.btn-secondary { + background: #F3D66C; + border-color: #F3D66C; + color: black; +} + +.btn-secondary:hover, +.btn-secondary:focus, +.btn-secondary:active +{ + color: black; + border-color: #F3D66C; + outline: none !important; + box-shadow: none !important; + background: #F3D66C; +} + +.moveDown { + margin-top: 50px; +} + +#btnBuyNow { + width: 120px; +} + +.card { + background: transparent; + border: none; + margin-right: 0 !important; +} + +.card .row { + margin-left: 0 !important; +} + + +.card img { + width: 80px; + float: left; +} + +.card ul { + list-style: none; + vertical-align: middle; + color: white; + padding: 0; +} + +.card li:first-child { + font-size: 1rem; + display: grid; + padding-left: 10px; +} + +.card li { + font-size: 0.8rem; + display: grid; + padding-left: 10px; + margin-top: 5px; +} + +.card hr { + display: inline; + margin: 0 0 0 10px; +} + +.col-sm { + padding: 0; +} + +#seeMore { + width: 150px; +} + +#attend { + width: auto; +} \ No newline at end of file diff --git a/pyconbalkan/core/static/img/background.jpg b/pyconbalkan/core/static/img/background.jpg new file mode 100644 index 00000000..608a618f Binary files /dev/null and b/pyconbalkan/core/static/img/background.jpg differ diff --git a/pyconbalkan/core/static/img/favicon-16x16.png b/pyconbalkan/core/static/img/favicon-16x16.png new file mode 100644 index 00000000..401ccd11 Binary files /dev/null and b/pyconbalkan/core/static/img/favicon-16x16.png differ diff --git a/pyconbalkan/core/static/img/favicon-32x32.png b/pyconbalkan/core/static/img/favicon-32x32.png new file mode 100644 index 00000000..47a4d3f8 Binary files /dev/null and b/pyconbalkan/core/static/img/favicon-32x32.png differ diff --git a/pyconbalkan/core/static/img/logo.jpg b/pyconbalkan/core/static/img/logo.jpg new file mode 100644 index 00000000..86edc8c2 Binary files /dev/null and b/pyconbalkan/core/static/img/logo.jpg differ diff --git a/pyconbalkan/core/static/js/timer.js b/pyconbalkan/core/static/js/timer.js new file mode 100644 index 00000000..8f0f69e7 --- /dev/null +++ b/pyconbalkan/core/static/js/timer.js @@ -0,0 +1,30 @@ +// Set the date we're counting down to +var countDownDate = new Date("May 15, 2018 00:00:01").getTime(); + +// Update the count down every 1 second +var x = setInterval(function() { + + // Get todays date and time + var now = new Date().getTime(); + + // Find the distance between now an the count down date + var distance = countDownDate - now; + + // Time calculations for days, hours, minutes and seconds + var days = Math.floor(distance / (1000 * 60 * 60 * 24)); + var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); + var seconds = Math.floor((distance % (1000 * 60)) / 1000); + + // Output the result in an element with id="demo" + document.getElementById("days").innerHTML = days; + document.getElementById("hours").innerHTML = hours + ":"; + document.getElementById("minutes").innerHTML = minutes + ":"; + document.getElementById("seconds").innerHTML = seconds; + + // If the count down is over, write some text + if (distance < 0) { + clearInterval(x); + document.getElementById("demo").innerHTML = "EXPIRED"; + } +}, 1000); \ No newline at end of file diff --git a/pyconbalkan/core/templates/home.html b/pyconbalkan/core/templates/home.html new file mode 100644 index 00000000..a700f6c6 --- /dev/null +++ b/pyconbalkan/core/templates/home.html @@ -0,0 +1,198 @@ +{% load static %} + + + + +
+{{ conference.address }}
+{{ conference.from_date }} - {{ conference.to_date }}
+{{ conference.max_attendees }} attendees
+{{ conference.get_type_display }}
+
-
-