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

96
public/css/auth.css Normal file
View File

@@ -0,0 +1,96 @@
.auth-container {
max-width: 450px;
margin: 50px auto;
}
.auth-box {
background: white;
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.auth-box h2 {
text-align: center;
color: #333;
margin-bottom: 30px;
padding-bottom: 15px;
border-bottom: 2px solid #4CAF50;
}
.auth-form .form-group {
margin-bottom: 20px;
}
.auth-form label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: #555;
}
.auth-form input[type="text"],
.auth-form input[type="email"],
.auth-form input[type="password"] {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.auth-form input:focus {
outline: none;
border-color: #4CAF50;
}
.auth-form .btn-submit {
width: 100%;
padding: 14px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: background-color 0.3s;
}
.auth-form .btn-submit:hover {
background-color: #45a049;
}
.error-message {
background-color: #ffebee;
color: #c62828;
padding: 12px;
border-radius: 4px;
margin-bottom: 20px;
border-left: 4px solid #c62828;
}
.success-message {
background-color: #e8f5e9;
color: #2e7d32;
padding: 12px;
border-radius: 4px;
margin-bottom: 20px;
border-left: 4px solid #2e7d32;
}
.auth-links {
text-align: center;
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #eee;
}
.auth-links a {
color: #4CAF50;
text-decoration: none;
}
.auth-links a:hover {
text-decoration: underline;
}

146
public/css/calculator.css Normal file
View File

@@ -0,0 +1,146 @@
.calculator-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-top: 20px;
}
.form-section, .results-section {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.form-section h2, .results-section h2 {
color: #333;
border-bottom: 2px solid #4CAF50;
padding-bottom: 10px;
margin-bottom: 20px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: #555;
}
.form-group input,
.form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #4CAF50;
}
.checkbox-group {
display: flex;
align-items: center;
}
.checkbox-group input[type="checkbox"] {
width: auto;
margin-right: 8px;
}
.result-item {
padding: 15px;
margin-bottom: 15px;
background-color: #f8f9fa;
border-left: 4px solid #4CAF50;
border-radius: 4px;
}
.result-item h3 {
margin: 0 0 5px 0;
color: #333;
font-size: 16px;
}
.result-item .value {
font-size: 24px;
font-weight: bold;
color: #4CAF50;
}
.result-item .description {
margin-top: 5px;
font-size: 12px;
color: #666;
}
.button-group {
display: flex;
gap: 10px;
margin-top: 20px;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: background-color 0.3s;
}
.btn-primary {
background-color: #4CAF50;
color: white;
}
.btn-primary:hover {
background-color: #45a049;
}
.btn-secondary {
background-color: #6c757d;
color: white;
}
.btn-secondary:hover {
background-color: #5a6268;
}
.share-link {
margin-top: 15px;
padding: 10px;
background-color: #e8f5e9;
border-radius: 4px;
display: none;
}
.share-link input {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
margin-top: 5px;
}
.info-banner {
background-color: #e3f2fd;
padding: 15px;
border-radius: 4px;
margin-bottom: 20px;
border-left: 4px solid #2196F3;
}
@media (max-width: 768px) {
.calculator-container {
grid-template-columns: 1fr;
}
}

112
public/js/calculator.js Normal file
View File

@@ -0,0 +1,112 @@
$(document).ready(function() {
// Live calculation function
function calculate() {
const kaufpreis = parseFloat($('#kaufpreis').val()) || 0;
const wohnflaeche = parseFloat($('#wohnflaeche').val()) || 0;
const nutzflaeche = parseFloat($('#nutzflaeche').val()) || 0;
const baujahr = parseInt($('#baujahr').val()) || 0;
const abschreibungszeit = parseFloat($('#abschreibungszeit').val()) || 50;
const bundeslandSteuer = parseFloat($('#bundesland_id option:selected').data('steuer')) || 0;
// Gesamtfläche
const gesamtflaeche = wohnflaeche + nutzflaeche;
$('#result-gesamtflaeche').text(gesamtflaeche.toLocaleString('de-DE') + ' m²');
// Preis pro m²
const preisProQm = wohnflaeche > 0 ? kaufpreis / wohnflaeche : 0;
$('#result-preis-pro-qm').text(preisProQm.toLocaleString('de-DE', {minimumFractionDigits: 2, maximumFractionDigits: 2}) + ' €');
// Grunderwerbsteuer
const grunderwerbsteuer = kaufpreis * (bundeslandSteuer / 100);
$('#result-grunderwerbsteuer').text(grunderwerbsteuer.toLocaleString('de-DE', {minimumFractionDigits: 2, maximumFractionDigits: 2}) + ' €');
// Gesamtkosten
const gesamtkosten = kaufpreis + grunderwerbsteuer;
$('#result-gesamtkosten').text(gesamtkosten.toLocaleString('de-DE', {minimumFractionDigits: 2, maximumFractionDigits: 2}) + ' €');
// Jährliche Abschreibung
const abschreibung = abschreibungszeit > 0 ? kaufpreis / abschreibungszeit : 0;
$('#result-abschreibung').text(abschreibung.toLocaleString('de-DE', {minimumFractionDigits: 2, maximumFractionDigits: 2}) + ' €');
// Alter der Immobilie
const currentYear = new Date().getFullYear();
const alter = baujahr > 0 ? currentYear - baujahr : 0;
$('#result-alter').text(alter + ' Jahre');
}
// Trigger calculation on any input change
$('#immo-calculator-form input, #immo-calculator-form select').on('input change', function() {
calculate();
});
// Generate shareable link
$('#share-link-btn').click(function() {
const formData = $('#immo-calculator-form').serializeArray();
const params = new URLSearchParams();
formData.forEach(item => {
if (item.value) {
params.append(item.name, item.value);
}
});
const shareUrl = window.location.origin + window.location.pathname + '?' + params.toString();
$('#share-url').val(shareUrl);
$('#share-link-container').slideDown();
});
// Copy link to clipboard
$('#copy-link-btn').click(function() {
const shareUrl = $('#share-url');
shareUrl.select();
document.execCommand('copy');
alert('Link wurde in die Zwischenablage kopiert!');
});
// Reset form
$('#reset-btn').click(function() {
$('#immo-calculator-form')[0].reset();
$('#share-link-container').slideUp();
calculate();
});
// Save immobilie (for logged in users)
$('#save-immobilie-btn').click(function() {
const formData = $('#immo-calculator-form').serializeArray();
const data = {};
formData.forEach(item => {
if (item.name === 'garage') {
data[item.name] = $('#garage').is(':checked');
} else {
data[item.name] = item.value;
}
});
$.ajax({
url: '/immobilie/save',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(data),
success: function(response) {
if (response.success) {
alert(response.message + '\n\nSie können Ihre gespeicherten Immobilien unter "Meine Immobilien" einsehen.');
} else {
alert('Fehler: ' + response.message);
}
},
error: function(xhr) {
if (xhr.status === 401) {
alert('Sie müssen angemeldet sein, um Immobilien zu speichern.');
window.location.href = '/login';
} else {
const response = xhr.responseJSON;
alert('Fehler: ' + (response ? response.message : 'Unbekannter Fehler'));
}
}
});
});
// Initial calculation on page load
calculate();
});