Skip to content

Commit

Permalink
feat: music and movie card design (#51)
Browse files Browse the repository at this point in the history
* wip: add music playlist in mobile

* chore: lint

* feat: add all playlists

* chore: lint

* fix: wrong album cover

* feat: extarct songlist and songitem component

* chore: lint

* feat: add movie card

* chore: lint

* fix: lockfile
  • Loading branch information
hidaviddong committed Jun 20, 2024
1 parent a726eed commit 7d854dd
Show file tree
Hide file tree
Showing 14 changed files with 288 additions and 59 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
Expand Down
8 changes: 8 additions & 0 deletions src/components/ui/icons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,11 @@ export function ArrowRightIcon(props) {
</svg>
);
}

export function MusicPlayIcon(props) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...props}>
<path fill="#ffffff" d="M8 5v14l11-7z"></path>
</svg>
);
}
44 changes: 44 additions & 0 deletions src/components/ui/tabs.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as TabsPrimitive from "@radix-ui/react-tabs";
import * as React from "react";

import { cn } from "@/lib/utils";

const Tabs = TabsPrimitive.Root;

const TabsList = React.forwardRef(({ className, ...props }, ref) => (
<TabsPrimitive.List
ref={ref}
className={cn(
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
className,
)}
{...props}
/>
));
TabsList.displayName = TabsPrimitive.List.displayName;

const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
className,
)}
{...props}
/>
));
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;

const TabsContent = React.forwardRef(({ className, ...props }, ref) => (
<TabsPrimitive.Content
ref={ref}
className={cn(
"ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
className,
)}
{...props}
/>
));
TabsContent.displayName = TabsPrimitive.Content.displayName;

export { Tabs, TabsList, TabsTrigger, TabsContent };
66 changes: 65 additions & 1 deletion src/config/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,68 @@ const SideProjects = [
},
];

export { Works, SideProjects };
const SONG_BASEURL = "https://img1.doubanio.com/lpic/";
const Songs = [
{ title: "Blue Moon", artist: "David Tao", url: "s4208287" },
{ title: "Love Words", artist: "Dean Ting", url: "s33545377" },
{ title: "After the Love Has Gone", artist: "Earth Wind & Fire", url: "s2558289" },
{ title: "Regulate (feat. Nate Dogg)", artist: "Warren G", url: "s28000661" },
{ title: "Nuthin' But A 'G' Thang", artist: "Dr. Dre, Snoop Dogg", url: "s34485730" },
{
title: "Can't Take My Eyes Off of You (I Love You Baby)",
artist: "Lauryn Hill",
url: "s34291208",
},
{ title: "Ex-Factor", artist: "Lauryn Hill", url: "s34291208" },
{ title: "Strange Weather", artist: "YELLOW, 9m88", url: "s33722359" },
{ title: "Over", artist: "Khalil Fong", url: "s4720193" },
{ title: "How Deep Is Your Love", artist: "PJ Morton", url: "s29437574" },
{ title: "Isn't She Lovely", artist: "Stevie Wonder", url: "s34317705" },
{ title: "Stan (feat. Dido)", artist: "Eminem", url: "s3809299" },
{ title: "Once in a Blue Moon (feat. Mavis Fan)", artist: "YELLOW", url: "s34869641" },
{ title: "My Only Girl", artist: "Khalil Fong", url: "s24459457" },
{ title: "Definition of Love", artist: "Khalil Fong", url: "s24459457" },
{ title: "Madoromi", artist: "Naoko Gushima", url: "s33289183" },
];

// https://www.omdbapi.com/
const MOVIE_BASEURL = "https://m.media-amazon.com/images/M/";

const Movies = [
{
title: "Annie Hall",
year: "1977",
imageUrl:
"MV5BZDg1OGQ4YzgtM2Y2NS00NjA3LWFjYTctMDRlMDI3NWE1OTUyXkEyXkFqcGdeQXVyMjUzOTY1NTc@._V1_SX300",
},
{
title: "Take the Money and Run",
year: "1969",
imageUrl: "MV5BMjE2Mjc5NDg3OV5BMl5BanBnXkFtZTgwMzUxMjMyMTE@._V1_SX300",
},
{
title: "Following",
year: "1998",
imageUrl:
"MV5BNDVhYTAyMDgtM2NhNS00MmQ3LWE0ZDMtNWIxMjlhODFmOWUwXkEyXkFqcGdeQXVyMTA5NjIyODcx._V1_SX300",
},
{
title: "Inception",
year: "2010",
imageUrl: "MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300",
},
{
title: "Interstellar",
year: "2014",
imageUrl:
"MV5BZjdkOTU3MDktN2IxOS00OGEyLWFmMjktY2FiMmZkNWIyODZiXkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_SX300",
},
{
title: "Memento",
year: "2000",
imageUrl:
"MV5BZTcyNjk1MjgtOWI3Mi00YzQwLWI5MTktMzY4ZmI2NDAyNzYzXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_SX300",
},
];

