buletomato25 commited on
Commit
764bda3
·
2 Parent(s): 589d073 3b517e3

commit_032221

Browse files
static/menu.js CHANGED
@@ -1,50 +1,50 @@
1
- // Show user registration page
2
- function showUserRegister() {
3
- fetch("/reset");
4
- window.location.href = "userregister";
5
- }
6
-
7
- // Show recorder page
8
- function showRecorder() {
9
- window.location.href = "index";
10
- }
11
-
12
- // Show results page
13
- function showResults() {
14
- window.location.href = "feedback";
15
- }
16
-
17
- // Show talk detail page
18
- function showTalkDetail() {
19
- window.location.href = "talk_detail";
20
- }
21
-
22
- // Reset action page
23
- function resetAction() {
24
- window.location.href = "reset_html";
25
- }
26
-
27
- // Toggle hamburger menu visibility
28
- function toggleMenu(event) {
29
- event.stopPropagation(); // Prevents click event from propagating to the document
30
- const menu = document.getElementById("menu");
31
- menu.classList.toggle("open");
32
- }
33
-
34
- // Close the menu if clicked outside
35
- function closeMenu(event) {
36
- const menu = document.getElementById("menu");
37
- if (
38
- menu.classList.contains("open") &&
39
- !menu.contains(event.target) &&
40
- !event.target.closest("#menuButton")
41
- ) {
42
- menu.classList.remove("open");
43
- }
44
- }
45
-
46
- // Add event listener for closing the menu when clicking outside
47
- document.addEventListener("click", closeMenu);
48
-
49
- // Show recorder page
50
  document.getElementById("add-btn").addEventListener("click", showRecorder);
 
1
+ // Show user registration page
2
+ function showUserRegister() {
3
+ fetch("/reset");
4
+ window.location.href = "userregister";
5
+ }
6
+
7
+ // Show recorder page
8
+ function showRecorder() {
9
+ window.location.href = "index";
10
+ }
11
+
12
+ // Show results page
13
+ function showResults() {
14
+ window.location.href = "feedback";
15
+ }
16
+
17
+ // Show talk detail page
18
+ function showTalkDetail() {
19
+ window.location.href = "talk_detail";
20
+ }
21
+
22
+ // Reset action page
23
+ function resetAction() {
24
+ window.location.href = "reset_html";
25
+ }
26
+
27
+ // Toggle hamburger menu visibility
28
+ function toggleMenu(event) {
29
+ event.stopPropagation(); // Prevents click event from propagating to the document
30
+ const menu = document.getElementById("menu");
31
+ menu.classList.toggle("open");
32
+ }
33
+
34
+ // Close the menu if clicked outside
35
+ function closeMenu(event) {
36
+ const menu = document.getElementById("menu");
37
+ if (
38
+ menu.classList.contains("open") &&
39
+ !menu.contains(event.target) &&
40
+ !event.target.closest("#menuButton")
41
+ ) {
42
+ menu.classList.remove("open");
43
+ }
44
+ }
45
+
46
+ // Add event listener for closing the menu when clicking outside
47
+ document.addEventListener("click", closeMenu);
48
+
49
+ // Show recorder page 名前に気を付けて!
50
  document.getElementById("add-btn").addEventListener("click", showRecorder);
