Missing files
This commit is contained in:
parent
1c5f403d41
commit
cd176537f1
|
@ -0,0 +1,102 @@
|
||||||
|
from django import forms
|
||||||
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
|
|
||||||
|
from crispy_forms.helper import FormHelper
|
||||||
|
from crispy_forms.layout import Layout, Fieldset, ButtonHolder, Submit
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from .models import User, Reference, QSO
|
||||||
|
from .validators import CallUsernameValidator
|
||||||
|
|
||||||
|
class CustomUserCreationForm(UserCreationForm):
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ("username",)
|
||||||
|
|
||||||
|
username = forms.CharField(max_length=50, validators=[CallUsernameValidator()])
|
||||||
|
|
||||||
|
class UpdateRefForm(forms.Form):
|
||||||
|
existingRef = forms.ModelChoiceField(label="Existing Reference", queryset=Reference.objects.all(), help_text="If reference already exists, select it here.", required=False)
|
||||||
|
newRefName = forms.CharField(max_length=50, label="New Reference", help_text="Enter name of new ref, if we should create a new", required=False)
|
||||||
|
|
||||||
|
def clean_newRefName(self):
|
||||||
|
data = self.cleaned_data["newRefName"].strip()
|
||||||
|
if Reference.objects.filter(name=data).count() > 0:
|
||||||
|
raise forms.ValidationError("Reference already exists")
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super(UpdateRefForm, self).clean()
|
||||||
|
|
||||||
|
existingRef = cleaned_data.get("existingRef")
|
||||||
|
newRefName = cleaned_data.get("newRefName")
|
||||||
|
|
||||||
|
if existingRef and newRefName:
|
||||||
|
raise forms.ValidationError("Select an existing ref or create a new one, not both!")
|
||||||
|
if not existingRef and not newRefName:
|
||||||
|
raise forms.ValidationError("Select either an existing ref or create a new one!")
|
||||||
|
|
||||||
|
class QSOForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = QSO
|
||||||
|
fields = ["time", "call", "band", "reportTX", "reportRX", "ownNo", "otherNo", "refStr", "remarks"]
|
||||||
|
|
||||||
|
widgets = {
|
||||||
|
"time": forms.DateTimeInput(attrs={"placeholder": "Current time"})
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, user, *args, **kwargs):
|
||||||
|
super(QSOForm, self).__init__(*args, **kwargs)
|
||||||
|
self.user = user
|
||||||
|
|
||||||
|
self.helper = FormHelper()
|
||||||
|
self.helper.form_id = "qso-log-form"
|
||||||
|
self.helper.form_class = "form-inline"
|
||||||
|
self.helper.form_style = 'inline'
|
||||||
|
self.helper.field_template = "bootstrap3/layout/inline_field.html"
|
||||||
|
self.helper.action = reverse("contest:log")
|
||||||
|
self.helper.add_input(Submit('submit', 'Log'))
|
||||||
|
|
||||||
|
self.helper.layout = Layout(
|
||||||
|
'time',
|
||||||
|
'call',
|
||||||
|
'band',
|
||||||
|
'reportTX',
|
||||||
|
'reportRX', 'ownNo', 'otherNo', 'refStr', 'remarks',
|
||||||
|
)
|
||||||
|
|
||||||
|
def clean_call(self):
|
||||||
|
data = self.cleaned_data["call"].upper().strip()
|
||||||
|
if Reference.objects.filter(name=data).count() > 0:
|
||||||
|
raise forms.ValidationError("Reference already exists")
|
||||||
|
|
||||||
|
try:
|
||||||
|
CallUsernameValidator()(data)
|
||||||
|
except forms.ValidationError:
|
||||||
|
raise forms.ValidationError("Enter a valid callsign (1-2 chars, a number, 1-4 chars, maybe a /[A-Z])")
|
||||||
|
|
||||||
|
if data == self.user.username:
|
||||||
|
raise forms.ValidationError("You cannot log QSOs with yourself")
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def clean_ownNo(self):
|
||||||
|
data = self.cleaned_data["ownNo"]
|
||||||
|
|
||||||
|
if data < 1 or data > 100000:
|
||||||
|
raise forms.ValidationError("Number has to be in range of [1, 1000000]")
|
||||||
|
|
||||||
|
try:
|
||||||
|
QSO.objects.get(owner=self.user, ownNo=data)
|
||||||
|
raise forms.ValidationError("You already logged a QSO with the number %s" % data)
|
||||||
|
except:
|
||||||
|
return data
|
||||||
|
|
||||||
|
def clean_otherNo(self):
|
||||||
|
data = self.cleaned_data["otherNo"]
|
||||||
|
|
||||||
|
if data < 1 or data > 100000:
|
||||||
|
raise forms.ValidationError("Number has to be in range of [1, 1000000]")
|
||||||
|
|
||||||
|
return data
|
|
@ -0,0 +1,22 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2017-01-18 11:20
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Contest',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=20)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,39 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2017-01-18 12:08
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0002_contest'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='band',
|
||||||
|
name='contest',
|
||||||
|
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='contest.Contest'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='contest',
|
||||||
|
name='callQrg',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='contest.Frequency'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='qso',
|
||||||
|
name='otherNo',
|
||||||
|
field=models.IntegerField(default=0),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='qso',
|
||||||
|
name='ownNo',
|
||||||
|
field=models.IntegerField(default=0),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,21 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2017-01-18 13:17
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0003_auto_20170118_1208'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='contest',
|
||||||
|
name='shortName',
|
||||||
|
field=models.CharField(default='test', max_length=20, unique=True),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,21 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2017-01-18 14:28
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0004_contest_shortname'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='frequency',
|
||||||
|
name='note',
|
||||||
|
field=models.CharField(default='', max_length=50),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,22 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2017-01-19 00:19
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0005_frequency_note'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='qso',
|
||||||
|
name='band',
|
||||||
|
field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='contest.Band'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,30 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2017-01-19 00:44
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0006_qso_band'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='qso',
|
||||||
|
name='remarks',
|
||||||
|
field=models.CharField(blank=True, max_length=50),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='qso',
|
||||||
|
name='reportRX',
|
||||||
|
field=models.CharField(default=59, max_length=7),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='qso',
|
||||||
|
name='reportTX',
|
||||||
|
field=models.CharField(default=59, max_length=7),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,32 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2017-01-19 12:02
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0007_auto_20170119_0044'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='qso',
|
||||||
|
name='ref',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='contest.Reference'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='qso',
|
||||||
|
name='refStr',
|
||||||
|
field=models.CharField(default='', max_length=20),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='qso',
|
||||||
|
name='time',
|
||||||
|
field=models.DateTimeField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,18 @@
|
||||||
|
from django.core import validators
|
||||||
|
from django.utils import six
|
||||||
|
from django.utils.deconstruct import deconstructible
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
@deconstructible
|
||||||
|
class CallUsernameValidator(validators.RegexValidator):
|
||||||
|
#regex = r'^[\w.@+-]+$'
|
||||||
|
regex = r'^(?:[A-Z]+/)?[A-Z]{1,2}[0-9][A-Z]{1,4}(?:/[A-Z])?$'
|
||||||
|
message = _(
|
||||||
|
'Enter a valid Callsign as Username, ALL UPPERCASE, if needed with /A /B,'
|
||||||
|
'e.g. DL7BST, DN1BER/A, DL/OE1FOO'
|
||||||
|
)
|
||||||
|
flags = re.ASCII if six.PY3 else 0
|
||||||
|
|
|
@ -0,0 +1,320 @@
|
||||||
|
/* ==========================================================================
|
||||||
|
UNI-FORM STYLE by DRAGAN BABIC
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2013, Dragan Babic
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
NOTE ABOUT STYLING FORMS
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
When styling your form make sure to copy the selector from uni-form.css
|
||||||
|
into this file and override it with your properties and values.
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form {
|
||||||
|
margin: 1.5em 0;
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Form titles
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form .uni-form-title {
|
||||||
|
margin: 1.5em 0;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Holders
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder {
|
||||||
|
padding: 1em 1em 1.5em 1em;
|
||||||
|
border: 1px solid #efefef;
|
||||||
|
border-width: 1px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels .ctrl-holder {
|
||||||
|
padding: 1.5em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form fieldset .ctrl-holder:last-child {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder.focused {
|
||||||
|
background: #fffcdf
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .button-holder {
|
||||||
|
background: #efefef;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
padding: 1.5em;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Design for input fields
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form .input-text,
|
||||||
|
.uni-form .input-textarea {
|
||||||
|
padding: 5px;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
-webkit-box-shadow: 1px 1px 3px rgba(0,0,0,.15) inset;
|
||||||
|
box-shadow: 1px 1px 3px rgba(0,0,0,.15) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .input-text:focus,
|
||||||
|
.uni-form .input-textarea:focus {
|
||||||
|
border-color: #343434;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .input-textarea {
|
||||||
|
height: 12em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .input-select {}
|
||||||
|
|
||||||
|
.uni-form .input-file {}
|
||||||
|
|
||||||
|
/* Disabled inputs */
|
||||||
|
|
||||||
|
.uni-form .input-disabled {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
border-color: #ccc;
|
||||||
|
color: #999;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Buttons
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form .action-primary {
|
||||||
|
padding: 1em 2em;
|
||||||
|
line-height: 1;
|
||||||
|
background: #254a86;
|
||||||
|
border: 1px solid #163362;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .action-primary:focus,
|
||||||
|
.uni-form .action-primary:hover {
|
||||||
|
background: #2b58a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .action-primary:active {
|
||||||
|
background: #1d3c6d;
|
||||||
|
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,.5) inset;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,.5) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .action-secondary,
|
||||||
|
.uni-form button.action-secondary,
|
||||||
|
.uni-form input[type=submit].action-secondary {
|
||||||
|
float: right;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
margin: 1.25em 0 0 0;
|
||||||
|
padding: 0;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disabled actions */
|
||||||
|
|
||||||
|
.uni-form .action-disabled,
|
||||||
|
.uni-form .action-disabled:link,
|
||||||
|
.uni-form .action-disabled:visited,
|
||||||
|
.uni-form .action-disabled:focus,
|
||||||
|
.uni-form .action-disabled:hover,
|
||||||
|
.uni-form .action-disabled:active {
|
||||||
|
background: #ccc;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
color: #999;
|
||||||
|
text-shadow: 1px 1px 0 rgba(255,255,255,.25);
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Required fields asterisks
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form .inline-labels label em,
|
||||||
|
.uni-form .inline-labels .label em {
|
||||||
|
font-style: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Labels within grouped controls
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form .multi label {
|
||||||
|
margin-top: .3em; /* Compensate for the smaller font size */
|
||||||
|
font-size: .85em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Form hints
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form .form-hint {
|
||||||
|
padding-top: .3em; /* Compensate for the smaller font size */
|
||||||
|
font-size: .85em;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder.focused .form-hint {
|
||||||
|
color: #343434;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Messages
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* Error message at the top of the form ------------------------------------- */
|
||||||
|
|
||||||
|
.uni-form #errorMsg {
|
||||||
|
background: #ffdfdf;
|
||||||
|
border: 1px solid #f3afb5;
|
||||||
|
margin: 1.5em 0;
|
||||||
|
padding: 0 1.5em;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form #errorMsg h3 {
|
||||||
|
margin: 1em 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form #errorMsg ol {
|
||||||
|
margin: 1.5em 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form #errorMsg li {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 0 4px 0;
|
||||||
|
padding: 7px;
|
||||||
|
background: #f6bec1;
|
||||||
|
position: relative;
|
||||||
|
font-size: .85em;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Holder errors ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder.error,
|
||||||
|
.uni-form .ctrl-holder.focused.error {
|
||||||
|
background-color: #ffdfdf;
|
||||||
|
border-color: #f3afb5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder.error .input-text.error,
|
||||||
|
.uni-form .ctrl-holder.error .input-file.error,
|
||||||
|
.uni-form .ctrl-holder.error .input-select.error,
|
||||||
|
.uni-form .ctrl-holder.error .input-textarea.error {
|
||||||
|
color: #af4c4c;
|
||||||
|
border-color: #c55f68;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Success messages at the top of the form ---------------------------------- */
|
||||||
|
|
||||||
|
.uni-form #okMsg {
|
||||||
|
background: #e1f4cd;
|
||||||
|
border: 1px solid #b6cda4;
|
||||||
|
margin: 0 0 1.5em 0;
|
||||||
|
padding: 1.5em;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form #okMsg p {
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Holder valid input ------------------------------------------------------- */
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder.valid {
|
||||||
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAABpElEQVRIiWNgGAWDAfTvV+2vX6W0/v//UAN0OUZqWbLsoV7BodXv+mF8fUeexkzjGw0wPhM1LPn/v0LhyLp39chiF/d/qUf2GTM1LPqp/GT99y//NJDF2DiZHniZHa+E8Sn20bKHegUfXv1xQBefmGUeiMynyKL//0MNkOMFBvQdeRoZGVdfQBajKOi+yHzd/vvnfwlkMW5+5gvVPncj0dWS7aPpZzUavn78i5GMe1LMErGpJ8ui//9DDS7u/1KPLo4tyGAAI+j+/w81+Kn8bXndaiXGxU3PsWoiJchgAMVH//+HGmRPOL7/w6s/DusmvJq/649RAroGUoMMq0XZE47v//eXQQDGR7eMnCDDahE2ALPs///7AiVzTs1HlxcQYzmAXNTgAihlHSzokH2FbCB6xmRiZvgwtSDGkJGx4wEhi1B8xMi4+sLUAktHJmaGD+gKseV+myChRmIswbCIkGXIQECM5UCU/KUJxFiC1SJiLGNiZvjQHhuBN5URZREhy0gJMoIW4bKM1CAjCfz/H2pQv0ppfesW5fn//9/HSJGjgKYAAELOyUHrhNdJAAAAAElFTkSuQmCC);
|
||||||
|
background-position: 99% 1em;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 18px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels .ctrl-holder.valid {
|
||||||
|
background-position: 31% 1.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctrl-holder.valid .input-text,
|
||||||
|
.ctrl-holder.valid .input-select,
|
||||||
|
.ctrl-holder.valid .input-textarea {
|
||||||
|
border-color: #88a24f;
|
||||||
|
color: #88a24f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Columns
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* Remove borders from .ctrl-holder */
|
||||||
|
|
||||||
|
.uni-form-row > .ctrl-holder {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add borders to rows */
|
||||||
|
|
||||||
|
.uni-form-row {
|
||||||
|
border: 1px solid #efefef;
|
||||||
|
border-width: 1px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form-row:last-child {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
480 breakpoint
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
@media screen and (max-width: 480px) {
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder,
|
||||||
|
.uni-form .inline-labels .ctrl-holder {
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder.valid,
|
||||||
|
.uni-form .inline-labels .ctrl-holder.valid {
|
||||||
|
background-position: 97% 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,425 @@
|
||||||
|
/* ==========================================================================
|
||||||
|
Copyright (c) 2013, Dragan Babic
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
Generals
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form * {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-ms-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset stuff and prevent inheritance */
|
||||||
|
|
||||||
|
.uni-form fieldset {
|
||||||
|
border: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This are the main units that contain form elements */
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder,
|
||||||
|
.uni-form .button-holder {}
|
||||||
|
|
||||||
|
/* Clear all floats */
|
||||||
|
|
||||||
|
.uni-form:after,
|
||||||
|
.uni-form .button-holder:after,
|
||||||
|
.uni-form .ctrl-holder:after,
|
||||||
|
.uni-form-row:after {
|
||||||
|
content: ".";
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
line-height: 0;
|
||||||
|
font-size: 0;
|
||||||
|
clear: both;
|
||||||
|
min-height: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form label,
|
||||||
|
.uni-form button {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Default layout
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
Styles for form controls where labels are above the input elements
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* Target only the "main" labels */
|
||||||
|
|
||||||
|
.uni-form .ctrl-holder > label,
|
||||||
|
.uni-form .ctrl-holder > .label {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Required fields asterisk styling */
|
||||||
|
|
||||||
|
.uni-form label em,
|
||||||
|
.uni-form .label em {
|
||||||
|
float: left;
|
||||||
|
width: .75em;
|
||||||
|
margin: 0 0 0 -.75em;
|
||||||
|
font-style: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Float the input elements */
|
||||||
|
|
||||||
|
.uni-form .ctrl,
|
||||||
|
.uni-form .input-text,
|
||||||
|
.uni-form .input-file,
|
||||||
|
.uni-form .input-select,
|
||||||
|
.uni-form .input-textarea {
|
||||||
|
float: left;
|
||||||
|
width: 65%; /* 2% for spacing */
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .ctrl {
|
||||||
|
padding-right: 3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make some spacing between the label and the input/list */
|
||||||
|
|
||||||
|
.uni-form label + .input-text,
|
||||||
|
.uni-form label + .input-file,
|
||||||
|
.uni-form label + .input-select,
|
||||||
|
.uni-form label + .input-textarea {
|
||||||
|
margin-top: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Postition the hints */
|
||||||
|
|
||||||
|
.uni-form .form-hint {
|
||||||
|
float: right;
|
||||||
|
width: 33%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouped controls (one below the other by default) */
|
||||||
|
|
||||||
|
.uni-form .multi {
|
||||||
|
float: left;
|
||||||
|
width: 67%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 3% 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .multi + .form-hint {
|
||||||
|
margin-top: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .multi > li {
|
||||||
|
margin: .5em 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alternate layout for grouped controls (stacked inline) */
|
||||||
|
|
||||||
|
.uni-form .multi-inline > li {
|
||||||
|
float: left;
|
||||||
|
margin: .5em 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .columns-2 > li {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .columns-2 > li + li {
|
||||||
|
padding-left: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .columns-3 > li {
|
||||||
|
width: 33.3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .columns-3 > li + li,
|
||||||
|
.uni-form .columns-3 > li + li + li {
|
||||||
|
padding-left: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .multi .input-text,
|
||||||
|
.uni-form .multi .input-select,
|
||||||
|
.uni-form .multi select {
|
||||||
|
display: inline-block;
|
||||||
|
float: none;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Alternate layout
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
Styles for form controls where labels are in line with the input elements
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
Set the class of the parent (preferably to a fieldset) to .inline-labels
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form .inline-labels .ctrl-holder > label,
|
||||||
|
.uni-form .inline-labels .ctrl-holder > .label {
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
width: 33%;
|
||||||
|
padding-right: 3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Float the input elements */
|
||||||
|
|
||||||
|
.uni-form .ctrl,
|
||||||
|
.uni-form .inline-labels .input-text,
|
||||||
|
.uni-form .inline-labels .input-file,
|
||||||
|
.uni-form .inline-labels .input-select,
|
||||||
|
.uni-form .inline-labels .input-textarea {
|
||||||
|
float: left;
|
||||||
|
width: 67%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Postition the hints */
|
||||||
|
|
||||||
|
.uni-form .inline-labels .form-hint {
|
||||||
|
clear: both;
|
||||||
|
float: none;
|
||||||
|
width: auto;
|
||||||
|
margin-left: 33%;
|
||||||
|
padding-top: .5em; /* Must use padding because of the clearing */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouped controls (one below the other by default) */
|
||||||
|
|
||||||
|
.uni-form .inline-labels .multi {
|
||||||
|
float: left;
|
||||||
|
width: 67%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels .multi > li {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels .multi > li + li {
|
||||||
|
margin-top: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels .multi label {
|
||||||
|
float: none;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels .multi .input-text,
|
||||||
|
.uni-form .inline-labels .multi .input-select,
|
||||||
|
.uni-form .inline-labels .multi .input-file,
|
||||||
|
.uni-form .inline-labels .multi .input-textarea {
|
||||||
|
float: none;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alternate layout for grouped controls (stacked inline) */
|
||||||
|
|
||||||
|
.uni-form .inline-labels .multi-inline > li + li {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Additional stuff
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* When you don't want to use a label for grouped fields */
|
||||||
|
|
||||||
|
.uni-form .inline-labels .no-label .multi {
|
||||||
|
margin-left: 33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Classes for control of the widths of the fields */
|
||||||
|
|
||||||
|
.uni-form .small {
|
||||||
|
width: 30% !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .medium {
|
||||||
|
width: 45% !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .large {
|
||||||
|
float: none;
|
||||||
|
display: block;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .large + .form-hint,
|
||||||
|
.uni-form .inline-labels .large + .form-hint {
|
||||||
|
float: none;
|
||||||
|
width: auto;
|
||||||
|
margin-left: 0;
|
||||||
|
padding-top: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .auto {
|
||||||
|
width: auto !important;
|
||||||
|
height: auto !important;
|
||||||
|
display: inline-block !important;
|
||||||
|
float: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make spacing in between two inputs */
|
||||||
|
|
||||||
|
.uni-form .small + input,
|
||||||
|
.uni-form .medium + input,
|
||||||
|
.uni-form .auto + input,
|
||||||
|
.uni-form .small + select,
|
||||||
|
.uni-form .medium + select,
|
||||||
|
.uni-form .auto + select {
|
||||||
|
margin-right: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Read-Only output
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* Default layout */
|
||||||
|
|
||||||
|
.uni-form .read-only-label {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .read-only {
|
||||||
|
margin: .5em 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .read-only .choice-label {
|
||||||
|
color: #777;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: .8em;
|
||||||
|
letter-spacing: .15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alternate layout */
|
||||||
|
|
||||||
|
.uni-form .inline-labels .read-only-label {
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
width: 33%;
|
||||||
|
margin: 0;
|
||||||
|
padding-right: 3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels .read-only {
|
||||||
|
float: right;
|
||||||
|
width: 67%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels .read-only + .read-only {
|
||||||
|
margin-top: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Columns
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.uni-form-row {}
|
||||||
|
|
||||||
|
.uni-form-row > .ctrl-holder {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns-2 > .ctrl-holder {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns-3 > .ctrl-holder {
|
||||||
|
width: 33.3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
480 breakpoint
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
@media screen and (max-width: 480px) {
|
||||||
|
|
||||||
|
/* Default layout selectors */
|
||||||
|
.uni-form .ctrl-holder > label,
|
||||||
|
.uni-form .ctrl-holder > .label,
|
||||||
|
.uni-form .input-text,
|
||||||
|
.uni-form .input-select,
|
||||||
|
.uni-form .input-textarea,
|
||||||
|
.uni-form .input-file,
|
||||||
|
.uni-form .ctrl,
|
||||||
|
.uni-form .multi,
|
||||||
|
.uni-form .multi-inline > li,
|
||||||
|
.uni-form .form-hint,
|
||||||
|
/* Alternate layout selectors */
|
||||||
|
.uni-form .inline-labels .ctrl-holder > label,
|
||||||
|
.uni-form .inline-labels .ctrl-holder > .label,
|
||||||
|
.uni-form .inline-labels .input-text,
|
||||||
|
.uni-form .inline-labels .input-select,
|
||||||
|
.uni-form .inline-labels .input-textarea,
|
||||||
|
.uni-form .inline-labels .input-file,
|
||||||
|
.uni-form .inline-labels .ctrl,
|
||||||
|
.uni-form .multi,
|
||||||
|
.uni-form .inline-labels .multi-inline > li,
|
||||||
|
.uni-form .inline-labels .form-hint,
|
||||||
|
.uni-form .inline-labels .no-label .multi {
|
||||||
|
float: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels label + .input-text,
|
||||||
|
.uni-form .inline-labels label + .input-file,
|
||||||
|
.uni-form .inline-labels label + .input-select,
|
||||||
|
.uni-form .inline-labels label + .input-textarea {
|
||||||
|
margin-top: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .inline-labels .ctrl-holder > label,
|
||||||
|
.uni-form .inline-labels .ctrl-holder > .label,
|
||||||
|
.uni-form .multi,
|
||||||
|
.uni-form .multi-inline > li,
|
||||||
|
.uni-form .columns-2 > li + li,
|
||||||
|
.uni-form .columns-3 > li + li,
|
||||||
|
.uni-form .columns-3 > li + li + li {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-form .form-hint,
|
||||||
|
.uni-form .inline-labels .form-hint,
|
||||||
|
.uni-form .inline-labels .no-label .multi{
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Welcome, {{ user }}</h2>
|
||||||
|
{% if user.ref %}
|
||||||
|
{# user has a reference, we can start logging QSOs! #}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<p>
|
||||||
|
Welcome to {{ contest }}!
|
||||||
|
</p><p>
|
||||||
|
You got yourself a ref registered. Very nice. Now you are ready to go! So go ahead and <a href="{% url "contest:log" %}">log some QSOs</a>!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<p>
|
||||||
|
Hey you, {{ user }}, you don't have a <abbr title="You know, like, location, where you are">ref</abbr>!
|
||||||
|
You should <strong>get your ref registered</strong>!
|
||||||
|
Get yourself registered with your callsign and your current location by calling out to <strong>DK0TU</strong>
|
||||||
|
on {{ contest.callQrg }}.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if user.is_staff %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<p>Hey, you are <strong>staff</strong>. Do you want to <a href="{% url "contest:registerRefs" %}">register people</a>?</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Welcome!</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Log a QSO!</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<style scoped>
|
||||||
|
#id_reportRX, #id_reportTX {
|
||||||
|
width: 25px;
|
||||||
|
}
|
||||||
|
#id_ownNo, #id_otherNo {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
#id_refStr {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
#id_call {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<!--
|
||||||
|
{% crispy form %}
|
||||||
|
-->
|
||||||
|
<form method="post" action="{% url "contest:log" %}" class="uniForm form-inline">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<!--
|
||||||
|
{% for field in form %}
|
||||||
|
<div class="form-group col-md-1">
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
-->
|
||||||
|
<input type="submit" value="Log">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Your QSO log</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>No.</th>
|
||||||
|
<th>Time</th>
|
||||||
|
<th>Call</th>
|
||||||
|
<th>Band</th>
|
||||||
|
<th>TX Report</th>
|
||||||
|
<th>RX Report</th>
|
||||||
|
<th>Other No.</th>
|
||||||
|
<th>Reference</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for qso in qsos %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ qso.ownNo }}</td>
|
||||||
|
<td>{{ qso.time }}</td>
|
||||||
|
<td>{{ qso.call }}</td>
|
||||||
|
<td>{{ qso.band }}</td>
|
||||||
|
<td>{{ qso.reportTX }}</td>
|
||||||
|
<td>{{ qso.reportRX }}</td>
|
||||||
|
<td>{{ qso.otherNo }}</td>
|
||||||
|
<td>{{ qso.refStr }}</td>
|
||||||
|
<td><a href="{% url "contest:logEdit" qso.id %}">Edit</a> <a href="{% url "contest:logDelete" qso.id %}">Delete</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Welcome!</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
We have the User {{ user }}, create a ref for them or choose an existing ref!
|
||||||
|
|
||||||
|
Are you sure you want to delete this QSO?
|
||||||
|
<form method="post" action="{% url "contest:logDelete" qso.id %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>QSO</th><td>{{ qso }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<input type="submit" name="delete" value="yes">
|
||||||
|
<input type="submit" name="delete" value="no">
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Welcome!</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
We have the User {{ user }}, create a ref for them or choose an existing ref!
|
||||||
|
|
||||||
|
<form method="post" action="{% url "contest:logEdit" qso.id %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>User</th><td>{{ user }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ form.as_table }}
|
||||||
|
</table>
|
||||||
|
<input type="submit" value="Save">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>No.</th>
|
||||||
|
<th>Time</th>
|
||||||
|
{% if logShowComplete %}
|
||||||
|
<th>Call A</th>
|
||||||
|
<th>Call B</th>
|
||||||
|
{% else %}
|
||||||
|
<th>Call</th>
|
||||||
|
{% endif %}
|
||||||
|
<th>Band</th>
|
||||||
|
<th>TX Report</th>
|
||||||
|
<th>RX Report</th>
|
||||||
|
<th>Other No.</th>
|
||||||
|
<th>Reference</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for qso in qsos %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ qso.ownNo }}</td>
|
||||||
|
<td>{{ qso.time }}</td>
|
||||||
|
{% if logShowComplete %}
|
||||||
|
<td>{{ qso.owner.username }}</td>
|
||||||
|
<td>{{ qso.call }}</td>
|
||||||
|
{% else %}
|
||||||
|
<td>{{ qso.call }}</td>
|
||||||
|
{% endif %}
|
||||||
|
<td>{{ qso.band }}</td>
|
||||||
|
<td>{{ qso.reportTX }}</td>
|
||||||
|
<td>{{ qso.reportRX }}</td>
|
||||||
|
<td>{{ qso.otherNo }}</td>
|
||||||
|
<td>{{ qso.refStr }}</td>
|
||||||
|
<td><a href="{% url "contest:logEdit" qso.id %}">Edit</a> <a href="{% url "contest:logDelete" qso.id %}">Delete</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
|
@ -0,0 +1,51 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Contest Rules && Overview!</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="panel-heading">The Contest</div>
|
||||||
|
<p>
|
||||||
|
Welcome to {{ contest.name }}!
|
||||||
|
<p/>
|
||||||
|
<p>We might be laid back people here at {{ contest.name }}, but we have some rules!</p>
|
||||||
|
<p>The <abbr title="Frequency">QRG</abbr>-changing is a serious thing. Also there is other stuff. But
|
||||||
|
maybe it's funnier if you find that out by yourself. And we punish you for not knowing. Such
|
||||||
|
is live.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="panel-heading">QRGs</div>
|
||||||
|
<p>The following frequencies may be used in this contest</p>
|
||||||
|
<table class="table table-inverse">
|
||||||
|
<thead class="thead-inverse">
|
||||||
|
<tr>
|
||||||
|
<th>Channel</th>
|
||||||
|
<th>Band</th>
|
||||||
|
<th>QRG</th>
|
||||||
|
<th>Note</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for qrg in qrgs %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ qrg.channel }}</td>
|
||||||
|
<td>{{ qrg.band }}</td>
|
||||||
|
<td>{{ qrg.qrg }}</td>
|
||||||
|
<td>{{ qrg.note }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Welcome!</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<p>
|
||||||
|
Register Someone!!!!
|
||||||
|
Here be FORM for registering someone without a ref
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Contest Stations</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
Here is a Table with all OMs/YLs in the contest!
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Call</th>
|
||||||
|
<th>Ref</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for u in alluser %}
|
||||||
|
<tr class="{% if not u.ref %}danger{% endif %}">
|
||||||
|
<td>{{ u.username }}</td>
|
||||||
|
<td>{{ u.ref|default:"unknown / unset" }}</td>
|
||||||
|
<td><a href="{% url "contest:updateRef" u.id %}">Update / Create ref</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Current QSOs</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{% include "contest/logTable.html" with logShowComplete=1 qsos=qsos %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Welcome!</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
We have the User {{ user }}, create a ref for them or choose an existing ref!
|
||||||
|
|
||||||
|
<form method="post" action="{% url "contest:updateRef" user.id %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>User</th><td>{{ user }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ form.as_table }}
|
||||||
|
</table>
|
||||||
|
<input type="submit" value="Save">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Welcome!</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
I have {{ call_count }} callsigns in my Database!
|
||||||
|
<form method="POST" action="{% url 'register' %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table>
|
||||||
|
{{ form.as_table }}
|
||||||
|
</table>
|
||||||
|
<input type="submit" value="Create User">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in New Issue