diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 9b67254a36d0a04504b54141f62f5109282518ab..af6fe82aefdabb3623c09800bafdb1e930797ef4 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -15,6 +15,7 @@ services: working_dir: '/app' volumes: - .:/app + - /home/s3rius/.m2:/root/.m2 networks: - test_corporate_network diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt index 4c78ce5f68b1db0ceb85b7957e80c711eb257534..e40ad46da0a945f79eb4850bd19f225df1f7f8aa 100644 --- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt +++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt @@ -9,7 +9,6 @@ import org.springframework.ui.Model import org.springframework.web.bind.annotation.* import org.springframework.web.servlet.view.RedirectView import java.util.UUID.fromString -import java.util.UUID.randomUUID @Controller @RequestMapping("/cinemas") @@ -22,7 +21,8 @@ class CinemasController { @GetMapping("/list") fun getCinemasBrowsePage(model: Model): String? { - model.addAttribute("cinemas", cinemaService.findAll()) + val items = getAllItems(cinemaService, publisher) + model.addAttribute("cinemas", items) return "cinemas/list" } diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/SubscribersController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/SubscribersController.kt new file mode 100644 index 0000000000000000000000000000000000000000..6974267b9402aeb68a6dac26ea51a983861091ad --- /dev/null +++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/SubscribersController.kt @@ -0,0 +1,63 @@ +package com.s3ai.corporate_app2.controllers + +import com.s3ai.corporate_app2.jms.persistance.* +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Controller +import org.springframework.ui.Model +import org.springframework.web.bind.annotation.* +import org.springframework.web.servlet.view.RedirectView +import java.util.* + +class FilterForm { + var actions: MutableList<JMSEntityAction> = mutableListOf() +} + +@Controller +@RequestMapping("/subscription") +class SubscribersController { + + @Autowired + lateinit var subscriberRepository: SubscribersRepository + + @Autowired + lateinit var subTypeRepo: SubscriptionTypeRepository + + @GetMapping("/subscribe") + fun getSubscribePage(model: Model): String? { + val subscriber: Subscriber? + subscriber = Subscriber() + subscriber.id = UUID.randomUUID() + model.addAttribute("subscriber", subscriber) + model.addAttribute("types", JMSEntityAction.values()) + return "subscription/subscribe" + } + + @GetMapping("/unsubscribe") + fun getUnsubscribePage(model: Model): String { + return "subscription/unsubscribe" + } + + + @PostMapping("/subscribe") + fun addSubscriber(@ModelAttribute sub: Subscriber, @ModelAttribute(name = "actions") actionsForm: FilterForm, model: Model): RedirectView { + if (actionsForm.actions.size < 1) return RedirectView("/") + val subscriber = subscriberRepository.save(sub) + for (action in actionsForm.actions) { + val newType = SubscriptionType() + newType.type = action + newType.subscriber = subscriber + subTypeRepo.save(newType) + } + return RedirectView("/") + } + + @PostMapping("/unsubscribe") + fun unsubscribeByEmail(@RequestParam(name = "email", required = true) email: String, model: Model): RedirectView { + val user = subscriberRepository.findSubscriberByEmail(email) + if (user.isPresent) { + subscriberRepository.delete(user.get()) + } + return RedirectView("/") + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt index 234a961403183f206e7f80bd6fdda05e2be15d55..dbe5e808384f2b2210b04904302d31d98d35928c 100644 --- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt +++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt @@ -26,7 +26,8 @@ class TicketsController { @GetMapping("/list") fun getTicketsBrowsePage(model: Model): String? { - model.addAttribute("tickets", ticketService.findAll()) + val items = getAllItems(ticketService, publisher) + model.addAttribute("tickets", items) return "tickets/list" } diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt index 4ba236218ab05b14fa8da59205c96a8fbbc394a4..6c09ff72a7bef7b33c937da6d311bc6e4f1d3ad6 100644 --- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt +++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt @@ -21,7 +21,8 @@ class UsersController { @GetMapping("/list") fun getUsersBrowsePage(model: Model): String? { - model.addAttribute("users", userService.findAll()) + val items = getAllItems(userService, publisher) + model.addAttribute("users", items) return "users/list" } diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt index a57aa21550abcbf133dce7a352f78100cf1783d5..f08a73a77c534d19c6978ea5b778ddda4b1c06aa 100644 --- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt +++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt @@ -58,12 +58,9 @@ fun <T : Any> getAllItems(jpaService: CinemaServices<T>, publisher: JMSPublisher fun <T : Any> updateItem(jpaService: CinemaServices<T>, item: T, item_id: UUID?, publisher: JMSPublisher) { var action = JMSEntityAction.UPDATE - var description = "Item id: $item_id." val updatedItem = jpaService.save(item) - if (null == item_id) { - action = JMSEntityAction.CREATE - description = "New item data: $updatedItem" - } + val description = "New item data: $updatedItem" + if (null == item_id) action = JMSEntityAction.CREATE publishMessage(publisher, jpaService.itemName(), action, description) } diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/SubscriptionApiController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/SubscriptionApiController.kt deleted file mode 100644 index 10d5cccb43ba1aa843092f9130d387af98582432..0000000000000000000000000000000000000000 --- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/SubscriptionApiController.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.s3ai.corporate_app2.controllers.rest - -import com.s3ai.corporate_app2.jms.JMSPublisher -import com.s3ai.corporate_app2.jms.persistance.SubscribersRepository -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.web.bind.annotation.DeleteMapping -import org.springframework.web.bind.annotation.RequestParam -import org.springframework.web.bind.annotation.RestController -import javax.servlet.http.HttpServletResponse - -@RestController -class SubscriptionApiController { - - @Autowired - lateinit var service: SubscribersRepository - - @Autowired - lateinit var publisher: JMSPublisher - - @DeleteMapping("/delete") - fun deleteTicket(@RequestParam(name = "id", required = true) id: Long, response: HttpServletResponse): String { - val item = service.findById(id).orElse(null) - if (null != item) { - service.delete(item) - return "Deleted" - } - response.status = HttpServletResponse.SC_NOT_FOUND - return "Subscriber cannot be found" - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/s3ai/corporate_app2/jms/JmsConsumer.kt b/src/main/kotlin/com/s3ai/corporate_app2/jms/JmsConsumer.kt index 60b567fb744d71259ff9e1cf1cf0f9b1852a96aa..a9b3b8a5218432d8025d952f340a4cb6e10b9e76 100644 --- a/src/main/kotlin/com/s3ai/corporate_app2/jms/JmsConsumer.kt +++ b/src/main/kotlin/com/s3ai/corporate_app2/jms/JmsConsumer.kt @@ -3,8 +3,8 @@ package com.s3ai.corporate_app2.jms import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import com.s3ai.corporate_app2.jms.persistance.JMSAction -import com.s3ai.corporate_app2.jms.persistance.JMSActionService -import com.s3ai.corporate_app2.jms.persistance.JMSEntityAction +import com.s3ai.corporate_app2.jms.persistance.JMSActionRepository +import com.s3ai.corporate_app2.jms.persistance.SubscriptionTypeRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value import org.springframework.jms.annotation.JmsListener @@ -17,21 +17,21 @@ import org.springframework.stereotype.Component @Component class JmsConsumer { - @Value("\${target.addresses}") - private lateinit var targetUsers: Array<String> - @Value("\${spring.mail.username}") private lateinit var sourceUser: String @Autowired - private lateinit var service: JMSActionService + private lateinit var jmsActionService: JMSActionRepository @Autowired private lateinit var sender: JavaMailSender + @Autowired + private lateinit var subTypeRepo: SubscriptionTypeRepository + private final val mapper = jacksonObjectMapper() - fun sendEmail(action: JMSAction): Boolean { + fun sendEmail(action: JMSAction, targetUsers: Array<String>): Boolean { val message = sender.createMimeMessage() val helper = MimeMessageHelper(message) try { @@ -48,13 +48,16 @@ class JmsConsumer { } + fun notifySubscribers(action: JMSAction) { + val users = subTypeRepo.findSubscriptionTypeByType(action.actionJMS) + val emails = users.map { u -> u.subscriber.email!! }.distinct().toTypedArray() + if (emails.isNotEmpty()) sendEmail(action, emails) + } + @JmsListener(destination = "cinemas.queue") fun consume(action_text: String) { val action: JMSAction = mapper.readValue(action_text) - println(action.toString()) - if (action.actionJMS == JMSEntityAction.DELETE) { - action.delivered = sendEmail(action) - } - service.save(action) + jmsActionService.save(action) + notifySubscribers(action) } } \ No newline at end of file diff --git a/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/entities.kt b/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/entities.kt index 8e362dbeac18515be3734d13dc3a0b242c7f4e04..2b411a5a4da4a9ec5d4be019a117f1be28980bc5 100644 --- a/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/entities.kt +++ b/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/entities.kt @@ -1,6 +1,8 @@ package com.s3ai.corporate_app2.jms.persistance import com.fasterxml.jackson.annotation.JsonAutoDetect +import org.hibernate.annotations.OnDelete +import org.hibernate.annotations.OnDeleteAction import java.util.* import javax.persistence.* @@ -24,7 +26,7 @@ class JMSAction { lateinit var actionJMS: JMSEntityAction @Column(name = "entity") lateinit var entity: String - @Column(name = "description") + @Column(name = "description", columnDefinition = "TEXT") lateinit var actionDescription: String @Column(name = "delivered") var delivered: Boolean = true @@ -39,15 +41,12 @@ class JMSAction { class Subscriber { @Id @GeneratedValue(strategy = GenerationType.AUTO) - var id: Long? = null + var id: UUID? = null @Column(name = "email") - lateinit var email: String + var email: String? = null - @ManyToMany - @JoinTable(name = "sub_type_mapping", - joinColumns = [JoinColumn(name = "subscriber_id", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "subscription_type_id", referencedColumnName = "id")]) + @OneToMany var types: List<SubscriptionType> = mutableListOf() } @@ -62,6 +61,7 @@ class SubscriptionType { @Column(length = 8, name = "type") lateinit var type: JMSEntityAction - @ManyToMany(mappedBy = "types") - var subscribers: List<Subscriber> = mutableListOf() + @OneToOne + @OnDelete(action = OnDeleteAction.CASCADE) + lateinit var subscriber: Subscriber } \ No newline at end of file diff --git a/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/repositories.kt b/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/repositories.kt index 2117af34fd36e5d2467e2e00bb889f3e351f227b..d33f03567beaa9979924620d23ba187a21152d81 100644 --- a/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/repositories.kt +++ b/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/repositories.kt @@ -13,12 +13,13 @@ interface JMSActionRepository : JpaRepository<JMSAction, UUID> { } @Repository -interface SubscribersRepository : JpaRepository<Subscriber, Long> { - +interface SubscribersRepository : JpaRepository<Subscriber, UUID> { + @Query("FROM Subscriber WHERE email = :email") + fun findSubscriberByEmail(@Param("email") email: String): Optional<Subscriber> } @Repository interface SubscriptionTypeRepository : JpaRepository<SubscriptionType, Long> { @Query("FROM SubscriptionType WHERE type = :type") - fun selectByType(@Param("type") type: JMSEntityAction): List<SubscriptionType> + fun findSubscriptionTypeByType(@Param("type") type: JMSEntityAction): List<SubscriptionType> } \ No newline at end of file diff --git a/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/services.kt b/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/services.kt deleted file mode 100644 index 7683ad43dd0153f465bfd875fab8d3beaebfe44b..0000000000000000000000000000000000000000 --- a/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/services.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.s3ai.corporate_app2.jms.persistance - -import org.springframework.stereotype.Service - -@Service -class JMSActionService(private val jmsActionRepository: JMSActionRepository) { - fun save(item: JMSAction): JMSAction = jmsActionRepository.save(item) -} - diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 594c24815133ebe6ae5e084cb5543585442ff16b..174500c59db2965eb5978115e1fd81579a9e8390 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -28,6 +28,4 @@ spring.mail.properties.mail.smtp.auth = true spring.mail.properties.mail.smtp.socketFactory.port = 465 spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory spring.mail.properties.mail.smtp.socketFactory.fallback = false -spring.mail.properties.mail.smtp.ssl.enable=false - -target.addresses=win10@list.ru,win10@mail.ru \ No newline at end of file +spring.mail.properties.mail.smtp.ssl.enable=false \ No newline at end of file diff --git a/src/main/resources/static/css/index.css b/src/main/resources/static/css/index.css index debb6d5093a78a712339848412fe77c5f4ad9378..2b1e279bc8a5e9ae24160b4489e0a8dcbc12ba5a 100644 --- a/src/main/resources/static/css/index.css +++ b/src/main/resources/static/css/index.css @@ -1 +1 @@ -.index-gradient{background:linear-gradient(to bottom, #283048 0%, #859398 100%)}.projects-section{padding:10rem 0}.projects-section .featured-text{padding:2rem}@media(min-width: 992px){.projects-section .featured-text{padding:0 0 0 2rem;border-left:.5rem solid #64a19d}}.projects-section .project-text{padding:3rem;font-size:90%}@media(min-width: 992px){.projects-section .project-text{padding:5rem}.projects-section .project-text hr{border-color:#64a19d;border-width:.25rem;width:30%}}.masthead{object-fit:cover !important;text-align:center !important;background-repeat:no-repeat !important;background-attachment:fixed !important;background-position:center !important}.masthead .white{color:#fff}.hide-y{overflow-y:hidden}.landing-info-row{height:100px}.landing-info-row .landing-info-image{height:100px;object-fit:cover;width:100%;text-align:center;background-repeat:no-repeat;background-attachment:fixed;background-position:center}.masthead{position:relative;width:100%;height:auto;min-height:35rem;padding:15rem 0;background-position:center;background-repeat:no-repeat;background-attachment:scroll;background-size:cover}.masthead h1{font-family:"Varela Round";font-size:2.5rem;line-height:2.5rem;letter-spacing:.8rem;background:-webkit-linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0));-webkit-text-fill-color:transparent;-webkit-background-clip:text}.masthead h2{max-width:20rem;font-size:1rem}@media(min-width: 768px){.masthead h1{font-size:4rem;line-height:4rem}}@media(min-width: 992px){.masthead{height:100vh;padding:0}.masthead h1{font-size:6.5rem;line-height:6.5rem;letter-spacing:.8rem}.masthead h2{max-width:30rem;font-size:1.25rem}}.contact-section{padding:5rem 0 0}.contact-section .card{border:0;border-bottom:.25rem solid #64a19d}.contact-section .card h4{font-size:.8rem;font-family:"Varela Round";text-transform:uppercase;letter-spacing:.15rem}.contact-section .card hr{border-color:#64a19d;border-width:.25rem;width:3rem}.contact-section .social{margin-top:5rem}.contact-section .social a{text-align:center;height:3rem;width:3rem;background:rgba(255,255,255,.1);border-radius:100%;line-height:3rem;color:rgba(255,255,255,.3)}.contact-section .social a:hover{color:rgba(255,255,255,.5)}.contact-section .social a:active{color:#fff}.btn{box-shadow:0 .1875rem .1875rem 0 rgba(0,0,0,.1) !important;padding:1.25rem 2rem;font-family:"Varela Round";font-size:80%;text-transform:uppercase;letter-spacing:.15rem;border:0}.btn-interact{background-color:#64a19d}.btn-interact:hover{background-color:#4f837f}.btn-interact:focus{background-color:#4f837f;color:#fff}.btn-interact:active{background-color:#467370 !important}.about-section{padding-top:10rem}.about-section p{margin-bottom:5rem}/*# sourceMappingURL=index.css.map */ +.index-gradient{background:linear-gradient(to bottom, #283048 0%, #859398 100%)}.projects-section{padding:10rem 0}.projects-section .featured-text{padding:2rem}@media(min-width: 992px){.projects-section .featured-text{padding:0 0 0 2rem;border-left:.5rem solid #64a19d}}.projects-section .project-text{padding:3rem;font-size:90%}@media(min-width: 992px){.projects-section .project-text{padding:5rem}.projects-section .project-text hr{border-color:#64a19d;border-width:.25rem;width:30%}}.masthead{object-fit:cover !important;text-align:center !important;background-repeat:no-repeat !important;background-attachment:fixed !important;background-position:center !important}.masthead .white{color:#fff}.hide-y{overflow-y:hidden}.landing-info-row{height:100px}.landing-info-row .landing-info-image{height:100px;object-fit:cover;width:100%;text-align:center;background-repeat:no-repeat;background-attachment:fixed;background-position:center}.masthead{position:relative;width:100%;height:auto;min-height:35rem;padding:15rem 0;background-position:center;background-repeat:no-repeat;background-attachment:scroll;background-size:cover}.masthead h1{font-family:"Varela Round";font-size:2.5rem;line-height:2.5rem;letter-spacing:.8rem;background:-webkit-linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0));-webkit-text-fill-color:transparent;-webkit-background-clip:text}.masthead h2{max-width:20rem;font-size:1rem}@media(min-width: 768px){.masthead h1{font-size:4rem;line-height:4rem}}@media(min-width: 992px){.masthead{height:100vh;padding:0}.masthead h1{font-size:6.5rem;line-height:6.5rem;letter-spacing:.8rem}.masthead h2{max-width:30rem;font-size:1.25rem}}.contact-section{padding:5rem 0 0}.contact-section .card{border:0;border-bottom:.25rem solid #64a19d}.contact-section .card h4{font-size:.8rem;font-family:"Varela Round";text-transform:uppercase;letter-spacing:.15rem}.contact-section .card hr{border-color:#64a19d;border-width:.25rem;width:3rem}.contact-section .social{margin-top:5rem}.contact-section .social a{text-align:center;height:3rem;width:3rem;background:rgba(255,255,255,.1);border-radius:100%;line-height:3rem;padding-top:1rem;color:rgba(255,255,255,.3)}.contact-section .social a:hover{color:rgba(255,255,255,.5)}.contact-section .social a:active{color:#fff}.btn{box-shadow:0 .1875rem .1875rem 0 rgba(0,0,0,.1) !important;padding:1.25rem 2rem;font-family:"Varela Round";font-size:80%;text-transform:uppercase;letter-spacing:.15rem;border:0}.btn-interact{background-color:#64a19d}.btn-interact:hover{background-color:#4f837f}.btn-interact:focus{background-color:#4f837f;color:#fff}.btn-interact:active{background-color:#467370 !important}.about-section{padding-top:10rem}.about-section p{margin-bottom:5rem}/*# sourceMappingURL=index.css.map */ diff --git a/src/main/resources/static/css/index.css.map b/src/main/resources/static/css/index.css.map index ac5ec28cec5c7830247919fbb40389de5b05cde7..9de368993141b11db8c8f0765e5adb8c455ce2b7 100644 --- a/src/main/resources/static/css/index.css.map +++ b/src/main/resources/static/css/index.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/index.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA,gBACE,gEAGF,kBACE,gBAEA,iCACE,aACA,yBAFF,iCAGI,mBACA,iCAIJ,gCACE,aACA,cACA,yBAHF,gCAII,aACA,mCACE,aCXE,QDYF,oBACA,WAOR,UACE,4BACA,6BACA,uCACA,uCACA,sCAEA,iBACE,WAKJ,QACE,kBAGF,kBACE,aAEA,sCACE,aACA,iBACA,WACA,kBACA,4BACA,4BACA,2BAIJ,UACE,kBACA,WACA,YACA,iBACA,gBACA,2BACA,4BACA,6BACA,sBAEA,aACE,2BACA,iBACA,mBACA,qBACA,qFACA,oCACA,6BAGF,aACE,gBACA,eAGF,yBACE,aACE,eACA,kBAGJ,yBAhCF,UAiCI,aACA,UACA,aACE,iBACA,mBACA,qBAEF,aACE,gBACA,mBAKN,iBACE,iBAEA,uBACE,SACA,mCAEA,0BACE,gBACA,2BACA,yBACA,sBAGF,0BACE,aCjHI,QDkHJ,oBACA,WAIJ,yBACE,gBAEA,2BACE,kBACA,YACA,WACA,gCACA,mBACA,iBACA,2BAEA,iCACE,2BAGF,kCACE,MCpJA,KD0JR,KACE,2DACA,qBACA,2BACA,cACA,yBACA,sBACA,SAGF,cACE,iBCzJQ,QD2JR,oBACE,yBAGF,oBACE,yBACA,WAGF,qBACE,oCAIJ,eACE,kBAEA,iBACE","file":"index.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/index.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA,gBACE,gEAGF,kBACE,gBAEA,iCACE,aACA,yBAFF,iCAGI,mBACA,iCAIJ,gCACE,aACA,cACA,yBAHF,gCAII,aACA,mCACE,aCXE,QDYF,oBACA,WAOR,UACE,4BACA,6BACA,uCACA,uCACA,sCAEA,iBACE,WAKJ,QACE,kBAGF,kBACE,aAEA,sCACE,aACA,iBACA,WACA,kBACA,4BACA,4BACA,2BAIJ,UACE,kBACA,WACA,YACA,iBACA,gBACA,2BACA,4BACA,6BACA,sBAEA,aACE,2BACA,iBACA,mBACA,qBACA,qFACA,oCACA,6BAGF,aACE,gBACA,eAGF,yBACE,aACE,eACA,kBAGJ,yBAhCF,UAiCI,aACA,UACA,aACE,iBACA,mBACA,qBAEF,aACE,gBACA,mBAKN,iBACE,iBAEA,uBACE,SACA,mCAEA,0BACE,gBACA,2BACA,yBACA,sBAGF,0BACE,aCjHI,QDkHJ,oBACA,WAIJ,yBACE,gBAEA,2BACE,kBACA,YACA,WACA,gCACA,mBACA,iBACA,iBACA,2BAEA,iCACE,2BAGF,kCACE,MCrJA,KD2JR,KACE,2DACA,qBACA,2BACA,cACA,yBACA,sBACA,SAGF,cACE,iBC1JQ,QD4JR,oBACE,yBAGF,oBACE,yBACA,WAGF,qBACE,oCAIJ,eACE,kBAEA,iBACE","file":"index.css"} \ No newline at end of file diff --git a/src/main/resources/static/css/subscribes.css b/src/main/resources/static/css/subscribes.css new file mode 100644 index 0000000000000000000000000000000000000000..bddef40a2197a7b43b64c0b9862bb535176e25a8 --- /dev/null +++ b/src/main/resources/static/css/subscribes.css @@ -0,0 +1 @@ +.editing .container{height:100%;display:flex;justify-content:center;align-items:center}.table-padding{padding-top:56px}/*# sourceMappingURL=subscribes.css.map */ diff --git a/src/main/resources/static/css/subscribes.css.map b/src/main/resources/static/css/subscribes.css.map new file mode 100644 index 0000000000000000000000000000000000000000..ca13f09148a7e341d71224b04abdbe028a09bfca --- /dev/null +++ b/src/main/resources/static/css/subscribes.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../scss/cinemas.scss"],"names":[],"mappings":"AAEE,oBACE,YACA,aACA,uBACA,mBAIJ,eACE","file":"subscribes.css"} \ No newline at end of file diff --git a/src/main/resources/static/images/email.jpg b/src/main/resources/static/images/email.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1c0b5ad82dd76e3e7c7ad4c3f1e1e7ff8a2dcfa0 Binary files /dev/null and b/src/main/resources/static/images/email.jpg differ diff --git a/src/main/resources/static/scss/index.scss b/src/main/resources/static/scss/index.scss index 9cd61da7fde0cfeb33ccd958c7eafeecebf4dd4a..eca5788b5a44fa6f3c2588a6fe73a32fce11d3e4 100644 --- a/src/main/resources/static/scss/index.scss +++ b/src/main/resources/static/scss/index.scss @@ -139,6 +139,7 @@ background: fade-out($white, 0.9); border-radius: 100%; line-height: 3rem; + padding-top: 1rem; color: fade-out($white, 0.7); &:hover { diff --git a/src/main/resources/static/scss/subscribes.scss b/src/main/resources/static/scss/subscribes.scss new file mode 100644 index 0000000000000000000000000000000000000000..5743cc609b56787d8ce5ee9d9d10e56fbdeaf990 --- /dev/null +++ b/src/main/resources/static/scss/subscribes.scss @@ -0,0 +1 @@ +@import "cinemas"; \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 81d4dfdba74410001268d4b148a786847b4ae90a..f61ebdb980d0fd115da98fa7d81fda45b34bd5cd 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -29,7 +29,8 @@ <h2 class="text-white mb-4">Built for cinema business. Built with passion for movies.</h2> <p class="text-white-50"> We are glad to provide you the best possible instrument to manage your cinema network. - Use it to control your cinemas, track tickets to movies, and gather precious data for your business. + Use it to control your cinemas, track tickets to movies, and gather precious data for your + business. System is established to be user-friendly and easy to get on. </p> </div> @@ -80,7 +81,7 @@ </div> <!-- Project Two Row --> - <div class="row justify-content-center hide-y no-gutters"> + <div class="row justify-content-center hide-y no-gutters mt-3"> <div class="col-lg-6"> <img class="pl-3 img-fluid landing-info-image" src="/images/landing_users.jpg" alt=""> @@ -91,7 +92,8 @@ <div class="project-text w-100 my-auto text-center text-lg-left"> <h4 class="text-white">User management</h4> <p class="mb-0 text-white-50"> - Build up your customers database. Track popularity of certain titles and places basing + Build up your customers database. Track popularity of certain titles and places + basing on precious personal data of innocent people, and enjoy the world we live in. </p> <hr class="d-none d-lg-block mb-0 mr-0"> @@ -101,12 +103,36 @@ </div> </div> + <div class="row justify-content-center no-gutters mb-5 mt-3 mb-lg-0"> + <div class="col-lg-6"> + <img class="img-fluid landing-info-image pr-3" + src="/images/email.jpg" alt=""> + </div> + <div class="col-lg-6 order-lg-first"> + <div class="bg-black text-center h-100 project"> + <div class="d-flex h-100"> + <div class="project-text w-100 my-auto text-center text-lg-right"> + <h4 class="text-white">Updates subscription</h4> + <p class="mb-0 text-white-50"> + Stay up to date with the latest site updates. + Track your database changes with only your email. + All updates will be instantly sent to you. </p> + </div> + </div> + </div> + </div> + </div> </div> </section> </div> - +<section class="subscribe-section pt-3 bg-dark"> + <div class="row justify-content-center"> + <a class="btn btn-light mr-2" href="/subscription/subscribe">Subscribe</a> + <a class="btn btn-light ml-2" href="/subscription/unsubscribe">Unsubscribe</a> + </div> +</section> <!-- Contact Section --> -<section class="contact-section mt-3 bg-black"> +<section class="contact-section pt-3 bg-dark"> <div class="container"> <div class="row"> @@ -158,7 +184,7 @@ <a href="#" class="mx-2"> <i class="fab fa-vk"></i> </a> - <a href="https://gitlab.le-memese.com/s3rius/corporative_systems" class="mx-2"> + <a href="https://gitlab.le-memese.com/s3rius/corporative_systems2" class="mx-2"> <i class="fab fa-gitlab"></i> </a> </div> @@ -167,7 +193,7 @@ </section> <!-- Footer --> -<footer class="bg-black small text-center text-black-50"> +<footer class="bg-dark small text-center text-white-50"> <div class="container"> Copyright © le-memese 2019 </div> diff --git a/src/main/resources/templates/subscription/subscribe.html b/src/main/resources/templates/subscription/subscribe.html new file mode 100644 index 0000000000000000000000000000000000000000..a66314e387a21812513695d810f5a711f31abaec --- /dev/null +++ b/src/main/resources/templates/subscription/subscribe.html @@ -0,0 +1,61 @@ +<html xmlns:th="http://www.thymeleaf.org"> +<head> + <title>Edit cinema</title> + <head th:include="commons/imports"></head> + <link rel="stylesheet" href="/css/subscribes.css"> + <script src="/js/subscribe.js"></script> +</head> +<body class="themed-gradient"> + +<!-- Navigation --> +<body th:include="commons/header"></body> + +<div class="editing"> + <div class="container justify-content-center"> + + <form id="cinemaForm" class="d-flex justify-content-center" th:object="${subscriber}" method="post" + action="/subscription/subscribe"> + <fieldset> + + <legend> + <div class="text-center"><h2><b class="white">Subscribe to updates</b></h2></div> + </legend> + <br> + <input type="hidden" name="id" th:field="*{id}"> + + <div class="form-group"> + <div class="inputGroupContainer"> + <div class="input-group"> + <div class="input-group-prepend"> + <div class="input-group-text"><i class="fas fa-envelope"></i></div> + </div> + <input type="text" + class="form-control validate" + id="Email" + name="email" + placeholder="User's email" th:field="*{email}" required> + </div> + </div> + </div> + <div class="form-group"> + <div class="inputGroupContainer"> + <div class="input-group"> +<!-- <div class="input-group-prepend">--> +<!-- <div class="input-group-text"><i class="fas fa-chair"></i></div>--> +<!-- </div>--> + <div class="form-check" th:each="item: ${types}"> + <input type="checkbox" class="form-check-input" name="actions" th:value="${item}"> + <label th:text="${item.str}" class="text-white pr-2"></label> + </div> + </div> + </div> + </div> + <div class="justify-content-center"> + <button type="submit" class="btn btn-primary w-100"><i class="fas fa-check"></i>Submit</button> + </div> + </fieldset> + </form> + </div> +</div> +</body> +</html> diff --git a/src/main/resources/templates/subscription/unsubscribe.html b/src/main/resources/templates/subscription/unsubscribe.html new file mode 100644 index 0000000000000000000000000000000000000000..3e625399c170d1a15bf9e121a62e38cb0d92e35b --- /dev/null +++ b/src/main/resources/templates/subscription/unsubscribe.html @@ -0,0 +1,46 @@ +<html xmlns:th="http://www.thymeleaf.org"> +<head> + <title>Edit cinema</title> + <head th:include="commons/imports"></head> + <link rel="stylesheet" href="/css/subscribes.css"> + <script src="/js/subscribe.js"></script> +</head> +<body class="themed-gradient"> + +<!-- Navigation --> +<body th:include="commons/header"></body> + +<div class="editing"> + <div class="container justify-content-center"> + + <form id="cinemaForm" class="d-flex justify-content-center" method="post" + action="/subscription/unsubscribe"> + <fieldset> + + <legend> + <div class="text-center"><h2><b class="white">Subscribe to updates</b></h2></div> + </legend> + <br> + + <div class="form-group"> + <div class="inputGroupContainer"> + <div class="input-group"> + <div class="input-group-prepend"> + <div class="input-group-text"><i class="fas fa-envelope"></i></div> + </div> + <input type="text" + class="form-control validate" + id="Email" + placeholder="User's email" name="email" required> + </div> + </div> + </div> + <div class="justify-content-center"> + <button type="submit" class="btn btn-primary w-100"><i class="fas fa-check"></i>Submit</button> + </div> + </fieldset> + </form> + </div> +</div> +</body> +</html>