commit df0de7ea9d040430ae8db89cae8f97d31436aa67
Author: root <root@hub.scroll.pub> Date: 2024-12-28 19:24:52 +0000 Subject: Initial commit diff --git a/body.html b/body.html new file mode 100644 index 0000000..db789f4 --- /dev/null +++ b/body.html @@ -0,0 +1,47 @@ +<header> + <nav> + <div class="logo">StudyLog</div> + <button class="theme-toggle" aria-label="Toggle dark mode">🌙</button> + </nav> +</header> + +<main> + <section class="add-course"> + <h1>Track Your Learning Progress</h1> + <form id="courseForm"> + <div class="input-group"> + <input type="text" id="courseName" placeholder="Course or Book Title" required> + <input type="text" id="platform" placeholder="Platform (e.g., Udemy, O'Reilly)"> + <input type="number" id="totalHours" placeholder="Total Expected Hours" min="0" step="0.5" required> + </div> + <button type="submit">Add Course</button> + </form> + </section> + + <section class="courses"> + <h2>Your Courses</h2> + <div class="course-grid" id="courseList"></div> + </section> + + <section class="stats"> + <h2>Statistics</h2> + <div class="stats-grid"> + <div class="stat-card"> + <h3>Total Courses</h3> + <p id="totalCourses">0</p> + </div> + <div class="stat-card"> + <h3>Study Hours</h3> + <p id="totalHoursStudied">0</p> + </div> + <div class="stat-card"> + <h3>Completion Rate</h3> + <p id="completionRate">0%</p> + </div> + </div> + </section> +</main> + +<footer> + <p>Built with passion by StudyLog</p> +</footer> \ No newline at end of file diff --git a/index.scroll b/index.scroll new file mode 100644 index 0000000..fc73c88 --- /dev/null +++ b/index.scroll @@ -0,0 +1,8 @@ +buildHtml +baseUrl https://studylog.scroll.pub +metaTags +editButton /edit.html +title StudyLog - Track Your Learning Journey +style.css +body.html +script.js \ No newline at end of file diff --git a/prompt.json b/prompt.json new file mode 100644 index 0000000..bf2814b --- /dev/null +++ b/prompt.json @@ -0,0 +1,20 @@ +{ + "id": "msg_015NmPSXVxWDcnAhySdfrYGn", + "type": "message", + "role": "assistant", + "model": "claude-3-5-sonnet-20241022", + "content": [ + { + "type": "text", + "text": "I'll create a study time tracking website with a clean, modern design.\n\nSuggested domain name: studylog.scroll.pub - Simple, memorable, and clearly represents the purpose.\n\n---domain---\nstudylog.scroll.pub\n---index.scroll---\nbuildHtml\nbaseUrl https://studylog.scroll.pub\nmetaTags\neditButton /edit.html\ntitle StudyLog - Track Your Learning Journey\nstyle.css\nbody.html\nscript.js\n---body.html---\n<header>\n <nav>\n <div class=\"logo\">StudyLog</div>\n <button class=\"theme-toggle\" aria-label=\"Toggle dark mode\">🌙</button>\n </nav>\n</header>\n\n<main>\n <section class=\"add-course\">\n <h1>Track Your Learning Progress</h1>\n <form id=\"courseForm\">\n <div class=\"input-group\">\n <input type=\"text\" id=\"courseName\" placeholder=\"Course or Book Title\" required>\n <input type=\"text\" id=\"platform\" placeholder=\"Platform (e.g., Udemy, O'Reilly)\">\n <input type=\"number\" id=\"totalHours\" placeholder=\"Total Expected Hours\" min=\"0\" step=\"0.5\" required>\n </div>\n <button type=\"submit\">Add Course</button>\n </form>\n </section>\n\n <section class=\"courses\">\n <h2>Your Courses</h2>\n <div class=\"course-grid\" id=\"courseList\"></div>\n </section>\n\n <section class=\"stats\">\n <h2>Statistics</h2>\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <h3>Total Courses</h3>\n <p id=\"totalCourses\">0</p>\n </div>\n <div class=\"stat-card\">\n <h3>Study Hours</h3>\n <p id=\"totalHoursStudied\">0</p>\n </div>\n <div class=\"stat-card\">\n <h3>Completion Rate</h3>\n <p id=\"completionRate\">0%</p>\n </div>\n </div>\n </section>\n</main>\n\n<footer>\n <p>Built with passion by StudyLog</p>\n</footer>\n---style.css---\n:root {\n --primary: #4a90e2;\n --secondary: #f5f7fa;\n --text: #2c3e50;\n --background: #ffffff;\n --card: #ffffff;\n --shadow: rgba(0, 0, 0, 0.1);\n}\n\n[data-theme=\"dark\"] {\n --primary: #64b5f6;\n --secondary: #1a1a1a;\n --text: #e0e0e0;\n --background: #121212;\n --card: #1e1e1e;\n --shadow: rgba(255, 255, 255, 0.1);\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 background: var(--background);\n color: var(--text);\n line-height: 1.6;\n transition: background-color 0.3s, color 0.3s;\n}\n\nheader {\n background: var(--card);\n box-shadow: 0 2px 10px var(--shadow);\n padding: 1rem;\n position: sticky;\n top: 0;\n z-index: 100;\n}\n\nnav {\n max-width: 1200px;\n margin: 0 auto;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.logo {\n font-size: 1.5rem;\n font-weight: bold;\n color: var(--primary);\n}\n\n.theme-toggle {\n background: none;\n border: none;\n font-size: 1.2rem;\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 50%;\n transition: background-color 0.3s;\n}\n\n.theme-toggle:hover {\n background: var(--secondary);\n}\n\nmain {\n max-width: 1200px;\n margin: 2rem auto;\n padding: 0 1rem;\n}\n\n.add-course {\n background: var(--card);\n padding: 2rem;\n border-radius: 1rem;\n box-shadow: 0 4px 6px var(--shadow);\n margin-bottom: 2rem;\n}\n\nh1 {\n font-size: 2rem;\n margin-bottom: 1.5rem;\n color: var(--primary);\n}\n\n.input-group {\n display: grid;\n gap: 1rem;\n margin-bottom: 1rem;\n}\n\n@media (min-width: 768px) {\n .input-group {\n grid-template-columns: repeat(3, 1fr);\n }\n}\n\ninput {\n padding: 0.8rem;\n border: 2px solid var(--secondary);\n border-radius: 0.5rem;\n background: var(--background);\n color: var(--text);\n transition: border-color 0.3s;\n}\n\ninput:focus {\n border-color: var(--primary);\n outline: none;\n}\n\nbutton {\n background: var(--primary);\n color: white;\n padding: 0.8rem 1.5rem;\n border: none;\n border-radius: 0.5rem;\n cursor: pointer;\n transition: transform 0.2s, opacity 0.2s;\n}\n\nbutton:hover {\n transform: translateY(-2px);\n opacity: 0.9;\n}\n\n.course-grid {\n display: grid;\n gap: 1.5rem;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n}\n\n.course-card {\n background: var(--card);\n padding: 1.5rem;\n border-radius: 1rem;\n box-shadow: 0 4px 6px var(--shadow);\n transition: transform 0.3s;\n}\n\n.course-card:hover {\n transform: translateY(-5px);\n}\n\n.stats-grid {\n display: grid;\n gap: 1.5rem;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n margin-top: 1rem;\n}\n\n.stat-card {\n background: var(--card);\n padding: 1.5rem;\n border-radius: 1rem;\n text-align: center;\n box-shadow: 0 4px 6px var(--shadow);\n}\n\n.stat-card h3 {\n color: var(--primary);\n margin-bottom: 0.5rem;\n}\n\n.stat-card p {\n font-size: 2rem;\n font-weight: bold;\n}\n\nfooter {\n text-align: center;\n padding: 2rem;\n background: var(--card);\n margin-top: 4rem;\n}\n\n@media (max-width: 768px) {\n h1 {\n font-size: 1.5rem;\n }\n \n .stat-card p {\n font-size: 1.5rem;\n }\n}\n---script.js---\ndocument.addEventListener('DOMContentLoaded', () => {\n // Theme toggling\n const themeToggle = document.querySelector('.theme-toggle');\n const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');\n \n function setTheme(isDark) {\n document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');\n themeToggle.textContent = isDark ? '☀️' : '🌙';\n }\n \n setTheme(prefersDark.matches);\n \n themeToggle.addEventListener('click', () => {\n const isDark = document.documentElement.getAttribute('data-theme') === 'dark';\n setTheme(!isDark);\n });\n\n // Course management\n const courseForm = document.getElementById('courseForm');\n const courseList = document.getElementById('courseList');\n let courses = JSON.parse(localStorage.getItem('courses')) || [];\n\n function saveCourses() {\n localStorage.setItem('courses', JSON.stringify(courses));\n updateStats();\n renderCourses();\n }\n\n function updateStats() {\n document.getElementById('totalCourses').textContent = courses.length;\n \n const totalHours = courses.reduce((sum, course) => sum + course.hoursSpent, 0);\n document.getElementById('totalHoursStudied').textContent = totalHours.toFixed(1);\n \n const completion = courses.reduce((sum, course) => {\n return sum + (course.hoursSpent / course.totalHours) * 100;\n }, 0) / (courses.length || 1);\n \n document.getElementById('completionRate').textContent = `${completion.toFixed(1)}%`;\n }\n\n function renderCourses() {\n courseList.innerHTML = '';\n courses.forEach((course, index) => {\n const progress = (course.hoursSpent / course.totalHours) * 100;\n \n const courseCard = document.createElement('div');\n courseCard.className = 'course-card';\n courseCard.innerHTML = `\n <h3>${course.name}</h3>\n <p>${course.platform}</p>\n <div class=\"progress\">\n <div class=\"progress-bar\" style=\"width: ${progress}%\"></div>\n </div>\n <p>${course.hoursSpent}/${course.totalHours} hours</p>\n <div class=\"actions\">\n <button onclick=\"addTime(${index}, 0.5)\">+30min</button>\n <button onclick=\"removeCourse(${index})\">Delete</button>\n </div>\n `;\n courseList.appendChild(courseCard);\n });\n }\n\n courseForm.addEventListener('submit', (e) => {\n e.preventDefault();\n const newCourse = {\n name: document.getElementById('courseName').value,\n platform: document.getElementById('platform').value,\n totalHours: parseFloat(document.getElementById('totalHours').value),\n hoursSpent: 0\n };\n courses.push(newCourse);\n saveCourses();\n courseForm.reset();\n });\n\n window.addTime = (index, hours) => {\n courses[index].hoursSpent = Math.min(\n courses[index].hoursSpent + hours,\n courses[index].totalHours\n );\n saveCourses();\n };\n\n window.removeCourse = (index) => {\n if (confirm('Are you sure you want to delete this course?')) {\n courses.splice(index, 1);\n saveCourses();\n }\n };\n\n // Initial render\n renderCourses();\n updateStats();\n});\n---end---\n\nThis implementation provides:\n\n1. Clean, semantic HTML5 structure\n2. Responsive design that works on all devices\n3. Dark/light theme support with system preference detection\n4. Local storage for data persistence\n5. Beautiful animations and transitions\n6. Accessible design with proper ARIA labels\n7. Progress tracking with visual feedback\n8. Statistics dashboard\n9. Clean and modern UI with card-based design\n10. Intuitive course management system\n\nThe design is both functional and aesthetically pleasing, with smooth animations, proper spacing, and a professional color scheme. The dark mode implementation ensures comfortable viewing in all lighting conditions." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 284, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "output_tokens": 2985 + } +} \ No newline at end of file diff --git a/readme.scroll b/readme.scroll new file mode 100644 index 0000000..d97e117 --- /dev/null +++ b/readme.scroll @@ -0,0 +1,2 @@ +# studylog.scroll.pub +Website generated by Claude from prompt: a studying time tracker to track video courses like udemy courses or books \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..cd568b8 --- /dev/null +++ b/script.js @@ -0,0 +1,96 @@ +document.addEventListener('DOMContentLoaded', () => { + // Theme toggling + const themeToggle = document.querySelector('.theme-toggle'); + const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); + + function setTheme(isDark) { + document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light'); + themeToggle.textContent = isDark ? '☀️' : '🌙'; + } + + setTheme(prefersDark.matches); + + themeToggle.addEventListener('click', () => { + const isDark = document.documentElement.getAttribute('data-theme') === 'dark'; + setTheme(!isDark); + }); + + // Course management + const courseForm = document.getElementById('courseForm'); + const courseList = document.getElementById('courseList'); + let courses = JSON.parse(localStorage.getItem('courses')) || []; + + function saveCourses() { + localStorage.setItem('courses', JSON.stringify(courses)); + updateStats(); + renderCourses(); + } + + function updateStats() { + document.getElementById('totalCourses').textContent = courses.length; + + const totalHours = courses.reduce((sum, course) => sum + course.hoursSpent, 0); + document.getElementById('totalHoursStudied').textContent = totalHours.toFixed(1); + + const completion = courses.reduce((sum, course) => { + return sum + (course.hoursSpent / course.totalHours) * 100; + }, 0) / (courses.length || 1); + + document.getElementById('completionRate').textContent = `${completion.toFixed(1)}%`; + } + + function renderCourses() { + courseList.innerHTML = ''; + courses.forEach((course, index) => { + const progress = (course.hoursSpent / course.totalHours) * 100; + + const courseCard = document.createElement('div'); + courseCard.className = 'course-card'; + courseCard.innerHTML = ` + <h3>${course.name}</h3> + <p>${course.platform}</p> + <div class="progress"> + <div class="progress-bar" style="width: ${progress}%"></div> + </div> + <p>${course.hoursSpent}/${course.totalHours} hours</p> + <div class="actions"> + <button onclick="addTime(${index}, 0.5)">+30min</button> + <button onclick="removeCourse(${index})">Delete</button> + </div> + `; + courseList.appendChild(courseCard); + }); + } + + courseForm.addEventListener('submit', (e) => { + e.preventDefault(); + const newCourse = { + name: document.getElementById('courseName').value, + platform: document.getElementById('platform').value, + totalHours: parseFloat(document.getElementById('totalHours').value), + hoursSpent: 0 + }; + courses.push(newCourse); + saveCourses(); + courseForm.reset(); + }); + + window.addTime = (index, hours) => { + courses[index].hoursSpent = Math.min( + courses[index].hoursSpent + hours, + courses[index].totalHours + ); + saveCourses(); + }; + + window.removeCourse = (index) => { + if (confirm('Are you sure you want to delete this course?')) { + courses.splice(index, 1); + saveCourses(); + } + }; + + // Initial render + renderCourses(); + updateStats(); +}); \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..e1dcf69 --- /dev/null +++ b/style.css @@ -0,0 +1,189 @@ +:root { + --primary: #4a90e2; + --secondary: #f5f7fa; + --text: #2c3e50; + --background: #ffffff; + --card: #ffffff; + --shadow: rgba(0, 0, 0, 0.1); +} + +[data-theme="dark"] { + --primary: #64b5f6; + --secondary: #1a1a1a; + --text: #e0e0e0; + --background: #121212; + --card: #1e1e1e; + --shadow: rgba(255, 255, 255, 0.1); +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: system-ui, -apple-system, sans-serif; + background: var(--background); + color: var(--text); + line-height: 1.6; + transition: background-color 0.3s, color 0.3s; +} + +header { + background: var(--card); + box-shadow: 0 2px 10px var(--shadow); + padding: 1rem; + position: sticky; + top: 0; + z-index: 100; +} + +nav { + max-width: 1200px; + margin: 0 auto; + display: flex; + justify-content: space-between; + align-items: center; +} + +.logo { + font-size: 1.5rem; + font-weight: bold; + color: var(--primary); +} + +.theme-toggle { + background: none; + border: none; + font-size: 1.2rem; + cursor: pointer; + padding: 0.5rem; + border-radius: 50%; + transition: background-color 0.3s; +} + +.theme-toggle:hover { + background: var(--secondary); +} + +main { + max-width: 1200px; + margin: 2rem auto; + padding: 0 1rem; +} + +.add-course { + background: var(--card); + padding: 2rem; + border-radius: 1rem; + box-shadow: 0 4px 6px var(--shadow); + margin-bottom: 2rem; +} + +h1 { + font-size: 2rem; + margin-bottom: 1.5rem; + color: var(--primary); +} + +.input-group { + display: grid; + gap: 1rem; + margin-bottom: 1rem; +} + +@media (min-width: 768px) { + .input-group { + grid-template-columns: repeat(3, 1fr); + } +} + +input { + padding: 0.8rem; + border: 2px solid var(--secondary); + border-radius: 0.5rem; + background: var(--background); + color: var(--text); + transition: border-color 0.3s; +} + +input:focus { + border-color: var(--primary); + outline: none; +} + +button { + background: var(--primary); + color: white; + padding: 0.8rem 1.5rem; + border: none; + border-radius: 0.5rem; + cursor: pointer; + transition: transform 0.2s, opacity 0.2s; +} + +button:hover { + transform: translateY(-2px); + opacity: 0.9; +} + +.course-grid { + display: grid; + gap: 1.5rem; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); +} + +.course-card { + background: var(--card); + padding: 1.5rem; + border-radius: 1rem; + box-shadow: 0 4px 6px var(--shadow); + transition: transform 0.3s; +} + +.course-card:hover { + transform: translateY(-5px); +} + +.stats-grid { + display: grid; + gap: 1.5rem; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + margin-top: 1rem; +} + +.stat-card { + background: var(--card); + padding: 1.5rem; + border-radius: 1rem; + text-align: center; + box-shadow: 0 4px 6px var(--shadow); +} + +.stat-card h3 { + color: var(--primary); + margin-bottom: 0.5rem; +} + +.stat-card p { + font-size: 2rem; + font-weight: bold; +} + +footer { + text-align: center; + padding: 2rem; + background: var(--card); + margin-top: 4rem; +} + +@media (max-width: 768px) { + h1 { + font-size: 1.5rem; + } + + .stat-card p { + font-size: 1.5rem; + } +} \ No newline at end of file