Changes in / [c807e22:ed8f998]


Ignore:
Files:
7 edited

Legend:

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

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

    rc807e22 red8f998  
    1 import { useRef, useState } from "react";
     1import { use, 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";
     7import { useAuth } from "../context/authContext";
    78
    89export interface SongItemData {
     
    5051  const navigate = useNavigate();
    5152  const { play, currentSong } = usePlayer();
     53  const { user } = useAuth();
    5254  const [internalOpen, setInternalOpen] = useState(false);
    5355  const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 });
     
    165167
    166168      {/* Like button */}
    167       {onLikeToggle && (
     169      {user && onLikeToggle && (
    168170        <button
    169171          onClick={(e) => {
     
    187189
    188190      {/* Three-dot menu */}
    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                   });
     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                  }
    214218                }
     219                setPlaylistOpen(true);
    215220              }
    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>
     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 */}
    238244    </div>
    239245  );
  • frontend/src/components/userProfile/ArtistView.tsx

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

    rc807e22 red8f998  
    33import type { BaseNonAdminUser } from "../../utils/types";
    44import { useEffect } from "react";
     5import { useAuth } from "../../context/authContext";
    56
    67interface ModalProps {
     
    1819}: ModalProps) => {
    1920  const navigate = useNavigate();
     21  const { user } = useAuth();
    2022  useEffect(() => {
    2123    document.body.style.overflow = "hidden";
     
    7274                  </div>
    7375                </div>
    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>
     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                )}
    8588              </div>
    8689            ))
  • frontend/src/pages/LandingPage.tsx

    rc807e22 red8f998  
    1414} from "../utils/types";
    1515import { toEmbedUrl } from "../utils/utils";
     16import { useAuth } from "../context/authContext";
    1617
    1718const CATEGORIES: { value: SearchCategory; label: string }[] = [
     
    2526  const navigate = useNavigate();
    2627  const { play, currentSong } = usePlayer();
     28  const { user } = useAuth();
    2729  const [songs, setSongs] = useState<Song[]>([]);
    2830  const [loading, setLoading] = useState<boolean>(true);
    2931
    30   // search state
    3132  const [searchInput, setSearchInput] = useState("");
    3233  const [activeQuery, setActiveQuery] = useState("");
     
    3637  const [hasSearched, setHasSearched] = useState(false);
    3738
    38   // playlist dropdown state
    3939  const [openPlaylistDropdown, setOpenPlaylistDropdown] = useState<
    4040    number | null
     
    415415                            {song.releasedBy}
    416416                          </p>
    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">
     417                          {user && (
     418                            <div className="flex items-center justify-between mt-4 pt-3 border-t border-white/10">
     419                              {/* Like button */}
    457420                              <button
    458421                                onClick={(e) => {
    459422                                  e.stopPropagation();
    460                                   togglePlaylistDropdown(song.id);
     423                                  toggleLike(song.id);
    461424                                }}
    462425                                className="text-gray-400 hover:text-[#1db954] transition-colors cursor-pointer"
    463                                 aria-label="Add to playlist"
     426                                aria-label={
     427                                  song.isLikedByCurrentUser
     428                                    ? "Unlike song"
     429                                    : "Like song"
     430                                }
    464431                              >
    465                                 <svg
    466                                   className="w-6 h-6"
    467                                   fill="none"
    468                                   stroke="currentColor"
    469                                   viewBox="0 0 24 24"
     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                                )}
     454                              </button>
     455
     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"
    470465                                >
    471                                   <path
    472                                     strokeLinecap="round"
    473                                     strokeLinejoin="round"
    474                                     strokeWidth={2}
    475                                     d="M12 4v16m8-8H4"
    476                                   />
    477                                 </svg>
    478                               </button>
    479 
    480                               <PlaylistDropdown
    481                                 songId={song.id}
    482                                 isOpen={openPlaylistDropdown === song.id}
    483                                 onClose={() => setOpenPlaylistDropdown(null)}
    484                                 direction="above"
    485                               />
     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>
    486488                            </div>
    487                           </div>
     489                          )}
    488490                        </div>
    489491                      </div>
  • frontend/src/pages/SongDetail.tsx

    rc807e22 red8f998  
    407407              )}
    408408            </h2>
    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"
     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"
    418413              >
    419                 <path
    420                   strokeLinecap="round"
    421                   strokeLinejoin="round"
    422                   strokeWidth={2}
    423                   d="M12 4v16m8-8H4"
    424                 />
    425               </svg>
    426               Add Review
    427             </button>
     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            )}
    428430          </div>
    429431
  • frontend/src/pages/UserDetail.tsx

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