Skip to content
Snippets Groups Projects
Commit 7b97a7f6 authored by Tomáš Valenta's avatar Tomáš Valenta
Browse files

finished first tool

parent c5ac41cb
No related branches found
No related tags found
No related merge requests found
{% extends "shared/base.html" %}
{% load render_bundle from webpack_loader %}
{% block name %}Kalkulačka velikosti skupiny členů{% endblock %}
{% block description %}TODO - Description.{% endblock %}
{% block head %}
{% render_bundle "member_group_size_calc" %}
{% endblock %}
{% block content %}
aaa
<main class="p-10">
<h1 class="text-6xl font-bebas mb-5">Kalkulačka výpočtu skupiny členů</h1>
<div class="bg-amber-100 p-4 flex flex-row items-center gap-4 mb-4 lg:w-[768px] md:w-full">
<i class="fa-solid fa-lightbulb text-3xl text-amber-800"></i>
<div class="text-amber-800">
Tato kalkulačka slouží pro výpočet skupiny členů podle <a
class="underline text-amber-900"
href="https://wiki.pirati.cz/rules/jdr"
>Jednacího řádu</a>.
</div>
</div>
<div class="bg-gray-100 p-4 flex flex-row items-start gap-4 mb-4 lg:w-[768px] md:w-full">
<i class="fa-solid fa-circle-info text-3xl text-gray-800"></i>
<div class="text-gray-800">
<h2 class="text-lg font-bold mb-3">Jednací řád celostátního fóra</h2>
<div class="mb-3">
<strong>§ 5 Skupina členů</strong>
</div>
<p>
<strong>Skupinou členů</strong> se rozumí jen taková skupina, která čítá aspoň stanovený <a
class="underline text-gray-900"
href="https://lide.pirati.cz/"
>počet členů strany</a>, kteří podpořili určitý návrh. Počet členů se stanoví u návrhu na zahájení jednání jako dvojnásobek druhé odmocniny z počtu přítomných členů, nejméně však jedna setina a nejvýše jedna pětina z počtu přítomných členů. U návrhu na již zahájeném jednání se takto stanovený počet snižuje na polovinu.
</p>
</div>
</div>
<div class="text-lg mb-4">
Počet členů sdružení či orgánu:
<input
id="member-count"
class="w-[7ch]"
type="number"
value="0"
><button
id="calculate"
class="ml-3 px-4 py-2 bg-black text-white duration-100 font-bebas hover:bg-white hover:text-black"
>OK</button>
</div>
<div class="mb-4 flex gap-3 items-start">
<table class="inline-block table-auto">
<thead>
<tr>
<th
class="px-3 py-2 bg-black text-white text-center text-xl font-bebas border border-black"
colspan="2"
>Počty členů</th>
</tr>
</thead>
<tbody>
<tr class="border border-black">
<th class="font-bold text-left px-4 py-2">Setina</th>
<th class="font-normal px-4 py-2" id="hundredth">0</th>
</tr>
<tr class="border border-black">
<th class="font-bold text-left px-4 py-2">Desetina</th>
<th class="font-normal px-4 py-2" id="tenth">0</th>
</tr>
<tr class="border border-black">
<th class="font-bold text-left px-4 py-2">Pětina</th>
<th class="font-normal px-4 py-2" id="fifth">0</th>
</tr>
<tr class="border border-black">
<th class="font-bold text-left px-4 py-2">2x odmocnina</th>
<th class="font-normal px-4 py-2" id="two-square-roots">0</th>
</tr>
</tbody>
</table>
<table class="inline-block table-auto">
<thead>
<tr>
<th
class="px-3 py-2 bg-black text-white text-center text-xl font-bebas border border-black"
colspan="2"
>Hodnoty podle jednacího řádu</th>
</tr>
</thead>
<tbody>
<tr class="border border-black">
<th class="font-bold text-left px-4 py-2">Rozeslání členského podnětu</th>
<th class="font-normal px-4 py-2" id="member-motion">0</th>
</tr>
<tr class="border border-black">
<th class="font-bold text-left px-4 py-2">Zařazení na běžící jednání</th>
<th class="font-normal px-4 py-2" id="ongoing-motion">0</th>
</tr>
<tr class="border border-black">
<th class="font-bold text-left px-4 py-2">Svolání jednání</th>
<th class="font-normal px-4 py-2" id="motion-start">0</th>
</tr>
</tbody>
</table>
</div>
<p class="font-light">
<i>Vypočtené hodnoty jsou zaokrouhleny na celé číslo nahoru.</i>
</p>
</main>
{% endblock %}
......@@ -4,7 +4,9 @@
"description": "",
"private": true,
"dependencies": {
"@fortawesome/fontawesome-free": "^6.2.1",
"css-loader": "^6.7.3",
"jquery": "^3.6.3",
"style-loader": "^3.3.1",
"tailwindcss": "^3.2.4",
"webpack": "^5.75.0",
......
......@@ -39,8 +39,6 @@ STATIC_ROOT = os.environ.get(
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
......@@ -57,7 +55,6 @@ MIDDLEWARE = [
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
......@@ -73,7 +70,6 @@ TEMPLATES = [
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
......@@ -90,26 +86,6 @@ DATABASES = {
"default": dj_database_url.config(conn_max_age=600)
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
......
......@@ -13,10 +13,8 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("", include("member_group_size_calc.urls")),
path('admin/', admin.site.urls),
path("vypocet-skupiny-clenu", include("member_group_size_calc.urls")),
]
......@@ -517,8 +517,218 @@ html {
--tw-backdrop-sepia: ;
}
.static {
position: static;
}
.mb-5 {
margin-bottom: 1.25rem;
}
.mb-4 {
margin-bottom: 1rem;
}
.mb-3 {
margin-bottom: 0.75rem;
}
.ml-3 {
margin-left: 0.75rem;
}
.block {
display: block;
}
.inline-block {
display: inline-block;
}
.flex {
display: flex;
}
.table {
display: table;
}
.w-\[7ch\] {
width: 7ch;
}
.table-auto {
table-layout: auto;
}
.flex-row {
flex-direction: row;
}
.items-start {
align-items: flex-start;
}
.items-center {
align-items: center;
}
.gap-4 {
gap: 1rem;
}
.gap-3 {
gap: 0.75rem;
}
.border {
border-width: 1px;
}
.border-black {
--tw-border-opacity: 1;
border-color: rgb(0 0 0 / var(--tw-border-opacity));
}
.bg-amber-100 {
--tw-bg-opacity: 1;
background-color: rgb(254 243 199 / var(--tw-bg-opacity));
}
.bg-gray-100 {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
}
.bg-black {
--tw-bg-opacity: 1;
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
}
.p-10 {
padding: 2.5rem;
}
.p-4 {
padding: 1rem;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.py-2 {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
.px-3 {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
.text-left {
text-align: left;
}
.text-center {
text-align: center;
}
.font-bebas {
font-family: Bebas Neue, ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
}
.text-6xl {
font-size: 3.75rem;
line-height: 1;
}
.text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
}
.text-lg {
font-size: 1.125rem;
line-height: 1.75rem;
}
.text-xl {
font-size: 1.25rem;
line-height: 1.75rem;
}
.font-bold {
font-weight: 700;
}
.font-normal {
font-weight: 400;
}
.font-light {
font-weight: 300;
}
.text-amber-800 {
--tw-text-opacity: 1;
color: rgb(146 64 14 / var(--tw-text-opacity));
}
.text-amber-900 {
--tw-text-opacity: 1;
color: rgb(120 53 15 / var(--tw-text-opacity));
}
.text-gray-800 {
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.text-gray-900 {
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-white {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
}
.underline {
text-decoration-line: underline;
}
.duration-100 {
transition-duration: 100ms;
}
@layer typography {
.font-bebas {
font-family: "Bebas Neue";
}
}
.hover\:bg-white:hover {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.hover\:text-black:hover {
--tw-text-opacity: 1;
color: rgb(0 0 0 / var(--tw-text-opacity));
}
@media (min-width: 768px) {
.md\:w-full {
width: 100%;
}
}
@media (min-width: 1024px) {
.lg\:w-\[768px\] {
width: 768px;
}
}
{% load render_bundle from webpack_loader %}
{% load static %}
<!DOCTYPE html>
<html lang="cs">
......@@ -9,7 +10,23 @@
<title>{% block name %}{% endblock %}</title>
<meta name="description" content="{% block description %}{% endblock %}">
{% render_bundle "main" %}
<link
rel="stylesheet"
type="text/css"
href="{% static "shared/style.css" %}"
>
<link
rel="stylesheet"
href="https://gfonts.pirati.cz/css2?family=Bebas+Neue&family=Roboto+Condensed:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap"
>
<link rel="shortcut icon" type="image/png" href="https://www.pirati.cz/static/shared/favicon/favicon-196.png" sizes="196x196">
<link rel="shortcut icon" type="image/png" href="https://www.pirati.cz/static/shared/favicon/favicon-128.png" sizes="128x128">
<link rel="shortcut icon" type="image/png" href="https://www.pirati.cz/static/shared/favicon/favicon-96.png" sizes="96x96">
<link rel="shortcut icon" type="image/png" href="https://www.pirati.cz/static/shared/favicon/favicon-32.png" sizes="32x32">
<link rel="shortcut icon" type="image/png" href="https://www.pirati.cz/static/shared/favicon/favicon-16.png" sizes="16x16">
{% render_bundle "base" %}
{% block head %}{% endblock %}
</head>
......
import $ from "jquery";
import "@fortawesome/fontawesome-free/js/fontawesome";
import "@fortawesome/fontawesome-free/js/solid";
import "@fortawesome/fontawesome-free/js/regular";
$(window).ready(
() => {
$("#member-count").on(
"keypress",
event => {
if (event.key === "Enter") {
$("#calculate").click();
}
}
)
$("#calculate").on(
"click",
event => {
const memberCount = Number($("#member-count").val());
if (isNaN(memberCount) || memberCount === 0) {
alert("Prosím, zadej skutečný počet členů.");
return;
}
const hundredth = Math.ceil(memberCount / 100);
const fifth = Math.ceil(memberCount / 5);
const twoSquareRoots = Math.ceil(2 * Math.sqrt(memberCount));
$("#hundredth").html(hundredth);
$("#tenth").html(Math.ceil(memberCount / 10));
$("#fifth").html(fifth);
$("#two-square-roots").html(twoSquareRoots);
const motionStart = Math.max(
Math.min(fifth, twoSquareRoots), hundredth
);
const motion = Math.ceil(motionStart / 2);
$("#member-motion,#ongoing-motion").html(motion);
$("#motion-start").html(motionStart);
}
);
}
)
......@@ -4,7 +4,10 @@ const BundleTracker = require('webpack-bundle-tracker');
module.exports = {
mode: "production",
context: __dirname,
entry: path.resolve("static_src", "base.js"),
entry: {
base: path.resolve("static_src", "base.js"),
member_group_size_calc: path.resolve("static_src", "member_group_size_calc.js"),
},
output: {
path: path.resolve(__dirname, "shared", "static", "shared"),
filename: "[name]-[fullhash].js",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment