Skip to content

Commit

Permalink
Show search in modal view
Browse files Browse the repository at this point in the history
  • Loading branch information
JRomainG committed Dec 26, 2023
1 parent 80e0f95 commit dcd2c0a
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 38 deletions.
4 changes: 2 additions & 2 deletions src/app/page.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.main {
margin: 10px;
.body {
padding: 10px;
}
51 changes: 35 additions & 16 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,41 @@
import { getQueue, getCurrentPlayback } from "@/utils/queue";
import styles from "./page.module.css";
import { redirect } from "next/navigation";
import TitleBar from "./titlebar";
import TrackCover from "./track_cover";
import TrackList from "./track_list";
import Form from "./form";

interface Props {
queue: any;
currentPlayback: any;
}

export function Body({ queue, currentPlayback }: Props) {
return (
<div className={styles.body}>
<h1>Currently playing</h1>
{(() => {
if (
currentPlayback?.isPlaying &&
currentPlayback.item?.type === "track"
) {
return <TrackCover currentPlayback={currentPlayback} />;
} else {
return <div>Play any song on Spotify to get started!</div>;
}
})()}
<br />
<h1>Queue</h1>
{(() => {
if (queue !== null && queue.length > 0) {
return <TrackList items={queue}></TrackList>;
} else {
return <div>Your song queue is empty.</div>;
}
})()}
</div>
);
}

export default async function Home() {
const [queue, currentPlayback] = await Promise.all([
Expand All @@ -14,21 +46,8 @@ export default async function Home() {

return (
<main className={styles.main}>
<Form />

{currentPlayback?.isPlaying && currentPlayback.item?.type === "track" && (
<>
<h1>Currently playing</h1>
<TrackCover currentPlayback={currentPlayback} />
</>
)}

{queue.length > 0 && (
<>
<h1>Queue</h1>
<TrackList items={queue}></TrackList>
</>
)}
<TitleBar />
<Body queue={queue} currentPlayback={currentPlayback} />
</main>
);
}
Expand Down
16 changes: 16 additions & 0 deletions src/app/search.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.input {
border: 1px solid #999999;
height: 40px;
box-sizing: border-box;
padding: 1px 10px;
outline: none;
transition: 0.2s ease-in-out;
width: 100%;
border-radius: 20px;
margin-bottom: 5px;
}

.input:focus {
transition: 0.2s ease-in-out;
border: 1px solid #1fdf64;
}
13 changes: 8 additions & 5 deletions src/app/form.tsx → src/app/search.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import * as Spotify from "spotify-api.js";
import { pushTrack, searchTracks } from "./actions";
import { TrackHeader, TrackItem } from "./track_list";
import { useRouter } from "next/navigation";
import styles from "./search.module.css";
import track_styles from "./track_list.module.css";

export default function Form() {
export default function Search() {
const router = useRouter();
const [query, setQuery] = useState("");
const [results, setResults] = useState<Spotify.Track[]>([]);
Expand All @@ -32,17 +34,18 @@ export default function Form() {

return (
<form>
<h1>Add a song</h1>
<input
type="search"
className={styles.input}
placeholder="Search song name..."
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
{results.length > 0 && (
<>
<table>
<table className={track_styles.table}>
<thead>
<TrackHeader />
<TrackHeader onClick={() => undefined} />
</thead>
<tbody>
{results.map((track, index) => (
Expand Down
75 changes: 75 additions & 0 deletions src/app/titlebar.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
.header {
display: table;
width: 100%;
background-color: #1fdf64;
padding: 5px 10px 5px 10px;
margin: 0;
}

.header div {
display: table-row;
}

.header div div {
display: table-cell;
width: auto;
}

.header .icon {
width: 25px;
height: 25px;
vertical-align: middle;
display: inline-block;
}

.header .title {
width: 100%;
padding: 0 20px 0 20px;
vertical-align: middle;
display: inline-block;
}

.header button {
width: 100px;
vertical-align: middle;
display: inline-block;
}

.modal {
width: 90%;
height: 90%;
margin: 2% 5% 5% 5%;
border-width: 1px;
border-color: black;
padding: 10px;
border-radius: 20px;
}

.modal::backdrop {
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(10px);
}

.modal_header {
width: 100%;
display: table;
padding-bottom: 10px;
}

.modal_header div {
display: table-cell;
width: auto;
}

.modal_header h1 {
width: 100%;
vertical-align: middle;
display: inline-block;
}

.modal_header button {
width: 25px;
height: 25px;
vertical-align: middle;
display: inline-block;
}
112 changes: 112 additions & 0 deletions src/app/titlebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
"use client";
import {
useRef,
useEffect,
useState,
DispatchWithoutAction,
ReactNode,
MouseEvent,
} from "react";
import Image from "next/image";
import styles from "./titlebar.module.css";
import Search from "./search";

interface Props {
title: string | undefined;
children: ReactNode;
isOpen: boolean;
handleClose: DispatchWithoutAction;
}

function Modal({ title, children, isOpen, handleClose }: Props) {
const dialogRef = useRef<HTMLDialogElement>(null);

const close = () => {
dialogRef.current?.close();
};

function handleClickOutside(event: MouseEvent) {
if (!dialogRef.current) {
return;
}

const box = dialogRef.current?.getBoundingClientRect();
if (
event.pageX < box.left ||
event.pageX > box.right ||
event.pageY < box.top + window.scrollY ||
event.pageY > box.bottom + window.scrollY
) {
close();
}
}

useEffect(() => {
const dialog = dialogRef.current;
if (isOpen && !dialogRef.current?.open) {
dialog?.showModal();
document.body.style.overflow = "hidden";
} else {
dialog?.close();
document.body.style.overflow = "";
}
}, [isOpen]);

return (
<dialog
className={styles.modal}
ref={dialogRef}
onClose={handleClose}
onClick={handleClickOutside}
>
<div className={styles.modal_header}>
<div style={{ width: "100%" }}>
<h1>{title}</h1>
</div>
<div style={{ width: "25px" }}>
<button type="button" onClick={close} title="close">
</button>
</div>
</div>
{children}
</dialog>
);
}

export default function TitleBar() {
const [isOpen, setIsOpen] = useState(false);
const showSongModel = () => {
setIsOpen(true);
};
const hideSongModel = () => {
setIsOpen(false);
};

return (
<div style={{ width: "100%" }}>
<header className={styles.header}>
<div>
<div style={{ width: "25px" }}>
<Image
alt="icon"
className={styles.icon}
src="/favicon.ico"
width={50}
height={50}
></Image>
</div>
<div style={{ width: "100%" }}>
<h2 className={styles.title}>Spotify collab</h2>
</div>
<div style={{ width: "100px" }}>
<button onClick={showSongModel}>+ Add a song</button>
</div>
</div>
</header>
<Modal title="Add a song" isOpen={isOpen} handleClose={hideSongModel}>
<Search />
</Modal>
</div>
);
}
12 changes: 11 additions & 1 deletion src/app/track.module.css → src/app/track_cover.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,15 @@ table .cover_column {
}

.duration {
width: 150px;
width: 100px;
}

@media (max-width: 760px) {
.cover {
width: 80px;
height: 80px;
}
table .cover_column {
width: 80px;
}
}
2 changes: 1 addition & 1 deletion src/app/track_cover.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Image from "next/image";
import * as Spotify from "spotify-api.js";
import { formatDuration } from "@/utils/ui";
import styles from "./track.module.css";
import styles from "./track_cover.module.css";

interface Props {
currentPlayback: Spotify.CurrentPlayback;
Expand Down
14 changes: 7 additions & 7 deletions src/app/track_list.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
padding: 5px;
}

table .cover_column {
.cover_column {
width: 50px;
}

Expand All @@ -30,12 +30,6 @@ table .cover_column {
cursor: auto;
}

.index {
height: 50px;
line-height: 50px;
text-align: center;
}

.cover {
width: 50px;
height: 50px;
Expand All @@ -52,3 +46,9 @@ table .cover_column {
.artist {
color: #777777;
}

@media (max-width: 760px) {
.album {
display: none;
}
}
Loading

0 comments on commit dcd2c0a

Please sign in to comment.