| author | Thorsten Ortlepp
<post@ortlepp.ms> 2026-01-30 23:10:23 UTC |
| committer | Thorsten Ortlepp
<post@ortlepp.ms> 2026-01-30 23:10:23 UTC |
| parent | 136fe7269a95dfe31987e5bcf710bce1620b00c2 |
| src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java | +0 | -2 |
| src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java | +1 | -1 |
| src/main/java/dev/rubidium/subscriptiontool/controller/ManagementController.java | +69 | -0 |
| src/main/java/dev/rubidium/subscriptiontool/model/Action.java | +6 | -0 |
| src/main/java/dev/rubidium/subscriptiontool/model/ManagementAction.java | +23 | -0 |
| src/main/java/dev/rubidium/subscriptiontool/model/Subscriber.java | +13 | -0 |
| src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Mail.java | +15 | -11 |
| src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Subscription.java | +13 | -0 |
| src/main/java/dev/rubidium/subscriptiontool/persistence/repository/SubscriptionRepository.java | +4 | -0 |
| src/main/java/dev/rubidium/subscriptiontool/properties/Translation.java | +13 | -1 |
| src/main/java/dev/rubidium/subscriptiontool/scheduler/MailScheduler.java | +2 | -0 |
| src/main/java/dev/rubidium/subscriptiontool/service/ManagementService.java | +13 | -0 |
| src/main/java/dev/rubidium/subscriptiontool/service/PersistenceService.java | +8 | -1 |
| src/main/java/dev/rubidium/subscriptiontool/service/impl/ManagementServiceImpl.java | +48 | -0 |
| src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java | +77 | -23 |
| src/main/java/dev/rubidium/subscriptiontool/service/impl/SubscriptionServiceImpl.java | +1 | -1 |
| src/main/resources/application.properties | +2 | -0 |
| src/main/resources/templates/Manage.html | +75 | -0 |
| src/main/resources/translation.properties | +13 | -1 |
diff --git a/src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java b/src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java index 2720e0b..c782084 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java +++ b/src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java @@ -5,11 +5,9 @@ import dev.rubidium.subscriptiontool.properties.Translation; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableConfigurationProperties({Translation.class, MailProperties.class}) -@EnableScheduling public class SubscriptionToolApplication { static void main(String[] args) { diff --git a/src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java b/src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java index 1af5023..ebbf3ec 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java +++ b/src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java @@ -28,7 +28,7 @@ public class SecurityConfiguration { public SecurityFilterChain defaultHttpSecurity(HttpSecurity httpSecurity) { httpSecurity .authorizeHttpRequests((requests) -> requests - .requestMatchers("/actuator", "/actuator/**") + .requestMatchers("/actuator", "/actuator/**", "/manage", "/manage/**") .authenticated() .anyRequest() .permitAll()) diff --git a/src/main/java/dev/rubidium/subscriptiontool/controller/ManagementController.java b/src/main/java/dev/rubidium/subscriptiontool/controller/ManagementController.java new file mode 100644 index 0000000..d952ea2 --- /dev/null +++ b/src/main/java/dev/rubidium/subscriptiontool/controller/ManagementController.java @@ -0,0 +1,69 @@ +package dev.rubidium.subscriptiontool.controller; + +import dev.rubidium.subscriptiontool.model.Action; +import dev.rubidium.subscriptiontool.model.ManagementAction; +import dev.rubidium.subscriptiontool.model.Subscriber; +import dev.rubidium.subscriptiontool.properties.Translation; +import dev.rubidium.subscriptiontool.service.ManagementService; +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; + +@Controller +public class ManagementController { + + private static final String ATTRIBUTE_NAME_TRANSLATION = "translation"; + private static final String ATTRIBUTE_NAME_SUBSCRIBERS = "subscribers"; + private static final String ATTRIBUTE_NAME_MAILS = "mails"; + + private final ManagementService managementService; + private final Translation translation; + + public ManagementController(final ManagementService managementService, + final Translation translation) { + this.managementService = managementService; + this.translation = translation; + } + + @GetMapping("/manage") + public String index(Model model) { + var subscribers = managementService.getSubscribers(); + + model.addAttribute(ATTRIBUTE_NAME_TRANSLATION, translation); + model.addAttribute(ATTRIBUTE_NAME_SUBSCRIBERS, subscribers); + model.addAttribute(ATTRIBUTE_NAME_MAILS, extractMails(subscribers)); + + return "Manage"; + } + + @PostMapping("/manage") + public String action(@ModelAttribute ManagementAction managementAction, Model model) { + if (managementAction.getAction() == Action.ACTIVATE) { + managementService.activateSubscription(managementAction.getSubscription()); + } else if (managementAction.getAction() == Action.DELETE) { + managementService.deleteSubscription(managementAction.getSubscription()); + } + + var subscribers = managementService.getSubscribers(); + + model.addAttribute(ATTRIBUTE_NAME_TRANSLATION, translation); + model.addAttribute(ATTRIBUTE_NAME_SUBSCRIBERS, subscribers); + model.addAttribute(ATTRIBUTE_NAME_MAILS, extractMails(subscribers)); + + return "Manage"; + } + + private String extractMails(List<Subscriber> subscribers) { + var mails = new ArrayList<String>(); + subscribers.forEach(subscriber -> { + if (subscriber.confirmed()) { + mails.add(subscriber.mail()); + } + }); + return String.join(", ", mails); + } +} diff --git a/src/main/java/dev/rubidium/subscriptiontool/model/Action.java b/src/main/java/dev/rubidium/subscriptiontool/model/Action.java new file mode 100644 index 0000000..a16d9c3 --- /dev/null +++ b/src/main/java/dev/rubidium/subscriptiontool/model/Action.java @@ -0,0 +1,6 @@ +package dev.rubidium.subscriptiontool.model; + +public enum Action { + ACTIVATE, + DELETE +} diff --git a/src/main/java/dev/rubidium/subscriptiontool/model/ManagementAction.java b/src/main/java/dev/rubidium/subscriptiontool/model/ManagementAction.java new file mode 100644 index 0000000..ada85fd --- /dev/null +++ b/src/main/java/dev/rubidium/subscriptiontool/model/ManagementAction.java @@ -0,0 +1,23 @@ +package dev.rubidium.subscriptiontool.model; + +public class ManagementAction { + + private Action action; + private Long subscription; + + public Action getAction() { + return action; + } + + public void setAction(Action action) { + this.action = action; + } + + public Long getSubscription() { + return subscription; + } + + public void setSubscription(Long subscription) { + this.subscription = subscription; + } +} diff --git a/src/main/java/dev/rubidium/subscriptiontool/model/Subscriber.java b/src/main/java/dev/rubidium/subscriptiontool/model/Subscriber.java new file mode 100644 index 0000000..1ef2c42 --- /dev/null +++ b/src/main/java/dev/rubidium/subscriptiontool/model/Subscriber.java @@ -0,0 +1,13 @@ +package dev.rubidium.subscriptiontool.model; + +import java.time.LocalDateTime; + +public record Subscriber(Long id, + String mail, + Boolean confirmed, + LocalDateTime registration, + LocalDateTime confirmation, + Boolean doiMailStatus, + LocalDateTime doiMailTime) { + +} diff --git a/src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Mail.java b/src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Mail.java index 4f90e39..cc819f8 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Mail.java +++ b/src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Mail.java @@ -5,6 +5,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import java.sql.Timestamp; @@ -17,9 +19,6 @@ public class Mail { @Column(name = "id") private Long id; - @Column(name = "subscription") - private Long subscription; - @Column(name = "sent") private Boolean sent; @@ -29,6 +28,10 @@ public class Mail { @Column(name = "completion") private Timestamp completion; + @OneToOne + @JoinColumn(name = "subscription", referencedColumnName = "id") + private Subscription subscription; + public Long getId() { return id; } @@ -37,14 +40,6 @@ public class Mail { this.id = id; } - public Long getSubscription() { - return subscription; - } - - public void setSubscription(Long subscription) { - this.subscription = subscription; - } - public Boolean getSent() { return sent; } @@ -68,4 +63,13 @@ public class Mail { public void setCompletion(Timestamp completion) { this.completion = completion; } + + public Subscription getSubscription() { + return subscription; + } + + public void setSubscription( + Subscription subscription) { + this.subscription = subscription; + } } diff --git a/src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Subscription.java b/src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Subscription.java index e300d56..acee97b 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Subscription.java +++ b/src/main/java/dev/rubidium/subscriptiontool/persistence/entity/Subscription.java @@ -1,10 +1,12 @@ package dev.rubidium.subscriptiontool.persistence.entity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import java.sql.Timestamp; @@ -32,6 +34,9 @@ public class Subscription { @Column(name = "confirmation") private Timestamp confirmation; + @OneToOne(mappedBy = "subscription", cascade = CascadeType.ALL, orphanRemoval = true) + private Mail relationMail; + public Long getId() { return id; } @@ -79,4 +84,12 @@ public class Subscription { public void setConfirmation(Timestamp confirmation) { this.confirmation = confirmation; } + + public Mail getRelationMail() { + return relationMail; + } + + public void setRelationMail(Mail relationMail) { + this.relationMail = relationMail; + } } diff --git a/src/main/java/dev/rubidium/subscriptiontool/persistence/repository/SubscriptionRepository.java b/src/main/java/dev/rubidium/subscriptiontool/persistence/repository/SubscriptionRepository.java index 51768c9..60e281c 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/persistence/repository/SubscriptionRepository.java +++ b/src/main/java/dev/rubidium/subscriptiontool/persistence/repository/SubscriptionRepository.java @@ -1,6 +1,7 @@ package dev.rubidium.subscriptiontool.persistence.repository; import dev.rubidium.subscriptiontool.persistence.entity.Subscription; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -11,4 +12,7 @@ public interface SubscriptionRepository extends JpaRepository<Subscription, Long @Query("SELECT s FROM Subscription s WHERE s.code = :code") Subscription findByCode(String code); + + @Query("SELECT s FROM Subscription s LEFT JOIN s.relationMail ORDER BY s.id ASC") + List<Subscription> findAllSubscriptions(); } diff --git a/src/main/java/dev/rubidium/subscriptiontool/properties/Translation.java b/src/main/java/dev/rubidium/subscriptiontool/properties/Translation.java index 1f60f64..eca69dc 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/properties/Translation.java +++ b/src/main/java/dev/rubidium/subscriptiontool/properties/Translation.java @@ -20,6 +20,18 @@ public record Translation(String title, String mailSubject, String mailText, String error, - String home) { + String home, + String manage, + String tableMail, + String tableStatus, + String tableRegistered, + String tableConfirmed, + String tableDoiMail, + String tableActions, + String active, + String inactive, + String activate, + String delete, + String copy) { } diff --git a/src/main/java/dev/rubidium/subscriptiontool/scheduler/MailScheduler.java b/src/main/java/dev/rubidium/subscriptiontool/scheduler/MailScheduler.java index fa2c4cc..c46d590 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/scheduler/MailScheduler.java +++ b/src/main/java/dev/rubidium/subscriptiontool/scheduler/MailScheduler.java @@ -6,10 +6,12 @@ import dev.rubidium.subscriptiontool.service.MailService; import dev.rubidium.subscriptiontool.service.PersistenceService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @Service +@EnableScheduling public class MailScheduler { private static final Logger logger = LoggerFactory.getLogger(MailScheduler.class); diff --git a/src/main/java/dev/rubidium/subscriptiontool/service/ManagementService.java b/src/main/java/dev/rubidium/subscriptiontool/service/ManagementService.java new file mode 100644 index 0000000..f9deefe --- /dev/null +++ b/src/main/java/dev/rubidium/subscriptiontool/service/ManagementService.java @@ -0,0 +1,13 @@ +package dev.rubidium.subscriptiontool.service; + +import dev.rubidium.subscriptiontool.model.Subscriber; +import java.util.List; + +public interface ManagementService { + + List<Subscriber> getSubscribers(); + + void activateSubscription(Long id); + + void deleteSubscription(Long id); +} diff --git a/src/main/java/dev/rubidium/subscriptiontool/service/PersistenceService.java b/src/main/java/dev/rubidium/subscriptiontool/service/PersistenceService.java index 1e6890b..f84896e 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/service/PersistenceService.java +++ b/src/main/java/dev/rubidium/subscriptiontool/service/PersistenceService.java @@ -1,5 +1,6 @@ package dev.rubidium.subscriptiontool.service; +import dev.rubidium.subscriptiontool.model.Subscriber; import dev.rubidium.subscriptiontool.model.UnsentMail; import java.util.List; @@ -7,11 +8,17 @@ public interface PersistenceService { boolean createSubscription(String email, String code); + boolean deleteSubscription(Long id); + boolean deleteSubscription(String email); - boolean updateSubscription(String code); + boolean confirmSubscription(Long id); + + boolean confirmSubscription(String code); List<UnsentMail> getUnsentMails(); void updateMail(Long id); + + List<Subscriber> getSubscribers(); } diff --git a/src/main/java/dev/rubidium/subscriptiontool/service/impl/ManagementServiceImpl.java b/src/main/java/dev/rubidium/subscriptiontool/service/impl/ManagementServiceImpl.java new file mode 100644 index 0000000..416e0ed --- /dev/null +++ b/src/main/java/dev/rubidium/subscriptiontool/service/impl/ManagementServiceImpl.java @@ -0,0 +1,48 @@ +package dev.rubidium.subscriptiontool.service.impl; + +import dev.rubidium.subscriptiontool.model.Subscriber; +import dev.rubidium.subscriptiontool.service.ManagementService; +import dev.rubidium.subscriptiontool.service.PersistenceService; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class ManagementServiceImpl implements ManagementService { + + private static final Logger logger = LoggerFactory.getLogger(ManagementServiceImpl.class); + + private final PersistenceService persistenceService; + + public ManagementServiceImpl(final PersistenceService persistenceService) { + this.persistenceService = persistenceService; + } + + @Override + public List<Subscriber> getSubscribers() { + var result = persistenceService.getSubscribers(); + logger.info("Retrieved {} subscribers", result.size()); + return result; + } + + @Override + public void deleteSubscription(Long id) { + boolean result = persistenceService.deleteSubscription(id); + if (result) { + logger.warn("Deletion of subscription {} successful", id); + } else { + logger.warn("Deletion of subscription {} unsuccessful", id); + } + } + + @Override + public void activateSubscription(Long id) { + boolean result = persistenceService.confirmSubscription(id); + if (result) { + logger.warn("Activation of subscription {} successful", id); + } else { + logger.warn("Activation of subscription {} unsuccessful", id); + } + } +} diff --git a/src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java b/src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java index d3f7e9d..cf5ae20 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java +++ b/src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java @@ -1,5 +1,6 @@ package dev.rubidium.subscriptiontool.service.impl; +import dev.rubidium.subscriptiontool.model.Subscriber; import dev.rubidium.subscriptiontool.model.UnsentMail; import dev.rubidium.subscriptiontool.persistence.entity.Mail; import dev.rubidium.subscriptiontool.persistence.entity.Subscription; @@ -10,6 +11,7 @@ import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -39,10 +41,8 @@ public class PersistenceServiceImpl implements PersistenceService { subscription.setRegistration(Timestamp.valueOf(LocalDateTime.now())); subscriptionRepository.saveAndFlush(subscription); - Long subscriptionId = subscriptionRepository.findByMail(email).getId(); - Mail mail = new Mail(); - mail.setSubscription(subscriptionId); + mail.setSubscription(subscription); mail.setSent(Boolean.FALSE); mail.setCreation(Timestamp.valueOf(LocalDateTime.now())); mailRepository.saveAndFlush(mail); @@ -53,45 +53,73 @@ public class PersistenceServiceImpl implements PersistenceService { return false; } + @Override + public boolean deleteSubscription(Long id) { + Subscription subscription = subscriptionRepository.findById(id).orElse(null); + boolean result = deleteSubscription(subscription); + if (!result) { + logger.warn("No subscription found for id {}", id); + } + return result; + } + @Override public boolean deleteSubscription(String email) { Subscription subscription = subscriptionRepository.findByMail(email); + boolean result = deleteSubscription(subscription); + if (!result) { + logger.warn("No subscription found for email {}", email); + } + return result; + } + + private boolean deleteSubscription(Subscription subscription) { if (subscription != null) { - Mail mail = mailRepository.findBySubscription(subscription.getId()); - if (mail != null) { - mailRepository.deleteById(mail.getId()); + if (subscription.getRelationMail() != null) { + mailRepository.deleteById(subscription.getRelationMail().getId()); } subscriptionRepository.deleteById(subscription.getId()); return true; } - logger.warn("No subscription found for email {}", email); return false; } @Override - public boolean updateSubscription(String code) { - Subscription subscription = subscriptionRepository.findByCode(code); - if (subscription != null) { - if (subscription.getConfirmed()) { - logger.warn("Subscription {} already confirmed", subscription.getId()); - } else { - subscription.setConfirmed(Boolean.TRUE); - subscription.setConfirmation(Timestamp.valueOf(LocalDateTime.now())); - subscriptionRepository.saveAndFlush(subscription); - } - return true; + public boolean confirmSubscription(Long id) { + Optional<Subscription> subscription = subscriptionRepository.findById(id); + if (subscription.isPresent()) { + return confirmSubscription(subscription.get()); } - logger.warn("No subscription found for code {}", code); + logger.warn("No subscription found for id {}", id); return false; } + @Override + public boolean confirmSubscription(String code) { + Subscription subscription = subscriptionRepository.findByCode(code); + if (subscription == null) { + logger.warn("No subscription found for code {}", code); + return false; + } + return confirmSubscription(subscription); + } + + private boolean confirmSubscription(Subscription subscription) { + if (subscription.getConfirmed()) { + logger.warn("Subscription {} already confirmed", subscription.getId()); + return false; + } + subscription.setConfirmed(Boolean.TRUE); + subscription.setConfirmation(Timestamp.valueOf(LocalDateTime.now())); + subscriptionRepository.saveAndFlush(subscription); + return true; + } + @Override public List<UnsentMail> getUnsentMails() { var mails = new ArrayList<UnsentMail>(); - mailRepository.findUnsentMails().forEach(mail -> - subscriptionRepository.findById(mail.getSubscription()).ifPresent(subscription -> - mails.add(new UnsentMail(mail.getId(), subscription.getMail(), - subscription.getCode())))); + mailRepository.findUnsentMails().forEach(mail -> mails.add(new UnsentMail(mail.getId(), + mail.getSubscription().getMail(), mail.getSubscription().getCode()))); return mails; } @@ -103,4 +131,30 @@ public class PersistenceServiceImpl implements PersistenceService { mailRepository.saveAndFlush(mail); }); } + + @Override + public List<Subscriber> getSubscribers() { + var result = new ArrayList<Subscriber>(); + subscriptionRepository.findAllSubscriptions().forEach(subscription -> { + Boolean doiMailStatus = Boolean.FALSE; + LocalDateTime doiMailTime = null; + if (subscription.getRelationMail() != null) { + doiMailStatus = subscription.getRelationMail().getSent(); + if (subscription.getRelationMail().getCompletion() != null) { + doiMailTime = subscription.getRelationMail().getCompletion().toLocalDateTime(); + } + } + LocalDateTime confirmation = + subscription.getConfirmation() == null ? null : + subscription.getConfirmation().toLocalDateTime(); + result.add(new Subscriber(subscription.getId(), + subscription.getMail(), + subscription.getConfirmed(), + subscription.getRegistration().toLocalDateTime(), + confirmation, + doiMailStatus, + doiMailTime)); + }); + return result; + } } diff --git a/src/main/java/dev/rubidium/subscriptiontool/service/impl/SubscriptionServiceImpl.java b/src/main/java/dev/rubidium/subscriptiontool/service/impl/SubscriptionServiceImpl.java index 856ea18..9fe52bc 100644 --- a/src/main/java/dev/rubidium/subscriptiontool/service/impl/SubscriptionServiceImpl.java +++ b/src/main/java/dev/rubidium/subscriptiontool/service/impl/SubscriptionServiceImpl.java @@ -38,6 +38,6 @@ public class SubscriptionServiceImpl implements SubscriptionService { @Override public boolean confirmSubscription(String code) { logger.info("Confirming a subscription at {}", LocalDateTime.now()); - return persistenceService.updateSubscription(code); + return persistenceService.confirmSubscription(code); } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b875956..cc8b1bc 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,6 +8,8 @@ info.app-license=MIT License spring.datasource.url=jdbc:postgresql://localhost:5000/subscriptiontool spring.datasource.username=USERNAME spring.datasource.password=PASSWORD +spring.datasource.hikari.minimum-idle=3 +spring.datasource.hikari.maximum-pool-size=6 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.jpa.properties.hibernate.default_schema=public diff --git a/src/main/resources/templates/Manage.html b/src/main/resources/templates/Manage.html new file mode 100644 index 0000000..dd27564 --- /dev/null +++ b/src/main/resources/templates/Manage.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html xmlns:th="http://www.thymeleaf.org" lang="en"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link href="/bootstrap.min.css" rel="stylesheet"> + <title th:text="${translation.title()}"/> + <script> + function copyTo() { + var text = document.getElementById("mailto").textContent; + navigator.clipboard.writeText(text); + } + </script> +</head> +<body> +<div class="container-fluid"> + <h1 class="text-center fs-3"><span th:text="${translation.title()}"/> <span th:text="${translation.manage()}"/></h1> + + <table class="table table-striped"> + <thead> + <tr> + <th scope="col" th:text="${translation.tableMail()}"/> + <th scope="col" th:text="${translation.tableStatus()}"/> + <th scope="col" th:text="${translation.tableRegistered()}"/> + <th scope="col" th:text="${translation.tableConfirmed()}"/> + <th scope="col" th:text="${translation.tableDoiMail()}"/> + <th scope="col" colspan="2" th:text="${translation.tableActions()}"/> + </tr> + </thead> + <tbody> + <tr th:each="subscriber : ${subscribers}"> + <td><span th:text="${subscriber.mail}"/></td> + + <td th:if="${subscriber.confirmed == true}"><span th:text="${translation.active()}"/></td> + <td th:unless="${subscriber.confirmed == true}"><span th:text="${translation.inactive()}"/></td> + + <td><span th:text="${#temporals.format(subscriber.registration)}"/></td> + + <td th:if="${subscriber.confirmation == null}">—</td> + <td th:unless="${subscriber.confirmation == null}"><span th:text="${#temporals.format(subscriber.confirmation)}"/></td> + + <td th:if="${subscriber.doiMailTime() == null}">—</td> + <td th:unless="${subscriber.doiMailTime() == null}"><span th:text="${#temporals.format(subscriber.doiMailTime())}"/></td> + + <td> + <button type="button" class="btn btn-secondary btn-sm" disabled th:if="${subscriber.confirmed == true}" th:text="${translation.activate()}"/> + <form action="#" th:action="@{/manage}" method="post" th:unless="${subscriber.confirmed == true}"> + <input type="hidden" name="action" th:value="${T(dev.rubidium.subscriptiontool.model.Action).ACTIVATE}"/> + <input type="hidden" name="subscription" th:value="${subscriber.id()}"/> + <input type="submit" class="btn btn-primary btn-sm" th:value="${translation.activate()}"/> + </form> + </td> + <td> + <form action="#" th:action="@{/manage}" method="post"> + <input type="hidden" name="action" th:value="${T(dev.rubidium.subscriptiontool.model.Action).DELETE}"/> + <input type="hidden" name="subscription" th:value="${subscriber.id()}"/> + <input type="submit" class="btn btn-danger btn-sm" th:value="${translation.delete()}"/> + </form> + </td> + </tr> + </tbody> + </table> + + <div class="py-3"> + <hr/> + </div> + + <div class="py-3"> + <pre class="bg-secondary text-white text-wrap lh-lg" id="mailto" th:text="${mails}"/> + <p><button class="btn btn-primary btn-sm" onclick="copyTo()" th:text="${translation.copy()}"/></p> + </div> + +</div> +</body> +</html> diff --git a/src/main/resources/translation.properties b/src/main/resources/translation.properties index 0ca249f..f9acb32 100644 --- a/src/main/resources/translation.properties +++ b/src/main/resources/translation.properties @@ -15,4 +15,16 @@ translation.back=Back translation.mailSubject=Please confirm your subscription translation.mailText=Hi,\n\nplease confirm your subscription by clicking the following link:\n%s\n\nBest regards translation.error=An error occurred -translation.home=Home \ No newline at end of file +translation.home=Home +translation.manage=Management +translation.tableMail=Mail +translation.tableStatus=Status +translation.tableRegistered=Registered +translation.tableConfirmed=Confirmed +translation.tableDoiMail=DOI Mail +translation.tableActions=Actions +translation.active=active +translation.inactive=inactive +translation.activate=activate +translation.delete=delete +translation.copy=copy to clipboard