From 06595006cb6d202462efd1bff3fb59340274ee39 Mon Sep 17 00:00:00 2001 From: Sven Carstensen Date: Thu, 14 Aug 2025 19:56:57 +0200 Subject: [PATCH] Erweiterungen --- .../de/assecutor/votianlt/model/AppUser.java | 56 ++++++ .../pages/base/ui/view/MainLayout.java | 2 +- .../pages/domain/AddCompanyRepository.java | 5 +- .../pages/domain/AddCustomerRepository.java | 5 +- .../pages/domain/LoginRepository.java | 5 +- .../pages/service/AddCompanyService.java | 7 +- .../pages/service/AddCustomerService.java | 8 +- .../votianlt/pages/service/AddJobService.java | 56 ------ .../pages/service/AppUserService.java | 40 +++++ .../pages/service/CustomerService.java | 20 +-- .../votianlt/pages/view/AddJobView.java | 140 --------------- .../votianlt/pages/view/AppUserView.java | 168 ++++++++++++++++++ .../repository/AppUserRepository.java | 15 ++ 13 files changed, 289 insertions(+), 238 deletions(-) create mode 100644 src/main/java/de/assecutor/votianlt/model/AppUser.java create mode 100644 src/main/java/de/assecutor/votianlt/pages/service/AppUserService.java create mode 100644 src/main/java/de/assecutor/votianlt/pages/view/AppUserView.java create mode 100644 src/main/java/de/assecutor/votianlt/repository/AppUserRepository.java diff --git a/src/main/java/de/assecutor/votianlt/model/AppUser.java b/src/main/java/de/assecutor/votianlt/model/AppUser.java new file mode 100644 index 0000000..7fe731a --- /dev/null +++ b/src/main/java/de/assecutor/votianlt/model/AppUser.java @@ -0,0 +1,56 @@ +package de.assecutor.votianlt.model; + +import lombok.Data; +import org.bson.types.ObjectId; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.time.LocalDateTime; + +@Data +@Document(collection = "app_user") +public class AppUser { + + @Id + private ObjectId id; + + @Field("bezeichnung") + private String bezeichnung; + + @Field("vorname") + private String vorname; + + @Field("nachname") + private String nachname; + + @Field("telefon") + private String telefon; + + @Field("app_code") + private String appCode; + + @Field("email") + @org.springframework.data.mongodb.core.index.Indexed(unique = true) + private String email; + + @Field("geraet") + private String geraet; + + @Field("erstellt_am") + private LocalDateTime erstelltAm; + + @Field("erstellt_von") + private ObjectId erstelltVon; + + @Field("aktualisiert_am") + private LocalDateTime aktualisiertAm; + + @Field("aktualisiert_von") + private ObjectId aktualisiertVon; + + public AppUser() { + this.erstelltAm = LocalDateTime.now(); + this.aktualisiertAm = LocalDateTime.now(); + } +} diff --git a/src/main/java/de/assecutor/votianlt/pages/base/ui/view/MainLayout.java b/src/main/java/de/assecutor/votianlt/pages/base/ui/view/MainLayout.java index 79a55a3..61d87b2 100644 --- a/src/main/java/de/assecutor/votianlt/pages/base/ui/view/MainLayout.java +++ b/src/main/java/de/assecutor/votianlt/pages/base/ui/view/MainLayout.java @@ -80,7 +80,7 @@ public final class MainLayout extends AppLayout { // Create navigation items for the collapsible list SideNavItem jobs = new SideNavItem("Aufträge", "jobs", new Icon(VaadinIcon.LIST)); SideNavItem customers = new SideNavItem("Kunden", "customers", new Icon(VaadinIcon.USERS)); - SideNavItem appUsers = new SideNavItem("App-Nutzer", "3", new Icon(VaadinIcon.COG)); + SideNavItem appUsers = new SideNavItem("App-Nutzer", "app-user", new Icon(VaadinIcon.USERS)); 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)); diff --git a/src/main/java/de/assecutor/votianlt/pages/domain/AddCompanyRepository.java b/src/main/java/de/assecutor/votianlt/pages/domain/AddCompanyRepository.java index 236aaef..69c3e4a 100644 --- a/src/main/java/de/assecutor/votianlt/pages/domain/AddCompanyRepository.java +++ b/src/main/java/de/assecutor/votianlt/pages/domain/AddCompanyRepository.java @@ -1,12 +1,9 @@ package de.assecutor.votianlt.pages.domain; import de.assecutor.votianlt.model.Company; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; import org.springframework.data.mongodb.repository.MongoRepository; public interface AddCompanyRepository extends MongoRepository { - // If you don't need a total row count, Slice is better than Page. - Slice findAllBy(Pageable pageable); + } diff --git a/src/main/java/de/assecutor/votianlt/pages/domain/AddCustomerRepository.java b/src/main/java/de/assecutor/votianlt/pages/domain/AddCustomerRepository.java index fcd9bbb..559d067 100644 --- a/src/main/java/de/assecutor/votianlt/pages/domain/AddCustomerRepository.java +++ b/src/main/java/de/assecutor/votianlt/pages/domain/AddCustomerRepository.java @@ -2,12 +2,9 @@ package de.assecutor.votianlt.pages.domain; import de.assecutor.votianlt.model.Customer; import org.bson.types.ObjectId; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; import org.springframework.data.mongodb.repository.MongoRepository; public interface AddCustomerRepository extends MongoRepository { - // If you don't need a total row count, Slice is better than Page. - Slice findAllBy(Pageable pageable); + } diff --git a/src/main/java/de/assecutor/votianlt/pages/domain/LoginRepository.java b/src/main/java/de/assecutor/votianlt/pages/domain/LoginRepository.java index 91abdab..f0186dd 100644 --- a/src/main/java/de/assecutor/votianlt/pages/domain/LoginRepository.java +++ b/src/main/java/de/assecutor/votianlt/pages/domain/LoginRepository.java @@ -1,16 +1,13 @@ package de.assecutor.votianlt.pages.domain; import de.assecutor.votianlt.model.User; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.Optional; public interface LoginRepository extends MongoRepository { - // If you don't need a total row count, Slice is better than Page. - Slice findAllBy(Pageable pageable); + Optional findByEmail(String email); } diff --git a/src/main/java/de/assecutor/votianlt/pages/service/AddCompanyService.java b/src/main/java/de/assecutor/votianlt/pages/service/AddCompanyService.java index 259af49..25ac151 100644 --- a/src/main/java/de/assecutor/votianlt/pages/service/AddCompanyService.java +++ b/src/main/java/de/assecutor/votianlt/pages/service/AddCompanyService.java @@ -2,13 +2,10 @@ package de.assecutor.votianlt.pages.service; import de.assecutor.votianlt.model.Company; import de.assecutor.votianlt.pages.domain.AddCompanyRepository; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service @Transactional(propagation = Propagation.REQUIRES_NEW) public class AddCompanyService { @@ -18,9 +15,7 @@ public class AddCompanyService { this.addCompanyRepository = addCompanyRepository; } - public List list(Pageable pageable) { - return addCompanyRepository.findAllBy(pageable).toList(); - } + public void addCompany(Company company) { addCompanyRepository.save(company); diff --git a/src/main/java/de/assecutor/votianlt/pages/service/AddCustomerService.java b/src/main/java/de/assecutor/votianlt/pages/service/AddCustomerService.java index 51f19c2..3300e43 100644 --- a/src/main/java/de/assecutor/votianlt/pages/service/AddCustomerService.java +++ b/src/main/java/de/assecutor/votianlt/pages/service/AddCustomerService.java @@ -3,14 +3,10 @@ package de.assecutor.votianlt.pages.service; import de.assecutor.votianlt.model.Customer; import de.assecutor.votianlt.pages.domain.AddCustomerRepository; import de.assecutor.votianlt.security.SecurityService; -import org.springframework.data.domain.Pageable; - import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service @Transactional(propagation = Propagation.REQUIRES_NEW) public class AddCustomerService { @@ -22,9 +18,7 @@ public class AddCustomerService { this.securityService = securityService; } - public List list(Pageable pageable) { - return addCustomerRepository.findAllBy(pageable).toList(); - } + public void addCustomer(Customer customer) { // Setze den aktuellen Benutzer als Ersteller - jetzt direkt aus der Session diff --git a/src/main/java/de/assecutor/votianlt/pages/service/AddJobService.java b/src/main/java/de/assecutor/votianlt/pages/service/AddJobService.java index 2652b9f..123e333 100644 --- a/src/main/java/de/assecutor/votianlt/pages/service/AddJobService.java +++ b/src/main/java/de/assecutor/votianlt/pages/service/AddJobService.java @@ -112,51 +112,7 @@ public class AddJobService { } } - /** - * Findet einen Auftrag anhand der ID - */ - public Optional findById(String id) { - try { - return jobRepository.findById(new org.bson.types.ObjectId(id)); - } catch (Exception e) { - log.error("Fehler beim Suchen des Auftrags mit ID {}: {}", id, e.getMessage()); - return Optional.empty(); - } - } - /** - * Findet einen Auftrag anhand der Auftragsnummer - */ - public Optional findByJobNumber(String jobNumber) { - return jobRepository.findByJobNumber(jobNumber); - } - - /** - * Findet alle Aufträge eines Benutzers - */ - public List findJobsByUser(String username) { - return jobRepository.findByCreatedBy(username); - } - - /** - * Findet alle Aufträge mit einem bestimmten Status - */ - public List findJobsByStatus(JobStatus status) { - return jobRepository.findByStatus(status); - } - - /** - * Löscht einen Auftrag - */ - public void deleteJob(String id) { - try { - jobRepository.deleteById(new org.bson.types.ObjectId(id)); - log.info("Auftrag mit ID {} erfolgreich gelöscht", id); - } catch (Exception e) { - log.error("Fehler beim Löschen des Auftrags mit ID {}: {}", id, e.getMessage()); - throw new RuntimeException("Auftrag konnte nicht gelöscht werden: " + e.getMessage()); - } - } /** * Generiert eine eindeutige Auftragsnummer @@ -181,19 +137,7 @@ public class AddJobService { return jobNumber; } - /** - * Zählt alle Aufträge - */ - public long countAllJobs() { - return jobRepository.count(); - } - /** - * Zählt Aufträge nach Status - */ - public long countJobsByStatus(JobStatus status) { - return jobRepository.countByStatus(status); - } /** * Speichert einen Auftrag als Entwurf (für automatisches Speichern) diff --git a/src/main/java/de/assecutor/votianlt/pages/service/AppUserService.java b/src/main/java/de/assecutor/votianlt/pages/service/AppUserService.java new file mode 100644 index 0000000..d2d6991 --- /dev/null +++ b/src/main/java/de/assecutor/votianlt/pages/service/AppUserService.java @@ -0,0 +1,40 @@ +package de.assecutor.votianlt.pages.service; + +import de.assecutor.votianlt.model.AppUser; +import de.assecutor.votianlt.repository.AppUserRepository; +import de.assecutor.votianlt.security.SecurityService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class AppUserService { + + private final AppUserRepository appUserRepository; + private final SecurityService securityService; + + @Autowired + public AppUserService(AppUserRepository appUserRepository, SecurityService securityService) { + this.appUserRepository = appUserRepository; + this.securityService = securityService; + } + + public AppUser createAppUser(AppUser appUser) { + // Set creation and update metadata + appUser.setErstelltAm(java.time.LocalDateTime.now()); + appUser.setAktualisiertAm(java.time.LocalDateTime.now()); + + // Set creator and updater if user is logged in + try { + appUser.setErstelltVon(securityService.getCurrentUserId()); + appUser.setAktualisiertVon(securityService.getCurrentUserId()); + } catch (Exception e) { + // User might not be logged in, continue without user ID + } + + return appUserRepository.save(appUser); + } + + +} diff --git a/src/main/java/de/assecutor/votianlt/pages/service/CustomerService.java b/src/main/java/de/assecutor/votianlt/pages/service/CustomerService.java index 9dd99ff..b3c0d8f 100644 --- a/src/main/java/de/assecutor/votianlt/pages/service/CustomerService.java +++ b/src/main/java/de/assecutor/votianlt/pages/service/CustomerService.java @@ -2,14 +2,11 @@ package de.assecutor.votianlt.pages.service; import de.assecutor.votianlt.model.Customer; import de.assecutor.votianlt.pages.domain.CustomerRepository; -import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -import java.time.Clock; -import java.time.LocalDate; import java.util.List; import org.bson.types.ObjectId; @@ -19,25 +16,16 @@ public class CustomerService { private final CustomerRepository todoRepository; - private final Clock clock; - - CustomerService(CustomerRepository todoRepository, Clock clock) { + CustomerService(CustomerRepository todoRepository) { this.todoRepository = todoRepository; - this.clock = clock; } - public void createTodo(String description, @Nullable LocalDate dueDate) { - if ("fail".equals(description)) { - throw new RuntimeException("This is for testing the error handler"); - } - var todo = new Customer(); - todoRepository.save(todo); - } - - public List list(Pageable pageable) { + public List list(org.springframework.data.domain.Pageable pageable) { return todoRepository.findAllBy(pageable).toList(); } + + public List findAll() { return todoRepository.findAll(); } diff --git a/src/main/java/de/assecutor/votianlt/pages/view/AddJobView.java b/src/main/java/de/assecutor/votianlt/pages/view/AddJobView.java index f57c0f1..5fc4de0 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/AddJobView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/AddJobView.java @@ -57,9 +57,6 @@ public class AddJobView extends Main { private ComboBox customerSelection; private Button preloadAddressButton; - // Required fields notice - private Span requiredFieldsNotice; - // Pickup address fields private TextField pickupCompany; private ComboBox pickupSalutation; @@ -325,13 +322,10 @@ public class AddJobView extends Main { // Left column (50%) - Pickup address section pickupSection = createPickupSection(); pickupSection.setWidth("50%"); - // Drag sources for dynamic control - DragSource pickupDragSource = configureDragAndDrop(pickupSection, "pickup"); // Right column (50%) - Delivery address section deliverySection = createDeliverySection(); deliverySection.setWidth("50%"); - DragSource deliveryDragSource = configureDragAndDrop(deliverySection, "delivery"); // Setup focus listeners for input fields setupInputFieldFocusListeners(); @@ -555,23 +549,6 @@ public class AddJobView extends Main { return section; } - - - - - private void copyPickupToDelivery() { - deliveryCompany.setValue(pickupCompany.getValue()); - deliverySalutation.setValue(pickupSalutation.getValue()); - deliveryFirstName.setValue(pickupFirstName.getValue()); - deliveryLastName.setValue(pickupLastName.getValue()); - deliveryPhone.setValue(pickupPhone.getValue()); - deliveryStreet.setValue(pickupStreet.getValue()); - deliveryHouseNumber.setValue(pickupHouseNumber.getValue()); - deliveryAddressAddition.setValue(pickupAddressAddition.getValue()); - deliveryZip.setValue(pickupZip.getValue()); - deliveryCity.setValue(pickupCity.getValue()); - } - private void setupValidation() { // Bind pickup address fields with validation binder.forField(pickupFirstName) @@ -723,7 +700,6 @@ public class AddJobView extends Main { private void triggerValidation() { // Create a temporary job object to trigger validation - Job tempJob = new Job(); binder.validate(); } @@ -909,69 +885,6 @@ public class AddJobView extends Main { appUser.clear(); } - /** - * Persistiert die aktuellen Formulardaten als Entwurf - */ - private void persistCurrentData() { - // Prüfen ob mindestens ein Feld ausgefüllt ist - if (isFormEmpty()) { - return; // Keine Daten zum Speichern - } - - Job job = new Job(); - - // Alle aktuellen Werte aus dem Formular lesen - job.setCustomerSelection(customerSelection.getValue()); - - // Pickup address - job.setPickupCompany(pickupCompany.getValue()); - job.setPickupSalutation(pickupSalutation.getValue()); - job.setPickupFirstName(pickupFirstName.getValue()); - job.setPickupLastName(pickupLastName.getValue()); - job.setPickupPhone(pickupPhone.getValue()); - job.setPickupStreet(pickupStreet.getValue()); - job.setPickupHouseNumber(pickupHouseNumber.getValue()); - job.setPickupAddressAddition(pickupAddressAddition.getValue()); - job.setPickupZip(pickupZip.getValue()); - job.setPickupCity(pickupCity.getValue()); - - // Delivery address - job.setDeliveryCompany(deliveryCompany.getValue()); - job.setDeliverySalutation(deliverySalutation.getValue()); - job.setDeliveryFirstName(deliveryFirstName.getValue()); - job.setDeliveryLastName(deliveryLastName.getValue()); - job.setDeliveryPhone(deliveryPhone.getValue()); - job.setDeliveryStreet(deliveryStreet.getValue()); - job.setDeliveryHouseNumber(deliveryHouseNumber.getValue()); - job.setDeliveryAddressAddition(deliveryAddressAddition.getValue()); - job.setDeliveryZip(deliveryZip.getValue()); - job.setDeliveryCity(deliveryCity.getValue()); - - // Digital processing - job.setDigitalProcessing(digitalProcessing.getValue()); - job.setAppUser(appUser.getValue()); - - // Als Entwurf speichern - addJobService.saveDraft(job); - } - - /** - * Prüft ob das Formular komplett leer ist - */ - private boolean isFormEmpty() { - return (customerSelection.getValue() == null || customerSelection.getValue().trim().isEmpty()) && - (pickupCompany.getValue() == null || pickupCompany.getValue().trim().isEmpty()) && - (pickupFirstName.getValue() == null || pickupFirstName.getValue().trim().isEmpty()) && - (pickupLastName.getValue() == null || pickupLastName.getValue().trim().isEmpty()) && - (pickupStreet.getValue() == null || pickupStreet.getValue().trim().isEmpty()) && - (pickupCity.getValue() == null || pickupCity.getValue().trim().isEmpty()) && - (deliveryCompany.getValue() == null || deliveryCompany.getValue().trim().isEmpty()) && - (deliveryFirstName.getValue() == null || deliveryFirstName.getValue().trim().isEmpty()) && - (deliveryLastName.getValue() == null || deliveryLastName.getValue().trim().isEmpty()) && - (deliveryStreet.getValue() == null || deliveryStreet.getValue().trim().isEmpty()) && - (deliveryCity.getValue() == null || deliveryCity.getValue().trim().isEmpty()); - } - /** * Lädt einen bestehenden Entwurf, falls vorhanden */ @@ -1401,59 +1314,6 @@ public class AddJobView extends Main { } } - /** - * Konfiguriert Drag-and-Drop für eine Etappen-Sektion - */ - private DragSource configureDragAndDrop(VerticalLayout section, String sectionType) { - // Drag Source konfigurieren - DragSource dragSource = DragSource.create(section); - dragSource.setEffectAllowed(EffectAllowed.MOVE); - dragSource.setDragData(sectionType); - - // Visual feedback beim Drag-Start - dragSource.addDragStartListener(event -> { - section.getStyle().set("opacity", "0.5"); - section.getStyle().set("border", "2px dashed var(--lumo-primary-color)"); - }); - - // Visual feedback beim Drag-Ende - dragSource.addDragEndListener(event -> { - section.getStyle().remove("opacity"); - section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)"); - }); - - // Drop Target konfigurieren - DropTarget dropTarget = DropTarget.create(section); - dropTarget.setActive(true); - - // Drop Handler - Etappen tauschen - dropTarget.addDropListener(event -> { - Object draggedData = event.getDragData().orElse(null); - String draggedSectionType = draggedData != null ? draggedData.toString() : ""; - - if (!sectionType.equals(draggedSectionType)) { - swapStages(); - } - - // Styles zurücksetzen - section.getStyle().set("background-color", "var(--lumo-base-color)"); - section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)"); - }); - - // Visual feedback bei Dragover mit JavaScript - section.getElement().addEventListener("dragover", e -> { - section.getStyle().set("background-color", "var(--lumo-primary-color-10pct)"); - section.getStyle().set("border", "2px solid var(--lumo-primary-color)"); - }); - - section.getElement().addEventListener("dragleave", e -> { - section.getStyle().set("background-color", "var(--lumo-base-color)"); - section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)"); - }); - - return dragSource; - } - /** * Tauscht die Inhalte der beiden Etappen (Pickup und Delivery) */ diff --git a/src/main/java/de/assecutor/votianlt/pages/view/AppUserView.java b/src/main/java/de/assecutor/votianlt/pages/view/AppUserView.java new file mode 100644 index 0000000..e126bfb --- /dev/null +++ b/src/main/java/de/assecutor/votianlt/pages/view/AppUserView.java @@ -0,0 +1,168 @@ +package de.assecutor.votianlt.pages.view; + +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.html.H2; +import com.vaadin.flow.component.html.Span; +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.component.textfield.TextField; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.data.binder.Binder; +import com.vaadin.flow.data.binder.ValidationException; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import de.assecutor.votianlt.model.AppUser; +import de.assecutor.votianlt.pages.service.AppUserService; +import jakarta.annotation.security.RolesAllowed; +import org.springframework.beans.factory.annotation.Autowired; + +@PageTitle("Neuen App-Nutzer anlegen") +@Route(value = "app-user", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class) +@RolesAllowed({"USER","ADMIN"}) +public class AppUserView extends VerticalLayout { + + private final Binder binder = new Binder<>(AppUser.class); + + // Form fields + private final TextField designationField = new TextField("Bezeichnung (HH H 000)"); + private final TextField firstnameField = new TextField("Vorname"); + private final TextField lastnameField = new TextField("Nachname"); + private final TextField phoneField = new TextField("Telefon (Mobil)"); + private final TextField appCodeField = new TextField("App-Code"); + private final TextField emailField = new TextField("E-Mail-Adresse"); + private final ComboBox deviceField = new ComboBox<>("kein Gerät"); + + private final AppUserService appUserService; + + @Autowired + public AppUserView(AppUserService appUserService) { + this.appUserService = appUserService; + setSizeFull(); + setPadding(true); + setSpacing(true); + + // Center content vertically + setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); + setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER); + + // Create main content container + VerticalLayout contentContainer = new VerticalLayout(); + contentContainer.setWidth("600px"); + contentContainer.setMaxWidth("90%"); + contentContainer.setSpacing(true); + contentContainer.setPadding(true); + contentContainer.getStyle().set("background", "var(--lumo-contrast-5pct)"); + contentContainer.getStyle().set("border-radius", "var(--lumo-border-radius)"); + contentContainer.getStyle().set("box-shadow", "var(--lumo-box-shadow-s)"); + + // Header with title and question mark icon + HorizontalLayout header = new HorizontalLayout(); + header.setAlignItems(FlexComponent.Alignment.CENTER); + header.setSpacing(true); + + H2 title = new H2("Neuen App-Nutzer anlegen"); + title.getStyle().set("margin", "0"); + + Icon questionIcon = new Icon(VaadinIcon.QUESTION_CIRCLE); + questionIcon.getStyle().set("color", "var(--lumo-secondary-text-color)"); + + header.add(title, questionIcon); + header.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); + contentContainer.add(header); + + // Form layout + FormLayout formLayout = new FormLayout(); + formLayout.setResponsiveSteps( + new FormLayout.ResponsiveStep("0", 1) + ); + + // Configure fields + designationField.setPlaceholder("(HH H 000)"); + designationField.setWidthFull(); + + firstnameField.setWidthFull(); + lastnameField.setWidthFull(); + + // Create horizontal layout for firstname and lastname + HorizontalLayout nameLayout = new HorizontalLayout(); + nameLayout.setWidthFull(); + nameLayout.setSpacing(true); + nameLayout.add(firstnameField, lastnameField); + + phoneField.setWidthFull(); + appCodeField.setWidthFull(); + emailField.setWidthFull(); + + // Configure device dropdown + deviceField.setItems("kein Gerät", "iPhone", "Android", "Tablet", "Desktop"); + deviceField.setValue("kein Gerät"); + deviceField.setWidthFull(); + + // Add fields to form + formLayout.add(designationField); + formLayout.add(nameLayout); + formLayout.add(phoneField); + formLayout.add(appCodeField); + formLayout.add(emailField); + formLayout.add(deviceField); + + contentContainer.add(formLayout); + + // Submit button + Button submitButton = new Button("App-Nutzer anlegen", e -> createAppUser()); + submitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + submitButton.setWidthFull(); + contentContainer.add(submitButton); + + // Add content container to main layout + add(contentContainer); + + // Setup binder + setupBinder(); + } + + private void setupBinder() { + // Bind fields to AppUser properties + binder.forField(designationField).bind(AppUser::getBezeichnung, AppUser::setBezeichnung); + binder.forField(firstnameField).bind(AppUser::getVorname, AppUser::setVorname); + binder.forField(lastnameField).bind(AppUser::getNachname, AppUser::setNachname); + binder.forField(phoneField).bind(AppUser::getTelefon, AppUser::setTelefon); + binder.forField(appCodeField).bind(AppUser::getAppCode, AppUser::setAppCode); + binder.forField(emailField).bind(AppUser::getEmail, AppUser::setEmail); + binder.forField(deviceField).bind(AppUser::getGeraet, AppUser::setGeraet); + } + + private void createAppUser() { + try { + // Create new AppUser object + AppUser newAppUser = new AppUser(); + binder.writeBean(newAppUser); + + // Save to MongoDB collection + appUserService.createAppUser(newAppUser); + + // Show success message + Notification.show( + "App-Nutzer erfolgreich angelegt", + 3000, + Notification.Position.MIDDLE + ); + + // Clear form + binder.readBean(new AppUser()); + + } catch (ValidationException e) { + Notification.show( + "Bitte überprüfen Sie die Eingaben", + 3000, + Notification.Position.MIDDLE + ); + } + } +} diff --git a/src/main/java/de/assecutor/votianlt/repository/AppUserRepository.java b/src/main/java/de/assecutor/votianlt/repository/AppUserRepository.java new file mode 100644 index 0000000..205b690 --- /dev/null +++ b/src/main/java/de/assecutor/votianlt/repository/AppUserRepository.java @@ -0,0 +1,15 @@ +package de.assecutor.votianlt.repository; + +import de.assecutor.votianlt.model.AppUser; +import org.bson.types.ObjectId; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AppUserRepository extends MongoRepository { + + // Custom query methods can be added here if needed + // For example: + // List findByEmail(String email); + // List findByBezeichnung(String bezeichnung); +}