Skip to content

Commit

Permalink
플레이리스트 생성 기능 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
ipcgrdn committed Dec 22, 2024
1 parent 756aa91 commit 59e2fe4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 49 deletions.
36 changes: 19 additions & 17 deletions src/app/album/[albumId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,23 +92,25 @@ export default function AlbumPage() {
</div>
</div>
<div className="flex flex-col w-full h-full items-start justify-between py-2 gap-y-4">
{albumProfile && (
<div
onClick={() => router.push(`/profile/${albumProfile.name}`)}
className="flex gap-x-2 items-center"
>
<Avatar className="w-6 h-6 lg:w-10 lg:h-10">
<AvatarImage
src={`${albumProfile.profileImage}`}
alt="profile"
/>
<AvatarFallback>U</AvatarFallback>
</Avatar>
<span className="text-sm hover:underline truncate">
{albumProfile.name}
</span>
</div>
)}
<div>
{albumProfile && (
<div
onClick={() => router.push(`/profile/${albumProfile.name}`)}
className="flex gap-x-2 items-center"
>
<Avatar className="w-6 h-6 lg:w-10 lg:h-10">
<AvatarImage
src={`${albumProfile.profileImage}`}
alt="profile"
/>
<AvatarFallback>U</AvatarFallback>
</Avatar>
<span className="text-sm hover:underline truncate">
{albumProfile.name}
</span>
</div>
)}
</div>
<div className="tracking-wide text-3xl md:text-4xl font-extrabold truncate">
{albumData?.title}
</div>
Expand Down
10 changes: 3 additions & 7 deletions src/components/modal/album/albumEdit-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { toast } from "sonner";
import { useState } from "react";
import { FieldValues, SubmitHandler, useForm } from "react-hook-form";

import { IconUserCircle } from "@tabler/icons-react";
import { IconDisc } from "@tabler/icons-react";
import { zodResolver } from "@hookform/resolvers/zod";

import { Input } from "@/components/ui/input";
Expand Down Expand Up @@ -101,10 +101,6 @@ const AlbumEditModal = () => {
try {
const albumArtUrl = file ? await uploadToS3(file) : "";

console.log(uuid);
console.log(values);
console.log(albumArtUrl);

const response = await api.patch(`/album/${uuid}`, {
title: values.title,
description: values.description,
Expand Down Expand Up @@ -152,11 +148,11 @@ const AlbumEditModal = () => {
<CustomModal
title={
<ModalTitle
icon={<IconUserCircle className="size-10 p-1" />}
icon={<IconDisc className="size-10 p-1" />}
title="앨범 편집"
/>
}
description="앨범을 소개해주세요"
description="앨범 정보를 입력해주세요"
isOpen={albumEditModal.isOpen}
onChange={onChange}
className="p-4 flex flex-col items-center justify-center"
Expand Down
71 changes: 46 additions & 25 deletions src/components/modal/playlist-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ import { CustomModal } from "./custom-modal";
import { IconPlaylist } from "@tabler/icons-react";
import { zodResolver } from "@hookform/resolvers/zod";
import usePlaylistModal from "@/hooks/modal/use-playlist-modal";
import { useRouter } from "next/navigation";
import { api } from "@/lib/axios";
import axios from "axios";

const PlaylistModal = () => {
const [isLoading, setIsloading] = useState(false);

const router = useRouter();
const playlistModal = usePlaylistModal();

const onChange = (open: boolean) => {
Expand All @@ -27,11 +31,12 @@ const PlaylistModal = () => {
};

const FormSchema = z.object({
playlistName: z
title: z
.string()
.min(1, { message: "플레이리스트 이름은 필수입니다." })
.max(20, { message: "플레이리스트 이름은 20자 이하로 입력해야 합니다." }),
playlistDescription: z.string().optional(),
description: z.string().optional(),
trackUuids: z.array(z.string()).optional(),
});

const {
Expand All @@ -42,34 +47,52 @@ const PlaylistModal = () => {
} = useForm<FieldValues>({
resolver: zodResolver(FormSchema),
defaultValues: {
// 이후 수정
playlistName: "",
playlistDescription: "",
title: "",
description: "",
trackUuids: [],
},
});

const onSubmit: SubmitHandler<FieldValues> = async () => {
// 이후 수정
const onSubmit: SubmitHandler<FieldValues> = async (values) => {
try {
setIsloading(true);

const response = await api.post("/playlists", values, {
withCredentials: true,
});

if (response.status !== 201) {
throw new Error("플레이리스트 생성에 실패하였습니다.");
}

console.log(`플레이리스트: ${values}`);

toast.success("플레이리스트가 생성되었습니다!");
reset();
playlistModal.onClose();
router.refresh();
} catch (error) {
toast.error(`문제가 발생하였습니다 ${error}`);
if (axios.isAxiosError(error) && error.response?.data) {
const errorData = error.response.data;
toast.error(errorData.detail || "플레이리스트 생성에 실패했습니다.");
} else if (error instanceof Error) {
toast.error(error.message);
} else {
toast.error("알 수 없는 오류가 발생했습니다.");
}
} finally {
setIsloading(false);

playlistModal.onClose();
toast.success("플레이리스트가 생성되었습니다!");
}
};

return (
<CustomModal
title={
<ModalTitle
icon={<IconPlaylist className="size-10 p-1" />}
title="플레이리스트 생성"
/>
}
title={
<ModalTitle
icon={<IconPlaylist className="size-10 p-1" />}
title="플레이리스트 생성"
/>
}
description="플레이리스트에 대한 정보를 입력해주세요"
isOpen={playlistModal.isOpen}
onChange={onChange}
Expand All @@ -81,21 +104,19 @@ const PlaylistModal = () => {
>
<div className="flex flex-col gap-y-4 items-center justify-center h-full w-full rounded-md overflow-y-auto mt-2">
<Input
id="playlistName"
id="title"
disabled={isLoading}
{...register("playlistName", { required: true })}
{...register("title", { required: true })}
placeholder="플레이리스트 이름 (필수)"
className="w-full h-14"
/>
<p
className={errors.playlistName ? "text-red-500 text-xs" : "hidden"}
>
{errors.playlistName ? String(errors.playlistName.message) : null}
<p className={errors.title ? "text-red-500 text-xs" : "hidden"}>
{errors.title ? String(errors.title.message) : null}
</p>
<Textarea
id="playlistDescription"
id="description"
disabled={isLoading}
{...register("playlistDescription", { required: false })}
{...register("description", { required: false })}
placeholder="플레이리스트 설명 (선택)"
className="w-full h-full resize-none"
/>
Expand Down

0 comments on commit 59e2fe4

Please sign in to comment.