diff --git a/Savings-Plannar/analysis.css b/Savings-Plannar/analysis.css new file mode 100644 index 0000000..8bb108b --- /dev/null +++ b/Savings-Plannar/analysis.css @@ -0,0 +1,185 @@ +body { + font-family: 'Poppins', sans-serif; + background-color: #f4f4f4; + color: #333; + margin: 0; + padding: 0; + min-height: 100vh; /* Ensure the body covers the full viewport height */ + display: flex; + justify-content: center; + align-items: flex-start; /* Align items at the start to avoid hiding */ + overflow-x: hidden; +} + +.analysis-container { + width: 95%; + max-width: 1200px; + margin: 20px auto; + padding: 20px; + background-color: white; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + position: relative; +} + +.header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 20px; +} + +h1 { + flex-grow: 1; + text-align: center; + margin-bottom: 30px; + font-size: 2rem; + color: #007bff; +} + +#back-button { + margin-right: 20px; + padding: 10px 20px; + font-size: 16px; + cursor: pointer; + border: none; + border-radius: 5px; + background-color: #6c757d; + color: white; + text-decoration: none; + transition: background-color 0.3s ease; +} + +#back-button:hover { + background-color: #5a6268; +} + +.chart-row { + display: flex; + justify-content: space-around; + flex-wrap: wrap; + margin-bottom: 40px; +} + +.chart-item { + flex: 1 1 45%; + max-width: 45%; + margin-bottom: 30px; + position: relative; + min-width: 300px; +} + +.chart-item canvas { + width: 100%; + height: auto; + max-height: 300px; +} + +.chart-legend { + margin-top: 10px; + text-align: center; + font-size: 0.9rem; + color: #555; +} + +#download-pdf { + position: fixed; /* Fix position to ensure it's always visible */ + bottom: 20px; + right: 20px; + margin: 10px; + padding: 10px 20px; + font-size: 16px; + cursor: pointer; + border: none; + border-radius: 5px; + background-color: #007bff; + color: white; + text-align: center; + text-decoration: none; + transition: background-color 0.3s ease; +} + +#download-pdf:hover { + background-color: #0056b3; +} + +.data-table { + margin-top: 40px; + padding: 10px; + background-color: #f9f9f9; + border-radius: 5px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +.data-table h2 { + text-align: center; + margin-bottom: 20px; + font-size: 1.5rem; + color: #007bff; +} + +#savings-data-table { + width: 100%; + border-collapse: collapse; + margin: 0 auto; + font-size: 1rem; +} + +#savings-data-table th, +#savings-data-table td { + padding: 10px; + border: 1px solid #ddd; + text-align: center; +} + +#savings-data-table th { + background-color: #f4f4f4; + font-weight: bold; +} + +/* General table styling */ +.savings-table { + width: 100%; + border-collapse: collapse; + margin: 20px 0; + font-size: 16px; + text-align: left; + background-color: #f9f9f9; +} + +.savings-table thead tr { + background-color: #007bff; + /* color: white; */ + text-align: left; +} + +.savings-table th, .savings-table td { + padding: 12px 15px; + border: 1px solid #ddd; + text-align: center; /* Center-align text in cells */ +} + +.savings-table tbody tr:nth-child(even) { + background-color: #f2f2f2; +} + +.savings-table tbody tr:hover { + background-color: #e9ecef; +} + +.savings-table th { + font-weight: bold; +} + +.savings-table td { + font-family: 'Poppins', sans-serif; +} + +.savings-table .year-column { + font-weight: bold; +} + +.savings-table .total-column { + font-weight: bold; + background-color: #e9ecef; +} \ No newline at end of file diff --git a/Savings-Plannar/analysis.html b/Savings-Plannar/analysis.html new file mode 100644 index 0000000..2f39268 --- /dev/null +++ b/Savings-Plannar/analysis.html @@ -0,0 +1,73 @@ + + + + + + Analyze My Savings + + + + + + + + +

Due to large table columns and calendar This website only supports Desktop View

+
+ +

My Savings Analysis

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+

Data Analysis Summary

+ + + + + + + + + + + + + + + + + + + + + + +
YearJanFebMarAprMayJunJulAugSepOctNovDecTotal Saving (Yearly)
+
+ + +
+ + + diff --git a/Savings-Plannar/analysis.js b/Savings-Plannar/analysis.js new file mode 100644 index 0000000..52ef864 --- /dev/null +++ b/Savings-Plannar/analysis.js @@ -0,0 +1,278 @@ +document.addEventListener('DOMContentLoaded', () => { + const savings = JSON.parse(localStorage.getItem('savings')) || {}; + const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + + if (Object.keys(savings).length === 0) { + alert("No savings data available to analyze."); + return; + } + + const savingsData = processSavingsData(savings); + populateSavingsTable(savingsData); + + const monthlyPieCtx = document.getElementById('monthly-pie-chart').getContext('2d'); + const yearlyPieCtx = document.getElementById('yearly-pie-chart').getContext('2d'); + const barCtx = document.getElementById('savings-bar-chart').getContext('2d'); + const lineCtx = document.getElementById('savings-line-chart').getContext('2d'); + + new Chart(monthlyPieCtx, { + type: 'pie', + data: { + labels: Object.keys(savingsData.monthly).map(key => { + const [year, month] = key.split('-'); + return `${monthNames[month - 1]} ${year}`; + }), + datasets: [{ + data: Object.values(savingsData.monthly), + backgroundColor: generateColors(Object.keys(savingsData.monthly).length) + }] + }, + options: { + plugins: { + legend: { + display: true, + position: 'bottom', + labels: { + boxWidth: 20, + padding: 10 + } + }, + tooltip: { + callbacks: { + label: function(context) { + let label = context.label || ''; + if (label) { + label += ': '; + } + label += `Rs. ${context.raw}`; + return label; + } + } + }, + datalabels: { + color: '#fff', + font: { + weight: 'bold', + size: 14 + }, + formatter: (value, context) => { + return context.chart.data.labels[context.dataIndex].replace(' ', '\n') + `\nRs. ${value}`; + }, + align: 'center', + anchor: 'center' + } + } + } + }); + + new Chart(yearlyPieCtx, { + type: 'pie', + data: { + labels: Object.keys(savingsData.yearly), + datasets: [{ + data: Object.values(savingsData.yearly), + backgroundColor: generateColors(Object.keys(savingsData.yearly).length) + }] + }, + options: { + plugins: { + legend: { + display: true, + position: 'bottom', + labels: { + boxWidth: 20, + padding: 10 + } + }, + tooltip: { + callbacks: { + label: function(context) { + let label = context.label || ''; + if (label) { + label += ': '; + } + label += `Rs. ${context.raw}`; + return label; + } + } + }, + datalabels: { + color: '#fff', + font: { + weight: 'bold', + size: 14 + }, + formatter: (value, context) => { + const year = context.chart.data.labels[context.dataIndex]; + return `${year}\nRs. ${value}`; + }, + align: 'center', + anchor: 'center' + } + } + } + }); + + new Chart(barCtx, { + type: 'bar', + data: { + labels: Object.keys(savingsData.monthly).map(key => { + const [year, month] = key.split('-'); + return `${monthNames[month - 1]} ${year}`; + }), + datasets: [{ + label: 'Monthly Savings (Rs)', + data: Object.values(savingsData.monthly), + backgroundColor: 'rgba(54, 162, 235, 0.6)', + borderColor: 'rgba(54, 162, 235, 1)', + borderWidth: 1 + }] + }, + options: { + scales: { + y: { + beginAtZero: true, + ticks: { + callback: function(value) { + return 'Rs. ' + value; + } + } + } + } + } + }); + + new Chart(lineCtx, { + type: 'line', + data: { + labels: savingsData.dates, + datasets: [{ + label: 'Savings Over Time (Rs)', + data: savingsData.amounts, + backgroundColor: 'rgba(153, 102, 255, 0.6)', + borderColor: 'rgba(153, 102, 255, 1)', + fill: false, + borderWidth: 2 + }] + }, + options: { + scales: { + y: { + beginAtZero: true, + ticks: { + callback: function(value) { + return 'Rs. ' + value; + } + } + } + } + } + }); + + document.getElementById('download-pdf').addEventListener('click', () => { + const { jsPDF } = window.jspdf; + const doc = new jsPDF('p', 'mm', 'a4'); + + doc.text('My Savings Analysis', 10, 10); + + const barChartCanvas = document.getElementById('savings-bar-chart'); + const pieChartCanvas1 = document.getElementById('monthly-pie-chart'); + const pieChartCanvas2 = document.getElementById('yearly-pie-chart'); + const lineChartCanvas = document.getElementById('savings-line-chart'); + const tableElement = document.querySelector('.data-table'); // Capture the data table element + + const imgWidth = 85; + const imgHeight = 55; + const margin = 10; + const initialY = 20; + + doc.addImage(pieChartCanvas1.toDataURL('image/png'), 'PNG', 10, initialY, imgWidth, imgHeight); + doc.addImage(pieChartCanvas2.toDataURL('image/png'), 'PNG', 105, initialY, imgWidth, imgHeight); + + doc.addImage(barChartCanvas.toDataURL('image/png'), 'PNG', 10, initialY + imgHeight + margin, imgWidth * 2 + margin, imgHeight); + + doc.addImage(lineChartCanvas.toDataURL('image/png'), 'PNG', 10, initialY + imgHeight * 2 + margin * 2, imgWidth * 2 + margin, imgHeight); + + // Capture the table and add to the PDF + html2canvas(tableElement).then(canvas => { + const tableImgData = canvas.toDataURL('image/png'); + doc.addPage(); + doc.addImage(tableImgData, 'PNG', 10, 10, 190, 0); // Adjust the width and let height scale automatically + doc.save('my_savings_analysis.pdf'); + }); + }); + + document.getElementById('back-button').addEventListener('click', () => { + window.location.href = 'index.html'; + }); + + function processSavingsData(savings) { + const yearlySavings = {}; + const monthlySavings = {}; + + for (const date in savings) { + const [year, month, day] = date.split('-').map(Number); + const amount = parseFloat(savings[date]); + + const yearKey = year; + const monthKey = `${year}-${month}`; + + if (!yearlySavings[yearKey]) { + yearlySavings[yearKey] = 0; + } + if (!monthlySavings[monthKey]) { + monthlySavings[monthKey] = 0; + } + + yearlySavings[yearKey] += amount; + monthlySavings[monthKey] += amount; + } + + return { + yearly: yearlySavings, + monthly: monthlySavings, + dates: Object.keys(savings), + amounts: Object.values(savings).map(parseFloat) + }; + } + + function populateSavingsTable(savingsData) { + const dataTableBody = document.querySelector("#savings-data-table tbody"); + + Object.keys(savingsData.yearly).forEach(year => { + const row = document.createElement("tr"); + + const yearCell = document.createElement("td"); + yearCell.textContent = year; + row.appendChild(yearCell); + + let yearlyTotal = 0; + for (let month = 1; month <= 12; month++) { + const monthKey = `${year}-${month}`; + const monthCell = document.createElement("td"); + + if (savingsData.monthly[monthKey]) { + monthCell.textContent = `Rs. ${savingsData.monthly[monthKey]}`; + yearlyTotal += savingsData.monthly[monthKey]; + } else { + monthCell.textContent = ''; + } + row.appendChild(monthCell); + } + + const totalCell = document.createElement("td"); + totalCell.textContent = `Rs. ${yearlyTotal}`; + row.appendChild(totalCell); + + dataTableBody.appendChild(row); + }); + } + + function generateColors(length) { + const colors = []; + for (let i = 0; i < length; i++) { + colors.push(`hsl(${i * (360 / length)}, 70%, 60%)`); + } + return colors; + } +}); diff --git a/Savings-Plannar/index.html b/Savings-Plannar/index.html new file mode 100644 index 0000000..595e1cb --- /dev/null +++ b/Savings-Plannar/index.html @@ -0,0 +1,72 @@ + + + + + + + Savings Planner + + + + + +

Due to large table columns and calendar This website only supports Desktop View

+
+
+
+ + August 2024 + +
+
+ + + + +
+
+
+
+
Sun
+
Mon
+
Tue
+
Wed
+
Thu
+
Fri
+
Sat
+
+
+ +
+
+
+ + + + + + + + + + diff --git a/Savings-Plannar/script.js b/Savings-Plannar/script.js new file mode 100644 index 0000000..4209cdb --- /dev/null +++ b/Savings-Plannar/script.js @@ -0,0 +1,366 @@ +document.addEventListener('DOMContentLoaded', () => { + const currentMonth = document.getElementById('current-month'); + const calendarGrid = document.getElementById('calendar-grid'); + const viewSelect = document.getElementById('view-select'); + const prevButton = document.getElementById('prev-month'); + const nextButton = document.getElementById('next-month'); + const datePickerButton = document.getElementById('date-picker-button'); // Date Picker Button + const datePicker = document.getElementById('date-picker'); // Hidden Date Input + const clearDateButton = document.createElement('button'); // Clear Date Button + const deleteAmountButton = document.getElementById('delete-amount'); // Reference to the delete button + document.getElementById('saving-modal').style.display = 'none'; + const today = new Date(); + + let displayedMonth = today.getMonth(); + let displayedYear = today.getFullYear(); + let displayedDay = today.getDate(); + let savings = JSON.parse(localStorage.getItem('savings')) || {}; // Store savings in local storage + + // Add "Clear Date" button + clearDateButton.style.display = "none"; + clearDateButton.id = 'clear-date-button'; + clearDateButton.innerHTML = ''; + clearDateButton.style.marginRight = '10px'; + clearDateButton.style.padding = '5px 10px'; + clearDateButton.style.fontSize = '16px'; + clearDateButton.style.cursor = 'pointer'; + clearDateButton.style.backgroundColor = '#dc3545'; + clearDateButton.style.color = 'white'; + clearDateButton.style.border = 'none'; + clearDateButton.style.borderRadius = '5px'; + + // Append the clear date button to the view selector + datePickerButton.after(clearDateButton); + + const renderCalendar = (view) => { + calendarGrid.innerHTML = ''; + + switch (view) { + case 'day': + currentMonth.textContent = new Date(displayedYear, displayedMonth, displayedDay).toLocaleDateString('en-US', { day: 'numeric', month: 'long', year: 'numeric' }); + showDayView(); + break; + case 'week': + const firstDayOfWeek = new Date(displayedYear, displayedMonth, displayedDay - (today.getDay() - 1)); + currentMonth.textContent = `Week of ${firstDayOfWeek.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })}`; + showWeekView(); + break; + case 'year': + currentMonth.textContent = `${displayedYear}`; + showYearView(); + break; + default: + currentMonth.textContent = new Date(displayedYear, displayedMonth).toLocaleDateString('en-US', { month: 'long', year: 'numeric' }); + showMonthView(); + break; + } + }; + + const showDayView = () => { + const dayCell = document.createElement('div'); + const dayOfWeek = new Date(displayedYear, displayedMonth, displayedDay).getDay(); + dayCell.textContent = displayedDay; + dayCell.style.gridColumnStart = dayOfWeek + 1; + dayCell.classList.add('current-day'); + appendSaving(dayCell, displayedYear, displayedMonth, displayedDay); + dayCell.addEventListener('click', () => { + openSavingModal(displayedDay); + }); + calendarGrid.appendChild(dayCell); + }; + + const showWeekView = () => { + const startOfWeek = new Date(displayedYear, displayedMonth, displayedDay); + startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay()); // Move to the previous Sunday + + const weekDates = []; + for (let i = 0; i < 7; i++) { + weekDates.push(new Date(startOfWeek)); + startOfWeek.setDate(startOfWeek.getDate() + 1); + } + + weekDates.forEach((date, index) => { + const dayCell = document.createElement('div'); + dayCell.textContent = date.getDate(); + + if (date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear()) { + dayCell.classList.add('current-day'); + } + + appendSaving(dayCell, date.getFullYear(), date.getMonth(), date.getDate()); + + // Ensure the day appears under the correct column + dayCell.style.gridColumnStart = index + 1; + + dayCell.addEventListener('click', () => { + openSavingModal(date.getDate(), date.getMonth()); + }); + calendarGrid.appendChild(dayCell); + }); + + // Update header to show the week date range + const firstDay = weekDates[0]; + const lastDay = weekDates[6]; + currentMonth.textContent = `Week of ${firstDay.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })}`; + }; + + const showMonthView = () => { + const daysInMonth = new Date(displayedYear, displayedMonth + 1, 0).getDate(); + const startDay = new Date(displayedYear, displayedMonth, 1).getDay(); + + for (let i = 0; i < startDay; i++) { + const emptyCell = document.createElement('div'); + calendarGrid.appendChild(emptyCell); + } + + for (let day = 1; day <= daysInMonth; day++) { + const dayCell = document.createElement('div'); + dayCell.textContent = day; + + if (day === today.getDate() && displayedMonth === today.getMonth() && displayedYear === today.getFullYear()) { + dayCell.classList.add('current-day'); + } + + appendSaving(dayCell, displayedYear, displayedMonth, day); + + dayCell.addEventListener('click', () => { + openSavingModal(day); + }); + + calendarGrid.appendChild(dayCell); + } + }; + + const showYearView = () => { + for (let month = 0; month < 12; month++) { + const monthLabel = document.createElement('div'); + monthLabel.textContent = new Date(displayedYear, month).toLocaleDateString('en-US', { month: 'short' }); + monthLabel.style.gridColumn = `span 7`; // span across the entire row + calendarGrid.appendChild(monthLabel); + + const daysInMonth = new Date(displayedYear, month + 1, 0).getDate(); + const startDay = new Date(displayedYear, month, 1).getDay(); + + for (let i = 0; i < startDay; i++) { + const emptyCell = document.createElement('div'); + calendarGrid.appendChild(emptyCell); + } + + for (let day = 1; day <= daysInMonth; day++) { + const dayCell = document.createElement('div'); + dayCell.textContent = day; + + if (day === today.getDate() && month === today.getMonth() && displayedYear === today.getFullYear()) { + dayCell.classList.add('current-day'); + } + + appendSaving(dayCell, displayedYear, month, day); + + dayCell.addEventListener('click', () => { + openSavingModal(day, month); + }); + + calendarGrid.appendChild(dayCell); + } + } + }; + + const appendSaving = (dayCell, year, month, day) => { + const savingKey = `${year}-${month + 1}-${day}`; + if (savings[savingKey]) { + const savingElem = document.createElement('div'); + savingElem.textContent = `Rs. ${savings[savingKey]}`; + savingElem.classList.add('saving'); + savingElem.addEventListener('click', (e) => { + e.stopPropagation(); // Prevents the modal from opening when clicking on the saving amount + alert(`Saving: Rs. ${savings[savingKey]}`); + }); + dayCell.appendChild(savingElem); + } + }; + + const openSavingModal = (day, month = displayedMonth) => { + const savingModal = document.getElementById('saving-modal'); + const savingDateInput = document.getElementById('saving-date'); + const savingAmountInput = document.getElementById('saving-amount'); + + const savingDate = new Date(displayedYear, month, day).toLocaleDateString('en-US'); + savingDateInput.value = savingDate; + + const savingKey = `${displayedYear}-${month + 1}-${day}`; + + if (savings[savingKey]) { + savingAmountInput.value = savings[savingKey]; + deleteAmountButton.style.display = 'inline-block'; // Show the delete button if there's an amount saved + } else { + savingAmountInput.value = ''; + deleteAmountButton.style.display = 'none'; // Hide the delete button if no amount is saved + } + + // Show the modal + savingModal.style.display = 'flex'; + }; + + deleteAmountButton.addEventListener('click', () => { + const savingDate = document.getElementById('saving-date').value; + const [month, day, year] = savingDate.split('/').map(Number); + const savingKey = `${year}-${month}-${day}`; + + if (savings[savingKey]) { + delete savings[savingKey]; // Remove the amount from the savings object + localStorage.setItem('savings', JSON.stringify(savings)); // Update local storage + renderCalendar(viewSelect.value); // Re-render the calendar to update the view + closeSavingModal(); // Close the modal after deletion + } + }); + + const closeSavingModal = () => { + document.getElementById('saving-modal').style.display = 'none'; + }; + + // Additional functionality: close modal if clicking outside of it + window.addEventListener('click', (event) => { + const savingModal = document.getElementById('saving-modal'); + if (event.target === savingModal) { + closeSavingModal(); + } + }); + + document.getElementById('close-modal').addEventListener('click', closeSavingModal); + + document.getElementById('saving-form').addEventListener('submit', (e) => { + e.preventDefault(); + const savingDate = document.getElementById('saving-date').value; + const savingAmount = document.getElementById('saving-amount').value; + + const [month, day, year] = savingDate.split('/').map(Number); + const savingKey = `${year}-${month}-${day}`; + + savings[savingKey] = savingAmount; + localStorage.setItem('savings', JSON.stringify(savings)); + + closeSavingModal(); + renderCalendar(viewSelect.value); + }); + + document.getElementById('analyze-button').addEventListener('click', () => { + window.location.href = 'analysis.html'; + }); + + prevButton.addEventListener('click', () => { + switch (viewSelect.value) { + case 'day': + displayedDay--; + if (displayedDay < 1) { + displayedMonth--; + if (displayedMonth < 0) { + displayedMonth = 11; + displayedYear--; + } + displayedDay = new Date(displayedYear, displayedMonth + 1, 0).getDate(); + } + break; + case 'week': + displayedDay -= 7; + if (displayedDay < 1) { + displayedMonth--; + if (displayedMonth < 0) { + displayedMonth = 11; + displayedYear--; + } + const daysInPrevMonth = new Date(displayedYear, displayedMonth + 1, 0).getDate(); + displayedDay = daysInPrevMonth + displayedDay; + } + break; + case 'year': + displayedYear--; + break; + default: + displayedMonth--; + if (displayedMonth < 0) { + displayedMonth = 11; + displayedYear--; + } + break; + } + renderCalendar(viewSelect.value); + }); + + nextButton.addEventListener('click', () => { + switch (viewSelect.value) { + case 'day': + displayedDay++; + const daysInCurrentMonth = new Date(displayedYear, displayedMonth + 1, 0).getDate(); + if (displayedDay > daysInCurrentMonth) { + displayedDay = 1; + displayedMonth++; + if (displayedMonth > 11) { + displayedMonth = 0; + displayedYear++; + } + } + break; + case 'week': + displayedDay += 7; + const daysInCurrentWeekMonth = new Date(displayedYear, displayedMonth + 1, 0).getDate(); + if (displayedDay > daysInCurrentWeekMonth) { + displayedDay -= daysInCurrentWeekMonth; + displayedMonth++; + if (displayedMonth > 11) { + displayedMonth = 0; + displayedYear++; + } + } + break; + case 'year': + displayedYear++; + break; + default: + displayedMonth++; + if (displayedMonth > 11) { + displayedMonth = 0; + displayedYear++; + } + break; + } + renderCalendar(viewSelect.value); + }); + + viewSelect.addEventListener('change', () => { + renderCalendar(viewSelect.value); + }); + + datePickerButton.addEventListener('click', () => { + datePicker.style.display = "block"; + datePicker.click(); + }); + + datePicker.addEventListener('change', (e) => { + const selectedDate = new Date(e.target.value); + displayedDay = selectedDate.getDate(); + displayedMonth = selectedDate.getMonth(); + displayedYear = selectedDate.getFullYear(); + datePicker.style.display = "none"; // Hide the date picker after selecting a date + + // Show the clear date button after a date is selected + clearDateButton.style.display = "inline-block"; + + renderCalendar(viewSelect.value); + }); + + clearDateButton.addEventListener('click', () => { + displayedDay = today.getDate(); + displayedMonth = today.getMonth(); + displayedYear = today.getFullYear(); + datePicker.style.display = "none"; // Hide the date picker when clearing the date + + // Hide the clear date button when the date is cleared + clearDateButton.style.display = "none"; + + renderCalendar(viewSelect.value); + }); + + renderCalendar(viewSelect.value); +}); + + diff --git a/Savings-Plannar/ss1.png b/Savings-Plannar/ss1.png new file mode 100644 index 0000000..533c28a Binary files /dev/null and b/Savings-Plannar/ss1.png differ diff --git a/Savings-Plannar/ss10.png b/Savings-Plannar/ss10.png new file mode 100644 index 0000000..fdc59c7 Binary files /dev/null and b/Savings-Plannar/ss10.png differ diff --git a/Savings-Plannar/ss11.png b/Savings-Plannar/ss11.png new file mode 100644 index 0000000..e10f915 Binary files /dev/null and b/Savings-Plannar/ss11.png differ diff --git a/Savings-Plannar/ss2.png b/Savings-Plannar/ss2.png new file mode 100644 index 0000000..8d42461 Binary files /dev/null and b/Savings-Plannar/ss2.png differ diff --git a/Savings-Plannar/ss3.png b/Savings-Plannar/ss3.png new file mode 100644 index 0000000..c30c217 Binary files /dev/null and b/Savings-Plannar/ss3.png differ diff --git a/Savings-Plannar/ss4.png b/Savings-Plannar/ss4.png new file mode 100644 index 0000000..f044c1d Binary files /dev/null and b/Savings-Plannar/ss4.png differ diff --git a/Savings-Plannar/ss5.png b/Savings-Plannar/ss5.png new file mode 100644 index 0000000..4b5b5e0 Binary files /dev/null and b/Savings-Plannar/ss5.png differ diff --git a/Savings-Plannar/ss6.png b/Savings-Plannar/ss6.png new file mode 100644 index 0000000..8e98a6d Binary files /dev/null and b/Savings-Plannar/ss6.png differ diff --git a/Savings-Plannar/ss7.png b/Savings-Plannar/ss7.png new file mode 100644 index 0000000..cd0f5e5 Binary files /dev/null and b/Savings-Plannar/ss7.png differ diff --git a/Savings-Plannar/ss8.png b/Savings-Plannar/ss8.png new file mode 100644 index 0000000..6988438 Binary files /dev/null and b/Savings-Plannar/ss8.png differ diff --git a/Savings-Plannar/ss9.png b/Savings-Plannar/ss9.png new file mode 100644 index 0000000..49b58b4 Binary files /dev/null and b/Savings-Plannar/ss9.png differ diff --git a/Savings-Plannar/styles.css b/Savings-Plannar/styles.css new file mode 100644 index 0000000..0b233ad --- /dev/null +++ b/Savings-Plannar/styles.css @@ -0,0 +1,282 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); + +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: "Poppins", sans-serif; +} + +body { + height: 100vh; + width: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.calendar-container { + width: 95%; + height: 90vh; + margin: 0 auto; + display: flex; + flex-direction: column; + border: 1px solid #ccc; + border-radius: 5px; + overflow: hidden; +} + +.calendar-header { + display: flex; + justify-content: space-between; + padding: 10px; + background-color: #f0f0f0; + border-bottom: 1px solid #ccc; +} + +.month-navigation { + display: flex; + align-items: center; +} + +.month-navigation button { + background: none; + border: none; + font-size: 18px; + cursor: pointer; + margin: 0 10px; +} + +#current-month { + font-size: 18px; + font-weight: bold; +} + +.view-selector { + display: flex; + align-items: center; +} + +.view-selector select { + padding: 5px; + font-size: 16px; + border: none; + outline: none; + color: #969696; + cursor: pointer; +} + +#date-picker-button { + margin-right: 10px; + padding: 5px 10px; + font-size: 16px; + cursor: pointer; + background-color: #28a745; + color: white; + border: none; + border-radius: 5px; +} + +#date-picker-button:hover { + background-color: #218838; +} + +.view-selector select { + padding: 5px; + font-size: 16px; +} + +.calendar-body { + flex: 1; + display: flex; + flex-direction: column; + overflow-y: auto; +} + +.days-header { + display: grid; + grid-template-columns: repeat(7, 1fr); + background-color: #e0e0e0; + padding: 10px 0; + font-weight: bold; + text-align: center; +} + +.days-grid { + display: grid; + grid-template-columns: repeat(7, 1fr); + grid-auto-rows: 1fr; + flex: 1; + overflow-y: auto; +} + +.days-grid div { + padding: 20px; + text-align: right; + border: 1px solid #ccc; + cursor: pointer; + position: relative; +} + +.days-grid .current-day { + background-color: lightblue; +} + +.days-grid .saving { + position: absolute; + bottom: 0; + left: 0; + background-color: green; + color: white; + padding: 2px 4px; + font-size: 12px; + border-radius: 3px; + cursor: pointer; +} + +.modal { + display: none; /* Hidden by default */ + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgba(0, 0, 0, 0.4); + display: flex; + justify-content: center; + align-items: center; +} + +.modal-content { + background-color: #fefefe; + margin: auto; + padding: 20px; + border: 1px solid #888; + width: 80%; + max-width: 500px; + border-radius: 10px; + position: relative; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); + animation-name: modalopen; + animation-duration: 0.4s; +} + +.close-btn { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; + position: absolute; + right: 20px; + top: 10px; + cursor: pointer; + transition: color 0.3s ease; +} + +.close-btn:hover, +.close-btn:focus { + color: #000; + text-decoration: none; + cursor: pointer; +} + +/* Form Styles */ +#saving-form { + display: flex; + flex-direction: column; +} + +#saving-form label { + margin-top: 10px; + font-weight: bold; +} + +#saving-form input { + margin-top: 5px; + padding: 8px; + font-size: 16px; + border-radius: 5px; + border: 1px solid #ccc; + outline: none; + width: 100%; +} + +#saving-form button { + margin-top: 15px; + padding: 10px 15px; + font-size: 16px; + border: none; + border-radius: 5px; + background-color: #28a745; + color: white; + cursor: pointer; + transition: background-color 0.3s ease; +} + +#saving-form button:hover { + background-color: #218838; +} + +/* Animation for Modal Open */ +@keyframes modalopen { + from { + opacity: 0; + transform: translateY(-50px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +#date-picker{ + display: block; + padding: 6px 8px; + margin-right: 8px; + border-radius: 3px; + border: none; + outline: none; + cursor: pointer; + background: #ddd; +} + +#analyze-button{ + padding: 7px 9px; + border: none; + outline: none; + margin-right: 8px; + background: #cecece; + border-radius: 4px; + cursor: pointer; +} + +/* Responsive adjustments for smaller screens */ +@media (max-width: 768px) { + .days-header, .days-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 480px) { + .days-header, .days-grid { + grid-template-columns: 1fr; + } +} + +#view{ + display: none; +} + +@media screen and (max-width:870px) { + .calendar-container, .analysis-container{ + display: none; + } + #view{ + display: block; + text-align: center; + font-size: 20px; + transform: translateY(50px); + } +} \ No newline at end of file