{"id":2604,"date":"2026-01-24T19:57:23","date_gmt":"2026-01-24T19:57:23","guid":{"rendered":"https:\/\/malikskitchen.in\/?page_id=2604"},"modified":"2026-01-28T10:10:44","modified_gmt":"2026-01-28T10:10:44","slug":"elementor-2604","status":"publish","type":"page","link":"https:\/\/malikskitchen.in\/index.php\/elementor-2604\/","title":{"rendered":"Task manager"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2604\" class=\"elementor elementor-2604\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9ea9bda e-flex e-con-boxed e-con e-parent\" data-id=\"9ea9bda\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f789b76 elementor-widget elementor-widget-html\" data-id=\"f789b76\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"hi\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\r\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\r\n    <meta name=\"mobile-web-app-capable\" content=\"yes\">\r\n    <title>Task Manager App<\/title>\r\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\r\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/Sortable\/1.15.0\/Sortable.min.js\"><\/script>\r\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jspdf\/2.5.1\/jspdf.umd.min.js\"><\/script>\r\n    <style>\r\n        * {\r\n            -webkit-tap-highlight-color: transparent;\r\n            box-sizing: border-box;\r\n        }\r\n        body {\r\n            touch-action: pan-y;\r\n            overscroll-behavior: contain;\r\n            transition: background-color 0.3s;\r\n            margin: 0;\r\n            padding: 0;\r\n        }\r\n        .light-mode {\r\n            background: #f3f4f6;\r\n        }\r\n        .dark-mode {\r\n            background: #1f2937;\r\n        }\r\n        .ghost {\r\n            opacity: 0.4;\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body class=\"light-mode min-h-screen\">\r\n    <div id=\"app\" class=\"p-3 pb-20\"><\/div>\r\n\r\n    <script>\r\n        const { jsPDF } = window.jspdf;\r\n\r\n        let tasks = JSON.parse(localStorage.getItem('taskManagerTasks') || '[]');\r\n        let filterPerson = '';\r\n        let showCompleted = true;\r\n        let darkMode = JSON.parse(localStorage.getItem('darkMode') || 'false');\r\n        let searchQuery = '';\r\n\r\n        document.body.className = darkMode ? 'dark-mode min-h-screen' : 'light-mode min-h-screen';\r\n\r\n        function saveTasks() {\r\n            localStorage.setItem('taskManagerTasks', JSON.stringify(tasks));\r\n            render();\r\n        }\r\n\r\n        function toggleDarkMode() {\r\n            darkMode = !darkMode;\r\n            localStorage.setItem('darkMode', JSON.stringify(darkMode));\r\n            document.body.className = darkMode ? 'dark-mode min-h-screen' : 'light-mode min-h-screen';\r\n            render();\r\n        }\r\n\r\n        function checkReminders() {\r\n            const now = new Date();\r\n            tasks.forEach(task => {\r\n                if (!task.completed && task.dueDate && !task.reminded) {\r\n                    const dueDate = new Date(task.dueDate);\r\n                    const hoursUntilDue = (dueDate - now) \/ (1000 * 60 * 60);\r\n                    \r\n                    if (hoursUntilDue <= 24 && hoursUntilDue > 0) {\r\n                        task.reminded = true;\r\n                        if (Notification.permission === 'granted') {\r\n                            new Notification('Task Reminder!', {\r\n                                body: `\"${task.text}\" is due soon!`\r\n                            });\r\n                        }\r\n                    }\r\n                }\r\n            });\r\n            saveTasks();\r\n        }\r\n\r\n        if ('Notification' in window && Notification.permission === 'default') {\r\n            Notification.requestPermission();\r\n        }\r\n\r\n        function addTask() {\r\n            const taskInput = document.getElementById('taskInput');\r\n            const assignInput = document.getElementById('assignInput');\r\n            const dueDateInput = document.getElementById('dueDateInput');\r\n            const priorityInput = document.getElementById('priorityInput');\r\n\r\n            if (taskInput.value.trim()) {\r\n                tasks.unshift({\r\n                    id: Date.now(),\r\n                    text: taskInput.value.trim(),\r\n                    assignedTo: assignInput.value.trim(),\r\n                    dueDate: dueDateInput.value,\r\n                    priority: priorityInput.value,\r\n                    completed: false,\r\n                    completedAt: null,\r\n                    reminded: false,\r\n                    createdAt: new Date().toISOString()\r\n                });\r\n\r\n                taskInput.value = '';\r\n                assignInput.value = '';\r\n                dueDateInput.value = '';\r\n                priorityInput.value = 'medium';\r\n                saveTasks();\r\n            }\r\n        }\r\n\r\n        function toggleTask(id) {\r\n            tasks = tasks.map(task => \r\n                task.id === id \r\n                    ? { ...task, completed: !task.completed, completedAt: !task.completed ? new Date().toISOString() : null }\r\n                    : task\r\n            );\r\n            saveTasks();\r\n        }\r\n\r\n        function deleteTask(id) {\r\n            if (confirm('Delete this task?')) {\r\n                tasks = tasks.filter(task => task.id !== id);\r\n                saveTasks();\r\n            }\r\n        }\r\n\r\n        function shareOnWhatsApp() {\r\n            const taskList = filterTasks(tasks);\r\n            \r\n            if (taskList.length === 0) {\r\n                alert('No tasks to share!');\r\n                return;\r\n            }\r\n\r\n            let message = 'My Tasks\\n\\n';\r\n            \r\n            taskList.forEach((task, index) => {\r\n                const status = task.completed ? 'Done' : 'Pending';\r\n                const priority = `[${task.priority.toUpperCase()}]`;\r\n                message += `${index + 1}. ${priority} [${status}] ${task.text}`;\r\n                if (task.assignedTo) message += ` (${task.assignedTo})`;\r\n                if (task.dueDate) message += ` - Due: ${new Date(task.dueDate).toLocaleDateString()}`;\r\n                message += '\\n';\r\n            });\r\n\r\n            window.open('https:\/\/wa.me\/?text=' + encodeURIComponent(message), '_blank');\r\n        }\r\n\r\n        function exportToPDF() {\r\n            const taskList = filterTasks(tasks);\r\n            \r\n            if (taskList.length === 0) {\r\n                alert('No tasks to export!');\r\n                return;\r\n            }\r\n\r\n            const doc = new jsPDF();\r\n            doc.setFontSize(18);\r\n            doc.text('My Tasks', 20, 20);\r\n            doc.setFontSize(10);\r\n            doc.text('Generated: ' + new Date().toLocaleString(), 20, 30);\r\n            \r\n            let yPos = 45;\r\n            taskList.forEach((task, index) => {\r\n                if (yPos > 270) {\r\n                    doc.addPage();\r\n                    yPos = 20;\r\n                }\r\n                \r\n                const status = task.completed ? '[Done]' : '[Pending]';\r\n                const priority = `[${task.priority.toUpperCase()}]`;\r\n                let line = `${index + 1}. ${priority} ${status} ${task.text}`;\r\n                \r\n                if (task.assignedTo) line += ` (${task.assignedTo})`;\r\n                if (task.dueDate) line += ` - Due: ${new Date(task.dueDate).toLocaleDateString()}`;\r\n                \r\n                doc.text(line, 20, yPos);\r\n                yPos += 10;\r\n            });\r\n            \r\n            doc.save(`Tasks_${Date.now()}.pdf`);\r\n        }\r\n\r\n        function filterTasks(taskList) {\r\n            let filtered = taskList;\r\n            \r\n            if (filterPerson) {\r\n                filtered = filtered.filter(t => t.assignedTo === filterPerson);\r\n            }\r\n            \r\n            if (!showCompleted) {\r\n                filtered = filtered.filter(t => !t.completed);\r\n            }\r\n\r\n            if (searchQuery) {\r\n                filtered = filtered.filter(t => \r\n                    t.text.toLowerCase().includes(searchQuery.toLowerCase()) ||\r\n                    (t.assignedTo && t.assignedTo.toLowerCase().includes(searchQuery.toLowerCase()))\r\n                );\r\n            }\r\n            \r\n            return filtered;\r\n        }\r\n\r\n        function getUniquePersons() {\r\n            return [...new Set(tasks.map(t => t.assignedTo).filter(Boolean))];\r\n        }\r\n\r\n        function getPriorityColor(priority) {\r\n            switch(priority) {\r\n                case 'high': return '#ef4444';\r\n                case 'medium': return '#f59e0b';\r\n                case 'low': return '#10b981';\r\n                default: return '#6b7280';\r\n            }\r\n        }\r\n\r\n        function isOverdue(task) {\r\n            if (!task.dueDate || task.completed) return false;\r\n            return new Date(task.dueDate) < new Date();\r\n        }\r\n\r\n        function render() {\r\n            const filteredTasks = filterTasks(tasks);\r\n            const uniquePersons = getUniquePersons();\r\n\r\n            const bgCard = darkMode ? 'bg-gray-800' : 'bg-white';\r\n            const textColor = darkMode ? 'text-white' : 'text-gray-900';\r\n            const textMuted = darkMode ? 'text-gray-400' : 'text-gray-600';\r\n            const borderColor = darkMode ? 'border-gray-700' : 'border-gray-300';\r\n            const inputBg = darkMode ? 'bg-gray-700 text-white' : 'bg-white';\r\n\r\n            const completedCount = filteredTasks.filter(t => t.completed).length;\r\n\r\n            const app = document.getElementById('app');\r\n            app.innerHTML = `\r\n                <!-- Header -->\r\n                <div class=\"${bgCard} rounded-xl shadow-md p-4 mb-3\">\r\n                    <div class=\"flex justify-between items-center mb-4\">\r\n                        <h1 class=\"text-xl font-bold ${textColor}\">Task Manager<\/h1>\r\n                        <button \r\n                            onclick=\"toggleDarkMode()\"\r\n                            class=\"px-3 py-1.5 text-xs ${darkMode ? 'bg-yellow-400 text-gray-900' : 'bg-gray-900 text-white'} rounded-lg font-medium\"\r\n                        >\r\n                            ${darkMode ? '\u2600 Light' : '\ud83c\udf19 Dark'}\r\n                        <\/button>\r\n                    <\/div>\r\n\r\n                    <!-- Add Task -->\r\n                    <div class=\"space-y-2.5\">\r\n                        <input\r\n                            id=\"taskInput\"\r\n                            type=\"text\"\r\n                            placeholder=\"Add new task...\"\r\n                            onkeypress=\"if(event.key==='Enter') addTask()\"\r\n                            class=\"w-full px-3 py-2.5 text-sm border ${borderColor} ${inputBg} rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500\"\r\n                        \/>\r\n                        \r\n                        <div class=\"grid grid-cols-2 gap-2\">\r\n                            <input\r\n                                id=\"assignInput\"\r\n                                type=\"text\"\r\n                                placeholder=\"Assign to...\"\r\n                                class=\"px-3 py-2 text-sm border ${borderColor} ${inputBg} rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500\"\r\n                            \/>\r\n                            <input\r\n                                id=\"dueDateInput\"\r\n                                type=\"date\"\r\n                                class=\"px-3 py-2 text-sm border ${borderColor} ${inputBg} rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500\"\r\n                            \/>\r\n                        <\/div>\r\n\r\n                        <div class=\"grid grid-cols-2 gap-2\">\r\n                            <select\r\n                                id=\"priorityInput\"\r\n                                class=\"px-3 py-2 text-sm border ${borderColor} ${inputBg} rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500\"\r\n                            >\r\n                                <option value=\"low\">\ud83d\udfe2 Low<\/option>\r\n                                <option value=\"medium\" selected>\ud83d\udfe1 Medium<\/option>\r\n                                <option value=\"high\">\ud83d\udd34 High<\/option>\r\n                            <\/select>\r\n                            <button\r\n                                onclick=\"addTask()\"\r\n                                class=\"py-2 bg-gradient-to-r from-purple-500 to-blue-500 text-white rounded-lg font-medium text-sm active:scale-95 transition-transform\"\r\n                            >\r\n                                Add Task\r\n                            <\/button>\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <!-- Filters & Actions -->\r\n                <div class=\"${bgCard} rounded-xl shadow-md p-3 mb-3\">\r\n                    <div class=\"space-y-2.5\">\r\n                        <input\r\n                            type=\"text\"\r\n                            placeholder=\"\ud83d\udd0d Search tasks...\"\r\n                            value=\"${searchQuery}\"\r\n                            oninput=\"searchQuery = this.value; render();\"\r\n                            class=\"w-full px-3 py-2 text-sm border ${borderColor} ${inputBg} rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500\"\r\n                        \/>\r\n                        \r\n                        <div class=\"flex gap-2\">\r\n                            ${uniquePersons.length > 0 ? `\r\n                                <select \r\n                                    onchange=\"filterPerson = this.value; render();\"\r\n                                    class=\"flex-1 px-3 py-2 text-sm border ${borderColor} ${inputBg} rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500\"\r\n                                >\r\n                                    <option value=\"\">All People<\/option>\r\n                                    ${uniquePersons.map(person => `\r\n                                        <option value=\"${person}\" ${filterPerson === person ? 'selected' : ''}>${person}<\/option>\r\n                                    `).join('')}\r\n                                <\/select>\r\n                            ` : ''}\r\n\r\n                            <label class=\"flex items-center gap-1.5 px-3 py-2 border ${borderColor} rounded-lg cursor-pointer ${inputBg}\">\r\n                                <input \r\n                                    type=\"checkbox\" \r\n                                    ${showCompleted ? 'checked' : ''} \r\n                                    onchange=\"showCompleted = this.checked; render();\" \r\n                                    class=\"w-4 h-4\" \r\n                                \/>\r\n                                <span class=\"text-xs ${textColor} whitespace-nowrap\">Show Done<\/span>\r\n                            <\/label>\r\n                        <\/div>\r\n\r\n                        <div class=\"flex gap-2\">\r\n                            <button\r\n                                onclick=\"shareOnWhatsApp()\"\r\n                                class=\"flex-1 px-3 py-2 bg-green-500 text-white rounded-lg text-xs font-medium active:scale-95 transition-transform\"\r\n                            >\r\n                                \ud83d\udce4 Share\r\n                            <\/button>\r\n                            \r\n                            <button\r\n                                onclick=\"exportToPDF()\"\r\n                                class=\"flex-1 px-3 py-2 bg-red-500 text-white rounded-lg text-xs font-medium active:scale-95 transition-transform\"\r\n                            >\r\n                                \ud83d\udcc4 PDF\r\n                            <\/button>\r\n                        <\/div>\r\n\r\n                        <div class=\"text-xs ${textMuted} text-center pt-1\">\r\n                            ${completedCount} \/ ${filteredTasks.length} completed\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <!-- Tasks List -->\r\n                <div id=\"tasks-container\" class=\"space-y-2.5\">\r\n                    ${filteredTasks.length === 0 ? `\r\n                        <div class=\"${bgCard} rounded-xl shadow-md p-8 text-center\">\r\n                            <p class=\"${textMuted}\">No tasks yet. Add one above!<\/p>\r\n                        <\/div>\r\n                    ` : filteredTasks.map(task => `\r\n                        <div\r\n                            class=\"${bgCard} rounded-xl shadow-md p-3 cursor-move active:shadow-lg transition-shadow\"\r\n                            style=\"border-left: 4px solid ${isOverdue(task) ? '#ef4444' : getPriorityColor(task.priority)}\"\r\n                        >\r\n                            <div class=\"flex items-start gap-2.5\">\r\n                                <button\r\n                                    onclick=\"toggleTask(${task.id})\"\r\n                                    class=\"flex-shrink-0 w-5 h-5 rounded-full border-2 flex items-center justify-center mt-0.5 active:scale-110 transition-all\"\r\n                                    style=\"border-color: ${task.completed ? '#10b981' : getPriorityColor(task.priority)}; background-color: ${task.completed ? '#10b981' : 'transparent'}\"\r\n                                >\r\n                                    ${task.completed ? '<span class=\"text-white text-xs\">\u2713<\/span>' : ''}\r\n                                <\/button>\r\n                                \r\n                                <div class=\"flex-1 min-w-0\">\r\n                                    <div class=\"flex flex-wrap items-center gap-1.5 mb-1.5\">\r\n                                        <span class=\"text-xs px-1.5 py-0.5 rounded font-medium\" style=\"background-color: ${getPriorityColor(task.priority)}20; color: ${getPriorityColor(task.priority)}\">\r\n                                            ${task.priority.toUpperCase()}\r\n                                        <\/span>\r\n                                        ${isOverdue(task) ? '<span class=\"text-xs px-1.5 py-0.5 rounded bg-red-100 text-red-700 font-medium\">OVERDUE<\/span>' : ''}\r\n                                    <\/div>\r\n                                    \r\n                                    <div class=\"${task.completed ? 'line-through ' + textMuted : textColor} text-sm font-medium mb-1\">\r\n                                        ${task.text}\r\n                                    <\/div>\r\n                                    \r\n                                    <div class=\"flex flex-wrap gap-2 text-xs ${textMuted}\">\r\n                                        ${task.assignedTo ? `<span>\ud83d\udc64 ${task.assignedTo}<\/span>` : ''}\r\n                                        ${task.dueDate ? `<span>\ud83d\udcc5 ${new Date(task.dueDate).toLocaleDateString('en-GB')}<\/span>` : ''}\r\n                                    <\/div>\r\n                                <\/div>\r\n                                \r\n                                <button\r\n                                    onclick=\"deleteTask(${task.id})\"\r\n                                    class=\"flex-shrink-0 w-6 h-6 flex items-center justify-center text-red-500 hover:text-red-700 text-lg active:scale-110 transition-all\"\r\n                                >\r\n                                    \u00d7\r\n                                <\/button>\r\n                            <\/div>\r\n                        <\/div>\r\n                    `).join('')}\r\n                <\/div>\r\n            `;\r\n\r\n            \/\/ Initialize drag and drop\r\n            const container = document.getElementById('tasks-container');\r\n            if (container) {\r\n                new Sortable(container, {\r\n                    animation: 150,\r\n                    ghostClass: 'ghost',\r\n                    handle: '.cursor-move',\r\n                    onEnd: function(evt) {\r\n                        const item = tasks[evt.oldIndex];\r\n                        tasks.splice(evt.oldIndex, 1);\r\n                        tasks.splice(evt.newIndex, 0, item);\r\n                        saveTasks();\r\n                    }\r\n                });\r\n            }\r\n        }\r\n\r\n        checkReminders();\r\n        render();\r\n        setInterval(() => {\r\n            checkReminders();\r\n            render();\r\n        }, 60000);\r\n    <\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Task Manager App<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"page-builder","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-2604","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/pages\/2604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/comments?post=2604"}],"version-history":[{"count":17,"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/pages\/2604\/revisions"}],"predecessor-version":[{"id":2797,"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/pages\/2604\/revisions\/2797"}],"wp:attachment":[{"href":"https:\/\/malikskitchen.in\/index.php\/wp-json\/wp\/v2\/media?parent=2604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}