static/process.js CHANGED
@@ -1,222 +1,222 @@
1
-
2
- let isRecording = false;
3
- let mediaRecorder;
4
- let audioChunks = [];
5
- let recordingInterval;
6
- let count_voice = 0;
7
- let before_rate = [];
8
- const RECORDING_INTERVAL_MS = 5000; // 5秒
9
- // メンバーとチャートの初期化
10
- let members = [];
11
- let voiceData = [];
12
- let baseMemberColors = ["#4caf50", "#007bff", "#ffc107", "#dc3545", "#28a745", "#9c27b0", "#ff9800"];
13
- // Chart.js の初期化
14
- const ctx = document.getElementById("speechChart").getContext("2d");
15
- const speechChart = new Chart(ctx, {
16
- type: "doughnut",
17
- data: {
18
- labels: members,
19
- datasets: [
20
- {
21
- data: voiceData,
22
- backgroundColor: getMemberColors(members.length),
23
- },
24
- ],
25
- },
26
- options: {
27
- responsive: true,
28
- plugins: {
29
- legend: {
30
- display: true,
31
- position: "bottom",
32
- labels: { color: "white" },
33
- },
34
- },
35
- },
36
- });
37
- // サーバーからメンバー情報を取得してチャートを更新する関数
38
- async function updateChartFrom() {
39
- try {
40
- const response = await fetch("/confirm");
41
- if (!response.ok) {
42
- throw new Error(`HTTP error! status: ${response.status}`);
43
- }
44
- const data = await response.json();
45
- if (!data || !data.members || !Array.isArray(data.members)) {
46
- console.error("Invalid member data received:", data);
47
- members = ["member1"];
48
- voiceData = [50, 50];
49
- updateChart();
50
- return;
51
- }
52
- members = data.members;
53
- voiceData = [];
54
- for (let i = 0; i < members.length; i++) {
55
- voiceData.push(100 / members.length);
56
- }
57
- updateChart();
58
- } catch (error) {
59
- console.error("Failed to fetch member data:", error);
60
- members = ["member1"];
61
- voiceData = [50, 50];
62
- updateChart();
63
- }
64
- }
65
- function updateChart() {
66
- // 一人モードの場合は、ユーザーとグレー(無音)の比率をチャートに表示
67
- if (members.length === 1) {
68
- const userName = members[0];
69
- speechChart.data.labels = [userName, "無音"];
70
- speechChart.data.datasets[0].backgroundColor = ["#4caf50", "#757575"];
71
- } else {
72
- // 複数メンバーの場合は通常通りの処理
73
- speechChart.data.labels = members;
74
- speechChart.data.datasets[0].backgroundColor = getMemberColors(members.length);
75
- }
76
- speechChart.data.datasets[0].data = voiceData;
77
- speechChart.update();
78
- }
79
-
80
- // ページ読み込み時にチャート情報を更新
81
- updateChartFrom();
82
- // 録音ボタンの録音開始/停止処理
83
- async function toggleRecording() {
84
- const recordButton = document.getElementById("recordButton");
85
- if (!isRecording) {
86
- // 録音開始
87
- isRecording = true;
88
- recordButton.classList.add("recording");
89
- try {
90
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
91
- mediaRecorder = new MediaRecorder(stream);
92
- audioChunks = [];
93
- mediaRecorder.ondataavailable = (event) => {
94
- if (event.data.size > 0) {
95
- audioChunks.push(event.data);
96
- }
97
- };
98
- mediaRecorder.onstop = () => {
99
- sendAudioChunks([...audioChunks]);
100
- audioChunks = [];
101
- };
102
- mediaRecorder.start();
103
- // 5秒ごとに録音を停止して送信するインターバルを設定
104
- recordingInterval = setInterval(() => {
105
- if (mediaRecorder && mediaRecorder.state === "recording") {
106
- mediaRecorder.stop();
107
- mediaRecorder.start();
108
- }
109
- }, RECORDING_INTERVAL_MS);
110
- } catch (error) {
111
- console.error("マイクへのアクセスに失敗しました:", error);
112
- isRecording = false;
113
- recordButton.classList.remove("recording");
114
- }
115
- } else {
116
- // 録音停止
117
- isRecording = false;
118
- recordButton.classList.remove("recording");
119
- if (mediaRecorder && mediaRecorder.state === "recording") {
120
- mediaRecorder.stop();
121
- }
122
- clearInterval(recordingInterval);
123
- count_voice = 0;
124
- //before_rate = [];
125
- }
126
- }
127
- function sendAudioChunks(chunks) {
128
- const audioBlob = new Blob(chunks, { type: "audio/wav" });
129
- const reader = new FileReader();
130
- reader.onloadend = () => {
131
- const base64String = reader.result.split(",")[1];
132
- const form = document.getElementById("recordForm");
133
- const nameInput = form.querySelector('input[name="name"]');
134
- const name = nameInput ? nameInput.value : "unknown";
135
- fetch("/upload_audio", {
136
- method: "POST",
137
- headers: { "Content-Type": "application/json" },
138
- body: JSON.stringify({ audio_data: base64String, name: name }),
139
- })
140
- .then((response) => response.json())
141
- .then((data) => {
142
- if (data.error) {
143
- alert("エラー: " + data.error);
144
- console.error(data.details);
145
- } else if (data.rate !== undefined) {
146
- updateChartData(data.rate);
147
- } else if (data.rates !== undefined) {
148
- updateChartData(data.rates);
149
- }
150
- })
151
- .catch((error) => {
152
- console.error("エラー:", error);
153
- });
154
- };
155
- reader.readAsDataURL(audioBlob);
156
- }
157
- function getMemberColors(memberCount) {
158
- // 一人モードの場合は特別な処理をしない(updateChartで処理するため)
159
- if (memberCount <= 1) {
160
- return ["#4caf50", "#757575"];
161
- } else {
162
- let colors = [];
163
- for (let i = 0; i < memberCount; i++) {
164
- colors.push(baseMemberColors[i % baseMemberColors.length]);
165
- }
166
- return colors;
167
- }
168
- }
169
- function updateChartData(newRate) {
170
- // 一人モードの時の処理
171
- if (members.length === 1) {
172
- if (count_voice === 0) {
173
- speechChart.data.datasets[0].data = [newRate, 100 - newRate];
174
- before_rate = [newRate];
175
- } else {
176
- // 一人モードでは、過去のデータと現在のデータを加重平均する
177
- let tmp_rate = (newRate + before_rate[0] * count_voice) / (count_voice + 1);
178
- speechChart.data.datasets[0].data = [tmp_rate, 100 - tmp_rate];
179
- before_rate = [tmp_rate];
180
- }
181
- count_voice++;
182
- // 一人モードでは常に緑色とグレーの組み合わせを使用
183
- speechChart.data.labels = [members[0], "無音"];
184
- speechChart.data.datasets[0].backgroundColor = ["#4caf50", "#757575"];
185
- } else {
186
- console.log(before_rate)
187
- // 複数人モードの処理
188
- if (!Array.isArray(newRate)) {
189
- console.error("newRate is not an array:", newRate);
190
- return;
191
- }
192
- if (newRate.length !== members.length) {
193
- console.error(
194
- "newRate length does not match members length:",
195
- newRate,
196
- members
197
- );
198
- return;
199
- }
200
- let averagedRates = new Array(newRate.length);
201
- for (let i = 0; i < newRate.length; i++) {
202
- let tmp_rate;
203
- if (count_voice === 0) {
204
- // 初回はそのまま
205
- tmp_rate = newRate[i];
206
- } else {
207
- // 2回目以降は、過去の平均値と現在の値を加重平均する
208
- tmp_rate = (newRate[i] + before_rate[i] * count_voice) / (count_voice + 1);
209
- }
210
- averagedRates[i] = tmp_rate;
211
- }
212
- // before_rateを更新
213
- before_rate = averagedRates;
214
- //グラフに反映
215
- speechChart.data.datasets[0].data = averagedRates;
216
- count_voice++;
217
- speechChart.data.datasets[0].backgroundColor = getMemberColors(
218
- members.length
219
- );
220
- }
221
- speechChart.update();
222
  }
 
