<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&family=Poppins:wght@600;700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<style>
:root {
--primary-blue: #1565C0; --accent-orange: #FF9800; --success: #4CAF50;
--danger: #F44336; --star: #FFC107; --pinned: #E3F2FD;
--radius: 16px; --radius-sm: 10px; --reserved: #FFF3E0;
}
[data-theme="light"] {
--bg: #F5F5F5; --surface: #FFFFFF; --card: #FFFFFF;
--text: #333333; --text-secondary: #666666; --border: #E0E0E0;
}
[data-theme="dark"] {
--bg: #121212; --surface: #1E1E1E; --card: #2D2D2D;
--text: #E0E0E0; --text-secondary: #AAAAAA; --border: #333333;
--pinned: #1A237E; --reserved: #3E2723;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Nunito', sans-serif; background: var(--bg); color: var(--text);
min-height: 100vh; -webkit-tap-highlight-color: transparent; overscroll-behavior: none;
}
#app { max-width: 480px; margin: 0 auto; min-height: 100vh; display: flex; flex-direction: column; }
.app-header {
background: var(--surface); padding: 10px 16px; display: flex; align-items: center;
gap: 10px; border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 100; min-height: 50px;
}
.app-header h1 {
font-family: 'Poppins', sans-serif; font-size: 19px; color: var(--primary-blue);
display: flex; align-items: center; gap: 8px; flex: 1;
}
.back-arrow {
display: flex; align-items: center; justify-content: center; width: 38px; height: 38px;
border: none; background: none; color: var(--text); cursor: pointer; border-radius: 50%;
font-size: 26px; flex-shrink: 0; transition: all 0.2s;
}
.back-arrow:hover { background: var(--border); }
.back-arrow:active { transform: scale(0.9); }
.header-title {
font-size: 17px; font-weight: 700; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.location-badge {
display: flex; align-items: center; gap: 4px; background: var(--bg); padding: 6px 10px;
border-radius: 20px; font-size: 11px; font-weight: 600; cursor: pointer;
border: 2px solid var(--border); color: var(--text); max-width: 110px;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex-shrink: 0;
}
.main-content { flex: 1; overflow-y: auto; padding-bottom: 70px; }
.bottom-nav {
position: fixed; bottom: 0; left: 50%; transform: translateX(-50%); max-width: 480px; width: 100%;
background: var(--surface); border-top: 1px solid var(--border); display: flex;
justify-content: space-around; padding: 6px 0; z-index: 100;
}
.nav-item {
display: flex; flex-direction: column; align-items: center; gap: 2px; cursor: pointer;
padding: 6px 12px; border: none; background: none; color: var(--text-secondary);
font-family: 'Nunito', sans-serif; font-size: 10px; font-weight: 600; transition: all 0.2s;
}
.nav-item.active { color: var(--primary-blue); }
.nav-item .material-icons { font-size: 22px; }
.card {
background: var(--card); border-radius: var(--radius); padding: 14px; margin: 8px 14px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08); border: 1px solid var(--border); transition: all 0.15s;
}
.card:active { transform: scale(0.98); }
.job-card.reserved {
border-left: 4px solid var(--accent-orange);
background: var(--reserved);
}
.job-card.reserved::after {
content: '🔒 RESERVIERT';
position: absolute;
top: 8px;
right: 40px;
background: var(--accent-orange);
color: white;
padding: 3px 8px;
border-radius: 10px;
font-size: 10px;
font-weight: 700;
}
.job-category {
background: rgba(255, 152, 0, 0.15); color: var(--accent-orange);
padding: 4px 10px; border-radius: 20px; font-size: 11px; font-weight: 700; white-space: nowrap;
}
.distance-badge {
background: rgba(76, 175, 80, 0.15); color: var(--success);
padding: 4px 10px; border-radius: 20px; font-size: 11px; font-weight: 700;
display: flex; align-items: center; gap: 3px;
}
.status-badge {
padding: 4px 10px; border-radius: 20px; font-size: 11px; font-weight: 700;
display: inline-block;
}
.status-badge.offen { background: rgba(76,175,80,0.15); color: var(--success); }
.status-badge.reserviert { background: rgba(255,152,0,0.15); color: var(--accent-orange); }
.status-badge.vergeben { background: rgba(33,150,243,0.15); color: #2196F3; }
.status-badge.erledigt { background: rgba(156,39,176,0.15); color: #9C27B0; }
.btn {
padding: 11px 20px; border-radius: 25px; border: none; cursor: pointer; font-size: 14px;
font-weight: 700; font-family: 'Nunito', sans-serif; display: flex; align-items: center;
justify-content: center; gap: 6px; transition: all 0.15s;
}
.btn:active { transform: scale(0.96); }
.btn-accent { background: var(--accent-orange); color: white; width: 100%; }
.btn-primary { background: var(--primary-blue); color: white; width: 100%; }
.btn-outline { background: transparent; border: 2px solid var(--primary-blue); color: var(--primary-blue); width: 100%; }
.btn-danger { background: var(--danger); color: white; width: 100%; }
.btn-reserve { background: var(--accent-orange); color: white; width: 100%; }
.btn-unreserve { background: #795548; color: white; width: 100%; }
.form-input, .form-textarea, select.form-input {
width: 100%; padding: 11px 14px; border-radius: var(--radius-sm); border: 2px solid var(--border);
background: var(--card); color: var(--text); font-size: 14px; font-family: 'Nunito', sans-serif; outline: none;
}
.form-input:focus, .form-textarea:focus { border-color: var(--primary-blue); }
.form-textarea { min-height: 90px; resize: vertical; }
.form-group { margin-bottom: 14px; }
.form-group label { display: block; margin-bottom: 5px; font-weight: 600; font-size: 13px; }
.filter-scroll { display: flex; gap: 8px; overflow-x: auto; padding: 10px 14px; scrollbar-width: none; }
.filter-scroll::-webkit-scrollbar { display: none; }
.filter-chip {
padding: 7px 14px; border-radius: 20px; border: 2px solid var(--border); background: var(--card);
color: var(--text); cursor: pointer; white-space: nowrap; font-size: 12px; font-weight: 600;
transition: all 0.2s; flex-shrink: 0;
}
.filter-chip.active { background: var(--accent-orange); color: white; border-color: var(--accent-orange); }
.search-input {
width: 100%; padding: 10px 14px; border-radius: var(--radius-sm); border: 2px solid var(--border);
background: var(--card); color: var(--text); font-size: 14px; outline: none; margin: 10px 14px; width: calc(100% - 28px);
}
.profile-avatar {
width: 70px; height: 70px; border-radius: 50%; background: var(--primary-blue);
margin: 0 auto 8px; display: flex; align-items: center; justify-content: center;
font-size: 28px; color: white; font-weight: 700; overflow: hidden;
}
.profile-avatar img { width: 100%; height: 100%; object-fit: cover; }
.chat-bubble {
max-width: 78%; padding: 10px 14px; border-radius: 18px; margin: 3px 0;
font-size: 14px; word-wrap: break-word;
}
.chat-bubble.sent { background: var(--primary-blue); color: white; align-self: flex-end; border-bottom-right-radius: 4px; }
.chat-bubble.received { background: var(--border); color: var(--text); align-self: flex-start; border-bottom-left-radius: 4px; }
.toast {
position: fixed; bottom: 85px; left: 50%; transform: translateX(-50%); background: #333;
color: white; padding: 10px 20px; border-radius: 25px; font-size: 13px; font-weight: 600;
z-index: 300; text-align: center; max-width: 90%;
}
.empty-state { text-align: center; padding: 35px 18px; color: var(--text-secondary); }
.empty-state .material-icons { font-size: 52px; color: #9E9E9E; margin-bottom: 10px; }
.hidden { display: none !important; }
.settings-item {
display: flex; align-items: center; justify-content: space-between;
padding: 14px 0; border-bottom: 1px solid var(--border); cursor: pointer;
}
.settings-item-left { display: flex; align-items: center; gap: 8px; }
.toggle-switch { width: 48px; height: 26px; border-radius: 13px; background: var(--border); cursor: pointer; transition: background 0.3s; }
.toggle-switch.active { background: var(--primary-blue); }
.toggle-switch::after { content: ''; display: block; width: 20px; height: 20px; border-radius: 50%; background: white; margin: 3px; transition: transform 0.3s; }
.toggle-switch.active::after { transform: translateX(22px); }
.modal-overlay {
position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.6);
z-index: 200; display: flex; align-items: center; justify-content: center; padding: 20px;
}
.modal-content {
background: var(--surface); border-radius: var(--radius); padding: 24px;
width: 100%; max-width: 400px; max-height: 80vh; overflow-y: auto;
}
</style>
<div id="app">
<div id="app-header-container"></div>
<div class="main-content" id="main-content"></div>
<nav class="bottom-nav hidden" id="bottom-nav">
<button class="nav-item active" data-page="jobs" onclick="navigateTo('jobs')">
<span class="material-icons">home</span>Start
</button>
<button class="nav-item" data-page="create" onclick="navigateTo('create')">
<span class="material-icons">add_circle_outline</span>Neu
</button>
<button class="nav-item" data-page="chats" onclick="navigateTo('chats')">
<span class="material-icons">chat_bubble_outline</span>Chat
</button>
<button class="nav-item" data-page="profile" onclick="navigateTo('profile')">
<span class="material-icons">person_outline</span>Profil
</button>
</nav>
</div>
<input type="file" id="image-upload" accept="image/*" style="display:none" onchange="handleImageUpload(event)">
<script>
// ==================== DATENBANK MIT STORAGE-EVENT ====================
const DB = {
_users: JSON.parse(localStorage.getItem('mf_users') || '{}'),
_jobs: JSON.parse(localStorage.getItem('mf_jobs') || '[]'),
_chats: JSON.parse(localStorage.getItem('mf_chats') || '[]'),
_messages: JSON.parse(localStorage.getItem('mf_messages') || '{}'),
_applications: JSON.parse(localStorage.getItem('mf_applications') || '[]'),
get users() { return this._users; },
set users(v) { this._users = v; this.save(); },
get jobs() { return this._jobs; },
set jobs(v) { this._jobs = v; this.save(); },
get chats() { return this._chats; },
set chats(v) { this._chats = v; this.save(); },
get messages() { return this._messages; },
set messages(v) { this._messages = v; this.save(); },
get applications() { return this._applications; },
set applications(v) { this._applications = v; this.save(); },
save() {
localStorage.setItem('mf_users', JSON.stringify(this._users));
localStorage.setItem('mf_jobs', JSON.stringify(this._jobs));
localStorage.setItem('mf_chats', JSON.stringify(this._chats));
localStorage.setItem('mf_messages', JSON.stringify(this._messages));
localStorage.setItem('mf_applications', JSON.stringify(this._applications));
// Trigger für andere Tabs
localStorage.setItem('mf_lastUpdate', Date.now().toString());
},
reload() {
this._users = JSON.parse(localStorage.getItem('mf_users') || '{}');
this._jobs = JSON.parse(localStorage.getItem('mf_jobs') || '[]');
this._chats = JSON.parse(localStorage.getItem('mf_chats') || '[]');
this._messages = JSON.parse(localStorage.getItem('mf_messages') || '{}');
this._applications = JSON.parse(localStorage.getItem('mf_applications') || '[]');
}
};
// ==================== LIVE-UPDATE ZWISCHEN TABS ====================
window.addEventListener('storage', function(e) {
if (e.key === 'mf_lastUpdate') {
console.log('🔄 Änderung erkannt - aktualisiere...');
DB.reload();
// Aktuelle Seite neu rendern
if (currentUser && currentPage) {
switch(currentPage) {
case 'jobs': renderJobs(); break;
case 'chats': showChatsScreen(); break;
case 'job-detail': if (currentPageData) showJobDetailScreen(currentPageData); break;
}
}
}
});
// ==================== POLLING FÜR LIVE-UPDATES ====================
let lastUpdateCheck = Date.now();
setInterval(() => {
const currentUpdate = parseInt(localStorage.getItem('mf_lastUpdate') || '0');
if (currentUpdate > lastUpdateCheck) {
lastUpdateCheck = currentUpdate;
DB.reload();
if (currentUser && currentPage === 'jobs') {
renderJobs();
}
}
}, 2000); // Alle 2 Sekunden prüfen
const FEEDBACK_EMAIL = atob('Ym9obGthdWthaUBnbWFpbC5jb20=');
let userLocation = JSON.parse(localStorage.getItem('mf_location') || 'null');
let userCoordinates = null;
let navigationHistory = [];
let currentUser = null;
let selectedCategory = null;
let radiusFilter = parseInt(localStorage.getItem('mf_radius') || '50');
let currentPage = '';
let currentPageData = null;
let pinnedChats = JSON.parse(localStorage.getItem('mf_pinnedChats') || '{}');
const categories = ['Alle','Nachhilfe','Hundesitting','Babysitting','Gartenarbeit','Einkaufen helfen','Computerhilfe','Haushaltshilfe','Sonstiges'];
const radiusOptions = [5,10,20,30,50,75,100,200];
// ==================== INIT ====================
function init() {
if (userLocation) userCoordinates = { lat: userLocation.lat, lng: userLocation.lng };
else {
userLocation = { lat: 51.89, lng: 10.17, name: 'Seesen' };
userCoordinates = { lat: 51.89, lng: 10.17 };
localStorage.setItem('mf_location', JSON.stringify(userLocation));
}
if (Object.keys(DB.users).length === 0) initDemoData();
const savedUser = JSON.parse(localStorage.getItem('mf_currentUser') || 'null');
if (savedUser && DB.users[savedUser.email]) {
currentUser = DB.users[savedUser.email];
document.getElementById('bottom-nav').classList.remove('hidden');
navigateTo('jobs');
} else showLoginScreen();
}
function initDemoData() {
DB._users = {
'max@test.de': { uid: 'user1', name: 'Max (16)', email: 'max@test.de', password: '123456', age: 16, photoURL: '', bio: 'Schüler', ratingSum: 23, ratingCount: 5, completedJobs: 12, blockedUsers: [], createdAt: new Date().toISOString() },
'lisa@test.de': { uid: 'user2', name: 'Lisa (15)', email: 'lisa@test.de', password: '123456', age: 15, photoURL: '', bio: 'Mag Tiere', ratingSum: 18, ratingCount: 4, completedJobs: 8, blockedUsers: [], createdAt: new Date().toISOString() },
'herr-mueller@test.de': { uid: 'user3', name: 'Herr Müller (45)', email: 'herr-mueller@test.de', password: '123456', age: 45, photoURL: '', bio: 'Nachhilfe & Garten', ratingSum: 45, ratingCount: 9, completedJobs: 25, blockedUsers: [], createdAt: new Date().toISOString() }
};
DB._jobs = [
{ id: 'job1', title: 'Nachhilfe Mathe 8. Klasse', category: 'Nachhilfe', description: 'Suche Mathe-Nachhilfe für meinen Sohn (14). 1-2x pro Woche.', location: 'Seesen', lat: 51.89, lng: 10.17, payment: '18 € / Stunde', date: '2025-02-01', createdBy: 'user3', createdAt: new Date().toISOString(), status: 'offen' },
{ id: 'job2', title: 'Hundesitting Samstag', category: 'Hundesitting', description: 'Golden Retriever braucht Betreuung am Samstag.', location: 'Goslar', lat: 51.91, lng: 10.42, payment: '25 € / Tag', date: '2025-02-08', createdBy: 'user2', createdAt: new Date().toISOString(), status: 'offen' }
];
DB.save();
}
// ==================== STANDORT ====================
function updateLocation(name, lat, lng, radius) {
userLocation = { lat, lng, name };
userCoordinates = { lat, lng };
radiusFilter = radius;
localStorage.setItem('mf_location', JSON.stringify(userLocation));
localStorage.setItem('mf_radius', radius.toString());
}
function calculateDistance(lat1,lng1,lat2,lng2) {
const R=6371, dLat=(lat2-lat1)*Math.PI/180, dLng=(lng2-lng1)*Math.PI/180;
const a=Math.sin(dLat/2)**2+Math.cos(lat1*Math.PI/180)*Math.cos(lat2*Math.PI/180)*Math.sin(dLng/2)**2;
return Math.round(R*2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a))*10)/10;
}
function getDistanceText(job) { if(!userCoordinates||!job.lat||!job.lng)return null; const d=calculateDistance(userCoordinates.lat,userCoordinates.lng,job.lat,job.lng); return d<1?'< 1 km':`${d} km`; }
function sortJobsByDistance(jobs) { if(!userCoordinates)return jobs; return jobs.sort((a,b)=>calculateDistance(userCoordinates.lat,userCoordinates.lng,a.lat||52.5,a.lng||13.4)-calculateDistance(userCoordinates.lat,userCoordinates.lng,b.lat||52.5,b.lng||13.4)); }
// ==================== NAVIGATION ====================
function navigateTo(page, data=null, addToHistory=true) {
if(addToHistory&¤tPage&¤tPage!==page){navigationHistory.push({page:currentPage,data:currentPageData});}
currentPage=page; currentPageData=data;
updateHeader(page); updateBottomNav(page);
if(!currentUser&&page!=='login'){showLoginScreen();return;}
switch(page){case'jobs':showJobsScreen();break;case'create':showCreateJobScreen();break;case'chats':showChatsScreen();break;case'profile':showProfileScreen();break;case'settings':showSettingsScreen();break;case'job-detail':showJobDetailScreen(data);break;case'user-profile':showUserProfileScreen(data);break;case'chat':showChatScreen(data);break;case'my-jobs':showMyJobs();break;case'my-applications':showMyApplications();break;case'edit-profile':editProfileScreen();break;case'feedback':showFeedbackScreen();break;case'delete-account':showDeleteAccountScreen();break;default:showJobsScreen();}
}
function goBack() { if(navigationHistory.length>0){const prev=navigationHistory.pop();navigateTo(prev.page,prev.data,false);}else navigateTo('jobs'); }
function updateHeader(page) {
const container=document.getElementById('app-header-container');
const mainPages=['jobs','create','chats','profile','settings'];
let showBack=!mainPages.includes(page)&&page!=='login', title='';
switch(page){case'jobs':title='MiniJob Finder';break;case'create':title='Job erstellen';break;case'chats':title='Nachrichten';break;case'profile':title='Mein Profil';break;case'settings':title='Einstellungen';break;case'job-detail':title='Job-Details';break;case'user-profile':title='Nutzerprofil';break;case'chat':title='Chat';break;case'my-jobs':title='Meine Jobs';break;case'my-applications':title='Bewerbungen';break;case'edit-profile':title='Profil bearbeiten';break;case'feedback':title='Feedback';break;case'delete-account':title='Account löschen';break;default:title='';}
if(showBack)container.innerHTML=`<div class="app-header"><button class="back-arrow" onclick="goBack()">←</button><span class="header-title">${title}</span></div>`;
else if(page==='login')container.innerHTML='';
else container.innerHTML=`<div class="app-header"><span style="font-size:22px">💼</span><h1 style="font-size:18px">MiniJob Finder</h1><button class="location-badge" onclick="showLocationModal()"><span class="material-icons" style="font-size:14px">location_on</span><span>${(userLocation?.name||'Ort').substring(0,12)}</span></button></div>`;
}
function updateBottomNav(page) {
document.querySelectorAll('.nav-item').forEach(item=>item.classList.toggle('active',item.dataset.page===page||(page==='settings'&&item.dataset.page==='profile')));
}
function showToast(msg) {
const e=document.querySelector('.toast'); if(e)e.remove();
const t=document.createElement('div'); t.className='toast'; t.textContent=msg;
document.body.appendChild(t); setTimeout(()=>t.remove(),3000);
}
function escapeHtml(t) { if(!t)return''; const d=document.createElement('div'); d.textContent=t; return d.innerHTML; }
function generateId() { return'id_'+Date.now()+'_'+Math.random().toString(36).substr(2,9); }
// ==================== LOCATION MODAL ====================
function showLocationModal() {
document.querySelector('.modal-overlay')?.remove();
const overlay = document.createElement('div'); overlay.className = 'modal-overlay'; overlay.id = 'location-modal';
overlay.innerHTML = `
<div class="modal-content" onclick="event.stopPropagation()">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:16px">
<button class="back-arrow" onclick="closeLocationModal()">←</button>
<h2 style="font-size:18px">📍 Standort ändern</h2>
</div>
<div class="form-group"><label>Stadt / Ort</label><input type="text" id="modal-location-input" class="form-input" placeholder="z.B. Seesen, Berlin..." value="${escapeHtml(userLocation?.name||'')}"></div>
<div class="form-group"><label>Suchradius</label><select id="modal-radius-input" class="form-input">${radiusOptions.map(r=>`<option value="${r}" ${r===radiusFilter?'selected':''}>${r} km</option>`).join('')}</select></div>
<div style="display:flex;gap:8px"><button class="btn btn-outline" onclick="closeLocationModal()">Abbrechen</button><button class="btn btn-accent" onclick="saveLocationFromModal()">Speichern</button></div>
</div>`;
document.body.appendChild(overlay);
overlay.addEventListener('click', (e) => { if (e.target === overlay) closeLocationModal(); });
setTimeout(() => document.getElementById('modal-location-input')?.focus(), 200);
}
function closeLocationModal() { document.getElementById('location-modal')?.remove(); }
function saveLocationFromModal() {
const city = document.getElementById('modal-location-input')?.value?.trim();
const radius = parseInt(document.getElementById('modal-radius-input')?.value || '50');
if (!city) { showToast('Bitte Stadt eingeben'); return; }
const cityCoords = { 'seesen':[51.89,10.17], 'goslar':[51.91,10.42], 'berlin':[52.52,13.40], 'hamburg':[53.55,9.99], 'münchen':[48.13,11.58], 'köln':[50.94,6.96] };
let coords = [52.52, 13.40];
for (const [c, coord] of Object.entries(cityCoords)) { if (city.toLowerCase().includes(c)) { coords = coord; break; } }
updateLocation(city, coords[0], coords[1], radius);
closeLocationModal();
showToast(`📍 ${city} (${radius} km)`);
if (currentPage === 'settings') showSettingsScreen(); else if (currentPage === 'jobs') showJobsScreen();
}
// ==================== LOGIN ====================
function showLoginScreen() {
currentPage='login'; document.getElementById('bottom-nav').classList.add('hidden'); document.getElementById('app-header-container').innerHTML='';
document.getElementById('main-content').innerHTML=`
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:80vh;padding:20px">
<span style="font-size:60px">💼</span>
<h2 style="font-family:'Poppins',sans-serif;font-size:24px;color:var(--primary-blue);margin:8px 0">MiniJob Finder</h2>
<p style="color:var(--text-secondary);margin-bottom:16px;text-align:center">Finde Minijobs in deiner Nähe</p>
${userLocation?`<p style="color:var(--success);margin-bottom:14px">📍 ${userLocation.name}</p>`:''}
<div style="width:100%"><div class="form-group"><label>E-Mail</label><input type="email" id="login-email" class="form-input" placeholder="max@test.de"></div>
<div class="form-group"><label>Passwort</label><input type="password" id="login-password" class="form-input" placeholder="123456" onkeypress="if(event.key==='Enter')login()"></div>
<button class="btn btn-accent" onclick="login()">Anmelden</button>
<button class="btn btn-outline" onclick="showRegisterScreen()" style="margin-top:8px">Neues Konto</button>
<div style="background:var(--card);border-radius:var(--radius-sm);padding:12px;margin-top:14px;text-align:center;font-size:11px"><strong>Demo:</strong><br>📧 max@test.de | 🔑 123456<br>📧 herr-mueller@test.de | 🔑 123456</div></div></div>`;
}
function showRegisterScreen() {
document.getElementById('main-content').innerHTML=`
<div style="padding:16px"><button class="back-arrow" onclick="showLoginScreen()">←</button>
<h2 style="margin:14px 0;text-align:center">Konto erstellen</h2>
<div class="form-group"><label>Name</label><input type="text" id="reg-name" class="form-input" placeholder="Dein Name"></div>
<div class="form-group"><label>E-Mail</label><input type="email" id="reg-email" class="form-input" placeholder="deine@email.de"></div>
<div class="form-group"><label>Passwort</label><input type="password" id="reg-password" class="form-input" placeholder="Mind. 6 Zeichen"></div>
<div class="form-group"><label>Geburtsdatum (mind. 13 Jahre)</label><input type="date" id="reg-birthdate" class="form-input"></div>
<button class="btn btn-accent" onclick="register()">Registrieren</button></div>`;
}
function login() {
const email=document.getElementById('login-email').value.trim().toLowerCase(), password=document.getElementById('login-password').value;
const user=DB.users[email];
if(user&&user.password===password){currentUser=user;localStorage.setItem('mf_currentUser',JSON.stringify({email}));document.getElementById('bottom-nav').classList.remove('hidden');navigationHistory=[];showToast(`👋 ${user.name}!`);navigateTo('jobs');}
else showToast('❌ Falsche Anmeldedaten');
}
function register() {
const name=document.getElementById('reg-name').value.trim(), email=document.getElementById('reg-email').value.trim().toLowerCase(), password=document.getElementById('reg-password').value, birthdate=document.getElementById('reg-birthdate').value;
if(!name||!email||!password||!birthdate){showToast('Alle Felder ausfüllen');return;}
if(DB.users[email]){showToast('E-Mail bereits registriert');return;}
const age=Math.floor((new Date()-new Date(birthdate))/(365.25*24*60*60*1000));
if(age<13){showToast('Mindestens 13 Jahre alt');return;}
DB.users[email]={uid:generateId(),name,email,password,age,photoURL:'',bio:'',ratingSum:0,ratingCount:0,completedJobs:0,blockedUsers:[],createdAt:new Date().toISOString()};
currentUser=DB.users[email]; localStorage.setItem('mf_currentUser',JSON.stringify({email}));
document.getElementById('bottom-nav').classList.remove('hidden'); navigationHistory=[]; showToast('🎉 Willkommen!'); navigateTo('jobs');
}
function logout() { currentUser=null; localStorage.removeItem('mf_currentUser'); document.getElementById('bottom-nav').classList.add('hidden'); navigationHistory=[]; showLoginScreen(); showToast('👋 Abgemeldet'); }
// ==================== BILD-UPLOAD ====================
function triggerImageUpload() { document.getElementById('image-upload').click(); }
function handleImageUpload(event) {
const file=event.target.files[0]; if(!file)return;
const reader=new FileReader();
reader.onload=function(e){if(currentUser){currentUser.photoURL=e.target.result;if(DB.users[currentUser.email])DB.users[currentUser.email].photoURL=e.target.result;DB.save();showToast('📸 Profilbild gespeichert!');}};
reader.readAsDataURL(file); event.target.value='';
}
// ==================== FEEDBACK ====================
function showFeedbackScreen() {
updateHeader('feedback');
document.getElementById('main-content').innerHTML = `
<div style="padding:16px"><h2 style="margin-bottom:8px">📝 Feedback</h2>
<div class="form-group"><label>Betreff</label><input type="text" id="feedback-subject" class="form-input"></div>
<div class="form-group"><label>Nachricht *</label><textarea id="feedback-message" class="form-textarea"></textarea></div>
<button class="btn btn-feedback" onclick="sendFeedback()" style="background:#8E24AA;color:white">Senden</button></div>`;
}
function sendFeedback() {
const message=document.getElementById('feedback-message').value.trim();
if(!message){showToast('Nachricht schreiben');return;}
window.location.href='mailto:'+FEEDBACK_EMAIL+'?subject=[MiniJob Finder] Feedback&body='+encodeURIComponent('Von: '+currentUser.name+' ('+currentUser.email+')\n\n'+message);
showToast('✅ E-Mail-Client geöffnet');
}
// ==================== JOBS SCREEN ====================
function showJobsScreen() {
updateHeader('jobs');
document.getElementById('main-content').innerHTML=`
<input type="text" class="search-input" id="job-search" placeholder="🔍 Jobs suchen..." oninput="renderJobs()">
<div class="filter-scroll">${categories.map(c=>`<button class="filter-chip ${(c==='Alle'&&!selectedCategory)||c===selectedCategory?'active':''}" onclick="setCategory('${c==='Alle'?'':c}')">${c}</button>`).join('')}</div>
<div style="padding:4px 14px;font-size:11px"><span>Umkreis:</span> <select id="radius-select" class="form-input" style="width:auto;padding:4px 8px" onchange="changeRadius()">${radiusOptions.map(r=>`<option value="${r}" ${r===radiusFilter?'selected':''}>${r} km</option>`).join('')}</select> <span style="color:var(--text-secondary)">📍 ${userLocation?.name||'Unbekannt'}</span></div>
<div id="jobs-list"></div>`;
renderJobs();
}
function setCategory(cat) { selectedCategory=cat||null; showJobsScreen(); }
function changeRadius() { radiusFilter=parseInt(document.getElementById('radius-select').value); localStorage.setItem('mf_radius',radiusFilter); renderJobs(); }
function renderJobs() {
const jobsList=document.getElementById('jobs-list'); if(!jobsList)return;
// Daten neu laden (wichtig für Live-Updates!)
DB.reload();
let jobs=DB.jobs.filter(j=>j.status==='offen'||j.status==='reserviert');
if(userCoordinates)jobs=jobs.filter(j=>{if(!j.lat||!j.lng)return true;return calculateDistance(userCoordinates.lat,userCoordinates.lng,j.lat,j.lng)<=radiusFilter;});
if(selectedCategory)jobs=jobs.filter(j=>j.category===selectedCategory);
const s=document.getElementById('job-search')?.value?.toLowerCase()||'';
if(s)jobs=jobs.filter(j=>j.title.toLowerCase().includes(s)||j.description.toLowerCase().includes(s)||j.location.toLowerCase().includes(s));
if(userCoordinates)jobs=sortJobsByDistance(jobs);
if(jobs.length===0){
jobsList.innerHTML=`<div class="empty-state"><span class="material-icons">rocket_launch</span><h2>Keine Jobs im Umkreis</h2><p>Erstelle den ersten Job!</p><button class="btn btn-accent" onclick="navigateTo('create')" style="margin-top:12px">Job erstellen</button></div>`;
return;
}
jobsList.innerHTML=jobs.map(job=>{
const creator=Object.values(DB.users).find(u=>u.uid===job.createdBy);
const dist=getDistanceText(job);
const isReserved=job.status==='reserviert';
return`<div class="card job-card ${isReserved?'reserved':''}" onclick="navigateTo('job-detail','${job.id}')" style="position:relative">
<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:6px">
<strong style="font-size:14px;flex:1">${escapeHtml(job.title)}</strong>
<span class="job-category">${escapeHtml(job.category)}</span>
</div>
<p style="color:var(--text-secondary);font-size:12px;margin-bottom:6px">${escapeHtml(job.description.substring(0,80))}...</p>
<div style="display:flex;justify-content:space-between;align-items:center;font-size:11px;color:var(--text-secondary)">
<span>📍 ${escapeHtml(job.location)}</span>
${dist?`<span class="distance-badge">📏 ${dist}</span>`:''}
<span style="color:var(--success);font-weight:700">💰 ${escapeHtml(job.payment)}</span>
</div>
${isReserved?`<div style="margin-top:6px"><span class="status-badge reserviert">🔒 Reserviert</span></div>`:''}
</div>`;
}).join('');
}
// ==================== JOB DETAIL MIT RESERVIEREN ====================
function showJobDetailScreen(jobId) {
updateHeader('job-detail');
DB.reload();
const job=DB.jobs.find(j=>j.id===jobId);
if(!job){document.getElementById('main-content').innerHTML='<div class="empty-state"><p>Job nicht gefunden</p></div>';return;}
const creator=Object.values(DB.users).find(u=>u.uid===job.createdBy);
const isOwner=job.createdBy===currentUser?.uid;
const isReserved=job.status==='reserviert';
const isOffen=job.status==='offen';
document.getElementById('main-content').innerHTML=`
<div style="padding:14px">
<div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;margin-bottom:12px">
<span class="job-category">${escapeHtml(job.category)}</span>
<span class="status-badge ${job.status}">${job.status==='offen'?'✅ Offen':job.status==='reserviert'?'🔒 Reserviert':job.status}</span>
</div>
<h2 style="font-size:18px;margin-bottom:8px">${escapeHtml(job.title)}</h2>
<p style="font-size:13px;line-height:1.5;margin-bottom:14px;color:var(--text-secondary)">${escapeHtml(job.description)}</p>
<div style="background:var(--card);padding:12px;border-radius:var(--radius-sm);margin-bottom:14px;font-size:12px">
<p>📍 ${escapeHtml(job.location)}</p><p>💰 ${escapeHtml(job.payment)}</p>
<p>📅 ${new Date(job.date).toLocaleDateString('de-DE')}</p>
<p>🕐 Erstellt: ${new Date(job.createdAt).toLocaleDateString('de-DE')}</p>
</div>
${creator?`<div class="card" style="margin:0 0 14px 0" onclick="navigateTo('user-profile','${creator.uid}')"><div style="display:flex;align-items:center;gap:10px"><div style="width:40px;height:40px;border-radius:50%;background:var(--primary-blue);color:white;display:flex;align-items:center;justify-content:center;font-weight:700">${creator.name.charAt(0)}</div><div><strong>${escapeHtml(creator.name)}</strong><div style="font-size:11px;color:var(--text-secondary)">${creator.age}J</div></div></div></div>`:''}
${isOffen&&!isOwner?`<button class="btn btn-accent" onclick="applyForJob('${job.id}')">📩 Jetzt bewerben</button>`:''}
${isReserved&&!isOwner?`<button class="btn btn-outline" disabled style="opacity:0.6">🔒 Bereits reserviert</button>`:''}
${isOwner&&isOffen?`<button class="btn btn-reserve" onclick="reserveJob('${job.id}')">🔒 Für Bewerber reservieren</button>`:''}
${isOwner&&isReserved?`<button class="btn btn-unreserve" onclick="unreserveJob('${job.id}')">🔓 Reservierung aufheben</button>`:''}
${isOwner?`<button class="btn btn-danger" onclick="deleteJob('${job.id}')" style="margin-top:6px">🗑️ Job löschen</button>`:''}
</div>`;
}
function applyForJob(jobId) {
const msg=prompt('💬 Nachricht an den Anbieter:');
if(!msg)return;
DB.applications.push({id:generateId(),jobId,applicantId:currentUser.uid,applicantName:currentUser.name,message:msg,status:'ausstehend',createdAt:new Date().toISOString()});
const job=DB.jobs.find(j=>j.id===jobId);
if(job)startChatWithMessage(job.createdBy,`📩 Bewerbung für "${job.title}":\n\n${msg}\n\nVon: ${currentUser.name}`);
DB.save();
showToast('✅ Bewerbung gesendet! Der Anbieter kann den Job jetzt für dich reservieren.');
}
// ==================== JOB RESERVIEREN/FREIGEBEN ====================
function reserveJob(jobId) {
if(!confirm('🔒 Job reservieren?\n\nDer Job wird als "Reserviert" markiert und andere sehen, dass er vergeben sein könnte.\n\nDu kannst die Reservierung jederzeit aufheben.')) return;
const jobIndex = DB._jobs.findIndex(j=>j.id===jobId);
if(jobIndex>-1){
DB._jobs[jobIndex].status = 'reserviert';
DB.save();
showToast('🔒 Job reserviert!');
navigateTo('job-detail', jobId);
}
}
function unreserveJob(jobId) {
if(!confirm('🔓 Reservierung aufheben?\n\nDer Job ist dann wieder für alle sichtbar und offen.')) return;
const jobIndex = DB._jobs.findIndex(j=>j.id===jobId);
if(jobIndex>-1){
DB._jobs[jobIndex].status = 'offen';
DB.save();
showToast('🔓 Job wieder offen!');
navigateTo('job-detail', jobId);
}
}
function deleteJob(jobId) { if(!confirm('Job löschen?'))return; DB.jobs=DB.jobs.filter(j=>j.id!==jobId); DB.save(); showToast('Job gelöscht'); goBack(); }
// ==================== CREATE JOB ====================
function showCreateJobScreen() {
updateHeader('create');
document.getElementById('main-content').innerHTML=`
<div style="padding:14px"><h2>📝 Neuen Job erstellen</h2>
<div class="form-group"><label>Titel *</label><input type="text" id="job-title" class="form-input" placeholder="z.B. Nachhilfe"></div>
<div class="form-group"><label>Kategorie *</label><select id="job-category" class="form-input" onchange="document.getElementById('custom-cat').style.display=this.value==='andere'?'block':'none'"><option value="">Wählen...</option>${categories.filter(c=>c!=='Alle').map(c=>`<option value="${c}">${c}</option>`).join('')}<option value="andere">➕ Eigene...</option></select><input type="text" id="custom-cat" class="form-input" placeholder="Kategorie" style="display:none;margin-top:6px"></div>
<div class="form-group"><label>Beschreibung *</label><textarea id="job-description" class="form-textarea"></textarea></div>
<div class="form-group"><label>Ort *</label><input type="text" id="job-location" class="form-input" value="${escapeHtml(userLocation?.name||'')}"></div>
<div class="form-group"><label>Bezahlung *</label><input type="text" id="job-payment" class="form-input" placeholder="z.B. 15 €/Std"></div>
<button class="btn btn-accent" onclick="createJob()">Veröffentlichen</button></div>`;
}
function createJob() {
const title=document.getElementById('job-title').value.trim(), description=document.getElementById('job-description').value.trim(), location=document.getElementById('job-location').value.trim(), payment=document.getElementById('job-payment').value.trim();
let category=document.getElementById('job-category').value;
if(category==='andere')category=document.getElementById('custom-cat').value.trim();
if(!title||!category||!description||!location||!payment){showToast('Alle Felder ausfüllen');return;}
DB.jobs.unshift({id:generateId(),title,category,description,location,payment,lat:userLocation?.lat||51.89,lng:userLocation?.lng||10.17,date:new Date().toISOString().split('T')[0],createdBy:currentUser.uid,createdAt:new Date().toISOString(),status:'offen'});
DB.save();
showToast('🎉 Job veröffentlicht!');
navigateTo('jobs');
}
// ==================== PROFILE & SETTINGS ====================
function showProfileScreen() {
updateHeader('profile');
const myJobs=DB.jobs.filter(j=>j.createdBy===currentUser.uid).length;
const myApps=DB.applications.filter(a=>a.applicantId===currentUser.uid).length;
document.getElementById('main-content').innerHTML=`
<div style="background:var(--card);padding:20px;text-align:center;border-radius:0 0 var(--radius) var(--radius);margin-bottom:14px">
<div class="profile-avatar" onclick="triggerImageUpload()">${currentUser.photoURL?`<img src="${currentUser.photoURL}">`:currentUser.name.charAt(0)}</div>
<h2>${escapeHtml(currentUser.name)}</h2><p>${currentUser.age} Jahre</p>
<div style="display:flex;justify-content:center;gap:18px;margin-top:8px"><div><strong>${myJobs}</strong><br><span style="font-size:11px">Jobs</span></div><div><strong>${myApps}</strong><br><span style="font-size:11px">Bewerb.</span></div></div>
</div>
<div style="padding:14px;display:flex;flex-direction:column;gap:6px">
<button class="btn btn-outline" onclick="navigateTo('my-jobs')">Meine Jobs</button>
<button class="btn btn-outline" onclick="navigateTo('settings')">Einstellungen</button>
<button class="btn" onclick="navigateTo('feedback')" style="background:#8E24AA;color:white">Feedback</button>
</div>`;
}
function showSettingsScreen() {
updateHeader('settings');
const isDark=document.body.getAttribute('data-theme')==='dark';
document.getElementById('main-content').innerHTML=`
<div style="padding:14px">
<div style="background:var(--card);border-radius:var(--radius);padding:16px;margin-bottom:14px">
<div style="display:flex;align-items:center;gap:10px">
<div style="width:45px;height:45px;border-radius:50%;background:var(--primary-blue);color:white;display:flex;align-items:center;justify-content:center;font-weight:700">${currentUser.name.charAt(0)}</div>
<div><strong>${escapeHtml(currentUser.name)}</strong><p style="font-size:12px;color:var(--text-secondary)">${escapeHtml(currentUser.email)}</p></div>
</div>
</div>
<div style="background:var(--card);border-radius:var(--radius);padding:4px 14px;margin-bottom:14px">
<div class="settings-item" onclick="toggleTheme();showSettingsScreen()"><div class="settings-item-left"><span class="material-icons">${isDark?'dark_mode':'light_mode'}</span>Dark Mode</div><div class="toggle-switch ${isDark?'active':''}"></div></div>
<div class="settings-item" onclick="showLocationModal()"><div class="settings-item-left"><span class="material-icons">edit_location</span>Standort: ${userLocation?.name||'?'} (${radiusFilter}km)</div></div>
<div class="settings-item" onclick="navigateTo('edit-profile')"><div class="settings-item-left"><span class="material-icons">edit</span>Profil bearbeiten</div></div>
</div>
<button class="btn btn-danger" onclick="logout()">Abmelden</button>
<button class="btn" onclick="navigateTo('delete-account')" style="background:#B71C1C;color:white;margin-top:8px">Account löschen</button>
</div>`;
}
function toggleTheme() {
const t=document.body.getAttribute('data-theme')==='light'?'dark':'light';
document.body.setAttribute('data-theme',t); localStorage.setItem('mf_theme',t);
}
function showMyJobs() {
updateHeader('my-jobs');
const myJobs=DB.jobs.filter(j=>j.createdBy===currentUser.uid);
const c=document.getElementById('main-content');
if(myJobs.length===0){c.innerHTML=`<div class="empty-state"><h3>Keine Jobs</h3></div>`;return;}
c.innerHTML=`<div style="padding:14px">${myJobs.map(j=>`<div class="card" onclick="navigateTo('job-detail','${j.id}')"><div style="display:flex;justify-content:space-between"><strong>${escapeHtml(j.title)}</strong><span class="status-badge ${j.status}">${j.status}</span></div><p style="font-size:11px">${escapeHtml(j.location)} • ${escapeHtml(j.payment)}</p></div>`).join('')}</div>`;
}
function showMyApplications() {
updateHeader('my-applications');
const myApps=DB.applications.filter(a=>a.applicantId===currentUser.uid);
const c=document.getElementById('main-content');
if(myApps.length===0){c.innerHTML=`<div class="empty-state"><h3>Keine Bewerbungen</h3></div>`;return;}
c.innerHTML=`<div style="padding:14px">${myApps.map(a=>{const j=DB.jobs.find(j=>j.id===a.jobId);return`<div class="card"><strong>${escapeHtml(j?.title||'Job weg')}</strong><p style="font-size:11px">Status: ${a.status}</p></div>`;}).join('')}</div>`;
}
function editProfileScreen() {
updateHeader('edit-profile');
document.getElementById('main-content').innerHTML=`
<div style="padding:14px"><div style="text-align:center;margin-bottom:16px"><div class="profile-avatar" onclick="triggerImageUpload()">${currentUser.photoURL?`<img src="${currentUser.photoURL}">`:currentUser.name.charAt(0)}</div></div>
<div class="form-group"><label>Name</label><input type="text" id="edit-name" class="form-input" value="${escapeHtml(currentUser.name)}"></div>
<div class="form-group"><label>Bio</label><textarea id="edit-bio" class="form-textarea">${escapeHtml(currentUser.bio||'')}</textarea></div>
<button class="btn btn-accent" onclick="saveProfile()">Speichern</button></div>`;
}
function saveProfile() {
const name=document.getElementById('edit-name').value.trim(), bio=document.getElementById('edit-bio').value.trim();
if(!name){showToast('Name erforderlich');return;}
currentUser.name=name; currentUser.bio=bio;
if(DB.users[currentUser.email]){DB.users[currentUser.email].name=name;DB.users[currentUser.email].bio=bio;}
DB.save(); showToast('✅ Gespeichert!'); goBack();
}
function showUserProfileScreen(userId) {
updateHeader('user-profile');
const user=Object.values(DB.users).find(u=>u.uid===userId);
if(!user)return;
document.getElementById('main-content').innerHTML=`
<div style="background:var(--card);padding:16px;text-align:center;margin-bottom:12px">
<div style="width:60px;height:60px;border-radius:50%;background:var(--primary-blue);color:white;display:flex;align-items:center;justify-content:center;font-weight:700;margin:0 auto">${user.name.charAt(0)}</div>
<h2>${escapeHtml(user.name)}</h2><p>${user.age}J</p>
</div>
<div style="padding:14px">${user.uid!==currentUser?.uid?`<button class="btn btn-primary" onclick="startChat('${user.uid}')">💬 Nachricht</button>`:''}</div>`;
}
// ==================== CHATS ====================
function showChatsScreen() {
updateHeader('chats');
const myChats=DB.chats.filter(c=>c.participants.includes(currentUser.uid));
const sorted=[...myChats].sort((a,b)=>{
const aM=DB.messages[a.id]||[], bM=DB.messages[b.id]||[];
return(bM.length>0?new Date(bM[bM.length-1].timestamp).getTime():0)-(aM.length>0?new Date(aM[aM.length-1].timestamp).getTime():0);
});
const c=document.getElementById('main-content');
if(sorted.length===0){c.innerHTML=`<div class="empty-state"><span class="material-icons">chat_bubble_outline</span><h3>Keine Chats</h3></div>`;return;}
c.innerHTML=`<div style="padding:14px">${sorted.map(chat=>{
const oId=chat.participants.find(id=>id!==currentUser.uid), oU=Object.values(DB.users).find(u=>u.uid===oId);
const msgs=DB.messages[chat.id]||[], last=msgs[msgs.length-1];
return`<div class="card" onclick="navigateTo('chat','${chat.id}')"><div style="display:flex;align-items:center;gap:10px"><div style="width:38px;height:38px;border-radius:50%;background:var(--primary-blue);color:white;display:flex;align-items:center;justify-content:center;font-weight:700">${(oU?.name||'?')[0]}</div><div style="flex:1"><strong>${escapeHtml(oU?.name||'?')}</strong><p style="font-size:11px;color:var(--text-secondary)">${last?escapeHtml(last.text.substring(0,30)):'Keine Nachrichten'}</p></div></div></div>`;
}).join('')}</div>`;
}
function startChat(otherUserId) { startChatWithMessage(otherUserId,null); }
function startChatWithMessage(uid,msg) {
let chat=DB.chats.find(c=>c.participants.includes(currentUser.uid)&&c.participants.includes(uid));
if(!chat){chat={id:generateId(),participants:[currentUser.uid,uid],createdAt:new Date().toISOString(),lastRead:{}};DB.chats.push(chat);DB.messages[chat.id]=[];}
if(msg)DB.messages[chat.id].push({id:generateId(),senderId:currentUser.uid,text:msg,timestamp:new Date().toISOString()});
DB.save(); navigateTo('chat',chat.id);
}
function showChatScreen(chatId) {
updateHeader('chat');
const chat=DB.chats.find(c=>c.id===chatId);
if(!chat)return;
if(!chat.lastRead)chat.lastRead={}; chat.lastRead[currentUser.uid]=Date.now(); DB.save();
const msgs=DB.messages[chatId]||[];
document.getElementById('main-content').innerHTML=`<div style="display:flex;flex-direction:column;height:calc(100vh-155px)"><div id="msg-container" style="flex:1;overflow-y:auto;padding:10px">${msgs.length===0?'<p style="text-align:center;margin-top:40px;color:var(--text-secondary)">💬 Keine Nachrichten</p>':''}</div><div style="padding:8px;display:flex;gap:6px;border-top:1px solid var(--border)"><input type="text" id="msg-input" class="form-input" placeholder="Nachricht..." style="flex:1" onkeypress="if(event.key==='Enter')sendMessage('${chatId}')"><button class="btn btn-primary" onclick="sendMessage('${chatId}')" style="width:auto">➤</button></div></div>`;
renderMessages(chatId);
}
function renderMessages(chatId) {
const c=document.getElementById('msg-container'); if(!c)return;
const msgs=DB.messages[chatId]||[];
c.innerHTML=msgs.map(m=>`<div style="display:flex;justify-content:${m.senderId===currentUser.uid?'flex-end':'flex-start'}"><div class="chat-bubble ${m.senderId===currentUser.uid?'sent':'received'}">${escapeHtml(m.text)}<div style="font-size:9px;opacity:0.6;margin-top:3px">${new Date(m.timestamp).toLocaleTimeString('de-DE',{hour:'2-digit',minute:'2-digit'})}</div></div></div>`).join('');
if(msgs.length>0)c.scrollTop=c.scrollHeight;
}
function sendMessage(chatId) {
const i=document.getElementById('msg-input'), t=i.value.trim(); if(!t)return;
if(!DB.messages[chatId])DB.messages[chatId]=[];
DB.messages[chatId].push({id:generateId(),senderId:currentUser.uid,text:t,timestamp:new Date().toISOString()});
DB.save(); i.value=''; renderMessages(chatId);
}
// ==================== ACCOUNT LÖSCHEN ====================
function showDeleteAccountScreen() {
updateHeader('delete-account');
document.getElementById('main-content').innerHTML = `
<div style="padding:16px">
<div style="text-align:center;margin-bottom:20px"><span class="material-icons" style="font-size:64px;color:var(--danger)">warning_amber</span>
<h2 style="color:var(--danger)">Account löschen</h2></div>
<div class="form-group"><label>Passwort zur Bestätigung</label><input type="password" id="delete-password" class="form-input"></div>
<label style="display:flex;align-items:center;gap:8px;margin-bottom:14px"><input type="checkbox" id="delete-confirm">Ja, ich möchte meinen Account unwiderruflich löschen</label>
<button class="btn btn-delete-account" onclick="deleteAccount()" style="background:#B71C1C;color:white">🗑️ Account löschen</button>
<button class="btn btn-outline" onclick="goBack()" style="margin-top:8px">Abbrechen</button>
</div>`;
}
function deleteAccount() {
if(!document.getElementById('delete-confirm').checked){showToast('Bitte bestätigen');return;}
if(document.getElementById('delete-password').value!==currentUser.password){showToast('Falsches Passwort');return;}
if(!confirm('WIRKLICH löschen?'))return;
const uid=currentUser.uid, email=currentUser.email;
DB.jobs=DB.jobs.filter(j=>j.createdBy!==uid);
DB.applications=DB.applications.filter(a=>a.applicantId!==uid);
DB.chats.forEach(c=>{if(c.participants.includes(uid))delete DB.messages[c.id];});
DB.chats=DB.chats.filter(c=>!c.participants.includes(uid));
delete DB.users[email]; DB.save();
currentUser=null; localStorage.removeItem('mf_currentUser');
document.getElementById('bottom-nav').classList.add('hidden');
showToast('Account gelöscht'); showLoginScreen();
}
// ==================== START ====================
const savedTheme=localStorage.getItem('mf_theme');
if(savedTheme)document.body.setAttribute('data-theme',savedTheme);
console.log('🚀 MiniJob Finder v4.0');
console.log('🔄 Live-Updates zwischen Tabs aktiv');
console.log('🔒 Job-Reservierung verfügbar');
init();
</script>