diff --git a/README.md b/README.md index 1ebe379f5f423c7dcc8775d39ffd571117fb89f8..31fdad470809c35f1711b8f825f76dc08d118af4 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,28 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: - -- Configure the top-level `parserOptions` property like this: - -```js - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['./tsconfig.json', './tsconfig.node.json'], - tsconfigRootDir: __dirname, - }, -``` - -- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` -- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list +# Premium Podcast App + +## Deskripsi Singkat Aplikasi +Aplikasi Premium Podcast App adalah versi premium dari aplikasi php yang telah dibuat sebelumnya. Pada versi premium, pengguna memiliki keleluasaan yang lebih melalui fitur yang ditawarkan, misalnya seperti queue dimana pengguna dapat mengantrikan podcast yang ingin diputarnya dan akan berjalan secara otomatis nantinya. Aplikasi ini dibangun menggunakan Vite + React + Typescript + +## Tampilan Layar + +### Halaman Home + +### Halaman Search + +### Halaman Library + +### Halaman Queue + +### Halaman Podcast + +### Halaman Episode + + +## Pembagian Tugas +Halaman Home : 13521149 +Halaman Search : 13521119 +Halaman Library : 13521079 +Halaman Queue : 13521149 +Halaman Podcast : 13521079 +Halaman Episode : 13521079 +Halaman Profile : 13521119 \ No newline at end of file diff --git a/docs/halaman-episode.png b/docs/halaman-episode.png new file mode 100644 index 0000000000000000000000000000000000000000..4fcc3295b8d131b8fba48547fba2a03674bc7cc1 Binary files /dev/null and b/docs/halaman-episode.png differ diff --git a/docs/halaman-home.png b/docs/halaman-home.png new file mode 100644 index 0000000000000000000000000000000000000000..151e36ed971d2a31a46c0476490d2f3e960f6ce1 Binary files /dev/null and b/docs/halaman-home.png differ diff --git a/docs/halaman-library.png b/docs/halaman-library.png new file mode 100644 index 0000000000000000000000000000000000000000..947f9cad68bbeddd13a9408a029ba24b637d42a9 Binary files /dev/null and b/docs/halaman-library.png differ diff --git a/docs/halaman-podcast.png b/docs/halaman-podcast.png new file mode 100644 index 0000000000000000000000000000000000000000..a8e8b88faddaf0552346678568fc036f53e7ec06 Binary files /dev/null and b/docs/halaman-podcast.png differ diff --git a/docs/halaman-queue.png b/docs/halaman-queue.png new file mode 100644 index 0000000000000000000000000000000000000000..e1d399f0bf0fe84ab2855e5ef38849d405f049b8 Binary files /dev/null and b/docs/halaman-queue.png differ diff --git a/src/components/EpisodeList.tsx b/src/components/EpisodeList.tsx index d54493a5c1d43874f687bacc8fb10d2dc96360e6..fae0887817b6f4ebf3f316f32bd633d63d214c61 100644 --- a/src/components/EpisodeList.tsx +++ b/src/components/EpisodeList.tsx @@ -100,7 +100,7 @@ export default function EpisodeList({ return ( <div onClick={handleNavigate} - className="cursor-pointer group/item flex items-center w-[1100px] h-[110px] rounded-xl bg-white hover:bg-NAVY-5 text-black hover:text-white" + className="cursor-pointer group/item flex items-center w-full h-[110px] rounded-xl bg-white hover:bg-NAVY-5 text-black hover:text-white" > <h1 className="h2 ml-[30px] mr-[20px]">{order}</h1> <img diff --git a/src/components/PodcastHeader.tsx b/src/components/PodcastHeader.tsx index a1aaa4819441e8e1bc874f86eab070b7f171bb58..418b9101f4d021f3f76d38136b0554e8fcdca3de 100644 --- a/src/components/PodcastHeader.tsx +++ b/src/components/PodcastHeader.tsx @@ -3,8 +3,9 @@ import Placeholder from "../assets/placeholder_image.jpg"; import PlayIcon from "../assets/play-icon.svg"; import PlusIcon from "../assets/plus-icon.svg"; import { Queue, useQueue, useQueueDispatch } from "../contexts/QueueContext"; -// import { useState, useEffect } from "react"; -// import { cardProps } from "./LibraryCard"; +import { useState, useEffect } from "react"; +import { cardProps } from "./LibraryCard"; +import { useNavigate } from "react-router-dom" export type headerProps = { category: string; @@ -31,35 +32,46 @@ export default function PodcastHeader({ const queue = useQueue(); const dispatchQueue = useQueueDispatch(); - // const [libraryData, setLibraryData] = useState<cardProps[]>([]); + const [libraryData, setLibraryData] = useState<cardProps[]>([]); + const [isVisible, setIsVisible] = useState(false); + const navigate = useNavigate(); - // useEffect(() => { - // (async () => { - // const resLibaryData = await axios.get( - // `${import.meta.env.VITE_REST_URL}/library/${userId}`, - // { - // headers: { - // Authorization: `Bearer ${localStorage.getItem("token")}`, - // }, - // } - // ); - // setLibraryData(resLibaryData.data.playlists); - // })(); - // }, [userId]); - - // const handleAddPodcastToLibrary = async () => { - // const axiosInstance = axios.create({ - // headers: { - // Authorization: `Bearer ${localStorage.getItem("token")}`, - // }, - // }); - - // await axiosInstance.post(`${import.meta.env.VITE_REST_URL}/playlist/podcast/${id_podcast}`, { - // idPlaylist: , - // idPodcast: , - // }) - - // } + useEffect(() => { + (async () => { + const resLibaryData = await axios.get( + `${import.meta.env.VITE_REST_URL}/library`, + { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); + setLibraryData(resLibaryData.data.playlists); + })(); + }, []); + + const toggleVisibility = () => { + setIsVisible(!isVisible); + } + + const handleNavigateLib = () => { + navigate(`/library`); + } + + const handleAddPodcastToLibrary = async (idPlaylist:number) => { + + const axiosInstance = axios.create({ + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + }); + + await axiosInstance.post(`${import.meta.env.VITE_REST_URL}/playlist/podcast/${id_podcast}`, { + idPlaylist: idPlaylist, + idPodcast: id_podcast, + }) + + } const handleAddToQueue = async (e: React.MouseEvent<HTMLElement>) => { e.stopPropagation(); @@ -99,7 +111,7 @@ export default function PodcastHeader({ return ( <div className="block"> - <div className="w-[950px] inline-flex mt-[20px]"> + <div className="w-full inline-flex mt-[20px]"> <div className=""> <div className="w-[225px] h-[225px]"> <img @@ -128,7 +140,9 @@ export default function PodcastHeader({ </div> <div className="block"> - <p className="b3 text-gray-600 ">{description}</p> + <p className="b3 text-gray-600 md:max-xl:text-[12px]"> + {description} + </p> </div> </div> </div> @@ -142,6 +156,7 @@ export default function PodcastHeader({ > Add To Library <img + onClick={toggleVisibility} className="inline ml-[45px]" width={16} height={16} @@ -150,6 +165,29 @@ export default function PodcastHeader({ /> </button> + {isVisible? ( + <div className="w-[100px] h-[100px] overflow-y-scroll rounded-xl shadow-lg bg-WHITE text-black"> + {libraryData?.map((data:cardProps) => ( + <button onClick={()=>handleAddPodcastToLibrary(data.id_playlist)}>{data.title}</button> + ))} + </div> + ) : + <button + data-te-toggle="tooltip" + title="create new library" + className=" w-[225px] h-[50px] text-NAVY-5 bg-white rounded-[16px] h4 leading-4 shadow-lg" + > + New Library + <img + onClick={handleNavigateLib} + className="inline ml-[45px]" + width={16} + height={16} + src={PlusIcon} + alt="plus icon" + /> + </button>} + <button onClick={handleAddToQueue} data-te-toggle="tooltip" diff --git a/src/pages/podcast/index.tsx b/src/pages/podcast/index.tsx index d523b89d9b4870860244cde22353101e05a09a88..9cbf9712831d9aaed7b87cb6ae70a78316363e38 100644 --- a/src/pages/podcast/index.tsx +++ b/src/pages/podcast/index.tsx @@ -30,7 +30,7 @@ export default function PodcastPage(): JSX.Element { import.meta.env.VITE_REST_URL }/podcast/${podcastId}?premium=${searchParams.get("premium")}` ); - if(!resPodcast.data.podcast) { + if (!resPodcast.data.podcast) { navigate(`/`); } setPodcastHeader(resPodcast.data.podcast); @@ -39,7 +39,7 @@ export default function PodcastPage(): JSX.Element { }, [podcastId, searchParams, navigate]); return ( - <div className="ml-[100px]"> + <div className="ml-[32px] xl:ml-[100px]"> {podcastHeader ? ( <PodcastHeader {...podcastHeader} @@ -52,7 +52,7 @@ export default function PodcastPage(): JSX.Element { <hr className="h-px mt-[30px] ml-[-100px] bg-black bg-opacity-40" /> </div> - <section className="mt-[20px] overflow-y-scroll h-[60vh] mb-[60px]"> + <section className="mt-[20px] overflow-y-scroll h-[60vh] pb-[60px] ml-[-16px] xl:ml-0"> {episodes?.map((episode: episodeProps, idx: number) => ( <Episode key={idx}