55 < script src ="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js "> </ script >
66 < script src ="https://cdn.tailwindcss.com "> </ script >
77 < style >
8+ : root {
9+ --shadow : rgba (0 , 0 , 0 , 0.1 );
10+ }
11+
812 @media print {
913 body * {
1014 visibility : hidden;
1923 }
2024 }
2125
22- .card {
23- width : 6cm ;
24- height : 6cm ;
25- border : 1px solid # e5e7eb ;
26- border-radius : 8px ;
27- background : white;
28- padding : 10px ;
29- margin : 10px ;
30- page-break-inside : avoid !important ;
31- break-inside : avoid !important ;
32- }
33-
34- .page {
35- page-break-after : always !important ;
36- page-break-before : always !important ;
37- margin-bottom : 2cm ;
38- }
39-
40- .card-container {
41- display : grid;
42- grid-template-columns : repeat (3 , 1fr );
43- gap : 20px ;
44- padding : 20px ;
45- page-break-inside : avoid !important ;
46- break-inside : avoid !important ;
47- }
48-
49- .card-page {
50- display : grid;
51- grid-template-columns : repeat (3 , 1fr );
52- gap : 20px ;
53- padding : 20px ;
54- page-break-after : always;
55- }
56-
57- .qr-container {
58- display : flex;
59- justify-content : center;
60- height : 100% ;
61- align-items : center;
62- }
63-
64- .metadata {
65- text-align : center;
66- height : 100% ;
67- display : flex;
68- flex-direction : column;
69- justify-content : center;
70- }
71-
72- .metadata .year {
73- font-size : 24px ;
74- margin-top : 8px ;
75- }
76-
77- # printArea {
78- display : block;
79- padding : 1cm ;
80- }
81-
82- .hidden {
83- display : none;
26+ body {
27+ overflow : hidden;
8428 }
8529
8630 # pauseResumeButton {
87- width : min (60vmin , 300px ); /* Cap the max size on desktop */
31+ width : min (60vmin , 300px );
8832 height : min (60vmin , 300px );
8933 border : none;
9034 border-radius : 50% ;
9741 transition : all 0.4s cubic-bezier (0.22 , 1 , 0.36 , 1 );
9842 box-shadow :
9943 0 2rem 4rem rgba (29 , 185 , 84 , 0.2 ),
100- 0 1rem 2rem rgba ( 0 , 0 , 0 , 0.1 ),
44+ 0 1rem 2rem var ( --shadow ),
10145 inset 0 -2px 0 rgba (0 , 0 , 0 , 0.1 ),
10246 inset 0 2px 0 rgba (255 , 255 , 255 , 0.2 );
10347 overflow : hidden;
10650 # pauseResumeButton ::before {
10751 content : '' ;
10852 position : absolute;
109- top : 0 ;
110- left : 0 ;
111- right : 0 ;
112- bottom : 0 ;
53+ inset : 0 ;
11354 border-radius : 50% ;
11455 background : linear-gradient (145deg , rgba (255 , 255 , 255 , 0.2 ), transparent);
11556 opacity : 0 ;
12162 background : linear-gradient (145deg , # 34F07E, # 1FCC5E );
12263 box-shadow :
12364 0 3rem 5rem rgba (29 , 185 , 84 , 0.25 ),
124- 0 1.5rem 3rem rgba ( 0 , 0 , 0 , 0.15 ),
65+ 0 1.5rem 3rem var ( --shadow ),
12566 inset 0 -2px 0 rgba (0 , 0 , 0 , 0.1 ),
12667 inset 0 2px 0 rgba (255 , 255 , 255 , 0.2 );
12768 }
13576 background : linear-gradient (145deg , # 1DB954, # 1AA54C );
13677 box-shadow :
13778 0 1rem 2rem rgba (29 , 185 , 84 , 0.15 ),
138- 0 0.5rem 1rem rgba ( 0 , 0 , 0 , 0.1 ),
79+ 0 0.5rem 1rem var ( --shadow ),
13980 inset 0 -1px 0 rgba (0 , 0 , 0 , 0.1 ),
14081 inset 0 1px 0 rgba (255 , 255 , 255 , 0.1 );
14182 }
14283
14384 # pauseResumeButton svg {
14485 filter : drop-shadow (0 4px 8px rgba (0 , 0 , 0 , 0.2 ));
14586 }
146-
147- # player {
148- display : flex;
149- justify-content : center;
150- align-items : center;
151- height : 100vh ;
152- margin : 0 ;
153- flex-direction : column;
154- }
155-
156- .button-container {
157- display : flex;
158- flex-direction : column;
159- align-items : center;
160- gap : 2rem ;
161- }
162-
163- .scan-button {
164- padding : 1.5rem 3rem ;
165- font-size : 1.5rem ;
166- font-weight : 600 ;
167- color : white;
168- background : linear-gradient (145deg , # 1e1e1e, # 2d2d2d );
169- border : none;
170- border-radius : 15px ;
171- cursor : pointer;
172- text-decoration : none;
173- transition : all 0.3s ease;
174- box-shadow : 0 10px 20px rgba (0 , 0 , 0 , 0.2 );
175- text-transform : uppercase;
176- letter-spacing : 1px ;
177- }
178-
179- .scan-button : hover {
180- transform : translateY (-2px );
181- box-shadow : 0 15px 30px rgba (0 , 0 , 0 , 0.3 );
182- }
183-
184- .scan-button : active {
185- transform : translateY (1px );
186- box-shadow : 0 5px 15px rgba (0 , 0 , 0 , 0.1 );
187- }
188-
189- # playlistModal {
190- z-index : 1000 ;
191- }
192-
193- input [type = "range" ] {
194- -webkit-appearance : none;
195- height : 8px ;
196- background : # e5e7eb ;
197- border-radius : 4px ;
198- outline : none;
199- }
200-
201- input [type = "range" ]::-webkit-slider-thumb {
202- -webkit-appearance : none;
203- width : 20px ;
204- height : 20px ;
205- background : # 1DB954 ;
206- border-radius : 50% ;
207- cursor : pointer;
208- }
209-
210- input [type = "range" ]::-moz-range-thumb {
211- width : 20px ;
212- height : 20px ;
213- background : # 1DB954 ;
214- border-radius : 50% ;
215- cursor : pointer;
216- border : none;
217- }
21887 </ style >
21988</ head >
220- < body class ="bg-gray-100 min-h-screen ">
89+ < body class ="bg-gray-100 dark:bg-black min-h-screen overflow-hidden ">
22190< div id ="setup " class ="max-w-md mx-auto p-6 ">
222- < div class ="bg-white rounded-lg shadow-xl p-8 ">
223- < input type ="text " id ="clientId " placeholder ="Enter Spotify Client ID " class ="w-full px-4 py-2 mb-4 border rounded ">
224- < button onclick ="startAuth() " class ="w-full bg-green-500 text-white py-2 px-4 rounded "> Initialize</ button >
91+ < div class ="bg-white dark:bg-gray-900 rounded-lg shadow-xl p-8 ">
92+ < input type ="text " id ="clientId " placeholder ="Enter Spotify Client ID "
93+ class ="w-full px-4 py-2 mb-4 border rounded bg-white dark:bg-gray-700 text-black dark:text-white ">
94+ < button onclick ="startAuth() "
95+ class ="w-full bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded transition-colors ">
96+ Initialize
97+ </ button >
22598 </ div >
22699</ div >
227100
228- < div id ="player " class ="hidden ">
229- < div class ="button-container ">
230- < button id ="pauseResumeButton "> < span class ="play "> ▷</ span > </ button >
231- < a href ="https://www.gptgames.dev/tools/spotify_qr_scanner " class ="scan-button ">
101+ < div id ="player " class ="hidden h-screen flex justify-center items-center flex-col ">
102+ < div class ="flex flex-col items-center gap-8 ">
103+ < button id ="pauseResumeButton ">
104+ < span class ="play "> ▷</ span >
105+ </ button >
106+ < a href ="https://www.gptgames.dev/tools/spotify_qr_scanner "
107+ class ="px-12 py-6 text-2xl font-semibold text-white dark:text-white bg-gray-800 dark:bg-gray-700
108+ hover:transform hover:-translate-y-1 rounded-2xl shadow-lg uppercase tracking-wide
109+ transition-all duration-300 ">
232110 Scan for next song
233111 </ a >
234112 </ div >
235- < button id ="createQRButton " class ="fixed top-4 right-4 bg-green-500 text-white py-2 px-4 rounded ">
113+ < button id ="createQRButton "
114+ class ="fixed top-4 right-4 bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded transition-colors ">
236115 Create QR codes from Playlist
237116 </ button >
238117</ div >
239118
240- < div id ="printArea "> </ div >
241-
242- < div id ="playlistModal " class ="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center ">
243- < div class ="bg-white p-8 rounded-lg shadow-xl max-w-md w-full ">
244- < h2 class ="text-xl font-bold mb-4 "> Create QR Codes from Playlist</ h2 >
245- < input
246- type ="text "
247- id ="playlistUrl "
248- placeholder ="Enter Spotify playlist URL "
249- class ="w-full px-4 py-2 mb-4 border rounded "
250- >
119+ < div id ="printArea " class ="p-[1cm] "> </ div >
120+
121+ < div id ="playlistModal " class ="fixed inset-0 bg-black/50 hidden items-center justify-center ">
122+ < div class ="bg-white dark:bg-gray-900 p-8 rounded-lg shadow-xl max-w-md w-full ">
123+ < h2 class ="text-xl font-bold mb-4 text-black dark:text-white ">
124+ Create QR Codes from Playlist
125+ </ h2 >
126+ < input type ="text " id ="playlistUrl " placeholder ="Enter Spotify playlist URL "
127+ class ="w-full px-4 py-2 mb-4 border rounded bg-white dark:bg-gray-700 text-black dark:text-white ">
251128 < div class ="mb-4 ">
252- < label class ="block text-sm font-medium text-gray-700 mb-2 ">
129+ < label class ="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 ">
253130 Number of songs: < span id ="songCount "> 21</ span >
254131 </ label >
255- < input
256- type ="range "
257- id ="songSlider "
258- min ="3 "
259- max ="300 "
260- step ="3 "
261- value ="21 "
262- class ="w-full "
263- >
132+ < input type ="range " id ="songSlider " min ="3 " max ="300 " step ="3 " value ="21 "
133+ class ="w-full ">
264134 </ div >
265135 < div class ="flex justify-end gap-4 ">
266- < button onclick ="closePlaylistModal() " class ="px-4 py-2 text-gray-600 hover:text-gray-800 ">
136+ < button onclick ="closePlaylistModal() "
137+ class ="px-4 py-2 text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200 ">
267138 Cancel
268139 </ button >
269- < button onclick ="processPlaylist() " class ="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 ">
140+ < button onclick ="processPlaylist() "
141+ class ="px-4 py-2 bg-green-500 hover:bg-green-600 text-white rounded transition-colors ">
270142 Create
271143 </ button >
272144 </ div >
@@ -351,10 +223,11 @@ <h2 class="text-xl font-bold mb-4">Create QR Codes from Playlist</h2>
351223
352224 function createQRCard ( track , isQRSide ) {
353225 const card = document . createElement ( 'div' ) ;
354- card . className = 'card' ;
226+ card . className = 'w-[6cm] h-[6cm] border border-gray-200 rounded-lg bg-white p-2.5 m-2.5 break-inside-avoid' ;
227+
355228 if ( isQRSide ) {
356229 const qrContainer = document . createElement ( 'div' ) ;
357- qrContainer . className = 'qr-container ' ;
230+ qrContainer . className = 'flex justify-center items-center h-full ' ;
358231 qrContainer . id = `qr-${ track . id } ` ;
359232 card . appendChild ( qrContainer ) ;
360233 new QRCode ( qrContainer , {
@@ -367,8 +240,12 @@ <h2 class="text-xl font-bold mb-4">Create QR Codes from Playlist</h2>
367240 } ) ;
368241 } else {
369242 const metadata = document . createElement ( 'div' ) ;
370- metadata . className = 'metadata' ;
371- metadata . innerHTML = `<h3 class="title">${ track . name } </h3><p class="artist">${ track . artist } </p><p class="year">${ track . year } </p>` ;
243+ metadata . className = 'text-center h-full flex flex-col justify-center text-black' ;
244+ metadata . innerHTML = `
245+ <h3 class="text-lg font-semibold">${ track . name } </h3>
246+ <p class="text-gray-600">${ track . artist } </p>
247+ <p class="text-2xl mt-2">${ track . year } </p>
248+ ` ;
372249 card . appendChild ( metadata ) ;
373250 }
374251 return card ;
0 commit comments