211 lines
9.7 KiB
Plaintext
211 lines
9.7 KiB
Plaintext
@model DashboardViewModel
|
||
@using System.Text.Encodings.Web
|
||
@using System.Text.Json
|
||
@using System.Linq
|
||
@{
|
||
ViewData["Title"] = "Übersicht";
|
||
|
||
var chartSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web)
|
||
{
|
||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||
};
|
||
|
||
var monthlyStats = Model.MonthlyApplications ?? Array.Empty<MonthlyApplicationStat>();
|
||
var recentApplications = Model.RecentApplications ?? Enumerable.Empty<Application>();
|
||
}
|
||
|
||
@if (!Model.IsAuthenticated)
|
||
{
|
||
<section class="hero">
|
||
<div class="hero-content">
|
||
<p class="eyebrow">LEA Bewerbungs-Tracker</p>
|
||
<h1>Behalte deine Bewerbungen mühelos im Blick</h1>
|
||
<p class="lead">Erfasse Bewerbungen, aktualisiere Status und sammle Notizen an einem Ort. Mit wenigen Klicks bleibst du organisiert und bestens vorbereitet auf jedes Gespräch.</p>
|
||
<div class="hero-actions">
|
||
<a class="btn btn-primary" asp-controller="Account" asp-action="Register">Jetzt registrieren</a>
|
||
<a class="btn btn-outline" asp-controller="Account" asp-action="Login">Anmelden</a>
|
||
</div>
|
||
</div>
|
||
<div class="hero-visual" aria-hidden="true">
|
||
<div class="hero-card">
|
||
<span class="status-badge status-applied">Beworben</span>
|
||
<span class="status-badge status-interview">Interview</span>
|
||
<span class="status-badge status-offer">Angebot</span>
|
||
<span class="status-badge status-rejected">Abgelehnt</span>
|
||
</div>
|
||
<div class="hero-highlight">
|
||
<p><strong>Smarter Überblick</strong></p>
|
||
<p>Analysiere Trends, nutze Filter und führe strukturierte Gespräche mit deinem nächsten Arbeitgeber.</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="feature-grid">
|
||
<article class="feature-card">
|
||
<h3>Bewerbungen speichern</h3>
|
||
<p>Lege jede Bewerbung mit wenigen Angaben an – inklusive Ansprechpartner, Quelle und individuellen Notizen.</p>
|
||
</article>
|
||
<article class="feature-card">
|
||
<h3>Status & Fortschritt</h3>
|
||
<p>Halte Termine und Feedback fest, aktualisiere den Status und bleibe immer einen Schritt voraus.</p>
|
||
</article>
|
||
<article class="feature-card">
|
||
<h3>Individuelle Statistiken</h3>
|
||
<p>Erhalte auf einen Blick, wie viele Bewerbungen offen, im Interview oder bereits abgeschlossen sind.</p>
|
||
</article>
|
||
</section>
|
||
}
|
||
else
|
||
{
|
||
<section class="dashboard-header">
|
||
<div>
|
||
<p class="eyebrow">Willkommen zurück</p>
|
||
<h1>@(string.IsNullOrWhiteSpace(Model.FullName) ? "Dein Bewerbungs-Dashboard" : $"Hallo, {Model.FullName}!")</h1>
|
||
<p class="lead">Behalte deine Bewerbungen im Blick, aktualisiere den Status und bereite dich optimal auf deine nächsten Schritte vor.</p>
|
||
<div class="action-group">
|
||
<a class="btn btn-primary" asp-controller="Applications" asp-action="Create">Neue Bewerbung erfassen</a>
|
||
<a class="btn btn-outline" asp-controller="Applications" asp-action="Index">Alle Bewerbungen anzeigen</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="stats-grid">
|
||
<article class="stat-card">
|
||
<p class="stat-label">Gesamt</p>
|
||
<p class="stat-value">@Model.TotalApplications</p>
|
||
<p class="stat-caption">Bewerbungen insgesamt</p>
|
||
</article>
|
||
<article class="stat-card">
|
||
<p class="stat-label">Beworben</p>
|
||
<p class="stat-value">@Model.AppliedCount</p>
|
||
<p class="stat-caption">Offene Bewerbungen</p>
|
||
</article>
|
||
<article class="stat-card">
|
||
<p class="stat-label">Interviews</p>
|
||
<p class="stat-value">@Model.InterviewCount</p>
|
||
<p class="stat-caption">Geplante Gespräche</p>
|
||
</article>
|
||
<article class="stat-card">
|
||
<p class="stat-label">Angebote</p>
|
||
<p class="stat-value">@Model.OfferCount</p>
|
||
<p class="stat-caption">Erfolgreiche Angebote</p>
|
||
</article>
|
||
<article class="stat-card">
|
||
<p class="stat-label">Absagen</p>
|
||
<p class="stat-value">@Model.RejectedCount</p>
|
||
<p class="stat-caption">Erhaltene Rückmeldungen</p>
|
||
</article>
|
||
</section>
|
||
|
||
<section class="visual-grid">
|
||
<article class="chart-card">
|
||
<div class="chart-card-header">
|
||
<h2>Statusübersicht</h2>
|
||
<p>Wie sich deine Bewerbungen aktuell verteilen.</p>
|
||
</div>
|
||
@if (Model.TotalApplications == 0)
|
||
{
|
||
<p class="chart-empty">Sobald du Bewerbungen erfasst, erscheint hier eine Visualisierung.</p>
|
||
}
|
||
else
|
||
{
|
||
var statusChartConfig = JsonSerializer.Serialize(new
|
||
{
|
||
type = "doughnut",
|
||
labels = new[] { "Beworben", "Interview", "Angebot", "Abgelehnt" },
|
||
values = new[] { Model.AppliedCount, Model.InterviewCount, Model.OfferCount, Model.RejectedCount },
|
||
colors = new[] { "#4460f7", "#3ac0a0", "#ff9f43", "#ef476f" },
|
||
borderColor = "#ffffff",
|
||
datasetLabel = "Bewerbungen",
|
||
legend = true
|
||
}, chartSerializerOptions);
|
||
|
||
<div class="chart-wrapper">
|
||
<canvas id="dashboard-status-chart" data-chart='@Html.Raw(statusChartConfig)'></canvas>
|
||
</div>
|
||
}
|
||
</article>
|
||
|
||
<article class="chart-card">
|
||
<div class="chart-card-header">
|
||
<h2>Monatlicher Verlauf</h2>
|
||
<p>Wie viele Bewerbungen du in den letzten Monaten versendet hast.</p>
|
||
</div>
|
||
@if (!monthlyStats.Any(stat => stat.Count > 0))
|
||
{
|
||
<p class="chart-empty">Sobald Bewerbungen vorhanden sind, zeigen wir hier deinen Verlauf.</p>
|
||
}
|
||
else
|
||
{
|
||
var monthlyLabels = monthlyStats.Select(stat => stat.Label).ToArray();
|
||
var monthlyValues = monthlyStats.Select(stat => stat.Count).ToArray();
|
||
var monthlyChartConfig = JsonSerializer.Serialize(new
|
||
{
|
||
type = "line",
|
||
labels = monthlyLabels,
|
||
values = monthlyValues,
|
||
colors = new[] { "rgba(68, 96, 247, 0.20)" },
|
||
borderColor = "#4460f7",
|
||
datasetLabel = "Bewerbungen",
|
||
tension = 0.35,
|
||
fill = true,
|
||
legend = false
|
||
}, chartSerializerOptions);
|
||
|
||
<div class="chart-wrapper">
|
||
<canvas id="dashboard-monthly-chart" data-chart='@Html.Raw(monthlyChartConfig)'></canvas>
|
||
</div>
|
||
}
|
||
</article>
|
||
</section>
|
||
|
||
<section class="recent-applications">
|
||
<div class="section-header">
|
||
<h2>Aktuelle Bewerbungen</h2>
|
||
<a class="link" asp-controller="Applications" asp-action="Index">Zur Bewerbungsübersicht</a>
|
||
</div>
|
||
|
||
@if (!recentApplications.Any())
|
||
{
|
||
<div class="empty-state">
|
||
<p>Noch keine Bewerbungen erfasst.</p>
|
||
<a class="btn btn-primary" asp-controller="Applications" asp-action="Create">Jetzt starten</a>
|
||
</div>
|
||
}
|
||
else
|
||
{
|
||
<div class="table-responsive">
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Unternehmen</th>
|
||
<th>Rolle</th>
|
||
<th>Status</th>
|
||
<th>Beworben am</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@foreach (var application in recentApplications)
|
||
{
|
||
<tr>
|
||
<td>@application.Company</td>
|
||
<td>@application.Role</td>
|
||
<td>
|
||
<span class="status-badge status-@application.Status.ToString().ToLowerInvariant()">
|
||
@application.Status.GetDisplayName()
|
||
</span>
|
||
</td>
|
||
<td>@application.AppliedOn.ToString("dd.MM.yyyy")</td>
|
||
<td class="table-actions">
|
||
<a class="link" asp-controller="Applications" asp-action="Details" asp-route-id="@application.Id">Details</a>
|
||
</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
}
|
||
</section>
|
||
}
|