source: frontend/src/components/playlist/CreatePlaylistModal.tsx@ ce45c7a

main
Last change on this file since ce45c7a was 85512ff, checked in by Dimitar Arsov <dimitararsov04@…>, 5 months ago

save playlist

  • Property mode set to 100644
File size: 3.7 KB
Line 
1import { useState, useEffect } from "react";
2import type { CreatePlaylistModalProps } from "../../utils/types";
3
4const CreatePlaylistModal = ({
5 isOpen,
6 onClose,
7 onSubmit,
8}: CreatePlaylistModalProps) => {
9 const [playlistName, setPlaylistName] = useState("");
10 const [isClosing, setIsClosing] = useState(false);
11 const [isOpening, setIsOpening] = useState(false);
12
13 useEffect(() => {
14 if (isOpen) {
15 setIsClosing(false);
16 setPlaylistName("");
17 setIsOpening(true);
18 setTimeout(() => setIsOpening(false), 10);
19 }
20 }, [isOpen]);
21
22 const handleClose = () => {
23 setIsClosing(true);
24 setTimeout(() => {
25 onClose();
26 setIsClosing(false);
27 }, 200);
28 };
29
30 const handleSubmit = (e: React.FormEvent) => {
31 e.preventDefault();
32 if (playlistName.trim()) {
33 onSubmit(playlistName.trim());
34 handleClose();
35 }
36 };
37
38 if (!isOpen && !isClosing) return null;
39
40 return (
41 <div
42 className={`fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-50 px-4 transition-opacity duration-200 ${
43 isClosing || isOpening ? "opacity-0" : "opacity-100"
44 }`}
45 onClick={handleClose}
46 >
47 <div
48 className={`bg-[#181818] rounded-xl p-8 w-full max-w-md border border-white/10 transition-all duration-200 ${
49 isClosing || isOpening
50 ? "scale-95 opacity-0"
51 : "scale-100 opacity-100"
52 }`}
53 onClick={(e) => e.stopPropagation()}
54 >
55 <div className="flex justify-between items-center mb-6">
56 <h2 className="text-2xl font-bold text-white">Create Playlist</h2>
57 <button
58 onClick={handleClose}
59 className="text-gray-400 hover:text-white transition-colors cursor-pointer"
60 aria-label="Close modal"
61 >
62 <svg
63 className="w-6 h-6"
64 fill="none"
65 stroke="currentColor"
66 viewBox="0 0 24 24"
67 >
68 <path
69 strokeLinecap="round"
70 strokeLinejoin="round"
71 strokeWidth={2}
72 d="M6 18L18 6M6 6l12 12"
73 />
74 </svg>
75 </button>
76 </div>
77
78 <form onSubmit={handleSubmit} className="space-y-6">
79 <div>
80 <label
81 className="block text-sm font-medium text-gray-300 mb-2"
82 htmlFor="playlistName"
83 >
84 Playlist Name
85 </label>
86 <input
87 type="text"
88 id="playlistName"
89 autoFocus
90 className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
91 placeholder="Enter playlist name"
92 value={playlistName}
93 onChange={(e) => setPlaylistName(e.target.value)}
94 />
95 </div>
96
97 <div className="flex gap-3">
98 <button
99 type="button"
100 onClick={handleClose}
101 className="flex-1 py-3 bg-[#282828] rounded-full text-white font-semibold hover:bg-[#3a3a3a] transition-colors cursor-pointer"
102 >
103 Cancel
104 </button>
105 <button
106 type="submit"
107 disabled={!playlistName.trim()}
108 className="flex-1 py-3 bg-[#1db954] rounded-full text-black font-semibold hover:bg-[#1ed760] transition-colors disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-[#1db954] cursor-pointer"
109 >
110 Create
111 </button>
112 </div>
113 </form>
114 </div>
115 </div>
116 );
117};
118
119export default CreatePlaylistModal;
Note: See TracBrowser for help on using the repository browser.