Ignore:
Timestamp:
02/05/26 18:59:39 (5 months ago)
Author:
Filip Gavrilovski <filipgavrilovski28@…>
Branches:
main
Children:
cb4a1da
Parents:
15782a6
Message:

add landing page with partial mock data

File:
1 edited

Legend:

Unmodified
Added
Removed
  • frontend/src/pages/LandingPage.tsx

    r15782a6 r694fc25  
     1import { useEffect, useState } from "react";
     2import axiosInstance from "../api/axiosInstance";
     3import type { Song } from "../utils/types";
     4import Nav from "./Nav";
     5
    16const LandingPage = () => {
    2         return <div>landing page</div>;
     7        const [songs, setSongs] = useState<Song[]>([]);
     8        const [loading, setLoading] = useState<boolean>(true);
     9        const [isSidebarOpen, setIsSidebarOpen] = useState<boolean>(true);
     10
     11        // mock data for recently listened songs
     12        const recentlyListened = [
     13                { id: 1, title: "Song One", artist: "Artist A", cover: "/favicon.png" },
     14                { id: 2, title: "Song Two", artist: "Artist B", cover: "/favicon.png" },
     15                { id: 3, title: "Song Three", artist: "Artist C", cover: "/favicon.png" },
     16                { id: 4, title: "Song Four", artist: "Artist D", cover: "/favicon.png" },
     17                { id: 5, title: "Song Five", artist: "Artist E", cover: "/favicon.png" },
     18        ];
     19
     20        // mock data for my playlists
     21        const playlists = [
     22                { id: 1, name: "My Favorites", songCount: 25 },
     23                { id: 2, name: "Workout Mix", songCount: 18 },
     24                { id: 3, name: "Chill Vibes", songCount: 32 },
     25                { id: 4, name: "Party Hits", songCount: 45 },
     26        ];
     27
     28        useEffect(() => {
     29                const fetchSongs = async () => {
     30                        try {
     31                                const response = await axiosInstance.get("/songs");
     32                                const data = response.data;
     33                                console.log("Fetched songs:", data);
     34                                setSongs(data);
     35                        } catch (error) {
     36                                console.error("Error fetching songs:", error);
     37                        } finally {
     38                                setLoading(false);
     39                        }
     40                };
     41                fetchSongs();
     42        }, []);
     43
     44        return (
     45                <>
     46                        <Nav
     47                                isSidebarOpen={isSidebarOpen}
     48                                onToggleSidebar={() => setIsSidebarOpen(!isSidebarOpen)}
     49                        />
     50                        <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white flex pt-20">
     51                                {/* Sidebar */}
     52                                <div
     53                                        className={`fixed left-0 top-0 h-full bg-[#121212] border-r border-white/10 transition-transform duration-300 ease-in-out z-100 ${
     54                                                isSidebarOpen ? "translate-x-0" : "-translate-x-full"
     55                                        } w-64 overflow-y-auto`}
     56                                >
     57                                        <div className="p-6">
     58                                                {/* Sidebar Header */}
     59                                                <div className="flex justify-between items-center mb-6">
     60                                                        <h2 className="text-xl font-bold text-white">Library</h2>
     61                                                        <button
     62                                                                onClick={() => setIsSidebarOpen(false)}
     63                                                                className="text-gray-400 hover:text-white transition-colors"
     64                                                                aria-label="Close sidebar"
     65                                                        >
     66                                                                <svg
     67                                                                        className="w-6 h-6"
     68                                                                        fill="none"
     69                                                                        stroke="currentColor"
     70                                                                        viewBox="0 0 24 24"
     71                                                                >
     72                                                                        <path
     73                                                                                strokeLinecap="round"
     74                                                                                strokeLinejoin="round"
     75                                                                                strokeWidth={2}
     76                                                                                d="M6 18L18 6M6 6l12 12"
     77                                                                        />
     78                                                                </svg>
     79                                                        </button>
     80                                                </div>
     81
     82                                                {/* Recently Listened */}
     83                                                <div className="mb-8">
     84                                                        <h3 className="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">
     85                                                                Recently Played
     86                                                        </h3>
     87                                                        <div className="space-y-3">
     88                                                                {recentlyListened.map((song) => (
     89                                                                        <div
     90                                                                                key={song.id}
     91                                                                                className="flex items-center gap-3 p-2 rounded-lg hover:bg-white/5 cursor-pointer transition-colors"
     92                                                                        >
     93                                                                                <img
     94                                                                                        src={song.cover}
     95                                                                                        alt={song.title}
     96                                                                                        className="w-10 h-10 rounded object-cover"
     97                                                                                />
     98                                                                                <div className="flex-1 min-w-0">
     99                                                                                        <p className="text-sm font-medium text-white truncate">
     100                                                                                                {song.title}
     101                                                                                        </p>
     102                                                                                        <p className="text-xs text-gray-400 truncate">
     103                                                                                                {song.artist}
     104                                                                                        </p>
     105                                                                                </div>
     106                                                                        </div>
     107                                                                ))}
     108                                                        </div>
     109                                                </div>
     110
     111                                                {/* Playlists */}
     112                                                <div>
     113                                                        <h3 className="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">
     114                                                                Your Playlists
     115                                                        </h3>
     116                                                        <div className="space-y-2">
     117                                                                {playlists.map((playlist) => (
     118                                                                        <div
     119                                                                                key={playlist.id}
     120                                                                                className="flex items-center justify-between p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors"
     121                                                                        >
     122                                                                                <div className="flex items-center gap-3">
     123                                                                                        <div className="w-10 h-10 bg-linear-to-br from-purple-500 to-pink-500 rounded flex items-center justify-center">
     124                                                                                                <svg
     125                                                                                                        className="w-5 h-5 text-white"
     126                                                                                                        fill="currentColor"
     127                                                                                                        viewBox="0 0 20 20"
     128                                                                                                >
     129                                                                                                        <path d="M18 3a1 1 0 00-1.196-.98l-10 2A1 1 0 006 5v9.114A4.369 4.369 0 005 14c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2V7.82l8-1.6v5.894A4.37 4.37 0 0015 12c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2V3z" />
     130                                                                                                </svg>
     131                                                                                        </div>
     132                                                                                        <div>
     133                                                                                                <p className="text-sm font-medium text-white">
     134                                                                                                        {playlist.name}
     135                                                                                                </p>
     136                                                                                                <p className="text-xs text-gray-400">
     137                                                                                                        {playlist.songCount} songs
     138                                                                                                </p>
     139                                                                                        </div>
     140                                                                                </div>
     141                                                                        </div>
     142                                                                ))}
     143                                                        </div>
     144                                                </div>
     145                                        </div>
     146                                </div>
     147
     148                                {/* Main Content */}
     149                                <div
     150                                        className={`flex-1 transition-all duration-300 ${
     151                                                isSidebarOpen ? "ml-64" : "ml-0"
     152                                        }`}
     153                                >
     154                                        <div className="p-8">
     155                                                {loading ? (
     156                                                        <div className="flex flex-col items-center justify-center min-h-[60vh] gap-6">
     157                                                                <div className="w-12 h-12 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin"></div>
     158                                                                <p className="text-xl text-gray-400">Loading songs...</p>
     159                                                        </div>
     160                                                ) : (
     161                                                        <div className="max-w-7xl mx-auto">
     162                                                                <div className="mb-12 pb-6 border-b border-white/10">
     163                                                                        <h1 className="text-5xl font-bold mb-3 pb-1 bg-linear-to-r from-[#1db954] to-[#1ed760] bg-clip-text text-transparent">
     164                                                                                Top Songs
     165                                                                        </h1>
     166                                                                        <p className="text-xl text-gray-400">
     167                                                                                Listen to the newest tracks on FinkWave
     168                                                                        </p>
     169                                                                </div>
     170                                                                <div className="grid grid-cols-[repeat(auto-fill,minmax(220px,1fr))] gap-8 py-4">
     171                                                                        {songs.map((song) => (
     172                                                                                <div
     173                                                                                        key={song.id}
     174                                                                                        className="bg-[#282828] rounded-xl overflow-hidden cursor-pointer shadow-lg transition-all duration-300 ease-in-out hover:-translate-y-2 hover:shadow-2xl group"
     175                                                                                >
     176                                                                                        <div className="relative w-full pt-[100%] overflow-hidden bg-[#181818]">
     177                                                                                                <img
     178                                                                                                        src={song.cover || "/favicon.png"}
     179                                                                                                        alt={song.title}
     180                                                                                                        className="absolute top-0 left-0 w-full h-full object-cover"
     181                                                                                                        onError={(e) => {
     182                                                                                                                (e.target as HTMLImageElement).src = "/favicon.png";
     183                                                                                                        }}
     184                                                                                                />
     185                                                                                                <div className="absolute top-0 left-0 w-full h-full bg-black/60 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
     186                                                                                                        <div className="w-15 h-15 rounded-full bg-[#1db954] flex items-center justify-center text-2xl text-black shadow-[0_4px_12px_rgba(29,185,84,0.5)]">
     187                                                                                                                ▶
     188                                                                                                        </div>
     189                                                                                                </div>
     190                                                                                        </div>
     191                                                                                        <div className="p-4 flex flex-col items-center">
     192                                                                                                <h3 className="text-lg font-semibold mb-2 text-white overflow-hidden text-ellipsis whitespace-nowrap">
     193                                                                                                        {song.title}
     194                                                                                                </h3>
     195                                                                                                <p className="text-sm text-gray-400 mb-3 overflow-hidden text-ellipsis whitespace-nowrap">
     196                                                                                                        {"<album>"}
     197                                                                                                </p>
     198                                                                                                <p className="text-sm text-gray-400 mb-3 overflow-hidden text-ellipsis whitespace-nowrap">
     199                                                                                                        {song.releasedBy}
     200                                                                                                </p>
     201                                                                                                {/* <div className="inline-block bg-[#1db954]/20 px-3 py-1 rounded-xl border border-[#1db954]/40">
     202                                                                                                        <span className="text-xs text-[#1db954] font-medium uppercase tracking-wider">
     203                                                                                                                {song.genre}
     204                                                                                                        </span>
     205                                                                                                </div> */}
     206                                                                                        </div>
     207                                                                                </div>
     208                                                                        ))}
     209                                                                </div>
     210                                                        </div>
     211                                                )}
     212                                        </div>
     213                                </div>
     214                        </div>
     215                </>
     216        );
    3217};
    4218
Note: See TracChangeset for help on using the changeset viewer.