612 lines
38 KiB
Plaintext
612 lines
38 KiB
Plaintext
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<%- include('partials/head') %>
|
||
</head>
|
||
<body class="min-h-screen transition-colors duration-300 bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100" id="body">
|
||
<%- include('partials/header') %>
|
||
|
||
<main class="container mx-auto px-4 py-8">
|
||
<!-- Filter Section -->
|
||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8">
|
||
<h2 class="text-lg font-semibold text-gray-800 dark:text-white mb-4">Filter</h2>
|
||
<form id="filterForm" class="flex flex-wrap gap-4 items-end">
|
||
<div class="flex-1 min-w-32">
|
||
<label for="filterMonth" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Monat
|
||
</label>
|
||
<select
|
||
id="filterMonth"
|
||
name="month"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
|
||
<option value="">-- Alle Monate --</option>
|
||
<% availableMonths.forEach(m => { %>
|
||
<option value="<%= m.month %>"><%= m.month %> - <%= m.year %></option>
|
||
<% }); %>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="flex-1 min-w-32">
|
||
<label for="filterYear" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Jahr
|
||
</label>
|
||
<select
|
||
id="filterYear"
|
||
name="year"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
|
||
<option value="">-- Alle Jahre --</option>
|
||
<% const years = [...new Set(availableMonths.map(m => m.year))].sort().reverse(); %>
|
||
<% years.forEach(y => { %>
|
||
<option value="<%= y %>"><%= y %></option>
|
||
<% }); %>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="flex space-x-2">
|
||
<button
|
||
type="submit"
|
||
class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors">
|
||
Filtern
|
||
</button>
|
||
<a
|
||
href="/"
|
||
class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
||
Zurücksetzen
|
||
</a>
|
||
</div>
|
||
|
||
<div class="ml-auto">
|
||
<button
|
||
type="button"
|
||
id="exportPdfBtn"
|
||
class="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors flex items-center space-x-2">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||
</svg>
|
||
<span>PDF Export</span>
|
||
</button>
|
||
</div>
|
||
|
||
<div>
|
||
<button
|
||
type="button"
|
||
id="addApplicationBtn"
|
||
class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors flex items-center space-x-2">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
|
||
</svg>
|
||
<span>Bewerbung hinzufügen</span>
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Statistics Section -->
|
||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8">
|
||
<h2 class="text-lg font-semibold text-gray-800 dark:text-white mb-6">Statistik</h2>
|
||
|
||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||
<!-- Total Applications -->
|
||
<div class="bg-blue-50 dark:bg-gray-700 rounded-lg p-4 text-center">
|
||
<div class="text-3xl font-bold text-blue-600 dark:text-blue-400"><%= statistics.total %></div>
|
||
<div class="text-gray-600 dark:text-gray-400 mt-2">Gesamtbewerbungen</div>
|
||
</div>
|
||
|
||
<!-- By Application Type -->
|
||
<div class="bg-green-50 dark:bg-gray-700 rounded-lg p-4">
|
||
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">Nach Bewerbungsart</h3>
|
||
<div class="space-y-2">
|
||
<% if (statistics.byArt.length > 0) { %>
|
||
<% statistics.byArt.forEach(item => { %>
|
||
<div class="flex justify-between text-sm">
|
||
<span class="text-gray-600 dark:text-gray-400"><%= item.art %></span>
|
||
<span class="font-medium text-gray-800 dark:text-white"><%= item.count %></span>
|
||
</div>
|
||
<% }); %>
|
||
<% } else { %>
|
||
<p class="text-sm text-gray-500 dark:text-gray-400">Keine Daten verfügbar</p>
|
||
<% } %>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- By Status -->
|
||
<div class="bg-purple-50 dark:bg-gray-700 rounded-lg p-4">
|
||
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">Nach Status</h3>
|
||
<div class="space-y-2">
|
||
<% if (statistics.byStatus.length > 0) { %>
|
||
<% statistics.byStatus.forEach(item => { %>
|
||
<div class="flex justify-between text-sm">
|
||
<span class="text-gray-600 dark:text-gray-400"><%= item.status %></span>
|
||
<span class="font-medium text-gray-800 dark:text-white"><%= item.count %></span>
|
||
</div>
|
||
<% }); %>
|
||
<% } else { %>
|
||
<p class="text-sm text-gray-500 dark:text-gray-400">Keine Daten verfügbar</p>
|
||
<% } %>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Applications Table -->
|
||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden">
|
||
<table class="w-full">
|
||
<thead class="bg-gray-50 dark:bg-gray-700">
|
||
<tr>
|
||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Datum</th>
|
||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Firma</th>
|
||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Stelle</th>
|
||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Art</th>
|
||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Status</th>
|
||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Aktionen</th>
|
||
</tr>
|
||
</thead>
|
||
<% if (applications.length > 0) { %>
|
||
<%
|
||
// Status-Reihenfolge synchron zu public/js/main.js halten
|
||
const statusOrder = ['Gesendet', 'Eingangsbestätigung', 'Vorstellungsgespräch',
|
||
'Einstellung', 'Absage', 'Keine Rückmeldung'];
|
||
const statusDot = {
|
||
'Gesendet': 'bg-indigo-500',
|
||
'Eingangsbestätigung': 'bg-blue-500',
|
||
'Vorstellungsgespräch': 'bg-yellow-500',
|
||
'Einstellung': 'bg-green-500',
|
||
'Absage': 'bg-red-500',
|
||
'Keine Rückmeldung': 'bg-gray-400',
|
||
'Ohne Status': 'bg-gray-300'
|
||
};
|
||
const groups = {};
|
||
applications.forEach(a => {
|
||
const key = (a.status && a.status.trim()) ? a.status.trim() : 'Ohne Status';
|
||
(groups[key] = groups[key] || []).push(a);
|
||
});
|
||
const orderedKeys = [
|
||
...statusOrder.filter(s => groups[s]),
|
||
...Object.keys(groups).filter(k => !statusOrder.includes(k))
|
||
];
|
||
%>
|
||
<% orderedKeys.forEach(statusKey => { %>
|
||
<tbody class="bg-gray-100 dark:bg-gray-900/40 border-b border-gray-200 dark:border-gray-700">
|
||
<tr>
|
||
<td colspan="6" class="px-6 py-3">
|
||
<div class="flex items-center gap-3">
|
||
<span class="inline-block w-2.5 h-2.5 rounded-full <%= statusDot[statusKey] || 'bg-gray-300' %>"></span>
|
||
<span class="text-sm font-semibold uppercase tracking-wider text-gray-700 dark:text-gray-200"><%= statusKey %></span>
|
||
<span class="text-xs font-medium px-2 py-0.5 rounded-full bg-white dark:bg-gray-700 text-gray-600 dark:text-gray-300"><%= groups[statusKey].length %></span>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
<% groups[statusKey].forEach(app => { %>
|
||
<%
|
||
const hatNotizen = app.notizen && app.notizen.trim().length > 0;
|
||
const hatInterne = app.interne_notizen && app.interne_notizen.trim().length > 0;
|
||
const hatVerlauf = app.verlauf && app.verlauf.length > 0;
|
||
const hatDetails = hatNotizen || hatInterne || hatVerlauf;
|
||
const padB = hatDetails ? 'pb-2' : 'pb-4';
|
||
%>
|
||
<tbody class="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
|
||
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">
|
||
<td class="px-6 pt-4 <%= padB %> whitespace-nowrap text-sm text-gray-900 dark:text-white">
|
||
<%= new Date(app.datum).toLocaleDateString('de-DE') %>
|
||
</td>
|
||
<td class="px-6 pt-4 <%= padB %> whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">
|
||
<%= app.firma %>
|
||
</td>
|
||
<td class="px-6 pt-4 <%= padB %> whitespace-nowrap text-sm text-gray-900 dark:text-white">
|
||
<%= app.stelle %>
|
||
</td>
|
||
<td class="px-6 pt-4 <%= padB %> whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
|
||
<%= app.art || '-' %>
|
||
</td>
|
||
<td class="px-6 pt-4 <%= padB %> whitespace-nowrap text-sm">
|
||
<span class="px-2 py-1 rounded-full text-xs font-medium
|
||
<%= app.status === 'Einstellung' ? 'bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100' :
|
||
app.status === 'Absage' ? 'bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100' :
|
||
app.status === 'Vorstellungsgespräch' ? 'bg-yellow-100 text-yellow-800 dark:bg-yellow-800 dark:text-yellow-100' :
|
||
'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300' %>">
|
||
<%= app.status || '-' %>
|
||
</span>
|
||
</td>
|
||
<td class="px-6 pt-4 <%= padB %> whitespace-nowrap text-sm align-top">
|
||
<a href="/bewerbung/<%= app.id %>"
|
||
class="inline-block align-middle text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 mr-3"
|
||
aria-label="Bearbeiten">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
|
||
</svg>
|
||
</a>
|
||
<button
|
||
class="delete-btn align-middle text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300"
|
||
data-id="<%= app.id %>">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
|
||
</svg>
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
<% if (hatDetails) { %>
|
||
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">
|
||
<td colspan="6" class="px-6 pb-5 pt-0 space-y-3">
|
||
<% if (hatVerlauf) { %>
|
||
<div class="rounded-lg border-l-4 border-indigo-400 dark:border-indigo-500 bg-indigo-50/60 dark:bg-gray-700/40 px-4 py-3">
|
||
<div class="flex items-center gap-2 mb-2">
|
||
<svg class="w-4 h-4 text-indigo-500 dark:text-indigo-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||
</svg>
|
||
<span class="text-xs font-semibold uppercase tracking-wider text-indigo-600 dark:text-indigo-400">Status-Verlauf</span>
|
||
</div>
|
||
<ol class="space-y-1.5">
|
||
<% app.verlauf.forEach(v => { %>
|
||
<li class="flex flex-wrap gap-x-2 text-sm">
|
||
<span class="text-gray-500 dark:text-gray-400 whitespace-nowrap"><%= new Date(v.datum).toLocaleDateString('de-DE') %></span>
|
||
<span class="font-semibold text-gray-800 dark:text-gray-100"><%= v.status %></span>
|
||
<% if (v.kommentar && v.kommentar.trim()) { %>
|
||
<span class="text-gray-600 dark:text-gray-300 whitespace-pre-wrap break-words">– <%= v.kommentar %></span>
|
||
<% } %>
|
||
</li>
|
||
<% }); %>
|
||
</ol>
|
||
</div>
|
||
<% } %>
|
||
<% if (hatNotizen) { %>
|
||
<div class="rounded-lg border-l-4 border-blue-400 dark:border-blue-500 bg-blue-50/70 dark:bg-gray-700/40 px-4 py-3">
|
||
<div class="flex items-center gap-2 mb-2">
|
||
<svg class="w-4 h-4 text-blue-500 dark:text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||
</svg>
|
||
<span class="text-xs font-semibold uppercase tracking-wider text-blue-600 dark:text-blue-400">Notizen</span>
|
||
</div>
|
||
<p class="whitespace-pre-wrap break-words text-base leading-relaxed text-gray-800 dark:text-gray-200"><%= app.notizen %></p>
|
||
</div>
|
||
<% } %>
|
||
<% if (hatInterne) { %>
|
||
<div class="rounded-lg border-l-4 border-amber-400 dark:border-amber-500 bg-amber-50/70 dark:bg-gray-700/40 px-4 py-3">
|
||
<div class="flex items-center gap-2 mb-2">
|
||
<svg class="w-4 h-4 text-amber-500 dark:text-amber-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
|
||
</svg>
|
||
<span class="text-xs font-semibold uppercase tracking-wider text-amber-600 dark:text-amber-400">Interne Notizen · nicht im PDF</span>
|
||
</div>
|
||
<p class="whitespace-pre-wrap break-words text-base leading-relaxed text-gray-800 dark:text-gray-200"><%= app.interne_notizen %></p>
|
||
</div>
|
||
<% } %>
|
||
</td>
|
||
</tr>
|
||
<% } %>
|
||
</tbody>
|
||
<% }); %>
|
||
<% }); %>
|
||
<% } else { %>
|
||
<tbody class="bg-white dark:bg-gray-800">
|
||
<tr>
|
||
<td colspan="6" class="px-6 py-12 text-center text-gray-500 dark:text-gray-400">
|
||
<p>Keine Bewerbungen gefunden.</p>
|
||
<p class="mt-2 text-sm">Klicken Sie auf "Bewerbung hinzufügen", um Ihre erste Bewerbung einzutragen.</p>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
<% } %>
|
||
</table>
|
||
</div>
|
||
</main>
|
||
|
||
<%- include('partials/footer') %>
|
||
|
||
<!-- Settings Modal -->
|
||
<div id="settingsModal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden">
|
||
<div class="flex items-center justify-center min-h-screen p-4">
|
||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-md p-6">
|
||
<div class="flex justify-between items-center mb-6">
|
||
<h2 class="text-xl font-bold text-gray-800 dark:text-white">Benutzereinstellungen</h2>
|
||
<button id="closeSettingsModal" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
|
||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<form id="settingsForm" class="space-y-4">
|
||
<div>
|
||
<label for="userName" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Vollständiger Name *
|
||
</label>
|
||
<input
|
||
type="text"
|
||
id="userName"
|
||
name="name"
|
||
required
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white"
|
||
placeholder="Max Mustermann"
|
||
value="<%= settings.name || '' %>">
|
||
</div>
|
||
|
||
<div>
|
||
<label for="userAddress" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Adresse *
|
||
</label>
|
||
<textarea
|
||
id="userAddress"
|
||
name="adresse"
|
||
required
|
||
rows="2"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white"
|
||
placeholder="Musterstraße 1, 12345 Musterstadt"><%= settings.adresse || '' %></textarea>
|
||
</div>
|
||
|
||
<div>
|
||
<label for="customerNumber" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Jobcenter Kundennummer
|
||
</label>
|
||
<input
|
||
type="text"
|
||
id="customerNumber"
|
||
name="kundennummer"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white"
|
||
placeholder="z.B. 123456789"
|
||
value="<%= settings.kundennummer || '' %>">
|
||
</div>
|
||
|
||
<div class="flex justify-end space-x-3 pt-4">
|
||
<button
|
||
type="button"
|
||
id="cancelSettings"
|
||
class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
||
Abbrechen
|
||
</button>
|
||
<button
|
||
type="submit"
|
||
class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors">
|
||
Speichern
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Add/Edit Application Modal -->
|
||
<div id="applicationModal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden">
|
||
<div class="flex items-center justify-center min-h-screen p-4">
|
||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-lg p-6">
|
||
<div class="flex justify-between items-center mb-6">
|
||
<h2 id="modalTitle" class="text-xl font-bold text-gray-800 dark:text-white">Bewerbung hinzufügen</h2>
|
||
<button id="closeApplicationModal" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
|
||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<form id="applicationForm" class="space-y-4">
|
||
<input type="hidden" id="applicationId" name="id">
|
||
|
||
<div>
|
||
<label for="applicationDatum" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Datum *
|
||
</label>
|
||
<input
|
||
type="date"
|
||
id="applicationDatum"
|
||
name="datum"
|
||
required
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
|
||
</div>
|
||
|
||
<div>
|
||
<label for="applicationFirma" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Firma *
|
||
</label>
|
||
<input
|
||
type="text"
|
||
id="applicationFirma"
|
||
name="firma"
|
||
required
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white"
|
||
placeholder="Firmenname">
|
||
</div>
|
||
|
||
<div>
|
||
<label for="applicationStelle" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Stelle *
|
||
</label>
|
||
<input
|
||
type="text"
|
||
id="applicationStelle"
|
||
name="stelle"
|
||
required
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white"
|
||
placeholder="Stellenbezeichnung">
|
||
</div>
|
||
|
||
<div>
|
||
<label for="applicationArt" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Art der Bewerbung
|
||
</label>
|
||
<select
|
||
id="applicationArt"
|
||
name="art"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
|
||
<option value="">-- Bitte wählen --</option>
|
||
<% artOptions.forEach(option => { %>
|
||
<option value="<%= option %>"><%= option %></option>
|
||
<% }); %>
|
||
</select>
|
||
</div>
|
||
|
||
<div>
|
||
<label for="applicationStatus" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Status (Anfangsstatus)
|
||
</label>
|
||
<select
|
||
id="applicationStatus"
|
||
name="status"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
|
||
<option value="">-- Bitte wählen --</option>
|
||
<% statusOptions.forEach(option => { %>
|
||
<option value="<%= option %>"><%= option %></option>
|
||
<% }); %>
|
||
</select>
|
||
</div>
|
||
|
||
<div>
|
||
<label for="applicationKommentar" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Kommentar zur Statusänderung
|
||
</label>
|
||
<textarea
|
||
id="applicationKommentar"
|
||
name="kommentar"
|
||
rows="2"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed"
|
||
placeholder="Optional – z.B. „per E-Mail an Frau Müller“"></textarea>
|
||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Weitere Statusänderungen dokumentierst du später auf der Bearbeiten-Seite.</p>
|
||
</div>
|
||
|
||
<div>
|
||
<label for="applicationNotizen" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Notizen
|
||
</label>
|
||
<textarea
|
||
id="applicationNotizen"
|
||
name="notizen"
|
||
rows="4"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed"
|
||
placeholder="Allgemeine Notizen zur Bewerbung..."></textarea>
|
||
</div>
|
||
|
||
<div>
|
||
<label for="applicationInterneNotizen" class="block text-sm font-medium text-amber-700 dark:text-amber-400 mb-2 flex items-center gap-1.5">
|
||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
|
||
</svg>
|
||
Interne Notizen (nicht im PDF)
|
||
</label>
|
||
<textarea
|
||
id="applicationInterneNotizen"
|
||
name="interne_notizen"
|
||
rows="3"
|
||
class="w-full px-3 py-2 border border-amber-300 dark:border-amber-700 rounded-md bg-amber-50 dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed"
|
||
placeholder="Nur für dich – erscheint nicht im Export..."></textarea>
|
||
</div>
|
||
|
||
<div class="flex justify-end space-x-3 pt-4">
|
||
<button
|
||
type="button"
|
||
id="cancelApplication"
|
||
class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
||
Abbrechen
|
||
</button>
|
||
<button
|
||
type="submit"
|
||
class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors">
|
||
Speichern
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Delete Confirmation Modal -->
|
||
<div id="deleteModal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden">
|
||
<div class="flex items-center justify-center min-h-screen p-4">
|
||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-md p-6">
|
||
<div class="flex justify-between items-center mb-6">
|
||
<h2 class="text-xl font-bold text-gray-800 dark:text-white">Bewerbung löschen</h2>
|
||
<button id="closeDeleteModal" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
|
||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<p class="text-gray-600 dark:text-gray-400 mb-6">
|
||
Sind Sie sicher, dass Sie diese Bewerbung löschen möchten? Dieser Vorgang kann nicht rückgängig gemacht werden.
|
||
</p>
|
||
|
||
<div class="flex justify-end space-x-3">
|
||
<button
|
||
type="button"
|
||
id="cancelDelete"
|
||
class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
||
Abbrechen
|
||
</button>
|
||
<button
|
||
type="button"
|
||
id="confirmDelete"
|
||
class="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-md transition-colors">
|
||
Löschen
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- PDF Export Modal -->
|
||
<div id="pdfExportModal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden">
|
||
<div class="flex items-center justify-center min-h-screen p-4">
|
||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-md p-6">
|
||
<div class="flex justify-between items-center mb-6">
|
||
<h2 class="text-xl font-bold text-gray-800 dark:text-white">PDF Export</h2>
|
||
<button id="closePdfModal" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
|
||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<form id="pdfExportForm" class="space-y-4">
|
||
<div>
|
||
<label for="pdfMonth" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Monat
|
||
</label>
|
||
<select
|
||
id="pdfMonth"
|
||
name="month"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
|
||
<option value="">-- Alle Monate --</option>
|
||
<% availableMonths.forEach(m => { %>
|
||
<option value="<%= m.month %>"><%= m.month %> - <%= m.year %></option>
|
||
<% }); %>
|
||
</select>
|
||
</div>
|
||
|
||
<div>
|
||
<label for="pdfYear" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
Jahr
|
||
</label>
|
||
<select
|
||
id="pdfYear"
|
||
name="year"
|
||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
|
||
<option value="">-- Alle Jahre --</option>
|
||
<% const pdfYears = [...new Set(availableMonths.map(m => m.year))].sort().reverse(); %>
|
||
<% pdfYears.forEach(y => { %>
|
||
<option value="<%= y %>"><%= y %></option>
|
||
<% }); %>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="flex justify-end space-x-3 pt-4">
|
||
<button
|
||
type="button"
|
||
id="cancelPdfExport"
|
||
class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
|
||
Abbrechen
|
||
</button>
|
||
<button
|
||
type="submit"
|
||
class="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors">
|
||
PDF generieren
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Load main JavaScript -->
|
||
<script src="/js/main.js"></script>
|
||
</body>
|
||
</html>
|