Added main page. Added links page
This commit is contained in:
@@ -33,6 +33,8 @@ ALLOWED_HOSTS = [env('HOST_1')]
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'main',
|
||||
'links',
|
||||
'faerun_calendar',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
@@ -106,7 +108,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/4.0/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
LANGUAGE_CODE = 'ru-ru'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
|
||||
+3
-1
@@ -20,5 +20,7 @@ from django.conf.urls.static import static
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('', include('faerun_calendar.urls')),
|
||||
path('', include('main.urls')),
|
||||
path('calendar/', include('faerun_calendar.urls')),
|
||||
path('links/', include('links.urls')),
|
||||
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
|
||||
Binary file not shown.
@@ -1,17 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
{% extends 'main/pagetemplate.html' %}
|
||||
|
||||
{% load static %}
|
||||
{% block pagetitle %}
|
||||
Календарь
|
||||
{% endblock %}
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Calendar</title>
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{% static 'faerun_calendar/css/main.css' %}">
|
||||
</head>
|
||||
<body>
|
||||
{% block content %}
|
||||
<div class="calendarpage">
|
||||
<h1>Календарь</h1>
|
||||
{% include 'faerun_calendar/calendar.html' %}
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
|
||||
|
||||
def index(request):
|
||||
return render(request, 'faerun_calendar/index.html')
|
||||
# return HttpResponse('<h1>Calendar</h1>')
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class LinksConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'links'
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
@@ -0,0 +1,18 @@
|
||||
{% extends 'main/pagetemplate.html' %}
|
||||
|
||||
{% block pagetitle %}
|
||||
Полезные ссылки
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="linkspage">
|
||||
<h1>Полезные ссылки</h1>
|
||||
<ul>
|
||||
<li><a href="https://drive.google.com/drive/folders/1GgZ5pwoZEv9AwnsgfSLYpTIP0MtFsez_">Записи игр по Драконьему кушу (Google Drive)</a></li>
|
||||
<li><a href="https://disk.yandex.ru/d/A9vQyEO6W_kZVg">Записи игр по Драконьему кушу (Яндекс Диск)</a></li>
|
||||
<li><a href="https://hobbyworld.ru//download/rules/DnD_character_list.pdf">Лист персонажа (документ PDF)</a></li>
|
||||
<li><a href="https://hobbyworld.ru//download/rules/Glossary5E_2.xlsx">Глоссарий (книга Excel)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@@ -0,0 +1,8 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
|
||||
def index(request):
|
||||
return render(request, 'links/index.html')
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class MainConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'main'
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
@@ -0,0 +1,33 @@
|
||||
aside.menu {
|
||||
border: 3px solid black;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 15px;
|
||||
margin: 25px;
|
||||
}
|
||||
|
||||
aside.menu ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
aside.menu li {
|
||||
display: flex;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
aside.menu a {
|
||||
border-radius: 10px;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
background: DeepSkyBlue;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
aside.menu a:hover {
|
||||
background: DodgerBlue;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{% extends 'main/pagetemplate.html' %}
|
||||
|
||||
{% block pagetitle %}
|
||||
Главная страница
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="mainpage">
|
||||
<h1>Главная страница</h1>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
{% load static %}
|
||||
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block pagetitle %}{% endblock %}</title>
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{% static 'main/css/main.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'faerun_calendar/css/main.css' %}">
|
||||
|
||||
<link rel="icon" href="{% static 'iconsmall.png' %}">
|
||||
<link rel="apple-touch-icon" href="{% static 'iconbig.png' %}">
|
||||
</head>
|
||||
<body>
|
||||
<aside class="menu">
|
||||
<ul>
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/calendar">Календарь</a></li>
|
||||
<li><a href="/links">Полезные ссылки</a></li>
|
||||
<li><a href="/static/ookona.html">Оокона</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@@ -0,0 +1,8 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
|
||||
def index(request):
|
||||
return render(request, 'main/index.html')
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,339 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
label {
|
||||
background: azure;
|
||||
border: solid black 1px;
|
||||
border-radius: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
input[type=text] {
|
||||
background: LightYellow;
|
||||
border: solid black 1px;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
}
|
||||
hr {
|
||||
clear: both;
|
||||
}
|
||||
input.error {
|
||||
background: salmon;
|
||||
}
|
||||
div.misc, div.abilities, div.skills {
|
||||
float: left;
|
||||
min-height: 30px;
|
||||
}
|
||||
div.misc {
|
||||
min-width: 280px;
|
||||
}
|
||||
div.abilities {
|
||||
min-width: 200px;
|
||||
}
|
||||
div.skills {
|
||||
min-width: 280px;
|
||||
}
|
||||
div.misc, div.abilities, div.skills {
|
||||
margin: 5px 15px;
|
||||
border: solid black 2px;
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
div.misc *, div.abilities *, div.skills * {
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
div.abilities input, div.skills input {
|
||||
max-width: 25px;
|
||||
}
|
||||
label.skills {
|
||||
padding: 5px;
|
||||
}
|
||||
input[type=checkbox]:checked ~ .skills {
|
||||
color: white;
|
||||
background: navy;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
const checkbox_suffix = "_cb";
|
||||
const message_suffix = "_msg";
|
||||
|
||||
const min_ability = 10;
|
||||
const max_ability = 80;
|
||||
const max_sum_ability = 80;
|
||||
|
||||
class Ability {
|
||||
constructor(name, short_name_rus, long_name_rus) {
|
||||
this.name = name;
|
||||
this.short_name_rus = short_name_rus;
|
||||
this.long_name_rus = long_name_rus;
|
||||
}
|
||||
}
|
||||
const abilities = [
|
||||
new Ability("dexterity", "ЛВК", "Ловкость"),
|
||||
new Ability("strength", "СИЛ", "Сила"),
|
||||
new Ability("constitution", "ВЫН", "Выносливость"),
|
||||
new Ability("appearance", "НАР", "Наружность"),
|
||||
new Ability("charisma", "ХАР", "Харизма"),
|
||||
new Ability("will", "ВОЛ", "Воля"),
|
||||
new Ability("wisdom", "МУД", "Мудрость"),
|
||||
new Ability("intelligence", "ИНТ", "Интеллект"),
|
||||
]
|
||||
|
||||
class Skill {
|
||||
constructor(name, base, name_rus, dependencies) {
|
||||
this.name = name;
|
||||
this.base = base;
|
||||
this.name_rus = name_rus;
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
}
|
||||
const skills = [
|
||||
new Skill("light_firearm", 5, "Лёгкий огнестрел", {}),
|
||||
new Skill("medium_firearm", 5, "Средний огнестрел", {}),
|
||||
new Skill("heavy_firearm", 5, "Тяжёлый огнестрел", {}),
|
||||
new Skill("recon", 5, "Разведка", {}),
|
||||
new Skill("gambling", 1, "Азартные игры", {}),
|
||||
new Skill("artillery", 0, "Артиллерия", {}),
|
||||
new Skill("barter", 10, "Бартер", {}),
|
||||
new Skill("blocking", 10, "Блокирование", {}),
|
||||
new Skill("accounting", 5, "Бухгалтерское дело", {}),
|
||||
new Skill("riding", 5, "Верховая езда", {}),
|
||||
new Skill("lockpicking", 1, "Взлом", {}),
|
||||
new Skill("explosives", 0, "Взрывчатка", {}),
|
||||
new Skill("pole_weapons", 5, "Древковое оружие", {}),
|
||||
new Skill("blunt_weapons", 10, "Дробящее оружие", {}),
|
||||
new Skill("slashing_weapons", 5, "Рубящее оружие", {}),
|
||||
new Skill("pierce_weapons", 5, "Колющее оружие", {}),
|
||||
<!-- new Skill("", "", {}),-->
|
||||
]
|
||||
|
||||
|
||||
function isDataValidForAbility(data) {
|
||||
var value = parseInt(data);
|
||||
if (value != value) {
|
||||
return false;
|
||||
}
|
||||
if (value < min_ability || value > max_ability) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateAbilities() {
|
||||
var sum = 0;
|
||||
for (const ability of abilities) {
|
||||
var element = document.getElementById(ability.name);
|
||||
const value = parseInt(element.value);
|
||||
if (value == value) {
|
||||
sum += value;
|
||||
}
|
||||
}
|
||||
|
||||
const max = 500;
|
||||
|
||||
|
||||
var error_desc_sum = "";
|
||||
var error_desc_separate = "";
|
||||
var error_desc_separate_names = [];
|
||||
|
||||
const is_sum_error = sum > max || sum != sum;
|
||||
|
||||
if (is_sum_error) {
|
||||
error_desc_sum = `Неверное значение суммы характеристик. Сумма не должна превышать ${max}`;
|
||||
}
|
||||
|
||||
for (const ability of abilities) {
|
||||
var element = document.getElementById(ability.name);
|
||||
const is_data_valid = isDataValidForAbility(element.value);
|
||||
|
||||
if (!is_data_valid) {
|
||||
if (!error_desc_separate) {
|
||||
error_desc_sum = `Неверное значение характеристик. Значение должно быть в диапазоне от ${min_ability} до ${max_ability}`;
|
||||
}
|
||||
error_desc_separate_names += ability.name_rus;
|
||||
}
|
||||
|
||||
element.className = !is_sum_error && is_data_valid ? "" : "error";
|
||||
}
|
||||
|
||||
document.getElementById('abilities_result').textContent = max-sum;
|
||||
|
||||
const error_text = "";
|
||||
|
||||
if (error_desc_sum) {
|
||||
error_text += error_desc_sum;
|
||||
}
|
||||
|
||||
if (error_desc_separate) {
|
||||
if (error_text) error_text += "\n";
|
||||
error_text += error_desc_separate;
|
||||
}
|
||||
|
||||
document.getElementById(`abilities${message_suffix}`).textContent = error_text;
|
||||
}
|
||||
|
||||
function isDataValidForSkill(data, base, is_selected) {
|
||||
var value = parseInt(data);
|
||||
if (value != value) {
|
||||
return false;
|
||||
}
|
||||
if (is_selected) {
|
||||
if (value < 20 || value > 70) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (value < base || value > 70) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateSkills() {
|
||||
var sum_selected = 0;
|
||||
var sum_unselected = 0;
|
||||
var sum_unselected_base = 0;
|
||||
var count_selected = 0;
|
||||
|
||||
for (const skill of skills) {
|
||||
var element = document.getElementById(skill.name);
|
||||
var cb = document.getElementById(`${skill.name}${checkbox_suffix}`);
|
||||
const value = parseInt(element.value);
|
||||
if (cb.checked) {
|
||||
count_selected++;
|
||||
}
|
||||
if (value == value) {
|
||||
if (cb.checked) {
|
||||
sum_selected += value
|
||||
}
|
||||
else {
|
||||
sum_unselected += value
|
||||
}
|
||||
}
|
||||
const base = parseInt(skill.sum_unselected_base);
|
||||
if (base == base) {
|
||||
sum_unselected_base += base;
|
||||
}
|
||||
}
|
||||
|
||||
const max_selected = 500;
|
||||
const max_unselected = 80;
|
||||
const max_count_selected = 8;
|
||||
|
||||
for (const skill of skills) {
|
||||
var element = document.getElementById(skill.name);
|
||||
var cb = document.getElementById(`${skill.name}${checkbox_suffix}`);
|
||||
const base = parseInt(skill.sum_unselected_base);
|
||||
if (base == base) {
|
||||
sum_unselected_base += base;
|
||||
}
|
||||
var isValid = count_selected <= max_count_selected;
|
||||
|
||||
if (isValid) {
|
||||
if (cb.checked) {
|
||||
isValid = sum_selected <= max_selected || sum_selected != sum_selected;
|
||||
cb.className = "selected";
|
||||
}
|
||||
else {
|
||||
var isValid = (sum_unselected-sum_unselected_base <= max_unselected ||
|
||||
sum_unselected != sum_unselected);
|
||||
cb.className = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
isValid = isDataValidForSkill(element.value, base, cb.checked);
|
||||
}
|
||||
|
||||
element.className = isValid ? "" : "error";
|
||||
}
|
||||
|
||||
document.getElementById('skills_result_selected').textContent = max_selected-sum_selected;
|
||||
document.getElementById('skills_result_unselected').textContent = max_unselected-sum_unselected;
|
||||
}
|
||||
|
||||
function updateAfterLoading() {
|
||||
for (const ability of abilities) {
|
||||
var element = document.getElementById(ability.name);
|
||||
element.oninput = validateAbilities;
|
||||
}
|
||||
|
||||
for (const skill of skills) {
|
||||
var element = document.getElementById(skill.name);
|
||||
var cb = document.getElementById(`${skill.name}${checkbox_suffix}`);
|
||||
element.oninput = validateSkills;
|
||||
cb.oninput = validateSkills;
|
||||
}
|
||||
|
||||
validateAbilities();
|
||||
validateSkills();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Оокона</h1>
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="misc">
|
||||
<div class="misc">
|
||||
Имя: <input id="name" type="text">
|
||||
</div>
|
||||
<div class="misc">
|
||||
Класс: <input id="class" type="text">
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="abilities">
|
||||
<script>
|
||||
for (const ability of abilities) {
|
||||
document.write(`<div class="abilities">`);
|
||||
document.write(`<input id="${ability.name}" type="text"></input>`);
|
||||
document.write(`<label class="skills">${ability.long_name_rus}</label>`);
|
||||
document.write(`</div>`);
|
||||
}
|
||||
</script>
|
||||
<div class="abilities">
|
||||
Осталось: <span id="abilities_result"></span>
|
||||
</div>
|
||||
<script>
|
||||
document.write(`<p id="abilities${message_suffix}"></p>`);
|
||||
</script>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="skills">
|
||||
<script>
|
||||
for (const skill of skills) {
|
||||
document.write(`<div class="skills">`);
|
||||
document.write(`<input class="skills" id="${skill.name}${checkbox_suffix}" type="checkbox">`);
|
||||
document.write(`<input id="${skill.name}" type="text">`);
|
||||
document.write(`<label for="${skill.name}${checkbox_suffix}" class="skills">${skill.name_rus}</label>`);
|
||||
document.write(`</div>`);
|
||||
}
|
||||
</script>
|
||||
<div class="skills">
|
||||
Осталось (осн/доп): <span id="skills_result_selected"></span>/<span id="skills_result_unselected"></span>
|
||||
</div>
|
||||
<script>
|
||||
document.write(`<p id="skills${message_suffix}"></p>`);
|
||||
</script>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
updateAfterLoading();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user