Changeset ab49338


Ignore:
Timestamp:
09/04/21 12:17:17 (3 years ago)
Author:
KostaFortumanov <kfortumanov@…>
Branches:
master
Children:
0f4f552
Parents:
5306751
Message:

Dodadeno prijavuvanje na objavi

Location:
src/main
Files:
8 added
10 edited

Legend:

Unmodified
Added
Removed
  • src/main/java/it/finki/charitable/controller/DonationPostController.java

    r5306751 rab49338  
    22
    33import it.finki.charitable.entities.*;
    4 import it.finki.charitable.services.DonationInformationService;
    5 import it.finki.charitable.services.DonationPostService;
    6 import it.finki.charitable.services.FundsCollectedService;
    7 import it.finki.charitable.services.UserService;
     4import it.finki.charitable.services.*;
    85import it.finki.charitable.util.FileUploadUtil;
    9 import org.springframework.data.domain.Page;
    106import org.springframework.format.annotation.DateTimeFormat;
    117import org.springframework.security.core.context.SecurityContextHolder;
     
    1612import org.springframework.web.multipart.MultipartFile;
    1713
    18 import java.io.File;
    1914import java.io.IOException;
    2015import java.time.LocalDate;
     
    3227    private final FundsCollectedService fundsCollectedService;
    3328    private final DonationInformationService donationInformationService;
    34 
    35     public DonationPostController(DonationPostService donationPostService, UserService userService, FundsCollectedService fundsCollectedService, DonationInformationService donationInformationService) {
     29    private final ReportPostService reportPostService;
     30    private final ReasonService reasonService;
     31
     32    public DonationPostController(DonationPostService donationPostService, UserService userService, FundsCollectedService fundsCollectedService, DonationInformationService donationInformationService, ReportPostService reportPostService, ReasonService reasonService) {
    3633        this.donationPostService = donationPostService;
    3734        this.userService = userService;
    3835        this.fundsCollectedService = fundsCollectedService;
    3936        this.donationInformationService = donationInformationService;
     37        this.reportPostService = reportPostService;
     38        this.reasonService = reasonService;
    4039    }
    4140
     
    140139            return "post";
    141140        }
    142         AppUser user = post.getUser();
    143         model.addAttribute("post", post);
    144         model.addAttribute("createdByFirstName", user.getFirstName());
    145         model.addAttribute("createdByLastName", user.getLastName());
    146         double total = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
    147         model.addAttribute("total", total);
     141
     142        if (post.getApproved() || (post.getUser().getUsername().equals(SecurityContextHolder.getContext().getAuthentication().getName()) && !post.getApproved())) {
     143            AppUser user = post.getUser();
     144            Moderator moderator = post.getModerator();
     145            model.addAttribute("post", post);
     146            model.addAttribute("createdByFirstName", user.getFirstName());
     147            model.addAttribute("createdByLastName", user.getLastName());
     148            if (moderator != null) {
     149                model.addAttribute("moderatorFirstName", moderator.getFirstName());
     150                model.addAttribute("moderatorLastName", moderator.getLastName());
     151            }
     152            double total = post.getFundsCollected().stream().mapToDouble(FundsCollected::getFunds).sum();
     153            model.addAttribute("total", total);
     154        } else {
     155            model.addAttribute("notFound", true);
     156        }
    148157        return "post";
    149158    }
    150 
    151 //    @RequestMapping("/deletePost")
    152 //    public String deletePost(@RequestParam Long postid) {
    153 //        DonationPost post = donationPostService.getById(postid);
    154 //        if (post.getUser().getUsername().equals(SecurityContextHolder.getContext().getAuthentication().getName())) {
    155 //            List<String> fileForDeletion = post.getPhotosForDeletion();
    156 //            for (String f : fileForDeletion) {
    157 //                File file = new File(f);
    158 //                file.delete();
    159 //            }
    160 //            donationPostService.delete(post);
    161 //        }
    162 //
    163 //        return "redirect:/myPosts";
    164 //    }
    165159
    166160    @RequestMapping("/donate")
     
    188182    }
    189183
     184    @RequestMapping("/report")
     185    public String report(@RequestParam Long postid,
     186                         @RequestParam String description) {
     187
     188        DonationPost donationPost = donationPostService.getById(postid);
     189        ReportPost reportPost = reportPostService.findByDonationPost(donationPost);
     190        if(reportPost == null) {
     191            reportPost = new ReportPost();
     192            reportPost.setDonationPost(donationPost);
     193        }
     194
     195        Reason reason = new Reason();
     196        AppUser user = (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
     197        reason.setUser(user);
     198        reason.setDescription(description);
     199        reasonService.save(reason);
     200        reportPost.getReasons().add(reason);
     201        reportPostService.save(reportPost);
     202        return String.format("redirect:/post?postid=%d", postid);
     203    }
     204
    190205    @ModelAttribute("user")
    191206    public AppUser addAttributes() {
  • src/main/java/it/finki/charitable/controller/ModeratorController.java

    r5306751 rab49338  
    11package it.finki.charitable.controller;
    22
    3 import it.finki.charitable.entities.AppUser;
    4 import it.finki.charitable.entities.DonationPost;
     3import it.finki.charitable.entities.*;
    54import it.finki.charitable.services.DonationPostService;
    65import it.finki.charitable.services.EmailService;
     6import it.finki.charitable.services.ReasonService;
     7import it.finki.charitable.services.ReportPostService;
    78import org.springframework.security.core.context.SecurityContextHolder;
    89import org.springframework.stereotype.Controller;
     
    1314
    1415import java.io.File;
     16import java.util.ArrayList;
    1517import java.util.List;
    1618
     
    2022    private final DonationPostService donationPostService;
    2123    private final EmailService emailService;
     24    private final ReportPostService reportPostService;
     25    private final ReasonService reasonService;
    2226
    23     public ModeratorController(DonationPostService donationPostService, EmailService emailService) {
     27    public ModeratorController(DonationPostService donationPostService, EmailService emailService, ReportPostService reportPostService, ReasonService reasonService) {
    2428        this.donationPostService = donationPostService;
    2529        this.emailService = emailService;
     30        this.reportPostService = reportPostService;
     31        this.reasonService = reasonService;
    2632    }
    2733
     
    4854        model.addAttribute("createdByFirstName", user.getFirstName());
    4955        model.addAttribute("createdByLastName", user.getLastName());
     56        if (post.getApproved()) {
     57            model.addAttribute("approved", true);
     58        }
    5059        return "moderatorPost";
    5160    }
     
    5564        DonationPost post = donationPostService.getById(postid);
    5665        post.setApproved(true);
     66        post.setModerator((Moderator) SecurityContextHolder.getContext().getAuthentication().getPrincipal());
    5767        donationPostService.save(post);
    58         emailService.sendApprovalEmail(post.getUser().getEmail(),"CharitAbleMk: " + post.getTitle() + " has been approved", postid);
     68        emailService.sendApprovalEmail(post.getUser().getEmail(), "CharitAbleMk: " + post.getTitle() + " has been approved", postid);
    5969        return "redirect:/moderator/approval";
    6070    }
     
    6575        DonationPost post = donationPostService.getById(postid);
    6676        emailService.sendNoApprovalEmail(post.getUser().getEmail(), "CharitAbleMk: " + post.getTitle() + " has not been approved", description);
    67         List<String> fileForDeletion = post.getPhotosForDeletion();
     77        deleteDonationPost(post);
     78        return "redirect:/moderator/approval";
     79    }
     80
     81    @RequestMapping("/moderator/myApprovedPosts")
     82    public String myApprovedPosts(Model model) {
     83        Moderator moderator = (Moderator) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
     84        List<DonationPost> postList = donationPostService.findAllByModerator(moderator);
     85        if (postList.size() == 0) {
     86            model.addAttribute("noPosts", true);
     87            return "postApproval";
     88        }
     89        model.addAttribute("postList", postList);
     90        return "postApproval";
     91    }
     92
     93    @RequestMapping("/moderator/report")
     94    public String reportedPosts(Model model) {
     95        List<ReportPost> postList = reportPostService.findAll();
     96        if (postList.size() == 0) {
     97            model.addAttribute("noPosts", true);
     98            return "reportedPosts";
     99        }
     100        model.addAttribute("postList", postList);
     101        return "reportedPosts";
     102    }
     103
     104    @RequestMapping("/moderator/reportPost")
     105    public String report(@RequestParam Long postid, Model model) {
     106        ReportPost post = reportPostService.findById(postid);
     107        model.addAttribute("post", post);
     108        DonationPost donationPost = post.getDonationPost();
     109        AppUser user = donationPost.getUser();
     110        model.addAttribute("createdByFirstName", user.getFirstName());
     111        model.addAttribute("createdByLastName", user.getLastName());
     112        model.addAttribute("report", true);
     113        Moderator moderator = post.getDonationPost().getModerator();
     114        model.addAttribute("moderatorFirstName", moderator.getFirstName());
     115        model.addAttribute("moderatorLastName", moderator.getLastName());
     116
     117        return "reportPost";
     118    }
     119
     120    @RequestMapping("/moderator/dismiss")
     121    public String dismiss(@RequestParam Long postid) {
     122        ReportPost post = reportPostService.findById(postid);
     123        deleteReportPost(post);
     124        return "redirect:/moderator/reportedPosts";
     125    }
     126
     127    @RequestMapping("/moderator/deletePost")
     128    public String deletePost(@RequestParam Long postid,
     129                             @RequestParam String description) {
     130        ReportPost post = reportPostService.findById(postid);
     131        DonationPost donationPost = post.getDonationPost();
     132        emailService.sendDeletionEmail(donationPost.getUser().getEmail(), "CharitAbleMk: " + donationPost.getTitle() + " has been deleted", description);
     133        deleteReportPost(post);
     134        deleteDonationPost(donationPost);
     135        return "redirect:/moderator/approval";
     136    }
     137
     138    public void deleteDonationPost(DonationPost donationPost) {
     139        List<String> fileForDeletion = donationPost.getPhotosForDeletion();
    68140        for (String f : fileForDeletion) {
    69141            File file = new File(f);
    70142            file.delete();
    71143        }
    72         donationPostService.delete(post);
    73         return "redirect:/moderator/approval";
     144        donationPostService.delete(donationPost);
     145    }
     146
     147    public void deleteReportPost(ReportPost reportPost) {
     148        List<Reason> reasons = new ArrayList<>(reportPost.getReasons());
     149        if (reportPost.getReasons().size() > 0) {
     150            reportPost.getReasons().subList(0, reportPost.getReasons().size()).clear();
     151        }
     152        reportPostService.save(reportPost);
     153        for(Reason r: reasons) {
     154            reasonService.delete(r);
     155        }
     156        reportPostService.delete(reportPost);
    74157    }
    75158
  • src/main/java/it/finki/charitable/entities/DonationPost.java

    r5306751 rab49338  
    5555    private AppUser user;
    5656
     57    @ManyToOne
     58    private Moderator moderator;
     59
    5760    @OneToMany
    5861    private List<FundsCollected> fundsCollected = new ArrayList<>();
     
    204207    }
    205208
     209    public Moderator getModerator() {
     210        return moderator;
     211    }
     212
     213    public void setModerator(Moderator moderator) {
     214        this.moderator = moderator;
     215    }
     216
    206217    public List<FundsCollected> getFundsCollected() {
    207218        return fundsCollected;
  • src/main/java/it/finki/charitable/repository/DonationPostRepository.java

    r5306751 rab49338  
    33import it.finki.charitable.entities.AppUser;
    44import it.finki.charitable.entities.DonationPost;
     5import it.finki.charitable.entities.Moderator;
    56import org.springframework.data.jpa.repository.JpaRepository;
    67import org.springframework.stereotype.Repository;
     
    1213    List<DonationPost> findAllByUser(AppUser user);
    1314    List<DonationPost> findAllByApproved(Boolean approved);
     15    List<DonationPost> findAllByModerator(Moderator moderator);
    1416}
  • src/main/java/it/finki/charitable/services/DonationPostService.java

    r5306751 rab49338  
    33import it.finki.charitable.entities.AppUser;
    44import it.finki.charitable.entities.DonationPost;
     5import it.finki.charitable.entities.Moderator;
    56import it.finki.charitable.repository.DonationPostRepository;
    67import org.springframework.data.domain.Page;
     
    4546    }
    4647
     48    public List<DonationPost> findAllByModerator(Moderator moderator) {
     49        return donationPostRepository.findAllByModerator(moderator);
     50    }
     51
    4752    public void delete(DonationPost donationPost) {
    4853        donationPostRepository.delete(donationPost);
  • src/main/java/it/finki/charitable/services/EmailService.java

    r5306751 rab49338  
    4040        message.setSubject(subject);
    4141
    42         String text = "Sorry, your post hasn't been approved" + "\n" +
     42        String text = "Sorry, your post hasn't been approved\n" +
     43                "Moderator:\n" + description;
     44        message.setText(text);
     45        javaMailSender.send(message);
     46    }
     47
     48    public void sendDeletionEmail(String to, String subject, String description) {
     49        SimpleMailMessage message = new SimpleMailMessage();
     50        message.setTo(to);
     51        message.setSubject(subject);
     52
     53        String text = "Sorry, your post has been deleted\n" +
    4354                "Moderator:\n" + description;
    4455        message.setText(text);
  • src/main/resources/templates/common/navbar.html

    r5306751 rab49338  
    3838                    <a sec:authorize="isAnonymous()" type="button" class="btn btn-outline-light me-2" th:href="@{/login}">Login</a>
    3939                    <a sec:authorize="isAnonymous()" type="button" class="btn btn-warning" th:href="@{/register}">Sign-up</a>
    40                     <a sec:authorize="isAuthenticated()" type="button" class="btn btn-outline-light me-2" th:href="@{/userInformation}">My profile - <span th:text="${user.firstName}"></span></a>
     40                    <a sec:authorize="isAuthenticated() and hasAuthority('USER')" type="button" class="btn btn-outline-light me-2" th:href="@{/userInformation}">My profile - <span th:text="${user.firstName}"></span></a>
     41                    <a sec:authorize="isAuthenticated() and hasAuthority('MODERATOR')" type="button" class="btn btn-outline-light me-2" th:href="@{/moderator/myApprovedPosts}">My approved posts - <span th:text="${user.firstName} + ${user.lastName}"></span></a>
    4142                    <a sec:authorize="isAuthenticated()" type="button" class="btn btn-warning" th:href="@{/logout}">Logout</a>
    4243                </div>
  • src/main/resources/templates/moderatorPost.html

    r5306751 rab49338  
    2424                <div id="myCarousel" class="carousel carousel-dark slide card" data-bs-ride="carousel">
    2525                    <div class="carousel-indicators">
    26                         <button th:each="image, itrStat : ${post.moderatorPath}" type="button" data-bs-target="#myCarousel"
    27                                 th:data-bs-slide-to="${itrStat.index}" th:classappend="${itrStat.index} == 0 ? active"></button>
     26                        <button th:each="image, itrStat : ${post.moderatorPath}" type="button"
     27                                data-bs-target="#myCarousel"
     28                                th:data-bs-slide-to="${itrStat.index}"
     29                                th:classappend="${itrStat.index} == 0 ? active"></button>
    2830                    </div>
    2931                    <div class="carousel-inner">
    30                         <div th:each="image, itrStat : ${post.moderatorPath}" th:classappend="${itrStat.index} == 0 ? active"
     32                        <div th:each="image, itrStat : ${post.moderatorPath}"
     33                             th:classappend="${itrStat.index} == 0 ? active"
    3134                             class="carousel-item">
    3235                            <img class="card-img" th:src="${image}" style="object-fit: contain">
    3336                        </div>
    3437                    </div>
    35                     <button class="carousel-control-prev" type="button" data-bs-target="#myCarousel" data-bs-slide="prev">
     38                    <button class="carousel-control-prev" type="button" data-bs-target="#myCarousel"
     39                            data-bs-slide="prev">
    3640                        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    3741                        <span class="visually-hidden">Previous</span>
    3842                    </button>
    39                     <button class="carousel-control-next" type="button" data-bs-target="#myCarousel" data-bs-slide="next">
     43                    <button class="carousel-control-next" type="button" data-bs-target="#myCarousel"
     44                            data-bs-slide="next">
    4045                        <span class="carousel-control-next-icon" aria-hidden="true"></span>
    4146                        <span class="visually-hidden">Next</span>
     
    5055                <p th:text="${post.description}"></p>
    5156                <h5>Funds needed:</h5>
    52                 <p><span th:text="${total}"></span>/<span th:text="${post.fundsNeeded}"></span> - <span th:text="${post.currency}"></span></p>
     57                <p><span th:text="${total}"></span>/<span th:text="${post.fundsNeeded}"></span> - <span
     58                        th:text="${post.currency}"></span></p>
    5359                <h5>Date due:</h5>
    5460                <p th:text="${post.dateDue}"></p>
     
    6167                <p><span th:text="${createdByFirstName}"></span> <span th:text="${createdByLastName}"></span></p>
    6268
    63                 <a class="btn btn-success" th:href="@{/moderator/approvePost(postid=${post.id})}">Approve</a>
    64                 <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
    65                     Dont Approve
    66                 </button>
     69                <div th:unless="${approved}">
     70                    <a class="btn btn-success" th:href="@{/moderator/approvePost(postid=${post.id})}">Approve</a>
     71                    <button type="button" class="btn btn-danger" data-bs-toggle="modal"
     72                            data-bs-target="#staticBackdrop">
     73                        Dont Approve
     74                    </button>
     75                </div>
    6776
    6877                <!-- Modal -->
    69                 <div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
     78                <div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false"
     79                     tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
    7080                    <div class="modal-dialog modal-dialog-centered">
    7181                        <div class="modal-content">
    7282                            <div class="modal-header">
    73                                 <h5 class="modal-title" id="staticBackdropLabel">Donate</h5>
    74                                 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
     83                                <h5 class="modal-title" id="staticBackdropLabel">Dont approve</h5>
     84                                <button type="button" class="btn-close" data-bs-dismiss="modal"
     85                                        aria-label="Close"></button>
    7586                            </div>
    7687                            <div class="modal-body">
    7788                                <div class="card-body">
    78                                     <form th:action="@{/moderator/dontApprove(postid=${post.id})}" method="post" id="myForm">
     89                                    <form th:action="@{/moderator/dontApprove(postid=${post.id})}" method="post"
     90                                          id="myForm">
    7991                                        <label for="description">Description</label>
    80                                         <textarea class="form-control" id="description" name="description" rows="5"></textarea>
     92                                        <textarea class="form-control" id="description" name="description"
     93                                                  rows="5"></textarea>
    8194                                    </form>
    8295                                </div>
  • src/main/resources/templates/myProfile.html

    r5306751 rab49338  
    245245                                                Add collected funds
    246246                                            </button>
    247                                             <a class="btn btn-sm btn-danger"
    248                                                th:href="@{/deletePost(postid=${post.id})}">Delete</a>
    249247                                        </div>
    250248                                    </div>
  • src/main/resources/templates/post.html

    r5306751 rab49338  
    6060            <h5>Created by:</h5>
    6161            <p><span th:text="${createdByFirstName}"></span> <span th:text="${createdByLastName}"></span></p>
    62 
    63             <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
     62            <h5>Approved by:</h5>
     63            <p th:unless="${moderatorFirstName}">Not approved</p>
     64            <p><span th:text="${moderatorFirstName}"></span> <span th:text="${moderatorLastName}"></span></p>
     65
     66            <button sec:authorize="isAuthenticated()" type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
    6467                Donate
     68            </button>
     69            <a sec:authorize="isAnonymous()" type="button" class="btn btn-primary" th:href="@{/login}">
     70                Donate
     71            </a>
     72            <button type="button" class="btn btn-danger" data-bs-toggle="modal"
     73                    data-bs-target="#staticBackdrop1">
     74                Report
    6575            </button>
    6676
     
    126136                </div>
    127137            </div>
     138            <div class="modal fade" id="staticBackdrop1" data-bs-backdrop="static" data-bs-keyboard="false"
     139                 tabindex="-1" aria-labelledby="staticBackdropLabel1" aria-hidden="true">
     140                <div class="modal-dialog modal-dialog-centered">
     141                    <div class="modal-content">
     142                        <div class="modal-header">
     143                            <h5 class="modal-title" id="staticBackdropLabel1">Report post</h5>
     144                            <button type="button" class="btn-close" data-bs-dismiss="modal"
     145                                    aria-label="Close"></button>
     146                        </div>
     147                        <div class="modal-body">
     148                            <div class="card-body">
     149                                <form th:action="@{/report(postid=${post.id})}" method="post"
     150                                      id="myForm1">
     151                                    <label for="description">Description</label>
     152                                    <textarea class="form-control" id="description" name="description"
     153                                              rows="5"></textarea>
     154                                </form>
     155                            </div>
     156                        </div>
     157                        <div class="modal-footer">
     158                            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
     159                            <input type="submit" class="btn btn-primary" form="myForm1" value="Confirm">
     160                        </div>
     161                    </div>
     162                </div>
     163            </div>
    128164        </div>
    129165    </div>
Note: See TracChangeset for help on using the changeset viewer.