Compare commits
4 Commits
7b0d76dae8
...
Schedule/m
Author | SHA1 | Date | |
---|---|---|---|
220c891c72 | |||
2b9493422d | |||
621f568ba2 | |||
972d08a54d |
1
Clyde
Submodule
1
Clyde
Submodule
Submodule Clyde added at bd27ffd3cb
@ -16,8 +16,6 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("org.projectlombok:lombok")
|
||||
annotationProcessor("org.projectlombok:lombok")
|
||||
implementation("org.springframework.boot:spring-boot-starter-jdbc")
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||
implementation("org.springframework.boot:spring-boot-starter-mail")
|
||||
@ -27,7 +25,6 @@ dependencies {
|
||||
implementation("com.kohlschutter.junixsocket:junixsocket-core:2.9.0")
|
||||
// implementation("org.springframework.session:spring-session-jdbc")
|
||||
developmentOnly("org.springframework.boot:spring-boot-devtools")
|
||||
developmentOnly("org.springframework.boot:spring-boot-docker-compose")
|
||||
runtimeOnly("org.postgresql:postgresql")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||
testImplementation("org.springframework.boot:spring-boot-testcontainers")
|
||||
|
@ -1,34 +0,0 @@
|
||||
package ovh.herisson.Clyde.DTO.Msg;
|
||||
|
||||
/******************************************************
|
||||
* @file DiscussionDTO.java
|
||||
* @author Anthony Debucquoy
|
||||
* @scope Extension messagerie
|
||||
*
|
||||
* File to format a discussion using messageDTO
|
||||
******************************************************/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Discussion;
|
||||
import ovh.herisson.Clyde.DTO.Msg.MessagesDTO;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class DiscussionDTO {
|
||||
private long id;
|
||||
private String name;
|
||||
private List<User> members;
|
||||
private List<MessagesDTO> msgs;
|
||||
|
||||
public static DiscussionDTO construct(Discussion d, User u){
|
||||
List<MessagesDTO> msgsdto = new ArrayList<>();
|
||||
d.getMsgs().forEach(x -> msgsdto.add(MessagesDTO.construct(x, u)));
|
||||
return new DiscussionDTO(d.getId(), d.getName(), d.getMembers(), msgsdto);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package ovh.herisson.Clyde.DTO.Msg;
|
||||
|
||||
/******************************************************
|
||||
* @file MessagesDTO.java
|
||||
* @author Anthony Debucquoy
|
||||
* @scope Extension messagerie
|
||||
*
|
||||
* File to Format the response adding the sender field
|
||||
******************************************************/
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Message;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MessagesDTO {
|
||||
private long id;
|
||||
private String content;
|
||||
private User author;
|
||||
private boolean sender;
|
||||
private Date created;
|
||||
//TODO: Attachment
|
||||
|
||||
public static MessagesDTO construct(Message m, User user){
|
||||
boolean sender = false;
|
||||
if(m.getAuthor().equals(user))
|
||||
sender = true;
|
||||
return new MessagesDTO(m.getId(), m.getContent(), m.getAuthor(), sender, m.getCreated());
|
||||
}
|
||||
}
|
@ -47,6 +47,7 @@ public class ApplicationsController {
|
||||
|
||||
//if unAuthed
|
||||
authorizedApps.add(Applications.Login);
|
||||
authorizedApps.add(Applications.Schedule);
|
||||
|
||||
User user = authServ.getUserFromToken(token);
|
||||
if(user == null)
|
||||
|
@ -1,103 +0,0 @@
|
||||
package ovh.herisson.Clyde.EndPoints.Msg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.websocket.server.PathParam;
|
||||
import lombok.AllArgsConstructor;
|
||||
import ovh.herisson.Clyde.Repositories.CourseRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Msg.ForumRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Msg.TopicRepository;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
import ovh.herisson.Clyde.Services.CourseService;
|
||||
import ovh.herisson.Clyde.Services.Msg.ForumService;
|
||||
import ovh.herisson.Clyde.Tables.Course;
|
||||
import ovh.herisson.Clyde.Tables.Role;
|
||||
import ovh.herisson.Clyde.Tables.Token;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Forum;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Topic;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
|
||||
@AllArgsConstructor
|
||||
public class ForumController {
|
||||
|
||||
private CourseRepository courseRepo;
|
||||
private CourseService courseServ;
|
||||
private AuthenticatorService authServ;
|
||||
private ForumService forumServ;
|
||||
private ForumRepository forumRepo;
|
||||
private TopicRepository topicRepo;
|
||||
|
||||
//// Endpoints to get and create new forums
|
||||
|
||||
@GetMapping("/forums/{id}")
|
||||
public ResponseEntity<List<Forum>> getForumFromCourseId(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||
User u = authServ.getUserFromToken(token);
|
||||
if(u == null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
return new ResponseEntity<>(courseRepo.findById(id).getForums(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/forums/{id}")
|
||||
public ResponseEntity<Forum> createForumOfCourse(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Forum data){
|
||||
User u = authServ.getUserFromToken(token);
|
||||
Course c = courseRepo.findById(id);
|
||||
if(!(c.getOwner().equals(u) || u.getRole() == Role.Admin)){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
forumServ.createForum(c, data);
|
||||
return new ResponseEntity<>(HttpStatus.ACCEPTED);
|
||||
}
|
||||
|
||||
//// Endpoints to get and create forum's topic
|
||||
|
||||
@GetMapping("/forum/{id}")
|
||||
public ResponseEntity<List<Topic>> getTopicsFromForumId(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||
User u = authServ.getUserFromToken(token);
|
||||
if(u != null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
return new ResponseEntity<>(forumRepo.findById(id).orElse(null).getTopics(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/forum/{id}")
|
||||
public ResponseEntity<Topic> postTopicToForum(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Topic data){
|
||||
User u = authServ.getUserFromToken(token);
|
||||
Forum f = forumRepo.findById(id).orElse(null);
|
||||
if(!f.getWriters().contains(u)){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
forumServ.createTopic(f, data);
|
||||
return new ResponseEntity<>(HttpStatus.ACCEPTED);
|
||||
}
|
||||
|
||||
//// Endpoints related to topics and messages
|
||||
|
||||
@GetMapping("/forum/post/{id}")
|
||||
public ResponseEntity<Topic> getPost(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||
User u = authServ.getUserFromToken(token);
|
||||
if(u != null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
Topic t = topicRepo.findById(id).orElse(null);
|
||||
return new ResponseEntity<>(t, HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
// TODO: <tonitch> Create a new post/topic and response to a topic
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
package ovh.herisson.Clyde.EndPoints.Msg;
|
||||
|
||||
/******************************************************
|
||||
* @file MessagesController.java
|
||||
* @author Anthony Debucquoy
|
||||
* @scope Extension messagerie
|
||||
*
|
||||
* Entry point for the messages application
|
||||
******************************************************/
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import ovh.herisson.Clyde.DTO.Msg.DiscussionDTO;
|
||||
import ovh.herisson.Clyde.Repositories.UserRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Msg.DiscussionRepository;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
import ovh.herisson.Clyde.Services.UserService;
|
||||
import ovh.herisson.Clyde.Services.Msg.DiscussionService;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Discussion;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Message;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
|
||||
@AllArgsConstructor
|
||||
public class MessagesController {
|
||||
|
||||
private AuthenticatorService authServ;
|
||||
private DiscussionService discServ;
|
||||
private DiscussionRepository discRepo;
|
||||
private UserService userServ;
|
||||
|
||||
@GetMapping("/discussions")
|
||||
public ResponseEntity<Iterable<Discussion>> getDiscussions(@RequestHeader("Authorization") String token ){
|
||||
User user = authServ.getUserFromToken(token);
|
||||
if(user == null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
|
||||
Iterable<Discussion> mock = discServ.getOwned(authServ.getUserFromToken(token));
|
||||
|
||||
return new ResponseEntity<>(mock, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/discussion/{id}")
|
||||
public ResponseEntity<DiscussionDTO> getDiscussion(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||
User user = authServ.getUserFromToken(token);
|
||||
if(user == null || !discServ.hasDiscussion(user, id) ){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
return new ResponseEntity<>(DiscussionDTO.construct(discRepo.findById(id).orElse(null), authServ.getUserFromToken(token)), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PatchMapping("/discussion/{id}")
|
||||
public ResponseEntity<Discussion> AlterDiscussion(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Discussion data){
|
||||
User user = authServ.getUserFromToken(token);
|
||||
if(user == null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
|
||||
Discussion disc = discRepo.findById(id).orElse(null);
|
||||
disc.setName(data.getName());
|
||||
discRepo.save(disc);
|
||||
return new ResponseEntity<>(disc, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PatchMapping("/discussion/{id}/add")
|
||||
public ResponseEntity<Discussion> invite(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody User data){
|
||||
User user = authServ.getUserFromToken(token);
|
||||
if(user == null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
|
||||
Discussion disc = discRepo.findById(id).orElse(null);
|
||||
User invited = userServ.getUserById(data.getRegNo());
|
||||
disc.addMember(invited);
|
||||
discRepo.save(disc);
|
||||
return new ResponseEntity<>(disc, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PatchMapping("/discussion/{id}/remove")
|
||||
public ResponseEntity<Discussion> removeMember(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody User data){
|
||||
User user = authServ.getUserFromToken(token);
|
||||
if(user == null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
|
||||
Discussion disc = discRepo.findById(id).orElse(null);
|
||||
User member = userServ.getUserById(data.getRegNo());
|
||||
disc.delMember(member);
|
||||
discRepo.save(disc);
|
||||
return new ResponseEntity<>(disc, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/discussion/{id}")
|
||||
public ResponseEntity<Discussion> sendMessage(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Message msg){
|
||||
User user = authServ.getUserFromToken(token);
|
||||
if(user == null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
|
||||
Discussion disc = discRepo.findById(id).orElse(null);
|
||||
msg.setAuthor(user);
|
||||
if(disc != null)
|
||||
discServ.CreateMessage(disc, msg);
|
||||
return new ResponseEntity<>(disc, HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/discussion")
|
||||
public ResponseEntity<Discussion> createDiscussion(@RequestHeader("Authorization") String token, @RequestBody Discussion data){
|
||||
return new ResponseEntity<>(discServ.create(data.getName(), authServ.getUserFromToken(token)), HttpStatus.OK);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package ovh.herisson.Clyde.Repositories.Msg;
|
||||
|
||||
/******************************************************
|
||||
* @file DiscussionRepository.java
|
||||
* @author Anthony Debucquoy
|
||||
* @scope Extension messagerie
|
||||
*
|
||||
* Repository of Discussion allowing to fetch discussion by user
|
||||
******************************************************/
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import ovh.herisson.Clyde.Tables.Msg.Discussion;
|
||||
|
||||
public interface DiscussionRepository extends CrudRepository<Discussion, Long>{
|
||||
|
||||
@Query("SELECT d FROM Discussion d INNER JOIN FETCH d.members dm WHERE dm.id = ?1")
|
||||
List<Discussion> findByMembership(long userid);
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package ovh.herisson.Clyde.Repositories.Msg;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import ovh.herisson.Clyde.Tables.Msg.Forum;
|
||||
|
||||
public interface ForumRepository extends CrudRepository<Forum, Long> {
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package ovh.herisson.Clyde.Repositories.Msg;
|
||||
|
||||
/******************************************************
|
||||
* @file MessageRepository.java
|
||||
* @author Anthony Debucquoy
|
||||
* @scope Extension messagerie
|
||||
******************************************************/
|
||||
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import ovh.herisson.Clyde.Tables.Msg.Message;
|
||||
|
||||
public interface MessageRepository extends CrudRepository<Message, Long> {}
|
@ -1,10 +0,0 @@
|
||||
package ovh.herisson.Clyde.Repositories.Msg;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import ovh.herisson.Clyde.Tables.Msg.Topic;
|
||||
|
||||
public interface TopicRepository extends CrudRepository<Topic, Long> {
|
||||
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
package ovh.herisson.Clyde.Services.Msg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/******************************************************
|
||||
* @file DiscussionService.java
|
||||
* @author Anthony Debucquoy
|
||||
* @scope Extension messagerie
|
||||
*
|
||||
* Various function utilised by the messages application
|
||||
******************************************************/
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.fasterxml.jackson.databind.util.JSONPObject;
|
||||
|
||||
import ovh.herisson.Clyde.Repositories.Msg.DiscussionRepository;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Discussion;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Message;
|
||||
|
||||
@Service
|
||||
public class DiscussionService {
|
||||
|
||||
@Autowired
|
||||
private DiscussionRepository discRepo;
|
||||
|
||||
public Discussion create(String name, User author){
|
||||
return discRepo.save(new Discussion(name, author));
|
||||
}
|
||||
|
||||
/**
|
||||
* list discussions owned by a certain user
|
||||
*/
|
||||
public Iterable<Discussion> getOwned(User author){
|
||||
return discRepo.findByMembership(author.getRegNo());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a message and link it to it's discussion
|
||||
*/
|
||||
public Discussion CreateMessage(Discussion disc, Message msg){
|
||||
disc.addMessage(msg);
|
||||
return discRepo.save(disc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a user is in a discussion
|
||||
*/
|
||||
public boolean hasDiscussion(User user, long id) {
|
||||
Discussion disc = discRepo.findById(id).orElse(null);
|
||||
List<User> members = disc.getMembers();
|
||||
return members.contains(user);
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package ovh.herisson.Clyde.Services.Msg;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import ovh.herisson.Clyde.Repositories.CourseRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Msg.ForumRepository;
|
||||
import ovh.herisson.Clyde.Tables.Course;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Forum;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Topic;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class ForumService {
|
||||
|
||||
private CourseRepository courseRepo;
|
||||
private ForumRepository forumRepo;
|
||||
|
||||
public void createForum(Course c, Forum f){
|
||||
c.addForum(f);
|
||||
courseRepo.save(c);
|
||||
}
|
||||
|
||||
public void createTopic(Forum f, Topic data) {
|
||||
f.addTopic(data);
|
||||
forumRepo.save(f);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package ovh.herisson.Clyde.Tables;
|
||||
public enum Applications {
|
||||
// without any token
|
||||
Login,
|
||||
Schedule,
|
||||
|
||||
// with any token
|
||||
Profile,
|
||||
|
@ -1,16 +1,10 @@
|
||||
package ovh.herisson.Clyde.Tables;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Forum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.OnDelete;
|
||||
import org.hibernate.annotations.OnDeleteAction;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class Course {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@ -23,15 +17,6 @@ public class Course {
|
||||
@JoinColumn(name = "Users")
|
||||
private User owner;
|
||||
|
||||
//// Extension Messagerie /////
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
private List<Forum> forums;
|
||||
|
||||
public void addForum(Forum f){
|
||||
forums.add(f);
|
||||
}
|
||||
///////////////////////////////
|
||||
|
||||
public Course(int credits, String title, User owner){
|
||||
this.credits = credits;
|
||||
this.title = title;
|
||||
|
@ -1,32 +0,0 @@
|
||||
package ovh.herisson.Clyde.Tables.Msg;
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class Answers {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private int id;
|
||||
|
||||
@CreationTimestamp
|
||||
private Date creation;
|
||||
|
||||
@ManyToOne
|
||||
private Topic topic;
|
||||
|
||||
private String content;
|
||||
|
||||
@OneToOne
|
||||
private User author;
|
||||
|
||||
private boolean anonymous;
|
||||
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
package ovh.herisson.Clyde.Tables.Msg;
|
||||
|
||||
/******************************************************
|
||||
* @file Discussion.java
|
||||
* @author Anthony Debucquoy
|
||||
* @scope Extension messagerie
|
||||
*
|
||||
* Discussion allow to regroupe multiple user in and message together
|
||||
* for the messages application to work
|
||||
******************************************************/
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class Discussion{
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
private String name;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(
|
||||
name = "discussion_members",
|
||||
joinColumns = @JoinColumn(name = "discussion_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "user_id")
|
||||
)
|
||||
private List<User> members;
|
||||
|
||||
@OneToMany(mappedBy="discussion", orphanRemoval = true, cascade = CascadeType.ALL)
|
||||
private List<Message> msgs;
|
||||
|
||||
public Discussion(String name){
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Discussion(String name, User user){
|
||||
this.name = name;
|
||||
this.members = List.of(user);
|
||||
}
|
||||
|
||||
public void addMessage(Message msg){
|
||||
msg.setDiscussion(this);
|
||||
msgs.add(msg);
|
||||
}
|
||||
|
||||
public void addMember(User user) {
|
||||
members.add(user);
|
||||
}
|
||||
|
||||
public void delMember(User user) {
|
||||
members.remove(user);
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package ovh.herisson.Clyde.Tables.Msg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import ovh.herisson.Clyde.Tables.Course;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class Forum {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private int id;
|
||||
|
||||
@ManyToOne
|
||||
private Course course;
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToMany
|
||||
private List<Topic> topics;
|
||||
|
||||
public void addTopic(Topic t) {
|
||||
topics.add(t);
|
||||
}
|
||||
|
||||
@OneToMany
|
||||
private List<User> writers; // User who are authorized to create a post
|
||||
|
||||
@OneToMany
|
||||
private List<User> register;
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package ovh.herisson.Clyde.Tables.Msg;
|
||||
|
||||
/******************************************************
|
||||
* @file Message.java
|
||||
* @author Anthony Debucquoy
|
||||
* @scope Extension messagerie
|
||||
*
|
||||
* Represent a message sent to a discussion
|
||||
******************************************************/
|
||||
|
||||
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java.util.Date;
|
||||
|
||||
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.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.Temporal;
|
||||
import jakarta.persistence.TemporalType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Entity
|
||||
public class Message {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
private String content;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(nullable = false)
|
||||
private Date created;
|
||||
|
||||
@ManyToOne
|
||||
private User author;
|
||||
|
||||
public User getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
@OneToOne
|
||||
private Message response;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JsonIgnore
|
||||
private Discussion discussion;
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package ovh.herisson.Clyde.Tables.Msg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class Topic {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private int id;
|
||||
|
||||
private String subject, content;
|
||||
|
||||
@OneToOne
|
||||
private User author;
|
||||
|
||||
@OneToMany(mappedBy = "topic", cascade = CascadeType.ALL)
|
||||
private List<Answers> answers;
|
||||
|
||||
private boolean locked; // true if new messages can be posted
|
||||
}
|
@ -1,13 +1,7 @@
|
||||
package ovh.herisson.Clyde.Tables;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
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
|
||||
@ -24,18 +18,8 @@ public class User {
|
||||
private String country;
|
||||
private Date birthDate;
|
||||
private String profilePictureUrl;
|
||||
private Role role;
|
||||
@JsonIgnore
|
||||
private ovh.herisson.Clyde.Tables.Role role;
|
||||
private String password;
|
||||
|
||||
////// Extension Messagerie /////
|
||||
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
|
||||
private List<Message> msgs;
|
||||
/////////////////////////////////
|
||||
|
||||
@ManyToMany( mappedBy = "members" )
|
||||
private List<Discussion> discussions;
|
||||
|
||||
public User(String lastName, String firstName, String email, String address,
|
||||
String country, Date birthDate, String profilePictureUrl, Role role, String password)
|
||||
{
|
||||
|
@ -25,7 +25,6 @@ window.addEventListener('hashchange', () => {
|
||||
const login=ref(i18n("app.login"))
|
||||
const active=ref(false)
|
||||
|
||||
|
||||
const apps = ref([])
|
||||
appList().then(e => apps.value = e)
|
||||
|
||||
@ -99,19 +98,20 @@ window.addEventListener('hashchange', () => {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display:grid;
|
||||
|
||||
grid-template-columns:[firstCol-start]70px[firstCol-end secondCol-start] auto [endCol];
|
||||
grid-template-rows:[firstRow-start] var(--header-size) [firstRow-end secondRow-start] calc(100% - var(--header-size)) [endRow];
|
||||
grid-template-columns:[firstCol-start]70px[firstCol-end secondCol-start]auto[endCol];
|
||||
grid-template-rows:[firstRow-start]61px[firstRow-end secondRow-start] auto [endRow];
|
||||
grid-template-areas:
|
||||
"topBar topBar"
|
||||
"leftBar page";
|
||||
|
||||
row-gap:0px;
|
||||
column-gap:0px;
|
||||
}
|
||||
|
||||
.page {
|
||||
grid-area:page;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
place-self:center;
|
||||
}
|
||||
|
||||
.topBar{
|
||||
@ -154,7 +154,7 @@ window.addEventListener('hashchange', () => {
|
||||
|
||||
ul.vertical{
|
||||
list-style-type: none;
|
||||
margin-top: var(--header-size);
|
||||
margin-top: 61px;
|
||||
top:0;
|
||||
left:0;
|
||||
padding: 25px 0 0;
|
||||
@ -202,7 +202,7 @@ window.addEventListener('hashchange', () => {
|
||||
left:0;
|
||||
|
||||
position: fixed;
|
||||
height:var(--header-size);
|
||||
height:61px;
|
||||
width: 100%;
|
||||
background-color: rgb(24, 24, 24);
|
||||
}
|
||||
|
@ -1,175 +0,0 @@
|
||||
<!----------------------------------------------------
|
||||
File: Forums.vue
|
||||
Author: Anthony Debucquoy
|
||||
Scope: Extension messagerie
|
||||
Description: Forum des étudiants
|
||||
----------------------------------------------------->
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { getCourses } from '@/rest/courses.js'
|
||||
import { ForumsOfCurrentCourse, getForumsOfCourse, createForum } from '@/rest/forum.js'
|
||||
import { PostsOfCurrentForum, getPostsOfForum } from '@/rest/forum.js'
|
||||
import { fetchedPost, fetchPost } from '@/rest/forum.js'
|
||||
import { getSelf } from '@/rest/Users.js'
|
||||
|
||||
const courses = await reactive(getCourses());
|
||||
const selectedCourse = ref();
|
||||
const selectedForum = ref();
|
||||
const Role = (await getSelf()).role;
|
||||
|
||||
const addForum = ref(false);
|
||||
const addForumName = ref("");
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="app">
|
||||
<div id="ForumSelector">
|
||||
<select id="cours" value="" v-model="selectedCourse" @change="getForumsOfCourse(selectedCourse)">
|
||||
<option v-for="course in courses" :value="course.courseId">{{course.title}}</option>
|
||||
</select>
|
||||
|
||||
<select id="forum" value="" v-model="selectedForum" @change="getPostsOfForum(selectedForum)" v-if="ForumsOfCurrentCourse != null">
|
||||
<option v-for="forum in ForumsOfCurrentCourse" :value=forum.id>{{forum.name}}</option>
|
||||
</select>
|
||||
<button v-if="(Role === 'Admin' || Role === 'Teacher') && ForumsOfCurrentCourse != null " id="createPost" @click="addForum = true">+</button>
|
||||
</div>
|
||||
<div id="PostSelector" v-if="PostsOfCurrentForum != null">
|
||||
<div @click="fetchPost(post.id)" class="postItem" v-for="post in PostsOfCurrentForum" :key="post.id">{{ post.name }}</div>
|
||||
<button v-if="Role === 'Admin' || Role === 'Teacher' " id="createPost" @click="createPost()">+</button>
|
||||
</div>
|
||||
<div id="PostViewer" v-if="fetchedPost != null">
|
||||
<div id="Post">
|
||||
<h1>{{ fetchedPost.subject }}</h1>
|
||||
{{fetchedPost.content}}
|
||||
</div>
|
||||
<div id="Messages">
|
||||
<p v-for="msg in fetchedPost.messages">{{msg.author}} - {{msg.content}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="forumAdder" v-if=addForum @click.self="addForum = false">
|
||||
<div id="addForumForm">
|
||||
<label>New Forum:</label>
|
||||
<input type="text" placeholder="Name" v-model=addForumName @keyup.enter="createForum(selectedCourse, $event.target.value); addForum = false;" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
#forumAdder{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #00000022;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
#addForumForm{
|
||||
position: relative;
|
||||
width: 30%;
|
||||
left: calc(50% - 30% / 2);
|
||||
top: calc(50% - 10% / 2);
|
||||
border-radius: 10px;
|
||||
height: 10%;
|
||||
background-color: white;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
#app{
|
||||
display: grid;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
grid-template: 5em auto / 25% 75%;
|
||||
}
|
||||
|
||||
#ForumSelector{
|
||||
background-color: #FFFFFF0E;
|
||||
grid-column: 1 / 3;
|
||||
border-radius: 100px;
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
#ForumSelector select{
|
||||
background-color: #ffa000;
|
||||
border: none;
|
||||
margin: 10px;
|
||||
border-radius: 10px;
|
||||
width: 200px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#ForumSelector button{
|
||||
background-color: green;
|
||||
border: none;
|
||||
border-radius: 25%;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#PostSelector{
|
||||
background-color: #FFFFFF0E;
|
||||
border-radius: 0 25px 25px 0;
|
||||
margin: 10px 0 10px 10px;
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
|
||||
.postItem{
|
||||
color: darkorange;
|
||||
display: flex;
|
||||
font-family: sans-serif;
|
||||
font-weight: bold;
|
||||
height: 4vh;
|
||||
margin: 5px;
|
||||
border-radius: 0 30px 30px 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid darkorange;
|
||||
}
|
||||
|
||||
.postItem:hover{
|
||||
background-color: gray;
|
||||
}
|
||||
|
||||
#PostViewer{
|
||||
background-color: #FFFFFF0E;
|
||||
border-radius: 25px;
|
||||
margin: 10px;
|
||||
|
||||
max-height: 100%;
|
||||
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#Post{
|
||||
padding: 25px;
|
||||
|
||||
}
|
||||
|
||||
#Messages{
|
||||
padding: 25px;
|
||||
border-top: 3px dotted white;
|
||||
|
||||
}
|
||||
|
||||
#Messages > p {
|
||||
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,213 +0,0 @@
|
||||
<!----------------------------------------------------
|
||||
File: Msg.vue
|
||||
Author: Anthony Debucquoy
|
||||
Scope: Extension messagerie
|
||||
Description: Main msg page
|
||||
----------------------------------------------------->
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { discussionsList, currentDiscussion, fetchDiscussion, createDiscussion, sendMessage, updateDiscussionName, invite, removeMember} from '@/rest/msg.js'
|
||||
|
||||
const msgContent = ref("");
|
||||
const addMember = ref(false);
|
||||
const currentTitle = ref("");
|
||||
|
||||
function formatTime(date){
|
||||
return date.getHours() + ":" + date.getMinutes() + " " + date.getDate() + "/" + date.getMonth();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="msg">
|
||||
<div id="discList">
|
||||
<div @click="fetchDiscussion(discussion.id).then(e => currentTitle = currentDiscussion.name)" class="discItem" v-for="discussion in discussionsList" :key="discussion.id">{{ discussion.name }}</div>
|
||||
<button id="createDiscussion" @click="createDiscussion('New Discussion')">+</button>
|
||||
</div>
|
||||
<div id="discussion" v-if="currentDiscussion.length != 0">
|
||||
<h1 id=msgName ><input class="InputTitle" type="text" @change="updateDiscussionName(currentDiscussion.id, currentTitle)" v-model="currentTitle"></h1>
|
||||
<div id=msgs>
|
||||
<div class="msg" v-for="msg in currentDiscussion.msgs" :sender="msg.sender" :key="msg.id">
|
||||
{{ msg.content }}<br/>
|
||||
<span class="sender"><span v-if="!msg.sender">{{ msg.author.firstName }} {{ msg.author.lastName.toUpperCase() }}</span> {{formatTime(new Date(msg.created))}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id=messageBox>
|
||||
<input type="text" @keyup.enter="sendMessage(currentDiscussion.id, msgContent, null); msgContent = ''" v-model="msgContent">
|
||||
<input type="submit" @click="sendMessage(currentDiscussion.id, msgContent, null); msgContent = ''" value="send">
|
||||
</div>
|
||||
</div>
|
||||
<div id="members" v-if="currentDiscussion.length != 0">
|
||||
<div class="memberItem" v-for="member in currentDiscussion.members" @click="removeMember(currentDiscussion.id, member.regNo)" :key="member.id"><span>{{ member.firstName }} {{ member.lastName.toUpperCase() }}</span></div>
|
||||
<input type=text id="addMembers" @focus="addMember = true" @blur="addMember = false;$event.target.value = ''" @change="invite(currentDiscussion.id, $event.target.value)" :placeholder="addMember ? 'Regno' : '+'"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
div#msg{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 20% auto 10%;
|
||||
}
|
||||
|
||||
div#discList{
|
||||
margin: 30px 0 30px 30px;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
div#members{
|
||||
margin: 30px 0;
|
||||
border-radius: 10px 0 0 10px;
|
||||
background-color: red;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
padding: 10px 0 0 10px;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.InputTitle{
|
||||
all: inherit;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.discItem{
|
||||
color: darkorange;
|
||||
display: flex;
|
||||
font-family: sans-serif;
|
||||
font-weight: bold;
|
||||
height: 4vh;
|
||||
margin: 5px;
|
||||
border-radius: 0 30px 30px 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid darkorange;
|
||||
}
|
||||
|
||||
.memberItem{
|
||||
color: darkorange;
|
||||
display: flex;
|
||||
font-family: sans-serif;
|
||||
font-weight: bold;
|
||||
height: 4vh;
|
||||
margin: 5px;
|
||||
border-radius: 30px 0 0 30px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid darkorange;
|
||||
}
|
||||
|
||||
.memberItem:hover span{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.memberItem:hover{
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.memberItem:hover:before{
|
||||
color: white;
|
||||
content: "X"
|
||||
}
|
||||
|
||||
#createDiscussion{
|
||||
height: 4vh;
|
||||
margin: 5px;
|
||||
color: white;
|
||||
background-color: green;
|
||||
border-radius: 0 30px 30px 0;
|
||||
border: none;
|
||||
font-weight: 900;
|
||||
font-size: 2em;
|
||||
}
|
||||
#addMembers{
|
||||
height: 4vh;
|
||||
margin: 5px;
|
||||
text-align: center;
|
||||
color: white;
|
||||
background-color: green;
|
||||
border-radius: 30px 0 0 30px;
|
||||
border: none;
|
||||
font-weight: 900;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
div#discussion{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 30px;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#msgName{
|
||||
text-align: center;
|
||||
display: block;
|
||||
background-color: #2a1981;
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
width: 75%;
|
||||
margin: 30px auto;
|
||||
}
|
||||
|
||||
.discItem:hover{
|
||||
background-color: gray;
|
||||
}
|
||||
|
||||
#msgs{
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.msg {
|
||||
background-color: aliceblue;
|
||||
font-family: sans-serif;
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
max-width: 50%;
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.sender{
|
||||
display: inline-block;
|
||||
color: gray;
|
||||
font-size: 0.5em;
|
||||
}
|
||||
|
||||
.msg[sender=true]{
|
||||
background-color: darkorange;
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
#messageBox{
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background-color: white;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#messageBox input[type="text"]{
|
||||
all: inherit;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
#messageBox input[type="submit"]{
|
||||
border: inherit;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
</style>
|
211
frontend/src/Apps/Schedule.vue
Normal file
211
frontend/src/Apps/Schedule.vue
Normal file
@ -0,0 +1,211 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const schedule = [
|
||||
{course:"Math Pour L'info",
|
||||
start:"Wed Mar 27 2024 10:15 GMT+0100",
|
||||
end:"Wed Mar 27 2024 12:15 GMT+0100"},
|
||||
{
|
||||
course:"Calculus",
|
||||
start:"Wed Mar 27 2024 08:00 GMT+0100",
|
||||
end:"Wed Mar 27 2024 10:00 GMT+0100"
|
||||
|
||||
},
|
||||
{
|
||||
course:"Physique II",
|
||||
start:"Tue Mar 26 2024 10:15 GMT+0100",
|
||||
end:"Tue Mar 26 2024 12:15 GMT+0100"
|
||||
},
|
||||
{
|
||||
course:"Math Pour L'info",
|
||||
start:"Thu Mar 28 2024 10:15 GMT+0100",
|
||||
end:"Thu Mar 28 2024 12:15 GMT+0100"
|
||||
}]
|
||||
function formatDate(date) {
|
||||
var d = new Date(date),
|
||||
month = '' + (d.getMonth() + 1),
|
||||
day = '' + d.getDate(),
|
||||
year = d.getFullYear();
|
||||
|
||||
if (month.length < 2)
|
||||
month = '0' + month;
|
||||
if (day.length < 2)
|
||||
day = '0' + day;
|
||||
|
||||
return [day, month, year].join('-');
|
||||
}
|
||||
function getMonday(d) {
|
||||
d = new Date(d);
|
||||
var day = d.getDay(),
|
||||
diff = d.getDate() - day + (day == 0 ? -6 : 1);
|
||||
return new Date(d.setDate(diff));
|
||||
}
|
||||
|
||||
function getAnyDays(d){
|
||||
|
||||
var day = new Date(mondayOfWeek.value);
|
||||
day.setDate(day.getDate() + d );
|
||||
|
||||
return day;
|
||||
}
|
||||
|
||||
const mondayOfWeek=ref(getMonday(new Date(schedule[1].start)))
|
||||
|
||||
function isNotCourse(element){
|
||||
return element==null;
|
||||
}
|
||||
|
||||
function durationCourse(element){
|
||||
const hour = element.end.substring(3,5) -element.start.substring(3,5);
|
||||
|
||||
|
||||
return (element.end - element.start)%2;
|
||||
}
|
||||
function sortByDate(a, b) {
|
||||
const nameA = a.start; // ignore upper and lowercase
|
||||
const nameB = b.start; // ignore upper and lowercase
|
||||
|
||||
if (nameA < nameB) {
|
||||
return -1;
|
||||
}
|
||||
if (nameA > nameB) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function transpose(a) {
|
||||
const trans = [[],[],[],[],[],[]];
|
||||
for(let i = 0; i < 6;i++){
|
||||
for(let j=0; j< 7; j++){
|
||||
if(a[j][i] !== null){
|
||||
trans[i].push(a[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return trans;
|
||||
}
|
||||
|
||||
function matrixFromList(list){
|
||||
const matrix = [[],[],[],[],[],[],[]];
|
||||
for(let key in list){
|
||||
const temp = [];
|
||||
const day = new Date(list[key].start);
|
||||
matrix[day.getDay()].push(list[key]);
|
||||
matrix[day.getDay()].sort((a,b) => sortByDate(a,b));
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
|
||||
const schedule2 = matrixFromList(schedule);
|
||||
const scheduleByWeek = transpose(schedule2);
|
||||
|
||||
console.log(scheduleByWeek)
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div class="grid">
|
||||
<div class="options" >
|
||||
</div>
|
||||
<div class="schedule">
|
||||
<table class="table">
|
||||
<tr style="background-color:rgb(24,24,24)">
|
||||
<th/>
|
||||
<th class="header">Lundi {{formatDate(getAnyDays(0))}}</th>
|
||||
<th class="header">Mardi {{formatDate(getAnyDays(1))}}</th>
|
||||
<th class="header">Mercredi {{formatDate(getAnyDays(2))}}</th>
|
||||
<th class="header">Jeudi {{formatDate(getAnyDays(3))}}</th>
|
||||
<th class="header">Vendredi {{formatDate(getAnyDays(4))}}</th>
|
||||
<th class="header">Samedi {{formatDate(getAnyDays(5))}}</th>
|
||||
<th class="header">Dimanche {{formatDate(getAnyDays(6))}}</th>
|
||||
</tr>
|
||||
<tr v-for="(n,index) in 12">
|
||||
<th class="hour">{{8 + index}}:00-{{9+index}}:00</th>
|
||||
<td v-for="m in 7"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="courseGrid">
|
||||
<div v-for="i in 7">
|
||||
Test
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.grid{
|
||||
display:grid;
|
||||
margin-top:2%;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
grid-template-columns:15vw 70vw;
|
||||
column-gap:2.5vw;
|
||||
|
||||
grid-template-areas:"options schedule";
|
||||
}
|
||||
.schedule{
|
||||
position:relative;
|
||||
border-radius:20px;
|
||||
grid-area:schedule;
|
||||
width:100%;
|
||||
height:85vh;
|
||||
background-color:rgba(255,255,255,0.1);
|
||||
}
|
||||
.options{
|
||||
border-radius:20px;
|
||||
grid-area:options;
|
||||
background-color:rgba(255,255,255,0.1);
|
||||
width:100%;
|
||||
height:85vh;
|
||||
}
|
||||
|
||||
.table{
|
||||
width:100%;
|
||||
height:100%;
|
||||
border-spacing:0;
|
||||
border-collapse:separate;
|
||||
border-radius: 20px;
|
||||
border: 2px solid black
|
||||
}
|
||||
|
||||
.hour{
|
||||
background-color:rgb(72,72,72)
|
||||
|
||||
}
|
||||
|
||||
.header{
|
||||
align-items:center;
|
||||
width:12.5%;
|
||||
color:#FFFFFF;
|
||||
}
|
||||
table th:not(:last-child),
|
||||
table td:not(:last-child) {
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
|
||||
table tr:not(:last-child)>td,
|
||||
table tr:not(:last-child)>th
|
||||
{
|
||||
border-bottom:1px solid black;
|
||||
}
|
||||
|
||||
.courseGrid{
|
||||
top:13.75%;
|
||||
left:12.5%;
|
||||
position:absolute;
|
||||
width:87.5%;
|
||||
height:86.25%;
|
||||
display:grid;
|
||||
grid-template-columns:repeat(7,1fr);
|
||||
}
|
||||
|
||||
|
||||
.course{
|
||||
width:100%;
|
||||
height:100%;
|
||||
background-color:rgb(100,0,100);
|
||||
}
|
||||
|
||||
|
||||
</style>
|
@ -1,7 +1,3 @@
|
||||
:root {
|
||||
--header-size: 61px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: rgb(53, 25, 60);
|
||||
margin:0;
|
||||
|
@ -9,24 +9,22 @@ import Profil from "@/Apps/Profil.vue"
|
||||
import Courses from "@/Apps/ManageCourses.vue"
|
||||
import Users from "@/Apps/UsersList.vue"
|
||||
import Students from "@/Apps/StudentsList.vue"
|
||||
import Msg from "@/Apps/Msg.vue"
|
||||
import Forums from '@/Apps/Forums.vue'
|
||||
import Schedule from "@/Apps/Schedule.vue"
|
||||
|
||||
const apps = {
|
||||
'/schedule': Schedule,
|
||||
'/login': LoginPage,
|
||||
'/inscription': Inscription,
|
||||
'/profil': Profil,
|
||||
'/manage-courses' : Courses,
|
||||
'/users-list' : Users,
|
||||
'/students-list' : Students,
|
||||
'/msg' : Msg,
|
||||
'/forums': Forums,
|
||||
}
|
||||
|
||||
const appsList = {
|
||||
'Msg': { path: '#/msg', icon: 'fa-comment', text: i18n("app.messages") },
|
||||
'Notification': { path: '#/notifs', icon: 'fa-bell', text: i18n("app.notifications") },
|
||||
'Forum': { path: '#/forums', icon: 'fa-envelope', text: i18n("app.forum") },
|
||||
'Forum': { path: '#/forum', icon: 'fa-envelope', text: i18n("app.forum") },
|
||||
'Schedule': { path: '#/schedule', icon: 'fa-calendar-days', text: i18n("app.schedules") },
|
||||
'Inscription': { path: '#/inscription', icon: 'fa-users', text: i18n("app.inscription.requests") },
|
||||
'ManageCourses': { path: '#/manage-courses', icon: 'fa-book', text: i18n("app.manage.courses") },
|
||||
|
@ -1,65 +0,0 @@
|
||||
import { ref } from 'vue'
|
||||
import { restGet, restPost, restDelete, restPatch } from './restConsumer.js'
|
||||
|
||||
/**
|
||||
* List forums of a course
|
||||
*/
|
||||
export async function getForumsOfCourse(id){
|
||||
ForumsOfCurrentCourse.value = await restGet("/forums/" + id)
|
||||
}
|
||||
|
||||
export const ForumsOfCurrentCourse = ref();
|
||||
|
||||
export function createForum(id, name){
|
||||
restPost("/forums/" + id, {name: name}).then(_ => getForumsOfCourse(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* List post of a specified forum
|
||||
*/
|
||||
export async function getPostsOfForum(id){
|
||||
PostsOfCurrentForum.value = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Post~1"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Post~2"
|
||||
},
|
||||
]
|
||||
// PostsCurrentForum.value = await restGet("/forum/" + id);
|
||||
}
|
||||
|
||||
export const PostsOfCurrentForum = ref();
|
||||
|
||||
/**
|
||||
* Get a post and its responses
|
||||
*/
|
||||
export async function fetchPost(id){
|
||||
fetchedPost.value = {
|
||||
id: 1,
|
||||
subject: "This is the subject of the post",
|
||||
content: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
|
||||
messages: [
|
||||
{
|
||||
id: 1,
|
||||
author: "author~1",
|
||||
content: "J'ai pas copris le message !"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
author: "author~2",
|
||||
content: "tu as fait une faute dans ton message..."
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
author: null,
|
||||
content: "I'm anonymous noww..."
|
||||
}
|
||||
]
|
||||
}
|
||||
// fetchedPost.value = await restGet("/forum/post/" + id);
|
||||
}
|
||||
|
||||
export const fetchedPost = ref();
|
@ -1,60 +0,0 @@
|
||||
/*******************************************************
|
||||
* File: msg.js
|
||||
* Author: Anthony Debucquoy
|
||||
* Scope: Extension messagerie
|
||||
* Description: Messages frontend api consumer
|
||||
*******************************************************/
|
||||
|
||||
import { restGet, restPost, restPatch } from './restConsumer.js'
|
||||
import { ref } from 'vue'
|
||||
|
||||
/**
|
||||
* - id
|
||||
* - name
|
||||
* - members
|
||||
*/
|
||||
export const discussionsList = ref();
|
||||
export const currentDiscussion = ref([]);
|
||||
let timerSet = false
|
||||
|
||||
|
||||
export async function createDiscussion(name){
|
||||
let disc = await restPost("/discussion", {name: name});
|
||||
discussionsList.value.push(disc);
|
||||
}
|
||||
|
||||
|
||||
export async function invite(id, regNo){
|
||||
restPatch("/discussion/"+ id+ "/add", {regNo: parseInt(regNo)}).then(() => fetchDiscussion(id))
|
||||
}
|
||||
|
||||
export async function removeMember(id, regNo){
|
||||
restPatch("/discussion/"+ id+ "/remove", {regNo: parseInt(regNo)}).then(() => fetchDiscussion(id))
|
||||
}
|
||||
|
||||
export async function sendMessage(id, content, responseId){
|
||||
let data = {
|
||||
content: content,
|
||||
response: responseId,
|
||||
}
|
||||
restPost("/discussion/" + id, data).then(() => fetchDiscussion(id));
|
||||
}
|
||||
|
||||
export async function updateDiscussionName(id, name){
|
||||
restPatch("/discussion/" + id, {name: name}).then(() => fetchDiscussions());
|
||||
}
|
||||
|
||||
|
||||
async function fetchDiscussions(){
|
||||
discussionsList.value = await restGet("/discussions");
|
||||
}
|
||||
|
||||
export async function fetchDiscussion(id){
|
||||
currentDiscussion.value = await restGet("/discussion/" + id);
|
||||
if(!timerSet){
|
||||
timerSet = true;
|
||||
setTimeout(() => {timerSet = false;fetchDiscussion(currentDiscussion.value.id)} , 5000);
|
||||
}
|
||||
}
|
||||
|
||||
await fetchDiscussions();
|
Reference in New Issue
Block a user