Files
Key-service-Server/Website/templates/preise.html
T

577 lines
18 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}Preise{% endblock %}
{% block head %}
{{ super() }}
<style>
.booking-hero {
background: linear-gradient(135deg, rgba(28, 90, 99, 0.14), rgba(255, 255, 255, 0.65)),
linear-gradient(180deg, #fffefb 0%, #f2f5f2 100%);
border: 1px solid rgba(28, 90, 99, 0.16);
border-radius: 24px;
padding: 2.2rem;
margin-bottom: 1.8rem;
box-shadow: 0 18px 44px rgba(18, 49, 54, 0.08);
overflow: hidden;
position: relative;
}
.booking-hero::before {
content: "";
position: absolute;
inset: 0;
background: radial-gradient(circle at top right, rgba(34, 98, 128, 0.16), transparent 36%);
pointer-events: none;
}
.booking-hero > * {
position: relative;
z-index: 1;
}
.booking-hero h1 {
margin-bottom: 0.65rem;
color: #133d4a;
font-size: clamp(2rem, 3.5vw, 3.2rem);
}
.booking-hero p {
margin: 0.75rem 0 0;
max-width: 780px;
color: #3b5f69;
font-size: clamp(1rem, 1.05vw, 1.1rem);
}
.packages-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.4rem;
margin-bottom: 1.8rem;
align-items: stretch;
}
.package-card {
background: #ffffff;
border: 1px solid #dfe7e7;
border-radius: 22px;
box-shadow: 0 18px 40px rgba(23, 44, 57, 0.05);
padding: 1.8rem;
display: flex;
flex-direction: column;
height: 100%;
gap: 1.2rem;
transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
}
.package-card:hover {
transform: translateY(-3px);
border-color: #b2d4dc;
box-shadow: 0 24px 48px rgba(23, 44, 57, 0.1);
}
.package-card__header {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 1.2rem;
}
.package-card__header > div {
min-width: 0;
width: 100%;
}
.package-card__tag {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.45rem 0.8rem;
border-radius: 999px;
background: #e6f5f8;
color: #106476;
font-size: 0.9rem;
font-weight: 700;
letter-spacing: 0.01em;
margin-bottom: 0.6rem;
}
.package-card__name {
margin: 0;
color: #143f46;
font-size: clamp(1.4rem, 2.5vw, 1.8rem);
line-height: 1.2;
word-wrap: break-word;
}
.package-card__price {
display: inline-flex;
align-items: baseline;
gap: 0.35rem;
font-weight: 700;
color: #102d37;
white-space: normal;
margin-top: 0.2rem;
}
.package-card__price span {
font-size: clamp(1.8rem, 3vw, 2.4rem);
letter-spacing: -0.04em;
line-height: 1.1;
}
.package-card__old-price {
color: #c62828;
text-decoration: line-through;
margin-right: 0.5rem;
font-size: clamp(1rem, 2.2vw, 1.1rem);
font-weight: 700;
opacity: 0.95;
}
.package-card__new-price {
color: #0b6440;
font-size: clamp(1.8rem, 3vw, 2.4rem);
font-weight: 800;
letter-spacing: -0.04em;
}
.package-card__price small {
color: #57717b;
font-size: 0.95rem;
}
.package-card__description {
margin: 0;
color: #4b6a72;
line-height: 1.75;
}
.package-card__features {
margin: 1rem 0 0;
padding: 0;
list-style: none;
display: grid;
gap: 0.75rem;
flex: 1 1 auto;
}
.package-card__features li {
display: grid;
grid-template-columns: auto 1fr;
gap: 0.75rem;
align-items: flex-start;
color: #4f6a72;
font-size: 0.98rem;
}
.package-card__features li::before {
content: "✓";
color: #187490;
font-weight: 700;
line-height: 1.2;
}
.package-card__actions {
margin-top: auto;
padding-top: 0.25rem;
}
.package-card__actions form,
.package-card__actions a {
width: 100%;
display: inline-flex;
}
.btn {
width: 100%;
border: 1px solid #1c5a63;
background: linear-gradient(120deg, #1d6d79 0%, #164b55 100%);
color: #ffffff;
border-radius: 999px;
padding: 0.95rem 1.2rem;
font-weight: 700;
cursor: pointer;
text-align: center;
transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.btn:hover,
.btn:focus-visible {
transform: translateY(-1px);
box-shadow: 0 12px 24px rgba(28, 90, 99, 0.22);
}
.btn.secondary {
border-color: #c7dde3;
background: #f7fbfb;
color: #1d5f6f;
}
.notice {
padding: 1.3rem 1.35rem;
border-radius: 20px;
background: #ffffff;
border: 1px solid #dfe7ea;
color: #304f5a;
box-shadow: 0 12px 24px rgba(23, 44, 57, 0.04);
}
.notice strong {
color: #15444c;
}
@media (max-width: 760px) {
.booking-hero {
padding: 1.5rem 1.2rem;
border-radius: 18px;
}
.booking-hero h1 {
font-size: 1.8rem;
}
.packages-grid {
grid-template-columns: 1fr;
gap: 1.2rem;
}
.package-card {
padding: 1.4rem 1.2rem;
border-radius: 18px;
gap: 1rem;
}
.package-card__header {
gap: 0.8rem;
}
.package-card__price {
margin-top: 0;
}
.package-card__price span {
font-size: 2rem;
}
.btn {
padding: 1rem 1.2rem;
font-size: 1.05rem;
}
}
/* Custom Modal Styles */
.custom-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
align-items: center;
justify-content: center;
z-index: 100;
padding: 1rem;
}
.custom-modal.active {
display: flex;
}
.custom-modal-backdrop {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(18, 49, 54, 0.4);
backdrop-filter: blur(4px);
}
.custom-modal-content {
position: relative;
background: #ffffff;
border-radius: 20px;
padding: 2.2rem;
max-width: 500px;
width: 100%;
box-shadow: 0 24px 54px rgba(23, 44, 57, 0.2);
z-index: 101;
animation: modalEnter 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes modalEnter {
from {
opacity: 0;
transform: translateY(20px) scale(0.95);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.custom-modal-content h3 {
margin-top: 0;
margin-bottom: 1rem;
color: #133d4a;
}
.custom-modal-content p {
color: #4b6a72;
margin-bottom: 0.8rem;
}
.custom-modal-actions {
display: flex;
gap: 1rem;
margin-top: 2rem;
justify-content: flex-end;
}
.custom-modal-actions button {
width: auto;
min-width: 120px;
}
@media (max-width: 600px) {
.custom-modal-content {
padding: 1.6rem;
border-radius: 16px;
}
.custom-modal-actions {
flex-direction: column;
}
.custom-modal-actions button {
width: 100%;
}
}
</style>
{% endblock %}
{% block content %}
<section class="booking-hero">
<h1>Preise</h1>
<p>Preise zu unseren Modulen
<p>Unsere Module und Pakete sind klar strukturiert und transparent. Wählen Sie die passende Lösung für Ihre Schule und senden Sie die Anfrage direkt an unser Admin-Team.</p>
<p>Nach der Anfrage wird sich ein Administrator zeitnah über das Portal mit Ihnen in Verbindung setzen, um die Buchung persönlich vor Ort zu besprechen oder einen direkten Start zu vereinbaren.</p>
<p>Unsere Server stehen in einem Deutschen Data-Center der Firma Strato und garantieren eine hohe Verfügbarkeit und Sicherheit Ihrer Daten.</p>
</section>
<section class="packages-grid" aria-label="Buchungspakete">
<article class="package-card">
<div class="package-card__header">
<div>
<span class="package-card__tag">Modul</span>
<h2 class="package-card__name">Inventarsystem</h2>
</div>
<div class="package-card__price">
<span>350 €</span>
<small>/ Jahr</small>
</div>
</div>
<p class="package-card__description">Der stabile Einstieg in die Schulverwaltung mit Inventarverwaltung, Benutzerrechten und Berichten für den gesamten Schulbetrieb.</p>
<ul class="package-card__features">
<li>Inventarverwaltung mit Rollenrechten</li>
<li>Basis-Support und Ticketing</li>
<li>Schulweite Übersichten und Berichte</li>
<li>Erweiterte Instanzverwaltung</li>
<li>Ihre Schullehrmittel auf einen Blick</li>
</ul>
<div class="package-card__actions">
{% if 'username' in session %}
<form method="POST" action="{{ url_for('book_option_package') }}" class="booking-form">
<input type="hidden" name="package" value="inventarsystem">
<button class="btn" type="button" onclick="openBookingModal(this.form)">Jetzt buchen</button>
</form>
{% else %}
<a class="btn secondary" href="{{ url_for('login') }}">Hinweis: Registrieren Sie sich oder loggen sich bitte ein, um einen gemeinsamen Termin zu vereinbaren.</a>
{% endif %}
</div>
</article>
<article class="package-card">
<div class="package-card__header">
<div>
<span class="package-card__tag">Modul</span>
<h2 class="package-card__name">Bibliothekssystem</h2>
</div>
<div class="package-card__price">
<span>100 €</span>
<small>/ Jahr</small>
</div>
</div>
<p class="package-card__description">Ein spezialisiertes Modul für Bibliotheken und Medienzentren mit Ausleihprozessen, Medienbeständen und historischer Transparenz.</p>
<ul class="package-card__features">
<li>Ausgabe- und Rückgabeprozesse</li>
<li>Bestandsübersichten für Medien</li>
<li>Transparente Historie pro Medium</li>
<li></li>
</ul>
<div class="package-card__actions">
{% if 'username' in session %}
<form method="POST" action="{{ url_for('book_option_package') }}" class="booking-form">
<input type="hidden" name="package" value="buecherei">
<button class="btn" type="button" onclick="openBookingModal(this.form)">Jetzt buchen</button>
</form>
{% else %}
<a class="btn secondary" href="{{ url_for('login') }}">Mit Konto buchen</a>
{% endif %}
</div>
</article>
<article class="package-card">
<div class="package-card__header">
<div>
<span class="package-card__tag">Modul</span>
<h2 class="package-card__name">Terminplaner</h2>
</div>
<div class="package-card__price">
<span>100 €</span>
<small>/ Jahr</small>
</div>
</div>
<p class="package-card__description">Ein für flexible Terminplanung entwickeltes Modul, dass dem Nutzer erlaubt, seine Termine für beispielsweise Elternsprechstunden komfortabel und schnell im Zugriff zu haben.</p>
<ul class="package-card__features">
<li>Flexible Slot- und Zeitfenster-Erstellung </li>
<li>Hürdenlose Buchung ohne Registrierung</li>
<li>Echtzeit-Aktualisierung gebuchter Termine</li>
<li>Direkte Terminvergabe per Einladungslink</li>
</ul>
<div class="package-card__actions">
{% if 'username' in session %}
<form method="POST" action="{{ url_for('book_option_package') }}" class="booking-form">
<input type="hidden" name="package" value="Terminverwaltung">
<button class="btn" type="button" onclick="openBookingModal(this.form)">Jetzt buchen</button>
</form>
{% else %}
<a class="btn secondary" href="{{ url_for('login') }}">Mit Konto buchen</a>
{% endif %}
</div>
</article>
<article class="package-card">
<div class="package-card__header">
<div>
<span class="package-card__tag">Paket</span>
<h2 class="package-card__name">Startpaket</h2>
</div>
<div class="package-card__price">
<span>420 €</span>
<small>/ Jahr</small>
</div>
</div>
<p class="package-card__description">Das Starterpaket enhält die Inventarverwaltung und das Bibliothekssystem, als ideale Komplettlösung.</p>
<ul class="package-card__features">
<li>Das Inventarsystem idealer start Punkt</li>
<li>Das Bibliothekssystem als passende Ergänzung</li>
<li>Ein einfaches und intuitive Benutzeroberfläche</li>
<li>Der Perfekte Start für Ihre Digitalisierung</li>
</ul>
<div class="package-card__actions">
{% if 'username' in session %}
<form method="POST" action="{{ url_for('book_option_package') }}" class="booking-form">
<input type="hidden" name="package" value="Terminverwaltung">
<button class="btn" type="button" onclick="openBookingModal(this.form)">Jetzt buchen</button>
</form>
{% else %}
<a class="btn secondary" href="{{ url_for('login') }}">Mit Konto buchen</a>
{% endif %}
</div>
</article>
<article class="package-card">
<div class="package-card__header">
<div>
<span class="package-card__tag">Premium</span>
<h2 class="package-card__name">Schulträger</h2>
</div>
<div class="package-card__price">
<span>Auf Anfrage</span>
</div>
</div>
<p class="package-card__description">Individuelles Angebot für Schulträger mit mehreren Schulen und speziellen Anforderungen an die Verwaltung.</p>
<ul class="package-card__features">
<li>Mandantenfähige Verwaltung</li>
<li>Zentrale Übersicht aller Schulen</li>
<li>Individuelle Anpassungen</li>
<li>Persönlicher Ansprechpartner</li>
</ul>
<div class="package-card__actions">
{% if 'username' in session %}
<form method="POST" action="{{ url_for('book_option_package') }}" class="booking-form">
<input type="hidden" name="package" value="schultraeger">
<button class="btn" type="button" onclick="openBookingModal(this.form)">Jetzt anfragen</button>
</form>
{% else %}
<a class="btn secondary" href="{{ url_for('login') }}">Mit Konto anfragen</a>
{% endif %}
</div>
</article>
</section>
<section class="notice">
{% if 'username' in session %}
<p><strong>Hinweis:</strong> Deine Buchungsanfrage wird direkt vom Admin-Team bearbeitet und deiner Schulinstanz zugeordnet.</p>
{% else %}
<p><strong>Hinweis:</strong> Bitte logge dich ein oder registriere dich, um einen Termin zu vereinbaren.</p>
{% endif %}
</section>
<!-- Custom Modal -->
<div class="custom-modal" id="bookingModal" aria-hidden="true" role="dialog" aria-modal="true">
<div class="custom-modal-backdrop" onclick="closeBookingModal()"></div>
<div class="custom-modal-content">
<h3>Buchung bestätigen</h3>
<p>Möchten Sie dieses Paket jetzt direkt buchen oder zuerst einen Gesprächstermin vereinbaren?</p>
<p style="font-size: 0.95rem;">Bitte wählen sie eine der Beiden Optionen aus um mit dem Verfahren weiter fortzufahren.</p>
<div class="custom-modal-actions">
<button class="btn secondary" type="button" onclick="closeBookingModal()">Abbrechen</button>
<button class="btn" type="button" onclick="goToBookingReview('consultation')">Gesprächstermin vereinbaren</button>
<button class="btn" type="button" onclick="goToBookingReview('payment')">Buchen</button>
</div>
</div>
</div>
<script>
const bookingReviewBaseUrl = "{{ url_for('booking_payment') }}";
let currentBookingForm = null;
function openBookingModal(formElement) {
currentBookingForm = formElement;
const modal = document.getElementById('bookingModal');
modal.classList.add('active');
modal.setAttribute('aria-hidden', 'false');
}
function closeBookingModal() {
currentBookingForm = null;
const modal = document.getElementById('bookingModal');
modal.classList.remove('active');
modal.setAttribute('aria-hidden', 'true');
}
function goToBookingReview(flow) {
if (!currentBookingForm) {
return;
}
const packageInput = currentBookingForm.querySelector('input[name="package"]');
const packageValue = packageInput ? packageInput.value : '';
const reviewUrl = new URL(bookingReviewBaseUrl, window.location.origin);
reviewUrl.searchParams.set('package', packageValue);
reviewUrl.searchParams.set('flow', flow);
window.location.href = reviewUrl.toString();
}
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
closeBookingModal();
}
});
</script>
{% endblock %}