mirror of
https://github.com/apricote/Listory.git
synced 2026-01-13 21:21:02 +00:00
feat(frontend): show recent listens
This commit is contained in:
parent
32dcd84964
commit
49bff95ea5
12 changed files with 217 additions and 16 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { User } from "../api/user";
|
||||
import { User } from "../api/entities/user";
|
||||
import { useAuth } from "../hooks/use-auth";
|
||||
import { SpotifyLogo } from "../icons/Spotify";
|
||||
|
||||
|
|
@ -12,12 +12,17 @@ export const NavBar: React.FC = () => {
|
|||
<div className="flex items-center flex-shrink-0 text-white mr-6">
|
||||
<span className="font-semibold text-xl tracking-tight">Listory</span>
|
||||
</div>
|
||||
<div className="w-full block flex-grow lg:flex lg:items-center lg:w-auto">
|
||||
<div className="w-full block flex-grow lg:flex lg:items-center lg:w-auto ">
|
||||
<div className="text-sm lg:flex-grow">
|
||||
{user && (
|
||||
<Link to="/">
|
||||
<NavItem>Home</NavItem>
|
||||
</Link>
|
||||
<>
|
||||
<Link to="/">
|
||||
<NavItem>Home</NavItem>
|
||||
</Link>
|
||||
<Link to="/listens">
|
||||
<NavItem>Your Listens</NavItem>
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -38,10 +43,14 @@ export const NavBar: React.FC = () => {
|
|||
|
||||
const NavUserInfo: React.FC<{ user: User }> = ({ user }) => {
|
||||
return (
|
||||
<div className="flex items-center mr-4">
|
||||
<div className="flex items-center mr-4 mt-4 lg:mt-0">
|
||||
<span className="text-green-200 text-sm">{user.displayName}</span>
|
||||
{user.photo && (
|
||||
<img className="w-6 h-6 rounded-full ml-4" src={user.photo}></img>
|
||||
<img
|
||||
className="w-6 h-6 rounded-full ml-4"
|
||||
src={user.photo}
|
||||
alt="Profile picture of logged in user"
|
||||
></img>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
93
frontend/src/components/RecentListens.tsx
Normal file
93
frontend/src/components/RecentListens.tsx
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { useAuth } from "../hooks/use-auth";
|
||||
import { Listen } from "../api/entities/listen";
|
||||
import { getRecentListens } from "../api/api";
|
||||
import { Redirect } from "react-router-dom";
|
||||
import { formatDistanceToNow } from "date-fns";
|
||||
|
||||
const LISTENS_PER_PAGE = 15;
|
||||
|
||||
export const RecentListens: React.FC = () => {
|
||||
const { user } = useAuth();
|
||||
|
||||
const [page, setPage] = useState(1);
|
||||
const [totalPages, setTotalPages] = useState(1);
|
||||
const [listens, setListens] = useState<Listen[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const listensFromApi = await getRecentListens({
|
||||
page,
|
||||
limit: LISTENS_PER_PAGE,
|
||||
});
|
||||
|
||||
if (totalPages !== listensFromApi.meta.totalPages) {
|
||||
setTotalPages(listensFromApi.meta.totalPages);
|
||||
}
|
||||
setListens(listensFromApi.items);
|
||||
} catch (err) {
|
||||
console.error("Error while fetching recent listens:", err);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
})();
|
||||
}, [user, page, totalPages]);
|
||||
|
||||
if (!user) {
|
||||
return <Redirect to="/" />;
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div>
|
||||
<span>Loading Listens</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>Recent listens</p>
|
||||
<div>
|
||||
{listens.length === 0 && (
|
||||
<div>
|
||||
<p>Could not find any listens!</p>
|
||||
</div>
|
||||
)}
|
||||
{listens.map((listen) => (
|
||||
<ListenItem listen={listen} />
|
||||
))}
|
||||
</div>
|
||||
<div>
|
||||
<p>Page: {page}</p>
|
||||
{page !== 1 && (
|
||||
<p>
|
||||
<button onClick={() => setPage(page - 1)}>Previous Page</button>
|
||||
</p>
|
||||
)}
|
||||
{page !== totalPages && (
|
||||
<p>
|
||||
<button onClick={() => setPage(page + 1)}>Next Page</button>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ListenItem: React.FC<{ listen: Listen }> = ({ listen }) => {
|
||||
const trackName = listen.track.name;
|
||||
const artists = listen.track.artists.map((artist) => artist.name).join(", ");
|
||||
const timeAgo = formatDistanceToNow(new Date(listen.playedAt), {
|
||||
addSuffix: true,
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
{trackName} - {artists} - {timeAgo}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue