Faq , q&a 상세 , 피드백 , 마이페이지 이용자 관리 퍼블리싱

This commit is contained in:
hong
2026-07-09 09:47:16 +09:00
parent cc4c1a6b53
commit 4f577c8c14
25 changed files with 2577 additions and 1651 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 133 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 159 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 239 KiB

@@ -79,6 +79,9 @@
li.innerHTML = '' li.innerHTML = ''
+ '<div class="djb-comment-meta">' + '<div class="djb-comment-meta">'
+ ' <div class="djb-comment-meta-left">' + ' <div class="djb-comment-meta-left">'
+ ' <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-right: 2px; opacity: 0.5;">'
+ ' <path d="M5 3v5a2 2 0 0 0 2 2h5 M9 7l3 3-3 3" stroke="#000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>'
+ ' </svg>'
+ ' <span class="djb-comment-writer">' + escapeHtml(c.writerName || '(알 수 없음)') + '</span>' + ' <span class="djb-comment-writer">' + escapeHtml(c.writerName || '(알 수 없음)') + '</span>'
+ (c.adminYn === 'Y' ? ' <span class="djb-comment-admin-badge">관리자</span>' : '') + (c.adminYn === 'Y' ? ' <span class="djb-comment-admin-badge">관리자</span>' : '')
+ ' </div>' + ' </div>'
@@ -9,28 +9,30 @@
// FAQ Accordion - Figma Design // FAQ Accordion - Figma Design
.faq-accordion { .faq-accordion {
background: #F6F9FB; display: flex;
border-radius: $border-radius-lg; flex-direction: column;
overflow: hidden; gap: 6px;
margin-bottom: $spacing-2xl; margin-bottom: $spacing-2xl;
@include respond-to('sm') {
background: #FFFFFF;
border-radius: 0;
}
.faq-item { .faq-item {
border-bottom: 1px solid #DADADA; position: relative;
border-radius: 10px;
background: #fff;
transition: $transition-base; transition: $transition-base;
&:last-child {
border-bottom: none;
}
// Active state - when accordion is open // Active state - when accordion is open
&.active { &.active {
.faq-question { .faq-question {
background: #4685ef;
border-color: #e8dddd;
.faq-question-q,
.faq-question-text {
color: #fff !important;
}
.faq-icon { .faq-icon {
color: #fff;
transform: rotate(180deg); transform: rotate(180deg);
} }
} }
@@ -42,33 +44,48 @@
} }
} }
// Question row - Figma: 18px bold, #212529 // Question row
.faq-question { .faq-question {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; min-height: 47px;
padding: $spacing-md $spacing-lg; height: auto;
font-size: 18px; padding: 8px 35px 8px 21px;
font-weight: $font-weight-bold; background: #fff;
color: #212529; border: 1px solid #dedede;
border-radius: 10px;
cursor: pointer; cursor: pointer;
transition: $transition-base; transition: $transition-base;
gap: 95px;
min-height: 54px;
@media (max-width: $breakpoint-md) { @media (max-width: $breakpoint-md) {
padding: $spacing-md $spacing-lg; padding: 12px 16px;
font-size: 16px; min-height: 44px;
gap: $spacing-lg;
} }
&:hover { .faq-question-q {
background: rgba($primary-blue, 0.02); font-size: 20px;
font-weight: 700;
color: #555;
margin-right: 15px;
line-height: 1;
@media (max-width: $breakpoint-md) {
font-size: 16px;
margin-right: 10px;
}
} }
.faq-question-text { .faq-question-text {
flex: 1; flex: 1;
line-height: $line-height-normal; font-size: 14px;
color: #000;
line-height: normal;
word-break: keep-all;
@media (max-width: $breakpoint-md) {
font-size: 13px;
line-height: 1.4;
}
} }
// Chevron icon // Chevron icon
@@ -79,7 +96,7 @@
justify-content: center; justify-content: center;
width: 22px; width: 22px;
height: 22px; height: 22px;
color: #212529; color: #000;
transition: transform 0.3s ease; transition: transform 0.3s ease;
svg { svg {
@@ -89,49 +106,41 @@
} }
} }
// Answer section - white background // Answer section
.faq-answer { .faq-answer {
display: none; display: none;
background: #F6F9FB; padding: 19px 21px 25px 21px;
padding: $spacing-lg 20px $spacing-xl;
border-top: none;
@include respond-to('sm') {
background: #FFFFFF;
}
@media (max-width: $breakpoint-md) { @media (max-width: $breakpoint-md) {
padding: $spacing-md $spacing-lg $spacing-lg; padding: 16px;
} }
.faq-answer-content { .faq-answer-content {
font-size: 18px; font-size: 14px;
font-weight: $font-weight-regular; color: #000;
color: #515151; line-height: 1.6;
background-color: #ffffff;
padding: $spacing-lg;
line-height: $line-height-loose;
@media (max-width: $breakpoint-md) { @media (max-width: $breakpoint-md) {
font-size: 14px; font-size: 13px;
} }
// Content formatting // Content formatting
p { p {
margin-bottom: $spacing-md; margin-bottom: 8px;
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
} }
ul, ol { ul,
margin: $spacing-sm 0; ol {
padding-left: $spacing-lg; margin: 8px 0;
padding-left: 20px;
} }
li { li {
margin-bottom: $spacing-xs; margin-bottom: 4px;
} }
a { a {
@@ -225,6 +234,7 @@
opacity: 0; opacity: 0;
transform: translateY(-10px); transform: translateY(-10px);
} }
to { to {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
@@ -41,9 +41,7 @@
// ── 댓글 목록 박스 (설계서 ① 영역) ───────────────────────── // ── 댓글 목록 박스 (설계서 ① 영역) ─────────────────────────
.djb-comment-list-box { .djb-comment-list-box {
padding: 24px 28px;
background-color: #FFFFFF; background-color: #FFFFFF;
border: 1px solid #E5E7EB;
border-radius: 8px; border-radius: 8px;
min-height: 120px; min-height: 120px;
margin-bottom: 28px; margin-bottom: 28px;
@@ -64,16 +62,16 @@
// ── 댓글 한 건 (설계서 작성자 + 날짜 + Contents) ─────────── // ── 댓글 한 건 (설계서 작성자 + 날짜 + Contents) ───────────
.djb-comment-item { .djb-comment-item {
padding: 18px 0; padding: 40px 0;
border-bottom: 1px dashed #E5E7EB; border-bottom: 1px solid #DFDFDF;
&:first-child { &:first-child {
padding-top: 4px; padding-top: 20px;
} }
&:last-child { &:last-child {
border-bottom: none; border-bottom: none;
padding-bottom: 4px; padding-bottom: 20px;
} }
&--admin .djb-comment-writer { &--admin .djb-comment-writer {
@@ -94,21 +92,21 @@
} }
.djb-comment-writer { .djb-comment-writer {
font-size: 18px; font-size: 14px;
font-weight: 700; font-weight: 500;
color: #111827; color: #000;
letter-spacing: -0.2px; letter-spacing: -0.2px;
} }
.djb-comment-admin-badge { .djb-comment-admin-badge {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
padding: 2px 8px; padding: 3px 8px;
background-color: #DBEAFE; background-color: #ecf1ff;
color: #1D4ED8; color: #2a69de;
border-radius: 10px; border-radius: 10px;
font-size: 11px; font-size: 9px;
font-weight: 600; font-weight: 700;
} }
.djb-comment-meta-right { .djb-comment-meta-right {
@@ -123,29 +121,32 @@
} }
.djb-comment-delete-btn { .djb-comment-delete-btn {
background: none; background: #fbe7e9;
border: 1px solid #E5E7EB; border: 1px solid #f1c2d6;
border-radius: 4px; border-radius: 5px;
padding: 3px 10px; padding: 3px 6px;
font-size: 12px; font-size: 10px;
color: #6B7280; font-weight: 500;
color: #bb1026;
cursor: pointer; cursor: pointer;
transition: all 0.15s ease; transition: all 0.15s ease;
display: flex;
align-items: center;
justify-content: center;
height: 20px;
&:hover { &:hover {
background-color: #FEE2E2; background-color: #f1c2d6; // Changed from darken(#fbe7e9, 5%) to fix warning
border-color: #FCA5A5;
color: #B91C1C;
} }
} }
.djb-comment-body { .djb-comment-body {
padding: 12px 16px; padding: 24px;
background-color: #F3F4F6; background-color: #f4f5f9;
border-radius: 6px; border-radius: 10px;
font-size: 14px; font-size: 14px;
line-height: 1.6; line-height: 20px;
color: #1F2937; color: #000;
white-space: pre-wrap; white-space: pre-wrap;
word-break: break-word; word-break: break-word;
} }
@@ -167,31 +168,31 @@ textarea.djb-comment-input {
display: block; display: block;
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
padding: 16px 18px; padding: 14px 18px;
border: 1px solid #D1D5DB; border: 1px solid #dfdfdf;
border-radius: 8px; border-radius: 10px;
background-color: #F9FAFB; background-color: #ffffff;
font-size: 14px; font-size: 14px;
line-height: 1.6; line-height: 1.6;
color: #1F2937; color: #000;
resize: vertical; resize: vertical;
min-height: 120px; min-height: 103px;
font-family: inherit; font-family: inherit;
outline: none; outline: none;
transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease; transition: border-color 0.15s ease, box-shadow 0.15s ease;
&::placeholder { &::placeholder {
color: #9CA3AF; color: #7f8a95;
} }
&:hover { &:hover {
border-color: #9CA3AF; border-color: #2a69de;
} }
&:focus { &:focus {
border-color: #1D4ED8; border-color: #2a69de;
background-color: #FFFFFF; background-color: #FFFFFF;
box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.15); box-shadow: 0 0 0 3px rgba(42, 105, 222, 0.1);
} }
} }
@@ -209,28 +210,22 @@ textarea.djb-comment-input {
} }
button.djb-comment-submit { button.djb-comment-submit {
display: inline-block; display: flex;
min-width: 140px; align-items: center;
padding: 12px 28px; justify-content: center;
background-color: #1D4ED8; width: 149px;
color: #FFFFFF; height: 39px;
border: 1px solid #1D4ED8; background-color: #ffffff;
border-radius: 8px; color: #4685ef;
font-size: 15px; border: 1px solid #2a69de;
border-radius: 10px;
font-size: 14px;
font-weight: 700; font-weight: 700;
letter-spacing: -0.2px;
cursor: pointer; cursor: pointer;
appearance: none; transition: all 0.2s ease;
-webkit-appearance: none;
line-height: 1.2;
text-align: center;
box-shadow: 0 2px 6px rgba(29, 78, 216, 0.18);
transition: background-color 0.15s ease, box-shadow 0.15s ease, transform 0.05s ease;
&:hover { &:hover {
background-color: #1E40AF; background-color: #f8faff;
border-color: #1E40AF;
box-shadow: 0 3px 10px rgba(29, 78, 216, 0.28);
} }
&:active { &:active {
@@ -238,9 +233,9 @@ button.djb-comment-submit {
} }
&:disabled { &:disabled {
background-color: #94A3B8; background-color: #f4f5f9;
border-color: #94A3B8; border-color: #dfdfdf;
box-shadow: none; color: #7f8a95;
cursor: not-allowed; cursor: not-allowed;
} }
} }
@@ -13,7 +13,7 @@
label { label {
display: block; display: block;
font-size: $font-size-sm; font-size: $font-size-sm;
font-weight: $font-weight-medium; font-weight: $font-weight-semibold;
color: $text-dark; color: $text-dark;
margin-bottom: $spacing-sm; margin-bottom: $spacing-sm;
@@ -453,6 +453,7 @@ select.form-control {
.form-field-wrapper { .form-field-wrapper {
flex: 1; flex: 1;
@include respond-to('sm') { @include respond-to('sm') {
width: 100%; width: 100%;
} }
@@ -757,6 +758,7 @@ select.form-control {
} }
.btn { .btn {
// Figma 모바일 (1291-3170): 144px × 40px, border-radius 8px, 14px bold // Figma 모바일 (1291-3170): 144px × 40px, border-radius 8px, 14px bold
@include respond-to('sm') { @include respond-to('sm') {
width: 144px !important; width: 144px !important;
@@ -960,3 +962,71 @@ select.form-control {
display: flex; display: flex;
align-items: center; align-items: center;
} }
// -----------------------------------------------------------------------------
// DJB Common Form Elements (Global Reusable Styles)
// -----------------------------------------------------------------------------
.djb-label {
display: block;
font-size: 14px;
font-weight: 700;
color: #000;
margin-bottom: 12px;
.required {
color: #e53e3e;
margin-left: 4px;
}
}
.djb-input {
width: 100%;
padding: 14px 18px;
border: 1px solid #DFDFDF;
border-radius: 8px;
font-size: 14px;
color: #000;
transition: border-color 0.2s;
background-color: #fcfcfc;
&::placeholder {
color: #94A3B8;
}
&:focus {
outline: none;
border-color: #2a69de;
}
}
.djb-textarea {
width: 100%;
padding: 14px 18px;
border: 1px solid #DFDFDF;
border-radius: 8px;
font-size: 14px;
color: #000;
resize: none;
transition: border-color 0.2s;
min-height: 250px;
&::placeholder {
color: #94A3B8;
}
&:focus {
outline: none;
border-color: #2a69de;
}
}
.djb-char-counter-wrapper {
text-align: right;
margin-top: 8px;
.char-counter {
font-size: 13px;
color: #7f8a95;
}
}
@@ -587,17 +587,17 @@
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 0 $spacing-sm; padding: 0 $spacing-md;
height: 30px; height: 28px;
white-space: nowrap; white-space: nowrap;
border-radius: $border-radius-sm; border-radius: 5px;
font-size: 13px; font-size: 12px;
font-weight: $font-weight-regular; font-weight: $font-weight-regular;
font-family: 'Spoqa Han Sans Neo', sans-serif;
color: #000000; color: #000000;
border: none; border: 1px solid transparent;
cursor: pointer; cursor: pointer;
transition: $transition-base; transition: $transition-base;
white-space: nowrap;
&:hover { &:hover {
transform: translateY(-1px); transform: translateY(-1px);
@@ -610,35 +610,42 @@
// Button variants // Button variants
&--default { &--default {
background-color: #DADADA; background-color: #f5f5f4;
border-color: #bdc7cf;
color: #64748b;
&:hover { &:hover {
background-color: darken(#DADADA, 5%); background-color: darken(#f5f5f4, 5%);
} }
} }
&--primary { &--primary {
background-color: #A4D6EA; background-color: #ecf0fa;
border-color: #4685ef;
color: #2a69de;
&:hover { &:hover {
background-color: darken(#A4D6EA, 5%); background-color: darken(#ecf0fa, 5%);
} }
} }
&--secondary { &--secondary {
background-color: #CDD4F0; background-color: #f5f5f4;
border-color: #bdc7cf;
color: #64748b;
&:hover { &:hover {
background-color: darken(#CDD4F0, 5%); background-color: darken(#f5f5f4, 5%);
} }
} }
&--danger { &--danger {
background-color: #F8D7DA; background-color: #fbe7e9;
color: #B02A37; border-color: #f1c2d6;
color: #bb1026;
&:hover { &:hover {
background-color: darken(#F8D7DA, 5%); background-color: darken(#fbe7e9, 5%);
} }
} }
} }
@@ -1176,7 +1176,8 @@
color: white; color: white;
.card-title ,.card-description { .card-title,
.card-description {
color: white; color: white;
} }
} }
@@ -2029,7 +2030,10 @@
color: #FFFFFF; color: #FFFFFF;
border: none; border: none;
h3, p, .card-icon, .card-arrow { h3,
p,
.card-icon,
.card-arrow {
color: #FFFFFF; color: #FFFFFF;
} }
@@ -2643,6 +2647,7 @@
font-size: 30px; font-size: 30px;
color: #000000; color: #000000;
line-height: normal; line-height: normal;
font-weight: 600;
margin: 0; margin: 0;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
@@ -26,6 +26,7 @@
.inquiry-header { .inquiry-header {
margin-bottom: $spacing-3xl; margin-bottom: $spacing-3xl;
@media (max-width: $breakpoint-sm) { @media (max-width: $breakpoint-sm) {
margin-bottom: $spacing-2xl; margin-bottom: $spacing-2xl;
} }
@@ -261,13 +262,68 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
gap: $spacing-md; gap: $spacing-md;
margin-top: $spacing-xl; margin-top: 40px;
@media (max-width: $breakpoint-sm) { @media (max-width: $breakpoint-sm) {
flex-direction: column; flex-direction: column;
align-items: stretch; align-items: stretch;
} }
// List Button - Figma Design
.btn-inquiry-new {
display: flex;
align-items: center;
justify-content: center;
width: 247px;
height: 60px;
background: #2a69de;
color: #fff;
border: none;
font-size: 20px;
font-weight: 700;
border-radius: 10px;
cursor: pointer;
text-decoration: none;
transition: $transition-base;
@media (max-width: $breakpoint-md) {
width: 100%;
height: 50px;
font-size: 16px;
}
&:hover {
background: #1d52b5; // Changed from darken(#2a69de, 10%)
transform: translateY(-2px);
}
&--outline {
background: #fff;
color: #2a69de;
border: 1px solid #2a69de;
width: 120px;
height: 50px;
font-size: 16px;
&:hover {
background: #f8faff;
}
}
&--danger {
background: #fff;
color: #bb1026;
border: 1px solid #bb1026;
width: 120px;
height: 50px;
font-size: 16px;
&:hover {
background: #fdf5f6;
}
}
}
// Layout for detail page split actions // Layout for detail page split actions
.actions-left, .actions-left,
.actions-right { .actions-right {
@@ -307,71 +363,115 @@
} }
.inquiry-detail-container { .inquiry-detail-container {
min-height: 600px; padding: 0;
margin: 0 auto; background: transparent;
} box-shadow: none;
min-height: auto;
margin: 0;
// Inquiry detail card // Header styles
.inquiry-detail-card { .notice-detail-header {
background: $white; border-bottom: 1px solid #000;
border-radius: $border-radius-lg; padding-bottom: 25px;
box-shadow: $shadow-md;
overflow: hidden;
margin-bottom: $spacing-xl;
// Header section .inquiry-header-meta {
.detail-header {
padding: $spacing-3xl $spacing-2xl $spacing-xl;
border-bottom: 2px solid $border-gray;
@media (max-width: $breakpoint-sm) {
padding: $spacing-2xl $spacing-lg $spacing-md;
}
// Status badge header styles now in components/_badges.scss
.inquiry-title {
font-size: $font-size-2xl;
font-weight: $font-weight-bold;
color: $text-dark;
line-height: $line-height-tight;
margin-bottom: $spacing-lg;
@media (max-width: $breakpoint-sm) {
font-size: $font-size-xl;
}
}
.inquiry-meta {
display: flex; display: flex;
align-items: center; gap: 6px;
gap: $spacing-lg; font-size: 16px;
flex-wrap: wrap; color: #767e89;
font-size: $font-size-sm; margin-bottom: 17px;
color: $text-gray;
@media (max-width: $breakpoint-sm) {
font-size: $font-size-xs;
gap: $spacing-md;
} }
.meta-item { .notice-detail-title-wrapper {
display: flex; display: flex;
align-items: flex-end;
gap: 15px;
@media (max-width: $breakpoint-md) {
flex-direction: column;
align-items: flex-start;
gap: 8px;
}
}
.notice-detail-title {
margin: 0;
font-size: 28px;
font-weight: 500;
@media (max-width: $breakpoint-md) {
font-size: 22px;
}
}
}
// Detail body
.notice-detail-body {
padding-top: 20px;
border-bottom: 1px solid #dfdfdf;
font-size: 14px;
line-height: 20px;
color: #000;
img {
max-width: 100%;
height: auto;
}
}
// Admin response
.inquiry-response-section {
padding-top: 40px;
padding-bottom: 40px;
border-bottom: 1px solid #dfdfdf;
.inquiry-response-header {
display: flex;
justify-content: space-between;
align-items: center; align-items: center;
gap: $spacing-xs; margin-bottom: 0px;
border: none;
i { .response-admin {
color: $primary-blue; display: flex;
gap: 9px;
align-items: center;
.admin-label {
font-size: 14px;
font-weight: 500;
color: #000;
} }
strong { .admin-badge {
color: $text-dark; background: #ecf1ff;
font-weight: $font-weight-medium; color: #2a69de;
} font-size: 9px;
font-weight: 700;
padding: 3px 8px;
border-radius: 10px;
}
}
.response-meta {
color: #767e89;
font-size: 14px;
}
}
.inquiry-response-body {
background: #f4f5f9;
border-radius: 10px;
padding: 24px;
font-size: 14px;
line-height: 20px;
color: #000;
} }
} }
} }
// Attachment section // Attachment section
.detail-attachments { .detail-attachments {
padding: $spacing-lg $spacing-2xl; padding: $spacing-lg $spacing-2xl;
@@ -442,7 +542,7 @@
} }
} }
} }
}
// Response section (answer from admin) // Response section (answer from admin)
.inquiry-response-card { .inquiry-response-card {
@@ -692,3 +792,74 @@
// Uses the same action button styles from .inquiry-actions above // Uses the same action button styles from .inquiry-actions above
// Supports: action-btn-primary, action-btn-secondary // Supports: action-btn-primary, action-btn-secondary
} }
// -----------------------------------------------------------------------------
// New DJB Board Write Form (피드백/개선요청, Q&A 등록 등)
// -----------------------------------------------------------------------------
.djb-board-write-container {
padding: 0;
.djb-board-write-header {
margin-bottom: 30px;
padding-bottom: 20px;
.title {
font-size: 24px;
font-weight: 700;
color: #000;
margin-bottom: 8px;
}
.subtitle {
font-size: 14px;
color: #7f8a95;
}
}
.djb-board-form {
.form-group {
margin-bottom: 30px;
}
}
.form-actions {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 40px;
.btn-cancel {
width: 100px;
height: 48px;
background-color: #fff;
border: 1px solid #DFDFDF;
border-radius: 8px;
color: #515961;
font-size: 15px;
font-weight: 700;
cursor: pointer;
transition: background-color 0.2s;
display: block;
&:hover {
background-color: #f8f9fa;
}
}
.btn-submit {
width: 100px;
height: 48px;
background-color: #2a69de;
border: 1px solid #2a69de;
border-radius: 8px;
color: #fff;
font-size: 15px;
font-weight: 700;
cursor: pointer;
&:hover {
background-color: darken(#2a69de, 5%);
}
}
}
}
@@ -71,6 +71,7 @@
margin: 0 auto; margin: 0 auto;
padding: $spacing-3xl 0; padding: $spacing-3xl 0;
min-height: 600px; min-height: 600px;
@media (max-width: $breakpoint-md) { @media (max-width: $breakpoint-md) {
padding: $spacing-2xl $spacing-md; padding: $spacing-2xl $spacing-md;
} }
@@ -78,10 +79,11 @@
// Notice Detail Header - Title and Date in one row // Notice Detail Header - Title and Date in one row
.notice-detail-header { .notice-detail-header {
margin-bottom: 26px; padding-bottom: 24px;
border-bottom: 1px solid #212529;
@media (max-width: $breakpoint-md) { @media (max-width: $breakpoint-md) {
margin-bottom: 16px; padding-bottom: 16px;
} }
} }
@@ -114,10 +116,12 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: 20px; height: 20px;
padding: 0 8px; width: 50px;
margin-right: 6px;
border-radius: 5px; border-radius: 5px;
font-size: 10px; font-size: 10px;
font-weight: 500; font-weight: 500;
box-sizing: border-box;
&--incident { &--incident {
border: 1px solid #f1c2d6; border: 1px solid #f1c2d6;
@@ -126,8 +130,33 @@
} }
&--maintenance { &--maintenance {
background: #fff4d6; background: #fdf4d4;
color: #9a6700; color: #ef9546;
border: 1px solid #ffcea1;
}
&--completed {
background: #e5f0ff;
color: #0a4ea3;
border: 1px solid #b3d4ff;
}
&--closed {
background: #f5f5f5;
color: #888888;
border: 1px solid #dedede;
}
&--pending {
background: #fdf4d4;
color: #ef9546;
border: 1px solid #ffcea1;
}
&--fix {
background: #e5f0ff;
color: #0a4ea3;
border: 1px solid #b3d4ff;
} }
} }
@@ -144,6 +173,7 @@
// Notice Attachment Section // Notice Attachment Section
.notice-detail-attachment { .notice-detail-attachment {
margin-top: 20px;
margin-bottom: 20px; margin-bottom: 20px;
padding: 15px 20px; padding: 15px 20px;
background: #f8fbfe; background: #f8fbfe;
@@ -197,13 +227,13 @@
// Incident Info Table // Incident Info Table
.notice-detail-incident-info { .notice-detail-incident-info {
margin-bottom: 10px; margin-bottom: 20px;
.detail-table { .detail-table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
table-layout: fixed; table-layout: fixed;
border-top: 1px solid #e3e8f0; border-top: none;
border-bottom: 1px solid #e3e8f0; border-bottom: 1px solid #e3e8f0;
tr { tr {
@@ -274,7 +304,8 @@
} }
} }
ul, ol { ul,
ol {
margin: $spacing-md 0; margin: $spacing-md 0;
padding-left: $spacing-xl; padding-left: $spacing-xl;
} }
@@ -321,6 +352,7 @@
} }
&:active { &:active {
transform: scale(0.98); transform: scale(0.98);
} }
} }
@@ -461,7 +493,12 @@
} }
} }
h1, h2, h3, h4, h5, h6 { h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: $spacing-xl; margin-top: $spacing-xl;
margin-bottom: $spacing-md; margin-bottom: $spacing-md;
font-weight: $font-weight-semibold; font-weight: $font-weight-semibold;
@@ -484,7 +521,8 @@
} }
} }
ul, ol { ul,
ol {
margin: $spacing-md 0; margin: $spacing-md 0;
padding-left: $spacing-xl; padding-left: $spacing-xl;
} }
@@ -759,9 +797,8 @@
} }
.inquiry-content-body { .inquiry-content-body {
background: #F6F9FB;
border-radius: 20px; border-radius: 20px;
padding: $spacing-2xl; padding: 10px 20px;
min-height: 200px; min-height: 200px;
font-size: $font-size-base; font-size: $font-size-base;
color: $text-dark; color: $text-dark;
@@ -139,6 +139,7 @@ $service-card-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgb
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 40px; gap: 40px;
min-width: 0; // Prevent flex item from expanding horizontally beyond parent
} }
.service-sidebar { .service-sidebar {
@@ -163,6 +164,44 @@ $service-card-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgb
transition: transform 0.3s ease, box-shadow 0.3s ease; transition: transform 0.3s ease, box-shadow 0.3s ease;
} }
.service-sidebar__profile {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
.avatar {
width: 53px;
height: 52px;
background-color: #9ac8ee;
border-radius: 11px;
display: flex;
align-items: center;
justify-content: center;
svg {
width: 36px;
height: 36px;
fill: #ffffff;
}
}
.user-name {
font-size: 16px;
font-weight: 500;
color: #000000;
text-align: center;
margin: 0;
}
}
.service-sidebar__divider {
height: 1px;
background-color: #e3e8f0;
margin: 4px 0;
width: 100%;
}
&__item { &__item {
font-size: 16px; font-size: 16px;
font-weight: 500; font-weight: 500;
@@ -13,6 +13,7 @@
margin: 0 auto; margin: 0 auto;
padding: $spacing-3xl 0; padding: $spacing-3xl 0;
margin-bottom: $spacing-2xl; margin-bottom: $spacing-2xl;
min-height: 750px; // Ensure the footer doesn't float when content is short
@media (max-width: $breakpoint-sm) { @media (max-width: $breakpoint-sm) {
padding: $spacing-lg $spacing-md; padding: $spacing-lg $spacing-md;
@@ -67,8 +68,25 @@
// Extends .list-table from components/_tables.scss // Extends .list-table from components/_tables.scss
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
.user-management-container { .user-management-container {
.list-table { .board-table {
margin-bottom: $spacing-2xl; margin-bottom: $spacing-2xl;
overflow-x: auto;
// Allow table rows to expand if buttons wrap
.board-table-row {
height: auto;
min-height: 50px;
.row-cell.row-actions {
white-space: normal;
}
}
.actions-desktop {
flex-wrap: wrap;
justify-content: center;
gap: 6px;
}
// Link styles in table cells // Link styles in table cells
.row-cell a { .row-cell a {
@@ -82,6 +100,39 @@
} }
} }
// Grid layout for user list table to avoid inline styles
.board-table--user-list {
.board-table-header,
.board-table-row {
display: grid;
grid-template-columns: 24px 112px 1fr 100px 100px 287px;
padding: 0 29px; // Match standard board-table padding
gap: 10px;
@media (max-width: $breakpoint-sm) {
display: flex;
padding: 15px;
min-width: auto;
}
}
.header-cell,
.row-cell {
padding: 0;
width: 100%;
box-sizing: border-box;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
}
.table-controls { .table-controls {
@extend .common-title-bar; @extend .common-title-bar;
@@ -92,7 +143,14 @@
.search-box { .search-box {
.btn { .btn {
height: 44px; height: 48px;
background-color: #2a69de;
border: 1px solid #2a69de;
border-radius: 9px;
color: #fff;
font-size: 15px;
font-weight: 700;
cursor: pointer;
} }
} }
} }
@@ -101,15 +159,22 @@
// Current user badge (used in actions column) // Current user badge (used in actions column)
.user-current-badge { .user-current-badge {
display: inline-flex; display: inline-flex;
height: 30px;
align-items: center; align-items: center;
gap: 6px; justify-content: center;
padding: 0 $spacing-sm; padding: 0 16px;
background-color: rgba($accent-purple, 0.1); height: 28px;
color: $accent-purple; background-color: #ecf0fa;
border-radius: $border-radius-sm; color: #2a69de;
font-size: 13px; border: 1px solid #4685ef;
font-weight: $font-weight-medium; border-radius: 5px;
font-size: 12px;
font-weight: 400;
font-family: 'Spoqa Han Sans Neo', sans-serif;
gap: 4px;
i {
display: none; // Hide the icon to match Figma exactly
}
// 모바일에서 숨김 // 모바일에서 숨김
@media (max-width: $breakpoint-sm) { @media (max-width: $breakpoint-sm) {
@@ -339,9 +404,12 @@
} }
@keyframes pulse { @keyframes pulse {
0%, 100% {
0%,
100% {
opacity: 1; opacity: 1;
} }
50% { 50% {
opacity: 0.5; opacity: 0.5;
} }
@@ -415,6 +483,7 @@
// 사용자 관리 모바일 디자인 // 사용자 관리 모바일 디자인
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@media (max-width: $breakpoint-sm) { @media (max-width: $breakpoint-sm) {
// Show mobile actions, hide desktop actions // Show mobile actions, hide desktop actions
.actions-desktop { .actions-desktop {
display: none !important; display: none !important;
@@ -659,7 +728,8 @@
width: 20px; width: 20px;
height: 20px; height: 20px;
i, svg { i,
svg {
font-size: 14px; font-size: 14px;
width: 14px; width: 14px;
height: 14px; height: 14px;
@@ -693,6 +763,7 @@
.list-table { .list-table {
.list-table-header { .list-table-header {
.header-cell { .header-cell {
// NO 컬럼 - 모바일에서 숨김 // NO 컬럼 - 모바일에서 숨김
&:nth-child(1) { &:nth-child(1) {
display: none; display: none;
@@ -729,6 +800,7 @@
.list-table-row { .list-table-row {
.row-cell { .row-cell {
// NO 컬럼 - 모바일에서 숨김 // NO 컬럼 - 모바일에서 숨김
&:nth-child(1), &:nth-child(1),
&.row-cell--number { &.row-cell--number {
@@ -840,6 +912,7 @@
.list-table { .list-table {
.list-table-header { .list-table-header {
.header-cell { .header-cell {
// NO 컬럼 - 모바일에서 숨김 // NO 컬럼 - 모바일에서 숨김
&:nth-child(1) { &:nth-child(1) {
display: none; display: none;
@@ -862,6 +935,7 @@
.list-table-row { .list-table-row {
.row-cell { .row-cell {
// NO 컬럼 - 모바일에서 숨김 // NO 컬럼 - 모바일에서 숨김
&:nth-child(1), &:nth-child(1),
&.row-cell--number { &.row-cell--number {
@@ -10,7 +10,8 @@
<div class="service-hero__inner"> <div class="service-hero__inner">
<div class="service-hero__icon-wrapper"> <div class="service-hero__icon-wrapper">
<!-- TODO: Update icon to faq icon --> <!-- TODO: Update icon to faq icon -->
<img th:src="@{/img/keyimage/notice_img.svg}" alt="FAQ 아이콘" style="width: 100%; height: 100%; object-fit: contain;" /> <img th:src="@{/img/keyimage/faq_img.svg}" alt="FAQ 아이콘"
style="width: 100%; height: 100%; object-fit: contain;" />
</div> </div>
<div class="service-hero__content"> <div class="service-hero__content">
<div class="service-hero__badge"> <div class="service-hero__badge">
@@ -18,7 +19,8 @@
<span class="service-hero__badge-text">FAQ 게시판</span> <span class="service-hero__badge-text">FAQ 게시판</span>
</div> </div>
<h1 class="service-hero__title">FAQ</h1> <h1 class="service-hero__title">FAQ</h1>
<p class="service-hero__desc">서비스 이용 중 궁금한 사항에 대한 답변을 빠르게 확인해 보세요<br>카테고리별 분류와 검색을 통해 원하는 정보를 쉽게 찾아보실 수 있습니다.</p> <p class="service-hero__desc">서비스 이용 중 궁금한 사항에 대한 답변을 빠르게 확인해 보세요<br>카테고리별 분류와 검색을 통해 원하는 정보를 쉽게 찾아보실 수
있습니다.</p>
</div> </div>
</div> </div>
</section> </section>
@@ -30,7 +32,8 @@
<!-- Content --> <!-- Content -->
<section class="service-content"> <section class="service-content">
<div class="notice-list-container" style="padding: 0; min-height: auto; margin: 0; background: transparent; box-shadow: none;"> <div class="notice-list-container"
style="padding: 0; min-height: auto; margin: 0; background: transparent; box-shadow: none;">
<!-- Search and Filter Controls --> <!-- Search and Filter Controls -->
<form name="faqForm" th:action="@{/faq_list}" method="post" th:object="${search}" onsubmit="return false;"> <form name="faqForm" th:action="@{/faq_list}" method="post" th:object="${search}" onsubmit="return false;">
@@ -43,13 +46,13 @@
</h2> </h2>
<div class="search-field"> <div class="search-field">
<input type="text" <input type="text" th:field="*{searchWrd}" placeholder="질문 또는 답변 내용으로 검색"
th:field="*{searchWrd}"
placeholder="질문 또는 답변 내용으로 검색"
onkeypress="if(event.keyCode === 13) { fn_search_faq(); return false; }"> onkeypress="if(event.keyCode === 13) { fn_search_faq(); return false; }">
<button type="button" class="search-field-btn" onclick="fn_search_faq()"> <button type="button" class="search-field-btn" onclick="fn_search_faq()">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.5 17.5L13.875 13.875M15.8333 9.16667C15.8333 12.8486 12.8486 15.8333 9.16667 15.8333C5.48477 15.8333 2.5 12.8486 2.5 9.16667C2.5 5.48477 5.48477 2.5 9.16667 2.5C12.8486 2.5 15.8333 5.48477 15.8333 9.16667Z" stroke="currentColor" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/> <path
d="M17.5 17.5L13.875 13.875M15.8333 9.16667C15.8333 12.8486 12.8486 15.8333 9.16667 15.8333C5.48477 15.8333 2.5 12.8486 2.5 9.16667C2.5 5.48477 5.48477 2.5 9.16667 2.5C12.8486 2.5 15.8333 5.48477 15.8333 9.16667Z"
stroke="currentColor" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round" />
</svg> </svg>
<span class="blind">검색</span> <span class="blind">검색</span>
</button> </button>
@@ -61,11 +64,13 @@
<div class="faq-accordion" th:if="${!#lists.isEmpty(page.content)}"> <div class="faq-accordion" th:if="${!#lists.isEmpty(page.content)}">
<div class="faq-item" th:each="faq : ${page.content}"> <div class="faq-item" th:each="faq : ${page.content}">
<div class="faq-question"> <div class="faq-question">
<span class="faq-question-q" style="font-family: 'OneShinhan', sans-serif; font-size: 20px; font-weight: 700; color: #555; margin-right: 15px;">Q</span> <span class="faq-question-q"
style="font-family: 'OneShinhan', sans-serif; font-size: 20px; font-weight: 700; color: #555; margin-right: 15px;">Q</span>
<span class="faq-question-text" th:text="${faq.faqQuestion}">질문 내용이 여기에 표시됩니다.</span> <span class="faq-question-text" th:text="${faq.faqQuestion}">질문 내용이 여기에 표시됩니다.</span>
<span class="faq-icon"> <span class="faq-icon">
<svg width="14" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="14" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 1L7 7L13 1" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M1 1L7 7L13 1" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round" />
</svg> </svg>
</span> </span>
</div> </div>
@@ -80,7 +85,8 @@
<!-- Empty State --> <!-- Empty State -->
<div class="user-empty-state" th:if="${#lists.isEmpty(page.content)}"> <div class="user-empty-state" th:if="${#lists.isEmpty(page.content)}">
<div class="empty-icon"> <div class="empty-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" viewBox="0 0 120 120" fill="none" role="img" aria-label="데이터 없음"> <svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" viewBox="0 0 120 120" fill="none"
role="img" aria-label="데이터 없음">
<circle cx="60" cy="60" r="50" fill="#F3F4F6" /> <circle cx="60" cy="60" r="50" fill="#F3F4F6" />
<rect x="30" y="35" width="60" height="50" rx="4" fill="#E5E7EB" stroke="#D1D5DB" stroke-width="2" /> <rect x="30" y="35" width="60" height="50" rx="4" fill="#E5E7EB" stroke="#D1D5DB" stroke-width="2" />
<line x1="40" y1="50" x2="80" y2="50" stroke="#9CA3AF" stroke-width="2" stroke-linecap="round" /> <line x1="40" y1="50" x2="80" y2="50" stroke="#9CA3AF" stroke-width="2" stroke-linecap="round" />
@@ -11,59 +11,99 @@
</section> </section>
<section layout:fragment="contentFragment"> <section layout:fragment="contentFragment">
<div class="signup-guide-v2">
<!-- Hero Section -->
<section class="service-hero">
<div class="service-hero__inner">
<div class="service-hero__icon-wrapper">
<img th:src="@{/img/keyimage/q&a_img.svg}" alt="Q&A 아이콘"
style="width: 100%; height: 100%; object-fit: contain;" />
</div>
<div class="service-hero__content">
<div class="service-hero__badge">
<span class="service-hero__badge-dot"></span>
<span class="service-hero__badge-text">Q&A 게시판</span>
</div>
<h1 class="service-hero__title">Q&A</h1>
<p class="service-hero__desc">DJBank 오픈 API 이용 중 발생한 의문점이나 불편 사항을 보내주세요<br>접수해주신 문의 사항은 담당자 확인 후 빠르게 안내해
드리겠습니다.</p>
</div>
</div>
</section>
<!-- Main Content -->
<div class="service-main">
<!-- Sidebar -->
<th:block th:replace="~{fragment/djbank/service_sidebar :: sidebar('qna')}"></th:block>
<!-- Content -->
<section class="service-content">
<div class="inquiry-detail-container"> <div class="inquiry-detail-container">
<!-- Inquiry Header: Status Badge and Title --> <!-- Detail Header -->
<div class="inquiry-detail-header"> <div class="notice-detail-header">
<div class="inquiry-header-top"> <div class="inquiry-header-meta">
<span class="inquiry-status-badge" <span th:text="${#temporals.format(inquiry.createdDate, 'yyyy.MM.dd')}">2026.06.24</span>
th:classappend="${inquiry.inquiryStatus == 'RESPONDED' ? 'inquiry-status-badge--completed' : (inquiry.inquiryStatus == 'CLOSED' ? 'inquiry-status-badge--closed' : 'inquiry-status-badge--pending')}" <span>|</span>
th:text="${inquiry.inquiryStatus == 'RESPONDED' ? '답변완료' : (inquiry.inquiryStatus == 'CLOSED' ? '종료' : '답변대기')}"> <span
답변대기 th:text="${inquiry.inquirerName != null ? inquiry.inquirerName : (inquiry.inquirer != null ? inquiry.inquirer.userName : '')}">EACTIVE</span>
</span>
<div class="inquiry-header-right">
<span class="inquiry-detail-writer"
th:text="${inquiry.inquirerName != null ? inquiry.inquirerName : (inquiry.inquirer != null ? inquiry.inquirer.userName : '')}">작성자</span>
<span class="inquiry-detail-divider">|</span>
<span class="inquiry-detail-date" th:text="${#temporals.format(inquiry.createdDate, 'yyyy.MM.dd')}">2025.11.01</span>
</div> </div>
<div class="notice-detail-title-wrapper">
<span class="notice-type-badge notice-type-badge--completed"
th:if="${inquiry.inquiryStatus == 'RESPONDED'}">답변완료</span>
<span class="notice-type-badge notice-type-badge--closed"
th:if="${inquiry.inquiryStatus == 'CLOSED'}">종료</span>
<span class="notice-type-badge notice-type-badge--pending"
th:if="${inquiry.inquiryStatus != 'RESPONDED' and inquiry.inquiryStatus != 'CLOSED'}">답변대기</span>
<h2 class="notice-detail-title" th:text="${inquiry.inquirySubject}">질문 제목</h2>
</div> </div>
<h2 class="inquiry-detail-title" th:text="${inquiry.inquirySubject}">질문 제목</h2>
</div> </div>
<!-- Inquiry Content Section --> <!-- Detail Body -->
<div class="inquiry-detail-content"> <div class="notice-detail-body">
<div id="inquiryDetail" class="inquiry-content-body" th:utext="${inquiry.inquiryDetail}"> <div id="inquiryDetail" class="inquiry-content-body" th:utext="${inquiry.inquiryDetail}">
문의 내용이 여기에 표시됩니다. 문의 내용이 여기에 표시됩니다.
</div> </div>
</div> </div>
<!-- Admin Response Section --> <!-- Admin Response Section -->
<div class="inquiry-response-section" th:if="${inquiry.inquiryStatus == 'RESPONDED' or inquiry.inquiryStatus == 'CLOSED'}"> <div class="inquiry-response-section"
th:if="${inquiry.inquiryStatus == 'RESPONDED' or inquiry.inquiryStatus == 'CLOSED'}">
<div class="inquiry-response-header"> <div class="inquiry-response-header">
<span class="response-label">관리자 답변</span> <div class="response-admin">
<span class="response-date" th:text="${#temporals.format(inquiry.responseDate, 'yyyy.MM.dd')}">2025.11.02</span> <span class="admin-label">ADMIN</span>
<span class="admin-badge">관리자</span>
</div> </div>
<div class="inquiry-response-body" id="responseDetail" th:utext="${inquiry.responseDetail}"> <div class="response-meta">
<span th:text="${#temporals.format(inquiry.responseDate, 'yyyy.MM.dd')}">2026-06-24</span>
</div>
</div>
<div id="responseDetail" class="inquiry-response-body" th:utext="${inquiry.responseDetail}">
답변 내용이 여기에 표시됩니다. 답변 내용이 여기에 표시됩니다.
</div> </div>
</div> </div>
<!-- Comment Section (DJBank Custom DJPGPT0002) --> <!-- Comment Section (DJBank Custom DJPGPT0002) -->
<th:block th:replace="~{apps/community/djb/fragments-inquiry-comments :: commentSection(${inquiry}, ${commentWritable})}"></th:block> <th:block
th:replace="~{apps/community/djb/fragments-inquiry-comments :: commentSection(${inquiry}, ${commentWritable})}">
</th:block>
<!-- Action Buttons --> <!-- Action Buttons -->
<div class="inquiry-detail-actions"> <div class="inquiry-actions">
<div class="actions-left"> <button type="button" class="btn-inquiry-new" th:onclick="|location.href='@{/inquiry}'|">목록</button>
<button type="button" class="btn-inquiry-list" th:onclick="|location.href='@{/inquiry}'|">목록</button> <th:block
</div> th:if="${inquiry.inquiryStatus == 'PENDING' && inquiry.inquirer.id == #authentication.principal.id}">
<div class="actions-right" th:if="${inquiry.inquiryStatus == 'PENDING' && inquiry.inquirer.id == #authentication.principal.id}"> <form id="deleteForm" th:action="@{/inquiry/{id}/delete(id=${inquiry.id})}" method="post"
<form id="deleteForm" th:action="@{/inquiry/{id}/delete(id=${inquiry.id})}" method="post" style="display: none;"></form> style="display: none;"></form>
<button type="button" class="btn-inquiry-edit" th:onclick="|location.href='@{/inquiry/edit(id=${inquiry.id})}'|">수정</button> <button type="button" class="btn-inquiry-new btn-inquiry-new--outline"
<button type="button" class="btn-inquiry-delete" onclick="confirmDelete()">삭제</button> th:onclick="|location.href='@{/inquiry/edit(id=${inquiry.id})}'|">수정</button>
<button type="button" class="btn-inquiry-new btn-inquiry-new--danger"
onclick="confirmDelete()">삭제</button>
</th:block>
</div> </div>
</div> </div>
</section>
</div>
</div> </div>
</section> </section>
@@ -11,69 +11,85 @@
</section> </section>
<th:block layout:fragment="contentFragment" th:with="isNew=${inquiry.id == null}"> <th:block layout:fragment="contentFragment" th:with="isNew=${inquiry.id == null}">
<section class="inquiry-form-container"> <div class="signup-guide-v2">
<!-- Hero Section -->
<section class="service-hero">
<div class="service-hero__inner">
<div class="service-hero__icon-wrapper">
<img th:src="@{/img/keyimage/q&a_img.svg}" alt="Q&A 아이콘"
style="width: 100%; height: 100%; object-fit: contain;" />
</div>
<div class="service-hero__content">
<div class="service-hero__badge">
<span class="service-hero__badge-dot"></span>
<span class="service-hero__badge-text">Q&A 게시판</span>
</div>
<h1 class="service-hero__title">Q&A</h1>
<p class="service-hero__desc">DJBank 오픈 API 이용 중 발생한 의문점이나 불편 사항을 보내주세요<br>접수해주신 문의 사항은 담당자 확인 후 빠르게 안내해 드리겠습니다.</p>
</div>
</div>
</section>
<!-- Main Content -->
<div class="service-main">
<!-- Sidebar -->
<th:block th:replace="~{fragment/djbank/service_sidebar :: sidebar('qna')}"></th:block>
<!-- Content -->
<section class="service-content">
<div class="djb-board-write-container">
<!-- Title Bar --> <!-- Title Bar -->
<div class="register-title-bar"> <div class="djb-board-write-header">
<h2 class="register-title" th:text="${isNew ? '질문하기' : '질문 수정'}">질문하기</h2> <h2 class="title" th:text="${isNew ? '질문하기' : '질문 수정'}">질문하기</h2>
<span class="register-subtitle">궁금하신 사항을 작성해 주세요.</span> <p class="subtitle">궁금하신 사항을 작성해 주세요.</p>
</div> </div>
<!-- Form Content --> <!-- Form Content -->
<div class="register-form-container">
<form name="inquiryForm" id="inquiryForm" th:action="${isNew}? @{/inquiry} : @{/inquiry/edit}" <form name="inquiryForm" id="inquiryForm" th:action="${isNew}? @{/inquiry} : @{/inquiry/edit}"
th:object="${inquiry}" method="post" class="register-form"> th:object="${inquiry}" method="post" class="djb-board-form">
<input type="hidden" th:field="*{id}" th:if="${!isNew}"> <input type="hidden" th:field="*{id}" th:if="${!isNew}">
<!-- Subject Field --> <!-- Subject Field -->
<div class="form-row"> <div class="form-group">
<div class="form-label-wrapper label-offset"> <label class="djb-label" for="inquirySubject">제목 <span class="required">*</span></label>
<span class="form-label-text">제목</span>
<span class="required-badge">필수</span>
</div>
<div class="form-field-wrapper">
<input type="text" <input type="text"
id="inquirySubject" id="inquirySubject"
th:field="*{inquirySubject}" th:field="*{inquirySubject}"
class="form-input" class="djb-input"
placeholder="제목을 입력하세요" placeholder="제목을 입력하세요"
required required
maxlength="200"> maxlength="200">
</div> </div>
</div>
<!-- Content Field --> <!-- Content Field -->
<div class="form-row"> <div class="form-group">
<div class="form-label-wrapper"> <label class="djb-label" for="inquiryDetail">내용 <span class="required">*</span></label>
<span class="form-label-text">내용</span>
<span class="required-badge">필수</span>
</div>
<div class="form-field-wrapper">
<textarea id="inquiryDetail" <textarea id="inquiryDetail"
th:field="*{inquiryDetail}" th:field="*{inquiryDetail}"
class="form-textarea" class="djb-textarea"
rows="10"
placeholder="내용을 입력하세요" placeholder="내용을 입력하세요"
required required
maxlength="2000"></textarea> maxlength="2000"></textarea>
<small class="char-counter-wrapper"> <div class="djb-char-counter-wrapper">
<span class="char-counter">0 / 2000</span> <span class="char-counter">0 / 2000</span>
</small>
</div> </div>
</div> </div>
</form> </form>
</div>
<!-- Form Actions --> <!-- Form Actions -->
<div class="form-actions"> <div class="form-actions">
<button type="button" class="btn btn-submit btn-secondary" th:onclick="|location.href='@{/inquiry}'|">취소</button> <button type="button" class="btn-cancel" th:onclick="|location.href='@{/inquiry}'|">취소</button>
<button type="button" class="btn btn-submit btn-primary btn-submit-form"> <button type="button" class="btn-submit btn-submit-form">
<span th:text="${isNew ? '등록' : '수정'}">등록</span> <span th:text="${isNew ? '등록' : '수정'}">등록</span>
</button> </button>
</div> </div>
</div>
</section> </section>
</div>
</div>
</th:block> </th:block>
</body> </body>
@@ -85,12 +85,9 @@
<a th:href="@{/portalnotice/detail(id=${notice.id})}" class="notice-title-link"> <a th:href="@{/portalnotice/detail(id=${notice.id})}" class="notice-title-link">
<span class="notice-number" <span class="notice-number"
th:text="|[${page.totalElements - (page.number * page.size) - status.index}]|">[1]</span> th:text="|[${page.totalElements - (page.number * page.size) - status.index}]|">[1]</span>
<span class="notice-fix-badge" th:if="${notice.fixYn == 'Y'}" <span class="notice-type-badge notice-type-badge--fix" th:if="${notice.fixYn == 'Y'}">고정</span>
style="display:inline-block;padding:2px 8px;margin-right:6px;border-radius:10px;font-size:12px;background:#e5f0ff;color:#0a4ea3;font-weight:600;">고정</span> <span class="notice-type-badge notice-type-badge--incident" th:if="${notice.noticeType == '3'}">장애</span>
<span class="notice-type-badge notice-type-badge--incident" th:if="${notice.noticeType == '3'}" <span class="notice-type-badge notice-type-badge--maintenance" th:if="${notice.noticeType == '2'}">점검</span>
style="display:inline-block;padding:2px 8px;margin-right:6px;border-radius:10px;font-size:12px;background:#fde7e9;color:#c0152a;">장애</span>
<span class="notice-type-badge notice-type-badge--maintenance" th:if="${notice.noticeType == '2'}"
style="display:inline-block;padding:2px 8px;margin-right:6px;border-radius:10px;font-size:12px;background:#fff4d6;color:#9a6700;">점검</span>
<span th:text="${notice.noticeSubject}">공지사항 제목</span> <span th:text="${notice.noticeSubject}">공지사항 제목</span>
<span class="file-icon" th:if="${notice.fileId != null and !notice.fileId.isEmpty()}"> <span class="file-icon" th:if="${notice.fileId != null and !notice.fileId.isEmpty()}">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -11,109 +11,73 @@
</section> </section>
<th:block layout:fragment="contentFragment"> <th:block layout:fragment="contentFragment">
<section class="inquiry-form-container"> <div class="signup-guide-v2">
<!-- Hero Section -->
<section class="service-hero">
<div class="service-hero__inner">
<div class="service-hero__icon-wrapper">
<img th:src="@{/img/keyimage/feedback_img.svg}" alt="피드백 아이콘"
style="width: 100%; height: 100%; object-fit: contain;" />
</div>
<div class="service-hero__content">
<div class="service-hero__badge">
<span class="service-hero__badge-dot"></span>
<span class="service-hero__badge-text">피드백/개선요청</span>
</div>
<h1 class="service-hero__title">피드백/개선요청</h1>
<p class="service-hero__desc">DJBank 오픈 API 이용 중 발생한 피드백이나 개선요청을 보내주세요<br>작성해주신 내용은 담당자 확인 후 적극 반영하겠습니다.</p>
</div>
</div>
</section>
<!-- Main Content -->
<div class="service-main">
<!-- Sidebar -->
<th:block th:replace="~{fragment/djbank/service_sidebar :: sidebar('feedback')}"></th:block>
<!-- Content -->
<section class="service-content">
<div class="djb-board-write-container">
<!-- Title Bar --> <!-- Title Bar -->
<div class="register-title-bar"> <div class="djb-board-write-header">
<h2 class="register-title">피드백/개선요청</h2> <h2 class="title">피드백 / 개선 요청</h2>
<span class="register-subtitle">DJBank은 온라인 비즈니스 혁신을 위한 피드백/개선요청을 환영합니다.</span> <p class="subtitle">DJ Bank은 온라인 비즈니스 혁신을 위한 피드백/개선요청을 환영합니다.</p>
</div> </div>
<!-- Form Content --> <!-- Form Content -->
<div class="register-form-container">
<form name="partnershipForm" id="partnershipForm" th:action="@{/partnership}" th:object="${partnership}" <form name="partnershipForm" id="partnershipForm" th:action="@{/partnership}" th:object="${partnership}"
enctype="multipart/form-data" method="post" class="register-form"> enctype="multipart/form-data" method="post" class="djb-board-form">
<!-- 제목 Field --> <!-- 제목 Field -->
<div class="form-row"> <div class="form-group">
<div class="form-label-wrapper label-offset"> <label class="djb-label" for="bizSubject">제목 <span class="required">*</span></label>
<span class="form-label-text">제목</span> <input type="text" id="bizSubject" th:field="*{bizSubject}" class="djb-input"
<span class="required-badge">필수</span> placeholder="제안하고자 하는 제목을 입력해주세요" required maxlength="200">
</div>
<div class="form-field-wrapper">
<input type="text"
id="bizSubject"
th:field="*{bizSubject}"
class="form-input"
placeholder="제안하고자 하는 제목을 입력해 주세요"
required
maxlength="200">
</div>
</div> </div>
<!-- 사업 내용 Field --> <!-- 내용 Field -->
<div class="form-row"> <div class="form-group">
<div class="form-label-wrapper"> <label class="djb-label" for="bizDetail">내용 <span class="required">*</span></label>
<span class="form-label-text">내용</span> <textarea id="bizDetail" th:field="*{bizDetail}" class="djb-textarea"
<span class="required-badge">필수</span> placeholder="제안하고자 하는 내용을 상세히 입력해주세요" required maxlength="4000"></textarea>
</div> <div class="djb-char-counter-wrapper">
<div class="form-field-wrapper">
<textarea id="bizDetail"
th:field="*{bizDetail}"
class="form-textarea"
rows="10"
placeholder="제안하고자 하시는 내용을 상세히 입력해 주세요"
required
maxlength="4000"></textarea>
<small class="char-counter-wrapper">
<span class="char-counter">0 / 4000</span> <span class="char-counter">0 / 4000</span>
</small>
</div> </div>
</div> </div>
<!-- File Upload Field -->
<!--/* 260520 - DJB 에서는 첨부 파일 허용안함. */-->
<!--<div class="form-row">
<div class="form-label-wrapper label-offset">
<span class="form-label-text">첨부파일</span>
</div>
<div class="form-field-wrapper">
<div class="file-upload-inline">
<div class="file-input-display" id="fileInputDisplay">
<span class="file-display-text" id="fileDisplayText">선택된 파일이 없습니다</span>
<button type="button" class="btn-remove-file-inline" id="btnRemoveFile" title="파일 삭제" style="display: none;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
</div>
<button type="button" class="btn-file-attach" onclick="document.getElementById('file').click()">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 15.75C18 17.4833 17.3917 18.9583 16.175 20.175C14.9583 21.3917 13.4833 22 11.75 22C10.0167 22 8.54167 21.3917 7.325 20.175C6.10833 18.9583 5.5 17.4833 5.5 15.75V6.5C5.5 5.25 5.9375 4.1875 6.8125 3.3125C7.6875 2.4375 8.75 2 10 2C11.25 2 12.3125 2.4375 13.1875 3.3125C14.0625 4.1875 14.5 5.25 14.5 6.5V15.25C14.5 16.0167 14.2333 16.6667 13.7 17.2C13.1667 17.7333 12.5167 18 11.75 18C10.9833 18 10.3333 17.7333 9.8 17.2C9.26667 16.6667 9 16.0167 9 15.25V6H11V15.25C11 15.4667 11.0708 15.6458 11.2125 15.7875C11.3542 15.9292 11.5333 16 11.75 16C11.9667 16 12.1458 15.9292 12.2875 15.7875C12.4292 15.6458 12.5 15.4667 12.5 15.25V6.5C12.4833 5.8 12.2375 5.20833 11.7625 4.725C11.2875 4.24167 10.7 4 10 4C9.3 4 8.70833 4.24167 8.225 4.725C7.74167 5.20833 7.5 5.8 7.5 6.5V15.75C7.48333 16.9333 7.89167 17.9375 8.725 18.7625C9.55833 19.5875 10.5667 20 11.75 20C12.9167 20 13.9083 19.5875 14.725 18.7625C15.5417 17.9375 15.9667 16.9333 16 15.75V6H18V15.75Z" fill="currentColor"/>
</svg>
파일첨부
</button>
<input type="file"
id="file"
name="files"
th:accept="${isInternalUser ? '*' : '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.hwp,.gif,.jpg,.jpeg,.png'}"
style="display: none;">
</div>
<div class="form-help-text">
<p><i class="fas fa-check-circle"></i>
<span th:text="'첨부파일은 ' + ${@portalProperties.file.maxSize} + ' 이내로 등록해 주세요.'">첨부파일은 8MB 이내로 등록해 주세요.</span>
</p>
<p>
<i class="fas fa-check-circle"></i>
문서파일과 이미지 파일만 등록 가능합니다. (pdf, doc, docx, xls, xlsx, ppt, pptx, hwp, gif, jpg, png)
</p>
</div>
</div>
</div>-->
</form> </form>
</div>
<!-- Form Actions --> <!-- Form Actions -->
<div class="form-actions"> <div class="form-actions">
<button type="button" class="btn btn-submit btn-secondary" th:onclick="|location.href='@{/}'|">취소</button> <button type="button" class="btn-cancel" th:onclick="|location.href='@{/}'|">취소</button>
<button type="button" class="btn btn-submit btn-primary btn-submit-form"> <button type="button" class="btn-submit btn-submit-form">작성완료</button>
<span>작성 완료</span>
</button>
</div> </div>
</div>
</section> </section>
</div>
</div>
</th:block> </th:block>
</body> </body>
@@ -183,6 +147,7 @@
form.submit(); form.submit();
}); });
if (fileInput) {
fileInput.addEventListener('change', function () { fileInput.addEventListener('change', function () {
const file = fileInput.files[0]; const file = fileInput.files[0];
@@ -198,26 +163,34 @@
} }
/*[/]*/ /*[/]*/
if (fileDisplayText && fileInputDisplay && btnRemoveFile) {
fileDisplayText.textContent = file.name; fileDisplayText.textContent = file.name;
fileDisplayText.classList.add('has-file'); fileDisplayText.classList.add('has-file');
fileInputDisplay.classList.add('has-file'); fileInputDisplay.classList.add('has-file');
btnRemoveFile.style.display = 'flex'; btnRemoveFile.style.display = 'flex';
} }
}
}); });
}
// File remove handler // File remove handler
if (btnRemoveFile) {
btnRemoveFile.addEventListener('click', function (e) { btnRemoveFile.addEventListener('click', function (e) {
e.stopPropagation(); e.stopPropagation();
fileInput.value = ''; if (fileInput) fileInput.value = '';
if (fileDisplayText) {
fileDisplayText.textContent = '선택된 파일이 없습니다'; fileDisplayText.textContent = '선택된 파일이 없습니다';
fileDisplayText.classList.remove('has-file'); fileDisplayText.classList.remove('has-file');
fileInputDisplay.classList.remove('has-file'); }
btnRemoveFile.style.display = 'none'; if (fileInputDisplay) fileInputDisplay.classList.remove('has-file');
this.style.display = 'none';
}); });
}
// Focus on subject field // Focus on subject field
document.getElementById('bizSubject').focus(); document.getElementById('bizSubject').focus();
}); });
</script> </script>
</th:block> </th:block>
</html> </html>
@@ -162,17 +162,19 @@
<div class="hero-slide" data-slide="1"> <div class="hero-slide" data-slide="1">
<div class="hero-slide-content"> <div class="hero-slide-content">
<div class="hero-text-content"> <div class="hero-text-content">
<div class="hero-text"> <div class="hero-text">
<p class="hero-subtitle">더 안전하고 완벽한 거래</p> <p class="hero-subtitle">문서는 상세하게, 연동은 확실하게</p>
<h2 class="hero-title">광주은행 오픈 API<br>보안 솔루션</h2> <h2 class="hero-title">준비된 DJBank API<br>완벽한 서비스를 성공하세요.</h2>
</div> </div>
<a href="#" class="btn-hero-signup">개발 가이드 보기 <i class="bi bi-chevron-right"></i></a> <a href="#" class="btn-hero-signup">개발 가이드 보기 <i class="bi bi-chevron-right"></i></a>
</div> </div>
<div class="hero-image-content"> <div class="hero-image-content">
<svg class="hero-illustration" viewBox="0 0 500 400" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg class="hero-illustration" viewBox="0 0 500 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="250" cy="200" r="160" fill="url(#hero-grad-2)" opacity="0.15" /> <circle cx="250" cy="200" r="160" fill="url(#hero-grad-2)" opacity="0.15" />
<path d="M250 80L370 130V240C370 310 250 360 250 360C250 360 130 310 130 240V130L250 80Z" fill="#FFFFFF" <path d="M250 80L370 130V240C370 310 250 360 250 360C250 360 130 310 130 240V130L250 80Z"
stroke="#008AE2" stroke-width="6" class="floating-slow" /> fill="#FFFFFF" stroke="#008AE2" stroke-width="6" class="floating-slow" />
<path d="M250 140V280M180 210H320" stroke="#0049B4" stroke-width="6" stroke-linecap="round" <path d="M250 140V280M180 210H320" stroke="#0049B4" stroke-width="6" stroke-linecap="round"
opacity="0.2" /> opacity="0.2" />
<circle cx="250" cy="210" r="45" fill="#0049B4" /> <circle cx="250" cy="210" r="45" fill="#0049B4" />
@@ -210,13 +212,18 @@
<!-- Navigation Arrows --> <!-- Navigation Arrows -->
<button class="hero-nav-btn hero-nav-prev" id="heroPrevBtn" aria-label="이전 슬라이드"> <button class="hero-nav-btn hero-nav-prev" id="heroPrevBtn" aria-label="이전 슬라이드">
<svg width="18" height="32" viewBox="0 0 18 32" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform: scaleX(-1);"> <svg width="18" height="32" viewBox="0 0 18 32" fill="none" xmlns="http://www.w3.org/2000/svg"
<path d="M2.17021 31.1127L-0.000440909 28.942L13.3853 15.5564L-0.000438653 2.17065L2.17021 4.76837e-07L17.7266 15.5564L2.17021 31.1127Z" fill="#0049B4"/> style="transform: scaleX(-1);">
<path
d="M2.17021 31.1127L-0.000440909 28.942L13.3853 15.5564L-0.000438653 2.17065L2.17021 4.76837e-07L17.7266 15.5564L2.17021 31.1127Z"
fill="#0049B4" />
</svg> </svg>
</button> </button>
<button class="hero-nav-btn hero-nav-next" id="heroNextBtn" aria-label="다음 슬라이드"> <button class="hero-nav-btn hero-nav-next" id="heroNextBtn" aria-label="다음 슬라이드">
<svg width="18" height="32" viewBox="0 0 18 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="18" height="32" viewBox="0 0 18 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.17021 31.1127L-0.000440909 28.942L13.3853 15.5564L-0.000438653 2.17065L2.17021 4.76837e-07L17.7266 15.5564L2.17021 31.1127Z" fill="#0049B4"/> <path
d="M2.17021 31.1127L-0.000440909 28.942L13.3853 15.5564L-0.000438653 2.17065L2.17021 4.76837e-07L17.7266 15.5564L2.17021 31.1127Z"
fill="#0049B4" />
</svg> </svg>
</button> </button>
@@ -312,7 +319,8 @@
<span class="search-tag-divider">|</span> <span class="search-tag-divider">|</span>
<div class="search-tag-list" th:if="${hashtags != null and not #lists.isEmpty(hashtags)}"> <div class="search-tag-list" th:if="${hashtags != null and not #lists.isEmpty(hashtags)}">
<th:block th:each="hashtag, iterStat : ${hashtags}"> <th:block th:each="hashtag, iterStat : ${hashtags}">
<a href="#" class="search-tag-link hashtag-link" th:data-search="${hashtag}" th:text="${'#' + hashtag}"> <a href="#" class="search-tag-link hashtag-link" th:data-search="${hashtag}"
th:text="${'#' + hashtag}">
</a> </a>
<!-- <span class="hashtag-separator" th:unless="${iterStat.last}">|</span>--> <!-- <span class="hashtag-separator" th:unless="${iterStat.last}">|</span>-->
</th:block> </th:block>
@@ -353,15 +361,15 @@
<a th:href="@{/apis}" class="btn-all-apis"> <a th:href="@{/apis}" class="btn-all-apis">
전체보기 전체보기
<svg width="9" height="15" viewBox="0 0 9 15" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="9" height="15" viewBox="0 0 9 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.510742 13.5496L7.51074 7.04956L0.510742 0.549561" stroke="white" stroke-width="1.5" stroke-linejoin="round"/> <path d="M0.510742 13.5496L7.51074 7.04956L0.510742 0.549561" stroke="white" stroke-width="1.5"
stroke-linejoin="round" />
</svg> </svg>
</a> </a>
</div> </div>
<div class="api-cards-container"> <div class="api-cards-container">
<!-- Services 데이터를 반복하여 API 카드 표시 (최대 4개) --> <!-- Services 데이터를 반복하여 API 카드 표시 (최대 4개) -->
<div class="api-card" th:each="service, iterStat : ${services}" <div class="api-card" th:each="service, iterStat : ${services}" th:if="${iterStat.index < 4}"
th:if="${iterStat.index < 4}"
th:onclick="${service.id != null} ? |location.href='@{/apis(groupId=${service.id})}'| : |location.href='@{/apis}'|"> th:onclick="${service.id != null} ? |location.href='@{/apis(groupId=${service.id})}'| : |location.href='@{/apis}'|">
<h3 class="card-title" th:text="${service.groupName}">API 서비스</h3> <h3 class="card-title" th:text="${service.groupName}">API 서비스</h3>
<p class="card-description"> <p class="card-description">
@@ -373,7 +381,8 @@
</p> </p>
<div class="card-illustration"> <div class="card-illustration">
<!-- 서비스별 아이콘 매핑 - base64 인코딩된 이미지 사용 --> <!-- 서비스별 아이콘 매핑 - base64 인코딩된 이미지 사용 -->
<img th:src="${service.mainIcon != null and !#strings.isEmpty(service.mainIcon)} ? ${service.mainIcon} : @{/img/api_icon_default.png}" <img
th:src="${service.mainIcon != null and !#strings.isEmpty(service.mainIcon)} ? ${service.mainIcon} : @{/img/api_icon_default.png}"
th:alt="${service.groupName}"> th:alt="${service.groupName}">
</div> </div>
</div> </div>
@@ -511,8 +520,10 @@
<!-- Notice Card (Featured Wide Card) --> <!-- Notice Card (Featured Wide Card) -->
<a href="#" class="support-card support-card-notice"> <a href="#" class="support-card support-card-notice">
<div class="card-icon"> <div class="card-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" fill="currentColor" class="bi bi-megaphone" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" fill="currentColor" class="bi bi-megaphone"
<path d="M13 2.5a1.5 1.5 0 0 1 3 0v11a1.5 1.5 0 0 1-3 0v-.214c-2.162-1.241-4.49-1.843-6.912-2.083l.405 2.712A1 1 0 0 1 5.51 15.1h-.548a1 1 0 0 1-.916-.599l-1.85-3.49-.202-.003A2.014 2.014 0 0 1 0 9V7a2.02 2.02 0 0 1 1.992-2.013 75 75 0 0 0 2.483-.075c3.043-.154 6.148-.849 8.525-2.199zm1 0v11a.5.5 0 0 0 1 0v-11a.5.5 0 0 0-1 0m-1 1.35c-2.344 1.205-5.209 1.842-8 2.033v4.233q.27.015.537.036c2.568.189 5.093.744 7.463 1.993zm-9 6.215v-4.13a95 95 0 0 1-1.992.052A1.02 1.02 0 0 0 1 7v2c0 .55.448 1.002 1.006 1.009A61 61 0 0 1 4 10.065m-.657.975 1.609 3.037.01.024h.548l-.002-.014-.443-2.966a68 68 0 0 0-1.722-.082z"/> viewBox="0 0 16 16">
<path
d="M13 2.5a1.5 1.5 0 0 1 3 0v11a1.5 1.5 0 0 1-3 0v-.214c-2.162-1.241-4.49-1.843-6.912-2.083l.405 2.712A1 1 0 0 1 5.51 15.1h-.548a1 1 0 0 1-.916-.599l-1.85-3.49-.202-.003A2.014 2.014 0 0 1 0 9V7a2.02 2.02 0 0 1 1.992-2.013 75 75 0 0 0 2.483-.075c3.043-.154 6.148-.849 8.525-2.199zm1 0v11a.5.5 0 0 0 1 0v-11a.5.5 0 0 0-1 0m-1 1.35c-2.344 1.205-5.209 1.842-8 2.033v4.233q.27.015.537.036c2.568.189 5.093.744 7.463 1.993zm-9 6.215v-4.13a95 95 0 0 1-1.992.052A1.02 1.02 0 0 0 1 7v2c0 .55.448 1.002 1.006 1.009A61 61 0 0 1 4 10.065m-.657.975 1.609 3.037.01.024h.548l-.002-.014-.443-2.966a68 68 0 0 0-1.722-.082z" />
</svg> </svg>
</div> </div>
<div class="card-content"> <div class="card-content">
@@ -520,8 +531,10 @@
<p>DJBank API의 다양한 새로운 소식을 가장 먼저 전해드립니다.</p> <p>DJBank API의 다양한 새로운 소식을 가장 먼저 전해드립니다.</p>
</div> </div>
<div class="card-arrow"> <div class="card-arrow">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-right" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"
<path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8"/> class="bi bi-arrow-right" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8" />
</svg> </svg>
</div> </div>
</a> </a>
@@ -529,9 +542,12 @@
<!-- FAQ Card --> <!-- FAQ Card -->
<a href="#" class="support-card support-card-faq"> <a href="#" class="support-card support-card-faq">
<div class="card-icon"> <div class="card-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" fill="currentColor" class="bi bi-patch-question" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" fill="currentColor"
<path d="M8.05 9.6c.336 0 .504-.24.554-.627.04-.534.198-.815.847-1.26.673-.475 1.049-1.09 1.049-1.986 0-1.325-.92-2.227-2.262-2.227-1.02 0-1.792.492-2.1 1.29A1.7 1.7 0 0 0 6 5.48c0 .393.203.64.545.64.272 0 .455-.147.564-.51.158-.592.525-.915 1.074-.915.61 0 1.03.446 1.03 1.084 0 .563-.208.885-.822 1.325-.619.433-.926.914-.926 1.64v.111c0 .428.208.745.585.745"/> class="bi bi-patch-question" viewBox="0 0 16 16">
<path d="m10.273 2.513-.921-.944.715-.698.622.637.89-.011a2.89 2.89 0 0 1 2.924 2.924l-.01.89.636.622a2.89 2.89 0 0 1 0 4.134l-.637.622.011.89a2.89 2.89 0 0 1-2.924 2.924l-.89-.01-.622.636a2.89 2.89 0 0 1-4.134 0l-.622-.637-.89.011a2.89 2.89 0 0 1-2.924-2.924l.01-.89-.636-.622a2.89 2.89 0 0 1 0-4.134l.637-.622-.011-.89a2.89 2.89 0 0 1 2.924-2.924l.89.01.622-.636a2.89 2.89 0 0 1 4.134 0l-.715.698a1.89 1.89 0 0 0-2.704 0l-.92.944-1.32-.016a1.89 1.89 0 0 0-1.911 1.912l.016 1.318-.944.921a1.89 1.89 0 0 0 0 2.704l.944.92-.016 1.32a1.89 1.89 0 0 0 1.912 1.911l1.318-.016.921.944a1.89 1.89 0 0 0 2.704 0l.92-.944 1.32.016a1.89 1.89 0 0 0 1.911-1.912l-.016-1.318.944-.921a1.89 1.89 0 0 0 0-2.704l-.944-.92.016-1.32a1.89 1.89 0 0 0-1.912-1.911z"/> <path
d="M8.05 9.6c.336 0 .504-.24.554-.627.04-.534.198-.815.847-1.26.673-.475 1.049-1.09 1.049-1.986 0-1.325-.92-2.227-2.262-2.227-1.02 0-1.792.492-2.1 1.29A1.7 1.7 0 0 0 6 5.48c0 .393.203.64.545.64.272 0 .455-.147.564-.51.158-.592.525-.915 1.074-.915.61 0 1.03.446 1.03 1.084 0 .563-.208.885-.822 1.325-.619.433-.926.914-.926 1.64v.111c0 .428.208.745.585.745" />
<path
d="m10.273 2.513-.921-.944.715-.698.622.637.89-.011a2.89 2.89 0 0 1 2.924 2.924l-.01.89.636.622a2.89 2.89 0 0 1 0 4.134l-.637.622.011.89a2.89 2.89 0 0 1-2.924 2.924l-.89-.01-.622.636a2.89 2.89 0 0 1-4.134 0l-.622-.637-.89.011a2.89 2.89 0 0 1-2.924-2.924l.01-.89-.636-.622a2.89 2.89 0 0 1 0-4.134l.637-.622-.011-.89a2.89 2.89 0 0 1 2.924-2.924l.89.01.622-.636a2.89 2.89 0 0 1 4.134 0l-.715.698a1.89 1.89 0 0 0-2.704 0l-.92.944-1.32-.016a1.89 1.89 0 0 0-1.911 1.912l.016 1.318-.944.921a1.89 1.89 0 0 0 0 2.704l.944.92-.016 1.32a1.89 1.89 0 0 0 1.912 1.911l1.318-.016.921.944a1.89 1.89 0 0 0 2.704 0l.92-.944 1.32.016a1.89 1.89 0 0 0 1.911-1.912l-.016-1.318.944-.921a1.89 1.89 0 0 0 0-2.704l-.944-.92.016-1.32a1.89 1.89 0 0 0-1.912-1.911z" />
<path d="M7.001 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0" /> <path d="M7.001 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0" />
</svg> </svg>
</div> </div>
@@ -540,8 +556,10 @@
<p>자주 묻는 핵심 질문과 명쾌한 해결책</p> <p>자주 묻는 핵심 질문과 명쾌한 해결책</p>
</div> </div>
<div class="card-arrow"> <div class="card-arrow">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-right" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"
<path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8"/> class="bi bi-arrow-right" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8" />
</svg> </svg>
</div> </div>
</a> </a>
@@ -549,9 +567,12 @@
<!-- Q&A Card --> <!-- Q&A Card -->
<a href="#" class="support-card support-card-qna"> <a href="#" class="support-card support-card-qna">
<div class="card-icon"> <div class="card-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" fill="currentColor" class="bi bi-chat-left-text" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" fill="currentColor"
<path d="M14 1a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H4.414A2 2 0 0 0 3 11.586l-2 2V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12.793a.5.5 0 0 0 .854.353l2.853-2.853A1 1 0 0 1 4.414 12H14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/> class="bi bi-chat-left-text" viewBox="0 0 16 16">
<path d="M3 3.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5M3 6a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9A.5.5 0 0 1 3 6m0 2.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5"/> <path
d="M14 1a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H4.414A2 2 0 0 0 3 11.586l-2 2V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12.793a.5.5 0 0 0 .854.353l2.853-2.853A1 1 0 0 1 4.414 12H14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z" />
<path
d="M3 3.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5M3 6a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9A.5.5 0 0 1 3 6m0 2.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5" />
</svg> </svg>
</div> </div>
<div class="card-content"> <div class="card-content">
@@ -559,8 +580,10 @@
<p>1:1 실시간 문의 및 맞춤 비즈니스 상담</p> <p>1:1 실시간 문의 및 맞춤 비즈니스 상담</p>
</div> </div>
<div class="card-arrow"> <div class="card-arrow">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-right" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"
<path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8"/> class="bi bi-arrow-right" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8" />
</svg> </svg>
</div> </div>
</a> </a>
@@ -647,14 +670,17 @@
<!-- Counter 1 --> <!-- Counter 1 -->
<div class="stat-card" data-stat="service"> <div class="stat-card" data-stat="service">
<div class="stat-icon-wrapper"> <div class="stat-icon-wrapper">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-app-indicator" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor"
<path d="M5.5 2A3.5 3.5 0 0 0 2 5.5v5A3.5 3.5 0 0 0 5.5 14h5a3.5 3.5 0 0 0 3.5-3.5V8a.5.5 0 0 1 1 0v2.5a4.5 4.5 0 0 1-4.5 4.5h-5A4.5 4.5 0 0 1 1 10.5v-5A4.5 4.5 0 0 1 5.5 1H8a.5.5 0 0 1 0 1z"/> class="bi bi-app-indicator" viewBox="0 0 16 16">
<path
d="M5.5 2A3.5 3.5 0 0 0 2 5.5v5A3.5 3.5 0 0 0 5.5 14h5a3.5 3.5 0 0 0 3.5-3.5V8a.5.5 0 0 1 1 0v2.5a4.5 4.5 0 0 1-4.5 4.5h-5A4.5 4.5 0 0 1 1 10.5v-5A4.5 4.5 0 0 1 5.5 1H8a.5.5 0 0 1 0 1z" />
<path d="M16 3a3 3 0 1 1-6 0 3 3 0 0 1 6 0" /> <path d="M16 3a3 3 0 1 1-6 0 3 3 0 0 1 6 0" />
</svg> </svg>
</div> </div>
<p class="stat-label">서비스 이용 수</p>DJBank 오픈 API와 함께하고 있습니다. <p class="stat-label">서비스 이용 수</p>
<div class="stat-number-box"> <div class="stat-number-box">
<p class="stat-number" th:attr="data-target=${serviceCount != null ? serviceCount : 9999}" th:text="${serviceCount != null ? serviceCount : '9,999'}">9,999</p> <p class="stat-number" th:attr="data-target=${serviceCount != null ? serviceCount : 9999}"
th:text="${serviceCount != null ? serviceCount : '9,999'}">9,999</p>
<!-- <span class="stat-number" data-target="1562">0</span><span class="stat-unit">개</span>--> <!-- <span class="stat-number" data-target="1562">0</span><span class="stat-unit">개</span>-->
</div> </div>
</div> </div>
@@ -664,14 +690,18 @@
<!-- Counter 2 --> <!-- Counter 2 -->
<div class="stat-card" data-stat="use"> <div class="stat-card" data-stat="use">
<div class="stat-icon-wrapper"> <div class="stat-icon-wrapper">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-speedometer2" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor"
<path d="M8 4a.5.5 0 0 1 .5.5V6a.5.5 0 0 1-1 0V4.5A.5.5 0 0 1 8 4M3.732 5.732a.5.5 0 0 1 .707 0l.915.914a.5.5 0 1 1-.708.708l-.914-.915a.5.5 0 0 1 0-.707M2 10a.5.5 0 0 1 .5-.5h1.586a.5.5 0 0 1 0 1H2.5A.5.5 0 0 1 2 10m9.5 0a.5.5 0 0 1 .5-.5h1.5a.5.5 0 0 1 0 1H12a.5.5 0 0 1-.5-.5m.754-4.246a.39.39 0 0 0-.527-.02L7.547 9.31a.91.91 0 1 0 1.302 1.258l3.434-4.297a.39.39 0 0 0-.029-.518z"/> class="bi bi-speedometer2" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M0 10a8 8 0 1 1 15.547 2.661c-.442 1.253-1.845 1.602-2.932 1.25C11.309 13.488 9.475 13 8 13c-1.474 0-3.31.488-4.615.911-1.087.352-2.49.003-2.932-1.25A8 8 0 0 1 0 10m8-7a7 7 0 0 0-6.603 9.329c.203.575.923.876 1.68.63C4.397 12.533 6.358 12 8 12s3.604.532 4.923.96c.757.245 1.477-.056 1.68-.631A7 7 0 0 0 8 3"/> <path
d="M8 4a.5.5 0 0 1 .5.5V6a.5.5 0 0 1-1 0V4.5A.5.5 0 0 1 8 4M3.732 5.732a.5.5 0 0 1 .707 0l.915.914a.5.5 0 1 1-.708.708l-.914-.915a.5.5 0 0 1 0-.707M2 10a.5.5 0 0 1 .5-.5h1.586a.5.5 0 0 1 0 1H2.5A.5.5 0 0 1 2 10m9.5 0a.5.5 0 0 1 .5-.5h1.5a.5.5 0 0 1 0 1H12a.5.5 0 0 1-.5-.5m.754-4.246a.39.39 0 0 0-.527-.02L7.547 9.31a.91.91 0 1 0 1.302 1.258l3.434-4.297a.39.39 0 0 0-.029-.518z" />
<path fill-rule="evenodd"
d="M0 10a8 8 0 1 1 15.547 2.661c-.442 1.253-1.845 1.602-2.932 1.25C11.309 13.488 9.475 13 8 13c-1.474 0-3.31.488-4.615.911-1.087.352-2.49.003-2.932-1.25A8 8 0 0 1 0 10m8-7a7 7 0 0 0-6.603 9.329c.203.575.923.876 1.68.63C4.397 12.533 6.358 12 8 12s3.604.532 4.923.96c.757.245 1.477-.056 1.68-.631A7 7 0 0 0 8 3" />
</svg> </svg>
</div> </div>
<p class="stat-label">API 이용 건수 (월누적)</p> <p class="stat-label">API 이용 건수 (월누적)</p>
<div class="stat-number-box"> <div class="stat-number-box">
<p class="stat-number" th:attr="data-target=${totalApiCount != null ? totalApiCount : 9999}" th:text="${totalApiCount != null ? totalApiCount : '9,999'}">9,999</p> <p class="stat-number" th:attr="data-target=${totalApiCount != null ? totalApiCount : 9999}"
th:text="${totalApiCount != null ? totalApiCount : '9,999'}">9,999</p>
<!-- <span class="stat-number" data-target="984250">0</span><span class="stat-unit">건</span>--> <!-- <span class="stat-number" data-target="984250">0</span><span class="stat-unit">건</span>-->
</div> </div>
</div> </div>
@@ -681,15 +711,19 @@
<!-- Counter 3 --> <!-- Counter 3 -->
<div class="stat-card" data-stat="company"> <div class="stat-card" data-stat="company">
<div class="stat-icon-wrapper"> <div class="stat-icon-wrapper">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-building" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-building"
<path d="M4 2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zM4 5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zM7.5 5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm2.5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zM4.5 8a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm2.5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5z"/> viewBox="0 0 16 16">
<path d="M2 1a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1zm11 0H3v14h3v-2.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5V15h3z"/> <path
d="M4 2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zM4 5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zM7.5 5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm2.5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zM4.5 8a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm2.5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5z" />
<path
d="M2 1a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1zm11 0H3v14h3v-2.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5V15h3z" />
</svg> </svg>
</div> </div>
<p class="stat-label">API 활성화 기업</p> <p class="stat-label">API 활성화 기업</p>
<div class="stat-number-box"> <div class="stat-number-box">
<!-- <span class="stat-number" data-target="842">0</span><span class="stat-unit">개사</span>--> <!-- <span class="stat-number" data-target="842">0</span><span class="stat-unit">개사</span>-->
<p class="stat-number" th:attr="data-target=${approvedOrgCount != null ? approvedOrgCount : 9999}" th:text="${approvedOrgCount != null ? approvedOrgCount : '9,999'}">9,999</p> <p class="stat-number" th:attr="data-target=${approvedOrgCount != null ? approvedOrgCount : 9999}"
th:text="${approvedOrgCount != null ? approvedOrgCount : '9,999'}">9,999</p>
</div> </div>
</div> </div>
</div> </div>
@@ -978,4 +1012,5 @@
}); });
</script> </script>
</th:block> </th:block>
</html> </html>
@@ -3,19 +3,22 @@
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/djbank_title_layout}"> xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/djbank_title_layout}">
<body> <body>
<section layout:fragment="title">
<div class="page-title-banner">
<img th:src="@{/img/img_title_bg.png}" class="title-image">
<h1>이용자 관리</h1>
</div>
</section>
<th:block layout:fragment="contentFragment"> <th:block layout:fragment="contentFragment">
<section class="user-management-container"> <div class="service-main" style="padding-top: 40px;">
<!-- Sidebar -->
<th:block th:replace="~{fragment/djbank/service_sidebar :: sidebar('users')}"></th:block>
<!-- Main Content -->
<section class="service-content">
<section class="user-management-container" style="padding-top: 0;">
<!-- App List Title Section --> <!-- App List Title Section -->
<div class="table-controls"> <div class="table-controls">
<h2 class="total-count"> <h2 class="total-count">
<strong th:text="${(users != null ? users.size() : 0) + (pendingUsers != null ? pendingUsers.size() : 0)}">0</strong> <strong th:text="${(users != null ? users.size() : 0) + (pendingUsers != null ? pendingUsers.size() : 0)}">0</strong>
</h2> </h2>
<div class="search-box"> <div class="search-box">
<button type="button" class="btn btn-primary" id="addUserBtn"> <button type="button" class="btn btn-primary" id="addUserBtn">
@@ -26,37 +29,37 @@
</div> </div>
<!-- User Table --> <!-- User Table -->
<div class="list-table" th:if="${(users != null and !users.isEmpty()) or (pendingUsers != null and !pendingUsers.isEmpty())}"> <div class="board-table board-table--user-list" th:if="${(users != null and !users.isEmpty()) or (pendingUsers != null and !pendingUsers.isEmpty())}">
<!-- Table Header --> <!-- Table Header -->
<div class="list-table-header"> <div class="board-table-header">
<div class="header-cell" style="width: 90px;">NO.</div> <div class="header-cell">NO.</div>
<div class="header-cell" style="width: 90px;">성명</div> <div class="header-cell">성명</div>
<div class="header-cell" style="flex: 1; min-width: 180px;">이메일 / 휴대폰</div> <div class="header-cell">이메일 / 휴대폰</div>
<div class="header-cell" style="width: 120px;">권한</div> <div class="header-cell">권한</div>
<div class="header-cell" style="width: 120px;">계정상태</div> <div class="header-cell">계정상태</div>
<div class="header-cell" style="width: 320px;">설정</div> <div class="header-cell">설정</div>
</div> </div>
<!-- Table Body --> <!-- Table Body -->
<div class="list-table-body"> <div class="board-table-body">
<!-- Active/Inactive Users --> <!-- Active/Inactive Users -->
<div class="list-table-row" th:each="user, status : ${users}"> <div class="board-table-row" th:each="user, status : ${users}">
<div class="row-cell" style="width: 90px;" data-label="NO" th:text="${status.index + 1}">1</div> <div class="row-cell" data-label="NO" th:text="${status.index + 1}">1</div>
<div class="row-cell" style="width: 90px;" data-label="성명"> <div class="row-cell" data-label="성명">
<a th:href="@{/users/detail(id=${user.id})}" th:text="${user.maskedUserName}"> <a th:href="@{/users/detail(id=${user.id})}" th:text="${user.maskedUserName}">
사용자 이름 사용자 이름
</a> </a>
</div> </div>
<div class="row-cell" style="flex: 1; min-width: 180px;" data-label="이메일" th:text="${user.maskedEmailAddr}"> <div class="row-cell" data-label="이메일" th:text="${user.maskedEmailAddr}">
user@example.com user@example.com
</div> </div>
<div class="row-cell" style="width: 120px;" data-label="권한"> <div class="row-cell" data-label="권한">
<span th:if="${user.roleCode != null}" th:text="#{${user.roleCode}}">권한</span> <span th:if="${user.roleCode != null}" th:text="#{${user.roleCode}}">권한</span>
</div> </div>
<div class="row-cell" style="width: 120px;" data-label="계정상태" th:text="${user.userStatus.getDescription()}"> <div class="row-cell" data-label="계정상태" th:text="${user.userStatus.getDescription()}">
활성 활성
</div> </div>
<div class="row-cell row-actions" style="width: 320px;"> <div class="row-cell row-actions">
<!-- Current User --> <!-- Current User -->
<span class="user-current-badge" th:if="${user.id == currentUserId}"> <span class="user-current-badge" th:if="${user.id == currentUserId}">
<i class="fas fa-user-check"></i> 현재 사용자 <i class="fas fa-user-check"></i> 현재 사용자
@@ -146,15 +149,15 @@
</div> </div>
<!-- Pending Invitation Users --> <!-- Pending Invitation Users -->
<div class="list-table-row" th:each="user : ${pendingUsers}"> <div class="board-table-row" th:each="user : ${pendingUsers}">
<div class="row-cell" style="width: 90px;" data-label="NO">-</div> <div class="row-cell" data-label="NO">-</div>
<div class="row-cell" style="width: 90px;" data-label="성명">-</div> <div class="row-cell" data-label="성명">-</div>
<div class="row-cell" style="flex: 1; min-width: 180px;" data-label="휴대폰" th:text="${user.maskedMobileNumber}"> <div class="row-cell" data-label="휴대폰" th:text="${user.maskedMobileNumber}">
010-****-**** 010-****-****
</div> </div>
<div class="row-cell" style="width: 120px;" data-label="권한">이용자</div> <div class="row-cell" data-label="권한">이용자</div>
<div class="row-cell" style="width: 120px;" data-label="계정상태">초대중</div> <div class="row-cell" data-label="계정상태">초대중</div>
<div class="row-cell row-actions" style="width: 320px;"> <div class="row-cell row-actions">
<!-- Desktop --> <!-- Desktop -->
<div class="actions-desktop"> <div class="actions-desktop">
<button type="button" class="list-table-btn list-table-btn--secondary cancel_invitation" <button type="button" class="list-table-btn list-table-btn--secondary cancel_invitation"
@@ -199,6 +202,8 @@
th:replace="~{fragment/pagination :: pagination(jsFunction='fn_select_page')}"></div> th:replace="~{fragment/pagination :: pagination(jsFunction='fn_select_page')}"></div>
</section> </section>
</section>
</div>
</th:block> </th:block>
<section layout:fragment="pagePopups" class="content pop"> <section layout:fragment="pagePopups" class="content pop">
@@ -32,6 +32,42 @@
th:classappend="${activeMenu == 'feedback'} ? 'service-nav__item--active' : ''" th:classappend="${activeMenu == 'feedback'} ? 'service-nav__item--active' : ''"
class="service-nav__item">피드백/개선요청</a> class="service-nav__item">피드백/개선요청</a>
</th:block> </th:block>
<!-- 마이페이지 그룹 (My Page) -->
<th:block th:if="${activeMenu == 'users' or activeMenu == 'apiKey' or activeMenu == 'statistics' or activeMenu == 'profile' or activeMenu == 'password'}">
<!-- Profile Section -->
<div class="service-sidebar__profile">
<div class="avatar">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
</svg>
</div>
<p class="user-name"><span th:text="${#authentication.principal.userName}">사용자</span></p>
</div>
<div class="service-sidebar__divider"></div>
<a th:href="@{/users}"
th:classappend="${activeMenu == 'users'} ? 'service-nav__item--active' : ''"
class="service-nav__item"
sec:authorize="hasRole('ROLE_CORP_MANAGER')">이용자 관리</a>
<a th:href="@{/myapikey}"
th:classappend="${activeMenu == 'apiKey'} ? 'service-nav__item--active' : ''"
class="service-nav__item">인증 키 관리</a>
<a th:href="@{/statistics/daily}"
th:classappend="${activeMenu == 'statistics'} ? 'service-nav__item--active' : ''"
class="service-nav__item">이용통계</a>
<a th:href="@{/mypage/update_user}"
th:classappend="${activeMenu == 'profile'} ? 'service-nav__item--active' : ''"
class="service-nav__item">내정보 관리</a>
<a th:href="@{/mypage/password}"
th:classappend="${activeMenu == 'password'} ? 'service-nav__item--active' : ''"
class="service-nav__item">비밀번호 변경</a>
</th:block>
</nav> </nav>
</aside> </aside>
</body> </body>