Admin Bereich implementiert & Vorbereitung auf API
This commit is contained in:
parent
195e0a7b45
commit
efda608c4f
51
FilterCair.Client/Layout/AdminLayout.razor
Normal file
51
FilterCair.Client/Layout/AdminLayout.razor
Normal file
@ -0,0 +1,51 @@
|
||||
@inherits LayoutComponentBase
|
||||
@inject NavigationManager Nav
|
||||
|
||||
<div class="d-flex flex-column min-vh-100 bg-light">
|
||||
|
||||
<!-- 🔹 Admin Navbar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color:#003d66;">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand fw-semibold" href="/admin">
|
||||
<i class="bi bi-gear-fill me-2"></i> Adminbereich
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#adminNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="adminNav">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<NavLink class="nav-link text-white" href="/admin/customers" Match="NavLinkMatch.All">
|
||||
<i class="bi bi-buildings me-1"></i> Kunden
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<NavLink class="nav-link text-white" href="/admin/filters">
|
||||
<i class="bi bi-funnel me-1"></i> Filter
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<NavLink class="nav-link text-white" href="/admin/tasks">
|
||||
<i class="bi bi-list-check me-1"></i> Aufgaben
|
||||
</NavLink>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button class="btn btn-outline-light btn-sm" @onclick="@(() => Nav.NavigateTo("/"))">
|
||||
<i class="bi bi-arrow-left me-1"></i> Zurück
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 🔹 Body -->
|
||||
<main class="flex-fill container py-4">
|
||||
@Body
|
||||
</main>
|
||||
|
||||
<footer class="text-center text-secondary small py-2 mt-auto border-top">
|
||||
@DateTime.Now.Year FilterCair • Adminbereich
|
||||
</footer>
|
||||
</div>
|
||||
@ -1,6 +1,7 @@
|
||||
@inherits LayoutComponentBase
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
||||
@inject FilterCair.Client.Services.AppState State
|
||||
|
||||
<div class="d-flex flex-column min-vh-100">
|
||||
|
||||
@ -32,6 +33,11 @@
|
||||
<i class="bi bi-funnel me-1"></i> Filter-Form
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<NavLink class="nav-link text-white" href="/tasks">
|
||||
<i class="bi bi-list-check me-1"></i> Tasklist
|
||||
</NavLink>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- 🔐 Login/Logout Bereich -->
|
||||
@ -65,6 +71,27 @@
|
||||
|
||||
<!-- 🔹 FOOTER -->
|
||||
<footer class="footer text-center small text-secondary py-2 mt-auto border-top">
|
||||
© @DateTime.Now.Year FilterCair – FPM Service GmbH
|
||||
@if (!string.IsNullOrEmpty(State.SelectedCustomer))
|
||||
{
|
||||
<div class="text-muted small mb-1">
|
||||
<i class="bi bi-geo-alt me-1 text-primary"></i>
|
||||
Aktiver Kunde: <strong>@State.SelectedCustomer</strong>
|
||||
</div>
|
||||
}
|
||||
@DateTime.Now.Year FilterCair - FPM Service GmbH
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
@code{
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await State.LoadFromSessionAsync();
|
||||
State.OnChange += StateHasChanged;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
State.OnChange -= StateHasChanged;
|
||||
}
|
||||
}
|
||||
34
FilterCair.Client/Pages/Admin/AdminHome.razor
Normal file
34
FilterCair.Client/Pages/Admin/AdminHome.razor
Normal file
@ -0,0 +1,34 @@
|
||||
@page "/admin"
|
||||
@layout AdminLayout
|
||||
|
||||
<PageTitle>Adminbereich</PageTitle>
|
||||
|
||||
<div class="container py-4 text-center fade-in">
|
||||
<h4 class="mb-4 text-primary">
|
||||
<i class="bi bi-shield-lock me-2"></i> Willkommen im Adminbereich
|
||||
</h4>
|
||||
|
||||
<div class="row g-4 justify-content-center">
|
||||
<div class="col-12 col-md-4">
|
||||
<div class="card shadow-sm border-0 admin-tile" @onclick="@(() => Nav.NavigateTo("/admin/customers"))">
|
||||
<div class="card-body text-center">
|
||||
<i class="bi bi-buildings display-6 text-primary mb-3"></i>
|
||||
<h5 class="fw-semibold">Kunden verwalten</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-4">
|
||||
<div class="card shadow-sm border-0 admin-tile" @onclick="@(() => Nav.NavigateTo("/admin/filters"))">
|
||||
<div class="card-body text-center">
|
||||
<i class="bi bi-funnel display-6 text-primary mb-3"></i>
|
||||
<h5 class="fw-semibold">Filter verwalten</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Inject] NavigationManager Nav { get; set; } = default!;
|
||||
}
|
||||
152
FilterCair.Client/Pages/Admin/Customers.razor
Normal file
152
FilterCair.Client/Pages/Admin/Customers.razor
Normal file
@ -0,0 +1,152 @@
|
||||
@page "/admin/customers"
|
||||
@layout AdminLayout
|
||||
@using FilterCair.Shared.Models
|
||||
|
||||
<PageTitle>Kunden verwalten</PageTitle>
|
||||
|
||||
<div class="container py-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 flex-wrap gap-3">
|
||||
<h4 class="text-primary mb-0">
|
||||
<i class="bi bi-buildings me-2"></i> Kundenverwaltung
|
||||
</h4>
|
||||
<button class="btn btn-success rounded-pill" @onclick="ShowCreateModal">
|
||||
<i class="bi bi-plus-lg me-1"></i> Neuer Kunde
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Kundenliste -->
|
||||
@if (customers.Count == 0)
|
||||
{
|
||||
<div class="alert alert-info text-center">
|
||||
Keine Kunden vorhanden. Lege den ersten Kunden an!
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped align-middle shadow-sm">
|
||||
<thead class="table-primary">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Standort</th>
|
||||
<th>Ansprechpartner</th>
|
||||
<th>Telefon</th>
|
||||
<th>Email</th>
|
||||
<th style="width:120px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var c in customers)
|
||||
{
|
||||
<tr>
|
||||
<td>@c.Name</td>
|
||||
<td>@c.Standort</td>
|
||||
<td>@c.Ansprechpartner</td>
|
||||
<td>@c.Telefon</td>
|
||||
<td>@c.Email</td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-outline-danger btn-sm rounded-pill" @onclick="() => DeleteCustomer(c)">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Modal -->
|
||||
@if (showModal)
|
||||
{
|
||||
<div class="modal fade show d-block" tabindex="-1" style="background-color:rgba(0,0,0,0.5);">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content border-0 shadow-lg rounded-4">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title"><i class="bi bi-person-plus me-2"></i> Neuer Kunde</h5>
|
||||
<button type="button" class="btn-close btn-close-white" @onclick="CloseModal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<EditForm Model="@newCustomer" OnValidSubmit="SaveCustomer">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Name</label>
|
||||
<InputText class="form-control" @bind-Value="newCustomer.Name" required />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Standort</label>
|
||||
<InputText class="form-control" @bind-Value="newCustomer.Standort" required />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Ansprechpartner</label>
|
||||
<InputText class="form-control" @bind-Value="newCustomer.Ansprechpartner" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Telefon</label>
|
||||
<InputText class="form-control" @bind-Value="newCustomer.Telefon" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Email</label>
|
||||
<InputText class="form-control" @bind-Value="newCustomer.Email" />
|
||||
</div>
|
||||
|
||||
<div class="text-end">
|
||||
<button type="button" class="btn btn-outline-secondary me-2 rounded-pill" @onclick="CloseModal">
|
||||
Abbrechen
|
||||
</button>
|
||||
<button type="submit" class="btn btn-success rounded-pill">
|
||||
Speichern
|
||||
</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private List<CustomerModel> customers = new();
|
||||
private CustomerModel newCustomer = new();
|
||||
private bool showModal = false;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
// TODO: später über API laden
|
||||
customers = new()
|
||||
{
|
||||
new() { Id = 1, Name = "Freudenberg Weinheim", Standort = "Weinheim", Ansprechpartner = "Marc Wieland", Telefon = "+49 6201 80 1234", Email = "marc.wieland@freudenberg-pm.com" },
|
||||
new() { Id = 2, Name = "CleanAir Solutions", Standort = "Mannheim", Ansprechpartner = "Tom Fischer", Telefon = "+49 621 555 123" , Email = "FischersTom@cleanair.de"}
|
||||
};
|
||||
}
|
||||
|
||||
private void ShowCreateModal()
|
||||
{
|
||||
newCustomer = new CustomerModel();
|
||||
showModal = true;
|
||||
}
|
||||
|
||||
private void CloseModal()
|
||||
{
|
||||
showModal = false;
|
||||
}
|
||||
|
||||
private void SaveCustomer()
|
||||
{
|
||||
newCustomer.Id = customers.Count + 1;
|
||||
customers.Add(newCustomer);
|
||||
showModal = false;
|
||||
}
|
||||
|
||||
private void DeleteCustomer(CustomerModel customer)
|
||||
{
|
||||
customers.Remove(customer);
|
||||
}
|
||||
}
|
||||
84
FilterCair.Client/Pages/CustomerList.razor
Normal file
84
FilterCair.Client/Pages/CustomerList.razor
Normal file
@ -0,0 +1,84 @@
|
||||
@page "/customers"
|
||||
@using FilterCair.Shared.Models
|
||||
@inject IJSRuntime JS
|
||||
@inject NavigationManager Nav
|
||||
@inject FilterCair.Client.Services.AppState State
|
||||
|
||||
<h3>Kundenübersicht</h3>
|
||||
|
||||
|
||||
|
||||
<div class="container py-4 fade-in">
|
||||
<h4 class="mb-4 text-center text-primary">
|
||||
<i class="bi bi-buildings me-2"></i> Kunden & Fabriken
|
||||
</h4>
|
||||
|
||||
<!-- 🔍 Suchfeld -->
|
||||
<div class="mb-4 text-center">
|
||||
<input type="text" class="form-control w-50 mx-auto shadow-sm"
|
||||
placeholder="🔍 Kunde oder Standort suchen..."
|
||||
@bind="searchText"
|
||||
@bind:event="oninput" />
|
||||
</div>
|
||||
|
||||
<!-- 🏭 Kundenliste -->
|
||||
<div class="row g-4 justify-content-center">
|
||||
@foreach (var c in FilteredCustomers)
|
||||
{
|
||||
<div class="col-12 col-sm-6 col-lg-4">
|
||||
<div class="card customer-card border-0 shadow-sm h-100"
|
||||
@onclick="@(() => SelectCustomer(c))">
|
||||
<div class="card-body">
|
||||
<h5 class="fw-semibold mb-2 text-primary">
|
||||
<i class="bi bi-building me-1"></i> @c.Name
|
||||
</h5>
|
||||
<p class="text-muted mb-1">
|
||||
<i class="bi bi-geo-alt me-1"></i> @c.Standort
|
||||
</p>
|
||||
<p class="text-muted small mb-0">
|
||||
<i class="bi bi-person me-1"></i> @c.Ansprechpartner
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (FilteredCustomers.Count() == 0)
|
||||
{
|
||||
<div class="text-center text-muted mt-5">
|
||||
<i class="bi bi-search display-5 d-block mb-2"></i>
|
||||
Keine passenden Kunden gefunden.
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private List<CustomerModel> customers = new();
|
||||
private string searchText = "";
|
||||
|
||||
private IEnumerable<CustomerModel> FilteredCustomers =>
|
||||
string.IsNullOrWhiteSpace(searchText)
|
||||
? customers
|
||||
: customers.Where(c =>
|
||||
c.Name.Contains(searchText, StringComparison.OrdinalIgnoreCase) ||
|
||||
c.Standort.Contains(searchText, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
// später aus API laden
|
||||
customers = new()
|
||||
{
|
||||
new() { Id = 1, Name = "Freudenberg Weinheim", Standort = "Weinheim", Ansprechpartner = "Marc Wieland", Telefon = "+49 6201 80 1234" },
|
||||
new() { Id = 2, Name = "FilterTech GmbH", Standort = "Kaiserslautern", Ansprechpartner = "Lena Becker", Telefon = "+49 631 987654" },
|
||||
new() { Id = 3, Name = "CleanAir Solutions", Standort = "Mannheim", Ansprechpartner = "Tom Fischer", Telefon = "+49 621 555 123" }
|
||||
};
|
||||
}
|
||||
|
||||
private async Task SelectCustomer(CustomerModel c)
|
||||
{
|
||||
await State.SetCustomerAsync(c.Name);
|
||||
Nav.NavigateTo("/qrscanner");
|
||||
}
|
||||
|
||||
}
|
||||
@ -48,6 +48,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-6 col-lg-4">
|
||||
<div class="card dashboard-tile h-100" @onclick="@(() => Nav.NavigateTo("/tasks"))">
|
||||
<div class="card-body d-flex flex-column justify-content-center align-items-center text-center">
|
||||
<i class="bi bi-list-check display-5 mb-3 text-primary"></i>
|
||||
<h5 class="fw-semibold mb-2">Meine Aufgaben</h5>
|
||||
<p class="text-muted small mb-0">Übersicht aller offenen Wartungen und Filterprüfungen.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-6 col-lg-4">
|
||||
<div class="card dashboard-tile h-100" @onclick="@(() => Nav.NavigateTo("/customers"))">
|
||||
<div class="card-body d-flex flex-column justify-content-center align-items-center text-center">
|
||||
<i class="bi bi-buildings display-5 mb-3 text-primary"></i>
|
||||
<h5 class="fw-semibold mb-2">Kundenübersicht</h5>
|
||||
<p class="text-muted small mb-0">Wähle den Kundenstandort aus, um Filterdaten zu erfassen.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 📍 Standortanzeige -->
|
||||
|
||||
81
FilterCair.Client/Pages/Tasks.razor
Normal file
81
FilterCair.Client/Pages/Tasks.razor
Normal file
@ -0,0 +1,81 @@
|
||||
@page "/tasks"
|
||||
@using FilterCair.Shared.Models
|
||||
|
||||
|
||||
<div class="container py-4 fade-in">
|
||||
<h4 class="mb-4 text-primary text-center">
|
||||
<i class="bi bi-list-check me-2"></i> Meine Aufgaben
|
||||
</h4>
|
||||
|
||||
<div class="row g-3">
|
||||
@if (tasks.Count == 0)
|
||||
{
|
||||
<div class="text-center text-muted py-5">
|
||||
<i class="bi bi-emoji-neutral display-4 d-block mb-3"></i>
|
||||
Keine Aufgaben vorhanden.
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var t in tasks)
|
||||
{
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="card task-card shadow-sm border-0 rounded-4">
|
||||
<div class="card-body">
|
||||
<h5 class="fw-semibold">@t.Title</h5>
|
||||
<p class="text-muted small mb-2">@t.Beschreibung</p>
|
||||
|
||||
<span class="badge bg-@(GetStatusColor(t.Status)) me-2">@t.Status</span>
|
||||
<span class="badge bg-secondary">@t.Prio</span>
|
||||
|
||||
@if (t.FaelligBis.HasValue)
|
||||
{
|
||||
<div class="text-muted small mt-2">
|
||||
<i class="bi bi-calendar-event me-1"></i>
|
||||
Fällig: @t.FaelligBis.Value.ToShortDateString()
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<button class="btn btn-sm btn-outline-primary" @onclick="() => ToggleStatus(t)">
|
||||
<i class="bi bi-check2-circle me-1"></i> Status ändern
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private List<TaskModel> tasks = new();
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
tasks = new()
|
||||
{
|
||||
new() { Id = 1, Title = "Filter prüfen Halle A", Beschreibung = "Sichtprüfung durchführen", ZugewiesenAn = "Marc Wieland", Status = "Offen", Prio = "Normal", FaelligBis = DateTime.Today.AddDays(1) },
|
||||
new() { Id = 2, Title = "Wartung Filter B2", Beschreibung = "Druck prüfen & Dokumentation", ZugewiesenAn = "Marc Wieland", Status = "In Arbeit", Prio = "Hoch" },
|
||||
new() { Id = 3, Title = "Filter austauschen", Beschreibung = "Alten Filter entfernen & neuen einsetzen", ZugewiesenAn = "Marc Wieland", Status = "Erledigt", Prio = "Normal", FaelligBis = DateTime.Today.AddDays(-2) }
|
||||
};
|
||||
}
|
||||
|
||||
private void ToggleStatus(TaskModel t)
|
||||
{
|
||||
t.Status = t.Status switch
|
||||
{
|
||||
"Offen" => "In Arbeit",
|
||||
"In Arbeit" => "Erledigt",
|
||||
_ => "Offen"
|
||||
};
|
||||
}
|
||||
|
||||
private string GetStatusColor(string status) => status switch
|
||||
{
|
||||
"Erledigt" => "success",
|
||||
"In Arbeit" => "warning",
|
||||
_ => "secondary"
|
||||
};
|
||||
}
|
||||
@ -2,6 +2,7 @@ using FilterCair.Client;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
|
||||
using FilterCair.Client.Services;
|
||||
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
builder.RootComponents.Add<App>("#app");
|
||||
@ -21,4 +22,7 @@ builder.Services.AddMsalAuthentication(options =>
|
||||
"api://54b010c7-4a9a-4f2d-bea3-9faba3f12495/API.Access");
|
||||
});
|
||||
|
||||
//Services
|
||||
builder.Services.AddScoped<AppState>();
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
|
||||
51
FilterCair.Client/Services/AppState.cs
Normal file
51
FilterCair.Client/Services/AppState.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace FilterCair.Client.Services
|
||||
{
|
||||
public class AppState
|
||||
{
|
||||
private readonly IJSRuntime _js;
|
||||
public AppState(IJSRuntime js)
|
||||
{
|
||||
_js = js;
|
||||
}
|
||||
|
||||
public string? SelectedCustomer { get; private set; }
|
||||
|
||||
public bool IsOnline { get; private set; } = true;
|
||||
public event Action? OnChange;
|
||||
|
||||
private void NotifyStateChanged() => OnChange?.Invoke();
|
||||
|
||||
public async Task SetCustomerAsync(string customer)
|
||||
{
|
||||
SelectedCustomer = customer;
|
||||
await _js.InvokeVoidAsync("sessionStorage.setItem", "selectedCustomer", customer);
|
||||
NotifyStateChanged();
|
||||
}
|
||||
|
||||
public async Task LoadFromSessionAsync()
|
||||
{
|
||||
SelectedCustomer = await _js.InvokeAsync<string?>("sessionStorage.getItem", "selectedCustomer");
|
||||
NotifyStateChanged();
|
||||
}
|
||||
|
||||
public void SetOnlineStatus(bool isOnline)
|
||||
{
|
||||
IsOnline = isOnline;
|
||||
NotifyStateChanged();
|
||||
}
|
||||
|
||||
public async Task ClearAsync()
|
||||
{
|
||||
SelectedCustomer = null;
|
||||
await _js.InvokeVoidAsync("sessionStorage.removeItem", "selectedCustomer");
|
||||
NotifyStateChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -220,6 +220,57 @@ code {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.image-preview img:hover {
|
||||
transform: scale(1.05);
|
||||
.image-preview img:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
|
||||
.task-card {
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.task-card:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 16px rgba(0, 91, 153, 0.15);
|
||||
}
|
||||
|
||||
|
||||
.customer-card {
|
||||
border-radius: 1rem;
|
||||
transition: all 0.25s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.customer-card:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 18px rgba(0, 91, 153, 0.15);
|
||||
}
|
||||
|
||||
.customer-card:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
|
||||
.admin-tile {
|
||||
border-radius: 1rem;
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.admin-tile:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 20px rgba(0, 91, 153, 0.15);
|
||||
}
|
||||
|
||||
|
||||
.modal-dialog {
|
||||
max-width: 500px;
|
||||
margin: 1rem auto;
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.modal-dialog {
|
||||
max-width: 90%;
|
||||
margin: 0.5rem auto;
|
||||
}
|
||||
}
|
||||
|
||||
18
FilterCair.Shared/Models/CustomerModel.cs
Normal file
18
FilterCair.Shared/Models/CustomerModel.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FilterCair.Shared.Models
|
||||
{
|
||||
public class CustomerModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Standort { get; set; } = string.Empty;
|
||||
public string Ansprechpartner { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public string Telefon { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
21
FilterCair.Shared/Models/TaskModel.cs
Normal file
21
FilterCair.Shared/Models/TaskModel.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FilterCair.Shared.Models
|
||||
{
|
||||
public class TaskModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Beschreibung { get; set; } = string.Empty;
|
||||
public string ZugewiesenAn { get; set; } = string.Empty;
|
||||
public string Status { get; set; } = "Offen";
|
||||
public string Prio { get; set; } = "Mittel";
|
||||
public DateTime? FaelligBis { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user