class meal_list extends HTMLElement { constructor() { super(); const now = new Date(); const hours = now.getHours(); this.date = new Date("2025-03-10") .toISOString() .slice(0, 10) .replace(/-/g, ""); switch (true) { case hours < 8: this.selectedType = 1; break; case hours < 14: this.selectedType = 2; break; default: this.selectedType = 3; } } connectedCallback() { this.render(); } async get_meal(date, type) { try { let response = await fetch(`/api/meal?date=${date}&type=${type}`); if (!response.ok) throw new Error("Failed to fetch meal data"); let data = await response.json(); return data; } catch (error) { console.error("❌ API Error:", error); return ["식단 정보를 불러올 수 없습니다."]; } } async render() { const header = document.createElement("header"); const select = document.createElement("select"); const types = ["아침", "점심", "저녁"]; types.forEach((type, index) => { const option = document.createElement("option"); option.textContent = types[index]; option.value = index + 1; if (index + 1 === this.selectedType) option.selected = true; select.appendChild(option); }); select.addEventListener("change", async () => { this.selectedType = Number(select.value); await this.render(); }); const res = await this.get_meal(this.date, this.selectedType); const ul = document.createElement("ul"); res.meal_list.forEach((meal) => { const li = document.createElement("li"); li.textContent = meal; ul.appendChild(li); }); const kcal = document.createElement("p"); kcal.textContent = res.kcal; header.appendChild(select); header.appendChild(kcal); this.innerHTML = ""; this.append(header); this.appendChild(ul); } } customElements.define("meal-list", meal_list); class task_list extends HTMLElement { constructor() { super(); } connectedCallback() { this.render(); } async render() { const ul = document.createElement("ul"); let data = await fetch("/api/tasklist"); data = await data.json(); for (let i of data) { const date = new Date(i.end.date); date.setDate(date.getDate() - 1); const li = document.createElement("li"); const name = document.createElement("h2"); name.textContent = i.summary; const box = document.createElement("div"); const cal = document.createElement("img"); cal.src = "/public/images/calendar.png"; const deadline = document.createElement("p"); deadline.textContent = date.toISOString().slice(0, 10); box.append(cal, deadline); li.append(name, box); li.addEventListener("click", () => { const modal = document.createElement("task-edit"); modal.setAttribute("event_id", i.id); document.body.appendChild(modal); }); ul.appendChild(li); } this.innerHTML = ""; this.appendChild(ul); } } customElements.define("task-list", task_list); class edit_task extends HTMLElement { constructor() { super(); } connectedCallback() { this.render(); } async getData() { const response = await fetch( `/api/gettask?event_id=${this.getAttribute("event_id")}` ); let data = response.json(); return data; } async render() { this.className = "task_modal"; const data = await this.getData(); // 📌 닫기 버튼 const closeBtn = document.createElement("span"); closeBtn.classList.add("close"); closeBtn.innerHTML = "✖"; closeBtn.addEventListener("click", () => this.remove()); // 📌 제목 const title = document.createElement("div"); title.classList.add("title"); title.textContent = "Edit Task"; // 📌 Name 입력란 const nameGroup = this.createInputGroup( "Name", "text", "name", data.summary ); // 📌 Date 입력란 (시작~종료) const dateGroup = document.createElement("div"); dateGroup.classList.add("input-group"); const dateLabel = document.createElement("label"); dateLabel.textContent = "Date"; const dateContainer = document.createElement("div"); dateContainer.classList.add("date-group"); const startDate = this.createInput( "date", "start-date", data.start.date ); const tilde = document.createElement("span"); tilde.textContent = "~"; const endDate = this.createInput("date", "end-date", data.end.date); dateContainer.append(startDate, tilde, endDate); dateGroup.append(dateLabel, dateContainer); // 📌 Description 입력란 const descGroup = this.createInputGroup( "Desc", "textarea", "desc", data.description ); // 📌 버튼 컨테이너 const buttonContainer = document.createElement("div"); buttonContainer.classList.add("buttons"); const cancelBtn = document.createElement("button"); cancelBtn.classList.add("cancel"); cancelBtn.textContent = "Cancel"; cancelBtn.addEventListener("click", () => this.remove()); const saveBtn = document.createElement("button"); saveBtn.classList.add("save"); saveBtn.textContent = "Save"; saveBtn.addEventListener("click", async () => await this.saveTask()); buttonContainer.append(cancelBtn, saveBtn); this.innerHTML = ""; this.append( closeBtn, title, nameGroup, dateGroup, descGroup, buttonContainer ); } createInputGroup(labelText, inputType, id, default_value) { const group = document.createElement("div"); group.classList.add("input-group"); const label = document.createElement("label"); label.textContent = labelText; let input; if (inputType === "textarea") { input = document.createElement("textarea"); input.rows = "4"; } else { input = document.createElement("input"); input.type = inputType; } input.value = default_value; input.placeholder = default_value; input.id = id; group.append(label, input); return group; } createInput(type, id, default_value) { const input = document.createElement("input"); input.type = type; input.id = id; input.value = default_value; input.placeholder = default_value; return input; } async saveTask() { const name = document.getElementById("name").value; const startDate = document.getElementById("start-date").value; const endDate = document.getElementById("end-date").value; const desc = document.getElementById("desc").value; let response = await fetch("/api/edittask", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ event_id: this.getAttribute("event_id"), data: { end: { date: endDate }, start: { date: startDate }, summary: name, description: desc, }, }), }); response = await response.json(); console.log(response); const taskListComponent = document.querySelector("task-list"); if (taskListComponent) { taskListComponent.render(); } const targetIframe = document.getElementById("calendar_iframe"); if (targetIframe) { targetIframe.src = targetIframe.src; // ✅ iframe 새로고침 } this.remove(); } } customElements.define("task-edit", edit_task); class create_task extends HTMLElement { constructor() { super(); } connectedCallback() { this.render(); } async render() { this.className = "task_modal"; // 📌 닫기 버튼 const closeBtn = document.createElement("span"); closeBtn.classList.add("close"); closeBtn.innerHTML = "✖"; closeBtn.addEventListener("click", () => this.remove()); // 📌 제목 const title = document.createElement("div"); title.classList.add("title"); title.textContent = "Create Task"; // 📌 Name 입력란 const nameGroup = this.createInputGroup("Name", "text", "name"); // 📌 Date 입력란 (시작~종료) const dateGroup = document.createElement("div"); dateGroup.classList.add("input-group"); const dateLabel = document.createElement("label"); dateLabel.textContent = "Date"; const dateContainer = document.createElement("div"); dateContainer.classList.add("date-group"); const startDate = this.createInput("date", "start-date"); const tilde = document.createElement("span"); tilde.textContent = "~"; const endDate = this.createInput("date", "end-date"); dateContainer.append(startDate, tilde, endDate); dateGroup.append(dateLabel, dateContainer); // 📌 Description 입력란 const descGroup = this.createInputGroup("Desc", "textarea", "desc"); // 📌 버튼 컨테이너 const buttonContainer = document.createElement("div"); buttonContainer.classList.add("buttons"); const cancelBtn = document.createElement("button"); cancelBtn.classList.add("cancel"); cancelBtn.textContent = "Cancel"; cancelBtn.addEventListener("click", () => this.remove()); const saveBtn = document.createElement("button"); saveBtn.classList.add("save"); saveBtn.textContent = "Save"; saveBtn.addEventListener("click", async () => await this.saveTask()); buttonContainer.append(cancelBtn, saveBtn); this.innerHTML = ""; this.append( closeBtn, title, nameGroup, dateGroup, descGroup, buttonContainer ); } createInputGroup(labelText, inputType, id) { const group = document.createElement("div"); group.classList.add("input-group"); const label = document.createElement("label"); label.textContent = labelText; let input; if (inputType === "textarea") { input = document.createElement("textarea"); input.rows = "4"; } else { input = document.createElement("input"); input.type = inputType; } input.id = id; group.append(label, input); return group; } createInput(type, id) { const input = document.createElement("input"); input.type = type; input.id = id; return input; } async saveTask() { const name = document.getElementById("name").value; const startDate = document.getElementById("start-date").value; const endDate = document.getElementById("end-date").value; const desc = document.getElementById("desc").value; let response = await fetch("/api/createtask", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ event_id: this.getAttribute("event_id"), data: { end: { date: endDate }, start: { date: startDate }, summary: name, description: desc, }, }), }); response = await response.json(); console.log(response); const taskListComponent = document.querySelector("task-list"); if (taskListComponent) { taskListComponent.render(); } const targetIframe = document.getElementById("calendar_iframe"); if (targetIframe) { targetIframe.src = targetIframe.src; // ✅ iframe 새로고침 } this.remove(); } } customElements.define("create-task", create_task);