Changes in / [ed8f998:c807e22]


Ignore:
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/AuthService.java

    red8f998 rc807e22  
    122122
    123123        return userRepository.findByUsername(username).map(User::getId)
    124                 .orElseThrow(UnauthenticatedException::new);
     124                .orElseThrow(UserNotFoundException::new);
    125125    }
    126126
  • frontend/src/components/SongItem.tsx

    red8f998 rc807e22  
    1 import { use, useRef, useState } from "react";
     1import { useRef, useState } from "react";
    22import { useNavigate } from "react-router-dom";
    33import { baseURL } from "../api/axiosInstance";
     
    55import { toEmbedUrl } from "../utils/utils";
    66import PlaylistDropdown from "./playlist/PlaylistDropdown";
    7 import { useAuth } from "../context/authContext";
    87
    98export interface SongItemData {
     
    5150  const navigate = useNavigate();
    5251  const { play, currentSong } = usePlayer();
    53   const { user } = useAuth();
    5452  const [internalOpen, setInternalOpen] = useState(false);
    5553  const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 });
     
    167165
    168166      {/* Like button */}
    169       {user && onLikeToggle && (
     167      {onLikeToggle && (
    170168        <button
    171169          onClick={(e) => {
     
    189187
    190188      {/* Three-dot menu */}
    191       {user && (
    192         <div className="relative">
    193           <button
    194             ref={buttonRef}
    195             onClick={(e) => {
    196               e.stopPropagation();
    197               if (playlistOpen) {
    198                 setPlaylistOpen(false);
    199               } else {
    200                 if (buttonRef.current) {
    201                   const rect = buttonRef.current.getBoundingClientRect();
    202                   const spaceBelow = window.innerHeight - rect.bottom;
    203                   const dropdownHeight = 260;
    204 
    205                   if (spaceBelow < dropdownHeight) {
    206                     setDropdownDirection("above");
    207                     setDropdownPosition({
    208                       top: rect.top - 8,
    209                       left: rect.right - 224,
    210                     });
    211                   } else {
    212                     setDropdownDirection("below");
    213                     setDropdownPosition({
    214                       top: rect.bottom + 8,
    215                       left: rect.right - 224,
    216                     });
    217                   }
     189      <div className="relative">
     190        <button
     191          ref={buttonRef}
     192          onClick={(e) => {
     193            e.stopPropagation();
     194            if (playlistOpen) {
     195              setPlaylistOpen(false);
     196            } else {
     197              if (buttonRef.current) {
     198                const rect = buttonRef.current.getBoundingClientRect();
     199                const spaceBelow = window.innerHeight - rect.bottom;
     200                const dropdownHeight = 260;
     201
     202                if (spaceBelow < dropdownHeight) {
     203                  setDropdownDirection("above");
     204                  setDropdownPosition({
     205                    top: rect.top - 8,
     206                    left: rect.right - 224,
     207                  });
     208                } else {
     209                  setDropdownDirection("below");
     210                  setDropdownPosition({
     211                    top: rect.bottom + 8,
     212                    left: rect.right - 224,
     213                  });
    218214                }
    219                 setPlaylistOpen(true);
    220215              }
    221             }}
    222             className="p-2 hover:bg-white/10 rounded-full transition-colors cursor-pointer text-gray-400 hover:text-white"
    223             aria-label="More options"
    224           >
    225             <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
    226               <circle cx="12" cy="5" r="1.5" />
    227               <circle cx="12" cy="12" r="1.5" />
    228               <circle cx="12" cy="19" r="1.5" />
    229             </svg>
    230           </button>
    231 
    232           <PlaylistDropdown
    233             songId={song.id}
    234             isOpen={playlistOpen}
    235             onClose={() => setPlaylistOpen(false)}
    236             position={dropdownPosition}
    237             usePortal={true}
    238             direction={dropdownDirection}
    239           />
    240         </div>
    241       )}
    242 
    243       {/* Three-dot menu */}
     216              setPlaylistOpen(true);
     217            }
     218          }}
     219          className="p-2 hover:bg-white/10 rounded-full transition-colors cursor-pointer text-gray-400 hover:text-white"
     220          aria-label="More options"
     221        >
     222          <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
     223            <circle cx="12" cy="5" r="1.5" />
     224            <circle cx="12" cy="12" r="1.5" />
     225            <circle cx="12" cy="19" r="1.5" />
     226          </svg>
     227        </button>
     228
     229        <PlaylistDropdown
     230          songId={song.id}
     231          isOpen={playlistOpen}
     232          onClose={() => setPlaylistOpen(false)}
     233          position={dropdownPosition}
     234          usePortal={true}
     235          direction={dropdownDirection}
     236        />
     237      </div>
    244238    </div>
    245239  );
  • frontend/src/components/userProfile/ArtistView.tsx

    red8f998 rc807e22  
    66import type { ArtistContribution } from "../../utils/types";
    77import SongItem from "../SongItem";
    8 import { useAuth } from "../../context/authContext";
    98
    109interface ArtistViewProps {
  • frontend/src/components/userProfile/UserListModal.tsx

    red8f998 rc807e22  
    33import type { BaseNonAdminUser } from "../../utils/types";
    44import { useEffect } from "react";
    5 import { useAuth } from "../../context/authContext";
    65
    76interface ModalProps {
     
    1918}: ModalProps) => {
    2019  const navigate = useNavigate();
    21   const { user } = useAuth();
    2220  useEffect(() => {
    2321    document.body.style.overflow = "hidden";
     
    7472                  </div>
    7573                </div>
    76                 {user && (
    77                   <button
    78                     onClick={() => onFollowToggle(u.username)}
    79                     className={`px-4 py-1.5 text-sm font-medium rounded-full transition-colors cursor-pointer ${
    80                       u.isFollowedByCurrentUser
    81                         ? "bg-white/10 text-white hover:bg-white/20"
    82                         : "bg-[#1db954] text-black hover:bg-[#1ed760]"
    83                     }`}
    84                   >
    85                     {u.isFollowedByCurrentUser ? "Following" : "Follow"}
    86                   </button>
    87                 )}
     74
     75                <button
     76                  onClick={() => onFollowToggle(u.username)}
     77                  className={`px-4 py-1.5 text-sm font-medium rounded-full transition-colors cursor-pointer ${
     78                    u.isFollowedByCurrentUser
     79                      ? "bg-white/10 text-white hover:bg-white/20"
     80                      : "bg-[#1db954] text-black hover:bg-[#1ed760]"
     81                  }`}
     82                >
     83                  {u.isFollowedByCurrentUser ? "Following" : "Follow"}
     84                </button>
    8885              </div>
    8986            ))
  • frontend/src/pages/LandingPage.tsx

    red8f998 rc807e22  
    1414} from "../utils/types";
    1515import { toEmbedUrl } from "../utils/utils";
    16 import { useAuth } from "../context/authContext";
    1716
    1817const CATEGORIES: { value: SearchCategory; label: string }[] = [
     
    2625  const navigate = useNavigate();
    2726  const { play, currentSong } = usePlayer();
    28   const { user } = useAuth();
    2927  const [songs, setSongs] = useState<Song[]>([]);
    3028  const [loading, setLoading] = useState<boolean>(true);
    3129
     30  // search state
    3231  const [searchInput, setSearchInput] = useState("");
    3332  const [activeQuery, setActiveQuery] = useState("");
     
    3736  const [hasSearched, setHasSearched] = useState(false);
    3837
     38  // playlist dropdown state
    3939  const [openPlaylistDropdown, setOpenPlaylistDropdown] = useState<
    4040    number | null
     
    415415                            {song.releasedBy}
    416416                          </p>
    417                           {user && (
    418                             <div className="flex items-center justify-between mt-4 pt-3 border-t border-white/10">
    419                               {/* Like button */}
     417                          <div className="flex items-center justify-between mt-4 pt-3 border-t border-white/10">
     418                            {/* Like button */}
     419                            <button
     420                              onClick={(e) => {
     421                                e.stopPropagation();
     422                                toggleLike(song.id);
     423                              }}
     424                              className="text-gray-400 hover:text-[#1db954] transition-colors cursor-pointer"
     425                              aria-label={
     426                                song.isLikedByCurrentUser
     427                                  ? "Unlike song"
     428                                  : "Like song"
     429                              }
     430                            >
     431                              {song.isLikedByCurrentUser ? (
     432                                <svg
     433                                  className="w-6 h-6 fill-[#1db954]"
     434                                  viewBox="0 0 24 24"
     435                                >
     436                                  <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
     437                                </svg>
     438                              ) : (
     439                                <svg
     440                                  className="w-6 h-6"
     441                                  fill="none"
     442                                  stroke="currentColor"
     443                                  viewBox="0 0 24 24"
     444                                >
     445                                  <path
     446                                    strokeLinecap="round"
     447                                    strokeLinejoin="round"
     448                                    strokeWidth={2}
     449                                    d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
     450                                  />
     451                                </svg>
     452                              )}
     453                            </button>
     454
     455                            {/* Add to playlist button */}
     456                            <div className="relative">
    420457                              <button
    421458                                onClick={(e) => {
    422459                                  e.stopPropagation();
    423                                   toggleLike(song.id);
     460                                  togglePlaylistDropdown(song.id);
    424461                                }}
    425462                                className="text-gray-400 hover:text-[#1db954] transition-colors cursor-pointer"
    426                                 aria-label={
    427                                   song.isLikedByCurrentUser
    428                                     ? "Unlike song"
    429                                     : "Like song"
    430                                 }
     463                                aria-label="Add to playlist"
    431464                              >
    432                                 {song.isLikedByCurrentUser ? (
    433                                   <svg
    434                                     className="w-6 h-6 fill-[#1db954]"
    435                                     viewBox="0 0 24 24"
    436                                   >
    437                                     <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
    438                                   </svg>
    439                                 ) : (
    440                                   <svg
    441                                     className="w-6 h-6"
    442                                     fill="none"
    443                                     stroke="currentColor"
    444                                     viewBox="0 0 24 24"
    445                                   >
    446                                     <path
    447                                       strokeLinecap="round"
    448                                       strokeLinejoin="round"
    449                                       strokeWidth={2}
    450                                       d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
    451                                     />
    452                                   </svg>
    453                                 )}
     465                                <svg
     466                                  className="w-6 h-6"
     467                                  fill="none"
     468                                  stroke="currentColor"
     469                                  viewBox="0 0 24 24"
     470                                >
     471                                  <path
     472                                    strokeLinecap="round"
     473                                    strokeLinejoin="round"
     474                                    strokeWidth={2}
     475                                    d="M12 4v16m8-8H4"
     476                                  />
     477                                </svg>
    454478                              </button>
    455479
    456                               {/* Add to playlist button */}
    457                               <div className="relative">
    458                                 <button
    459                                   onClick={(e) => {
    460                                     e.stopPropagation();
    461                                     togglePlaylistDropdown(song.id);
    462                                   }}
    463                                   className="text-gray-400 hover:text-[#1db954] transition-colors cursor-pointer"
    464                                   aria-label="Add to playlist"
    465                                 >
    466                                   <svg
    467                                     className="w-6 h-6"
    468                                     fill="none"
    469                                     stroke="currentColor"
    470                                     viewBox="0 0 24 24"
    471                                   >
    472                                     <path
    473                                       strokeLinecap="round"
    474                                       strokeLinejoin="round"
    475                                       strokeWidth={2}
    476                                       d="M12 4v16m8-8H4"
    477                                     />
    478                                   </svg>
    479                                 </button>
    480 
    481                                 <PlaylistDropdown
    482                                   songId={song.id}
    483                                   isOpen={openPlaylistDropdown === song.id}
    484                                   onClose={() => setOpenPlaylistDropdown(null)}
    485                                   direction="above"
    486                                 />
    487                               </div>
     480                              <PlaylistDropdown
     481                                songId={song.id}
     482                                isOpen={openPlaylistDropdown === song.id}
     483                                onClose={() => setOpenPlaylistDropdown(null)}
     484                                direction="above"
     485                              />
    488486                            </div>
    489                           )}
     487                          </div>
    490488                        </div>
    491489                      </div>
  • frontend/src/pages/SongDetail.tsx

    red8f998 rc807e22  
    407407              )}
    408408            </h2>
    409             {user != null && (
    410               <button
    411                 onClick={() => setShowReviewModal(true)}
    412                 className="flex items-center gap-2 bg-[#1db954] hover:bg-[#1ed760] text-black text-sm font-semibold px-4 py-2 rounded-full transition-colors"
     409            <button
     410              onClick={() => setShowReviewModal(true)}
     411              className="flex items-center gap-2 bg-[#1db954] hover:bg-[#1ed760] text-black text-sm font-semibold px-4 py-2 rounded-full transition-colors"
     412            >
     413              <svg
     414                className="w-4 h-4"
     415                fill="none"
     416                stroke="currentColor"
     417                viewBox="0 0 24 24"
    413418              >
    414                 <svg
    415                   className="w-4 h-4"
    416                   fill="none"
    417                   stroke="currentColor"
    418                   viewBox="0 0 24 24"
    419                 >
    420                   <path
    421                     strokeLinecap="round"
    422                     strokeLinejoin="round"
    423                     strokeWidth={2}
    424                     d="M12 4v16m8-8H4"
    425                   />
    426                 </svg>
    427                 Add Review
    428               </button>
    429             )}
     419                <path
     420                  strokeLinecap="round"
     421                  strokeLinejoin="round"
     422                  strokeWidth={2}
     423                  d="M12 4v16m8-8H4"
     424                />
     425              </svg>
     426              Add Review
     427            </button>
    430428          </div>
    431429
  • frontend/src/pages/UserDetail.tsx

    red8f998 rc807e22  
    259259
    260260            {/* Follow button - hidden on own profile */}
    261             {currentUser && !isOwnProfile && (
     261            {!isOwnProfile && (
    262262              <div className="mt-4">
    263263                <button
Note: See TracChangeset for help on using the changeset viewer.