1
+
2
+ let isRecording = false;
3
+ let mediaRecorder;
4
+ let audioChunks = [];
5
+ let recordingInterval;
6
+ let count_voice = 0;
7
+ let before_rate = [];
8
+ const RECORDING_INTERVAL_MS = 5000; // 5秒
9
+ // メンバーとチャートの初期化
10
+ let members = [];
11
+ let voiceData = [];
12
+ let baseMemberColors = ["#4caf50", "#007bff", "#ffc107", "#dc3545", "#28a745", "#9c27b0", "#ff9800"];
13
+ // Chart.js の初期化
14
+ const ctx = document.getElementById("speechChart").getContext("2d");
15
+ const speechChart = new Chart(ctx, {
16
+ type: "doughnut",
17
+ data: {
18
+ labels: members,
19
+ datasets: [
20
+ {
21
+ data: voiceData,
22
+ backgroundColor: getMemberColors(members.length),
23
+ },
24
+ ],
25
+ },
26
+ options: {
27
+ responsive: true,
28
+ plugins: {
29
+ legend: {
30
+ display: true,
31
+ position: "bottom",
32
+ labels: { color: "white" },
33
+ },
34
+ },
35
+ },
36
+ });
37
+ // サーバーからメンバー情報を取得してチャートを更新する関数
38
+ async function updateChartFrom() {
39
+ try {
40
+ const response = await fetch("/confirm");
41
+ if (!response.ok) {
42
+ throw new Error(`HTTP error! status: ${response.status}`);
43
+ }
44
+ const data = await response.json();
45
+ if (!data || !data.members || !Array.isArray(data.members)) {
46
+ console.error("Invalid member data received:", data);
47
+ members = ["member1"];
48
+ voiceData = [50, 50];
49
+ updateChart();
50
+ return;
51
+ }
52
+ members = data.members;
53
+ voiceData = [];
54
+ for (let i = 0; i < members.length; i++) {
55
+ voiceData.push(100 / members.length);
56
+ }
57
+ updateChart();
58
+ } catch (error) {
59
+ console.error("Failed to fetch member data:", error);
60
+ members = ["member1"];
61
+ voiceData = [50, 50];
62
+ updateChart();
63
+ }
64
+ }
65
+ function updateChart() {
66
+ // 一人モードの場合は、ユーザーとグレー(無音)の比率をチャートに表示
67
+ if (members.length === 1) {
68
+ const userName = members[0];
69
+ speechChart.data.labels = [userName, "無音"];
70
+ speechChart.data.datasets[0].backgroundColor = ["#4caf50", "#757575"];
71
+ } else {
72
+ // 複数メンバーの場合は通常通りの処理
73
+ speechChart.data.labels = members;
74
+ speechChart.data.datasets[0].backgroundColor = getMemberColors(members.length);
75
+ }
76
+ speechChart.data.datasets[0].data = voiceData;
77
+ speechChart.update();
78
+ }
79
+
80
+ // ページ読み込み時にチャート情報を更新
81
+ updateChartFrom();
82
+ // 録音ボタンの録音開始/停止処理
83
+ async function toggleRecording() {
84
+ const recordButton = document.getElementById("recordButton");
85
+ if (!isRecording) {
86
+ // 録音開始
87
+ isRecording = true;
88
+ recordButton.classList.add("recording");
89
+ try {
90
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
91
+ mediaRecorder = new MediaRecorder(stream);
92
+ audioChunks = [];
93
+ mediaRecorder.ondataavailable = (event) => {
94
+ if (event.data.size > 0) {
95
+ audioChunks.push(event.data);
96
+ }
97
+ };
98
+ mediaRecorder.onstop = () => {
99
+ sendAudioChunks([...audioChunks]);
100
+ audioChunks = [];
101
+ };
102
+ mediaRecorder.start();
103
+ // 5秒ごとに録音を停止して送信するインターバルを設定
104
+ recordingInterval = setInterval(() => {
105
+ if (mediaRecorder && mediaRecorder.state === "recording") {
106
+ mediaRecorder.stop();
107
+ mediaRecorder.start();
108
+ }
109
+ }, RECORDING_INTERVAL_MS);
110
+ } catch (error) {
111
+ console.error("マイクへのアクセスに失敗しました:", error);
112
+ isRecording = false;
113
+ recordButton.classList.remove("recording");
114
+ }
115
+ } else {
116
+ // 録音停止
117
+ isRecording = false;
118
+ recordButton.classList.remove("recording");
119
+ if (mediaRecorder && mediaRecorder.state === "recording") {
120
+ mediaRecorder.stop();
121
+ }
122
+ clearInterval(recordingInterval);
123
+ count_voice = 0;
124
+ //before_rate = [];
125
+ }
126
+ }
127
+ function sendAudioChunks(chunks) {
128
+ const audioBlob = new Blob(chunks, { type: "audio/wav" });
129
+ const reader = new FileReader();
130
+ reader.onloadend = () => {
131
+ const base64String = reader.result.split(",")[1];
132
+ const form = document.getElementById("recordForm");
133
+ const nameInput = form.querySelector('input[name="name"]');
134
+ const name = nameInput ? nameInput.value : "unknown";
135
+ fetch("/upload_audio", {
136
+ method: "POST",
137
+ headers: { "Content-Type": "application/json" },
138
+ body: JSON.stringify({ audio_data: base64String, name: name }),
139
+ })
140
+ .then((response) => response.json())
141
+ .then((data) => {
142
+ if (data.error) {
143
+ alert("エラー: " + data.error);
144
+ console.error(data.details);
145
+ } else if (data.rate !== undefined) {
146
+ updateChartData(data.rate);
147
+ } else if (data.rates !== undefined) {
148
+ updateChartData(data.rates);
149
+ }
150
+ })
151
+ .catch((error) => {
152
+ console.error("エラー:", error);
153
+ });
154
+ };
155
+ reader.readAsDataURL(audioBlob);
156
+ }
157
+ function getMemberColors(memberCount) {
158
+ // 一人モードの場合は特別な処理をしない(updateChartで処理するため)
159
+ if (memberCount <= 1) {
160
+ return ["#4caf50", "#757575"];
161
+ } else {
162
+ let colors = [];
163
+ for (let i = 0; i < memberCount; i++) {
164
+ colors.push(baseMemberColors[i % baseMemberColors.length]);
165
+ }
166
+ return colors;
167
+ }
168
+ }
169
+ function updateChartData(newRate) {
170
+ // 一人モードの時の処理
171
+ if (members.length === 1) {
172
+ if (count_voice === 0) {
173
+ speechChart.data.datasets[0].data = [newRate, 100 - newRate];
174
+ before_rate = [newRate];
175
+ } else {
176
+ // 一人モードでは、過去のデータと現在のデータを加重平均する
177
+ let tmp_rate = (newRate + before_rate[0] * count_voice) / (count_voice + 1);
178
+ speechChart.data.datasets[0].data = [tmp_rate, 100 - tmp_rate];
179
+ before_rate = [tmp_rate];
180
+ }
181
+ count_voice++;
182
+ // 一人モードでは常に緑色とグレーの組み合わせを使用
183
+ speechChart.data.labels = [members[0], "無音"];
184
+ speechChart.data.datasets[0].backgroundColor = ["#4caf50", "#757575"];
185
+ } else {
186
+ console.log(before_rate)
187
+ // 複数人モードの処理
188
+ if (!Array.isArray(newRate)) {
189
+ console.error("newRate is not an array:", newRate);
190
+ return;
191
+ }
192
+ if (newRate.length !== members.length) {
193
+ console.error(
194
+ "newRate length does not match members length:",
195
+ newRate,
196
+ members
197
+ );
198
+ return;
199
+ }
200
+ let averagedRates = new Array(newRate.length);
201
+ for (let i = 0; i < newRate.length; i++) {
202
+ let tmp_rate;
203
+ if (count_voice === 0) {
204
+ // 初回はそのまま
205
+ tmp_rate = newRate[i];
206
+ } else {
207
+ // 2回目以降は、過去の平均値と現在の値を加重平均する
208
+ tmp_rate = (newRate[i] + before_rate[i] * count_voice) / (count_voice + 1);
209
+ }
210
+ averagedRates[i] = tmp_rate;
211
+ }
212
+ // before_rateを更新
213
+ before_rate = averagedRates;
214
+ //グラフに反映
215
+ speechChart.data.datasets[0].data = averagedRates;
216
+ count_voice++;
217
+ speechChart.data.datasets[0].backgroundColor = getMemberColors(
218
+ members.length
219
+ );
220
+ }
221
+ speechChart.update();
222
  }
