Changeset fd81a18


Ignore:
Timestamp:
01/26/26 18:34:45 (6 months ago)
Author:
Dimitar Arsov <dimitararsov04@…>
Branches:
main
Children:
a3ae097
Parents:
efe76fe
Message:

add playlists to user profile

Files:
4 added
16 edited

Legend:

Unmodified
Added
Removed
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/NonAdminUserController.java

    refe76fe rfd81a18  
    11package com.ukim.finki.develop.finkwave.controller;
    22
    3 import com.ukim.finki.develop.finkwave.model.NonAdminUser;
    43import com.ukim.finki.develop.finkwave.model.dto.NonAdminUserDTO;
    54import com.ukim.finki.develop.finkwave.service.NonAdminUserService;
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/ArtistContributionDTO.java

    refe76fe rfd81a18  
    99@AllArgsConstructor
    1010public class ArtistContributionDTO {
    11     private String role;
    1211    private Long musicalEntityId;
    1312    private String title;
     13    private String role;
    1414    private String entityType;
    1515}
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/ArtistMusicalEntitiesDTO.java

    refe76fe rfd81a18  
    55import lombok.AllArgsConstructor;
    66import lombok.Getter;
     7import lombok.NoArgsConstructor;
    78import lombok.Setter;
    89
     
    1213@Setter
    1314@AllArgsConstructor
     15@NoArgsConstructor
    1416public class ArtistMusicalEntitiesDTO {
    15     private List<Song> songs;
    16     private List<Album> albums;
     17    private List<ArtistContributionDTO> contributions;
    1718}
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/ListenerLikesDTO.java

    refe76fe rfd81a18  
    11package com.ukim.finki.develop.finkwave.model.dto;
    2 
     2import java.util.*;
    33import lombok.AllArgsConstructor;
    44import lombok.Getter;
     5import lombok.NoArgsConstructor;
    56import lombok.Setter;
    67
     
    89@Getter
    910@AllArgsConstructor
     11@NoArgsConstructor
    1012public class ListenerLikesDTO {
    11     private Long entityId;
    12     private String entityTitle;
    13     private String entityGenre;
    14     private String entityType;
     13    private List<MusicalEntityDTO> likedEntities;
     14   
     15
    1516}
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/NonAdminUserDTO.java

    refe76fe rfd81a18  
    11package com.ukim.finki.develop.finkwave.model.dto;
    22
    3 import lombok.AllArgsConstructor;
     3import com.ukim.finki.develop.finkwave.model.Playlist;
    44import lombok.Getter;
    5 import lombok.NoArgsConstructor;
    65import lombok.Setter;
    76
    87import java.util.List;
    98
     9
    1010@Getter
    1111@Setter
    12 @AllArgsConstructor
    13 @NoArgsConstructor
     12
    1413public class NonAdminUserDTO {
    15     private Long Id;
     14    private Long id;
    1615    private String username;
    1716    private String fullName;
    18     private String profilePhoto;
    19     private Long followerCount;
    20     private Long followingCount;
    2117    private String userType;
    22     // is it best practice to have this empty in listeners?
    23     private List<ArtistContributionDTO> contributions;
    24     private List<ListenerLikesDTO> likedEntities;
     18    private Long followers;
     19    private Long following;
     20
     21
     22   
     23    private ArtistMusicalEntitiesDTO musicalEntities;
     24   
     25    private ListenerLikesDTO likes;
     26    private List<PlaylistDTO>createdPlaylists;
    2527}
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/ArtistContributionRepository.java

    refe76fe rfd81a18  
    22
    33import org.springframework.data.jpa.repository.JpaRepository;
     4import org.springframework.data.jpa.repository.Query;
    45import org.springframework.stereotype.Repository;
    5 
     6import org.springframework.data.repository.query.Param;
    67import com.ukim.finki.develop.finkwave.model.ArtistContribution;
    78import com.ukim.finki.develop.finkwave.model.ArtistContributionId;
     
    1213public interface ArtistContributionRepository extends JpaRepository<ArtistContribution, ArtistContributionId> {
    1314
    14     List<ArtistContribution>findAllByArtist_Id(Long id);
     15    @Query("SELECT ac.musicalEntity.id,ac.musicalEntity.title,ac.role, "+
     16        "CASE WHEN s.id IS NOT NULL THEN 'Song' "+
     17        "WHEN a.id IS NOT NULL THEN 'Album' "+
     18        "ELSE 'Unknown' END "+
     19        "FROM ArtistContribution ac "+
     20        "LEFT JOIN Song s  ON s.musicalEntities.id=ac.musicalEntity.id "+
     21        "LEFT JOIN Album a ON a.musicalEntities.id=ac.musicalEntity.id "+
     22        "WHERE ac.artist.id=:artistId")
     23    List<Object[]>findContributionsByArtistId(@Param("artistId")Long artistId);
    1524}
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/ArtistRepository.java

    refe76fe rfd81a18  
    11package com.ukim.finki.develop.finkwave.repository;
    22
     3import java.util.Optional;
     4
    35import org.springframework.data.jpa.repository.JpaRepository;
     6import org.springframework.data.jpa.repository.Query;
     7import org.springframework.data.repository.query.Param;
    48import org.springframework.stereotype.Repository;
    59
     
    812@Repository
    913public interface ArtistRepository extends JpaRepository<Artist, Long> {
     14
     15    @Query("SELECT DISTINCT a FROM Artist a "+
     16        "JOIN FETCH a.nonAdminUser nu "+
     17        "JOIN FETCH nu.user "+
     18        "WHERE a.id=:artistId")
     19    Optional<Artist>findByIdWithUser(@Param("artistId")Long artistId);
     20
    1021}
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/LikeRepository.java

    refe76fe rfd81a18  
    22
    33import org.springframework.data.jpa.repository.JpaRepository;
     4import org.springframework.data.jpa.repository.Query;
     5import org.springframework.data.repository.query.Param;
    46import org.springframework.stereotype.Repository;
    57
     
    1113@Repository
    1214public interface LikeRepository extends JpaRepository<Like, LikeId> {
    13     List<Like>getLikesByListener_Id(Long id);
     15    @Query("SELECT l.musicalEntity.id, l.musicalEntity.title,l.musicalEntity.genre, " +
     16           "CASE WHEN s.id IS NOT NULL THEN 'SONG' " +
     17           "WHEN a.id IS NOT NULL THEN 'ALBUM' " +
     18           "ELSE 'UNKNOWN' END " +
     19           "FROM Like l " +
     20           "LEFT JOIN Song s ON s.musicalEntities.id = l.musicalEntity.id " +
     21           "LEFT JOIN Album a ON a.musicalEntities.id = l.musicalEntity.id " +
     22           "WHERE l.listener.id = :listenerId")
     23    List<Object[]> findLikedEntitiesWithTypeByListenerId(@Param("listenerId") Long listenerId);
    1424}
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/ListenerRepository.java

    refe76fe rfd81a18  
    11package com.ukim.finki.develop.finkwave.repository;
    22
     3import java.util.Optional;
     4
    35import org.springframework.data.jpa.repository.JpaRepository;
     6import org.springframework.data.jpa.repository.Query;
     7import org.springframework.data.repository.query.Param;
    48import org.springframework.stereotype.Repository;
    59
     
    812@Repository
    913public interface ListenerRepository extends JpaRepository<Listener, Long> {
     14    @Query("SELECT DISTINCT l FROM Listener l " +
     15           "JOIN FETCH l.nonAdminUser nu " +
     16           "JOIN FETCH nu.user " +
     17           "WHERE l.id = :listenerId")
     18    Optional<Listener> findByIdWithUser(@Param("listenerId") Long listenerId);
    1019}
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/PlaylistRepository.java

    refe76fe rfd81a18  
    22
    33import org.springframework.data.jpa.repository.JpaRepository;
     4import org.springframework.data.jpa.repository.Query;
     5import org.springframework.data.repository.query.Param;
    46import org.springframework.stereotype.Repository;
    57
    68import com.ukim.finki.develop.finkwave.model.Playlist;
    79
     10import java.util.List;
     11
    812@Repository
    913public interface PlaylistRepository extends JpaRepository<Playlist, Long> {
     14
     15
     16    @Query("SELECT DISTINCT p FROM Playlist p " +
     17            "JOIN FETCH p.createdBy l " +
     18            "JOIN FETCH l.nonAdminUser nu " +
     19            "JOIN FETCH nu.user u " +
     20            "WHERE l.id = :creatorId")
     21    List<Playlist> findByCreatorId(@Param("creatorId") Long creatorId);
     22
     23
     24
     25
     26
    1027}
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/ArtistService.java

    refe76fe rfd81a18  
    11package com.ukim.finki.develop.finkwave.service;
    22
    3 import com.ukim.finki.develop.finkwave.model.ArtistContribution;
    4 import com.ukim.finki.develop.finkwave.model.Song;
    53import com.ukim.finki.develop.finkwave.model.dto.ArtistContributionDTO;
    6 import com.ukim.finki.develop.finkwave.model.dto.ArtistMusicalEntitiesDTO;
    74import com.ukim.finki.develop.finkwave.repository.ArtistContributionRepository;
     5
     6import org.springframework.transaction.annotation.Transactional;
    87import lombok.AllArgsConstructor;
    98import org.springframework.stereotype.Service;
    109
    11 import java.util.ArrayList;
    1210import java.util.List;
    1311import java.util.stream.Collectors;
     
    1715public class ArtistService {
    1816
    19     private final MusicalEntityService musicalEntityService;
    20     private final ArtistContributionRepository contributionRepository;
     17    private final ArtistContributionRepository artistContributionRepository;
    2118
    2219
    23     public List<ArtistContributionDTO> getArtistContributions(Long id){
     20    @Transactional(readOnly=true)
     21    public List<ArtistContributionDTO> getArtistContributions(Long artistId){
     22        List<Object[]>results=artistContributionRepository.findContributionsByArtistId(artistId);
    2423
    25         ArtistMusicalEntitiesDTO artistMusicalEntities=musicalEntityService.getArtistMusicalEntities(id);
    26         List<ArtistContribution>contributions=contributionRepository.findAllByArtist_Id(id);
    27         return contributions.stream().map(c -> {
    28             boolean isSong = artistMusicalEntities.getSongs().stream()
    29                     .anyMatch(s -> s.getId().equals(c.getMusicalEntity().getId()));
    30 
    31             return new ArtistContributionDTO(
    32                     c.getRole(),
    33                     c.getMusicalEntity().getId(),
    34                     c.getMusicalEntity().getTitle(),
    35                     isSong ? "Song" : "Album"
    36             );
    37         }).collect(Collectors.toList());
     24        return results.stream()
     25        .map(row->new ArtistContributionDTO((Long)row[0], (String)row[1], (String)row[2], (String)row[3]))
     26        .collect(Collectors.toList());
    3827    }
    3928
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/ListenerService.java

    refe76fe rfd81a18  
    11package com.ukim.finki.develop.finkwave.service;
    22
    3 import com.ukim.finki.develop.finkwave.model.Album;
    4 import com.ukim.finki.develop.finkwave.model.Like;
    5 import com.ukim.finki.develop.finkwave.model.MusicalEntity;
    6 import com.ukim.finki.develop.finkwave.model.Song;
    7 import com.ukim.finki.develop.finkwave.model.dto.ArtistMusicalEntitiesDTO;
     3import com.ukim.finki.develop.finkwave.model.Playlist;
    84import com.ukim.finki.develop.finkwave.model.dto.ListenerLikesDTO;
    9 import com.ukim.finki.develop.finkwave.repository.AlbumRepository;
     5import com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDTO;
     6import com.ukim.finki.develop.finkwave.model.dto.PlaylistDTO;
    107import com.ukim.finki.develop.finkwave.repository.LikeRepository;
    11 import com.ukim.finki.develop.finkwave.repository.SongRepository;
     8import com.ukim.finki.develop.finkwave.repository.PlaylistRepository;
    129import lombok.AllArgsConstructor;
    1310import org.springframework.stereotype.Service;
    14 
    15 import java.util.ArrayList;
     11import org.springframework.transaction.annotation.Transactional;
    1612import java.util.List;
    17 import java.util.stream.Collectors;
    1813
    1914@Service
     
    2116public class ListenerService {
    2217    private final LikeRepository likeRepository;
    23     private final MusicalEntityService musicalEntityService;
     18    private final PlaylistRepository playlistRepository;
     19    @Transactional(readOnly = true)
     20    public ListenerLikesDTO getLikedEntities(Long listenerId) {
     21        List<Object[]> results = likeRepository.findLikedEntitiesWithTypeByListenerId(listenerId);
    2422
    25     public List<ListenerLikesDTO>getLikedEntities(Long listenerId){
    26         List<Like>likes=likeRepository.getLikesByListener_Id(listenerId);
     23        List<MusicalEntityDTO>likedEntities=results.stream()
     24        .map(row->new MusicalEntityDTO((Long)row[0], (String)row[1], (String)row[2],(String)row[3]))
     25        .toList();
     26       
     27        ListenerLikesDTO dto=new ListenerLikesDTO();
     28        dto.setLikedEntities(likedEntities);
     29        return dto;
     30    }
     31
     32    @Transactional(readOnly = true)
     33    public List<Playlist>getPlaylistsCreatedByUser(Long listenerId){
     34        return playlistRepository.findByCreatorId(listenerId);
     35    }
     36}
    2737
    2838
    29         return likes.stream().map(l -> new ListenerLikesDTO(
    30                 l.getMusicalEntity().getId(),
    31                 l.getMusicalEntity().getTitle(),
    32                 l.getMusicalEntity().getGenre(),
    33                 musicalEntityService.getEntityType(l.getMusicalEntity().getId())
    34         )).toList();
    35     }
    36 
    37 
    38 }
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/MusicalEntityService.java

    refe76fe rfd81a18  
    1 package com.ukim.finki.develop.finkwave.service;
     1// package com.ukim.finki.develop.finkwave.service;
    22
    3 import com.ukim.finki.develop.finkwave.model.Album;
    4 import com.ukim.finki.develop.finkwave.model.MusicalEntity;
    5 import com.ukim.finki.develop.finkwave.model.Song;
    6 import com.ukim.finki.develop.finkwave.model.dto.ArtistMusicalEntitiesDTO;
    7 import com.ukim.finki.develop.finkwave.repository.AlbumRepository;
    8 import com.ukim.finki.develop.finkwave.repository.MusicalEntityRepository;
    9 import com.ukim.finki.develop.finkwave.repository.SongRepository;
    10 import lombok.AllArgsConstructor;
    11 import org.springframework.stereotype.Service;
     3// import com.ukim.finki.develop.finkwave.model.Album;
     4// import com.ukim.finki.develop.finkwave.model.MusicalEntity;
     5// import com.ukim.finki.develop.finkwave.model.Song;
     6// import com.ukim.finki.develop.finkwave.model.dto.ArtistMusicalEntitiesDTO;
     7// import com.ukim.finki.develop.finkwave.repository.AlbumRepository;
     8// import com.ukim.finki.develop.finkwave.repository.MusicalEntityRepository;
     9// import com.ukim.finki.develop.finkwave.repository.SongRepository;
     10// import lombok.AllArgsConstructor;
     11// import org.springframework.stereotype.Service;
    1212
    13 import java.util.ArrayList;
    14 import java.util.Collections;
    15 import java.util.List;
    16 import java.util.stream.Collectors;
     13// import java.util.ArrayList;
     14// import java.util.Collections;
     15// import java.util.List;
     16// import java.util.stream.Collectors;
    1717
    18 @Service
    19 @AllArgsConstructor
    20 public class MusicalEntityService {
     18// @Service
     19// @AllArgsConstructor
     20// public class MusicalEntityService {
    2121
    22     private final MusicalEntityRepository musicalEntityRepository;
    23     private final SongRepository songRepository;
    24     private final AlbumRepository albumRepository;
     22//     private final MusicalEntityRepository musicalEntityRepository;
     23//     private final SongRepository songRepository;
     24//     private final AlbumRepository albumRepository;
    2525
    26     public ArtistMusicalEntitiesDTO getArtistMusicalEntities(Long artistId){
    27         List<Long>entitiesIDs=musicalEntityRepository.findAllByReleasedBy_Id(artistId).stream()
    28                 .map(MusicalEntity::getId)
    29                 .toList();
     26//     public ArtistMusicalEntitiesDTO getArtistMusicalEntities(Long artistId){
     27//         List<Long>entitiesIDs=musicalEntityRepository.findAllByReleasedBy_Id(artistId).stream()
     28//                 .map(MusicalEntity::getId)
     29//                 .toList();
    3030
    31         if (entitiesIDs.isEmpty()) {
    32             return new ArtistMusicalEntitiesDTO(Collections.emptyList(), Collections.emptyList());
    33         }
     31//         if (entitiesIDs.isEmpty()) {
     32//             return new ArtistMusicalEntitiesDTO(Collections.emptyList(), Collections.emptyList());
     33//         }
    3434
    35         // bulk fetching
    36         List<Song> songs = songRepository.findAllByIdIn(entitiesIDs);
     35//         // bulk fetching
     36//         List<Song> songs = songRepository.findAllByIdIn(entitiesIDs);
    3737
    38         List<Album> albums = albumRepository.findAllByIdIn(entitiesIDs);
     38//         List<Album> albums = albumRepository.findAllByIdIn(entitiesIDs);
    3939
    40         return new ArtistMusicalEntitiesDTO(songs, albums);
    41     }
     40//         return new ArtistMusicalEntitiesDTO(songs, albums);
     41//     }
    4242
    43     public String getEntityType(Long id) {
    44         if (songRepository.existsById(id)) return "Song";
    45         if (albumRepository.existsById(id)) return "Album";
    46         return "Unknown";
    47     }
     43//     public String getEntityType(Long id) {
     44//         if (songRepository.existsById(id)) return "Song";
     45//         if (albumRepository.existsById(id)) return "Album";
     46//         return "Unknown";
     47//     }
    4848
    49 }
     49// }
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/NonAdminUserService.java

    refe76fe rfd81a18  
    44import com.ukim.finki.develop.finkwave.model.Listener;
    55import com.ukim.finki.develop.finkwave.model.NonAdminUser;
    6 import com.ukim.finki.develop.finkwave.model.dto.ArtistContributionDTO;
    7 import com.ukim.finki.develop.finkwave.model.dto.NonAdminUserDTO;
     6import com.ukim.finki.develop.finkwave.model.Playlist;
     7import com.ukim.finki.develop.finkwave.model.dto.*;
    88import com.ukim.finki.develop.finkwave.repository.ArtistRepository;
    99import com.ukim.finki.develop.finkwave.repository.FollowRepository;
     
    1313import lombok.AllArgsConstructor;
    1414import org.springframework.stereotype.Service;
    15 
     15import org.springframework.transaction.annotation.Transactional;
    1616import java.util.List;
    17 import java.util.Optional;
    1817import java.util.stream.Collectors;
    1918
     
    2726    private final ArtistService artistService;
    2827    private final ListenerService listenerService;
     28    private final FollowRepository followRepository;
    2929
     30    @Transactional(readOnly = true)
    3031    public List<NonAdminUserDTO> getAllUsers() {
    3132        return nonAdminUserRepository.findAllWithUser().stream()
    3233                .map(user -> {
    3334                    String type = determineType(user.getId());
    34                     return mapper.toDTO(user, type);
     35                    Long followers = followRepository.countByFolloweeId(user.getId());
     36                    Long following = followRepository.countByFollowerId(user.getId());
     37                    return mapper.toDTO(user, type, followers, following);
    3538                })
    3639                .collect(Collectors.toList());
    3740    }
    3841
     42    @Transactional(readOnly = true)
    3943    public NonAdminUserDTO getById(Long id) {
    40         NonAdminUser userEntity = nonAdminUserRepository.findById(id)
    41                 .orElseThrow(() -> new RuntimeException("User not found with id: " + id));
    42 
    43         String type = determineType(id);
    44         NonAdminUserDTO dto = mapper.toDTO(userEntity, type);
    45         if (type.equals("Artist")){
    46             List<ArtistContributionDTO> workHistory = artistService.getArtistContributions(id);
    47             dto.setContributions(workHistory);
    48         }else if(type.equals("Listener")){
    49             dto.setLikedEntities(listenerService.getLikedEntities(id));
     44        Long followers=followRepository.countByFolloweeId(id);
     45        Long following=followRepository.countByFollowerId(id);
     46   
     47        if (artistRepository.existsById(id)) {
     48            return getArtistProfile(id,followers,following);
    5049        }
    51 
    52        return dto;
     50     
     51        if (listenerRepository.existsById(id)) {
     52            return getListenerProfile(id,followers,following);
     53        }
     54       
     55        throw new RuntimeException("User not found with id: " + id);
    5356    }
    5457
     58    private NonAdminUserDTO getArtistProfile(Long artistId, Long followers,Long following) {
     59        Artist artist = artistRepository.findByIdWithUser(artistId)
     60            .orElseThrow(() -> new RuntimeException("Artist not found with id: " + artistId));
     61       
     62     
     63        ArtistMusicalEntitiesDTO entitiesDTO = new ArtistMusicalEntitiesDTO();
     64        entitiesDTO.setContributions(artistService.getArtistContributions(artistId));
     65       
     66        return mapper.toArtistDTO(artist, entitiesDTO,followers,following);
     67    }
     68
     69    private NonAdminUserDTO getListenerProfile(Long listenerId, Long followers,Long following) {
     70        Listener listener = listenerRepository.findByIdWithUser(listenerId)
     71            .orElseThrow(() -> new RuntimeException("Listener not found with id: " + listenerId));
     72       
     73       
     74        ListenerLikesDTO likesDTO = listenerService.getLikedEntities(listenerId);
     75        List<PlaylistDTO>playlists=listenerService.getPlaylistsCreatedByUser(listenerId).stream()
     76                .map(p->new PlaylistDTO(
     77                        p.getId(),
     78                        p.getName(),
     79                        p.getCover(),
     80                        p.getCreatedBy().getNonAdminUser().getUser().getFullName()
     81                )).toList();
     82       
     83        return mapper.toListenerDTO(listener, likesDTO,followers,following,playlists);
     84    }
    5585
    5686    private String determineType(Long id) {
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/mappers/NonAdminUserMapper.java

    refe76fe rfd81a18  
    11package com.ukim.finki.develop.finkwave.service.mappers;
    22
    3 import com.ukim.finki.develop.finkwave.model.ArtistContribution;
    4 import com.ukim.finki.develop.finkwave.model.MusicalEntity;
     3import com.ukim.finki.develop.finkwave.model.Artist;
     4
     5import com.ukim.finki.develop.finkwave.model.Listener;
     6
     7import com.ukim.finki.develop.finkwave.model.Playlist;
     8import com.ukim.finki.develop.finkwave.model.dto.ArtistMusicalEntitiesDTO;
     9import com.ukim.finki.develop.finkwave.model.dto.ListenerLikesDTO;
     10import com.ukim.finki.develop.finkwave.model.dto.NonAdminUserDTO;
    511import com.ukim.finki.develop.finkwave.model.NonAdminUser;
    6 import com.ukim.finki.develop.finkwave.model.dto.ArtistContributionDTO;
    7 import com.ukim.finki.develop.finkwave.model.dto.NonAdminUserDTO;
    8 import com.ukim.finki.develop.finkwave.repository.ArtistContributionRepository;
    9 import com.ukim.finki.develop.finkwave.repository.FollowRepository;
    10 import com.ukim.finki.develop.finkwave.repository.MusicalEntityRepository;
    11 import lombok.AllArgsConstructor;
     12import com.ukim.finki.develop.finkwave.model.dto.PlaylistDTO;
    1213import org.springframework.stereotype.Component;
    1314
    14 import java.util.ArrayList;
    1515import java.util.List;
    1616
     17
    1718@Component
    18 @AllArgsConstructor
    1919public class NonAdminUserMapper {
    20     private final FollowRepository followRepository;
    2120
     21    public NonAdminUserDTO toArtistDTO(Artist artist, ArtistMusicalEntitiesDTO entitiesDTO, Long followers, Long following) {
     22        NonAdminUserDTO dto = createBaseDTO(
     23            artist.getNonAdminUser(),
     24            "ARTIST",
     25            followers,
     26            following
     27        );
     28        dto.setMusicalEntities(entitiesDTO);
     29        return dto;
     30    }
    2231
     32    public NonAdminUserDTO toListenerDTO(Listener listener, ListenerLikesDTO likesDTO, Long followers, Long following, List<PlaylistDTO>playlists) {
     33        NonAdminUserDTO dto = createBaseDTO(
     34            listener.getNonAdminUser(),
     35            "LISTENER",
     36            followers,
     37            following
     38        );
     39        dto.setLikes(likesDTO);
     40        dto.setCreatedPlaylists(playlists);
     41        return dto;
     42    }
    2343
    24     public NonAdminUserDTO toDTO(NonAdminUser entity, String type) {
    25         if (entity == null) return null;
     44    public NonAdminUserDTO toDTO(NonAdminUser user, String type,Long followers,Long following) {
     45        return createBaseDTO(user, type, followers, following);
     46    }
    2647
    27         return new NonAdminUserDTO(
    28                 entity.getId(),
    29                 entity.getUser().getUsername(),
    30                 entity.getUser().getFullName(),
    31                 entity.getUser().getProfilePhoto(),
    32                 followRepository.countByFolloweeId(entity.getId()),
    33                 followRepository.countByFollowerId(entity.getId()),
    34                 type,
    35                 new ArrayList<>(),
    36                 new ArrayList<>()
    37         );
     48    private NonAdminUserDTO createBaseDTO(NonAdminUser user, String userType, Long followers, Long following) {
     49        NonAdminUserDTO dto = new NonAdminUserDTO();
     50        dto.setId(user.getId());
     51        dto.setUsername(user.getUser().getUsername());
     52        dto.setFullName(user.getUser().getFullName());
     53        dto.setUserType(userType);
     54        dto.setFollowers(followers);
     55        dto.setFollowing(following);
     56        return dto;
    3857    }
    3958}
  • frontend/src/components/userProfile/UserDetail.tsx

    refe76fe rfd81a18  
    11import { useEffect, useState } from "react";
    22import { useParams, useNavigate } from "react-router-dom";
     3import ArtistView from "./ArtistView";
     4import ListenerView from "./ListenerView";
     5
     6interface MusicalEntityDTO {
     7  id: number;
     8  title: string;
     9  genre: string;
     10  type: string;
     11}
     12
     13interface ArtistContributionDTO {
     14  musicalEntityId: number;
     15  title: string;
     16  role: string;
     17  entityType: string;
     18}
     19
     20interface Playlist {
     21  id: number;
     22  name: string;
     23  cover: string;
     24  creatorName: string;
     25}
    326
    427interface User {
     
    629  username: string;
    730  fullName: string;
    8   followerCount: number;
    9   followingCount: number;
    1031  userType: string;
    11   contributions?: {
    12     role: string;
    13     title: string;
    14     musicalEntityId: number;
    15     entityType: string;
    16   }[];
     32  followers: number;
     33  following: number;
    1734
    18   likedEntities?: {
    19     entityId: number;
    20     entityTitle: string;
    21     entityGenre: string;
    22     entityType: string;
    23   }[];
     35  musicalEntities?: {
     36    contributions: ArtistContributionDTO[];
     37  };
     38
     39  likes?: {
     40    likedEntities: MusicalEntityDTO[];
     41  };
     42
     43  createdPlaylists?: Playlist[];
    2444}
    2545
     
    3454      const response = await fetch(`http://localhost:8080/users/${userId}`);
    3555      const data = await response.json();
     56      console.log("Fetched user data:", data);
    3657      setUser(data);
    3758    };
     
    4364  return (
    4465    <div className="container mx-auto p-6">
    45       {/* <button
    46         onClick={() => navigate("/allUsers")}
     66      <button
     67        onClick={() => navigate(-1)}
    4768        className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
    4869      >
    49         ← Back to All Users
    50       </button> */}
     70        ← Back
     71      </button>
     72
    5173      <div className="bg-white shadow-lg rounded-lg p-8">
    52         <h1 className="text-4xl font-bold mb-4">{user.fullName}</h1>
    53         <p className="text-gray-600 text-lg mb-2">Username: @{user.username}</p>
    54         <p className="text-gray-600 text-lg mb-2">
    55           Followers: {user.followerCount}
    56         </p>
    57         <p className="text-gray-600 text-lg mb-2">
    58           Following: {user.followingCount}
    59         </p>
    60         <p>Type: {user.userType}</p>
    61         {user.userType === "Artist" && user.contributions && (
    62           <div className="mt-8 border-t pt-6">
    63             <h2 className="text-2xl font-bold mb-4">Discography</h2>
    64             <div className="grid gap-3">
    65               {user.contributions.map((item, index) => (
    66                 <div
    67                   key={index}
    68                   className="p-4 border rounded flex justify-between items-center"
    69                 >
    70                   <div>
    71                     <p className="font-semibold">{item.title}</p>
    72                     <p className="text-sm text-gray-500">{item.entityType}</p>
    73                   </div>
    74                   <span className="bg-gray-100 px-3 py-1 rounded-full text-sm font-medium">
    75                     {item.role}
    76                   </span>
    77                   <span className="bg-gray-100 px-3 py-1 rounded-full text-sm font-medium">
    78                     {item.musicalEntityId}
    79                   </span>
    80                 </div>
    81               ))}
     74        {/* Profile Header */}
     75        <div className="flex items-start gap-6 mb-8">
     76          {/* Profile Photo */}
     77          <div className="shrink-0">
     78            <div className="w-32 h-32 rounded-full bg-linear-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white text-4xl font-bold shadow-lg">
     79              {user.fullName.charAt(0).toUpperCase()}
    8280            </div>
    8381          </div>
     82
     83          {/* User Info */}
     84          <div className="flex-1">
     85            <h1 className="text-4xl font-bold mb-2">{user.fullName}</h1>
     86            <span className="inline-block px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium mb-4">
     87              {user.userType}
     88            </span>
     89
     90            {/* Followers/Following Stats */}
     91            <div className="flex gap-6 mb-4 text-gray-700">
     92              <div className="flex flex-col">
     93                <span className="text-2xl font-bold">{user.followers}</span>
     94                <span className="text-sm text-gray-500">Followers</span>
     95              </div>
     96              <div className="flex flex-col">
     97                <span className="text-2xl font-bold">{user.following}</span>
     98                <span className="text-sm text-gray-500">Following</span>
     99              </div>
     100            </div>
     101
     102            <button className="px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors font-medium">
     103              Follow
     104            </button>
     105          </div>
     106        </div>
     107
     108        {user.userType === "ARTIST" && user.musicalEntities?.contributions && (
     109          <ArtistView contributions={user.musicalEntities.contributions} />
    84110        )}
    85111
    86         {user.userType === "Listener" && user.likedEntities && (
    87           <div>
    88             <h3 className="text-2xl font-bold mb-4">Liked Songs & Albums</h3>
    89             <div className="grid gap-2">
    90               {user.likedEntities.map((like) => (
    91                 <div
    92                   key={like.entityId}
    93                   className="p-3 bg-gray-50 rounded flex justify-between"
    94                 >
    95                   <span>{like.entityTitle}</span>
    96                   <span className="text-sm text-gray-400">
    97                     {like.entityType}
    98                   </span>
    99                   <span className="text-sm text-gray-400">
    100                     {like.entityGenre}
    101                   </span>
    102                 </div>
    103               ))}
    104             </div>
    105           </div>
     112        {user.userType === "LISTENER" && user.likes?.likedEntities && (
     113          <ListenerView
     114            likedEntities={user.likes.likedEntities}
     115            playlists={user.createdPlaylists}
     116          />
    106117        )}
    107118      </div>
Note: See TracChangeset for help on using the changeset viewer.