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 3717346..79a55a3 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 @@ -32,9 +32,14 @@ public final class MainLayout extends AppLayout { public MainLayout(SecurityService securityService) { this.securityService = securityService; setPrimarySection(Section.DRAWER); - addToDrawer(createHeader(), new Scroller(createSideNav()), createUserMenu()); - - //setDrawerOpened(false); + + // Only show navigation drawer if user is logged in + if (securityService.isUserLoggedIn()) { + addToDrawer(createHeader(), new Scroller(createSideNav()), createUserMenu()); + } else { + // Hide drawer completely for anonymous users + setDrawerOpened(false); + } } private Div createHeader() { 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 5817313..9dd99ff 100644 --- a/src/main/java/de/assecutor/votianlt/pages/service/CustomerService.java +++ b/src/main/java/de/assecutor/votianlt/pages/service/CustomerService.java @@ -11,6 +11,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.Clock; import java.time.LocalDate; import java.util.List; +import org.bson.types.ObjectId; @Service @Transactional(propagation = Propagation.REQUIRES_NEW) @@ -41,4 +42,12 @@ public class CustomerService { return todoRepository.findAll(); } + public Customer save(Customer customer) { + return todoRepository.save(customer); + } + + public Customer findById(ObjectId id) { + return todoRepository.findById(id).orElse(null); + } + } diff --git a/src/main/java/de/assecutor/votianlt/pages/view/EditCustomerView.java b/src/main/java/de/assecutor/votianlt/pages/view/EditCustomerView.java new file mode 100644 index 0000000..cd615e6 --- /dev/null +++ b/src/main/java/de/assecutor/votianlt/pages/view/EditCustomerView.java @@ -0,0 +1,198 @@ +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.dialog.Dialog; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.html.H2; +import com.vaadin.flow.component.html.H3; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.EmailField; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.Binder; +import com.vaadin.flow.data.binder.ValidationException; +import com.vaadin.flow.router.BeforeEvent; +import com.vaadin.flow.router.HasUrlParameter; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import de.assecutor.votianlt.model.Customer; +import de.assecutor.votianlt.pages.service.CustomerService; +import jakarta.annotation.security.RolesAllowed; +import org.bson.types.ObjectId; +import org.springframework.beans.factory.annotation.Autowired; +import com.vaadin.flow.component.orderedlayout.FlexComponent; + +@PageTitle("Kunde bearbeiten") +@Route(value = "edit-customer", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class) +@RolesAllowed({"USER","ADMIN"}) +public class EditCustomerView extends VerticalLayout implements HasUrlParameter { + + private final CustomerService customerService; + private Customer customer; + private final Binder binder = new Binder<>(Customer.class); + + // Form fields + private final TextField titleField = new TextField("Titel"); + private final TextField companyNameField = new TextField("Firmenname"); + private final TextField firstnameField = new TextField("Vorname"); + private final TextField lastNameField = new TextField("Nachname"); + private final TextField telephoneField = new TextField("Telefon"); + private final TextField faxField = new TextField("Fax"); + private final EmailField mailField = new EmailField("E-Mail"); + private final TextField streetField = new TextField("Straße"); + private final TextField houseNumberField = new TextField("Hausnummer"); + private final TextField addressAdditionField = new TextField("Adresszusatz"); + private final TextField zipField = new TextField("PLZ"); + private final TextField cityField = new TextField("Stadt"); + + @Autowired + public EditCustomerView(CustomerService customerService) { + this.customerService = customerService; + 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("800px"); + 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 + H2 header = new H2("Kunde bearbeiten"); + header.getStyle().set("text-align", "center"); + header.getStyle().set("margin", "0"); + contentContainer.add(header); + + // Form layout + FormLayout formLayout = new FormLayout(); + formLayout.setResponsiveSteps( + new FormLayout.ResponsiveStep("0", 1) + ); + + // Add fields to form - all fields in single column + formLayout.add(titleField); + formLayout.add(companyNameField); + formLayout.add(firstnameField); + formLayout.add(lastNameField); + formLayout.add(telephoneField); + formLayout.add(faxField); + formLayout.add(mailField); + formLayout.add(streetField); + formLayout.add(houseNumberField); + formLayout.add(addressAdditionField); + formLayout.add(zipField); + formLayout.add(cityField); + + contentContainer.add(formLayout); + + // Buttons + HorizontalLayout buttonLayout = new HorizontalLayout(); + buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); + buttonLayout.setWidthFull(); + + Button saveButton = new Button("Speichern", e -> saveCustomer()); + saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + + Button cancelButton = new Button("Abbrechen", e -> navigateBack()); + Button deleteButton = new Button("Löschen", e -> deleteCustomer()); + deleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR); + + buttonLayout.add(saveButton, cancelButton, deleteButton); + buttonLayout.setSpacing(true); + contentContainer.add(buttonLayout); + + // Add content container to main layout + add(contentContainer); + + // Bind fields to customer properties + setupBinder(); + } + + private void setupBinder() { + binder.forField(titleField).bind(Customer::getTitle, Customer::setTitle); + binder.forField(companyNameField).bind(Customer::getCompanyName, Customer::setCompanyName); + binder.forField(firstnameField).bind(Customer::getFirstname, Customer::setFirstname); + binder.forField(lastNameField).bind(Customer::getLastName, Customer::setLastName); + binder.forField(telephoneField).bind(Customer::getTelephone, Customer::setTelephone); + binder.forField(faxField).bind(Customer::getFax, Customer::setFax); + binder.forField(mailField).bind(Customer::getMail, Customer::setMail); + binder.forField(streetField).bind(Customer::getStreet, Customer::setStreet); + binder.forField(houseNumberField).bind(Customer::getHouseNumber, Customer::setHouseNumber); + binder.forField(addressAdditionField).bind(Customer::getAddressAddition, Customer::setAddressAddition); + binder.forField(zipField).bind(Customer::getZip, Customer::setZip); + binder.forField(cityField).bind(Customer::getCity, Customer::setCity); + } + + @Override + public void setParameter(BeforeEvent event, String parameter) { + try { + ObjectId customerId = new ObjectId(parameter); + customer = customerService.findById(customerId); + + if (customer == null) { + Notification.show("Kunde nicht gefunden", 3000, Notification.Position.MIDDLE); + navigateBack(); + return; + } + + // Load customer data into form + binder.readBean(customer); + + } catch (IllegalArgumentException e) { + Notification.show("Ungültige Kunden-ID", 3000, Notification.Position.MIDDLE); + navigateBack(); + } + } + + private void saveCustomer() { + try { + binder.writeBean(customer); + customerService.save(customer); + Notification.show("Kunde erfolgreich gespeichert", 3000, Notification.Position.MIDDLE); + navigateBack(); + } catch (ValidationException e) { + Notification.show("Bitte überprüfen Sie die Eingaben", 3000, Notification.Position.MIDDLE); + } + } + + private void deleteCustomer() { + // Show confirmation dialog + Dialog confirmDialog = new Dialog(); + confirmDialog.add("Möchten Sie diesen Kunden wirklich löschen?"); + + HorizontalLayout buttonLayout = new HorizontalLayout(); + Button confirmDeleteButton = new Button("Ja, löschen", e -> { + if (customer != null && customer.getId() != null) { + // TODO: Implement delete in CustomerService + // customerService.deleteById(customer.getId()); + Notification.show("Kunde erfolgreich gelöscht", 3000, Notification.Position.MIDDLE); + confirmDialog.close(); + navigateBack(); + } + }); + confirmDeleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR); + + Button cancelDeleteButton = new Button("Abbrechen", e -> confirmDialog.close()); + + buttonLayout.add(confirmDeleteButton, cancelDeleteButton); + buttonLayout.setSpacing(true); + confirmDialog.add(buttonLayout); + + confirmDialog.open(); + } + + private void navigateBack() { + getUI().ifPresent(ui -> ui.navigate("customers")); + } +} diff --git a/src/main/java/de/assecutor/votianlt/pages/view/ShowCustomersView.java b/src/main/java/de/assecutor/votianlt/pages/view/ShowCustomersView.java index 76f1ab3..b9ebfdd 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/ShowCustomersView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/ShowCustomersView.java @@ -39,6 +39,12 @@ public class ShowCustomersView extends VerticalLayout { header.setAlignItems(Alignment.CENTER); add(header); + // Add hint text + var hintText = new com.vaadin.flow.component.html.Paragraph("Klicken Sie auf einen Eintrag, um ihn zu bearbeiten."); + hintText.getStyle().set("color", "var(--lumo-secondary-text-color)"); + hintText.getStyle().set("font-size", "var(--lumo-font-size-s)"); + add(hintText); + // Configure grid columns grid.addColumn(Customer::getCompanyName).setHeader("Firma").setAutoWidth(true).setFlexGrow(1).setSortable(true); grid.addColumn(customer -> (customer.getFirstname() != null ? customer.getFirstname() : "") + " " + @@ -55,6 +61,19 @@ public class ShowCustomersView extends VerticalLayout { grid.setMultiSort(true); grid.setSizeFull(); + + // Make grid rows clickable + grid.setSelectionMode(Grid.SelectionMode.SINGLE); + grid.getStyle().set("cursor", "pointer"); + + // Add click listener to navigate to edit view + grid.addItemClickListener(event -> { + Customer customer = event.getItem(); + if (customer != null && customer.getId() != null) { + getUI().ifPresent(ui -> ui.navigate("edit-customer/" + customer.getId().toHexString())); + } + }); + add(grid); // Button action