static/register_record.js CHANGED
@@ -63,8 +63,9 @@ function sendAudioChunks(chunks, button) {
63
  const reader = new FileReader();
64
  reader.onloadend = () => {
65
  const base64String = reader.result.split(",")[1]; // Base64エンコードされた音声データ
66
- const form = button.closest("form");
67
- const nameInput = form.querySelector('input[name="name"]');
 
68
  const name = nameInput ? nameInput.value : "unknown"; // 名前がない
69
  fetch("/upload_base_audio", {
70
  method: "POST",
@@ -96,29 +97,54 @@ function sendAudioChunks(chunks, button) {
96
  reader.readAsDataURL(audioBlob);
97
  }
98
 
99
- document.getElementById("add-btn").addEventListener("click", () => {
100
- const newItem = document.createElement("div");
101
- newItem.className = "flex items-center gap-3 flex-wrap";
102
- newItem.innerHTML = `
103
- <form
104
- action="/submit"
105
- method="POST"
106
- class="flex items-center space-x-2 w-full sm:w-auto"
107
- onsubmit="event.preventDefault();"
108
- >
109
- <input
110
- type="text"
111
- name="name"
112
- placeholder="名前を入力"
113
- class="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-gray-700 text-white"
114
- />
115
-
116
- <button type="button" class="record-button" aria-label="音声録音開始">
117
- <div class="record-icon"></div>
118
- </button>
119
- </form>
120
- `;
121
- newItem.addEventListener("click", handleRecording);
122
- document.getElementById("people-list").appendChild(newItem);
123
- userCount++; // 新しいメンバーを追加するたびにカウントを増やす
124
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  const reader = new FileReader();
64
  reader.onloadend = () => {
65
  const base64String = reader.result.split(",")[1]; // Base64エンコードされた音声データ
66
+ // フォームの取得方法を変更
67
+ const form = button.closest(".user-item")?.querySelector("form")
68
+ const nameInput = form?.querySelector('input[name="name"]');
69
  const name = nameInput ? nameInput.value : "unknown"; // 名前がない
70
  fetch("/upload_base_audio", {
71
  method: "POST",
 
97
  reader.readAsDataURL(audioBlob);
98
  }
99
 
100
+ // 前の画面に戻る
101
+ function goBack() {
102
+ window.history.back();
103
+ }
104
+
105
+ // Add user function
106
+ function addUser() {
107
+ const userName = prompt("ユーザー名を入力してください");
108
+ if (userName) {
109
+ const userList = document.getElementById("people-list");
110
+ const userDiv = document.createElement("div");
111
+ userDiv.classList.add(
112
+ "user-item", // 追加
113
+ "bg-gray-700",
114
+ "p-4",
115
+ "rounded-lg",
116
+ "text-white",
117
+ "flex",
118
+ "justify-between",
119
+ "items-center",
120
+ "flex-wrap", // 追加
121
+ "gap-3" // 追加
122
+ );
123
+ userDiv.innerHTML = `
124
+ <form
125
+ action="/submit"
126
+ method="POST"
127
+ class="flex items-center space-x-2 w-full sm:w-auto"
128
+ onsubmit="event.preventDefault();"
129
+ >
130
+ <input
131
+ type="text"
132
+ name="name"
133
+ placeholder="名前を入力"
134
+ value="${userName}"
135
+ class="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-gray-700 text-white"
136
+ />
137
+ <button type="button" class="record-button" aria-label="音声録音開始">
138
+ <div class="record-icon"></div>
139
+ </button>
140
+ </form>
141
+ `;
142
+ userDiv
143
+ .querySelector(".record-button")
144
+ .addEventListener("click", handleRecording);
145
+ userList.appendChild(userDiv);
146
+ userCount++;
147
+ }
148
+ }
149
+
150
+ document.getElementById("add-btn").addEventListener("click", addUser);
static/talk_detail.js CHANGED
@@ -13,14 +13,6 @@ async function displayTranscription() {
13
  if (!data || !data.transcription) {
14
  throw new Error("会話データが見つかりませんでした。");
15
  }
16
- /*
17
- const formattedText = conversations
18
-
19
- .map((conv) => `【${conv.speaker}】 ${conv.text}`)
20
- .join("\n");
21
- console.log("フォーマットテキスト:", formattedText);
22
- transcriptionElement.textContent = formattedText;
23
- */
24
 
25
  transcriptionElement.textContent = conversations;
26
  loader.style.display = "none";
 
13
  if (!data || !data.transcription) {
14
  throw new Error("会話データが見つかりませんでした。");
15
  }
 
 
 
 
 
 
 
 
16
 
17
  transcriptionElement.textContent = conversations;
18
  loader.style.display = "none";
templates/feedback.html CHANGED
@@ -146,14 +146,12 @@
146
  </button>
147
  </div>
148
  </div>
149
-
150
  <div class="loader" id="loader">
151
  <div class="one"></div>
152
  <div class="two"></div>
153
  <div class="three"></div>
154
  <div class="four"></div>
155
  </div>
156
-
157
  <!-- Feedback Details -->
158
  <div class="text-xl font-semibold mb-6" id="level">会話レベル:</div>
159
  <div class="text-lg mb-2" id="Harassment_bool">ハラスメントの有無:</div>
 
146
  </button>
147
  </div>
148
  </div>
 
149
  <div class="loader" id="loader">
150
  <div class="one"></div>
151
  <div class="two"></div>
152
  <div class="three"></div>
153
  <div class="four"></div>
154
  </div>
 
155
  <!-- Feedback Details -->
156
  <div class="text-xl font-semibold mb-6" id="level">会話レベル:</div>
157
  <div class="text-lg mb-2" id="Harassment_bool">ハラスメントの有無:</div>
templates/index.html CHANGED
@@ -1,228 +1,228 @@
1
- <!DOCTYPE html>
2
- <html lang="ja">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>JustTalk - Voice Analysis</title>
7
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8
- <script src="https://cdn.tailwindcss.com"></script>
9
- <link
10
- rel="stylesheet"
11
- href="https://use.fontawesome.com/releases/v5.10.0/css/all.css"
12
- />
13
- <style>
14
- /* Custom Chart.js Styles */
15
- #speechChart {
16
- background-color: rgba(255, 255, 255, 0.05);
17
- border-radius: 10px;
18
- padding: 10px;
19
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
20
- }
21
-
22
- /* Record Button Styles */
23
- .record-button {
24
- width: 90px;
25
- height: 90px;
26
- background-color: transparent;
27
- border-radius: 50%;
28
- border: 5px solid white;
29
- display: flex;
30
- justify-content: center;
31
- align-items: center;
32
- cursor: pointer;
33
- box-shadow: 0 6px 10px rgba(0, 0, 0, 0.5);
34
- transition: all 0.2s ease;
35
- }
36
-
37
- .record-icon {
38
- width: 70px;
39
- height: 70px;
40
- background-color: #e53e3e;
41
- border-radius: 50%;
42
- transition: all 0.2s ease;
43
- }
44
-
45
- .recording .record-icon {
46
- width: 50px;
47
- height: 50px;
48
- border-radius: 15%;
49
- background-color: #c53030;
50
- }
51
-
52
- .icon i {
53
- font-size: 24px;
54
- }
55
-
56
- /* Hamburger Menu Styles */
57
- #menu {
58
- position: absolute;
59
- top: 0;
60
- left: 0;
61
- z-index: 10;
62
- transform: translateX(-100%);
63
- visibility: hidden;
64
- opacity: 0;
65
- background-color: rgb(31, 41, 55);
66
- transition: transform 0.3s ease-in-out, visibility 0s 0.3s,
67
- opacity 0.3s ease-in-out;
68
- backdrop-filter: blur(10px);
69
- border-right: 1px solid rgba(255, 255, 255, 0.2);
70
- }
71
-
72
- #menu.open {
73
- transform: translateX(0);
74
- visibility: visible;
75
- opacity: 1;
76
- transition: transform 0.3s ease-in-out, visibility 0s 0s,
77
- opacity 0.3s ease-in-out;
78
- }
79
-
80
- #menu button {
81
- transition: background-color 0.2s ease;
82
- background-color: rgba(0, 0, 0, 0.1); /* 変更点: 透明度を 10% に変更 */
83
- margin: 2px;
84
- border-radius: 5px;
85
- display: flex;
86
- align-items: center;
87
- justify-content: flex-start;
88
- gap: 10px;
89
- padding: 0.75rem 1rem;
90
- width: 100%;
91
- text-align: left;
92
- border: none;
93
- color: #fff;
94
- font-size: 1rem;
95
- cursor: pointer;
96
- }
97
-
98
- #menu button:hover {
99
- background-color: rgba(55, 65, 81, 0.7);
100
- }
101
-
102
- /* Responsive Design */
103
- @media (max-width: 640px) {
104
- .w-72 {
105
- width: 95%;
106
- }
107
- .h-72 {
108
- height: 350px;
109
- }
110
- }
111
- /* Main Container */
112
- body {
113
- background: linear-gradient(135deg, #2c3e50, #1f2937);
114
- display: flex;
115
- align-items: center;
116
- justify-content: center;
117
- min-height: 100vh;
118
- font-family: "Arial", sans-serif;
119
- }
120
-
121
- /* Main Content Wrapper */
122
- .main-content {
123
- border: 5px solid rgba(255, 255, 255, 0.2);
124
- padding: 2rem;
125
- border-radius: 1rem;
126
- width: 90%;
127
- max-width: 500px;
128
- background-color: rgba(0, 0, 0, 0.3);
129
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.4);
130
- text-align: center;
131
- }
132
-
133
- /* Title */
134
- .main-title {
135
- font-size: 2.5rem;
136
- font-weight: bold;
137
- margin-bottom: 1.5rem;
138
- color: #fff;
139
- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
140
- }
141
-
142
- /* Hamburger Menu Button */
143
- #menuButton {
144
- background-color: rgba(255, 255, 255, 0.1);
145
- border: none;
146
- border-radius: 50%;
147
- padding: 0.5rem;
148
- cursor: pointer;
149
- transition: background-color 0.2s ease;
150
- }
151
-
152
- #menuButton:hover {
153
- background-color: rgba(255, 255, 255, 0.2);
154
- }
155
- </style>
156
- </head>
157
- <body onclick="closeMenu(event)">
158
- <!-- Main Content Wrapper -->
159
- <div class="main-content relative">
160
- <!-- Title -->
161
- <div class="main-title">JustTalk</div>
162
-
163
- <!-- Hamburger Menu -->
164
- <div class="absolute top-4 left-4">
165
- <button
166
- id="menuButton"
167
- class="text-white text-2xl focus:outline-none"
168
- onclick="toggleMenu(event)"
169
- >
170
- <i class="fas fa-bars"></i>
171
- </button>
172
-
173
- <!-- Menu Content -->
174
- <div
175
- id="menu"
176
- class="absolute top-0 left-0 h-full w-64 bg-gray-800 text-white transform -translate-x-full transition-transform duration-300 ease-in-out opacity-0 visibility-hidden"
177
- >
178
- <div class="px-4 py-2 text-lg font-semibold">メニュー</div>
179
- <button onclick="showUserRegister()">
180
- <i class="fas fa-user-plus"></i> メン���ーを追加
181
- </button>
182
- <button onclick="showRecorder()">
183
- <i class="fas fa-microphone"></i> 録音画面を表示
184
- </button>
185
- <button onclick="showResults()">
186
- <i class="fas fa-chart-bar"></i> フィードバックを表示
187
- </button>
188
- <button onclick="showTalkDetail()">
189
- <i class="fas fa-comments"></i> 会話詳細を表示
190
- </button>
191
- <button onclick="resetAction()">
192
- <i class="fas fa-redo"></i> リセット
193
- </button>
194
- <button onclick="toggleMenu(event)">
195
- <i class="fas fa-times"></i> 閉じる
196
- </button>
197
- </div>
198
- </div>
199
-
200
- <!-- Chart Display -->
201
- <div class="chart w-72 h-72 mb-5 mx-auto">
202
- <canvas id="speechChart"></canvas>
203
- </div>
204
-
205
- <!-- Record Form -->
206
- <form
207
- id="recordForm"
208
- action="/submit"
209
- method="POST"
210
- class="flex items-center justify-center space-x-2 w-full sm:w-auto"
211
- onsubmit="event.preventDefault();"
212
- >
213
- <!-- Record Button -->
214
- <button
215
- type="button"
216
- class="record-button"
217
- id="recordButton"
218
- onclick="toggleRecording()"
219
- >
220
- <div class="record-icon" id="recordIcon"></div>
221
- </button>
222
- </form>
223
- </div>
224
-
225
- <script src="{{ url_for('static', filename='process.js') }}"></script>
226
- <script src="{{ url_for('static', filename='menu.js') }}"></script>
227
- </body>
228
- </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>JustTalk - Voice Analysis</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <link
10
+ rel="stylesheet"
11
+ href="https://use.fontawesome.com/releases/v5.10.0/css/all.css"
12
+ />
13
+ <style>
14
+ /* Custom Chart.js Styles */
15
+ #speechChart {
16
+ background-color: rgba(255, 255, 255, 0.05);
17
+ border-radius: 10px;
18
+ padding: 10px;
19
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
20
+ }
21
+
22
+ /* Record Button Styles */
23
+ .record-button {
24
+ width: 90px;
25
+ height: 90px;
26
+ background-color: transparent;
27
+ border-radius: 50%;
28
+ border: 5px solid white;
29
+ display: flex;
30
+ justify-content: center;
31
+ align-items: center;
32
+ cursor: pointer;
33
+ box-shadow: 0 6px 10px rgba(0, 0, 0, 0.5);
34
+ transition: all 0.2s ease;
35
+ }
36
+
37
+ .record-icon {
38
+ width: 70px;
39
+ height: 70px;
40
+ background-color: #e53e3e;
41
+ border-radius: 50%;
42
+ transition: all 0.2s ease;
43
+ }
44
+
45
+ .recording .record-icon {
46
+ width: 50px;
47
+ height: 50px;
48
+ border-radius: 15%;
49
+ background-color: #c53030;
50
+ }
51
+
52
+ .icon i {
53
+ font-size: 24px;
54
+ }
55
+
56
+ /* Hamburger Menu Styles */
57
+ #menu {
58
+ position: absolute;
59
+ top: 0;
60
+ left: 0;
61
+ z-index: 10;
62
+ transform: translateX(-100%);
63
+ visibility: hidden;
64
+ opacity: 0;
65
+ background-color: rgb(31, 41, 55);
66
+ transition: transform 0.3s ease-in-out, visibility 0s 0.3s,
67
+ opacity 0.3s ease-in-out;
68
+ backdrop-filter: blur(10px);
69
+ border-right: 1px solid rgba(255, 255, 255, 0.2);
70
+ }
71
+
72
+ #menu.open {
73
+ transform: translateX(0);
74
+ visibility: visible;
75
+ opacity: 1;
76
+ transition: transform 0.3s ease-in-out, visibility 0s 0s,
77
+ opacity 0.3s ease-in-out;
78
+ }
79
+
80
+ #menu button {
81
+ transition: background-color 0.2s ease;
82
+ background-color: rgba(0, 0, 0, 0.1); /* 変更点: 透明度を 10% に変更 */
83
+ margin: 2px;
84
+ border-radius: 5px;
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: flex-start;
88
+ gap: 10px;
89
+ padding: 0.75rem 1rem;
90
+ width: 100%;
91
+ text-align: left;
92
+ border: none;
93
+ color: #fff;
94
+ font-size: 1rem;
95
+ cursor: pointer;
96
+ }
97
+
98
+ #menu button:hover {
99
+ background-color: rgba(55, 65, 81, 0.7);
100
+ }
101
+
102
+ /* Responsive Design */
103
+ @media (max-width: 640px) {
104
+ .w-72 {
105
+ width: 95%;
106
+ }
107
+ .h-72 {
108
+ height: 350px;
109
+ }
110
+ }
111
+ /* Main Container */
112
+ body {
113
+ background: linear-gradient(135deg, #2c3e50, #1f2937);
114
+ display: flex;
115
+ align-items: center;
116
+ justify-content: center;
117
+ min-height: 100vh;
118
+ font-family: "Arial", sans-serif;
119
+ }
120
+
121
+ /* Main Content Wrapper */
122
+ .main-content {
123
+ border: 5px solid rgba(255, 255, 255, 0.2);
124
+ padding: 2rem;
125
+ border-radius: 1rem;
126
+ width: 90%;
127
+ max-width: 500px;
128
+ background-color: rgba(0, 0, 0, 0.3);
129
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.4);
130
+ text-align: center;
131
+ }
132
+
133
+ /* Title */
134
+ .main-title {
135
+ font-size: 2.5rem;
136
+ font-weight: bold;
137
+ margin-bottom: 1.5rem;
138
+ color: #fff;
139
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
140
+ }
141
+
142
+ /* Hamburger Menu Button */
143
+ #menuButton {
144
+ background-color: rgba(255, 255, 255, 0.1);
145
+ border: none;
146
+ border-radius: 50%;
147
+ padding: 0.5rem;
148
+ cursor: pointer;
149
+ transition: background-color 0.2s ease;
150
+ }
151
+
152
+ #menuButton:hover {
153
+ background-color: rgba(255, 255, 255, 0.2);
154
+ }
155
+ </style>
156
+ </head>
157
+ <body onclick="closeMenu(event)">
158
+ <!-- Main Content Wrapper -->
159
+ <div class="main-content relative">
160
+ <!-- Title -->
161
+ <div class="main-title">JustTalk</div>
162
+
163
+ <!-- Hamburger Menu -->
164
+ <div class="absolute top-4 left-4">
165
+ <button
166
+ id="menuButton"
167
+ class="text-white text-2xl focus:outline-none"
168
+ onclick="toggleMenu(event)"
169
+ >
170
+ <i class="fas fa-bars"></i>
171
+ </button>
172
+
173
+ <!-- Menu Content -->
174
+ <div
175
+ id="menu"
176
+ class="absolute top-0 left-0 h-full w-64 bg-gray-800 text-white transform -translate-x-full transition-transform duration-300 ease-in-out opacity-0 visibility-hidden"
177
+ >
178
+ <div class="px-4 py-2 text-lg font-semibold">メニュー</div>
179
+ <button onclick="showUserRegister()">
180
+ <i class="fas fa-user-plus"></i> メンバーを追加
181
+ </button>
182
+ <button onclick="showRecorder()">
183
+ <i class="fas fa-microphone"></i> 録音画面を表示
184
+ </button>
185
+ <button onclick="showResults()">
186
+ <i class="fas fa-chart-bar"></i> フィードバックを表示
187
+ </button>
188
+ <button onclick="showTalkDetail()">
189
+ <i class="fas fa-comments"></i> 会話詳細を表示
190
+ </button>
191
+ <button onclick="resetAction()">
192
+ <i class="fas fa-redo"></i> リセット
193
+ </button>
194
+ <button onclick="toggleMenu(event)">
195
+ <i class="fas fa-times"></i> 閉じる
196
+ </button>
197
+ </div>
198
+ </div>
199
+
200
+ <!-- Chart Display -->
201
+ <div class="chart w-72 h-72 mb-5 mx-auto">
202
+ <canvas id="speechChart"></canvas>
203
+ </div>
204
+
205
+ <!-- Record Form -->
206
+ <form
207
+ id="recordForm"
208
+ action="/submit"
209
+ method="POST"
210
+ class="flex items-center justify-center space-x-2 w-full sm:w-auto"
211
+ onsubmit="event.preventDefault();"
212
+ >
213
+ <!-- Record Button -->
214
+ <button
215
+ type="button"
216
+ class="record-button"
217
+ id="recordButton"
218
+ onclick="toggleRecording()"
219
+ >
220
+ <div class="record-icon" id="recordIcon"></div>
221
+ </button>
222
+ </form>
223
+ </div>
224
+
225
+ <script src="{{ url_for('static', filename='process.js') }}"></script>
226
+ <script src="{{ url_for('static', filename='menu.js') }}"></script>
227
+ </body>
228
+ </html>
templates/talkDetail.html CHANGED
@@ -1,49 +1,49 @@
1
- <!DOCTYPE html>
2
- <html lang="ja" class="dark">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>会話詳細画面</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <link
9
- rel="stylesheet"
10
- href="{{ url_for('static', filename='loading.css') }}"
11
- />
12
- </head>
13
- <body
14
- class="bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100 min-h-screen flex items-center justify-center"
15
- >
16
- <div class="loader" id="loader">
17
- <div class="one"></div>
18
- <div class="two"></div>
19
- <div class="three"></div>
20
- <div class="four"></div>
21
- </div>
22
- <div
23
- class="container mx-auto p-6 bg-white dark:bg-gray-800 shadow-lg rounded-2xl"
24
- >
25
- <h2 class="text-2xl font-semibold mb-4">会話の文字起こし表示</h2>
26
- <div
27
- id="transcription"
28
- class="p-4 bg-gray-200 dark:bg-gray-700 rounded-lg mb-4 max-h-96 overflow-y-auto"
29
- >
30
- ここに会話内容が表示されます。
31
- </div>
32
- <div class="flex justify-center gap-4">
33
- <button
34
- class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
35
- onclick="showRecorder()"
36
- >
37
- 録音画面を表示
38
- </button>
39
- <button
40
- class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
41
- onclick="showFeedback()"
42
- >
43
- フィードバック画面を表示
44
- </button>
45
- </div>
46
- </div>
47
- <script src="{{ url_for('static', filename='talk_detail.js') }}"></script>
48
- </body>
49
- </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="ja" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>会話詳細画面</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link
9
+ rel="stylesheet"
10
+ href="{{ url_for('static', filename='loading.css') }}"
11
+ />
12
+ </head>
13
+ <body
14
+ class="bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100 min-h-screen flex items-center justify-center"
15
+ >
16
+ <div class="loader" id="loader">
17
+ <div class="one"></div>
18
+ <div class="two"></div>
19
+ <div class="three"></div>
20
+ <div class="four"></div>
21
+ </div>
22
+ <div
23
+ class="container mx-auto p-6 bg-white dark:bg-gray-800 shadow-lg rounded-2xl"
24
+ >
25
+ <h2 class="text-2xl font-semibold mb-4">会話の文字起こし表示</h2>
26
+ <div
27
+ id="transcription"
28
+ class="p-4 bg-gray-200 dark:bg-gray-700 rounded-lg mb-4 max-h-96 overflow-y-auto"
29
+ >
30
+ ここに会話内容が表示されます。
31
+ </div>
32
+ <div class="flex justify-center gap-4">
33
+ <button
34
+ class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
35
+ onclick="showRecorder()"
36
+ >
37
+ 録音画面を表示
38
+ </button>
39
+ <button
40
+ class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
41
+ onclick="showFeedback()"
42
+ >
43
+ フィードバック画面を表示
44
+ </button>
45
+ </div>
46
+ </div>
47
+ <script src="{{ url_for('static', filename='talk_detail.js') }}"></script>
48
+ </body>
49
+ </html>
templates/userRegister.html CHANGED
@@ -4,6 +4,7 @@
4
  <meta charset="UTF-8" />
