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

add email signature generator

parent f4a0b5e4
Branches
No related tags found
3 merge requests!5Release,!4Release,!3Release
Pipeline #11628 passed
Showing
with 290 additions and 7 deletions
from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
class MailSignatureConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'mail_signature'
from django.db import models
# Create your models here.
{% extends "shared/base.html" %}
{% load render_bundle from webpack_loader %}
{% block title %}Generátor emailových podpisů{% endblock %}
{% block header_name %}Emailové podpisy{% endblock %}
{% block description %}Vyplněním získáš HTML kód, který můžeš vložit jako podpis do svých emailů.{% endblock %}
{% block head %}
<link
rel="stylesheet"
href="https://styleguide.pirati.cz/2.11.x/css/styles.css"
>
{% render_bundle "mail_signature" %}
{% endblock %}
{% block content %}
<main>
<h1 class="text-6xl font-bebas mb-5">Generátor emailových podpisů</h1>
<div class="prose max-w-none mb-5">
<p>
Vyplněním následujícího formuláře získáš HTML kód,
který můžeš vložit jako podpis do svých emailů.
</p>
</div>
<div class="grid gap-4 grid-cols-1 lg:grid-cols-2">
<form class="flex flex-col gap-3" id="source">
<div class="flex gap-4 items-center">
<label class="basis-56 flex items-center font-bold" for="name">
Jméno:
</label>
<input
id="name"
name="name"
type="text"
class="border border-gray-200 p-2 rounded-md grow w-full"
>
</div>
<div class="flex gap-4 items-center">
<label class="basis-56 flex items-center font-bold" for="function">
Název funkce:
</label>
<input
id="function"
name="function"
type="text"
class="border border-gray-200 p-2 rounded-md grow w-full"
>
</div>
<div class="flex gap-4 items-center">
<label class="basis-56 flex items-center font-bold" for="email">
E-mail:
</label>
<input
id="email"
name="email"
type="email"
class="border border-gray-200 p-2 rounded-md grow w-full"
>
</div>
<div class="flex gap-4 items-center">
<label class="basis-56 flex items-center font-bold" for="phone">
Telefonní číslo:
</label>
<input
id="phone"
name="phone"
type="tel"
class="border border-gray-200 p-2 rounded-md grow w-full"
>
</div>
<div class="flex gap-4 items-center">
<label class="basis-56 flex items-center font-bold" for="fejsbuk">
Facebook odkaz:
</label>
<input
id="fejsbuk"
name="fejsbuk"
type="url"
class="border border-gray-200 p-2 rounded-md grow w-full"
>
</div>
<div class="flex gap-4 items-center">
<label class="basis-56 flex items-center font-bold" for="linkedin">
LinkedIn odkaz:
</label>
<input
id="linkedin"
name="linkedin"
type="url"
class="border border-gray-200 p-2 rounded-md grow w-full"
>
</div>
<div class="text-right">
<button id="generate" class="btn btn--icon" type="button">
<div class="btn__body-wrap">
<div class="btn__body">Vygenerovat</div>
<div class="btn__icon">
<i class="ico--chevron-right"></i>
</div>
</div>
</button>
</div>
</form>
<div class="flex flex-col gap-3">
<div class="border border-gray-400 border-dotted p-2 rounded-md" id="preview"></div>
<textarea
class="border border-gray-200 p-2 font-mono rounded-md w-full"
rows="5"
id="content"
readonly
></textarea>
</div>
</div>
</main>
{% endblock %}
from django.test import TestCase
# Create your tests here.
from django.urls import path
from . import views
app_name = "mail_signature"
urlpatterns = [
path("", views.index, name="index"),
]
from django.shortcuts import render
# Create your views here.
def index(request):
return render(
request,
"mail_signature/index.html"
)
......@@ -4,6 +4,7 @@
"description": "",
"private": true,
"dependencies": {
"@tailwindcss/typography": "^0.5.9",
"css-loader": "^6.7.3",
"jquery": "^3.6.3",
"js-cookie": "^3.0.1",
......
......@@ -25,12 +25,14 @@
<main>
<h1 class="text-6xl font-bebas mb-5">Kalkulačka hlasování RV</h1>
<p class="mb-5 text-gray-800">
<div class="prose max-w-none mb-5">
<p>
Jednací řád k nahlédnutí <a
class="underline"
href="https://wiki.pirati.cz/rules/jrrv#rozhodujici_hlasovani_pri_referendu"
>na wiki</a>, § 9 (3).
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-7">
<div>
......
......@@ -48,6 +48,7 @@ INSTALLED_APPS = [
"shared",
"member_group_size_calc",
"rv_voting_calc",
"mail_signature",
]
MIDDLEWARE = [
......
......@@ -18,5 +18,6 @@ from django.urls import include, path
urlpatterns = [
path("vypocet-skupiny-clenu/", include("member_group_size_calc.urls")),
path("hlasovani-rv/", include("rv_voting_calc.urls")),
path("emailove-podpisy/", include("mail_signature.urls")),
path("", include("shared.urls")),
]
shared/static/shared/signature.webp

113 KiB

......@@ -34,6 +34,7 @@
</div>
</div>
</li>
<li class="card">
<a href="{% url "rv_voting_calc:index" %}">
<img
......@@ -53,6 +54,7 @@
</div>
</div>
</li>
<li class="card">
<a href="https://z.pirati.cz" target="_blank">
<img
......@@ -72,6 +74,26 @@
</div>
</div>
</li>
<li class="card">
<a href="{% url "mail_signature:index" %}" target="_blank">
<img
src="{% static "shared/signature.webp" %}"
alt="Generátor emailových podpisů"
class="w-full h-48 object-cover"
>
</a>
<div class="p-4">
<h2 class="mb-2 text-xl font-bold">
<a href="{% url "mail_signature:index" %}" target="_blank">
Generátor emailových podpisů
</a>
</h2>
<div class="font-light text-sm break-words">
Vyplněním získáš HTML kód, který můžeš vložit jako podpis do svých emailů.
</div>
</div>
</li>
</ul>
</main>
{% endblock %}
import $ from "jquery";
const escapeHTML = (str) => {
return new Option(str).innerHTML;
}
const generateSignature = () => {
let result = `<style>
@import url(https://gfonts.pirati.cz/css?family=Roboto);
body { font-family: Roboto, Arial; background: white; color:black; }
.pv { font-family: Roboto Condensed, Arial, sans-serif; font-size: 10pt; font-weight: normal; margin: 1em; background: white; color: black; }
.pv>.bl { margin-bottom:0.5em; line-height: 1.1em; }
.name { font-size: 13pt; font-weight: bold; }
.social { box-sizing: content-box; font-weight: bold; color: white !important; background: black; margin: 0.1em; padding: 0.2em; width: 1em; height: 1em; display: inline-block; text-align: center; text-decoration:none; border-radius: 0.5em; }
.logo { margin-top: 1.5em; }
.logo img { height: 3.5em; margin-left:-0.1em; }
</style>
<div class="pv">`;
let name = $("#name").val();
let func = $("#function").val();
if (name !== "") {
name = escapeHTML(name);
result += `<div class="bl">
<strong class="name">${name}</strong>`;
func = escapeHTML(func);
if (func !== "") {
result += `<br>${func}`;
}
result += "</div>";
}
let email = $("#email").val();
let phone = $("#phone").val();
let fejsbuk = $("#fejsbuk").val();
let linkedin = $("#linkedin").val();
if (email !== "" || phone !== "" || fejsbuk !== "" || linkedin !== "") {
result += "<div class=\"bl\">";
if (email !== "") {
email = escapeHTML(email);
result += `<a href="${email}">${email}</a><br>`;
}
if (phone !== "") {
phone = escapeHTML(phone);
result += `<a href="${phone}">${phone}</a><br>`;
}
if (fejsbuk !== "") {
fejsbuk = escapeHTML(fejsbuk);
result += `<a href="${fejsbuk}" class="social">f</a>`;
}
if (linkedin !== "") {
linkedin = escapeHTML(linkedin);
result += `<a href="${linkedin}" class="social">in</a>`;
}
result += "</div>";
}
result += `<div class="logo">
<img
src="data:image/png;base64,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"
alt="Logo Pirátské Strany"
>
</div>
</div>`;
$("#preview").html(result);
$("#content").val(result);
}
$(window).ready(
() => {
generateSignature();
$("#generate").on(
"click",
event => {
const form = $("#source")[0];
if (!form.checkValidity()) {
form.reportValidity();
return;
}
generateSignature();
}
);
}
);
......@@ -14,5 +14,7 @@ module.exports = {
},
},
},
plugins: [],
plugins: [
require("@tailwindcss/typography"),
],
}
......@@ -17,6 +17,10 @@ module.exports = {
import: path.resolve("static_src", "rv_voting_calc.js"),
dependOn: "shared",
},
mail_signature: {
import: path.resolve("static_src", "mail_signature.js"),
dependOn: "shared",
},
shared: ["jquery"],
},
output: {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment