diff --git a/README.md b/README.md
index 7db80e4c..f28759f4 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# README
+# README Test
This README would normally document whatever steps are necessary to get the
application up and running.
diff --git a/app/javascript/react/src/components/PanelLocation.jsx b/app/javascript/react/src/components/PanelLocation.jsx
new file mode 100644
index 00000000..ad09a234
--- /dev/null
+++ b/app/javascript/react/src/components/PanelLocation.jsx
@@ -0,0 +1,75 @@
+import React, { useState, useEffect } from 'react';
+import { readLogFile, extractRobotPositionData } from "../logProcessorLocation"; // Importe suas funções
+
+const PanelLocation = () => {
+const [data, setData] = useState([{ x: 0, y: 0 }]);
+const [error, setError] = useState(""); // Estado para a mensagem de erro
+
+const stylePanel= {
+ color: 'black',
+ fontSize: '20px',
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: '#FFF',
+};
+
+const handleFileUpload = async (event) => {
+ const file = event.target.files[0];
+ const logData = await readLogFile(file);
+ const result = extractRobotPositionData(logData); // Use a função correta aqui
+ console.log(result);
+
+ if (result.status === "error") {
+ // Se houver um erro, definir a mensagem de erro
+ setError(result.message);
+ setData([]); // Limpar os dados existentes
+ } else {
+ // Caso contrário, atualizar os dados
+ setData(result.data);
+ setError(""); // Limpar a mensagem de erro
+ }
+};
+
+const escalaX = 4;// Ajuste as escalas para o tamanho desejado do plano cartesiano
+const escalaY = 4;// Ajuste as escalas para o tamanho desejado do plano cartesiano
+
+const [index, setIndex] = useState(0);
+
+useEffect(() => {
+ const intervalId = setInterval(() => {
+ setIndex((prevIndex) => (prevIndex === data.length - 1 ? 0 : prevIndex + 1));
+ }, 2000); // Ajuste o intervalo de tempo entre os pontos conforme necessário
+
+ return () => clearInterval(intervalId);
+}, [data.length]);
+
+const animatedProps = {
+ cx: data[index].x * escalaX + 400,
+ cy: -data[index].y * escalaY + 400,
+};
+
+return (
+
+
Panel Location
+
+ {error &&
{error}
}
+
+ x: {data[index].x}, y: {data[index].y}
+
+
+
+);
+};
+
+export default PanelLocation;
\ No newline at end of file
diff --git a/app/javascript/react/src/components/TableComponent.jsx b/app/javascript/react/src/components/TableComponent.jsx
new file mode 100644
index 00000000..0e3df3aa
--- /dev/null
+++ b/app/javascript/react/src/components/TableComponent.jsx
@@ -0,0 +1,53 @@
+import React, { useState } from "react";
+import { readLogFile, extractRobotPositionData } from "../logProcessor"; // Importe suas funções
+
+const TableComponent = () => {
+ const [data, setData] = useState([]); // Estado para os dados da tabela
+ const [error, setError] = useState(""); // Estado para a mensagem de erro
+
+ const handleFileUpload = async (event) => {
+ const file = event.target.files[0];
+ const logData = await readLogFile(file);
+ const result = extractRobotPositionData(logData); // Mudança para a função correta
+
+ if (result.status === "error") {
+ // Se houver um erro, definir a mensagem de erro
+ setError(result.message);
+ setData([]); // Limpar os dados existentes
+ } else {
+ // Caso contrário, atualizar os dados
+ setData(result.data);
+ setError(""); // Limpar a mensagem de erro
+ }
+ };
+
+ return (
+
+
Robot Position Table
+
+ {error &&
{error}
}
+
+
+
+ | Tempo |
+ X |
+ Y |
+ Yaw |
+
+
+
+ {data.map((row, index) => (
+
+ | {row.time} |
+ {row.x} |
+ {row.y} |
+ {row.yaw} |
+
+ ))}
+
+
+
+ );
+};
+
+export default TableComponent;
diff --git a/app/javascript/react/src/logProcessor.js b/app/javascript/react/src/logProcessor.js
new file mode 100644
index 00000000..b73b0194
--- /dev/null
+++ b/app/javascript/react/src/logProcessor.js
@@ -0,0 +1,44 @@
+export function readLogFile(file) {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = (event) => resolve(event.target.result);
+ reader.onerror = (error) => reject(error);
+ reader.readAsText(file);
+ });
+}
+
+export function extractRobotPositionData(logData) {
+ const positionData = [];
+ const logLines = logData.split("\n");
+ // Ajuste na expressão regular para capturar números ou strings nos campos x, y e yaw
+ const positionRegex =
+ /(\d+\.\d+), \[INFO\], robot6, {'y': ('[^']+'|[\d.-]+), 'x': ('[^']+'|[\d.-]+), 'yaw': ('[^']+'|[\d.-]+)}, None, None\s*/;
+
+ for (let line of logLines) {
+ const match = line.match(positionRegex);
+ if (match) {
+ const timeStr = match[1];
+ const yStr = match[2].replace(/'/g, ""); // Remove as aspas, se houver
+ const xStr = match[3].replace(/'/g, ""); // Remove as aspas, se houver
+ const yawStr = match[4].replace(/'/g, ""); // Remove as aspas, se houver
+
+ const time = parseFloat(timeStr);
+ const y = parseFloat(yStr);
+ const x = parseFloat(xStr);
+ const yaw = parseFloat(yawStr);
+
+ // Verifica se algum dos valores não é um número
+ if ([time, y, x, yaw].some((val) => isNaN(val))) {
+ return {
+ status: "error",
+ message:
+ "Erro: Entrada apresenta dados inválidos - valores não numéricos encontrados no log.",
+ };
+ }
+
+ positionData.push({ time, y, x, yaw });
+ }
+ }
+
+ return { status: "success", data: positionData };
+}
diff --git a/app/javascript/react/src/logProcessorLocation.js b/app/javascript/react/src/logProcessorLocation.js
new file mode 100644
index 00000000..d8e9f8c2
--- /dev/null
+++ b/app/javascript/react/src/logProcessorLocation.js
@@ -0,0 +1,27 @@
+export function readLogFile(file) {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = (event) => resolve(event.target.result);
+ reader.onerror = (error) => reject(error);
+ reader.readAsText(file);
+ });
+}
+
+export function extractRobotPositionData(logData) {
+ const positionData = [];
+ const logLines = logData.split("\n");
+ const positionRegex =
+ /(\d+\.\d+), \[INFO\], robot6, {'y': ([\d.-]+), 'x': ([\d.-]+), 'yaw': ([\d.-]+)}, None, None/;
+
+ for (let line of logLines) {
+ const match = line.match(positionRegex);
+ if (match) {
+ const y = parseFloat(match[2]);
+ const x = parseFloat(match[3]);
+
+ positionData.push({ x, y });
+ }
+ }
+
+ return { status: "success", data: positionData };
+}
\ No newline at end of file