Spaces:
Runtime error
Runtime error
Upload 15 files
Browse files- Dockerfile +21 -0
- package-lock.json +0 -0
- package.json +42 -0
- public/favicon.ico +0 -0
- public/index.html +12 -0
- public/logo192.png +0 -0
- public/logo512.png +0 -0
- public/manifest.json +25 -0
- public/robots.txt +3 -0
- src/App.js +8 -0
- src/index.css +3 -0
- src/index.js +11 -0
- src/pages/result.js +18 -0
- src/pages/translation.js +93 -0
- tailwind.config.js +11 -0
Dockerfile
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Stage 1: Build React App
|
2 |
+
FROM node:16.13.2
|
3 |
+
|
4 |
+
WORKDIR /app
|
5 |
+
|
6 |
+
# Copy package.json and package-lock.json
|
7 |
+
COPY package.json package-lock.json ./
|
8 |
+
|
9 |
+
# Install dependencies
|
10 |
+
RUN npm install --legacy-peer-deps
|
11 |
+
|
12 |
+
# Copy the entire project
|
13 |
+
COPY public/ .
|
14 |
+
COPY src/ .
|
15 |
+
COPY tailwind.config.js .
|
16 |
+
|
17 |
+
# Build the React app
|
18 |
+
RUN npm build
|
19 |
+
|
20 |
+
# Start Nginx server
|
21 |
+
CMD ["npm", "start"]
|
package-lock.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
package.json
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "fe-mesin-translasi",
|
3 |
+
"version": "0.1.0",
|
4 |
+
"private": true,
|
5 |
+
"dependencies": {
|
6 |
+
"@testing-library/jest-dom": "^5.16.5",
|
7 |
+
"@testing-library/react": "^13.4.0",
|
8 |
+
"@testing-library/user-event": "^13.5.0",
|
9 |
+
"axios": "^1.4.0",
|
10 |
+
"react": "^18.2.0",
|
11 |
+
"react-dom": "^18.2.0",
|
12 |
+
"react-scripts": "5.0.1",
|
13 |
+
"web-vitals": "^2.1.4"
|
14 |
+
},
|
15 |
+
"scripts": {
|
16 |
+
"start": "react-scripts start",
|
17 |
+
"build": "react-scripts build",
|
18 |
+
"test": "react-scripts test",
|
19 |
+
"eject": "react-scripts eject"
|
20 |
+
},
|
21 |
+
"eslintConfig": {
|
22 |
+
"extends": [
|
23 |
+
"react-app",
|
24 |
+
"react-app/jest"
|
25 |
+
]
|
26 |
+
},
|
27 |
+
"browserslist": {
|
28 |
+
"production": [
|
29 |
+
">0.2%",
|
30 |
+
"not dead",
|
31 |
+
"not op_mini all"
|
32 |
+
],
|
33 |
+
"development": [
|
34 |
+
"last 1 chrome version",
|
35 |
+
"last 1 firefox version",
|
36 |
+
"last 1 safari version"
|
37 |
+
]
|
38 |
+
},
|
39 |
+
"devDependencies": {
|
40 |
+
"tailwindcss": "^3.3.2"
|
41 |
+
}
|
42 |
+
}
|
public/favicon.ico
ADDED
public/index.html
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="utf-8" />
|
5 |
+
<link rel="icon" href="" />
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
7 |
+
<title>Translation with NLLB methods</title>
|
8 |
+
</head>
|
9 |
+
<body>
|
10 |
+
<div id="root"></div>
|
11 |
+
</body>
|
12 |
+
</html>
|
public/logo192.png
ADDED
public/logo512.png
ADDED
public/manifest.json
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"short_name": "React App",
|
3 |
+
"name": "Create React App Sample",
|
4 |
+
"icons": [
|
5 |
+
{
|
6 |
+
"src": "favicon.ico",
|
7 |
+
"sizes": "64x64 32x32 24x24 16x16",
|
8 |
+
"type": "image/x-icon"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"src": "logo192.png",
|
12 |
+
"type": "image/png",
|
13 |
+
"sizes": "192x192"
|
14 |
+
},
|
15 |
+
{
|
16 |
+
"src": "logo512.png",
|
17 |
+
"type": "image/png",
|
18 |
+
"sizes": "512x512"
|
19 |
+
}
|
20 |
+
],
|
21 |
+
"start_url": ".",
|
22 |
+
"display": "standalone",
|
23 |
+
"theme_color": "#000000",
|
24 |
+
"background_color": "#ffffff"
|
25 |
+
}
|
public/robots.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
# https://www.robotstxt.org/robotstxt.html
|
2 |
+
User-agent: *
|
3 |
+
Disallow:
|
src/App.js
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import React from 'react';
|
2 |
+
import MyComponent from './pages/translation';
|
3 |
+
|
4 |
+
function App() {
|
5 |
+
return <MyComponent />;
|
6 |
+
}
|
7 |
+
|
8 |
+
export default App;
|
src/index.css
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
@tailwind base;
|
2 |
+
@tailwind components;
|
3 |
+
@tailwind utilities;
|
src/index.js
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import React from 'react';
|
2 |
+
import ReactDOM from 'react-dom/client';
|
3 |
+
import './index.css';
|
4 |
+
import App from './App';
|
5 |
+
|
6 |
+
const root = ReactDOM.createRoot(document.getElementById('root'));
|
7 |
+
root.render(
|
8 |
+
<React.StrictMode>
|
9 |
+
<App />
|
10 |
+
</React.StrictMode>
|
11 |
+
);
|
src/pages/result.js
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import React from 'react';
|
2 |
+
|
3 |
+
const result = ({response, time}) => {
|
4 |
+
return(
|
5 |
+
<>
|
6 |
+
<div className="mb-4">
|
7 |
+
<label htmlFor="name" className="block mb-2 font-bold text-gray-800">Result:</label>
|
8 |
+
<textarea type="text" value={response} id="name" name="text" className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring focus:border-blue-500" readOnly>{response}</textarea>
|
9 |
+
</div>
|
10 |
+
|
11 |
+
<div className="mb-4">
|
12 |
+
<label htmlFor="name" className="block mb-2 font-bold text-gray-800">Inference Time:</label>
|
13 |
+
<input type="text" value={time} id="name" name="text" className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring focus:border-blue-500" readOnly/>
|
14 |
+
</div>
|
15 |
+
</>
|
16 |
+
);
|
17 |
+
}
|
18 |
+
export default result
|
src/pages/translation.js
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import React, { useState } from 'react';
|
2 |
+
import axios from 'axios';
|
3 |
+
import Result from './result';
|
4 |
+
|
5 |
+
const MyComponent = () => {
|
6 |
+
const [formData, setFormData] = useState({
|
7 |
+
from_lang: 'ind_Latn',
|
8 |
+
to_lang: 'bjn_Latn',
|
9 |
+
text: '',
|
10 |
+
});
|
11 |
+
|
12 |
+
const [responseMessage, setResponseMessage] = useState('');
|
13 |
+
const [responseMessage1, setResponseMessage1] = useState('');
|
14 |
+
const [responseSuccess, setResponseSuccess] = useState(0);
|
15 |
+
|
16 |
+
const handleSubmit = async (event) => {
|
17 |
+
event.preventDefault();
|
18 |
+
try {
|
19 |
+
const response = await axios.post('https://aziizpra-api-nllb-tugas-akhir.hf.space/predict', formData);
|
20 |
+
const responseData = response.data;
|
21 |
+
setResponseMessage(responseData.result);
|
22 |
+
setResponseMessage1(responseData.inference_time);
|
23 |
+
setResponseSuccess(1);
|
24 |
+
} catch (error) {
|
25 |
+
console.log(error);
|
26 |
+
}
|
27 |
+
};
|
28 |
+
|
29 |
+
const handleSwapLanguages = () => {
|
30 |
+
setFormData((prevFormData) => ({
|
31 |
+
...prevFormData,
|
32 |
+
from_lang: formData.to_lang,
|
33 |
+
to_lang: formData.from_lang,
|
34 |
+
}));
|
35 |
+
};
|
36 |
+
|
37 |
+
const handleChange = (event) => {
|
38 |
+
setFormData({ ...formData, [event.target.name]: event.target.value });
|
39 |
+
};
|
40 |
+
|
41 |
+
const getLanguageText = (lang) => {
|
42 |
+
if (lang === 'ind_Latn') {
|
43 |
+
return 'Indonesia';
|
44 |
+
} else if (lang === 'bjn_Latn') {
|
45 |
+
return 'Banjar';
|
46 |
+
} else {
|
47 |
+
return lang; // Menampilkan nilai lang jika tidak ada kecocokan
|
48 |
+
}
|
49 |
+
};
|
50 |
+
|
51 |
+
return (
|
52 |
+
<>
|
53 |
+
<div className="p-4">
|
54 |
+
<div className="bg-white rounded-lg shadow-lg">
|
55 |
+
<div className="p-6">
|
56 |
+
<div className="text-center">
|
57 |
+
<h2 className="text-xl font-bold mb-4">Machine Translation With No Language Left Behind Methods</h2>
|
58 |
+
</div>
|
59 |
+
<form onSubmit={handleSubmit}>
|
60 |
+
<div className="flex mb-4 items-center">
|
61 |
+
<div className="w-1/2 relative mr-2">
|
62 |
+
<label htmlFor="input1" className="block mb-2 font-bold text-gray-800">From Language:</label>
|
63 |
+
<input type="text" id="input1" name="from_lang" className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring focus:border-blue-500" value={getLanguageText(formData.from_lang)} readOnly onChange={handleChange} />
|
64 |
+
</div>
|
65 |
+
<button type="button" className="flex-shrink-0 bg-gray-600 rounded-full w-10 h-10 mt-8 flex items-center justify-center shadow" onClick={handleSwapLanguages}>
|
66 |
+
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
67 |
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 4l6 6m0 0l-6 6m6-6H4"></path>
|
68 |
+
</svg>
|
69 |
+
</button>
|
70 |
+
<div className="w-1/2 relative ml-2">
|
71 |
+
<label htmlFor="input2" className="block mb-2 font-bold text-gray-800">To Language:</label>
|
72 |
+
<input type="text" id="input2" name="to_lang" className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring focus:border-blue-500" value={getLanguageText(formData.to_lang)} readOnly onChange={handleChange} />
|
73 |
+
</div>
|
74 |
+
</div>
|
75 |
+
|
76 |
+
<div className="mb-4">
|
77 |
+
<label htmlFor="name" className="block mb-2 font-bold text-gray-800">Text:</label>
|
78 |
+
<input type="text" id="name" name="text" className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring focus:border-blue-500" maxLength={1024} placeholder="Enter your Text to Translate" onChange={handleChange} required/>
|
79 |
+
</div>
|
80 |
+
|
81 |
+
<div className="text-center">
|
82 |
+
<button type="submit" className="px-4 py-2 bg-blue-500 text-white font-semibold rounded-lg hover:bg-blue-600">Translate!</button>
|
83 |
+
</div>
|
84 |
+
</form>
|
85 |
+
{responseSuccess === 1 && <Result response={responseMessage} time={responseMessage1}/> }
|
86 |
+
</div>
|
87 |
+
</div>
|
88 |
+
</div>
|
89 |
+
</>
|
90 |
+
);
|
91 |
+
};
|
92 |
+
|
93 |
+
export default MyComponent;
|
tailwind.config.js
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @type {import('tailwindcss').Config} */
|
2 |
+
module.exports = {
|
3 |
+
content: [
|
4 |
+
"./src/**/*.{js,jsx,ts,tsx}",
|
5 |
+
],
|
6 |
+
theme: {
|
7 |
+
extend: {},
|
8 |
+
},
|
9 |
+
plugins: [],
|
10 |
+
}
|
11 |
+
|