공지사항 목록 디자인 적용
This commit is contained in:
@@ -684,3 +684,70 @@ select.form-control {
|
||||
.form-actions-center {
|
||||
@extend .form-actions;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Search Field - Figma Design (node 1041:1670)
|
||||
// Rounded search input with icon button
|
||||
// -----------------------------------------------------------------------------
|
||||
.search-field {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 340px;
|
||||
height: 44px;
|
||||
background: $white;
|
||||
border: 1px solid #dadada;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
|
||||
@include respond-to('sm') {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
padding: 0 44px 0 16px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: $font-family-primary;
|
||||
font-size: 14px;
|
||||
font-weight: $font-weight-regular;
|
||||
color: $text-dark;
|
||||
outline: none;
|
||||
|
||||
&::placeholder {
|
||||
color: #8c959f;
|
||||
}
|
||||
}
|
||||
|
||||
.search-field-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
color: #515961;
|
||||
transition: $transition-fast;
|
||||
|
||||
&:hover {
|
||||
color: $primary-blue;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
border-color: $primary-blue;
|
||||
box-shadow: 0 0 0 2px rgba($primary-blue, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,6 +366,61 @@
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
// Title cell with inline file icon
|
||||
&--title {
|
||||
justify-content: flex-start;
|
||||
|
||||
@media (max-width: $breakpoint-md) {
|
||||
&::before {
|
||||
display: none; // Hide data-label for title on mobile
|
||||
}
|
||||
}
|
||||
|
||||
.notice-title-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: $spacing-sm;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
transition: $transition-base;
|
||||
|
||||
&:hover {
|
||||
color: $primary-blue;
|
||||
}
|
||||
|
||||
// Mobile number prefix [1] [2] etc
|
||||
.notice-number {
|
||||
display: none;
|
||||
font-weight: $font-weight-medium;
|
||||
color: $text-gray;
|
||||
flex-shrink: 0;
|
||||
|
||||
@media (max-width: $breakpoint-md) {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.file-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
color: #212529;
|
||||
|
||||
svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Number cell for notice list
|
||||
&--number {
|
||||
@media (max-width: $breakpoint-md) {
|
||||
display: none; // Hide separate number cell on mobile
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Action buttons container
|
||||
|
||||
@@ -1,85 +1,87 @@
|
||||
<!doctype html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/kjbank_base_layout}">
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/kjbank_title_layout}">
|
||||
|
||||
<body>
|
||||
<th:block layout:fragment="contentFragment">
|
||||
<!-- Notice List Page -->
|
||||
<div class="notice-page">
|
||||
<div class="notice-container">
|
||||
|
||||
<!-- Page Header -->
|
||||
<div class="notice-header">
|
||||
<h1 class="page-title">공지사항</h1>
|
||||
<p class="page-description">광주은행 API Portal의 새로운 소식과 공지사항을 확인하세요.</p>
|
||||
</div>
|
||||
|
||||
<!-- Search and Filter Controls -->
|
||||
<form name="noticeForm" th:action="@{/portalnotice}" method="get" onsubmit="return false;">
|
||||
<input type="hidden" name="page" value="1">
|
||||
|
||||
<div class="table-controls">
|
||||
<div class="total-count">
|
||||
총 <strong th:text="${page.totalElements}">0</strong>건
|
||||
</div>
|
||||
|
||||
<div class="search-box">
|
||||
<input type="text"
|
||||
name="searchSubjectOrDetail"
|
||||
th:value="${search.searchSubjectOrDetail}"
|
||||
placeholder="제목 또는 내용으로 검색">
|
||||
<button type="button" class="btn btn-primary" onclick="fn_search_notice()">
|
||||
<i class="fas fa-search"></i>
|
||||
<span>검색</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Notice Table -->
|
||||
<div class="notice-list-wrapper" th:if="${!portalNotices.isEmpty()}">
|
||||
<div class="notice-table">
|
||||
<!-- Table Header -->
|
||||
<div class="table-header">
|
||||
<div class="col-num">NO</div>
|
||||
<div class="col-title">제목</div>
|
||||
<div class="col-date">등록일</div>
|
||||
</div>
|
||||
|
||||
<!-- Table Rows -->
|
||||
<div class="table-row"
|
||||
th:each="notice, status : ${portalNotices}"
|
||||
th:onclick="'location.href=\'' + @{/portalnotice/detail(id=${notice.id})} + '\''">
|
||||
<div class="col-num"
|
||||
th:text="${page.totalElements - (page.number * page.size) - status.index}">1</div>
|
||||
<div class="col-title">
|
||||
<a th:href="@{/portalnotice/detail(id=${notice.id})}">
|
||||
<span th:text="${notice.noticeSubject}">공지사항 제목</span>
|
||||
<span class="file-icon" th:if="${notice.fileId != null and !notice.fileId.isEmpty()}">
|
||||
<img th:src="@{/img/icon/icon_file.png}" alt="첨부파일">
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-date"
|
||||
th:text="${#temporals.format(notice.createdDate, 'yyyy.MM.dd')}">2025.01.01</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Empty State -->
|
||||
<div class="table-empty" th:if="${portalNotices.isEmpty()}">
|
||||
<div class="empty-icon">
|
||||
<img th:src="@{/img/img_nodata.png}" alt="데이터 없음">
|
||||
</div>
|
||||
<p class="empty-text">조회된 데이터가 없습니다.</p>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="pagination" th:replace="~{fragment/pagination :: pagination(jsFunction='fn_select_page')}">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<section layout:fragment="title">
|
||||
<div class="page-title-banner">
|
||||
<img th:src="@{/img/img_title_bg.png}" class="title-image" alt="타이틀 배경">
|
||||
<h1>공지사항</h1>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<th:block layout:fragment="contentFragment">
|
||||
<section class="user-management-container">
|
||||
|
||||
<!-- Search and Filter Controls -->
|
||||
<form name="noticeForm" th:action="@{/portalnotice}" method="get" onsubmit="return false;">
|
||||
<input type="hidden" name="page" value="1">
|
||||
|
||||
<div class="table-controls">
|
||||
<h2 class="total-count">
|
||||
총 <strong th:text="${page.totalElements}">0</strong>건
|
||||
</h2>
|
||||
|
||||
<div class="search-field">
|
||||
<input type="text"
|
||||
name="searchSubjectOrDetail"
|
||||
th:value="${search.searchSubjectOrDetail}"
|
||||
placeholder="제목/내용 검색"
|
||||
onkeypress="if(event.keyCode === 13) { fn_search_notice(); return false; }">
|
||||
<button type="button" class="search-field-btn" onclick="fn_search_notice()">
|
||||
<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"/>
|
||||
</svg>
|
||||
<span class="blind">검색</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Notice Table -->
|
||||
<div class="list-table" th:if="${!portalNotices.isEmpty()}">
|
||||
<!-- Table Header -->
|
||||
<div class="list-table-header">
|
||||
<div class="header-cell" style="width: 80px;">NO</div>
|
||||
<div class="header-cell" style="flex: 1; min-width: 200px;">제목</div>
|
||||
<div class="header-cell" style="width: 120px;">등록일</div>
|
||||
</div>
|
||||
|
||||
<!-- Table Body -->
|
||||
<div class="list-table-body">
|
||||
<div class="list-table-row"
|
||||
th:each="notice, status : ${portalNotices}"
|
||||
th:onclick="'location.href=\'' + @{/portalnotice/detail(id=${notice.id})} + '\''"
|
||||
style="cursor: pointer;">
|
||||
<div class="row-cell row-cell--number" style="width: 80px;" data-label="NO"
|
||||
th:text="${page.totalElements - (page.number * page.size) - status.index}">1</div>
|
||||
<div class="row-cell row-cell--title" style="flex: 1; min-width: 200px;" data-label="제목">
|
||||
<a th:href="@{/portalnotice/detail(id=${notice.id})}" class="notice-title-link">
|
||||
<span class="notice-number" th:text="|[${page.totalElements - (page.number * page.size) - status.index}]|">[1]</span>
|
||||
<span th:text="${notice.noticeSubject}">공지사항 제목</span>
|
||||
<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">
|
||||
<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>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row-cell" style="width: 120px;" data-label="등록일"
|
||||
th:text="${#temporals.format(notice.createdDate, 'yyyy.MM.dd')}">2025.01.01</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Empty State -->
|
||||
<div class="user-empty-state" th:if="${portalNotices.isEmpty()}">
|
||||
<h3>조회된 공지사항이 없습니다</h3>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="pagination" th:replace="~{fragment/pagination :: pagination(jsFunction='fn_select_page')}">
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</th:block>
|
||||
|
||||
</body>
|
||||
@@ -105,3 +107,4 @@
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user