API updadte

This commit is contained in:
2025-11-09 11:12:48 +01:00
parent 7548e241be
commit 77206224a2
14 changed files with 1048 additions and 57 deletions

View File

@@ -0,0 +1,46 @@
{% extends 'base.html.twig' %}
{% block title %}Login - {{ parent() }}{% endblock %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('css/auth.css') }}">
{% endblock %}
{% block body %}
<div class="auth-container">
<div class="auth-box">
<h2>Anmelden</h2>
{% for message in app.flashes('success') %}
<div class="success-message">{{ message }}</div>
{% endfor %}
{% if error %}
<div class="error-message">
{{ error.messageKey|trans(error.messageData, 'security') }}
</div>
{% endif %}
<form class="auth-form" method="post" action="{{ path('app_login') }}">
<div class="form-group">
<label for="username">E-Mail</label>
<input type="email" id="username" name="_username" value="{{ last_username }}" required autofocus>
</div>
<div class="form-group">
<label for="password">Passwort</label>
<input type="password" id="password" name="_password" required>
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<button class="btn-submit" type="submit">Anmelden</button>
</form>
<div class="auth-links">
<p>Noch kein Konto? <a href="{{ path('app_register') }}">Jetzt registrieren</a></p>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,48 @@
{% extends 'base.html.twig' %}
{% block title %}Registrierung - {{ parent() }}{% endblock %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('css/auth.css') }}">
{% endblock %}
{% block body %}
<div class="auth-container">
<div class="auth-box">
<h2>Registrieren</h2>
{% if error %}
<div class="error-message">{{ error }}</div>
{% endif %}
<form class="auth-form" method="post" action="{{ path('app_register') }}">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name" required autofocus>
</div>
<div class="form-group">
<label for="email">E-Mail</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password">Passwort (min. 6 Zeichen)</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<label for="password_confirm">Passwort bestätigen</label>
<input type="password" id="password_confirm" name="password_confirm" required>
</div>
<button class="btn-submit" type="submit">Registrieren</button>
</form>
<div class="auth-links">
<p>Bereits registriert? <a href="{{ path('app_login') }}">Jetzt anmelden</a></p>
</div>
</div>
</div>
{% endblock %}

View File

@@ -48,7 +48,19 @@
<body>
<header>
<div class="container">
<h1>Immorechner</h1>
<div style="display: flex; justify-content: space-between; align-items: center;">
<h1><a href="{{ path('app_home') }}" style="color: white; text-decoration: none;">Immorechner</a></h1>
<nav>
{% if app.user %}
<span style="color: white; margin-right: 15px;">Hallo, {{ app.user.name }}!</span>
<a href="{{ path('app_my_immobilien') }}" style="color: white; text-decoration: none; margin-right: 10px;">Meine Immobilien</a>
<a href="{{ path('app_logout') }}" style="color: white; text-decoration: none; padding: 8px 16px; background-color: rgba(255,255,255,0.2); border-radius: 4px;">Abmelden</a>
{% else %}
<a href="{{ path('app_login') }}" style="color: white; text-decoration: none; margin-right: 10px;">Anmelden</a>
<a href="{{ path('app_register') }}" style="color: white; text-decoration: none; padding: 8px 16px; background-color: rgba(255,255,255,0.2); border-radius: 4px;">Registrieren</a>
{% endif %}
</nav>
</div>
</div>
</header>

View File

