## 작업 결과
**색상 통일 (화이트 테마):**
- `CouponInput.vue` — 결과 행 배경 `#0f172a` → `#f8fafc`, 텍스트/배지 라이트로
- `CouponManager.vue` — 입력창/쿠폰 리스트 배경/텍스트 전체 라이트로
- `HistoryList.vue` — 이력 아이템 배경/텍스트 라이트로, 스크롤바도 라이트
**CI/CD 설정:**
- Gitea `git.wageulwageul.com/hyoseung/coupon` 레포 생성
- `.gitea/workflows/deploy.yml` — front/back 각각 빌드 후 rsync 배포
- 백엔드 `ubuntu` PM2 → `hyoseung` PM2로 마이그레이션 (CI/CD 권한 문제 해결)
- 첫 푸시에 CI/CD 자동 실행 완료 ✅
이제부터는 `autoCoupon/` 폴더에서 코드 수정 후 `git push origin main` 하면 자동 배포됩니다.
107 lines
2.5 KiB
Vue
107 lines
2.5 KiB
Vue
<template>
|
|
<div class="history" v-if="store.history.length > 0">
|
|
<div class="history-header">
|
|
<h3>📋 입력 이력</h3>
|
|
<span class="count">총 {{ store.history.length }}건</span>
|
|
</div>
|
|
<div class="list">
|
|
<div
|
|
v-for="item in store.history"
|
|
:key="item.id"
|
|
class="item"
|
|
:class="statusClass(item.result_msg)"
|
|
>
|
|
<div class="item-left">
|
|
<span class="code">{{ item.coupon_code }}</span>
|
|
<span class="time">{{ formatDate(item.executed_at) }}</span>
|
|
</div>
|
|
<span class="badge" :class="statusClass(item.result_msg)">{{ item.result_msg }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useWosStore } from '../stores/wos.store';
|
|
const store = useWosStore();
|
|
|
|
function statusClass(msg: string) {
|
|
if (msg === '성공') return 'success';
|
|
if (msg.includes('사용') || msg.includes('만료') || msg.includes('존재하지')) return 'error';
|
|
return 'error';
|
|
}
|
|
|
|
function formatDate(dt: string) {
|
|
const d = new Date(dt);
|
|
return d.toLocaleDateString('ko-KR', { month: '2-digit', day: '2-digit' })
|
|
+ ' ' + d.toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit' });
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.history {
|
|
margin-top: 8px;
|
|
}
|
|
.history-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 10px;
|
|
}
|
|
.history-header h3 {
|
|
margin: 0;
|
|
color: #1e293b;
|
|
font-size: 1rem;
|
|
}
|
|
.count {
|
|
color: #64748b;
|
|
font-size: 0.85rem;
|
|
}
|
|
.list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
max-height: 360px;
|
|
overflow-y: auto;
|
|
padding-right: 4px;
|
|
}
|
|
.list::-webkit-scrollbar { width: 4px; }
|
|
.list::-webkit-scrollbar-track { background: #f1f5f9; }
|
|
.list::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
|
|
.item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 8px 12px;
|
|
background: #f8fafc;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 8px;
|
|
border-left: 3px solid #e2e8f0;
|
|
}
|
|
.item.success { border-left-color: #22c55e; }
|
|
.item.error { border-left-color: #ef4444; }
|
|
.item-left {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
.code {
|
|
font-family: monospace;
|
|
color: #334155;
|
|
font-size: 0.9rem;
|
|
}
|
|
.time {
|
|
color: #94a3b8;
|
|
font-size: 0.75rem;
|
|
}
|
|
.badge {
|
|
padding: 3px 10px;
|
|
border-radius: 20px;
|
|
font-size: 0.78rem;
|
|
font-weight: 600;
|
|
white-space: nowrap;
|
|
}
|
|
.badge.success { background: #dcfce7; color: #16a34a; }
|
|
.badge.error { background: #fee2e2; color: #dc2626; }
|
|
</style>
|