폰트 수정, UI수정 및 대시보드 수정
parent
65ea09ffd5
commit
7aedf07203
482
index.css
482
index.css
|
|
@ -670,7 +670,7 @@
|
|||
}
|
||||
|
||||
.sidebar-item-label {
|
||||
font-size: var(--text-sm);
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
@ -802,7 +802,7 @@
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 4px 0;
|
||||
font-size: 11px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.03em;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
|
|
@ -2083,7 +2083,7 @@
|
|||
}
|
||||
|
||||
.comp2-title-row {
|
||||
padding: 0 0 16px;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
|
@ -2098,7 +2098,7 @@
|
|||
}
|
||||
|
||||
.comp2-page-subtitle {
|
||||
font-size: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #9BCACC;
|
||||
line-height: 1.29;
|
||||
|
|
@ -2313,7 +2313,7 @@
|
|||
}
|
||||
|
||||
.comp2-info-label {
|
||||
font-size: 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #9BCACC;
|
||||
line-height: 1.29;
|
||||
|
|
@ -2362,7 +2362,7 @@
|
|||
}
|
||||
|
||||
.comp2-filesize {
|
||||
font-size: 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #9BCACC;
|
||||
line-height: 1.29;
|
||||
|
|
@ -2386,9 +2386,9 @@
|
|||
}
|
||||
|
||||
.comp2-meta-label {
|
||||
font-size: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #E5F1F2;
|
||||
color: #9BCACC;
|
||||
line-height: 1.29;
|
||||
}
|
||||
|
||||
|
|
@ -2406,7 +2406,7 @@
|
|||
}
|
||||
|
||||
.comp2-lyrics-text {
|
||||
font-size: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #E5F1F2;
|
||||
line-height: 1.625;
|
||||
|
|
@ -2500,7 +2500,7 @@
|
|||
flex: 1;
|
||||
height: 40px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 1.19;
|
||||
|
|
@ -3269,15 +3269,19 @@
|
|||
}
|
||||
|
||||
/* =====================================================
|
||||
Brand Intelligence v2 (피그마 디자인 기반)
|
||||
Brand Intelligence v2
|
||||
===================================================== */
|
||||
|
||||
.bi2-page {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(to bottom, #002224, #01191a);
|
||||
color: #E5F1F2;
|
||||
padding-top: 64px;
|
||||
padding-bottom: 160px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background: linear-gradient(to bottom, #002224, #01191a);
|
||||
color: #E5F1F2;
|
||||
font-family: 'Pretendard', sans-serif;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
|
@ -3333,11 +3337,22 @@
|
|||
/* 타이틀 영역 */
|
||||
.bi2-page-title-section {
|
||||
display: flex;
|
||||
max-width: 1440px;
|
||||
padding: 68px 16px 50px 16px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
padding: 8px 0 40px;
|
||||
align-self: stretch;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.bi2-page-divider {
|
||||
height: 0;
|
||||
width: calc(100% - 32px);
|
||||
max-width: 1440px;
|
||||
border: none;
|
||||
border-top: 1px solid var(--Color-teal-500, #067C80);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
|
@ -3357,39 +3372,44 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 20px;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.bi2-main-title {
|
||||
font-size: 48px;
|
||||
font-weight: 600;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 1.19;
|
||||
color: var(--Color-white, #FFF);
|
||||
text-align: center;
|
||||
font-family: Pretendard;
|
||||
font-size: 48px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
letter-spacing: -0.288px;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.bi2-subtitle {
|
||||
font-size: 14px;
|
||||
font-size: 21px;
|
||||
font-weight: 400;
|
||||
color: #E5F1F2;
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 1.19;
|
||||
text-align: center;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
/* 메인 컨테이너 */
|
||||
.bi2-main-container {
|
||||
display: flex;
|
||||
max-width: 1440px;
|
||||
min-width: 1000px;
|
||||
margin: 0 auto;
|
||||
background: #013032;
|
||||
border: 1px solid #034A4D;
|
||||
border-radius: 40px;
|
||||
padding: 32px 32px 112px;
|
||||
display: flex;
|
||||
padding: 68px 32px 112px 32px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
gap: 88px;
|
||||
align-self: stretch;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* 매장 헤더 */
|
||||
|
|
@ -3400,33 +3420,42 @@
|
|||
}
|
||||
|
||||
.bi2-store-name {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 1.3;
|
||||
color: var(--Color-white, #FFF);
|
||||
font-family: Pretendard;
|
||||
font-size: 40px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 130%; /* 52px */
|
||||
letter-spacing: -0.24px;
|
||||
}
|
||||
|
||||
.bi2-store-address {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #9BCACC;
|
||||
line-height: 1.29;
|
||||
color: var(--Color-teal-200, #9BCACC);
|
||||
font-family: Pretendard;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 22px; /* 137.5% */
|
||||
letter-spacing: -0.096px;
|
||||
}
|
||||
|
||||
/* 섹션 공통 */
|
||||
.bi2-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
gap: 20px;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.bi2-section-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #E5F1F2;
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 1.3;
|
||||
color: var(--Color-white, #FFF);
|
||||
font-family: Pretendard;
|
||||
font-size: 28px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 130%; /* 36.4px */
|
||||
letter-spacing: -0.168px;
|
||||
}
|
||||
|
||||
/* 브랜드 정체성 카드 */
|
||||
|
|
@ -3454,25 +3483,34 @@
|
|||
}
|
||||
|
||||
.bi2-label-sm {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #E5F1F2;
|
||||
line-height: 1.29;
|
||||
color: var(--Color-teal-50, #E5F1F2);
|
||||
/* Body_600 */
|
||||
font-family: Pretendard;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 22px; /* 137.5% */
|
||||
letter-spacing: -0.096px;
|
||||
}
|
||||
|
||||
.bi2-core-value {
|
||||
color: var(--Color-mint-50, #F4FFFC);
|
||||
font-family: Pretendard;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
color: #F4FFFC;
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 1.3;
|
||||
line-height: 130%; /* 31.2px */
|
||||
letter-spacing: -0.144px;
|
||||
}
|
||||
|
||||
.bi2-category-text {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #E5F1F2;
|
||||
line-height: 1.29;
|
||||
color: var(--Color-teal-50, #E5F1F2);
|
||||
font-family: Pretendard;
|
||||
font-size: 18px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 22px; /* 122.222% */
|
||||
letter-spacing: -0.108px;
|
||||
}
|
||||
|
||||
.bi2-identity-divider {
|
||||
|
|
@ -3494,23 +3532,26 @@
|
|||
}
|
||||
|
||||
.bi2-body-text {
|
||||
color: var(--Color-teal-100, #CEE5E6);
|
||||
font-family: Pretendard;
|
||||
font-size: 18px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
color: #CEE5E6;
|
||||
line-height: 1.6;
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 160%; /* 28.8px */
|
||||
letter-spacing: -0.108px;
|
||||
}
|
||||
|
||||
/* 셀링 포인트 카드 */
|
||||
.bi2-selling-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px 20px;
|
||||
justify-content: center;
|
||||
gap: clamp(20px, 4vw, 80px);
|
||||
background: #034245;
|
||||
border: 1px solid #034A4D;
|
||||
align-items: center;
|
||||
gap: 100px;
|
||||
align-self: stretch;
|
||||
border-radius: 20px;
|
||||
padding: 16px 32px;
|
||||
border: 1px solid var(--Color-teal-700, #034A4D);
|
||||
background: var(--Color-teal-750, #01393B);
|
||||
}
|
||||
|
||||
.bi2-selling-chart {
|
||||
|
|
@ -3525,8 +3566,8 @@
|
|||
|
||||
@media (max-width: 768px) {
|
||||
.bi2-radar-container svg {
|
||||
width: min(95vw, 420px) !important;
|
||||
height: min(95vw, 420px) !important;
|
||||
width: min(95vw, 440px) !important;
|
||||
height: min(95vw, 360px) !important;
|
||||
}
|
||||
|
||||
.bi2-radar-label-text {
|
||||
|
|
@ -3593,24 +3634,29 @@
|
|||
display: flex;
|
||||
align-items: stretch;
|
||||
gap: 16px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bi2-persona-card {
|
||||
flex: 1;
|
||||
background: #034245;
|
||||
border: 1px solid #034A4D;
|
||||
border-radius: 20px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 16px;
|
||||
flex: 1 0 0;
|
||||
align-self: stretch;
|
||||
border-radius: 20px;
|
||||
border: 1px solid var(--Color-teal-700, #034A4D);
|
||||
background: var(--Color-teal-750, #01393B);
|
||||
}
|
||||
|
||||
.bi2-persona-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding-bottom: 8px;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.bi2-persona-info {
|
||||
|
|
@ -3620,27 +3666,33 @@
|
|||
}
|
||||
|
||||
.bi2-persona-name {
|
||||
font-size: 18px;
|
||||
color: var(--Color-teal-50, #E5F1F2);
|
||||
font-family: Pretendard;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
color: #E5F1F2;
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 1.3;
|
||||
line-height: 130%; /* 26px */
|
||||
letter-spacing: -0.12px;
|
||||
}
|
||||
|
||||
.bi2-persona-age {
|
||||
color: var(--Color-teal-200, #9BCACC);
|
||||
/* 14_600 */
|
||||
font-family: Pretendard;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #9BCACC;
|
||||
line-height: 1.29;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 18px; /* 128.571% */
|
||||
}
|
||||
|
||||
.bi2-persona-desc {
|
||||
color: var(--Color-teal-100, #CEE5E6);
|
||||
/* 14_600 */
|
||||
font-family: Pretendard;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #CEE5E6;
|
||||
line-height: 1.29;
|
||||
word-break: keep-all;
|
||||
overflow-wrap: break-word;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 18px; /* 128.571% */
|
||||
}
|
||||
|
||||
.bi2-persona-divider {
|
||||
|
|
@ -3656,29 +3708,33 @@
|
|||
}
|
||||
|
||||
.bi2-persona-detail.grow {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
padding: 0 4px;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.bi2-label-xs {
|
||||
color: var(--Color-teal-100, #CEE5E6);
|
||||
font-family: Pretendard;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #CEE5E6;
|
||||
line-height: 1.29;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 18px; /* 128.571% */
|
||||
}
|
||||
|
||||
.bi2-persona-detail-text {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #E5F1F2;
|
||||
line-height: 26px;
|
||||
letter-spacing: -0.006em;
|
||||
white-space: pre-line;
|
||||
text-align: right;
|
||||
word-break: keep-all;
|
||||
overflow-wrap: break-word;
|
||||
flex: 1;
|
||||
color: var(--Color-teal-50, #E5F1F2);
|
||||
text-align: right;
|
||||
font-family: Pretendard;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 26px;
|
||||
letter-spacing: -0.096px;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
/* 추천 타겟 키워드 */
|
||||
|
|
@ -3689,16 +3745,23 @@
|
|||
}
|
||||
|
||||
.bi2-keyword-subtitle {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #9BCACC;
|
||||
line-height: 1.29;
|
||||
color: var(--Color-teal-200, #9BCACC);
|
||||
/* Body_600 */
|
||||
font-family: Pretendard;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 22px; /* 137.5% */
|
||||
letter-spacing: -0.096px;
|
||||
}
|
||||
|
||||
.bi2-keyword-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
align-content: flex-start;
|
||||
gap: 8px;
|
||||
align-self: stretch;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.bi2-keyword-pill {
|
||||
|
|
@ -3768,8 +3831,8 @@
|
|||
.bi2-main-container {
|
||||
min-width: unset;
|
||||
margin: 0 16px;
|
||||
padding: 24px 20px 80px;
|
||||
gap: 48px;
|
||||
padding: 24px 0px 80px;
|
||||
gap: 64px;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
|
|
@ -3779,7 +3842,11 @@
|
|||
}
|
||||
|
||||
.bi2-persona-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 20px;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.bi2-identity-bottom {
|
||||
|
|
@ -3788,11 +3855,18 @@
|
|||
}
|
||||
|
||||
.bi2-main-title {
|
||||
font-size: 28px;
|
||||
color: var(--Color-white, #FFF);
|
||||
text-align: center;
|
||||
font-family: Pretendard;
|
||||
font-size: 45px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
letter-spacing: -0.288px;
|
||||
}
|
||||
|
||||
.bi2-store-name {
|
||||
font-size: 24px;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.bi2-selling-name {
|
||||
|
|
@ -5664,6 +5738,7 @@
|
|||
/* Dashboard Container */
|
||||
.dashboard-container {
|
||||
width: 100%;
|
||||
min-width: 375px;
|
||||
padding: 0.75rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -5704,35 +5779,17 @@
|
|||
}
|
||||
|
||||
.dashboard-title {
|
||||
font-size: var(--text-lg);
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.025em;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.dashboard-title {
|
||||
font-size: var(--text-xl);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.dashboard-title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-description {
|
||||
font-size: 15px;
|
||||
font-size: 16px;
|
||||
color: var(--color-text-gray-500);
|
||||
margin-top: 0.125rem;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.dashboard-description {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Stats Grid */
|
||||
.stats-grid {
|
||||
flex-shrink: 0;
|
||||
|
|
@ -5787,65 +5844,29 @@
|
|||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-gray-400);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.stat-label {
|
||||
font-size: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.stat-label {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: var(--text-lg);
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-white);
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.stat-value {
|
||||
font-size: var(--text-xl);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.stat-value {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.stat-value {
|
||||
font-size: var(--text-3xl);
|
||||
}
|
||||
}
|
||||
|
||||
.stat-trend {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
font-size: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--color-mint);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.stat-trend {
|
||||
font-size: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Chart Card */
|
||||
.chart-card {
|
||||
flex: 1;
|
||||
|
|
@ -5903,18 +5924,6 @@
|
|||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.chart-title {
|
||||
font-size: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.chart-title {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-legend {
|
||||
display: flex;
|
||||
gap: 0.375rem;
|
||||
|
|
@ -5929,16 +5938,10 @@
|
|||
}
|
||||
|
||||
.chart-legend-text {
|
||||
font-size: 8px;
|
||||
font-size: 14px;
|
||||
color: var(--color-text-gray-400);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.chart-legend-text {
|
||||
font-size: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
|
|
@ -5967,12 +5970,6 @@
|
|||
box-shadow: 0 20px 25px -5px rgba(166, 255, 234, 0.2);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.chart-badge-value {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-badge-line {
|
||||
width: 2px;
|
||||
height: 0.5rem;
|
||||
|
|
@ -6034,15 +6031,15 @@
|
|||
}
|
||||
|
||||
.dashboard-last-updated {
|
||||
font-size: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--color-text-gray-500);
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
@media (min-width: 768px) {
|
||||
.dashboard-last-updated {
|
||||
display: block;
|
||||
font-size: 9px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6112,19 +6109,12 @@
|
|||
}
|
||||
|
||||
.dashboard-section-title {
|
||||
font-size: var(--text-sm);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-white);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.dashboard-section-title {
|
||||
font-size: var(--text-base);
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Chart Legend Dual (for YoY comparison) */
|
||||
.chart-legend-dual {
|
||||
display: flex;
|
||||
|
|
@ -6189,7 +6179,7 @@
|
|||
@media (min-width: 640px) {
|
||||
.platform-tab {
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: var(--text-sm);
|
||||
/* font-size: var(--text-sm); */
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
|
@ -6231,7 +6221,7 @@
|
|||
padding: 0.375rem 0.875rem;
|
||||
background-color: transparent;
|
||||
color: var(--color-text-gray-400);
|
||||
font-size: var(--text-sm);
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
|
|
@ -6334,30 +6324,12 @@
|
|||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.metric-card-value {
|
||||
font-size: var(--text-2xl);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.metric-card-value {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.metric-card-unit {
|
||||
font-size: var(--text-xs);
|
||||
color: var(--color-text-gray-500);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.metric-card-unit {
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
}
|
||||
|
||||
.metric-card-trend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -6366,12 +6338,6 @@
|
|||
font-weight: 500;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.metric-card-trend {
|
||||
font-size: var(--text-xs);
|
||||
}
|
||||
}
|
||||
|
||||
.metric-card-trend.up {
|
||||
color: var(--color-mint);
|
||||
}
|
||||
|
|
@ -6394,9 +6360,10 @@
|
|||
|
||||
/* YoY Chart */
|
||||
.yoy-chart-card {
|
||||
min-width: 351px;
|
||||
background-color: var(--color-bg-card);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: 0.75rem;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid var(--color-border-white-5);
|
||||
box-shadow: var(--shadow-xl);
|
||||
margin-bottom: 0.75rem;
|
||||
|
|
@ -6695,14 +6662,14 @@
|
|||
|
||||
@media (min-width: 768px) {
|
||||
.top-content-card {
|
||||
padding: 1.5rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.top-content-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.top-content-item {
|
||||
|
|
@ -6768,7 +6735,8 @@
|
|||
}
|
||||
|
||||
.top-content-title {
|
||||
font-size: var(--text-xs);
|
||||
max-width: 215px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-white);
|
||||
white-space: nowrap;
|
||||
|
|
@ -6776,12 +6744,6 @@
|
|||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.top-content-title {
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
}
|
||||
|
||||
.top-content-stats {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
|
|
@ -6791,31 +6753,19 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
font-size: 10px;
|
||||
font-size: 12px;
|
||||
color: var(--color-text-gray-400);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.top-content-stat {
|
||||
font-size: var(--text-xs);
|
||||
}
|
||||
}
|
||||
|
||||
.top-content-stat svg {
|
||||
color: var(--color-text-gray-500);
|
||||
}
|
||||
|
||||
.top-content-date {
|
||||
font-size: 9px;
|
||||
font-size: 12px;
|
||||
color: var(--color-text-gray-500);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.top-content-date {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Audience Section */
|
||||
.audience-section {
|
||||
margin-bottom: 0.75rem;
|
||||
|
|
@ -6856,7 +6806,7 @@
|
|||
}
|
||||
|
||||
.audience-card-title {
|
||||
font-size: var(--text-sm);
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-gray-300);
|
||||
margin-bottom: 1rem;
|
||||
|
|
@ -6876,7 +6826,7 @@
|
|||
}
|
||||
|
||||
.audience-bar-label {
|
||||
font-size: var(--text-xs);
|
||||
font-size: 14px;
|
||||
color: var(--color-text-gray-400);
|
||||
width: 60px;
|
||||
flex-shrink: 0;
|
||||
|
|
@ -6898,7 +6848,7 @@
|
|||
}
|
||||
|
||||
.audience-bar-value {
|
||||
font-size: var(--text-xs);
|
||||
font-size: 14px;
|
||||
color: var(--color-text-white);
|
||||
width: 36px;
|
||||
text-align: right;
|
||||
|
|
@ -6949,7 +6899,7 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.375rem;
|
||||
font-size: var(--text-xs);
|
||||
font-size: 14px;
|
||||
color: var(--color-text-gray-400);
|
||||
}
|
||||
|
||||
|
|
@ -7620,6 +7570,7 @@
|
|||
align-items: center;
|
||||
gap: 1.25rem;
|
||||
flex-shrink: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.sound-column > *:not(.btn-generate-sound):not(.error-message-new):not(.status-message-new) {
|
||||
|
|
@ -7674,7 +7625,7 @@
|
|||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
border-radius: 8px;
|
||||
color: var(--color-text-white);
|
||||
font-size: var(--text-sm);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-normal);
|
||||
|
|
@ -7959,7 +7910,7 @@
|
|||
background: transparent;
|
||||
border: none;
|
||||
color: var(--color-text-white);
|
||||
font-size: var(--text-sm);
|
||||
font-size: 16px;
|
||||
font-family: inherit;
|
||||
resize: none;
|
||||
outline: none;
|
||||
|
|
@ -8097,7 +8048,7 @@
|
|||
}
|
||||
|
||||
/* Responsive Styles for Sound Studio */
|
||||
@media (max-width: 639px) {
|
||||
@media (min-width: 768px) {
|
||||
.progress-indicator {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -8108,7 +8059,7 @@
|
|||
|
||||
.sound-type-btn {
|
||||
padding: 0.75rem 0.5rem;
|
||||
font-size: var(--text-xs);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.genre-row {
|
||||
|
|
@ -8117,7 +8068,7 @@
|
|||
|
||||
.genre-btn {
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: var(--text-xs);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8143,6 +8094,7 @@
|
|||
flex: 1;
|
||||
width: auto;
|
||||
min-height: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.lyrics-column {
|
||||
|
|
@ -9593,7 +9545,7 @@
|
|||
}
|
||||
|
||||
.social-posting-title {
|
||||
font-size: 1.125rem;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #FFFFFF;
|
||||
margin: 0;
|
||||
|
|
@ -9726,7 +9678,7 @@
|
|||
}
|
||||
|
||||
.social-posting-video-specs {
|
||||
font-size: 0.75rem;
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
margin: 0;
|
||||
}
|
||||
|
|
@ -9739,7 +9691,7 @@
|
|||
}
|
||||
|
||||
.social-posting-label {
|
||||
font-size: 0.8rem;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
|
@ -9757,7 +9709,7 @@
|
|||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 8px;
|
||||
color: #FFFFFF;
|
||||
font-size: 0.875rem;
|
||||
font-size: 14px;
|
||||
font-family: 'Pretendard', sans-serif;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
|
@ -9836,7 +9788,7 @@
|
|||
}
|
||||
|
||||
.social-posting-radio .radio-label {
|
||||
font-size: 0.85rem;
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ const Footer: React.FC = () => {
|
|||
<footer className="landing-footer">
|
||||
<div className="footer-content">
|
||||
<div className="footer-left">
|
||||
<img src="/assets/images/logo.svg" alt="CASTAD" className="footer-logo" />
|
||||
<img src="/assets/images/ado2-sidebar-logo.svg" alt="ADO2" className="footer-logo" />
|
||||
<p className="footer-copyright">Copyright ⓒ O2O Inc. All rights reserved</p>
|
||||
</div>
|
||||
<div className="footer-right">
|
||||
<p className="footer-info">{t('footer.company')}</p>
|
||||
<p className="footer-info">{t('footer.businessNumber')}</p>
|
||||
<p className="footer-info">{t('footer.headquarters')}</p>
|
||||
<p className="footer-info">{t('footer.researchCenter')}</p>
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ const SocialPostingModal: React.FC<SocialPostingModalProps> = ({
|
|||
const [isPrivacyDropdownOpen, setIsPrivacyDropdownOpen] = useState(false);
|
||||
const [isLoadingAutoDescription, setIsLoadingAutoDescription] = useState(false);
|
||||
const [isHorizontalVideo, setIsHorizontalVideo] = useState(false);
|
||||
const [videoMeta, setVideoMeta] = useState<{ width: number; height: number; duration: number } | null>(null);
|
||||
const channelDropdownRef = useRef<HTMLDivElement>(null);
|
||||
const privacyDropdownRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
|
|
@ -175,12 +176,6 @@ const SocialPostingModal: React.FC<SocialPostingModalProps> = ({
|
|||
if (isOpen) {
|
||||
loadSocialAccounts();
|
||||
loadAutocomplete();
|
||||
// // 비디오 정보로 기본 제목 설정
|
||||
// if (video) {
|
||||
// const date = new Date(video.created_at);
|
||||
// const formattedDate = `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, '0')}.${String(date.getDate()).padStart(2, '0')}`;
|
||||
// setTitle(`${video.store_name} ${formattedDate}`);
|
||||
// }
|
||||
}
|
||||
}, [isOpen, video]);
|
||||
|
||||
|
|
@ -436,6 +431,7 @@ const SocialPostingModal: React.FC<SocialPostingModalProps> = ({
|
|||
onLoadedMetadata={(e) => {
|
||||
const v = e.currentTarget;
|
||||
setIsHorizontalVideo(v.videoWidth > v.videoHeight);
|
||||
setVideoMeta({ width: v.videoWidth, height: v.videoHeight, duration: v.duration });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -453,7 +449,11 @@ const SocialPostingModal: React.FC<SocialPostingModalProps> = ({
|
|||
<p className="social-posting-video-title">
|
||||
{video.store_name} {new Date(video.created_at).toLocaleString('ko-KR')}
|
||||
</p>
|
||||
<p className="social-posting-video-specs">{t('social.videoSpecs')}</p>
|
||||
<p className="social-posting-video-specs">
|
||||
{videoMeta
|
||||
? `${videoMeta.width}×${videoMeta.height} · ${Math.floor(videoMeta.duration / 60)}:${String(Math.floor(videoMeta.duration % 60)).padStart(2, '0')}`
|
||||
: t('social.videoSpecs')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Channel Selector - Custom Dropdown */}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"logout": "Log Out"
|
||||
},
|
||||
"footer": {
|
||||
"company":"O2O Inc.",
|
||||
"businessNumber": "Business Registration No. : 620-87-00810 | CEO : Ahn Sungmin",
|
||||
"headquarters": "HQ : 41593 Unicorn Lab Daegu A05, 5F, 111 Oksan-ro, Buk-gu, Daegu, Korea",
|
||||
"researchCenter": "R&D : 13453 Rooms 504-505 (East), KT Pangyo Bldg, 32 Geumto-ro, Sujeong-gu, Seongnam-si, Gyeonggi-do, Korea",
|
||||
|
|
@ -25,7 +26,7 @@
|
|||
"social": {
|
||||
"title": "Social Media Posting",
|
||||
"postNumber": "Post 1",
|
||||
"videoSpecs": "1080x1920 · 10 sec",
|
||||
"videoSpecs": "720x1280 · 1:01",
|
||||
"channelLabel": "Post Channel",
|
||||
"loadingAccounts": "Loading accounts...",
|
||||
"noAccounts": "No connected social accounts.",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"logout": "로그아웃"
|
||||
},
|
||||
"footer": {
|
||||
"company":"㈜에이아이오투오",
|
||||
"businessNumber": "사업자 등록번호 : 620-87-00810 | 대표 : 안성민",
|
||||
"headquarters": "본사 : 41593 대구광역시 북구 옥산로 111, 5층 유니콘랩 대구 A05호",
|
||||
"researchCenter": "연구소 : 13453 경기 성남시 수정구 금토로 32 (금토동) (주)KT 판교빌딩 504호~505호 (East)",
|
||||
|
|
@ -25,7 +26,7 @@
|
|||
"social": {
|
||||
"title": "소셜 미디어 포스팅",
|
||||
"postNumber": "게시물 1",
|
||||
"videoSpecs": "1080x1920 · 10초",
|
||||
"videoSpecs": "720x1280 · 1:01",
|
||||
"channelLabel": "게시 채널",
|
||||
"loadingAccounts": "계정 로딩 중...",
|
||||
"noAccounts": "연결된 소셜 계정이 없습니다.",
|
||||
|
|
@ -345,11 +346,11 @@
|
|||
"conceptScalability": "컨셉 확장성",
|
||||
"noInfo": "정보 없음",
|
||||
"marketPositioning": "시장 포지셔닝",
|
||||
"coreValue": "핵심 가치 (Core Value)",
|
||||
"coreValue": "핵심 가치",
|
||||
"categoryDefinition": "카테고리 정의",
|
||||
"targetPersona": "타겟 페르소나",
|
||||
"targetPersona": "주요 고객 유형",
|
||||
"ageSuffix": "세",
|
||||
"sellingPoints": "주요 셀링 포인트 (USP)",
|
||||
"sellingPoints": "주요 셀링 포인트",
|
||||
"recommendedKeywords": "추천 타겟 키워드",
|
||||
"generateContent": "콘텐츠 생성",
|
||||
"pageDescBefore": "을 통해 도출된 ",
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ const AnalysisResultSection: React.FC<AnalysisResultSectionProps> = ({ onBack, o
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="bi2-page-divider" />
|
||||
|
||||
{/* Main Content Container */}
|
||||
<div className="bi2-main-container">
|
||||
{/* 매장명 & 주소 */}
|
||||
|
|
@ -130,9 +132,11 @@ const AnalysisResultSection: React.FC<AnalysisResultSectionProps> = ({ onBack, o
|
|||
<div className="bi2-persona-divider"></div>
|
||||
<div className="bi2-persona-detail grow">
|
||||
<span className="bi2-label-xs">{t('analysis.favorKeywords', { defaultValue: '선호 키워드' })}</span>
|
||||
<p className="bi2-persona-detail-text">
|
||||
{persona.favor_target.join('\n')}
|
||||
</p>
|
||||
<div className="bi2-persona-detail-text">
|
||||
{persona.favor_target.map((item, i) => (
|
||||
<p key={i}>{item}</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="bi2-persona-divider"></div>
|
||||
<div className="bi2-persona-detail">
|
||||
|
|
|
|||
|
|
@ -76,11 +76,27 @@ export const GeometricChart: React.FC<GeometricChartProps> = ({ data }) => {
|
|||
style={{ overflow: 'visible', width: '440px', height: '440px' }}
|
||||
>
|
||||
<defs>
|
||||
<filter id="radar-glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur stdDeviation="4" result="coloredBlur" />
|
||||
{/* 레이더 폴리곤 fill: radial gradient */}
|
||||
<radialGradient id="radar-fill-gradient" cx="280" cy="280" r="160" fx="280" fy="280" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="60%" stopColor="#034245" stopOpacity="0" />
|
||||
<stop offset="100%" stopColor="#94FBE0" stopOpacity="0.30" />
|
||||
</radialGradient>
|
||||
{/* 레이더 폴리곤 filter: outer drop-shadow + inset glow */}
|
||||
<filter id="radar-polygon-filter" x="-30%" y="-30%" width="160%" height="160%">
|
||||
{/* Outer drop shadow */}
|
||||
<feDropShadow dx="0" dy="0" stdDeviation="6" floodColor="#94FBE0" floodOpacity="0.5" result="dropShadow" />
|
||||
{/* Inset glow: invert alpha → blur → composite inside */}
|
||||
<feComponentTransfer in="SourceAlpha" result="invertedAlpha">
|
||||
<feFuncA type="linear" slope="-1" intercept="1" />
|
||||
</feComponentTransfer>
|
||||
<feGaussianBlur in="invertedAlpha" stdDeviation="6" result="blurredOuter" />
|
||||
<feComposite in="blurredOuter" in2="SourceAlpha" operator="in" result="insetMask" />
|
||||
<feFlood floodColor="#94FBE0" floodOpacity="0.5" result="insetColor" />
|
||||
<feComposite in="insetColor" in2="insetMask" operator="in" result="insetGlow" />
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur" />
|
||||
<feMergeNode in="dropShadow" />
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
<feMergeNode in="insetGlow" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
<filter id="badge-glow" x="-50%" y="-50%" width="200%" height="200%">
|
||||
|
|
@ -118,11 +134,11 @@ export const GeometricChart: React.FC<GeometricChartProps> = ({ data }) => {
|
|||
{/* 데이터 폴리곤 */}
|
||||
<polygon
|
||||
points={dataPolygon}
|
||||
fill="rgba(45, 212, 191, 0.15)"
|
||||
stroke="#2DD4BF"
|
||||
fill="url(#radar-fill-gradient)"
|
||||
stroke="var(--Color-mint-500, #94FBE0)"
|
||||
strokeWidth="2"
|
||||
strokeLinejoin="round"
|
||||
filter="url(#radar-glow)"
|
||||
filter="url(#radar-polygon-filter)"
|
||||
/>
|
||||
|
||||
{/* 데이터 포인트 */}
|
||||
|
|
@ -132,8 +148,8 @@ export const GeometricChart: React.FC<GeometricChartProps> = ({ data }) => {
|
|||
cx={point.x}
|
||||
cy={point.y}
|
||||
r="4"
|
||||
fill="#2DD4BF"
|
||||
stroke="#1A1A2E"
|
||||
fill="#ffffff"
|
||||
stroke="#ffffff"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
))}
|
||||
|
|
@ -145,7 +161,7 @@ export const GeometricChart: React.FC<GeometricChartProps> = ({ data }) => {
|
|||
const rank = rankMap.get(i) || i + 1;
|
||||
const isTopThree = rank <= 3;
|
||||
const isLeftSide = Math.cos(angle) < -0.1;
|
||||
const textX = isLeftSide ? -14 : 14;
|
||||
const textX = isLeftSide ? -20 : 20;
|
||||
const textAnchor: 'start' | 'end' = isLeftSide ? 'end' : 'start';
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
<div className="comp2-info-content">
|
||||
<div className="comp2-file-info">
|
||||
<h3 className="comp2-filename">{getFileName()}</h3>
|
||||
<p className="comp2-filesize">19.6MB</p>
|
||||
{/* <p className="comp2-filesize">19.6MB</p> */}
|
||||
</div>
|
||||
<div className="comp2-meta-grid">
|
||||
<div className="comp2-meta-item">
|
||||
|
|
|
|||
|
|
@ -618,21 +618,22 @@ const DashboardContent: React.FC<DashboardContentProps> = ({ onNavigate }) => {
|
|||
// 블러 조건: 1)계정 미연결 2)업로드 영상 없음 3)데이터 없음
|
||||
const isBlurred = accounts.length === 0 || isEmptyState || !dashboardData;
|
||||
|
||||
// API 데이터 우선 사용, 없거나 영상 없음(isEmptyState) 시 Mock 데이터로 폴백
|
||||
const contentMetrics = (!isEmptyState && dashboardData?.contentMetrics?.length) ? dashboardData.contentMetrics : MOCK_CONTENT_METRICS;
|
||||
const topContent = (!isEmptyState && dashboardData?.topContent?.length) ? dashboardData.topContent : MOCK_TOP_CONTENT;
|
||||
const hasRealAgeGroups = !isEmptyState && !!dashboardData?.audienceData?.ageGroups?.some(g => g.percentage > 0);
|
||||
const hasRealGender = !isEmptyState && ((dashboardData?.audienceData?.gender?.male ?? 0) + (dashboardData?.audienceData?.gender?.female ?? 0)) > 0;
|
||||
const hasRealTopRegions = !isEmptyState && !!dashboardData?.audienceData?.topRegions?.some(r => r.percentage > 0);
|
||||
// showMockData=true면 전체 mock 강제, 아니면 API 우선 / isEmptyState 시 mock 폴백
|
||||
const useReal = !showMockData && !isEmptyState;
|
||||
const contentMetrics = (useReal && dashboardData?.contentMetrics?.length) ? dashboardData.contentMetrics : MOCK_CONTENT_METRICS;
|
||||
const topContent = (useReal && dashboardData?.topContent?.length) ? dashboardData.topContent : MOCK_TOP_CONTENT;
|
||||
const hasRealAgeGroups = useReal && !!dashboardData?.audienceData?.ageGroups?.some(g => g.percentage > 0);
|
||||
const hasRealGender = useReal && ((dashboardData?.audienceData?.gender?.male ?? 0) + (dashboardData?.audienceData?.gender?.female ?? 0)) > 0;
|
||||
const hasRealTopRegions = useReal && !!dashboardData?.audienceData?.topRegions?.some(r => r.percentage > 0);
|
||||
const hasRealAudienceData = hasRealAgeGroups && hasRealGender && hasRealTopRegions;
|
||||
const audienceData = hasRealAudienceData ? dashboardData!.audienceData : MOCK_AUDIENCE_DATA;
|
||||
|
||||
// mode별 차트 데이터를 ChartDataPoint 통합 형식으로 변환
|
||||
const chartData: ChartDataPoint[] = mode === 'month'
|
||||
? ((!isEmptyState && dashboardData?.monthlyData?.length)
|
||||
? ((useReal && dashboardData?.monthlyData?.length)
|
||||
? dashboardData.monthlyData.map((d: MonthlyData) => ({ label: d.month, current: d.thisYear, previous: d.lastYear }))
|
||||
: MOCK_MONTHLY_DATA.map((d: MonthlyData) => ({ label: d.month, current: d.thisYear, previous: d.lastYear })))
|
||||
: ((!isEmptyState && dashboardData?.dailyData?.length)
|
||||
: ((useReal && dashboardData?.dailyData?.length)
|
||||
? dashboardData.dailyData.map((d: DailyData) => ({ label: d.date, current: d.thisPeriod, previous: d.lastPeriod }))
|
||||
: MOCK_DAILY_DATA.map((d: DailyData) => ({ label: d.date, current: d.thisPeriod, previous: d.lastPeriod })));
|
||||
|
||||
|
|
@ -657,8 +658,8 @@ const DashboardContent: React.FC<DashboardContentProps> = ({ onNavigate }) => {
|
|||
<path d="M15 10l4.553-2.069A1 1 0 0121 8.87v6.26a1 1 0 01-1.447.899L15 14M3 8a2 2 0 012-2h10a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2V8z" strokeLinecap="round" strokeLinejoin="round" />
|
||||
</svg>
|
||||
<div>
|
||||
<p style={{ color: '#a6ffea', fontWeight: 600, marginBottom: '2px' }}>아직 업로드된 영상이 없습니다.</p>
|
||||
<p style={{ color: 'rgba(255,255,255,0.5)', fontSize: '13px' }}>ADO2에서 영상을 업로드하면 실제 통계가 표시됩니다.</p>
|
||||
<p style={{ color: '#a6ffea', fontSize: '20px', fontWeight: 600, marginBottom: '2px' }}>아직 업로드된 영상이 없습니다.</p>
|
||||
<p style={{ color: 'rgba(255,255,255,0.5)', fontSize: '16px' }}>ADO2에서 영상을 업로드하면 실제 통계가 표시됩니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -786,7 +787,7 @@ const DashboardContent: React.FC<DashboardContentProps> = ({ onNavigate }) => {
|
|||
<div className="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
<h2 className="dashboard-section-title" style={{ marginBottom: '2px' }}>{t('dashboard.contentPerformance')}</h2>
|
||||
<p style={{ fontSize: '12px', color: 'rgba(255,255,255,0.4)', margin: 0 }}>ADO2에서 업로드한 최근 30개의 영상 통계가 표시됩니다.</p>
|
||||
<p style={{ fontSize: '14px', color: 'rgba(255,255,255,0.4)', margin: 0 }}>ADO2에서 업로드한 최근 30개의 영상 통계가 표시됩니다.</p>
|
||||
</div>
|
||||
<div className="mode-toggle">
|
||||
<button
|
||||
|
|
@ -860,7 +861,7 @@ const DashboardContent: React.FC<DashboardContentProps> = ({ onNavigate }) => {
|
|||
<AnimatedSection delay={1000} className="audience-section">
|
||||
<div style={{ marginBottom: '16px' }}>
|
||||
<h2 className="dashboard-section-title" style={{ marginBottom: '2px' }}>{t('dashboard.audienceInsights')}</h2>
|
||||
<p style={{ fontSize: '12px', color: 'rgba(255,255,255,0.4)', margin: 0 }}>선택한 채널의 통계가 표시됩니다.</p>
|
||||
<p style={{ fontSize: '14px', color: 'rgba(255,255,255,0.4)', margin: 0 }}>선택한 채널의 통계가 표시됩니다.</p>
|
||||
</div>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div className="audience-cards" style={!hasRealAudienceData && !showMockData ? { filter: 'blur(4px)', pointerEvents: 'none', userSelect: 'none' } : {}}>
|
||||
|
|
@ -883,7 +884,7 @@ const DashboardContent: React.FC<DashboardContentProps> = ({ onNavigate }) => {
|
|||
</div>
|
||||
</AnimatedItem>
|
||||
</div>
|
||||
{dashboardData && !isEmptyState && !hasRealAudienceData && (
|
||||
{dashboardData && !isEmptyState && !hasRealAudienceData && !showMockData && (
|
||||
<div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', pointerEvents: 'none' }}>
|
||||
<div style={{
|
||||
display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '10px',
|
||||
|
|
@ -892,7 +893,7 @@ const DashboardContent: React.FC<DashboardContentProps> = ({ onNavigate }) => {
|
|||
borderRadius: '12px',
|
||||
padding: '20px 28px',
|
||||
}}>
|
||||
<p style={{ color: 'rgba(255,255,255,0.85)', fontSize: '14px', fontWeight: 500, margin: 0, textAlign: 'center' }}>
|
||||
<p style={{ color: 'rgba(255,255,255,0.85)', fontSize: '16px', fontWeight: 500, margin: 0, textAlign: 'center' }}>
|
||||
누적 데이터가 부족하여 실제 시청자 정보가 없습니다.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -901,8 +902,7 @@ const DashboardContent: React.FC<DashboardContentProps> = ({ onNavigate }) => {
|
|||
</div>
|
||||
</AnimatedSection>
|
||||
|
||||
{/* 개발자 모드 전용: mock 데이터 블러 해제 버튼 */}
|
||||
{isTestPage && isEmptyState && (
|
||||
{/* mock 데이터 보기 버튼 */}
|
||||
<button
|
||||
onClick={() => setShowMockData(prev => !prev)}
|
||||
style={{
|
||||
|
|
@ -930,9 +930,8 @@ const DashboardContent: React.FC<DashboardContentProps> = ({ onNavigate }) => {
|
|||
: <><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></>
|
||||
}
|
||||
</svg>
|
||||
{showMockData ? 'Mock 숨기기' : 'Mock 보기'} [DEV]
|
||||
{showMockData ? 'Sample 숨기기' : 'Sample 보기'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue