Spaces:
Build error
Build error
<template> | |
<div id="app"> | |
<h1>YouTube RAG Explorer</h1> | |
<p>영상 URL과 찾고 싶은 내용을 입력해주세요.</p> | |
<div class="input-section"> | |
<label for="videoUrl">YouTube 영상 URL:</label> | |
<input type="text" id="videoUrl" v-model="videoUrl" placeholder="예: https://www.youtube.com/watch?v=..." /> | |
</div> | |
<div class="input-section"> | |
<label for="query">찾을 내용 (쿼리):</label> | |
<input type="text" id="query" v-model="query" placeholder="예: RAG 기술의 장점은?" /> | |
</div> | |
<button @click="processVideo" :disabled="loading"> | |
{{ loading ? '처리 중...' : '영상 탐색 시작' }} | |
</button> | |
<div v-if="errorMessage" class="error-message"> | |
{{ errorMessage }} | |
</div> | |
<div v-if="results.length > 0 && !loading" class="results-section"> | |
<h2>검색 결과:</h2> | |
<div v-for="(result, index) in results" :key="index" class="result-item"> | |
<p><strong>시간:</strong> <a :href="videoUrl + '&t=' + result.timestamp.replace(/:/g, 'm') + 's'" target="_blank">{{ result.timestamp }}</a></p> | |
<p><strong>내용:</strong> {{ result.text }}</p> | |
</div> | |
</div> | |
<div v-else-if="!loading && responseMessage" class="info-message"> | |
{{ responseMessage }} | |
</div> | |
</div> | |
</template> | |
<script> | |
import apiClient from './api'; // axios 인스턴스 import | |
export default { | |
name: 'App', | |
data() { | |
return { | |
videoUrl: '', | |
query: '', | |
loading: false, | |
results: [], | |
errorMessage: '', | |
responseMessage: '' | |
}; | |
}, | |
methods: { | |
async processVideo() { | |
this.errorMessage = ''; | |
this.results = []; | |
this.responseMessage = ''; | |
this.loading = true; | |
try { | |
const response = await apiClient.post(`/process_youtube_video`, { | |
video_url: this.videoUrl, | |
query: this.query | |
}); | |
this.responseMessage = response.data.message; | |
if (response.data.results && response.data.results.length > 0) { | |
this.results = response.data.results; | |
} else { | |
this.responseMessage = response.data.message || "결과를 찾을 수 없습니다."; | |
} | |
} catch (error) { | |
console.error("API 호출 중 오류 발생:", error); | |
if (error.response) { | |
this.errorMessage = `오류: ${error.response.data.detail || error.response.statusText}`; | |
} else if (error.request) { | |
this.errorMessage = '서버 응답이 없습니다. 백엔드가 실행 중인지 확인하세요.'; | |
} else { | |
this.errorMessage = '요청 설정 중 오류가 발생했습니다.'; | |
} | |
} finally { | |
this.loading = false; | |
} | |
} | |
} | |
} | |
</script> | |
<style> | |
#app { | |
font-family: Avenir, Helvetica, Arial, sans-serif; | |
-webkit-font-smoothing: antialiased; | |
-moz-osx-font-smoothing: grayscale; | |
text-align: center; | |
color: #2c3e50; | |
margin-top: 60px; | |
max-width: 800px; | |
margin-left: auto; | |
margin-right: auto; | |
padding: 20px; | |
border: 1px solid #eee; | |
border-radius: 8px; | |
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
} | |
.input-section { | |
margin-bottom: 20px; | |
} | |
label { | |
display: block; | |
font-weight: bold; | |
margin-bottom: 5px; | |
} | |
input[type="text"] { | |
width: calc(100% - 20px); | |
padding: 10px; | |
border: 1px solid #ccc; | |
border-radius: 4px; | |
font-size: 16px; | |
} | |
button { | |
background-color: #42b983; | |
color: white; | |
padding: 10px 20px; | |
border: none; | |
border-radius: 4px; | |
cursor: pointer; | |
font-size: 16px; | |
transition: background-color 0.3s ease; | |
} | |
button:hover:not(:disabled) { | |
background-color: #368a68; | |
} | |
button:disabled { | |
background-color: #cccccc; | |
cursor: not-allowed; | |
} | |
.error-message { | |
color: red; | |
margin-top: 20px; | |
font-weight: bold; | |
} | |
.info-message { | |
color: #3498db; | |
margin-top: 20px; | |
font-style: italic; | |
} | |
.results-section { | |
margin-top: 30px; | |
text-align: left; | |
border-top: 1px solid #eee; | |
padding-top: 20px; | |
} | |
.results-section h2 { | |
text-align: center; | |
color: #333; | |
} | |
.result-item { | |
background-color: #f9f9f9; | |
border: 1px solid #ddd; | |
border-radius: 6px; | |
padding: 15px; | |
margin-bottom: 15px; | |
} | |
.result-item p { | |
margin: 5px 0; | |
} | |
.result-item a { | |
color: #42b983; | |
text-decoration: none; | |
} | |
.result-item a:hover { | |
text-decoration: underline; | |
} | |
</style> |