diff --git a/backend/src/main/java/ovh/herisson/Clyde/Repositories/NotificationRepository.java b/backend/src/main/java/ovh/herisson/Clyde/Repositories/NotificationRepository.java new file mode 100644 index 0000000..2d7ce13 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Repositories/NotificationRepository.java @@ -0,0 +1,8 @@ +package ovh.herisson.Clyde.Repositories; + +import org.springframework.data.repository.CrudRepository; + +import ovh.herisson.Clyde.Tables.Notification; + +interface NotificationRepository extends CrudRepository {} + diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/Msg/DiscussionService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/Msg/DiscussionService.java index 9a471da..93703ef 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/Msg/DiscussionService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/Msg/DiscussionService.java @@ -17,6 +17,8 @@ import org.springframework.stereotype.Service; import com.fasterxml.jackson.databind.util.JSONPObject; import ovh.herisson.Clyde.Repositories.Msg.DiscussionRepository; +import ovh.herisson.Clyde.Services.UserService; +import ovh.herisson.Clyde.Tables.Notification; import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.Msg.Discussion; import ovh.herisson.Clyde.Tables.Msg.Message; @@ -26,6 +28,8 @@ public class DiscussionService { @Autowired private DiscussionRepository discRepo; + @Autowired + private UserService userServ; public Discussion create(String name, User author){ return discRepo.save(new Discussion(name, author)); @@ -42,6 +46,9 @@ public class DiscussionService { * Create a message and link it to it's discussion */ public Discussion CreateMessage(Discussion disc, Message msg){ + for(User u: disc.getMembers()){ + userServ.Notify(u, new Notification("msg.notification.new", msg.getContent(), "/#/msg")); + } disc.addMessage(msg); return discRepo.save(disc); } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/NotificationService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/NotificationService.java new file mode 100644 index 0000000..db0f02e --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/NotificationService.java @@ -0,0 +1,9 @@ +package ovh.herisson.Clyde.Services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class NotificationService { + +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java index 72eabd5..e88e565 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java @@ -3,6 +3,7 @@ package ovh.herisson.Clyde.Services; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import ovh.herisson.Clyde.Repositories.UserRepository; +import ovh.herisson.Clyde.Tables.Notification; import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.User; import java.util.*; @@ -131,4 +132,10 @@ public class UserService { public void delete(User user) { userRepo.delete(user); } + + public void Notify(User u, Notification n){ + n.setUser(u); + u.getNotifications().add(n); + userRepo.save(u); + } } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/Notification.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/Notification.java index 36ddaa5..ce8f0ad 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/Notification.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/Notification.java @@ -4,12 +4,17 @@ import java.util.Date; import org.hibernate.annotations.CreationTimestamp; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import jakarta.annotation.Nullable; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; import lombok.Data; +import lombok.NoArgsConstructor; @Data +@NoArgsConstructor @Entity public class Notification { @@ -21,11 +26,11 @@ public class Notification { @Id private int id; - private String Subject; + private String subject; private String body; - private Status status; + private Status status = Status.Unread; private String link; @@ -34,4 +39,10 @@ public class Notification { @CreationTimestamp private Date creation; + + public Notification(String subject, @Nullable String body, @Nullable String link){ + this.subject = subject; + this.body = body; + this.link = link; + } } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java index be615f0..2e51bb9 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java @@ -2,15 +2,19 @@ package ovh.herisson.Clyde.Tables; import jakarta.persistence.*; import lombok.Data; +import lombok.NoArgsConstructor; import ovh.herisson.Clyde.Tables.Msg.Discussion; import ovh.herisson.Clyde.Tables.Msg.Message; import java.util.Date; import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnore; + @Entity @Table(name = "Users") +@NoArgsConstructor @Data public class User { @Id @@ -24,19 +28,23 @@ public class User { private String country; private Date birthDate; private String profilePictureUrl; - private ovh.herisson.Clyde.Tables.Role role; + private Role role; + @JsonIgnore private String password; - @OneToMany(mappedBy = "user") + @JsonIgnore + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) private List notifications; ////// Extension Messagerie ///// + @JsonIgnore @OneToMany(mappedBy = "author", cascade = CascadeType.ALL) private List msgs; - ///////////////////////////////// + @JsonIgnore @ManyToMany( mappedBy = "members" ) private List discussions; + ///////////////////////////////// public User(String lastName, String firstName, String email, String address, String country, Date birthDate, String profilePictureUrl, Role role, String password) diff --git a/frontend/public/i18n/EN.txt b/frontend/public/i18n/EN.txt index e79a8a1..ae5a660 100644 --- a/frontend/public/i18n/EN.txt +++ b/frontend/public/i18n/EN.txt @@ -52,3 +52,4 @@ Curriculum=curriculum Credits=Credits InscriptionService=I.S. faculty=Faculty +msg.notification.new=You have a new message diff --git a/frontend/public/i18n/FR.txt b/frontend/public/i18n/FR.txt index c5f3ebf..8fcfe72 100644 --- a/frontend/public/i18n/FR.txt +++ b/frontend/public/i18n/FR.txt @@ -52,3 +52,4 @@ Curriculum=Cursus Credits=Credits InscriptionService=S.I. faculty=Faculté +msg.notification.new=Vous avez un nouveau message! diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 6dcad67..82124fa 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -3,6 +3,7 @@ import { ref } from 'vue' import i18n, { setLang } from './i18n.js' import { isLogged } from '@/rest/Users.js' + import { notifications, fetchNotifications, archiveNotification } from '@/rest/notifications.js' import { appList, currentView } from '@/rest/apps.js' var prevURL; @@ -14,16 +15,20 @@ window.onhashchange = function() { } const Logged = ref(isLogged()); +if(Logged){ + fetchNotifications(); +} + window.addEventListener('hashchange', () => { if((location.hash === "#/home" && prevURL === "#/login") || (location.hash === "#/home" && prevURL === "#/profil")){ window.location.reload(); } }); const home=ref(i18n("app.home")) - const notifications=ref(i18n("app.notifications")) const settings=ref(i18n("app.settings")) const login=ref(i18n("app.login")) const active=ref(false) + const notification = ref(false) const apps = ref([]) @@ -46,11 +51,14 @@ window.addEventListener('hashchange', () => {
  • -
    +
  • - -
    +
    +
    +
      +
    • {{ i18n(notif.subject) }} - {{ notif.body }}
    • +
  • @@ -219,8 +227,6 @@ window.addEventListener('hashchange', () => { background-color: black; border-radius:6px; color:white; - transform: translate(0px ,1px); - } ul.vertical:hover { @@ -252,6 +258,15 @@ window.addEventListener('hashchange', () => { .clyde:hover{ content: url("./assets/angry_clyde.png") } + + #notification{ + position: absolute; + top: 61px; + right: 0; + background-color: white; + width: 300px; + height: 600px; + } diff --git a/frontend/src/rest/notifications.js b/frontend/src/rest/notifications.js new file mode 100644 index 0000000..d2b0ccb --- /dev/null +++ b/frontend/src/rest/notifications.js @@ -0,0 +1,12 @@ +import { ref } from 'vue' +import { restGet, restPost } from '@/rest/restConsumer.js' + +export const notifications = ref({}); + +export function fetchNotifications(){ + restGet("/notifications").then( e => notifications.value = e ); +} + +export function archiveNotification(id){ + restPost("/notifications/" + id).then( e => fetchNotifications() ); +}