mirror of
https://github.com/headporter81/specialsource-homepage-frontend.git
synced 2026-08-08 15:21:11 +09:00
This commit is contained in:
+64
-20
@@ -32,7 +32,26 @@
|
||||
<main class="content-area">
|
||||
<transition name="fade" mode="out-in">
|
||||
|
||||
<div v-if="activeMenu === 'main'" id="videos-container" key="main">
|
||||
<div v-if="activeMenu === 'main'" class="sub-page main-page" key="main">
|
||||
<div class="ascii-container">
|
||||
<pre class="ascii-art">
|
||||
_ _
|
||||
___ _ __ ___ ___(_) __ _| |___ ___ _ _ _ __ ___ ___
|
||||
/ __| '_ \ / _ \/ __| |/ _` | / __|/ _ \| | | | '__/ __/ _ \
|
||||
\__ \ |_) | __/ (__| | (_| | \__ \ (_) | |_| | | | (_| __/
|
||||
|___/ .__/ \___|\___|_|\__,_|_|___/\___/ \__,_|_| \___\___|
|
||||
|_|
|
||||
|
||||
___ ___ _ __ ___ _ __ __ _ _ __ _ _
|
||||
/ __/ _ \| '_ ` _ \| '_ \ / _` | '_ \| | | |
|
||||
| (_| (_) | | | | | | |_) | (_| | | | | |_| |
|
||||
\___\___/|_| |_| |_| .__/ \__,_|_| |_|\__, |
|
||||
|_| |___/
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="activeMenu === 'youtube'" id="videos-container" key="youtube">
|
||||
<div
|
||||
v-for="(video, index) in videos"
|
||||
:key="video.id.videoId"
|
||||
@@ -63,7 +82,7 @@
|
||||
class="login-input"
|
||||
placeholder="ENTER ACCESS ID"
|
||||
@keyup.enter="handleLoginSubmit"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<div class="login-input-group">
|
||||
<label class="login-label">ACCESS KEY_</label>
|
||||
@@ -132,22 +151,22 @@ const videos = ref([]);
|
||||
const terminalRef = ref(null);
|
||||
const termInstance = ref(null);
|
||||
|
||||
// 로그인 폼 양방향 바인딩 변수
|
||||
// 로그인 폼 초기값 세팅 유지
|
||||
const loginId = ref('admin');
|
||||
const loginPw = ref('1234');
|
||||
|
||||
// 메뉴 및 인증 토큰 반응형 변수화
|
||||
const activeMenu = ref('main');
|
||||
const authToken = ref(localStorage.getItem('token'));
|
||||
|
||||
// 🟢 [NEW] 메뉴 아이템 배열에 YOUTUBE 명시적으로 배치
|
||||
const menuItems = [
|
||||
{ id: 'main', name: 'HOME' },
|
||||
{ id: 'youtube', name: 'YOUTUBE' },
|
||||
{ id: 'project', name: 'PROJECT' },
|
||||
{ id: 'about', name: 'ABOUT' },
|
||||
{ id: 'contact', name: 'CONTACT' }
|
||||
];
|
||||
|
||||
// 실시간 로그인 여부 체크
|
||||
const isLoggedIn = computed(() => !!authToken.value);
|
||||
|
||||
const changeMenu = (id) => {
|
||||
@@ -157,7 +176,6 @@ const changeMenu = (id) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 📺 유튜브 API 세팅 (8개 출력)
|
||||
const apiKey = 'AIzaSyD51LHwqoY8spjq6rsY_RlhBXzb96j7D6o';
|
||||
const channelId = 'UC8L92ju0V88s6TcmLPb8Bkg';
|
||||
const maxResults = 8;
|
||||
@@ -173,7 +191,6 @@ const fetchVideos = async () => {
|
||||
const openVideo = (id) => window.open(`https://www.youtube.com/watch?v=${id}`);
|
||||
const handleRegister = () => alert("회원가입은 현재 관리자 승인제로 운영됩니다.");
|
||||
|
||||
// 로그아웃 로직 (새로고침 없이 실시간 상태 갱신)
|
||||
const handleLogout = () => {
|
||||
localStorage.removeItem('token');
|
||||
authToken.value = null;
|
||||
@@ -183,7 +200,6 @@ const handleLogout = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 🔥 [핵심 기능] 보안 로그인 처리 및 터미널 동시 출력 로직
|
||||
const handleLoginSubmit = async () => {
|
||||
if (!loginId.value || !loginPw.value) {
|
||||
alert("아이디와 비밀번호를 모두 입력해 주세요.");
|
||||
@@ -202,11 +218,9 @@ const handleLoginSubmit = async () => {
|
||||
const response = await axios.post(`${apiBaseUrl}/api/login`, {
|
||||
username: loginId.value,
|
||||
password: loginPw.value
|
||||
},
|
||||
{
|
||||
}, {
|
||||
withCredentials: true
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
if (response.data && response.data.token) {
|
||||
localStorage.setItem('token', response.data.token);
|
||||
@@ -278,7 +292,6 @@ onMounted(() => {
|
||||
|
||||
.auth-group { display: flex; align-items: center; }
|
||||
|
||||
/* 로그인/회원가입 버튼 테마 깔맞춤 고정 */
|
||||
.nav-item {
|
||||
color: #00ff00 !important;
|
||||
text-decoration: none;
|
||||
@@ -305,11 +318,41 @@ onMounted(() => {
|
||||
.content-area {
|
||||
flex: 1; padding: 20px; min-height: 400px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.sub-page { max-width: 1000px; margin: 0 auto; padding-top: 15px; }
|
||||
.sub-page { max-width: 1000px; margin: 0 auto; padding-top: 15px; width: 100%; }
|
||||
.page-title { font-family: monospace; border-bottom: 1px solid #113311; padding-bottom: 10px; margin-bottom: 20px; color: #00ff00;}
|
||||
|
||||
/* 📺 유튜브 그리드 레이아웃 (4열 8개 무화) */
|
||||
/* 🟢 [NEW] 메인 홈 아스키 전광판 전용 스타일 클래스 양식 */
|
||||
.main-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
.ascii-container {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.ascii-art {
|
||||
font-family: 'Courier New', Courier, monospace !important;
|
||||
color: #33ff33 !important;
|
||||
line-height: 1.25;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 8px rgba(51, 255, 51, 0.8) !important;
|
||||
background: transparent;
|
||||
border: none;
|
||||
margin: 0 auto;
|
||||
white-space: pre;
|
||||
display: block;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
/* 📺 유튜브 그리드 레이아웃 */
|
||||
#videos-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
@@ -339,7 +382,7 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
padding: 2px 5px; box-shadow: 0 0 5px #00ff00; z-index: 10;
|
||||
}
|
||||
|
||||
/* 🔐 [신규 추가] 컨텐츠 내장형 해커 로그인 박스 디자인 스타일 양식 */
|
||||
/* 보안 로그인 프레임 */
|
||||
.login-terminal-frame {
|
||||
max-width: 550px; margin: 40px auto;
|
||||
border: 1px dashed #00ff00; padding: 35px;
|
||||
@@ -363,18 +406,18 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
}
|
||||
.login-submit-btn:hover { background: #00ff00; color: #000; box-shadow: 0 0 15px #00ff00; }
|
||||
|
||||
/* 프로젝트 리스트 */
|
||||
/* 프로젝트 리스트 및 기타 소형 요소 */
|
||||
.project-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
|
||||
.project-item { border: 1px solid #113311; padding: 15px; background: #080808; font-family: monospace;}
|
||||
.item-header { font-weight: bold; margin-bottom: 10px; color: #00ff00; }
|
||||
.about-text { font-family: monospace; line-height: 2; color: #00cc00;}
|
||||
.contact-form { font-family: monospace; line-height: 2; color: #00cc00;}
|
||||
|
||||
/* 애니메이션 트랜지션 */
|
||||
/* 애니메이션 */
|
||||
.fade-enter-active, .fade-leave-active { transition: opacity 0.25s ease; }
|
||||
.fade-enter-from, .fade-leave-to { opacity: 0; }
|
||||
|
||||
/* --- 하단 CRT 터미널 영역 --- */
|
||||
/* 하단 CRT 터미널 */
|
||||
.crt-monitor-frame {
|
||||
height: 300px; margin: 10px 40px 30px;
|
||||
border: 2px solid #1a1a1a; background: #0a0a0a; overflow: hidden;
|
||||
@@ -394,7 +437,7 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
text-shadow: 0 0 5px rgba(51, 255, 51, 0.6) !important;
|
||||
}
|
||||
|
||||
/* 📱 반응형 분기점 */
|
||||
/* 📱 반응형 처리 */
|
||||
@media screen and (max-width: 1100px) {
|
||||
#videos-container { grid-template-columns: repeat(2, 1fr); }
|
||||
.project-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
@@ -403,6 +446,7 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
#videos-container { grid-template-columns: 1fr; }
|
||||
.project-grid { grid-template-columns: 1fr; }
|
||||
.auth-nav { flex-direction: column; gap: 12px; padding: 15px 20px; }
|
||||
.ascii-art { font-size: 8px; /* 모바일 대응 크기 축소 */ }
|
||||
}
|
||||
@keyframes blink { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
|
||||
</style>
|
||||
Reference in New Issue
Block a user