앱 관리 - 앱목록 디자인 반영
This commit is contained in:
@@ -10628,7 +10628,7 @@ select.form-control {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-page-title-banner {
|
.page-title-banner {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 220px;
|
height: 220px;
|
||||||
@@ -10638,7 +10638,7 @@ select.form-control {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.org-page-title-banner::before {
|
.page-title-banner::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -10649,7 +10649,7 @@ select.form-control {
|
|||||||
background-size: 50px 50px;
|
background-size: 50px 50px;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
.org-page-title-banner .title-image {
|
.page-title-banner .title-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
@@ -10658,7 +10658,7 @@ select.form-control {
|
|||||||
width: auto;
|
width: auto;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
.org-page-title-banner h1 {
|
.page-title-banner h1 {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -10668,14 +10668,14 @@ select.form-control {
|
|||||||
letter-spacing: -0.5px;
|
letter-spacing: -0.5px;
|
||||||
}
|
}
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.org-page-title-banner {
|
.page-title-banner {
|
||||||
height: 120px;
|
height: 120px;
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
}
|
}
|
||||||
.org-page-title-banner .title-image {
|
.page-title-banner .title-image {
|
||||||
height: 120px;
|
height: 120px;
|
||||||
}
|
}
|
||||||
.org-page-title-banner h1 {
|
.page-title-banner h1 {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
@import '../abstracts/mixins';
|
@import '../abstracts/mixins';
|
||||||
|
|
||||||
// Page Title Banner
|
// Page Title Banner
|
||||||
.org-page-title-banner {
|
.page-title-banner {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 220px;
|
height: 220px;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<th:block layout:fragment="title">
|
<th:block layout:fragment="title">
|
||||||
<div class="org-page-title-banner" style="margin-bottom: 40px;">
|
<div class="page-title-banner" style="margin-bottom: 40px;">
|
||||||
<h1>API 마켓</h1>
|
<h1>API 마켓</h1>
|
||||||
</div>
|
</div>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|||||||
@@ -1,138 +1,123 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
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>
|
<body>
|
||||||
|
<section layout:fragment="title">
|
||||||
|
<div class="page-title-banner">
|
||||||
|
<h1>앱관리</h1>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
<th:block layout:fragment="contentFragment">
|
<th:block layout:fragment="contentFragment">
|
||||||
<section class="apikey-container">
|
<section class="app-management-container">
|
||||||
|
|
||||||
<!-- Header Section -->
|
<!-- App List Title Section -->
|
||||||
<div class="apikey-header">
|
<div class="app-list-title-section">
|
||||||
<div class="apikey-title">
|
<h2 class="app-list-title">앱 목록</h2>
|
||||||
<h1>마이페이지</h1>
|
|
||||||
<h2>인증키 목록</h2>
|
|
||||||
</div>
|
|
||||||
<div class="apikey-actions">
|
|
||||||
<button sec:authorize="hasRole('ROLE_API_KEY_REQUEST')"
|
|
||||||
type="button"
|
|
||||||
class="btn btn-primary"
|
|
||||||
id="requestApiKey">
|
|
||||||
<i class="fas fa-plus"></i>
|
|
||||||
<span>앱 생성하기</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Result Count -->
|
<!-- App List Container -->
|
||||||
<div class="apikey-result-count">
|
<div class="app-list-container">
|
||||||
총 <strong th:text="${(appRequests != null ? appRequests.size() : 0) + (apiKeys != null ? apiKeys.size() : 0)}">0</strong>개의 인증키
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- App Requests Cards Grid (Pending) -->
|
<!-- App Requests (Pending) -->
|
||||||
<div class="apikey-card-grid" th:if="${appRequests != null and !appRequests.isEmpty()}">
|
<th:block th:if="${appRequests != null and !appRequests.isEmpty()}">
|
||||||
|
<a class="app-list-item"
|
||||||
|
th:each="request : ${appRequests}"
|
||||||
|
th:href="@{/myapikey/app_request_detail(id=${request.id})}">
|
||||||
|
|
||||||
<a class="apikey-card"
|
<!-- App Icon -->
|
||||||
th:each="request : ${appRequests}"
|
<div class="app-list-icon">
|
||||||
th:href="@{/myapikey/app_request_detail(id=${request.id})}">
|
<img th:if="${request.appIconFileId != null}"
|
||||||
|
th:src="@{/file/download(fileSn=1,fileId=${request.appIconFileId})}"
|
||||||
<!-- App Icon -->
|
alt="App Icon"
|
||||||
<div class="apikey-card-icon">
|
class="app-icon-image">
|
||||||
<img th:if="${request.appIconFileId != null}"
|
<div th:unless="${request.appIconFileId != null}" class="app-icon-placeholder">
|
||||||
th:src="@{/file/download(fileSn=1,fileId=${request.appIconFileId})}"
|
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
alt="App Icon"
|
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
||||||
class="app-icon-image">
|
<circle cx="8.5" cy="8.5" r="1.5"></circle>
|
||||||
<div th:unless="${request.appIconFileId != null}" class="app-icon-placeholder">
|
<polyline points="21 15 16 10 5 21"></polyline>
|
||||||
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
</svg>
|
||||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
</div>
|
||||||
<circle cx="8.5" cy="8.5" r="1.5"></circle>
|
|
||||||
<polyline points="21 15 16 10 5 21"></polyline>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- App Content -->
|
<!-- App Info -->
|
||||||
<div class="apikey-card-content">
|
<div class="app-list-info">
|
||||||
<!-- App Name -->
|
<div class="app-list-header">
|
||||||
<h3 class="apikey-card-title" th:text="${request.clientName}">앱 이름</h3>
|
<!-- Status Badge -->
|
||||||
|
<span class="app-status-badge status-pending"
|
||||||
<!-- App Description -->
|
th:text="${request.approval != null and request.approval.approvalStatus != null ? request.approval.approvalStatus.description : '승인대기'}">
|
||||||
<p class="apikey-card-description"
|
승인대기
|
||||||
th:text="${request.appDescription != null ? request.appDescription : '설명 없음'}">
|
</span>
|
||||||
앱 설명이 여기에 표시됩니다.
|
<!-- App Name -->
|
||||||
</p>
|
<h3 class="app-list-name" th:text="${request.clientName}">앱 이름</h3>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- App Description -->
|
||||||
<!-- App Status Badge (Using Approval State) -->
|
<p class="app-list-description"
|
||||||
<div class="apikey-card-status-wrapper">
|
th:text="${request.appDescription != null ? request.appDescription : '설명 없음'}">
|
||||||
<span class="apikey-card-status status-pending"
|
앱 설명이 여기에 표시됩니다.
|
||||||
th:text="${request.approval != null and request.approval.approvalStatus != null ? request.approval.approvalStatus.description : '상태 없음'}">
|
</p>
|
||||||
승인 대기
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- API Key Cards Grid (Approved) -->
|
|
||||||
<div class="apikey-card-grid" th:if="${apiKeys != null and !apiKeys.isEmpty()}">
|
|
||||||
|
|
||||||
<a class="apikey-card"
|
|
||||||
th:each="apikey, status : ${apiKeys}"
|
|
||||||
th:href="@{/myapikey/credential_detail(id=${apikey.clientid})}">
|
|
||||||
|
|
||||||
<!-- App Icon -->
|
|
||||||
<div class="apikey-card-icon">
|
|
||||||
<img th:if="${apikey.appIconFileId != null}"
|
|
||||||
th:src="@{/file/download(fileSn=1,fileId=${apikey.appIconFileId})}"
|
|
||||||
alt="App Icon"
|
|
||||||
class="app-icon-image">
|
|
||||||
<div th:unless="${apikey.appIconFileId != null}" class="app-icon-placeholder">
|
|
||||||
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
||||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
||||||
<circle cx="8.5" cy="8.5" r="1.5"></circle>
|
|
||||||
<polyline points="21 15 16 10 5 21"></polyline>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- App Content -->
|
</a>
|
||||||
<div class="apikey-card-content">
|
</th:block>
|
||||||
<!-- App Name -->
|
|
||||||
<h3 class="apikey-card-title" th:text="${apikey.clientname}">앱 이름</h3>
|
|
||||||
|
|
||||||
<!-- App Description -->
|
<!-- API Keys (Approved) -->
|
||||||
<p class="apikey-card-description"
|
<th:block th:if="${apiKeys != null and !apiKeys.isEmpty()}">
|
||||||
th:text="${apikey.appDescription != null ? apikey.appDescription : '설명 없음'}">
|
<a class="app-list-item"
|
||||||
앱 설명이 여기에 표시됩니다.
|
th:each="apikey : ${apiKeys}"
|
||||||
</p>
|
th:href="@{/myapikey/credential_detail(id=${apikey.clientid})}">
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- App Status Badge -->
|
<!-- App Icon -->
|
||||||
<div class="apikey-card-status-wrapper">
|
<div class="app-list-icon">
|
||||||
<span class="apikey-card-status"
|
<img th:if="${apikey.appIconFileId != null}"
|
||||||
th:classappend="${apikey.appstatus == '1' ? 'status-active' : apikey.appstatus == '0' ? 'status-inactive' : 'status-pending'}"
|
th:src="@{/file/download(fileSn=1,fileId=${apikey.appIconFileId})}"
|
||||||
th:text="${apikey.appstatus == '1' ? '활성화' : apikey.appstatus == '0' ? '비활성화' : '승인 대기'}">
|
alt="App Icon"
|
||||||
활성화
|
class="app-icon-image">
|
||||||
</span>
|
<div th:unless="${apikey.appIconFileId != null}" class="app-icon-placeholder">
|
||||||
</div>
|
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
||||||
|
<circle cx="8.5" cy="8.5" r="1.5"></circle>
|
||||||
|
<polyline points="21 15 16 10 5 21"></polyline>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</a>
|
<!-- App Info -->
|
||||||
|
<div class="app-list-info">
|
||||||
|
<div class="app-list-header">
|
||||||
|
<!-- Status Badge -->
|
||||||
|
<span class="app-status-badge"
|
||||||
|
th:classappend="${apikey.appstatus == '1' ? 'status-approved' : apikey.appstatus == '0' ? 'status-inactive' : 'status-pending'}"
|
||||||
|
th:text="${apikey.appstatus == '1' ? '승인' : apikey.appstatus == '0' ? '비활성화' : '승인대기'}">
|
||||||
|
승인
|
||||||
|
</span>
|
||||||
|
<!-- App Name -->
|
||||||
|
<h3 class="app-list-name" th:text="${apikey.clientname}">앱 이름</h3>
|
||||||
|
</div>
|
||||||
|
<!-- App Description -->
|
||||||
|
<p class="app-list-description"
|
||||||
|
th:text="${apikey.appDescription != null ? apikey.appDescription : '설명 없음'}">
|
||||||
|
앱 설명이 여기에 표시됩니다.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</a>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
<!-- Empty State -->
|
||||||
|
<div class="app-list-empty" th:if="${(appRequests == null or appRequests.isEmpty()) and (apiKeys == null or apiKeys.isEmpty())}">
|
||||||
|
<div class="empty-icon">🔑</div>
|
||||||
|
<h3>등록된 앱이 없습니다</h3>
|
||||||
|
<p>새로운 앱을 생성하여 API를 사용해보세요.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Empty State -->
|
<!-- Create App Button -->
|
||||||
<div class="apikey-empty-state" th:if="${(appRequests == null or appRequests.isEmpty()) and (apiKeys == null or apiKeys.isEmpty())}">
|
<div class="app-create-button-wrapper" sec:authorize="hasRole('ROLE_API_KEY_REQUEST')">
|
||||||
<div class="empty-icon">🔑</div>
|
<button type="button" class="btn-app-create" id="requestApiKey">
|
||||||
<h3>등록된 인증키가 없습니다</h3>
|
앱 생성
|
||||||
<p>새로운 앱을 생성하여 API를 사용해보세요.</p>
|
|
||||||
<button sec:authorize="hasRole('ROLE_API_KEY_REQUEST')"
|
|
||||||
type="button"
|
|
||||||
class="btn btn-primary"
|
|
||||||
id="requestApiKeyEmpty">
|
|
||||||
<i class="fas fa-plus"></i>
|
|
||||||
<span>첫 앱 생성하기</span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -140,83 +125,278 @@
|
|||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
<th:block layout:fragment="contentScript">
|
<th:block layout:fragment="contentScript">
|
||||||
|
<style>
|
||||||
|
/* App Management Container */
|
||||||
|
.app-management-container {
|
||||||
|
max-width: 1228px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 60px 20px 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* App List Title Section */
|
||||||
|
.app-list-title-section {
|
||||||
|
background-color: #f6f9fb;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 14px 45px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-title {
|
||||||
|
font-family: 'Noto Sans KR', 'Malgun Gothic', sans-serif;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #212529;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* App List Container */
|
||||||
|
.app-list-container {
|
||||||
|
background-color: #f6f9fb;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 30px 45px;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* App List Item */
|
||||||
|
.app-list-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 40px 0;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-item:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
|
margin: 0 -20px;
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* App Icon */
|
||||||
|
.app-list-icon {
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-icon .app-icon-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-icon .app-icon-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #e9ecef;
|
||||||
|
border-radius: 12px;
|
||||||
|
color: #868e96;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* App Info */
|
||||||
|
.app-list-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 14px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status Badge */
|
||||||
|
.app-status-badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 5px 14px;
|
||||||
|
border-radius: 40px;
|
||||||
|
font-family: 'Noto Sans KR', 'Malgun Gothic', sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #ffffff;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-status-badge.status-pending {
|
||||||
|
background-color: #8c959f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-status-badge.status-approved {
|
||||||
|
background-color: #0049b4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-status-badge.status-changing {
|
||||||
|
background-color: #88a5f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-status-badge.status-inactive {
|
||||||
|
background-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* App Name */
|
||||||
|
.app-list-name {
|
||||||
|
font-family: 'Noto Sans KR', 'Malgun Gothic', sans-serif;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #212529;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* App Description */
|
||||||
|
.app-list-description {
|
||||||
|
font-family: 'Noto Sans KR', 'Malgun Gothic', sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #6e7780;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empty State */
|
||||||
|
.app-list-empty {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 80px 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-empty .empty-icon {
|
||||||
|
font-size: 64px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-empty h3 {
|
||||||
|
font-family: 'Noto Sans KR', 'Malgun Gothic', sans-serif;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #212529;
|
||||||
|
margin: 0 0 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-empty p {
|
||||||
|
font-family: 'Noto Sans KR', 'Malgun Gothic', sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #6e7780;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create App Button Wrapper */
|
||||||
|
.app-create-button-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create App Button */
|
||||||
|
.btn-app-create {
|
||||||
|
width: 220px;
|
||||||
|
height: 60px;
|
||||||
|
background-color: #0049b4;
|
||||||
|
color: #ffffff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-family: 'Noto Sans KR', 'Malgun Gothic', sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease, transform 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-app-create:hover {
|
||||||
|
background-color: #003a91;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-app-create:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media screen and (max-width: 768px) {
|
||||||
|
.app-management-container {
|
||||||
|
padding: 40px 16px 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-title-section {
|
||||||
|
padding: 12px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-title {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-item {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 30px 0;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-item:hover {
|
||||||
|
margin: 0 -10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-header {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-name {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list-description {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-create-button-wrapper {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-app-create {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 300px;
|
||||||
|
height: 54px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
|
||||||
// Card click handlers
|
// App creation button handler
|
||||||
const apikeyCards = document.querySelectorAll('.apikey-card');
|
|
||||||
apikeyCards.forEach(function(card) {
|
|
||||||
// Prevent navigation when clicking on specific elements
|
|
||||||
const preventNavElements = card.querySelectorAll('.btn-copy-key, .btn-view-detail, a');
|
|
||||||
preventNavElements.forEach(function(element) {
|
|
||||||
element.addEventListener('click', function(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Card click handler
|
|
||||||
card.addEventListener('click', function(e) {
|
|
||||||
// Don't navigate if clicking on interactive elements
|
|
||||||
if (e.target.closest('.btn-copy-key') || e.target.closest('.btn-view-detail')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const href = this.getAttribute('data-href');
|
|
||||||
if (href) {
|
|
||||||
window.location.href = href;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Keyboard accessibility
|
|
||||||
card.addEventListener('keypress', function(e) {
|
|
||||||
if (e.key === 'Enter' || e.key === ' ') {
|
|
||||||
e.preventDefault();
|
|
||||||
const href = this.getAttribute('data-href');
|
|
||||||
if (href) {
|
|
||||||
window.location.href = href;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Copy to clipboard functionality
|
|
||||||
const copyButtons = document.querySelectorAll('.btn-copy-key');
|
|
||||||
copyButtons.forEach(function(button) {
|
|
||||||
button.addEventListener('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
const textToCopy = this.getAttribute('data-clipboard-text');
|
|
||||||
|
|
||||||
// Create temporary input element
|
|
||||||
const tempInput = document.createElement('input');
|
|
||||||
tempInput.value = textToCopy;
|
|
||||||
document.body.appendChild(tempInput);
|
|
||||||
tempInput.select();
|
|
||||||
|
|
||||||
try {
|
|
||||||
document.execCommand('copy');
|
|
||||||
|
|
||||||
// Visual feedback
|
|
||||||
const originalContent = this.innerHTML;
|
|
||||||
this.innerHTML = '<span class="copy-icon">✓</span>';
|
|
||||||
this.classList.add('copied');
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.innerHTML = originalContent;
|
|
||||||
this.classList.remove('copied');
|
|
||||||
}, 2000);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Failed to copy text: ', err);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.body.removeChild(tempInput);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// App creation button handlers
|
|
||||||
const requestApiKeyBtn = document.getElementById('requestApiKey');
|
const requestApiKeyBtn = document.getElementById('requestApiKey');
|
||||||
const requestApiKeyEmptyBtn = document.getElementById('requestApiKeyEmpty');
|
|
||||||
|
|
||||||
function handleApiKeyRequest() {
|
function handleApiKeyRequest() {
|
||||||
// Clear any existing registration data from sessionStorage
|
// Clear any existing registration data from sessionStorage
|
||||||
@@ -230,17 +410,12 @@
|
|||||||
keysToRemove.forEach(key => sessionStorage.removeItem(key));
|
keysToRemove.forEach(key => sessionStorage.removeItem(key));
|
||||||
|
|
||||||
// Redirect to the API key registration wizard with clear parameter
|
// Redirect to the API key registration wizard with clear parameter
|
||||||
// This tells the server to clear the session and start fresh
|
|
||||||
window.location.href = '/myapikey/register/step1?clear=true';
|
window.location.href = '/myapikey/register/step1?clear=true';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestApiKeyBtn) {
|
if (requestApiKeyBtn) {
|
||||||
requestApiKeyBtn.addEventListener('click', handleApiKeyRequest);
|
requestApiKeyBtn.addEventListener('click', handleApiKeyRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestApiKeyEmptyBtn) {
|
|
||||||
requestApiKeyEmptyBtn.addEventListener('click', handleApiKeyRequest);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
layout:decorate="~{layout/kbank_signup_layout}">
|
layout:decorate="~{layout/kbank_signup_layout}">
|
||||||
<body>
|
<body>
|
||||||
<section layout:fragment="title">
|
<section layout:fragment="title">
|
||||||
<div class="org-page-title-banner">
|
<div class="page-title-banner">
|
||||||
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
||||||
<h1>법인회원 전환</h1>
|
<h1>법인회원 전환</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<section layout:fragment="title">
|
<section layout:fragment="title">
|
||||||
<div class="org-page-title-banner">
|
<div class="page-title-banner">
|
||||||
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
||||||
<h1>비밀번호 변경</h1>
|
<h1>비밀번호 변경</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
layout:decorate="~{layout/kjbank_title_layout}">
|
layout:decorate="~{layout/kjbank_title_layout}">
|
||||||
<body>
|
<body>
|
||||||
<section layout:fragment="title">
|
<section layout:fragment="title">
|
||||||
<div class="org-page-title-banner">
|
<div class="page-title-banner">
|
||||||
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
||||||
<h1>비밀번호 변경</h1>
|
<h1>비밀번호 변경</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
layout:decorate="~{layout/kjbank_title_layout}">
|
layout:decorate="~{layout/kjbank_title_layout}">
|
||||||
<body>
|
<body>
|
||||||
<section layout:fragment="title">
|
<section layout:fragment="title">
|
||||||
<div class="org-page-title-banner">
|
<div class="page-title-banner">
|
||||||
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
||||||
<h1>내 정보 관리</h1>
|
<h1>내 정보 관리</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
layout:decorate="~{layout/kjbank_title_layout}">
|
layout:decorate="~{layout/kjbank_title_layout}">
|
||||||
<body>
|
<body>
|
||||||
<section layout:fragment="title">
|
<section layout:fragment="title">
|
||||||
<div class="org-page-title-banner">
|
<div class="page-title-banner">
|
||||||
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
||||||
<h1>내 정보 관리</h1>
|
<h1>내 정보 관리</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
layout:decorate="~{layout/kjbank_title_layout}">
|
layout:decorate="~{layout/kjbank_title_layout}">
|
||||||
<body>
|
<body>
|
||||||
<section layout:fragment="title">
|
<section layout:fragment="title">
|
||||||
<div class="org-page-title-banner">
|
<div class="page-title-banner">
|
||||||
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
||||||
<h1>내 정보 관리</h1>
|
<h1>내 정보 관리</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
layout:decorate="~{layout/kjbank_title_layout}">
|
layout:decorate="~{layout/kjbank_title_layout}">
|
||||||
<body>
|
<body>
|
||||||
<section layout:fragment="title">
|
<section layout:fragment="title">
|
||||||
<div class="org-page-title-banner">
|
<div class="page-title-banner">
|
||||||
<img th:src="@{/img/user_register_title.png}" alt="법인회원가입" class="title-image">
|
<img th:src="@{/img/user_register_title.png}" alt="법인회원가입" class="title-image">
|
||||||
<h1>법인회원가입</h1>
|
<h1>법인회원가입</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
layout:decorate="~{layout/kjbank_title_layout}">
|
layout:decorate="~{layout/kjbank_title_layout}">
|
||||||
<body>
|
<body>
|
||||||
<section layout:fragment="title">
|
<section layout:fragment="title">
|
||||||
<div class="org-page-title-banner">
|
<div class="page-title-banner">
|
||||||
<img th:src="@{/img/user_register_title.png}" alt="개인회원가입" class="title-image">
|
<img th:src="@{/img/user_register_title.png}" alt="개인회원가입" class="title-image">
|
||||||
<h1 th:text="${!isInvited ? '개인회원가입' : '법인회원가입'}">개인회원가입</h1>
|
<h1 th:text="${!isInvited ? '개인회원가입' : '법인회원가입'}">개인회원가입</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
layout:decorate="~{layout/kjbank_title_layout}">
|
layout:decorate="~{layout/kjbank_title_layout}">
|
||||||
<body>
|
<body>
|
||||||
<section layout:fragment="title">
|
<section layout:fragment="title">
|
||||||
<div class="org-page-title-banner">
|
<div class="page-title-banner">
|
||||||
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
<img th:src="@{/img/user_register_title.png}" class="title-image">
|
||||||
<h1 th:text="${agreementTitle}">비밀번호 변경</h1>
|
<h1 th:text="${agreementTitle}">비밀번호 변경</h1>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user