Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,18 @@
<body>
<h1>AI チャット</h1>
<ul id="chat-messages">
<template id="chat-message-template">
<li class="chat-message">
<div class="chat-message__author">あなた</div>
<div class="chat-message__content"></div>
<button class="chat-message__delete-button" type="button">
削除
</button>
</li>
</template>
<template id="chat-message-template">
<li class="chat-message">
<div class="chat-message__author">あなた</div>
<div class="chat-message__content"></div>
<button class="chat-message__delete-button" type="button">削除</button>
</li>
</template>
</ul>
<div id="cook-time">
10分
<span>10分</span>
<input type="range" min="0" max="100" value="0" step="10" id="cook-time-slider">
100分~
<span>100分~</span>
</div>
<div id="selectButton"></div>
<div>選択した食材</div>
Expand Down
87 changes: 42 additions & 45 deletions public/script.js
Original file line number Diff line number Diff line change
@@ -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}はすでに選択されています`);
Expand All @@ -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; // 削除ボタンに食材情報を追加

Expand All @@ -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);

Expand All @@ -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);
};
171 changes: 119 additions & 52 deletions public/style.css
Original file line number Diff line number Diff line change
@@ -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
}
.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;
}