mirror of
https://github.com/headporter81/specialsource-homepage-frontend.git
synced 2026-08-08 15:21:11 +09:00
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
// [Props 정의]
|
||||
const props = defineProps({
|
||||
// 현재 진행 값
|
||||
progress: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0
|
||||
},
|
||||
// 총량
|
||||
total: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
// 하단에 표시할 상태 메시지
|
||||
status: {
|
||||
type: String,
|
||||
default: 'Initializing...'
|
||||
},
|
||||
// 막대의 총 글자 길이
|
||||
barLength: {
|
||||
type: Number,
|
||||
default: 30
|
||||
}
|
||||
});
|
||||
|
||||
// [핵심 로직: Computed로 실시간 계산]
|
||||
|
||||
// 1. 퍼센트 계산 (0 ~ 100, 소수점 버림)
|
||||
const percentage = computed(() => {
|
||||
if (props.total <= 0) return 0;
|
||||
const percent = (props.progress / props.total) * 100;
|
||||
return Math.min(Math.round(percent), 100); // 100%를 넘지 않도록 제한
|
||||
});
|
||||
|
||||
// 2. ASCII 막대 문자열 생성 (█░ 문자 조합)
|
||||
const barString = computed(() => {
|
||||
const filledCount = Math.round((props.barLength * percentage.value) / 100);
|
||||
const emptyCount = props.barLength - filledCount;
|
||||
|
||||
// '.repeat()'를 활용해 칼각 유지
|
||||
const filledBar = '█'.repeat(filledCount);
|
||||
const emptyBar = '░'.repeat(emptyCount);
|
||||
|
||||
return `${filledBar}${emptyBar}`;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tui-window">
|
||||
<div class="tui-header">
|
||||
<span class="tui-prompt">porter@specialsource-nas:~$</span>
|
||||
<span class="tui-cmd">deploy-service --watch</span>
|
||||
</div>
|
||||
|
||||
<div class="tui-bar-row">
|
||||
<span class="tui-bracket">[</span>
|
||||
<span class="tui-bar">{{ barString }}</span>
|
||||
<span class="tui-bracket">]</span>
|
||||
<span class="tui-percent">{{ percentage.toString().padStart(3, ' ') }}%</span>
|
||||
</div>
|
||||
|
||||
<div class="tui-status-row">
|
||||
<span class="tui-label">>> Status:</span>
|
||||
<span class="tui-message">{{ status }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* [TUI 핵심 스타일 CSS] */
|
||||
|
||||
.tui-window {
|
||||
/* 레트로 터미널 배경색 및 초록색 글씨 */
|
||||
background-color: #000000;
|
||||
color: #33ff33; /* 형광 초록 */
|
||||
|
||||
/* ★가장 중요: 칼각을 위한 고정폭 폰트 설정 */
|
||||
font-family: 'Courier New', 'Fira Code', 'Monaco', monospace;
|
||||
|
||||
padding: 1.5rem;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #33ff33;
|
||||
box-shadow: 0 0 15px rgba(51, 255, 51, 0.2);
|
||||
display: inline-block;
|
||||
min-width: 520px; /* 폰트에 따라 깨지지 않게 최소폭 지정 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tui-header {
|
||||
color: #aaaaaa; /* 프롬프트는 약간 흐리게 */
|
||||
margin-bottom: 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.tui-cmd {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.tui-bar-row {
|
||||
/* 막대가 스르륵 차오르는 느낌을 위한 자간 및 폰트 크기 조정 */
|
||||
font-size: 1.25rem;
|
||||
letter-spacing: 1px;
|
||||
|
||||
/* █와 ░의 높이를 맞추기 위해 white-space 설정 */
|
||||
white-space: pre;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tui-bracket {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.tui-bar {
|
||||
/* 막대 문자 자체에 약간의 글로우 효과 */
|
||||
text-shadow: 0 0 5px rgba(51, 255, 51, 0.5);
|
||||
}
|
||||
|
||||
.tui-percent {
|
||||
color: #ffffff;
|
||||
margin-left: 0.75rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tui-status-row {
|
||||
margin-top: 1rem;
|
||||
font-size: 0.95rem;
|
||||
border-top: 1px dotted #444;
|
||||
padding-top: 0.75rem;
|
||||
}
|
||||
|
||||
.tui-label {
|
||||
color: #888888;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.tui-message {
|
||||
color: #ffffff;
|
||||
/* 메시지가 길어질 경우 대비 */
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user