diff --git a/ProjectOne b/ProjectOne new file mode 160000 index 0000000..adf6752 --- /dev/null +++ b/ProjectOne @@ -0,0 +1 @@ +Subproject commit adf6752a1b52667d20ba1f7e3bb155e2fb3f41e3 diff --git a/README.md b/README.md index 03c100b..365fa3d 100644 --- a/README.md +++ b/README.md @@ -2,32 +2,52 @@ First Project for Software Developer Bootcamp ## Description -Our project is a calendar that helps keep track and check off tasks throughout the month with leveling urgency. Another thing this project does is help be a good study guide. -Our motivation for this was to create a simple and easy way to organize the tasks that you have the upcoming weeks and to help motivate the importance of studying. -This project helps solve the problem of when a task should be completed meaning setting how urgent a task is to get done will put it, it also solves the annoyance of having to study with a feature to add flash cards which will earn you points. +Our project is a calendar application designed to help users track and manage tasks throughout the month, with an emphasis on prioritizing tasks based on urgency. The goal of this project was to create an intuitive and efficient tool for organizing tasks and deadlines for the upcoming weeks. + +This application addresses the challenge of determining when tasks should be completed by allowing users to set urgency levels for each task. By prioritizing tasks according to urgency, it ensures that users stay on top of their responsibilities and deadlines. + + +## To use this calendar +1. Click on the date or day you wish to add a task to. +2. Select “Add Task” and enter the task description. +3. Choose the urgency level for the task and press Enter to save it. +5. To mark a task as completed, click on it, and a line will be drawn through it. +6. To remove a completed task, click the “X” button next to it. +7. The "View" dropdown menu allows you to toggle between Month, Week, and Day views. +8. Use the Next/Previous arrows to navigate between months, weeks, or days. +9. Clicking the "Today" button will take you directly to the current date in the active view. -## Usage -To use this calendar -1. Click on the date/day that you want to add a task to -2. Click add task and type out the task you would like to -3. Decide how urgent that task is then click enter -4. To check off a task simply click it and it’ll be taken off the task list -Flash cards coming soon ## Credits -Phoebe Ferguson-Phobeferg -Ryan Lang-langiam -Zawadi Brown-Zawadiflag12 -Rogerick Gordon-Rgordon333 -Jacob McDonald-JMcDonald99 +Phoebe Ferguson (@Phobeferg) +Ryan Lang (@langiam) +Zawadi Brown (@Zawadiflag12) +Rogerick Gordon (@Rgordon333) +Jacob McDonald (@JMcDonald99) + +## External Resources +W3Schools DOM Tutorial | W3 Schools +Introduction to the Document Object Model (DOM) | MDN +Document: querySelector() method | MDN +EventTarget: addEventListener() method | MDN +JS Function Basics | JS Info +Variables | MDN +localStorage property | MDN +Manipulating DOM's (RENDER) | MDN +createElement() method | MDN +ForEach Loops | MDN +Array.splice +Web Forms | MDN +day.js | npmjs +Load Event | MDN + -https://day.js.org/ ## License GNU AGPLv3 ## Features -Task manager -Color coded task list -Study guide \ No newline at end of file +- Task Management System: Efficiently create, prioritize, and track tasks with the ability to mark them as completed. +- Color-Coded Task List: Easily distinguish between tasks based on their urgency with a color-coded system. +- View Changer: Seamlessly switch between Month, Week, and Day views to get the most relevant perspective on your tasks. \ No newline at end of file diff --git a/index.html b/index.html index 8cb1a3b..cf41104 100644 --- a/index.html +++ b/index.html @@ -10,32 +10,28 @@ -
- -
- +
-
-

Group 5's Calendar

-
- -
+
+
-

+

+
- +
+
- +
@@ -46,29 +42,32 @@

