## index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DeepL 번역 서비스</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
font-size: 16px;
height: 100vh;
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
padding: 20px;
box-sizing: border-box;
gap: 10px;
}
.text-box {
flex: 1;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
padding: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
textarea {
flex: 1;
border: none;
resize: none;
font-size: 1em;
width: 100%;
height: 100%;
font-family: inherit;
}
textarea:focus {
outline: none;
}
.progress-bar {
height: 4px;
background-color: #e0e0e0;
margin-top: 10px;
position: relative;
}
.progress {
height: 100%;
width: 0;
background-color: #5b9bff;
transition: width 0.3s ease;
}
.progress-text {
text-align: center;
font-size: 0.8em;
color: #333;
margin-top: 5px;
}
button {
margin-top: 10px;
padding: 10px 20px;
background-color: #1f3c71;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1em;
font-family: inherit;
}
button:hover {
background-color: #0a3474;
}
.button-disabled {
background-color: #cccccc;
cursor: not-allowed;
}
#statusMessage {
margin-top: 10px;
font-weight: bold;
text-align: center;
}
@media (min-width: 768px) {
.container {
flex-direction: row;
}
.text-box {
width: 50%;
}
}
</style>
</head>
<body>
<div class="container">
<div class="text-box">
<textarea id="input" placeholder="번역할 텍스트를 입력하세요"></textarea>
<button id="translateBtn">번역</button>
</div>
<div class="text-box">
<textarea id="output" readonly placeholder="번역 결과가 여기에 표시됩니다"></textarea>
<div class="progress-bar">
<div id="progress" class="progress"></div>
</div>
<div id="progressText" class="progress-text">준비 중...</div>
<div id="statusMessage"></div>
<div id="downloadLink" style="margin-top: 10px;"></div>
</div>
</div>
<script>
const translateBtn = document.getElementById('translateBtn');
const statusMessage = document.getElementById('statusMessage');
function updateProgress(status, percentage) {
const progress = document.getElementById('progress');
const progressText = document.getElementById('progressText');
progress.style.width = `${percentage}%`;
progressText.textContent = `${status} (${percentage}%)`;
statusMessage.textContent = status;
}
async function translate() {
const input = document.getElementById('input').value;
const output = document.getElementById('output');
translateBtn.disabled = true;
translateBtn.classList.add('button-disabled');
translateBtn.textContent = '번역 중...';
updateProgress('전처리 중', 10);
try {
const response = await fetch('/translate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ text: input }),
});
updateProgress('번역 중', 50);
const data = await response.json();
if (data.error) {
output.value = "오류 발생: " + data.error;
updateProgress('오류 발생', 100);
} else {
output.value = data.translatedText;
updateProgress('번역 완료', 100);
const downloadLink = document.getElementById('downloadLink');
downloadLink.innerHTML = `<a href="/download/${data.filename}" download>번역 결과 다운로드</a>`;
}
} catch (error) {
output.value = "오류 발생: " + error;
updateProgress('오류 발생', 100);
} finally {
translateBtn.disabled = false;
translateBtn.classList.remove('button-disabled');
translateBtn.textContent = '번역';
}
}
translateBtn.addEventListener('click', translate);
</script>
</body>
</html>
'1인 프로젝트 > 나만의 번역기(Local DeepL)' 카테고리의 다른 글
4차 백업(heroku를 이용한 배포) (0) | 2024.08.04 |
---|---|
이건 또 무슨 오류야... 산 넘어 산! (웹 서버에 대한 잘못된 요청) (0) | 2024.08.04 |
★ 2차 백업(Segoe UI 글꼴 적용) (0) | 2024.08.04 |
1차 백업 (0) | 2024.08.04 |
프로젝트 구조 및 서비스 구성 (0) | 2024.08.04 |