export { Works, SideProjects, SONG_BASEURL, Songs, Movies, MOVIE_BASEURL };
53 changes: 0 additions & 53 deletions src/pages/+Layout.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
import { Dock, DockIcon } from "@/components/ui/dock";
import {
EmailIcon,
GithubIcon,
LinkedInIcon,
ResumeIcon,
WhatsAppIcon,
} from "@/components/ui/icons";
import { navigate } from "vike/client/router";

export default function LayoutDefault({ children }) {
const year = new Date().getFullYear();
return (
Expand All @@ -16,49 +6,6 @@ export default function LayoutDefault({ children }) {
<footer className="w-full text-center text-sm text-neutral-400">
<p>© {year} David Dong. All rights reserved.</p>
</footer>
<Dock className="fixed bottom-4 bg-white">
<DockIcon
data-umami-event="Github Button"
onClick={() => {
window.location.href = "https://github.com/DongHY1";
}}
>
<GithubIcon className="h-6 w-6" />
</DockIcon>
<DockIcon
data-umami-event="Linekdin Button"
onClick={() => {
window.location.href = "https://www.linkedin.com/in/DongHY1";
}}
>
<LinkedInIcon className="h-6 w-6" />
</DockIcon>

<DockIcon
data-umami-event="Email Button"
onClick={() => {
window.location.href = "mailto:hi@daviddong.me";
}}
>
<EmailIcon className="h-6 w-6" />
</DockIcon>
<DockIcon
data-umami-event="WhatsApp Button"
onClick={() => {
window.location.href = "https://wa.link/bbs3i9";
}}
>
<WhatsAppIcon className="h-6 w-6" />
</DockIcon>
<DockIcon
data-umami-event="Resume Button"
onClick={() => {
navigate("/cv.pdf");
}}
>
<ResumeIcon className="h-6 w-6" />
</DockIcon>
</Dock>
</div>
);
}
54 changes: 54 additions & 0 deletions src/pages/index/+Page.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Badge } from "@/components/ui/badge";
import { BentoCard, BentoGrid } from "@/components/ui/bento-grid";
import { Dock, DockIcon } from "@/components/ui/dock";
import {
EmailIcon,
GithubIcon,
LinkedInIcon,
ResumeIcon,
WhatsAppIcon,
} from "@/components/ui/icons";
import { Tag } from "@/components/ui/tag";
import { SideProjects, Works } from "@/config/project";
import { navigate } from "vike/client/router";
Expand Down Expand Up @@ -68,6 +76,52 @@ export default function Page() {
</section>
<ProjectLists title="Works" items={Works} />
<ProjectLists title="Side Projects" items={SideProjects} />

<div className="w-full justify-center flex">
<Dock className="fixed bottom-4 bg-white">
<DockIcon
data-umami-event="Github Button"
onClick={() => {
window.location.href = "https://github.com/DongHY1";
}}
>
<GithubIcon className="h-6 w-6" />
</DockIcon>
<DockIcon
data-umami-event="Linekdin Button"
onClick={() => {
window.location.href = "https://www.linkedin.com/in/DongHY1";
}}
>
<LinkedInIcon className="h-6 w-6" />
</DockIcon>

<DockIcon
data-umami-event="Email Button"
onClick={() => {
window.location.href = "mailto:hi@daviddong.me";
}}
>
<EmailIcon className="h-6 w-6" />
</DockIcon>
<DockIcon
data-umami-event="WhatsApp Button"
onClick={() => {
window.location.href = "https://wa.link/bbs3i9";
}}
>
<WhatsAppIcon className="h-6 w-6" />
</DockIcon>
<DockIcon
data-umami-event="Resume Button"
onClick={() => {
navigate("/cv.pdf");
}}
>
<ResumeIcon className="h-6 w-6" />
</DockIcon>
</Dock>
</div>
</article>
);
}
24 changes: 19 additions & 5 deletions src/pages/list/+Page.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import React from "react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { MovieCover, MovieList } from "./components/movie";
import { SongCover, SongList } from "./components/music";