-
-
- × -
Add Task
-
-
- - +
+
+ -
-
-
- -
- - - +
+
+ + +
+
+ + +
+ + +
+
+
-
diff --git a/script.js b/script.js index 19fed48..f851510 100644 --- a/script.js +++ b/script.js @@ -4,26 +4,37 @@ document.addEventListener("DOMContentLoaded", () => { const prevMonthButton = document.getElementById("prevMonth"); const nextMonthButton = document.getElementById("nextMonth"); const modal = document.getElementById("taskModal"); + const modalContent = document.getElementById("modalContent"); + const modalHeader = document.getElementById("modalHeader"); + const resizeHandle = document.getElementById("resizeHandle"); const taskForm = document.getElementById("taskForm"); const selectedDateInput = document.getElementById("selectedDate"); const darkModeButton = document.getElementById("darkb"); const hamburgerButton = document.getElementById("hamburgerButton"); const viewDropdown = document.getElementById("viewDropdown"); + const todayButton = document.getElementById("todayButton"); let currentDate = dayjs(); let tasks = JSON.parse(localStorage.getItem("tasks")) || {}; let currentView = "month"; let icon = darkModeButton.querySelector("i") + let isDragging = false; + let isResizing = false; + let dragOffset = { x: 0, y: 0 }; + let startSize = { width: 0, height: 0 }; + let startPosition = { x: 0, y: 0 }; + let lastTap = 0; - // Dark Mode Toggle - window.darkMode = () => { - document.body.classList.toggle("dark-mode"); - icon.classList.toggle("bi-brightness-high-fill"); - icon.classList.toggle("bi-moon-stars-fill"); - }; - darkModeButton.addEventListener("click", darkMode); + // Dark Mode Toggle + function toggleDarkMode() { + document.body.classList.toggle("dark-mode"); + icon.classList.toggle("bi-brightness-high-fill", !document.body.classList.contains("dark-mode")); + icon.classList.toggle("bi-moon-stars-fill", document.body.classList.contains("dark-mode")); + } + darkModeButton.addEventListener("click", toggleDarkMode); + // Today's Date Button todayButton.addEventListener("click", () => { currentDate = dayjs(); @@ -34,7 +45,10 @@ document.addEventListener("DOMContentLoaded", () => { function saveTasks() { localStorage.setItem("tasks", JSON.stringify(tasks)); } - + // Helper Function: Format Dates + function getFormattedDate(date) { + return date.format("YYYY-MM-DD"); + } // Hamburger Menu Toggle hamburgerButton.addEventListener("click", () => { viewDropdown.style.display = viewDropdown.style.display === "block" ? "none" : "block"; @@ -47,12 +61,15 @@ document.addEventListener("DOMContentLoaded", () => { viewDropdown.style.display = "none"; }; + + // Render Calendar function renderCalendar(date) { calendarGrid.classList.remove("month-view", "week-view", "day-view"); calendarGrid.classList.add(`${currentView}-view`); - + calendarGrid.innerHTML = ""; + ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].forEach((day) => { const dayHeader = document.createElement("div"); dayHeader.className = "day-name"; @@ -60,6 +77,12 @@ document.addEventListener("DOMContentLoaded", () => { calendarGrid.appendChild(dayHeader); }); + const screenWidth = window.innerWidth; + if (screenWidth < 768 && currentView === "month") { + changeView("week"); + return; + } + if (currentView === "month") { renderMonthView(date); } else if (currentView === "week") { @@ -67,10 +90,19 @@ document.addEventListener("DOMContentLoaded", () => { } else if (currentView === "day") { renderDayView(date); } + monthYear.textContent = date.format("MMMM YYYY"); + focusOnToday(); +} + // Function that brings you to today's date automatically on the screen + function focusOnToday() { + const todayElement = document.querySelector(".date.current-day"); + if (todayElement) { + todayElement.scrollIntoView({ behavior: "smooth", block: "center" }); + } } - + // Render Month View function renderMonthView(date) { const startOfMonth = date.startOf("month"); @@ -83,7 +115,7 @@ document.addEventListener("DOMContentLoaded", () => { } for (let day = 1; day <= daysInMonth; day++) { - const formattedDate = date.date(day).format("YYYY-MM-DD"); + const formattedDate = getFormattedDate(date.date(day)); addDate(day, date.date(day).isSame(dayjs(), "day") ? "current-day active" : "active", formattedDate); renderTasks(formattedDate); } @@ -100,7 +132,7 @@ document.addEventListener("DOMContentLoaded", () => { const startOfWeek = date.startOf("week"); for (let i = 0; i < 7; i++) { const day = startOfWeek.add(i, "day"); - const formattedDate = day.format("YYYY-MM-DD"); + const formattedDate = getFormattedDate(day); addDate(day.date(), day.isSame(dayjs(), "day") ? "current-day active" : "active", formattedDate); renderTasks(formattedDate); } @@ -108,7 +140,7 @@ document.addEventListener("DOMContentLoaded", () => { // Render Day View function renderDayView(date) { - const formattedDate = date.format("YYYY-MM-DD"); + const formattedDate = getFormattedDate(date); calendarGrid.innerHTML = ""; @@ -118,61 +150,87 @@ document.addEventListener("DOMContentLoaded", () => { calendarGrid.appendChild(dayHeader); const dayContainer = document.createElement("div"); - dayContainer.className = "date active"; + dayContainer.className = `date ${date.isSame(dayjs(), "day") ? "current-day active" : "active"}`; dayContainer.dataset.date = formattedDate; dayContainer.innerHTML = `
${date.date()}
- + `; calendarGrid.appendChild(dayContainer); renderTasks(formattedDate); } - // Add Date to Calendar - function addDate(day, classes, formattedDate) { - const dateElement = document.createElement("div"); - dateElement.className = `date ${classes}`; - dateElement.dataset.date = formattedDate; - dateElement.innerHTML = ` -
${day}
-
- ${formattedDate ? `` : ""} - `; - calendarGrid.appendChild(dateElement); - } // Render Tasks function renderTasks(date) { const taskContainer = document.getElementById(`${date}-tasks`); if (!taskContainer) return; - + taskContainer.innerHTML = ""; - + if (!tasks[date]) return; - + const sortedTasks = tasks[date].slice().sort((a, b) => { if (a.completed !== b.completed) return a.completed ? 1 : -1; if (a.urgency === "urgent" && b.urgency !== "urgent") return -1; if (b.urgency === "urgent" && a.urgency !== "urgent") return 1; return 0; }); - - sortedTasks.forEach((task, index) => { + + // Limit # of tasks on mobile + const maxTasks = window.innerWidth < 768 ? 2 : 5; + sortedTasks.slice(0, maxTasks).forEach((task, index) => { const taskItem = document.createElement("div"); taskItem.className = `task-item ${task.completed ? "completed" : task.urgency}`; taskItem.dataset.date = date; taskItem.dataset.index = index; taskItem.innerHTML = ` ${task.text} - + `; taskItem.querySelector(".task-text").addEventListener("click", () => toggleComplete(date, index)); taskContainer.appendChild(taskItem); }); - } - + + if (sortedTasks.length > maxTasks) { + const viewAllButton = document.createElement("button"); + viewAllButton.className = "view-all-tasks"; + viewAllButton.innerHTML = "▼"; + viewAllButton.style.color = "grey"; + viewAllButton.addEventListener("click", () => { + taskContainer.innerHTML = ""; + sortedTasks.forEach((task, index) => { + const taskItem = document.createElement("div"); + taskItem.className = `task-item ${task.completed ? "completed" : task.urgency}`; + taskItem.dataset.date = date; + taskItem.dataset.index = index; + taskItem.innerHTML = ` + ${task.text} + + `; + taskItem.querySelector(".task-text").addEventListener("click", () => toggleComplete(date, index)); + taskContainer.appendChild(taskItem); + }); + + // Replace arrow with "Collapse" option + const collapseButton = document.createElement("button"); + collapseButton.className = "view-all-tasks"; + collapseButton.innerHTML = "▲"; + collapseButton.style.color = "grey"; + collapseButton.addEventListener("click", () => { + renderTasks(date); + }); + taskContainer.appendChild(collapseButton); + }); + taskContainer.appendChild(viewAllButton); + } + } // Toggle Complete Task window.toggleComplete = (date, index) => { tasks[date][index].completed = !tasks[date][index].completed; @@ -182,14 +240,38 @@ document.addEventListener("DOMContentLoaded", () => { // Delete Task window.deleteTask = (date, index) => { + if (!tasks[date] || !tasks[date][index]) { + console.warn(`Task not found at index ${index} for date "${date}".`); + return; + } tasks[date].splice(index, 1); if (tasks[date].length === 0) delete tasks[date]; saveTasks(); renderTasks(date); }; + function openModal(date, event) { + if (event) event.stopPropagation(); + selectedDateInput.value = date; + + // Display the modal + modal.style.display = "block"; + + // Dynamically position the modal in the center of the viewport + const modalRect = modalContent.getBoundingClientRect(); + const viewportWidth = window.innerWidth; + const viewportHeight = window.innerHeight; + + const topPosition = Math.max((viewportHeight - modalRect.height) / 2, 20); + const leftPosition = Math.max((viewportWidth - modalRect.width) / 2, 20); + + modalContent.style.top = `${topPosition}px`; + modalContent.style.left = `${leftPosition}px`; + modalContent.style.position = "absolute"; + } // Modal Functions - window.openModal = (date) => { + window.openModal = (date, event) => { + if (event) event.stopPropagation(); selectedDateInput.value = date; modal.style.display = "block"; }; @@ -198,10 +280,191 @@ document.addEventListener("DOMContentLoaded", () => { modal.style.display = "none"; }; - window.addEventListener("click", (e) => { - if (e.target === modal) closeModal(); + window.addEventListener("resize", () => { + if (modal.style.display === "block") { + const modalRect = modalContent.getBoundingClientRect(); + const viewportWidth = window.innerWidth; + const viewportHeight = window.innerHeight; + + const topPosition = Math.max((viewportHeight - modalRect.height) / 2, 20); + const leftPosition = Math.max((viewportWidth - modalRect.width) / 2, 20); + + modalContent.style.top = `${topPosition}px`; + modalContent.style.left = `${leftPosition}px`; + } }); +// Dragging and Resizing the Modal +modalHeader.addEventListener("mousedown", (e) => { + isDragging = true; + dragOffset.x = e.clientX - modalContent.offsetLeft; + dragOffset.y = e.clientY - modalContent.offsetTop; + modalContent.style.transition = "none"; +}); + +document.addEventListener("mousemove", (e) => { + if (isDragging) { + modalContent.style.left = `${e.clientX - dragOffset.x}px`; + modalContent.style.top = `${e.clientY - dragOffset.y}px`; + modalContent.style.position = "absolute"; + } +}); + +document.addEventListener("mouseup", () => { + isDragging = false; +}); + +// Resizing the Modal for Desktop +resizeHandle.addEventListener("mousedown", (e) => { + isResizing = true; + startSize.width = modalContent.offsetWidth; + startSize.height = modalContent.offsetHeight; + startPosition.x = e.clientX; + startPosition.y = e.clientY; +}); + +document.addEventListener("mousemove", (e) => { + if (isResizing) { + const newWidth = startSize.width + (e.clientX - startPosition.x); + const newHeight = startSize.height + (e.clientY - startPosition.y); + modalContent.style.width = `${newWidth}px`; + modalContent.style.height = `${newHeight}px`; + } +}); + +document.addEventListener("mouseup", () => { + isResizing = false; +}); + +// Dragging the Entire Modal (Desktop) +modalContent.addEventListener("mousedown", (e) => { + isDragging = true; + dragOffset.x = e.clientX - modalContent.offsetLeft; + dragOffset.y = e.clientY - modalContent.offsetTop; + modalContent.style.transition = "none"; +}); + +document.addEventListener("mousemove", (e) => { + if (isDragging) { + modalContent.style.left = `${e.clientX - dragOffset.x}px`; + modalContent.style.top = `${e.clientY - dragOffset.y}px`; + modalContent.style.position = "absolute"; + } +}); + +document.addEventListener("mouseup", () => { + isDragging = false; +}); + +// Dragging the Entire Modal (Touch Devices) +modalContent.addEventListener("touchstart", (e) => { + if (e.touches.length === 1) { + isDragging = true; + dragOffset.x = e.touches[0].clientX - modalContent.offsetLeft; + dragOffset.y = e.touches[0].clientY - modalContent.offsetTop; + modalContent.style.transition = "none"; + } +}); + +modalContent.addEventListener("touchmove", (e) => { + if (isDragging && e.touches.length === 1) { + modalContent.style.left = `${e.touches[0].clientX - dragOffset.x}px`; + modalContent.style.top = `${e.touches[0].clientY - dragOffset.y}px`; + modalContent.style.position = "absolute"; + } +}); + +modalContent.addEventListener("touchend", () => { + isDragging = false; +}); + +// Resizing the Modal for Touch Devices +resizeHandle.addEventListener("touchstart", (e) => { + if (e.touches.length === 2) { + isResizing = true; + initialDistance = Math.hypot( + e.touches[0].clientX - e.touches[1].clientX, + e.touches[0].clientY - e.touches[1].clientY + ); + startSize.width = modalContent.offsetWidth; + startSize.height = modalContent.offsetHeight; + } +}); + +resizeHandle.addEventListener("touchmove", (e) => { + if (isResizing && e.touches.length === 2) { + const currentDistance = Math.hypot( + e.touches[0].clientX - e.touches[1].clientX, + e.touches[0].clientY - e.touches[1].clientY + ); + const scale = currentDistance / initialDistance; + + modalContent.style.width = `${startSize.width * scale}px`; + modalContent.style.height = `${startSize.height * scale}px`; + } +}); + +resizeHandle.addEventListener("touchend", () => { + isResizing = false; // End resizing +}); + +// Add event listener to the entire calendar grid +calendarGrid.addEventListener("click", (event) => { + const targetCell = event.target.closest(".date"); + if (!targetCell) return; + + // Hide all other Add Task buttons + const allAddTaskButtons = document.querySelectorAll(".add-task-btn"); + allAddTaskButtons.forEach((button) => (button.style.opacity = "0")); + + // Show the Add Task button for the tapped cell + const addTaskButton = targetCell.querySelector(".add-task-btn"); + if (addTaskButton) { + addTaskButton.style.opacity = "1"; + addTaskButton.style.zIndex = "10"; + } +}); + + +// Pinch-to-resize fallback for multitouch interactions +modal.addEventListener("touchstart", (e) => { + if (e.touches.length === 2) { // Detect multitouch for resizing + initialDistance = Math.hypot( + e.touches[0].clientX - e.touches[1].clientX, + e.touches[0].clientY - e.touches[1].clientY + ); + } +}); + +modal.addEventListener("touchmove", (e) => { + if (e.touches.length === 2) { // Multitouch gesture + const currentDistance = Math.hypot( + e.touches[0].clientX - e.touches[1].clientX, + e.touches[0].clientY - e.touches[1].clientY + ); + const scale = currentDistance / initialDistance; + modalContent.style.width = `${modalContent.offsetWidth * scale}px`; + modalContent.style.height = `${modalContent.offsetHeight * scale}px`; + initialDistance = currentDistance; + } +}); + +modal.addEventListener("touchend", () => { + isResizing = false; // End resizing +}); + +window.addEventListener("click", (e) => { + if (e.target === modal) { + closeModal(); + } else if (modal.contains(e.target)) { + e.stopPropagation(); + } +}); + +modalContent.addEventListener("click", (e) => { + e.stopPropagation(); // Prevent click propagation +}); + taskForm.addEventListener("submit", (e) => { e.preventDefault(); const date = selectedDateInput.value; @@ -237,6 +500,26 @@ document.addEventListener("DOMContentLoaded", () => { } } + calendarGrid.addEventListener("touchstart", (e) => { + const target = e.target.closest(".date"); + if (!target) return; + + const currentTime = new Date().getTime(); + const timeDiff = currentTime - lastTap; + + if (timeDiff < 300 && timeDiff > 0) { // Double-tap + const date = target.dataset.date; + if (date) { + openModal(date, e); + } + } else { // Single-tap + setTimeout(() => { + // Handle single-tap actions (e.g., select date) + }, 300); + } + + lastTap = currentTime; + }); // Add Date to Calendar function addDate(day, classes, formattedDate) { const dateElement = document.createElement("div"); @@ -250,27 +533,13 @@ document.addEventListener("DOMContentLoaded", () => { calendarGrid.appendChild(dateElement); } - prevMonthButton.addEventListener("click", () => { - if (currentView === "week") { - currentDate = currentDate.subtract(1, "week"); - } else if (currentView === "day") { - currentDate = currentDate.subtract(1, "day"); - } else { - currentDate = currentDate.subtract(1, "month"); + function changeDate(direction) { + const unit = currentView === "week" ? "week" : currentView === "day" ? "day" : "month"; + currentDate = direction === "prev" ? currentDate.subtract(1, unit) : currentDate.add(1, unit); + renderCalendar(currentDate); } - renderCalendar(currentDate); - }); - - nextMonthButton.addEventListener("click", () => { - if (currentView === "week") { - currentDate = currentDate.add(1, "week"); - } else if (currentView === "day") { - currentDate = currentDate.add(1, "day"); - } else { - currentDate = currentDate.add(1, "month"); - } - renderCalendar(currentDate); - }); + prevMonthButton.addEventListener("click", () => changeDate("prev")); + nextMonthButton.addEventListener("click", () => changeDate("next")); renderCalendar(currentDate); }); diff --git a/style.css b/style.css index 43fd85b..fd2cca9 100644 --- a/style.css +++ b/style.css @@ -12,9 +12,9 @@ --lightboarder: rgb(204, 204, 204); --darkbg: #141414; --darktxt: rgb(238, 231, 222); - --darkinactive: #2c2929; - --darkactive: #344d55; - --darktask: rgb(34, 0, 34); + --darkinactive: #1a1a1a; + --darkactive: #cacaca; + --darktask: rgb(68, 0, 68); } /* Dark Mode Styling */ @@ -27,12 +27,13 @@ border: solid 2.5px whitesmoke; background-color: var(--Lightbg); color: var(--lighttxt); - box-shadow: 2px 3px 8px rgb(218, 213, 213); + box-shadow: -2px 3px 8px rgb(218, 213, 213); } .dark-mode h1, .dark-mode h5 { color: var(--darktxt); + text-shadow: -2px 3px 8px rgb(218, 213, 213); } .dark-mode .calendar-grid, @@ -40,16 +41,80 @@ .dark-mode .date { background-color: var(--darkbg); color: var(--darktxt); + box-shadow: -4px 4px 10px rgb(218, 213, 213); } +.dark-mode .date.current-day { + background-color: var(--darkactive); + color: black; + box-shadow: 2px 2px 10px black; +} +.dark-mode .date.current-day .add-task-btn{ + background-color: black; + color: white; +} +.date.current-day .add-task-btn{ + background-color: white; + color: black; +} .dark-mode .day-name { background-color: #3d3d3d; color: rgb(255, 255, 255); } -.dark-mode .date.current-day { - border-color: white; - background-color: var(--darkactive); - color: white; +/* Dark-mode tasks */ +.dark-mode .task-item{ + border: 1px solid #3d3d3d; + color: #000; +} +.dark-mode .task-item.urgent { + background-color: rgb(255, 123, 0); + box-shadow: -1px 1px 5px rgb(255, 102, 0); +} +.dark-mode .task-item.urgent:hover { + background-color: rgb(201, 159, 120); +} + +.dark-mode .task-item.non-urgent { + background-color: yellow; + box-shadow: -1px 1px 5px yellow; +} +.dark-mode .task-item.non-urgent:hover { + background-color:rgb(248, 252, 188) ; +} +.dark-mode .date.current-day.active .task-item.urgent { + background-color: rgb(253, 135, 80); + box-shadow: -1px 1px 5px rgb(253, 135, 80); + color: black; +} +.dark-mode .date.current-day.active .task-item.urgent:hover { + background-color: rgb(255, 166, 125); + color: black; +} +.dark-mode .date.current-day.active .task-item.non-urgent { + background-color: rgb(128, 125, 0); + color: black; +} +.dark-mode .date.current-day.active .task-item.non-urgent:hover { + background-color: rgb( 252, 241, 92); + color: black; + box-shadow: -1px 1px 5px rgb(252, 241, 92); +} + +.dark-mode .task-item.completed { + background-color:#3b3b3b; + color: #aaaaaa; + box-shadow: -1px 1px 5px #aaaaaa; +} +.dark-mode .task-item.completed:hover { + background-color:#797979 ; + color: #3b3b3b; +} +.dark-mode .delete-task { + color: #8d000e; +} + +.dark-mode .delete-task:hover { + color: red; } /* dark buttons */ @@ -57,6 +122,7 @@ background-color: var(--darktask); color: var(--darktxt); border: #000; + box-shadow: -2px 3px 8px rgb(224, 130, 224); } .dark-mode .btn:hover { background-color: var(--Lightbg); @@ -67,6 +133,16 @@ color: black; } +/* Hamburger */ +.dark-mode .dropdown-menu{ +background-color: var(--darktask); +} +.dark-mode .dropdown-item{ + color: white; +} +.dark-mode .dropdown-item:hover{ + background-color: black; +} /* Body Styling */ body { font-family: Arial, sans-serif; @@ -75,7 +151,6 @@ body { transition: background-color 0.6s ease-in-out, color 0.6s ease-in-out; } - /* Font Smoothing */ body { -webkit-font-smoothing: antialiased; /* For Chrome, Edge, Safari */ @@ -84,9 +159,11 @@ body { h1 { font-size: 45px; font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif ; + font-weight: bold; +} +.call{ + padding-right: 15px; } - -h1, #monthYear { font-weight: bold; } @@ -99,11 +176,21 @@ h1, font-family: Georgia, 'Times New Roman', Times, serif; } +/* Hamburger Button */ #hamburgerButton { font-family: Georgia, 'Times New Roman', Times, serif; font-weight: bold; } - +.dropdown-menu{ +background-color: pink; +min-width: 0px; +} +.dropdown-item{ + color: black; +} +.dropdown-item:hover{ + background-color: white; +} /* Header Styling */ header { display: flex; @@ -112,46 +199,46 @@ header { #darkb { border: solid 2.5px black; - background-color: rgb(38, 51, 155); + background-color: rgb(38, 51, 155); box-shadow: 4px 6px 8px black; - float: right; - margin-right: 20px; border-radius: 50%; - width: 40px; - height: 40px; + width: 60px; + height: 60px; display: flex; align-items: center; justify-content: center; + color: rgb(248, 238, 150); } /* Container */ .container { - max-width: 1200px; - margin: auto; - padding: 20px; + padding: 1rem; + max-width: 100%; + margin: 0 auto; } - /* Calendar Grid */ .calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); - gap: 1px; + gap: 2px; background-color: #dee2e6; - border: 1px solid #dee2e6; border-radius: 8px; } - +.cal-head{ + display: flex; + width: 35%; + justify-content: space-between; +} .day-name { + background-color: rgb(219, 219, 219); + color: black; font-family: Georgia, 'Times New Roman', Times, serif; - background-color: #e9ecef; text-align: center; padding: 10px; font-weight: bold; border: 1px solid #dee2e6; - color: var(--lighttxt); - transition: color 0.3s ease-in-out; color: var(--lightboarder); - + transition: color 0.3s ease-in-out; } .calendar-grid.day-view { @@ -159,65 +246,69 @@ header { grid-template-rows: auto 1fr; } -.day-name { - background-color: #000000ce; - color: rgb(255, 255, 255); -} - -/* Month View - Default */ -/* Default Date Styling */ +/*Date Styling */ .date { - position: relative; + position: relative; + height: 150px; + padding: 5px; + display: flex; + flex-direction: column; background-color: var(--Lightbg); - height: 150px; border: 1px solid #dee2e6; + box-sizing: border-box; + overflow: hidden; +} + + +/* View-Specific Height Control */ +.week-view .date, +.day-view .date { + min-height: 300px; + height: auto; + max-height: 50vh; + overflow-y: auto; display: flex; flex-direction: column; justify-content: space-between; - padding: 5px; - cursor: pointer; - width: 150px; +} + +.date.active{ + width: 100%; } .date .add-task-btn { - visibility: hidden; + display: block; opacity: 0; position: absolute; - top: 50%; - left: 50%; + top: 13%; + right: -9%; transform: translate(-50%, -50%); - width: 50px; - height: 50px; + width: 40px; + height: 30px; background-color: #000000; color: white; border: none; - border-radius: 50%; /* Makes the button circular */ - font-size: 0.75rem; - font-weight: bold; - display: flex; - align-items: center; - justify-content: center; - z-index: 1; /*makes button hover above cell*/ + border-radius: 50%; + font-size: 0.7rem; + z-index: 1; cursor: pointer; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out; + will-change: opacity, transform; } - /* Show Add Task Button on Hover */ .date:hover .add-task-btn { - visibility: visible; - opacity: 1; - transform: translate(-50%, -50%) scale(1.1); + opacity: 1 !important; + transform: translate(-50%, -50%) scale(1.1) !important; } - - /* Current Day Highlight */ .date.current-day { border: 2px solid black; - background-color: rgb(117, 177, 176); - color: var(--lighttxt); + background-color: rgb(32, 32, 32); + color: white; + box-shadow: 2px 2px 10px black; } .date.inactive { @@ -227,51 +318,82 @@ header { opacity: 0.5; } -/* Changes the width of the date box in the day view */ -.date.active{ - width: 100%; -} /* Task Styles */ .task-item { margin: 5px 0; - padding: 5px 10px; + padding: 8px 12px; border: 1px solid #dee2e6; border-radius: 5px; - font-size: 0.85rem; + font-size: 0.9rem; + min-height: 40px; display: flex; justify-content: space-between; align-items: center; - + color: black; } +::-webkit-scrollbar { + width: 5px; + } .tasks{ white-space: nowrap; overflow-x: hidden; overflow-y: auto; + -webkit-overflow-scrolling: touch; text-overflow: ellipsis; - max-height: 150px; + max-height: calc(100% - 30px); padding: 5px; + word-wrap: break-word; +} +.tasks:hover{ + overflow-y: auto; + overflow-x: auto; + white-space: normal; + text-overflow: unset; } -/* .tasks{ - overflow: show; -} */ + +.date.current-day.active .task-item.urgent { + background-color: rgb(255, 166, 125); +} +.date.current-day.active .task-item.urgent:hover { + background-color: rgb(110, 40, 8); + color: white; +} +.date.current-day.active .task-item.non-urgent { + background-color: rgb(252, 241, 92); +} +.date.current-day.active .task-item.non-urgent:hover { + background-color: rgb(59, 59, 8); + color: white; +} .task-item.urgent { - background-color: rgb(243, 191, 191); - color: rgb(255, 33, 33); + background-color: rgb(255, 186, 83); +} +.task-item.urgent:hover { + background-color: rgb(255, 123, 0); } .task-item.non-urgent { - background-color: yellow; - color: rgb(87, 87, 54); + background-color: rgb(255, 255, 171); +} +.task-item.non-urgent:hover { + background-color: rgb(177, 180, 2); } .task-item.completed { - background-color: #7eca90; - color: #155724; + background-color: #797979; + color: #3b3b3b; text-decoration: line-through; cursor: pointer; } +.task-item.completed:hover { + background-color:#3b3b3b; + color: #797979; + text-decoration: line-through; + cursor: pointer; +} + /* Modal */ .custom-modal { @@ -282,20 +404,106 @@ header { left: 0; width: 100%; height: 100%; + pointer-events: none; background-color: rgba(37, 37, 37, 0.705); } +/* Modal Content */ .custom-modal-content { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + min-width: 200px; + min-height: 150px; + max-width: 90vw; + max-height: 90vh; background-color: var(--Lightbg); color: var(--lighttxt); - margin: 10% auto; padding: 20px; border-radius: 8px; - max-width: 400px; - width: 90%; - box-shadow: 0 4px 8px rgba(49, 49, 49, 0.1); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + overflow: auto; + resize: both; + pointer-events: all; } +.custom-modal-content { + transition: top 0.3s ease, left 0.3s ease, transform 0.3s ease; +} + +.view-all-tasks { + background: none; + border: none; + color: grey; + font-size: 1.2rem; + cursor: pointer; + margin-top: 5px; +} + +.view-all-tasks:hover { + color: darkgrey; +} +/* Thinner Header Bar */ +.modal-header { + cursor: move; + padding: 2px 10px; + background-color: #ccc; + border-bottom: 1px solid #aaa; + font-weight: normal; + display: flex; + justify-content: flex-end; +} + +/* Close Button */ +.modal-header .close-button { + font-size: 1.2rem; + cursor: pointer; +} + +/* Form Layout */ +form { + display: flex; + flex-direction: column; + gap: 15px; +} + +/* Labels and Input Fields */ +form .form-label { + font-weight: bold; +} + +form input, +form button { + width: 100%; + box-sizing: border-box; +} + +/* Inline Radio Buttons */ +.radio-group { + display: flex; + justify-content: space-between; + align-items: center; +} + +/* Add Task Button */ +form button { + margin-top: auto; +} + +/* Resize Handle */ +.resize-handle { + position: absolute; + width: 12px; + height: 12px; + bottom: 5px; + right: 5px; + cursor: se-resize; + background-color: #aaa; + border-radius: 50%; +} + + .close-button { position: absolute; top: 10px; @@ -305,21 +513,42 @@ header { cursor: pointer; } +.delete-task { + background: none; + border: none; + color: red; + font-size: 1.2rem; + cursor: pointer; +} + +.delete-task:hover { + color: #8d000e; +} + /* Buttons */ button { cursor: pointer; border: none; outline: none; } +#todayButton, +#hamburgerButton{ + height:60px; +} button:disabled { cursor: not-allowed; opacity: 0.6; } + .btn { background-color: pink; color: var(--lighttxt); border: #ffffff; + font-size: 1rem; + padding: 0.5rem 1rem; + height: auto; + white-space: nowrap; } .btn:hover { background-color: var(--darkbg); @@ -332,78 +561,109 @@ button:disabled { } -/* Responsive Design */ -/* Responsive Design - Extra Large Devices */ -@media (max-width: 1200px) { +/* Responsive Design - Small Devices*/ +@media (max-width: 450px) { .calendar-grid { - grid-template-columns: repeat(5, 1fr); /* 5 columns for slightly smaller screens */ -} -.day-name { - display: none; /* Hide day names to save space */ -} - -.date { - min-height: 90px; /* Adjust date cell height */ -} - -.date .add-task-btn { - width: 35px; /* Adjust button size */ - height: 35px; - font-size: 0.7rem; -} -} -@media (max-width: 1024px) { - .calendar-grid { - grid-template-columns: repeat(4, 1fr); /* 4 columns for medium screens */ + grid-template-columns: repeat(1, 1fr); + } .day-name { - display: none; /* Hide day names to save space */ + display: none; } + .dropdown-menu{ + right: 15px; + min-width: 0px; + } + .dropdown-item{ + font-size: 12px; + } + h1{ + font-size: 30px; + } + + #todayButton{ + display: none; + } + .date { - min-height: 80px; /* Reduce date cell height */ + min-height: 40px; } .date .add-task-btn { - width: 35px; - height: 35px; - font-size: 0.7rem; + width: 80%; + height: 25px; + font-size: 0.5rem; + position: relative; + left:200px; + top: -20px; } + } @media (max-width: 768px) { - .calendar-grid { - grid-template-columns: repeat(2, 1fr); /* 2 columns for small screens */ + .date .add-task-btn { + opacity: 1; + visibility: visible; + transform: none; + width: 35px; + height: 35px; + top: 5px; + right: 5px; + background-color: rgba(0, 0, 0, 0.7); } - - .day-name { - display: none; /* Hide day names to save space */ + + .dark-mode .date .add-task-btn { + background-color: var(--darktxt); + color: var(--darkbg); } - - .date { - min-height: 60px; /* Further reduce date cell height */ + /* Disable hover effects on mobile */ + +/* Restore hover effect */ +.date:hover .add-task-btn { + visibility: visible; + opacity: 1; + transform: scale(1.1); +} + .dark-mode .date .add-task-btn { + background-color: var(--darktxt); + color: var(--darkbg); } - - .date .add-task-btn { - width: 30px; - height: 30px; - font-size: 0.6rem; + + .dark-mode .calendar-grid { + box-shadow: none; } -} - -@media (max-width: 480px) { - .calendar-grid { - grid-template-columns: repeat(1, 1fr); /* 1 column for very small screens */ } - .date { - min-height: 50px; /* Minimized date cell height */ + /* Mobile Navigation Fixes */ +@media (max-width: 576px) { + #todayButton { + display: none; } - - .date .add-task-btn { - width: 25px; - height: 25px; - font-size: 0.5rem; + + .hamburger-menu { + position: relative; } + + .dropdown-menu { + right: 0; + left: auto; + } + + /* @media (hover: hover) and (pointer: fine) { + .date .add-task-btn { + opacity: 0; + visibility: hidden; + } + + .date:hover .add-task-btn { + visibility: visible; + opacity: 1; + transform: scale(1.1); + } + } */ + + } +