{"version":3,"sources":["webpack://microverse-todolist/./src/lib/project.ts","webpack://microverse-todolist/./src/lib/todo.ts","webpack://microverse-todolist/./src/localstorage.ts","webpack://microverse-todolist/./src/ui/todo.ts","webpack://microverse-todolist/./src/ui/project.ts","webpack://microverse-todolist/./src/ui/todo-form.ts","webpack://microverse-todolist/./src/ui/project-form.ts","webpack://microverse-todolist/./src/index.ts"],"names":["title","todos","id","Date","now","this","addTodo","todo","push","removeTodo","filter","getTodo","find","getTodos","Priority","description","dueDate","priority","update","save","data","window","localStorage","setItem","JSON","stringify","$TODO_CONTAINER","document","querySelector","$TODO_TITLE","parentNode","onEdit","onDelete","editHandler","deleteHandler","addEventListener","querySelectorAll","Array","from","classList","contains","style","height","getBoundingClientRect","width","setTitle","text","textContent","add","container","createElement","dataset","heading","content","bottom","date","actions","edit","editIcon","innerHTML","appendChild","remove","removeIcon","close","closeIcon","e","stopPropagation","offsetTop","i","elem","clear","$PROJECT_CONTAINER","onClick","onRemove","clickHandler","removeHandler","project","div","setActive","$TODO_FORM_OUTER","$TODO_FORM_INNER","$TODO_FORM","$formTitle","$title","$description","$dueDate","$priority","onSubmit","onClose","submitHandler","closeHandler","handleSubmit","hide","updateTitle","fill","value","checked","show","preventDefault","trim","r","$PROJECT_FORM","$hamburger","$nav","toggle","$addTodo","currentProject","todoBeingEdited","projects","getItem","parse","item","length","todoForm","todoRenderer","projectRenderer","p"],"mappings":"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","file":"36c17bb48b8ebaf9d14c_bundle.js","sourcesContent":["import Todo from './todo';\n\nexport type ProjectData = {\n title : string;\n};\n\nclass Project {\n public id: number = Date.now();\n public title: string;\n private todos: Todo[];\n\n constructor(title: string, todos: Todo[] = []) {\n this.title = title;\n this.todos = todos;\n }\n\n addTodo(todo: Todo): void {\n this.todos.push(todo);\n }\n\n removeTodo(id: number): void {\n this.todos = this.todos.filter(todo => todo.id !== id);\n }\n\n getTodo(id: number): Todo | undefined {\n return this.todos.find(todo => todo.id === id);\n }\n\n getTodos(): Todo[] {\n return this.todos;\n }\n}\n\nexport default Project;\n","export enum Priority {\n high = 1,\n medium,\n low\n};\n\nexport type TodoData = {\n title : string;\n description : string;\n dueDate : string;\n priority : Priority;\n};\n\nclass Todo {\n public id: number = Date.now();\n public title: string;\n public description: string;\n public dueDate: string;\n public priority: Priority;\n\n constructor(title: string, description: string, dueDate: string, priority: Priority) {\n this.title = title;\n this.description = description;\n this.dueDate = dueDate;\n this.priority = priority;\n }\n\n update({ title, description, dueDate, priority }: Partial): void {\n if (title) this.title = title;\n if (description) this.description = description;\n if (dueDate) this.dueDate = dueDate;\n if (priority) this.priority = priority;\n }\n}\n\nexport default Todo;\n","import Project from './lib/project';\nimport Todo from './lib/todo';\n\nexport const save = (data: Project[]) => {\n window.localStorage.setItem('data', JSON.stringify(data));\n};\n\nexport const get = (): Project[] => {\n const data = window.localStorage.getItem('data') || '[]';\n let projects = [];\n for (let item of JSON.parse(data)) {\n const project = new Project(item.title);\n project.id = item.id;\n projects.push(project);\n for (let { id, title, description, dueDate, priority } of item.todos) {\n const todo = new Todo(title, description, dueDate, priority);\n todo.id = id;\n project.addTodo(todo);\n }\n }\n if (projects.length === 0) {\n projects.push(new Project('Default'));\n save(projects);\n }\n return projects;\n};\n","import Todo from '../lib/todo';\n\nconst $TODO_CONTAINER = document.querySelector('#todos') as HTMLDivElement;\nconst $TODO_TITLE = $TODO_CONTAINER.parentNode?.querySelector('h1') as HTMLHeadingElement;\n\ntype TodoClickHandler = (todo: Todo) => void;\n\nclass TodoUI {\n editHandler: TodoClickHandler;\n deleteHandler: TodoClickHandler;\n\n constructor(onEdit: TodoClickHandler, onDelete: TodoClickHandler) {\n this.editHandler = onEdit;\n this.deleteHandler = onDelete;\n\n window.addEventListener('resize', () => {\n const todos = $TODO_CONTAINER.querySelectorAll('.todo') as NodeListOf;\n for (let todo of Array.from(todos)) {\n if (todo.classList.contains('fullscreen'))\n todo.style.height = 'auto';\n else\n todo.style.height = `${todo.getBoundingClientRect().width}px`;\n }\n });\n }\n\n setTitle(text: string) {\n $TODO_TITLE.textContent = text;\n }\n\n add(todo: Todo): void {\n const container = document.createElement('div');\n container.dataset.id = `${todo.id}`;\n container.classList.add('todo');\n container.classList.add(`priority-${todo.priority}`);\n const heading = document.createElement('h2');\n heading.textContent = todo.title;\n const content = document.createElement('p');\n content.textContent = todo.description;\n const bottom = document.createElement('div');\n bottom.classList.add('bottom');\n\n const date = document.createElement('div');\n date.classList.add('due-date');\n date.textContent = todo.dueDate;\n\n const actions = document.createElement('div');\n actions.classList.add('actions');\n const edit = document.createElement('button');\n const editIcon = document.createElement('span');\n editIcon.classList.add('material-icons');\n editIcon.innerHTML = 'create';\n edit.appendChild(editIcon);\n const remove = document.createElement('button');\n const removeIcon = document.createElement('span');\n removeIcon.classList.add('material-icons');\n removeIcon.innerHTML = 'delete';\n remove.appendChild(removeIcon);\n\n const close = document.createElement('button');\n const closeIcon = document.createElement('span');\n close.classList.add('todo-close');\n closeIcon.classList.add('material-icons');\n closeIcon.innerHTML = 'close';\n close.appendChild(closeIcon);\n\n actions.appendChild(edit);\n actions.appendChild(remove);\n\n bottom.appendChild(date);\n bottom.appendChild(actions);\n\n container.appendChild(close);\n container.appendChild(heading);\n container.appendChild(content);\n container.appendChild(bottom);\n\n container.addEventListener('click', () => container.classList.add('fullscreen'));\n\n edit.addEventListener('click', (e) => {\n e.stopPropagation();\n this.editHandler(todo)\n });\n\n remove.addEventListener('click', (e) => {\n e.stopPropagation();\n this.deleteHandler(todo)\n });\n\n close.addEventListener('click', (e) => {\n e.stopPropagation();\n container.classList.remove('fullscreen')\n });\n\n $TODO_CONTAINER.appendChild(container);\n\n // Flush dom updates\n container.offsetTop;\n\n container.style.height = `${container.getBoundingClientRect().width}px`;\n }\n\n update(todo: Todo): void {\n const container = $TODO_CONTAINER.querySelector(`.todo[data-id=\"${todo.id}\"]`);\n if (!container) return;\n for (let i = 1; i <= 3; i += 1) {\n container.classList.remove(`priority-${i}`);\n }\n container.classList.add(`priority-${todo.priority}`);\n container.querySelector('h2')!.textContent = todo.title;\n container.querySelector('p')!.textContent = todo.description;\n container.querySelector('.due-date')!.textContent = todo.dueDate;\n }\n\n remove(id: number): boolean {\n const elem = $TODO_CONTAINER.querySelector(`.todo[data-id=\"${id}\"]`);\n if (elem) {\n elem.remove();\n return true;\n }\n return false;\n }\n\n clear(): void {\n $TODO_CONTAINER.innerHTML = '';\n }\n}\n\nexport default TodoUI;\n","import Project from '../lib/project';\n\nconst $PROJECT_CONTAINER = document.querySelector(\"#projects\") as HTMLDivElement;\n\ntype ProjectClickHandler = (project: Project) => void;\n\nclass ProjectUI {\n clickHandler: ProjectClickHandler;\n removeHandler: ProjectClickHandler;\n\n constructor(onClick: ProjectClickHandler, onRemove: ProjectClickHandler) {\n this.clickHandler = onClick;\n this.removeHandler = onRemove;\n }\n\n add(project: Project): void {\n const div = document.createElement('div');\n div.classList.add('project');\n div.textContent = project.title;\n div.addEventListener('click', () => this.clickHandler(project));\n div.dataset.id = `${project.id}`;\n\n const removeIcon = document.createElement('span');\n removeIcon.classList.add('material-icons');\n removeIcon.innerHTML = 'close';\n\n removeIcon.addEventListener('click', (e) => {\n e.stopPropagation();\n this.removeHandler(project)\n });\n\n div.appendChild(removeIcon);\n\n $PROJECT_CONTAINER.appendChild(div);\n }\n\n remove(id: number): boolean {\n const elem = $PROJECT_CONTAINER.querySelector(`.project[data-id=\"${id}\"]`);\n if (elem) {\n elem.remove();\n return true;\n }\n return false;\n }\n\n setActive(id: number) {\n const elems = Array.from($PROJECT_CONTAINER.querySelectorAll('.project'));\n for (let elem of elems) {\n elem.classList.remove('active');\n }\n const elem = $PROJECT_CONTAINER.querySelector(`.project[data-id=\"${id}\"`);\n if (elem)\n elem.classList.add('active');\n }\n}\n\n\nexport default ProjectUI;\n","import { TodoData } from '../lib/todo';\n\ntype FormSubmitHandler = (todoData: TodoData) => void;\ntype FormCloseHandler = () => void;\n\nconst $TODO_FORM_OUTER = document.querySelector('.todo-form-outer') as HTMLDivElement;\nconst $TODO_FORM_INNER = $TODO_FORM_OUTER.querySelector('.todo-form-inner') as HTMLDivElement;\nconst $TODO_FORM = document.querySelector('#todo-form') as HTMLFormElement;\nconst $formTitle = $TODO_FORM_OUTER.querySelector('h2') as HTMLHeadingElement;\n\nconst $title = $TODO_FORM.querySelector('#todo-title') as HTMLInputElement;\nconst $description = $TODO_FORM.querySelector('#todo-description') as HTMLInputElement;\nconst $dueDate = $TODO_FORM.querySelector('#todo-due-date') as HTMLInputElement;\nconst $priority = $TODO_FORM.querySelectorAll('[name=\"priority\"]') as NodeListOf;\n\nclass TodoForm {\n submitHandler: FormSubmitHandler;\n closeHandler: FormCloseHandler;\n\n constructor(onSubmit: FormSubmitHandler, onClose: FormCloseHandler) {\n this.submitHandler = onSubmit;\n this.closeHandler = onClose;\n this.handleSubmit();\n\n $TODO_FORM_OUTER.addEventListener('click', () => this.hide());\n $TODO_FORM_INNER.addEventListener('click', (e) => e.stopPropagation());\n\n this.updateTitle('Add Note');\n }\n\n fill(todo: TodoData) {\n $title.value = todo.title;\n $description.value = todo.description;\n $dueDate.value = todo.dueDate;\n $priority[todo.priority - 1].checked = true;\n }\n\n clear() {\n $title.value = '';\n $description.value = '';\n $dueDate.value = '';\n $priority[0].checked = true;\n }\n\n updateTitle(title: string) {\n $formTitle.innerHTML = title;\n }\n\n show() {\n $TODO_FORM_OUTER.classList.add('shown');\n }\n\n hide() {\n $TODO_FORM_OUTER.classList.remove('shown');\n this.closeHandler();\n }\n\n private handleSubmit() {\n $TODO_FORM.addEventListener('submit', (e) => {\n e.preventDefault();\n this.submitHandler({\n title: $title.value.trim(),\n description: $description.value.trim(),\n dueDate: $dueDate.value.trim(),\n priority: +Array.from($priority).find(r => r.checked)!.value\n });\n this.clear();\n });\n }\n}\n\nexport default TodoForm;\n","import { ProjectData } from '../lib/project';\n\ntype FormSubmitHandler = (projectData: ProjectData) => void;\n\nconst $PROJECT_FORM = document.querySelector('#project-form') as HTMLFormElement;\nconst $title = $PROJECT_FORM.querySelector('#project-title') as HTMLInputElement;\n\nclass ProjectForm {\n submitHandler: FormSubmitHandler;\n\n constructor(onSubmit: FormSubmitHandler) {\n this.submitHandler = onSubmit;\n this.handleSubmit();\n }\n\n clear() {\n $title.value = '';\n }\n\n private handleSubmit() {\n $PROJECT_FORM.addEventListener('submit', (e) => {\n e.preventDefault();\n this.submitHandler({ title: $title.value.trim() });\n this.clear();\n });\n }\n}\n\nexport default ProjectForm;\n","import Project, { ProjectData } from './lib/project';\nimport Todo, { TodoData } from './lib/todo';\n\nimport * as storage from './localstorage';\n\nimport TodoUI from './ui/todo';\nimport ProjectUI from './ui/project';\nimport TodoForm from './ui/todo-form';\nimport ProjectForm from './ui/project-form';\n\n\n// Hamburger nav\nconst $hamburger = document.querySelector('#hamburger') as HTMLDivElement;\nconst $nav = document.querySelector('nav') as HTMLDivElement;\n\n$hamburger.addEventListener('click', () => {\n $nav.classList.toggle('open');\n $hamburger.classList.toggle('open');\n});\n\n\nconst $addTodo = document.querySelector('#add-todo') as HTMLDivElement;\n\nlet currentProject: Project | null = null;\n\nlet todoBeingEdited: Todo | null = null;\n\nlet projects = storage.get();\n\n$addTodo.addEventListener('click', () => {\n todoForm.show();\n todoForm.updateTitle('Add Todo');\n});\n\nconst onTodoEdit = (todo: Todo) => {\n todoForm.fill(todo);\n todoBeingEdited = todo;\n todoForm.updateTitle('Edit Todo');\n todoForm.show();\n storage.save(projects);\n};\n\nconst onTodoDelete = (todo: Todo) => {\n if (!currentProject) return;\n todoRenderer.remove(todo.id);\n currentProject.removeTodo(todo.id);\n storage.save(projects);\n};\n\nconst onProjectClick = (project: Project) => {\n if (currentProject && project.id === currentProject.id) return;\n currentProject = project;\n todoRenderer.setTitle(project.title);\n todoRenderer.clear();\n projectRenderer.setActive(project.id);\n for (let todo of project.getTodos()) {\n todoRenderer.add(todo);\n }\n $addTodo.classList.add('shown');\n};\n\nconst onTodoFormSubmit = ({ title, description, dueDate, priority }: TodoData) => {\n if (todoBeingEdited) {\n todoBeingEdited.update({ title, description, dueDate, priority });\n todoRenderer.update(todoBeingEdited);\n todoBeingEdited = null;\n } else {\n const todo = new Todo(title, description, dueDate, priority);\n if (currentProject) {\n todoRenderer.add(todo);\n currentProject.addTodo(todo);\n }\n }\n todoForm.hide();\n storage.save(projects);\n};\n\nconst onTodoFormClose = () => {\n todoBeingEdited = null;\n todoForm.clear();\n};\n\nconst onProjectFormSubmit = ({ title }: ProjectData) => {\n const project = new Project(title);\n projectRenderer.add(project);\n projects.push(project);\n storage.save(projects);\n};\n\nconst onProjectDelete = (project: Project) => {\n if (currentProject && currentProject.id === project.id) {\n currentProject = null;\n $addTodo.classList.remove('shown');\n todoRenderer.clear();\n todoRenderer.setTitle('');\n }\n projects = projects.filter(p => p.id !== project.id);\n storage.save(projects);\n projectRenderer.remove(project.id);\n};\n\nconst todoForm = new TodoForm(onTodoFormSubmit, onTodoFormClose);\nconst todoRenderer = new TodoUI(onTodoEdit, onTodoDelete);\nconst projectRenderer = new ProjectUI(onProjectClick, onProjectDelete);\n\nnew ProjectForm(onProjectFormSubmit);\n\nfor (let project of projects) {\n projectRenderer.add(project);\n}\n"],"sourceRoot":""}