export default function Page() {
return (
<div className="h-screen w-full prose flex flex-col justify-center items-center font-serif">
<h1>Music List</h1>
<h1>Movie List</h1>
</div>
<Tabs defaultValue="Music" className="h-full w-96 mt-12">
<TabsList className="grid w-full grid-cols-2 mb-4">
<TabsTrigger value="Music">Music</TabsTrigger>
<TabsTrigger value="Movies">Movies</TabsTrigger>
</TabsList>

<TabsContent value="Music" className="flex flex-col h-full justify-center items-center">
<SongCover />
<SongList />
</TabsContent>

<TabsContent value="Movies" className="flex flex-col h-full justify-center items-center">
<MovieCover />
<MovieList />
</TabsContent>
</Tabs>
);
}
12 changes: 12 additions & 0 deletions src/pages/list/components/movie/MovieCover.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default function MovieCover() {
return (
<div className="flex flex-col justify-center items-center gap-2 mb-4">
<div className="rounded-md w-72 h-72 drop-shadow-md border bg-gradient-to-br from-gray-100 via-pink-50 to-emerald-700 p-4">
<span className="text-4xl font-semibold text-black/90">David Dong's MovieList</span>
</div>
<div className="text-2xl font-semibold text-black/90">David Dong's MovieList</div>
<h2 className="text-[#d60017] text-xl font-normal">David Dong</h2>
<div className="text-[13px] text-black/50">Thriller, Tragicomedy</div>
</div>
);
}
31 changes: 31 additions & 0 deletions src/pages/list/components/movie/MovieList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { MOVIE_BASEURL, Movies } from "@/config/project";

function MovieItem({ title, year, imageUrl }) {
return (
<div className="flex group p-4 w-full hover:bg-zinc-100 hover:rounded-md">
<div
style={{ backgroundImage: `url('${MOVIE_BASEURL}${imageUrl}.jpg')` }}
className="rounded-md border drop-shadow-md flex justify-center items-center bg-cover bg-center h-44 w-32"
></div>
<div className="flex flex-col justify-start items-start ml-4 gap-2">
<div className="text-black/80 font-normal">{title}</div>
<div className="text-black/50 font-normal text-sm">{year}</div>
</div>
</div>
);
}

export default function MovieList() {
return (
<div className="flex w-full p-1 justify-center items-center flex-col">
{Movies.map((movie) => (
<MovieItem
key={movie.title}
title={movie.title}
year={movie.year}
imageUrl={movie.imageUrl}
/>
))}
</div>
);
}
3 changes: 3 additions & 0 deletions src/pages/list/components/movie/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import MovieCover from "./MovieCover";
import MovieList from "./MovieList";
export { MovieCover, MovieList };
12 changes: 12 additions & 0 deletions src/pages/list/components/music/SongCover.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default function SongCover() {
return (
<div className="flex flex-col justify-center items-center gap-2">
<div className="rounded-md w-72 h-72 drop-shadow-md border bg-gradient-to-br from-gray-100 via-pink-50 to-sky-700 p-4">
<span className="text-4xl font-semibold text-black/90">David Dong's Playlist</span>
</div>
<div className="text-2xl font-semibold text-black/90">David Dong's Playlist</div>
<h2 className="text-[#d60017] text-xl font-normal">David Dong</h2>
<div className="text-[13px] text-black/50">R&B Neo Soul Gospel</div>
</div>
);
}
35 changes: 35 additions & 0 deletions src/pages/list/components/music/SongList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { MusicPlayIcon } from "@/components/ui/icons";
import { SONG_BASEURL, Songs } from "@/config/project";
function SongItem({ song }) {
return (
<div className="group w-full flex hover:bg-zinc-100 hover:rounded-md p-2">
<div
style={{ backgroundImage: `url(${SONG_BASEURL}${song.url}.jpg)` }}
className="relative w-10 h-10 rounded-md border flex justify-center items-center bg-cover bg-center"
>
<div className="absolute inset-0 bg-black opacity-0 group-hover:opacity-50 transition-opacity rounded-md"></div>
<MusicPlayIcon
className="w-7 h-7 hidden group-hover:block z-10 cursor-pointer"
onClick={() => {
window.location.href =
"https://music.apple.com/tr/playlist/david-dongs-playlist/pl.u-leyl096uME0KMW6";
}}
/>
</div>
<div className="flex flex-col justify-center ml-2">
<div className="text-black/80 text-[13px] font-normal">{song.title}</div>
<div className="text-black/50 text-[13px] font-normal">{song.artist}</div>
</div>
</div>
);
}

export default function SongList() {
return (
<div className="flex flex-col w-full p-1 space-y-2">
{Songs.map((song) => (
<SongItem key={song.title} song={song} />
))}
</div>
);
}
4 changes: 4 additions & 0 deletions src/pages/list/components/music/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import SongCover from "./SongCover";
import SongList from "./SongList";

export { SongCover, SongList };

0 comments on commit 7d854dd

Please sign in to comment.