@@ -1,67 +1,167 @@
{% extends 'base.html.twig' %}
{% block title %}Willkommen - {{ parent() }}{% endblock %}
{% block title %}Immobilienwert berechnen - {{ parent() }}{% endblock %}
{% block stylesheets %}
{{ parent() }}
<style>
.welcome-box {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h2 {
color: #333;
border-bottom: 2px solid #4CAF50;
padding-bottom: 10px;
margin-bottom: 20px;
}
.info {
margin: 20px 0;
padding: 15px;
background-color: #e8f5e9;
border-left: 4px solid #4CAF50;
}
.api-link {
display: inline-block;
margin-top: 20px;
padding: 10px 20px;
background-color: #4CAF50;
color: white;
text-decoration: none;
border-radius: 4px;
}
.api-link:hover {
background-color: #45a049;
}
ul {
margin-left: 20px;
}
ul li {
margin: 8px 0;
}
</style>
<link rel="stylesheet" href="{{ asset('css/calculator.css') }}">
{% endblock %}
{% block body %}
<div class="welcome-box">
<h2>Willkommen bei Immorechner</h2>
<div class="info-banner">
<h2 style="margin-bottom: 10px; border: none;">Immobilienwert-Rechner</h2>
<p>Berechnen Sie die Werthaltigkeit Ihrer Immobilie. Alle Berechnungen erfolgen in Echtzeit.</p>
<p><strong>Ohne Registrierung:</strong> Teilen Sie Ihre Berechnung über einen Link.</p>
<p><strong>Mit Registrierung:</strong> Speichern Sie Ihre Immobilien dauerhaft.</p>
</div>
<div class="info">
<p><strong>Symfony-Anwendung erfolgreich installiert!</strong></p>
<p>Diese Anwendung verfügt über:</p>
<ul>
<li>Symfony 7.3 Framework</li>
<li>MariaDB Datenbank (mit Docker)</li>
<li>Doctrine ORM</li>
<li>API Platform für REST-API</li>
<li>Twig Template Engine für UI</li>
</ul>
<div class="calculator-container">
<div class="form-section">
<h2>Immobiliendaten</h2>
<form id="immo-calculator-form">
<div class="form-group">
<label for="adresse">Adresse</label>
<input type="text" id="adresse" name="adresse" value="{{ immobilienData.adresse }}" placeholder="z.B. Musterstraße 123, 12345 Berlin">
</div>
<div class="form-group">
<label for="kaufpreis">Kaufpreis (€)</label>
<input type="number" id="kaufpreis" name="kaufpreis" value="{{ immobilienData.kaufpreis }}" placeholder="z.B. 250000">
</div>
<div class="form-group">
<label for="wohnflaeche">Wohnfläche (m²)</label>
<input type="number" id="wohnflaeche" name="wohnflaeche" value="{{ immobilienData.wohnflaeche }}" placeholder="z.B. 80">
</div>
<div class="form-group">
<label for="nutzflaeche">Nutzfläche (m²)</label>
<input type="number" id="nutzflaeche" name="nutzflaeche" value="{{ immobilienData.nutzflaeche }}" placeholder="z.B. 100">
</div>
<div class="form-group">
<label for="zimmer">Anzahl Zimmer</label>
<input type="number" id="zimmer" name="zimmer" value="{{ immobilienData.zimmer }}" placeholder="z.B. 3">
</div>
<div class="form-group">
<label for="baujahr">Baujahr</label>
<input type="number" id="baujahr" name="baujahr" value="{{ immobilienData.baujahr }}" placeholder="z.B. 2015">
</div>
<div class="form-group">
<label for="etage">Etage</label>
<input type="number" id="etage" name="etage" value="{{ immobilienData.etage }}" placeholder="z.B. 2">
</div>
<div class="form-group">
<label for="typ">Immobilientyp</label>
<select id="typ" name="typ">
<option value="">-- Bitte wählen --</option>
<option value="Wohnung" {% if immobilienData.typ == 'Wohnung' %}selected{% endif %}>Wohnung</option>
<option value="Haus" {% if immobilienData.typ == 'Haus' %}selected{% endif %}>Haus</option>
<option value="Gewerbe" {% if immobilienData.typ == 'Gewerbe' %}selected{% endif %}>Gewerbe</option>
</select>
</div>
<div class="form-group">
<label for="bundesland_id">Bundesland</label>
<select id="bundesland_id" name="bundesland_id">
<option value="">-- Bitte wählen --</option>
{% for bundesland in bundeslaender %}
<option value="{{ bundesland.id }}"
data-steuer="{{ bundesland.grunderwerbsteuer }}"
{% if immobilienData.bundesland_id == bundesland.id %}selected{% endif %}>
{{ bundesland.name }} ({{ bundesland.grunderwerbsteuer }}%)
</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="heizungstyp_id">Heizungstyp</label>
<select id="heizungstyp_id" name="heizungstyp_id">
<option value="">-- Bitte wählen --</option>
{% for heizungstyp in heizungstypen %}
<option value="{{ heizungstyp.id }}"
{% if immobilienData.heizungstyp_id == heizungstyp.id %}selected{% endif %}>
{{ heizungstyp.name }}
</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="abschreibungszeit">Abschreibungszeit (Jahre)</label>
<input type="number" id="abschreibungszeit" name="abschreibungszeit" value="{{ immobilienData.abschreibungszeit }}" placeholder="z.B. 50">
</div>
<div class="form-group checkbox-group">
<input type="checkbox" id="garage" name="garage" {% if immobilienData.garage %}checked{% endif %}>
<label for="garage">Garage vorhanden</label>
</div>
<div class="button-group">
{% if app.user %}
<button type="button" class="btn btn-primary" id="save-immobilie-btn">Speichern</button>
{% endif %}
<button type="button" class="btn btn-primary" id="share-link-btn">Link teilen</button>
<button type="button" class="btn btn-secondary" id="reset-btn">Zurücksetzen</button>
</div>
<div class="share-link" id="share-link-container">
<strong>Teilen Sie diese Berechnung:</strong>
<input type="text" id="share-url" readonly>
<button type="button" class="btn btn-secondary" style="margin-top: 10px;" id="copy-link-btn">Link kopieren</button>
</div>
</form>
</div>
<p>Die REST-API ist über API Platform verfügbar und bietet automatische Dokumentation.</p>
<div class="results-section">
<h2>Berechnungsergebnisse</h2>
<a href="/api" class="api-link">Zur API-Dokumentation</a>
<div class="result-item">
<h3>Gesamtfläche</h3>
<div class="value" id="result-gesamtflaeche">0 m²</div>
<div class="description">Wohnfläche + Nutzfläche</div>
</div>
<div class="result-item">
<h3>Preis pro m² Wohnfläche</h3>
<div class="value" id="result-preis-pro-qm">0,00 €</div>
<div class="description">Kaufpreis / Wohnfläche</div>
</div>
<div class="result-item">
<h3>Grunderwerbsteuer</h3>
<div class="value" id="result-grunderwerbsteuer">0,00 €</div>
<div class="description">Abhängig vom Bundesland</div>
</div>
<div class="result-item">
<h3>Gesamtkosten</h3>
<div class="value" id="result-gesamtkosten">0,00 €</div>
<div class="description">Kaufpreis + Grunderwerbsteuer</div>
</div>
<div class="result-item">
<h3>Jährliche Abschreibung</h3>
<div class="value" id="result-abschreibung">0,00 €</div>
<div class="description">Kaufpreis / Abschreibungszeit</div>
</div>
<div class="result-item">
<h3>Alter der Immobilie</h3>
<div class="value" id="result-alter">0 Jahre</div>
<div class="description">Aktuelles Jahr - Baujahr</div>
</div>
</div>
</div>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="{{ asset('js/calculator.js') }}"></script>
{% endblock %}

View File

@@ -0,0 +1,152 @@
{% extends 'base.html.twig' %}
{% block title %}Meine Immobilien - {{ parent() }}{% endblock %}
{% block stylesheets %}
{{ parent() }}
<style>
.immobilien-list {
margin-top: 20px;
}
.immobilie-card {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.immobilie-card h3 {
color: #333;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 2px solid #4CAF50;
}
.immobilie-details {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
.detail-item {
padding: 10px;
background-color: #f8f9fa;
border-radius: 4px;
}
.detail-item label {
display: block;
font-weight: 500;
color: #666;
font-size: 12px;
margin-bottom: 5px;
}
.detail-item value {
display: block;
color: #333;
font-size: 16px;
}
.empty-state {
text-align: center;
padding: 60px 20px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.empty-state h2 {
color: #666;
margin-bottom: 20px;
}
.empty-state a {
display: inline-block;
padding: 12px 24px;
background-color: #4CAF50;
color: white;
text-decoration: none;
border-radius: 4px;
transition: background-color 0.3s;
}
.empty-state a:hover {
background-color: #45a049;
}
</style>
{% endblock %}
{% block body %}
<h1>Meine Immobilien</h1>
{% if immobilien|length > 0 %}
<div class="immobilien-list">
{% for immobilie in immobilien %}
<div class="immobilie-card">
<h3>{{ immobilie.adresse }}</h3>
<div class="immobilie-details">
<div class="detail-item">
<label>Typ</label>
<value>{{ immobilie.typ.label }}</value>
</div>
<div class="detail-item">
<label>Kaufpreis</label>
<value>{{ immobilie.kaufpreis|number_format(0, ',', '.') }} €</value>
</div>
<div class="detail-item">
<label>Wohnfläche</label>
<value>{{ immobilie.wohnflaeche }} m²</value>
</div>
<div class="detail-item">
<label>Nutzfläche</label>
<value>{{ immobilie.nutzflaeche }} m²</value>
</div>
<div class="detail-item">
<label>Gesamtfläche</label>
<value>{{ immobilie.gesamtflaeche }} m²</value>
</div>
<div class="detail-item">
<label>Zimmer</label>
<value>{{ immobilie.zimmer }}</value>
</div>
{% if immobilie.baujahr %}
<div class="detail-item">
<label>Baujahr</label>
<value>{{ immobilie.baujahr }}</value>
</div>
{% endif %}
{% if immobilie.bundesland %}
<div class="detail-item">
<label>Bundesland</label>
<value>{{ immobilie.bundesland.name }}</value>
</div>
{% endif %}
{% if immobilie.heizungstyp %}
<div class="detail-item">
<label>Heizungstyp</label>
<value>{{ immobilie.heizungstyp.name }}</value>
</div>
{% endif %}
<div class="detail-item">
<label>Garage</label>
<value>{{ immobilie.garage ? 'Ja' : 'Nein' }}</value>
</div>
<div class="detail-item">
<label>Erstellt am</label>
<value>{{ immobilie.createdAt|date('d.m.Y H:i') }}</value>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<h2>Sie haben noch keine Immobilien gespeichert</h2>
<p>Nutzen Sie den Immobilienrechner, um Ihre erste Immobilie zu berechnen und zu speichern.</p>
<a href="{{ path('app_home') }}">Zum Rechner</a>
</div>
{% endif %}
{% endblock %}