diff --git a/public/index.html b/public/index.html index cfca93d..9d14f60 100644 --- a/public/index.html +++ b/public/index.html @@ -9,20 +9,18 @@

AI チャット

- 10分 + 10分 - 100分~ + 100分~
選択した食材
diff --git a/public/script.js b/public/script.js index 5ffc589..773e938 100644 --- a/public/script.js +++ b/public/script.js @@ -1,59 +1,55 @@ const chatMessagesElement = document.getElementById("chat-messages"); -const chatMessageTemplateElement = document.getElementById( - "chat-message-template" -); +const chatMessageTemplateElement = document.getElementById("chat-message-template"); const submitButtonElement = document.getElementById("submit-button"); // メッセージを画面に描画する function addChatMessageElement(author, chatMessage) { - // template 要素 (HTMLTemplateElement) は content プロパティを持ち、cloneNode メソッドで複製して利用できる - // 引数に true を渡すと子孫要素も複製される const fragment = chatMessageTemplateElement.content.cloneNode(true); - // querySelector メソッドを用いると呼ばれたクラス内の要素を CSS のセレクタの記法で検索できる const contentElement = fragment.querySelector(".chat-message__content"); const rootElement = fragment.querySelector(".chat-message"); const authorElement = fragment.querySelector(".chat-message__author"); rootElement.classList.add(`chat-message--${author}`); const authorLabelMap = { you: "あなた", ai: "AI" }; authorElement.textContent = authorLabelMap[author]; - const deleteButtonElement = fragment.querySelector( - ".chat-message__delete-button" - ); + const deleteButtonElement = fragment.querySelector(".chat-message__delete-button"); + contentElement.textContent = chatMessage.content; + + // 削除ボタンのクリックイベント deleteButtonElement.onclick = () => { rootElement.remove(); }; + chatMessagesElement.appendChild(fragment); } async function postChat(request) { - const response = await fetch("/chat", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(request), - }); - return await response.json(); + const response = await fetch("/chat", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(request), + }); + return await response.json(); } - const createButton = document.getElementById("selectButton"); -const choiceOfIngredients = ["豚肉", "牛肉", "魚", "卵", "鶏肉"]; //選択肢の食材の配列 +const choiceOfIngredients = ["豚肉", "牛肉", "魚", "卵", "鶏肉"]; // 選択肢の食材の配列 -choiceOfIngredients.forEach((ingredient) => { //choiceOfIngredientsの配列からそれぞれのボタンを作成 +choiceOfIngredients.forEach((ingredient) => { // 食材ごとにボタンを作成 const newButton = document.createElement("button"); newButton.textContent = ingredient; newButton.type = "button"; - newButton.classList.add("select-btn"); + newButton.classList.add("select-btn"); // スタイルを適用 createButton.appendChild(newButton); }); -const selectedIngredients = []; +let selectedIngredients = []; const showSelectedIngredients = document.getElementById("selectedIngredients"); document.addEventListener('click', function(event) { - if (event.target.matches('.select-btn')) { + if (event.target.matches('.select-btn')) { // 食材ボタンがクリックされた場合 const ingredient = event.target.textContent; if (selectedIngredients.includes(ingredient)) { console.log(`${ingredient}はすでに選択されています`); @@ -64,7 +60,7 @@ document.addEventListener('click', function(event) { selectedIngredientsList.textContent = ingredient; const deleteButton = document.createElement("button"); - deleteButton.textContent = "削除"; + deleteButton.textContent = "×"; // ボタンをシンプルなアイコンに変更 deleteButton.classList.add("delete-btn"); deleteButton.dataset.ingredient = ingredient; // 削除ボタンに食材情報を追加 @@ -74,7 +70,7 @@ document.addEventListener('click', function(event) { console.log(ingredient); console.log(selectedIngredients); } - } else if (event.target.matches('.delete-btn')) { + } else if (event.target.matches('.delete-btn')) { // 削除ボタンがクリックされた場合 const ingredient = event.target.dataset.ingredient; const index = selectedIngredients.indexOf(ingredient); @@ -89,24 +85,25 @@ document.addEventListener('click', function(event) { }); submitButtonElement.onclick = async () => { - const promptText = selectedIngredients.join("と") + "を用いた主菜を含む一食の献立を3つ提案してください"; - const aiMessageChunk = await postChat({ promptText }); - addChatMessageElement("you", { content: promptText }); - addChatMessageElement("ai", aiMessageChunk); - selectedIngredients = []; - const responseString = aiMessageChunk.content; - - console.log(responseString); // これで返答をstring形式で取得できます - - // 献立を3つに分割(改行文字 "\n\n" を基準に分割する例) - const menuItems = responseString.split("###"); - - // 分割した献立をそれぞれ個別に保存または処理 - const menu1 = menuItems[1]; - const menu2 = menuItems[2]; - const menu3 = menuItems[3]; - - console.log("献立 1:", menu1); - console.log("献立 2:", menu2); - console.log("献立 3:", menu3); + const promptText = selectedIngredients.join("と") + "を用いた主菜を含む一食の献立を3つ提案してください"; + const aiMessageChunk = await postChat({ promptText }); + addChatMessageElement("you", { content: promptText }); + addChatMessageElement("ai", aiMessageChunk); + selectedIngredients = []; + showSelectedIngredients.innerHTML = ''; // 選択済み食材をクリア + const responseString = aiMessageChunk.content; + + console.log(responseString); // これで返答をstring形式で取得できます + + // 献立を3つに分割(改行文字 "\n\n" を基準に分割する例) + const menuItems = responseString.split("###"); + + // 分割した献立をそれぞれ個別に保存または処理 + const menu1 = menuItems[1]; + const menu2 = menuItems[2]; + const menu3 = menuItems[3]; + + console.log("献立 1:", menu1); + console.log("献立 2:", menu2); + console.log("献立 3:", menu3); }; diff --git a/public/style.css b/public/style.css index 8b22e9c..5869e25 100644 --- a/public/style.css +++ b/public/style.css @@ -1,69 +1,136 @@ +/* style.css */ +body { + font-family: Arial, sans-serif; + background-color: #f5f5f5; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + align-items: center; +} + +h1 { + color: #333; + margin-top: 20px; +} + #chat-messages { - list-style-type: none; - padding: 0; - display: flex; - flex-direction: column; - gap: 10px; - } + list-style: none; + padding: 0; + margin: 20px 0; + width: 80%; + max-width: 600px; + background-color: #fff; + border-radius: 10px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + overflow: hidden; +} - .chat-message { - padding: 10px; - border: 1px solid; - border-radius: 5px; - } +.chat-message { + padding: 10px 20px; + border-bottom: 1px solid #eee; + display: flex; + justify-content: space-between; + align-items: center; +} - .chat-message__author { - font-weight: bold; - } +.chat-message:last-child { + border-bottom: none; +} - .chat-message__content { - margin-top: 5px; - } +.chat-message__author { + font-weight: bold; +} - .chat-message__delete-button { - margin-top: 5px; - } +.chat-message__content { + flex: 1; + margin: 0 10px; +} - #input-form { - display: flex; - gap: 5px; - } +.chat-message__delete-button { + background-color: #ff6b6b; + border: none; + color: white; + padding: 5px 10px; + cursor: pointer; + border-radius: 5px; + transition: background-color 0.3s; +} - #prompt-text-input { - flex-grow: 1; - } - .chat-message--you { - border-color: #ff0000; - } - .chat-message--ai { - border-color: #0000ff; - } +.chat-message__delete-button:hover { + background-color: #ff4c4c; +} +#cook-time { + display: flex; + align-items: center; + margin: 20px 0; + width: 80%; + max-width: 600px; +} -.button { - border:2px solid black; - border-radius: 2px; - padding: 10px 10px +#cook-time-slider { + flex: 1; + margin: 0 10px; } -.button:hover{ - border:3px solid aquamarine; +#selectButton { + margin: 20px 0; + display: flex; + flex-wrap: wrap; + gap: 10px; } -.button-letter { - font-size: 10px; - color: red; +.select-btn { + background-color: #007bff; + border: none; + color: white; + padding: 10px 15px; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.3s; } -#cook-time-slider{ - width: 250px; - text-align: center; - overflow: hidden; - color: #ff0000; +.select-btn:hover { + background-color: #0056b3; +} + +#selectedIngredients { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +#selectedIngredients li { + background-color: #eee; + padding: 5px 10px; + border-radius: 20px; + display: flex; + align-items: center; + gap: 5px; } -#cook-time{ - color: #ff0000; - border:2px black; - padding:20px 10px -} \ No newline at end of file +.delete-btn { + background: none; + border: none; + color: #ff6b6b; + cursor: pointer; +} + +#submit-button { + background-color: #28a745; + border: none; + color: white; + padding: 10px 20px; + cursor: pointer; + border-radius: 5px; + transition: background-color 0.3s; + margin-top: 20px; +} + +#submit-button:hover { + background-color: #218838; +}