Erweiterungen
This commit is contained in:
@@ -21,7 +21,7 @@ import java.time.Clock;
|
||||
|
||||
@Route(value = "add_company", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
|
||||
@PageTitle("Neuen Firma anlegen")
|
||||
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Neue Firma anlegen")
|
||||
//@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Neue Firma anlegen")
|
||||
@RolesAllowed("USER")
|
||||
public class AddCompanyView extends Main {
|
||||
private final AddCompanyService addCompanyService;
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.time.Clock;
|
||||
|
||||
@Route(value = "add_customer", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
|
||||
@PageTitle("Neuen Kunden anlegen")
|
||||
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Neuen Kunden anlegen")
|
||||
//@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Neuen Kunden anlegen")
|
||||
@RolesAllowed("USER")
|
||||
public class AddCustomerView extends Main {
|
||||
private final AddCustomerService addCustomerService;
|
||||
|
||||
@@ -42,7 +42,7 @@ import java.util.Optional;
|
||||
|
||||
@Route(value = "add_job", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
|
||||
@PageTitle("Neuen Auftrag anlegen")
|
||||
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Neuen Auftrag anlegen")
|
||||
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Auftragserstellung")
|
||||
@RolesAllowed("USER")
|
||||
@Slf4j
|
||||
public class AddJobView extends Main {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.vaadin.flow.component.Component;
|
||||
import com.vaadin.flow.component.applayout.AppLayout;
|
||||
import com.vaadin.flow.component.avatar.Avatar;
|
||||
import com.vaadin.flow.component.avatar.AvatarVariant;
|
||||
import com.vaadin.flow.component.details.Details;
|
||||
import com.vaadin.flow.component.html.Div;
|
||||
import com.vaadin.flow.component.html.Span;
|
||||
import com.vaadin.flow.component.icon.Icon;
|
||||
@@ -11,6 +12,7 @@ import com.vaadin.flow.component.icon.VaadinIcon;
|
||||
import com.vaadin.flow.component.menubar.MenuBar;
|
||||
import com.vaadin.flow.component.menubar.MenuBarVariant;
|
||||
import com.vaadin.flow.component.orderedlayout.Scroller;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.component.sidenav.SideNav;
|
||||
import com.vaadin.flow.component.sidenav.SideNavItem;
|
||||
import com.vaadin.flow.router.Layout;
|
||||
@@ -20,6 +22,7 @@ import de.assecutor.votianlt.security.SecurityService;
|
||||
|
||||
import static com.vaadin.flow.theme.lumo.LumoUtility.*;
|
||||
|
||||
@Layout
|
||||
public final class MainLayout extends AppLayout {
|
||||
|
||||
private final SecurityService securityService;
|
||||
@@ -45,11 +48,64 @@ public final class MainLayout extends AppLayout {
|
||||
return header;
|
||||
}
|
||||
|
||||
private SideNav createSideNav() {
|
||||
private Component createSideNav() {
|
||||
var nav = new SideNav();
|
||||
nav.addClassNames(Margin.Horizontal.MEDIUM);
|
||||
MenuConfiguration.getMenuEntries().forEach(entry -> nav.addItem(createSideNavItem(entry)));
|
||||
return nav;
|
||||
|
||||
MenuConfiguration.getMenuEntries().forEach(entry -> {
|
||||
// Skip "Verwaltung" entry as we'll handle it separately with Details component
|
||||
if (!"Verwaltung".equals(entry.title())) {
|
||||
SideNavItem item = createSideNavItem(entry);
|
||||
nav.addItem(item);
|
||||
}
|
||||
});
|
||||
|
||||
// Create Details component for "Verwaltung" with collapsible list
|
||||
Details verwaltungDetails = new Details();
|
||||
verwaltungDetails.setSummaryText("Verwaltung");
|
||||
verwaltungDetails.addClassNames(Margin.Horizontal.MEDIUM, FontSize.MEDIUM, FontWeight.MEDIUM, "#000000");
|
||||
|
||||
// Create collapsible content with navigation items
|
||||
VerticalLayout verwaltungContent = new VerticalLayout();
|
||||
verwaltungContent.setPadding(false);
|
||||
verwaltungContent.setSpacing(true);
|
||||
|
||||
// Create navigation items for the collapsible list
|
||||
SideNavItem jobs = new SideNavItem("Aufträge", "1", new Icon(VaadinIcon.COG));
|
||||
SideNavItem customers = new SideNavItem("Kunden", "2", new Icon(VaadinIcon.COG));
|
||||
SideNavItem appUsers = new SideNavItem("App-Nutzer", "3", new Icon(VaadinIcon.COG));
|
||||
SideNavItem devices = new SideNavItem("Endgeräte", "4", new Icon(VaadinIcon.COG));
|
||||
SideNavItem invoices = new SideNavItem("Rechnungen", "5", new Icon(VaadinIcon.COG));
|
||||
SideNavItem statistics = new SideNavItem("Statistik", "6", new Icon(VaadinIcon.COG));
|
||||
|
||||
verwaltungContent.add(jobs, customers, appUsers, devices, invoices, statistics);
|
||||
verwaltungDetails.setContent(verwaltungContent);
|
||||
|
||||
// Create Details component for "Verwaltung" with collapsible list
|
||||
Details userDetails = new Details();
|
||||
userDetails.setSummaryText("Benutzer");
|
||||
userDetails.addClassNames(Margin.Horizontal.MEDIUM, FontSize.MEDIUM, FontWeight.MEDIUM, TextColor.BODY);
|
||||
|
||||
// Create collapsible content with navigation items
|
||||
VerticalLayout userContent = new VerticalLayout();
|
||||
userContent.setPadding(false);
|
||||
userContent.setSpacing(true);
|
||||
|
||||
// Create navigation items for the collapsible list
|
||||
SideNavItem profile = new SideNavItem("Mein Profil", "7", new Icon(VaadinIcon.COG));
|
||||
SideNavItem myInvoices = new SideNavItem("Meine Rechnungen", "8", new Icon(VaadinIcon.COG));
|
||||
SideNavItem imprint = new SideNavItem("Impressum", "9", new Icon(VaadinIcon.COG));
|
||||
|
||||
userContent.add(profile, myInvoices, imprint);
|
||||
userDetails.setContent(userContent);
|
||||
|
||||
// Create a vertical layout to hold both regular menu items and collapsible sections
|
||||
VerticalLayout navContainer = new VerticalLayout();
|
||||
navContainer.setPadding(false);
|
||||
navContainer.setSpacing(false);
|
||||
navContainer.add(nav, verwaltungDetails, userDetails);
|
||||
|
||||
return navContainer;
|
||||
}
|
||||
|
||||
private SideNavItem createSideNavItem(MenuEntry menuEntry) {
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
package de.assecutor.votianlt.pages.start.ui.view;
|
||||
|
||||
import com.vaadin.flow.component.Component;
|
||||
import com.vaadin.flow.component.html.*;
|
||||
import com.vaadin.flow.component.icon.Icon;
|
||||
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.router.PageTitle;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import de.assecutor.votianlt.security.SecurityService;
|
||||
import de.assecutor.votianlt.pages.base.ui.view.MainLayout;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
@Route(value = "dashboard", layout = MainLayout.class)
|
||||
@PageTitle("VotianLT - Dashboard")
|
||||
@RolesAllowed("USER")
|
||||
public class AuthenticatedStartView extends VerticalLayout {
|
||||
|
||||
private final SecurityService securityService;
|
||||
|
||||
public AuthenticatedStartView(SecurityService securityService) {
|
||||
this.securityService = securityService;
|
||||
setSizeFull();
|
||||
setPadding(false);
|
||||
setSpacing(false);
|
||||
setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);
|
||||
|
||||
// Hero Section for authenticated users
|
||||
add(createAuthenticatedHeroSection());
|
||||
|
||||
// System Section
|
||||
add(createSystemSection());
|
||||
|
||||
// App Section
|
||||
add(createAppSection());
|
||||
|
||||
// Footer
|
||||
add(createFooter());
|
||||
}
|
||||
|
||||
private Component createAuthenticatedHeroSection() {
|
||||
VerticalLayout heroSection = new VerticalLayout();
|
||||
heroSection.setWidthFull();
|
||||
heroSection.setPadding(true);
|
||||
heroSection.setSpacing(true);
|
||||
heroSection.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||
heroSection.getStyle().set("background", "linear-gradient(135deg, var(--lumo-primary-color-10pct), var(--lumo-primary-color-50pct))");
|
||||
heroSection.getStyle().set("min-height", "300px");
|
||||
heroSection.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
|
||||
|
||||
// Welcome message for authenticated user
|
||||
String currentUser = securityService.getCurrentUsername();
|
||||
H1 welcomeTitle = new H1("Willkommen zurück, " + currentUser + "!");
|
||||
welcomeTitle.getStyle().set("text-align", "center");
|
||||
welcomeTitle.getStyle().set("color", "var(--lumo-primary-text-color)");
|
||||
welcomeTitle.getStyle().set("margin-bottom", "var(--lumo-space-l)");
|
||||
|
||||
Paragraph welcomeDescription = new Paragraph(
|
||||
"Nutzen Sie die Navigation links, um neue Aufträge zu erstellen oder Ihre Verwaltung zu bearbeiten."
|
||||
);
|
||||
welcomeDescription.getStyle().set("text-align", "center");
|
||||
welcomeDescription.getStyle().set("max-width", "600px");
|
||||
welcomeDescription.getStyle().set("font-size", "var(--lumo-font-size-l)");
|
||||
|
||||
heroSection.add(welcomeTitle, welcomeDescription);
|
||||
return heroSection;
|
||||
}
|
||||
|
||||
private Component createSystemSection() {
|
||||
VerticalLayout systemSection = new VerticalLayout();
|
||||
systemSection.setWidthFull();
|
||||
systemSection.setPadding(true);
|
||||
systemSection.setSpacing(true);
|
||||
systemSection.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||
systemSection.getStyle().set("background-color", "var(--lumo-base-color)");
|
||||
|
||||
// Section Header
|
||||
H2 systemTitle = new H2("Das System");
|
||||
systemTitle.getStyle().set("color", "var(--lumo-primary-color)");
|
||||
systemTitle.getStyle().set("text-align", "center");
|
||||
|
||||
Paragraph systemIntro = new Paragraph(
|
||||
"Für Solo-Selbstständige und Kleinunternehmer im Transportgewerbe ist von entscheidender Bedeutung, " +
|
||||
"dass sie sich in erster Linie auf ihr eigentliches Geschäft konzentrieren können: Kunden gewinnen und Waren von A nach B liefern."
|
||||
);
|
||||
systemIntro.getStyle().set("text-align", "center");
|
||||
systemIntro.getStyle().set("max-width", "800px");
|
||||
systemIntro.getStyle().set("margin-bottom", "var(--lumo-space-xl)");
|
||||
|
||||
// Features Grid
|
||||
HorizontalLayout featuresGrid = new HorizontalLayout();
|
||||
featuresGrid.setWidthFull();
|
||||
featuresGrid.setSpacing(true);
|
||||
featuresGrid.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.START);
|
||||
|
||||
// Feature Cards
|
||||
featuresGrid.add(
|
||||
createFeatureCard(VaadinIcon.COG, "Einrichtungsassistent",
|
||||
"Mithilfe des Einrichtungsassistenten haben Sie die Möglichkeit, Ihr Nutzerprofil zu vervollständigen."),
|
||||
createFeatureCard(VaadinIcon.USERS, "Kunden- und Auftragsverwaltung",
|
||||
"Mit der Kunden- und Auftragsverwaltung haben Sie alle Kontaktdaten und Auftragsdetails stets im Blick."),
|
||||
createFeatureCard(VaadinIcon.CLIPBOARD_TEXT, "Auftragserstellung",
|
||||
"Stellen Sie mit wenigen Mausklicks Aufträge ins System ein und legen Sie fest, welcher Mitarbeiter welchen Transportauftrag abarbeiten soll.")
|
||||
);
|
||||
|
||||
systemSection.add(systemTitle, systemIntro, featuresGrid);
|
||||
return systemSection;
|
||||
}
|
||||
|
||||
private Component createFeatureCard(VaadinIcon iconType, String title, String description) {
|
||||
VerticalLayout card = new VerticalLayout();
|
||||
card.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||
card.setPadding(true);
|
||||
card.setSpacing(true);
|
||||
card.getStyle().set("background-color", "var(--lumo-base-color)");
|
||||
card.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
|
||||
card.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
|
||||
card.getStyle().set("box-shadow", "var(--lumo-box-shadow-s)");
|
||||
card.setWidth("300px");
|
||||
|
||||
Icon icon = iconType.create();
|
||||
icon.setSize("48px");
|
||||
icon.getStyle().set("color", "var(--lumo-primary-color)");
|
||||
icon.getStyle().set("margin-bottom", "var(--lumo-space-m)");
|
||||
|
||||
H3 cardTitle = new H3(title);
|
||||
cardTitle.getStyle().set("text-align", "center");
|
||||
cardTitle.getStyle().set("margin", "0");
|
||||
cardTitle.getStyle().set("color", "var(--lumo-primary-text-color)");
|
||||
|
||||
Paragraph cardDescription = new Paragraph(description);
|
||||
cardDescription.getStyle().set("text-align", "center");
|
||||
cardDescription.getStyle().set("font-size", "var(--lumo-font-size-s)");
|
||||
cardDescription.getStyle().set("color", "var(--lumo-secondary-text-color)");
|
||||
cardDescription.getStyle().set("margin", "0");
|
||||
|
||||
card.add(icon, cardTitle, cardDescription);
|
||||
return card;
|
||||
}
|
||||
|
||||
private Component createAppSection() {
|
||||
VerticalLayout appSection = new VerticalLayout();
|
||||
appSection.setWidthFull();
|
||||
appSection.setPadding(true);
|
||||
appSection.setSpacing(true);
|
||||
appSection.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||
appSection.getStyle().set("background-color", "var(--lumo-contrast-5pct)");
|
||||
|
||||
H2 appTitle = new H2("Die App");
|
||||
appTitle.getStyle().set("color", "var(--lumo-primary-color)");
|
||||
appTitle.getStyle().set("text-align", "center");
|
||||
|
||||
Paragraph appDescription = new Paragraph(
|
||||
"Mit unserer mobilen App bleiben Sie auch unterwegs immer über Ihre Aufträge informiert " +
|
||||
"und können wichtige Aufgaben direkt vom Smartphone aus erledigen."
|
||||
);
|
||||
appDescription.getStyle().set("text-align", "center");
|
||||
appDescription.getStyle().set("max-width", "600px");
|
||||
|
||||
appSection.add(appTitle, appDescription);
|
||||
return appSection;
|
||||
}
|
||||
|
||||
private Component createFooter() {
|
||||
VerticalLayout footer = new VerticalLayout();
|
||||
footer.setWidthFull();
|
||||
footer.setPadding(true);
|
||||
footer.setSpacing(true);
|
||||
footer.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||
footer.getStyle().set("background-color", "var(--lumo-contrast-10pct)");
|
||||
footer.getStyle().set("border-top", "1px solid var(--lumo-contrast-20pct)");
|
||||
|
||||
HorizontalLayout footerContent = new HorizontalLayout();
|
||||
footerContent.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER);
|
||||
footerContent.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
|
||||
|
||||
Paragraph copyright = new Paragraph("© 2024 VotianLT. Alle Rechte vorbehalten.");
|
||||
copyright.getStyle().set("color", "var(--lumo-secondary-text-color)");
|
||||
copyright.getStyle().set("font-size", "var(--lumo-font-size-s)");
|
||||
copyright.getStyle().set("margin", "0");
|
||||
|
||||
footerContent.add(copyright);
|
||||
footer.add(footerContent);
|
||||
|
||||
return footer;
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,16 @@ import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.router.PageTitle;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import com.vaadin.flow.router.RouterLayout;
|
||||
import com.vaadin.flow.router.BeforeEnterEvent;
|
||||
import com.vaadin.flow.router.BeforeEnterObserver;
|
||||
import com.vaadin.flow.server.auth.AnonymousAllowed;
|
||||
import de.assecutor.votianlt.security.SecurityService;
|
||||
import de.assecutor.votianlt.pages.base.ui.view.MainLayout;
|
||||
|
||||
@Route("")
|
||||
@PageTitle("VotianLT - Willkommen")
|
||||
@AnonymousAllowed
|
||||
public class StartView extends VerticalLayout {
|
||||
public class StartView extends VerticalLayout implements BeforeEnterObserver {
|
||||
|
||||
private final SecurityService securityService;
|
||||
|
||||
@@ -47,6 +50,14 @@ public class StartView extends VerticalLayout {
|
||||
add(createFooter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEnter(BeforeEnterEvent event) {
|
||||
// Redirect authenticated users to dashboard
|
||||
if (securityService.isUserLoggedIn()) {
|
||||
event.forwardTo("dashboard");
|
||||
}
|
||||
}
|
||||
|
||||
private Component createHeader() {
|
||||
HorizontalLayout header = new HorizontalLayout();
|
||||
header.setWidthFull();
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package de.assecutor.votianlt.pages.test;
|
||||
|
||||
import com.vaadin.flow.component.html.H1;
|
||||
import com.vaadin.flow.component.html.Paragraph;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.router.PageTitle;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import de.assecutor.votianlt.pages.base.ui.view.MainLayout;
|
||||
|
||||
@Route(value = "test", layout = MainLayout.class)
|
||||
@PageTitle("Test Seite")
|
||||
public class TestView extends VerticalLayout {
|
||||
|
||||
public TestView() {
|
||||
H1 title = new H1("Test Seite");
|
||||
Paragraph description = new Paragraph("Diese Seite dient zum Testen der Navigation.");
|
||||
|
||||
add(title, description);
|
||||
|
||||
setPadding(true);
|
||||
setSpacing(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package de.assecutor.votianlt.pages.verwaltung.ui.view;
|
||||
|
||||
import com.vaadin.flow.component.html.H1;
|
||||
import com.vaadin.flow.component.html.Main;
|
||||
import com.vaadin.flow.component.html.Paragraph;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.router.Menu;
|
||||
import com.vaadin.flow.router.PageTitle;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import com.vaadin.flow.theme.lumo.LumoUtility;
|
||||
import de.assecutor.votianlt.pages.base.ui.component.ViewToolbar;
|
||||
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
@Route(value = "verwaltung", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
|
||||
@PageTitle("Verwaltung")
|
||||
@Menu(order = 5, icon = "vaadin:cogs", title = "Verwaltung")
|
||||
@RolesAllowed("USER")
|
||||
public class VerwaltungView extends Main {
|
||||
|
||||
public VerwaltungView() {
|
||||
setSizeFull();
|
||||
addClassNames(LumoUtility.BoxSizing.BORDER, LumoUtility.Display.FLEX, LumoUtility.FlexDirection.COLUMN,
|
||||
LumoUtility.Padding.MEDIUM, LumoUtility.Gap.SMALL);
|
||||
|
||||
add(new ViewToolbar("Verwaltung"));
|
||||
|
||||
// Content
|
||||
VerticalLayout content = new VerticalLayout();
|
||||
|
||||
H1 title = new H1("Verwaltung");
|
||||
title.getStyle().set("color", "var(--lumo-primary-color)");
|
||||
|
||||
Paragraph description = new Paragraph("Willkommen im Verwaltungsbereich. Wählen Sie eine Option aus dem Menü.");
|
||||
description.getStyle().set("color", "var(--lumo-secondary-text-color)");
|
||||
|
||||
content.add(title, description);
|
||||
content.setDefaultHorizontalComponentAlignment(VerticalLayout.Alignment.CENTER);
|
||||
content.setJustifyContentMode(VerticalLayout.JustifyContentMode.CENTER);
|
||||
content.setSizeFull();
|
||||
|
||||
add(content);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user