5
  <title>ユーザー音声登録</title>
6
  <script src="https://cdn.tailwindcss.com"></script>
 
7
  <style>
8
  @keyframes pulse-scale {
9
  0%,
@@ -17,6 +18,8 @@
17
  .animate-pulse-scale {
18
  animation: pulse-scale 1s infinite;
19
  }
 
 
20
  .record-button {
21
  width: 50px;
22
  height: 50px;
@@ -38,6 +41,7 @@
38
  transition: all 0.3s ease;
39
  }
40
  .record-button.recording .record-icon {
 
41
  border-radius: 4px; /* 録音時に赤い部分だけ四角にする */
42
  }
43
  .recording .record-icon {
@@ -45,46 +49,103 @@
45
  height: 20px;
46
  border-radius: 50%;
47
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  @media (max-width: 640px) {
49
- .container {
50
- padding: 2rem;
51
  }
52
  }
53
  </style>
54
  </head>
55
- <body
56
- class="bg-gray-800 text-gray-100 dark:bg-gray-900 dark:text-gray-300 transition-colors"
57
- >
58
- <div class="container mx-auto p-5 max-w-full sm:max-w-2xl">
 
 
 
59
  <div id="people-list" class="space-y-4"></div>
60
- <button
61
- id="add-btn"
62
- class="mt-6 px-6 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors"
63
- >
64
- メンバーを追加
65
  </button>
66
 
67
- <!-- 録音画面に戻るボタン -->
68
  <button
69
  id="backButton"
70
- onclick="showRecorder()"
71
- class="mt-6 px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
72
  >
73
- 録音画面に戻る
74
  </button>
75
  </div>
76
 
77
  <script src="{{ url_for('static', filename='register_record.js') }}"></script>
78
- <script>
79
- function showRecorder() {
80
- // 録音画面へ遷移
81
- window.location.href = "index";
82
- }
83
- </script>
84
- <script>
85
-
86
-
87
 
88
- </script>
89
  </body>
90
  </html>
 
4
  <meta charset="UTF-8" />
5
  <title>ユーザー音声登録</title>
6
  <script src="https://cdn.tailwindcss.com"></script>
7
+ <script src="https://use.fontawesome.com/releases/v5.10.0/js/all.js"></script>
8
  <style>
9
  @keyframes pulse-scale {
10
  0%,
 
18
  .animate-pulse-scale {
19
  animation: pulse-scale 1s infinite;
20
  }
21
+
22
+ /* Record Button Styles */
23
  .record-button {
24
  width: 50px;
25
  height: 50px;
 
41
  transition: all 0.3s ease;
42
  }
43
  .record-button.recording .record-icon {
44
+ background-color: #f44336; /* 録音中は赤色 */
45
  border-radius: 4px; /* 録音時に赤い部分だけ四角にする */
46
  }
47
  .recording .record-icon {
 
49
  height: 20px;
50
  border-radius: 50%;
51
  }
52
+
53
+ /* Main Container */
54
+ body {
55
+ background: linear-gradient(135deg, #2c3e50, #1f2937);
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ min-height: 100vh;
60
+ font-family: "Arial", sans-serif;
61
+ }
62
+
63
+ /* Main Content Wrapper */
64
+ .main-content {
65
+ border: 5px solid rgba(255, 255, 255, 0.2);
66
+ padding: 2rem;
67
+ border-radius: 1rem;
68
+ width: 90%;
69
+ max-width: 500px;
70
+ background-color: rgba(0, 0, 0, 0.3);
71
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.4);
72
+ text-align: center;
73
+ }
74
+
75
+ /* Title */
76
+ .main-title {
77
+ font-size: 2.5rem;
78
+ font-weight: bold;
79
+ margin-bottom: 1.5rem;
80
+ color: #fff;
81
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
82
+ }
83
+
84
+ /* Buttons */
85
+ .action-button {
86
+ margin-top: 1rem;
87
+ padding: 0.75rem 1.5rem;
88
+ border-radius: 0.5rem;
89
+ cursor: pointer;
90
+ transition: background-color 0.2s ease;
91
+ width: 100%;
92
+ }
93
+
94
+ .action-button:hover {
95
+ background-color: rgba(55, 65, 81, 0.7);
96
+ }
97
+
98
+ .back-button {
99
+ background-color: #607d8b; /* 落ち着いたグレー */
100
+ color: white;
101
+ }
102
+
103
+ .add-button {
104
+ background-color: #4caf50; /* 落ち着いた緑色 */
105
+ color: white;
106
+ }
107
+
108
+ /* Disabled State */
109
+ .disabled {
110
+ opacity: 0.5;
111
+ pointer-events: none;
112
+ }
113
+
114
+ /* Responsive Design */
115
  @media (max-width: 640px) {
116
+ .main-content {
117
+ padding: 1.5rem;
118
  }
119
  }
120
  </style>
121
  </head>
122
+ <body>
123
+ <!-- Main Content Wrapper -->
124
+ <div class="main-content relative">
125
+ <!-- Title -->
126
+ <div class="main-title">ユーザー音声登録</div>
127
+
128
+ <!-- User List -->
129
  <div id="people-list" class="space-y-4"></div>
130
+
131
+ <!-- Add Button -->
132
+ <button id="add-btn" class="action-button add-button">
133
+ <i class="fas fa-user-plus"></i> メンバーを追加
 
134
  </button>
135
 
136
+ <!-- Back Button -->
137
  <button
138
  id="backButton"
139
+ onclick="goBack()"
140
+ class="action-button back-button"
141
  >
142
+ 戻る
143
  </button>
144
  </div>
145
 
146
  <script src="{{ url_for('static', filename='register_record.js') }}"></script>
147
+
 
 
 
 
 
 
 
 
148
 
149
+
150
  </body>
151
  </html>