commit 4bf81de1a99abe92c02e9ad6d62851ba0cf97c16
Author: root <root@hub.scroll.pub> Date: 2024-12-27 20:45:14 +0000 Subject: Initial commit diff --git a/body.html b/body.html new file mode 100644 index 0000000..f4714f7 --- /dev/null +++ b/body.html @@ -0,0 +1,25 @@ +<header> + <h1>Playlist Progress Tracker</h1> + <p class="tagline">Track your learning journey, one playlist at a time</p> +</header> + +<main> + <section class="add-playlist"> + <form id="playlist-form"> + <input type="text" id="playlist-title" placeholder="Playlist Title" required> + <input type="url" id="playlist-url" placeholder="YouTube Playlist URL" required> + <button type="submit" class="btn-add">Add Playlist</button> + </form> + </section> + + <section class="playlists"> + <h2>Your Playlists</h2> + <div id="playlist-container"> + <!-- Playlists will be added here dynamically --> + </div> + </section> +</main> + +<footer> + <p>Made with passion for continuous learning</p> +</footer> diff --git a/index.scroll b/index.scroll new file mode 100644 index 0000000..43c9377 --- /dev/null +++ b/index.scroll @@ -0,0 +1,11 @@ +buildHtml +baseUrl https://playlist-tracker.scroll.pub +metaTags + title Playlist Progress Tracker + description Track your YouTube learning progress by organizing playlists and marking them as completed + author Playlist Progress Tracker +editButton /edit.html +title Playlist Progress Tracker +style.css +body.html +script.js diff --git a/prompt.json b/prompt.json new file mode 100644 index 0000000..4dca79e --- /dev/null +++ b/prompt.json @@ -0,0 +1,20 @@ +{ + "id": "msg_018HS7WHr2Zk8K465RXk5kGY", + "type": "message", + "role": "assistant", + "model": "claude-3-5-sonnet-20241022", + "content": [ + { + "type": "text", + "text": "Let me create this website for tracking YouTube playlist progress.\n\n---domain---\nplaylist-tracker.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://playlist-tracker.scroll.pub\nmetaTags\n title Playlist Progress Tracker\n description Track your YouTube learning progress by organizing playlists and marking them as completed\n author Playlist Progress Tracker\neditButton /edit.html\ntitle Playlist Progress Tracker\nstyle.css\nbody.html\nscript.js\n\n---body.html---\n<header>\n <h1>Playlist Progress Tracker</h1>\n <p class=\"tagline\">Track your learning journey, one playlist at a time</p>\n</header>\n\n<main>\n <section class=\"add-playlist\">\n <form id=\"playlist-form\">\n <input type=\"text\" id=\"playlist-title\" placeholder=\"Playlist Title\" required>\n <input type=\"url\" id=\"playlist-url\" placeholder=\"YouTube Playlist URL\" required>\n <button type=\"submit\" class=\"btn-add\">Add Playlist</button>\n </form>\n </section>\n\n <section class=\"playlists\">\n <h2>Your Playlists</h2>\n <div id=\"playlist-container\">\n <!-- Playlists will be added here dynamically -->\n </div>\n </section>\n</main>\n\n<footer>\n <p>Made with passion for continuous learning</p>\n</footer>\n\n---style.css---\n:root {\n --primary-color: #6366f1;\n --secondary-color: #818cf8;\n --background: #f8fafc;\n --text: #1e293b;\n --success: #22c55e;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: system-ui, -apple-system, sans-serif;\n line-height: 1.6;\n color: var(--text);\n background: var(--background);\n}\n\nheader {\n background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));\n color: white;\n padding: 2rem;\n text-align: center;\n box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);\n}\n\nh1 {\n font-size: 2.5rem;\n margin-bottom: 0.5rem;\n}\n\n.tagline {\n font-size: 1.1rem;\n opacity: 0.9;\n}\n\nmain {\n max-width: 800px;\n margin: 2rem auto;\n padding: 0 1rem;\n}\n\n.add-playlist {\n background: white;\n padding: 2rem;\n border-radius: 1rem;\n box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);\n}\n\nform {\n display: grid;\n gap: 1rem;\n}\n\ninput {\n padding: 0.75rem;\n border: 2px solid #e2e8f0;\n border-radius: 0.5rem;\n font-size: 1rem;\n transition: border-color 0.2s;\n}\n\ninput:focus {\n outline: none;\n border-color: var(--primary-color);\n}\n\n.btn-add {\n background: var(--primary-color);\n color: white;\n border: none;\n padding: 0.75rem;\n border-radius: 0.5rem;\n cursor: pointer;\n font-size: 1rem;\n transition: background-color 0.2s;\n}\n\n.btn-add:hover {\n background: var(--secondary-color);\n}\n\n.playlists {\n margin-top: 2rem;\n}\n\nh2 {\n margin-bottom: 1rem;\n color: var(--text);\n}\n\n.playlist-item {\n background: white;\n padding: 1.5rem;\n border-radius: 0.5rem;\n margin-bottom: 1rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 4px -1px rgb(0 0 0 / 0.1);\n transition: transform 0.2s;\n}\n\n.playlist-item:hover {\n transform: translateY(-2px);\n}\n\n.playlist-info {\n flex-grow: 1;\n}\n\n.playlist-title {\n font-weight: 600;\n margin-bottom: 0.5rem;\n}\n\n.playlist-url {\n color: var(--primary-color);\n text-decoration: none;\n}\n\n.playlist-url:hover {\n text-decoration: underline;\n}\n\n.btn-complete {\n background: none;\n border: 2px solid var(--success);\n color: var(--success);\n padding: 0.5rem 1rem;\n border-radius: 0.5rem;\n cursor: pointer;\n margin-left: 1rem;\n transition: all 0.2s;\n}\n\n.completed .btn-complete {\n background: var(--success);\n color: white;\n}\n\n.completed {\n opacity: 0.7;\n}\n\nfooter {\n text-align: center;\n padding: 2rem;\n color: var(--text);\n opacity: 0.8;\n}\n\n@media (max-width: 600px) {\n header {\n padding: 1.5rem;\n }\n\n h1 {\n font-size: 2rem;\n }\n\n .playlist-item {\n flex-direction: column;\n gap: 1rem;\n text-align: center;\n }\n\n .btn-complete {\n margin-left: 0;\n }\n}\n\n---script.js---\ndocument.addEventListener('DOMContentLoaded', () => {\n const form = document.getElementById('playlist-form');\n const container = document.getElementById('playlist-container');\n \n // Load saved playlists from localStorage\n let playlists = JSON.parse(localStorage.getItem('playlists')) || [];\n \n // Render existing playlists\n renderPlaylists();\n \n form.addEventListener('submit', (e) => {\n e.preventDefault();\n \n const title = document.getElementById('playlist-title').value;\n const url = document.getElementById('playlist-url').value;\n \n addPlaylist(title, url);\n form.reset();\n });\n \n function addPlaylist(title, url) {\n const playlist = {\n id: Date.now(),\n title,\n url,\n completed: false\n };\n \n playlists.unshift(playlist);\n saveToLocalStorage();\n renderPlaylists();\n }\n \n function renderPlaylists() {\n container.innerHTML = '';\n \n playlists.forEach(playlist => {\n const element = document.createElement('div');\n element.className = `playlist-item ${playlist.completed ? 'completed' : ''}`;\n \n element.innerHTML = `\n <div class=\"playlist-info\">\n <div class=\"playlist-title\">${playlist.title}</div>\n <a href=\"${playlist.url}\" class=\"playlist-url\" target=\"_blank\" rel=\"noopener noreferrer\">\n ${playlist.url}\n </a>\n </div>\n <button class=\"btn-complete\" onclick=\"toggleComplete(${playlist.id})\">\n ${playlist.completed ? '✓ Completed' : 'Mark Complete'}\n </button>\n `;\n \n container.appendChild(element);\n });\n }\n \n // Make toggleComplete available globally\n window.toggleComplete = function(id) {\n const playlist = playlists.find(p => p.id === id);\n if (playlist) {\n playlist.completed = !playlist.completed;\n saveToLocalStorage();\n renderPlaylists();\n }\n }\n \n function saveToLocalStorage() {\n localStorage.setItem('playlists', JSON.stringify(playlists));\n }\n});\n\n---end---\n\nThis website features:\n- Clean, modern design with smooth animations and transitions\n- Local storage to persist playlist data\n- Mobile-responsive layout\n- Accessibility features (semantic HTML, proper contrast)\n- Beautiful gradient header\n- Smooth hover effects\n- Clean typography and spacing\n- Visual feedback for completed items\n- Form validation\n- Proper URL handling with security attributes\n\nUsers can:\n1. Add playlist titles and URLs\n2. Mark playlists as complete/incomplete\n3. Click through to YouTube playlists\n4. See their progress persistently across sessions\n\nThe design is professional yet engaging, with careful attention to visual hierarchy and user experience." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 295, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "output_tokens": 2208 + } +} \ No newline at end of file diff --git a/readme.scroll b/readme.scroll new file mode 100644 index 0000000..18113da --- /dev/null +++ b/readme.scroll @@ -0,0 +1,2 @@ +# playlist-tracker.scroll.pub +Website generated by Claude from prompt: a website where i can post youtube playlist links in sequence along with a tick mark button to assign it as done/completed \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..9eacc49 --- /dev/null +++ b/script.js @@ -0,0 +1,70 @@ +document.addEventListener('DOMContentLoaded', () => { + const form = document.getElementById('playlist-form'); + const container = document.getElementById('playlist-container'); + + // Load saved playlists from localStorage + let playlists = JSON.parse(localStorage.getItem('playlists')) || []; + + // Render existing playlists + renderPlaylists(); + + form.addEventListener('submit', (e) => { + e.preventDefault(); + + const title = document.getElementById('playlist-title').value; + const url = document.getElementById('playlist-url').value; + + addPlaylist(title, url); + form.reset(); + }); + + function addPlaylist(title, url) { + const playlist = { + id: Date.now(), + title, + url, + completed: false + }; + + playlists.unshift(playlist); + saveToLocalStorage(); + renderPlaylists(); + } + + function renderPlaylists() { + container.innerHTML = ''; + + playlists.forEach(playlist => { + const element = document.createElement('div'); + element.className = `playlist-item ${playlist.completed ? 'completed' : ''}`; + + element.innerHTML = ` + <div class="playlist-info"> + <div class="playlist-title">${playlist.title}</div> + <a href="${playlist.url}" class="playlist-url" target="_blank" rel="noopener noreferrer"> + ${playlist.url} + </a> + </div> + <button class="btn-complete" onclick="toggleComplete(${playlist.id})"> + ${playlist.completed ? '✓ Completed' : 'Mark Complete'} + </button> + `; + + container.appendChild(element); + }); + } + + // Make toggleComplete available globally + window.toggleComplete = function(id) { + const playlist = playlists.find(p => p.id === id); + if (playlist) { + playlist.completed = !playlist.completed; + saveToLocalStorage(); + renderPlaylists(); + } + } + + function saveToLocalStorage() { + localStorage.setItem('playlists', JSON.stringify(playlists)); + } +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..0be9fba --- /dev/null +++ b/style.css @@ -0,0 +1,174 @@ +:root { + --primary-color: #6366f1; + --secondary-color: #818cf8; + --background: #f8fafc; + --text: #1e293b; + --success: #22c55e; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: system-ui, -apple-system, sans-serif; + line-height: 1.6; + color: var(--text); + background: var(--background); +} + +header { + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + color: white; + padding: 2rem; + text-align: center; + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); +} + +h1 { + font-size: 2.5rem; + margin-bottom: 0.5rem; +} + +.tagline { + font-size: 1.1rem; + opacity: 0.9; +} + +main { + max-width: 800px; + margin: 2rem auto; + padding: 0 1rem; +} + +.add-playlist { + background: white; + padding: 2rem; + border-radius: 1rem; + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); +} + +form { + display: grid; + gap: 1rem; +} + +input { + padding: 0.75rem; + border: 2px solid #e2e8f0; + border-radius: 0.5rem; + font-size: 1rem; + transition: border-color 0.2s; +} + +input:focus { + outline: none; + border-color: var(--primary-color); +} + +.btn-add { + background: var(--primary-color); + color: white; + border: none; + padding: 0.75rem; + border-radius: 0.5rem; + cursor: pointer; + font-size: 1rem; + transition: background-color 0.2s; +} + +.btn-add:hover { + background: var(--secondary-color); +} + +.playlists { + margin-top: 2rem; +} + +h2 { + margin-bottom: 1rem; + color: var(--text); +} + +.playlist-item { + background: white; + padding: 1.5rem; + border-radius: 0.5rem; + margin-bottom: 1rem; + display: flex; + justify-content: space-between; + align-items: center; + box-shadow: 0 2px 4px -1px rgb(0 0 0 / 0.1); + transition: transform 0.2s; +} + +.playlist-item:hover { + transform: translateY(-2px); +} + +.playlist-info { + flex-grow: 1; +} + +.playlist-title { + font-weight: 600; + margin-bottom: 0.5rem; +} + +.playlist-url { + color: var(--primary-color); + text-decoration: none; +} + +.playlist-url:hover { + text-decoration: underline; +} + +.btn-complete { + background: none; + border: 2px solid var(--success); + color: var(--success); + padding: 0.5rem 1rem; + border-radius: 0.5rem; + cursor: pointer; + margin-left: 1rem; + transition: all 0.2s; +} + +.completed .btn-complete { + background: var(--success); + color: white; +} + +.completed { + opacity: 0.7; +} + +footer { + text-align: center; + padding: 2rem; + color: var(--text); + opacity: 0.8; +} + +@media (max-width: 600px) { + header { + padding: 1.5rem; + } + + h1 { + font-size: 2rem; + } + + .playlist-item { + flex-direction: column; + gap: 1rem; + text-align: center; + } + + .btn-complete { + margin-left: 0; + } +}