feat: 로그인 퍼블리싱

This commit is contained in:
hong
2026-07-30 10:01:38 +09:00
parent 4181d114c1
commit faaf9e8cd6
20 changed files with 1120 additions and 1238 deletions
@@ -73,7 +73,7 @@ public class AppServiceFacade {
List<AppRequest> appRequests = appRequestRepository.findAllByOrgAndTypeIsInAndApproval_ApprovalStatusIn(portalOrg, types,
Arrays.asList(new ProcessingState(), new RequestedState()));
// 승인정보(approval) 없는 신청도 목록에 노출한다. (사용자가 직접 삭제 가능)
// 승인정보(approval) 없는 신청도 목록에 노출`한다. (사용자가 직접 삭제 가능)
appRequests.addAll(appRequestRepository .findAllByOrgAndTypeIsInAndApprovalIsNull(portalOrg, types));
return appRequests;
+182 -237
View File
@@ -1421,7 +1421,7 @@ hr {
.nav-menu {
display: flex;
list-style: none;
gap: 28px;
gap: 24px;
margin: 0;
padding: 0;
}
@@ -1431,6 +1431,7 @@ hr {
.nav-menu > li.submenu-open > .nav-link {
background: var(--light-bg);
color: var(--primary-blue);
border-radius: 9px;
}
.nav-menu > li.submenu-open .sub-menu {
visibility: visible;
@@ -1476,7 +1477,7 @@ hr {
font-size: 16px;
font-weight: 500;
color: var(--text-gray);
padding: 8px;
padding: 12px;
position: relative;
transition: var(--transition-smooth);
}
@@ -4319,7 +4320,7 @@ select.form-control {
box-shadow: 0 0 0 3px rgba(0, 73, 180, 0.1);
}
.form-input:disabled, .form-input.input-readonly {
background: #F8FAFC;
background: #e9ecef !important;
color: #64748B;
cursor: not-allowed;
}
@@ -12133,26 +12134,27 @@ body.index-page-body {
}
.account-recovery-page {
display: flex;
align-items: flex-start;
align-items: center;
justify-content: center;
background: transparent;
padding: 0;
padding: 100px 20px;
position: relative;
min-height: auto;
margin: 0;
border-radius: 12px;
margin-bottom: 50px;
}
.account-recovery-container {
width: 100%;
max-width: 800px;
max-width: 650px;
margin: 0 auto;
position: relative;
padding: 24px;
}
.account-recovery-card {
background: transparent;
padding: 0;
background: #FFFFFF;
border-radius: 20px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
padding: 36px 36px 28px;
display: flex;
flex-direction: column;
align-items: stretch;
@@ -12160,7 +12162,8 @@ body.index-page-body {
}
@media (max-width: 576px) {
.account-recovery-card {
padding: 0 20px;
padding: 24px 20px 20px;
border-radius: 16px;
}
}
@@ -12175,10 +12178,9 @@ body.index-page-body {
.account-recovery-tabs {
display: flex;
gap: 0;
margin-bottom: 0;
margin-bottom: 28px;
width: 100%;
background: transparent;
border-radius: 0;
padding: 0;
}
.account-recovery-tabs .tab-link {
@@ -12186,36 +12188,37 @@ body.index-page-body {
display: flex;
align-items: center;
justify-content: center;
padding: 14px 24px;
padding: 14px 20px;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 16px;
font-weight: 700;
color: #8c959f;
font-size: 15px;
font-weight: 400;
color: #adb5bd;
text-decoration: none;
text-align: center;
background: #eceff4;
background: #FFFFFF;
border: 1.5px solid transparent;
border-bottom: 1.5px solid #dee2e6;
border-radius: 0;
transition: all 0.3s ease;
}
.account-recovery-tabs .tab-link:first-child {
border-radius: 30px 0 0 0;
}
.account-recovery-tabs .tab-link:last-child {
border-radius: 0 30px 0 0;
transition: all 0.2s ease;
cursor: pointer;
position: relative;
}
.account-recovery-tabs .tab-link:hover {
color: #3ba4ed;
background: #e4e8ed;
color: #0049b4;
}
.account-recovery-tabs .tab-link.active {
color: #FFFFFF;
background: #3ba4ed;
color: #0049b4;
font-weight: 700;
border-top: 1.5px solid #0049b4;
border-left: 1.5px solid #0049b4;
border-right: 1.5px solid #0049b4;
border-bottom: 2px solid #FFFFFF;
border-radius: 8px 8px 0px 0px;
}
@media (max-width: 576px) {
.account-recovery-tabs .tab-link {
padding: 12px 16px;
font-size: 14px;
padding: 12px 10px;
font-size: 13px;
}
}
@@ -12254,75 +12257,44 @@ body.index-page-body {
.account-recovery-form {
width: 100%;
margin-bottom: 0;
background: #F6F9FB;
padding: 40px;
border-radius: 0 0 12px 12px;
}
@media (max-width: 576px) {
.account-recovery-form {
padding: 24px 16px;
}
background: transparent;
padding: 0;
}
.account-recovery-form .form-group {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 20px;
flex-direction: column;
gap: 0;
margin-bottom: 12px;
}
.account-recovery-form .form-group:last-of-type {
margin-bottom: 0;
}
@media (max-width: 768px) {
.account-recovery-form .form-group {
flex-direction: column;
align-items: stretch;
gap: 10px;
}
}
.account-recovery-form .form-label {
display: flex;
align-items: center;
flex-shrink: 0;
width: 170px;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 15px;
font-weight: 400;
color: #212529;
margin-bottom: 0;
}
.account-recovery-form .form-label .required {
color: #ed5b5b;
margin-left: 2px;
}
@media (max-width: 768px) {
.account-recovery-form .form-label {
width: 100%;
font-size: 14px;
}
display: none;
}
.account-recovery-form .form-input {
flex: 1;
height: 40px;
width: 100%;
height: 48px;
padding: 0 16px;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
font-weight: 400;
color: #212529;
background: #FFFFFF;
border: 1px solid #dadada;
border-radius: 8px;
border: 1px solid #E2E8F0;
border-radius: 10px;
outline: none;
transition: all 0.3s ease;
transition: all 0.25s ease;
}
.account-recovery-form .form-input::placeholder {
color: #dadada;
color: #B0B8C1;
}
.account-recovery-form .form-input:hover {
border-color: #3ba4ed;
}
.account-recovery-form .form-input:focus {
border-color: #3ba4ed;
box-shadow: 0 0 0 2px rgba(59, 164, 237, 0.1);
box-shadow: 0 0 0 3px rgba(59, 164, 237, 0.12);
}
.account-recovery-form .form-input:disabled {
background: #F8F9FA;
@@ -12334,24 +12306,24 @@ body.index-page-body {
border-color: #ed5b5b;
}
.account-recovery-form .form-select {
height: 40px;
padding: 0 32px 0 16px;
height: 48px;
padding: 0 24px 0 12px;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
font-weight: 400;
color: #515151;
background: #FFFFFF;
border: 1px solid #dadada;
border-radius: 8px;
border: 1px solid #E2E8F0;
border-radius: 10px;
outline: none;
cursor: pointer;
transition: all 0.3s ease;
transition: all 0.25s ease;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='5' viewBox='0 0 10 5'%3E%3Cpath fill='%231D1B20' d='M5 5L0 0h10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
background-position: right 8px center;
background-size: 10px 5px;
}
.account-recovery-form .form-select:hover {
@@ -12359,7 +12331,7 @@ body.index-page-body {
}
.account-recovery-form .form-select:focus {
border-color: #3ba4ed;
box-shadow: 0 0 0 2px rgba(59, 164, 237, 0.1);
box-shadow: 0 0 0 3px rgba(59, 164, 237, 0.12);
}
.account-recovery-form .form-select:disabled {
background-color: #F8F9FA;
@@ -12373,50 +12345,89 @@ body.index-page-body {
font-size: 14px;
}
.reset-method-group {
margin-bottom: 16px !important;
}
.reset-method-tabs {
display: flex;
gap: 8px;
background: #f0f2f5;
border-radius: 10px;
padding: 4px;
}
.reset-method-tabs .reset-method-tab {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
margin: 0;
}
.reset-method-tabs .reset-method-tab input[type=radio] {
display: none;
}
.reset-method-tabs .reset-method-tab span {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
padding: 9px 12px;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 13px;
font-weight: 600;
color: #8c959f;
border-radius: 7px;
transition: all 0.2s ease;
text-align: center;
}
.reset-method-tabs .reset-method-tab input[type=radio]:checked + span {
background: #FFFFFF;
color: #212529;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.09);
}
.reset-method-tabs .reset-method-tab:hover span {
color: #3ba4ed;
}
.phone-input-group {
display: flex;
align-items: center;
gap: 8px;
flex: 1;
gap: 6px;
width: 100%;
}
.phone-input-group .phone-prefix {
width: 100px;
width: 90px;
min-width: 90px;
flex-shrink: 0;
}
.phone-input-group .phone-middle,
.phone-input-group .phone-last {
width: 100px;
flex-shrink: 0;
flex: 1;
min-width: 0;
}
.phone-input-group .phone-separator {
display: flex;
align-items: center;
justify-content: center;
width: 8px;
height: 1px;
background: #515151;
color: #B0B8C1;
font-size: 14px;
flex-shrink: 0;
width: 10px;
height: auto;
background: transparent;
}
@media (max-width: 768px) {
.phone-input-group .phone-separator::before {
content: "-";
}
@media (max-width: 576px) {
.phone-input-group {
flex-wrap: wrap;
gap: 6px;
}
.phone-input-group .phone-prefix,
.phone-input-group .phone-middle,
.phone-input-group .phone-last {
.phone-input-group .phone-prefix {
flex: 1;
min-width: 60px;
}
.phone-input-group .phone-separator {
width: 6px;
}
}
@media (max-width: 576px) {
.phone-input-group .phone-prefix,
.phone-input-group .phone-middle,
.phone-input-group .phone-last {
width: 100%;
width: auto;
}
.phone-input-group .phone-separator {
display: none;
@@ -12431,92 +12442,97 @@ body.index-page-body {
position: relative;
display: flex;
align-items: center;
flex: 1;
width: 100%;
gap: 8px;
}
.auth-input-group.mg-y {
margin-top: 20px;
margin-bottom: 12px;
}
.auth-input-group .auth-input {
flex: 1;
padding-right: 60px;
min-width: 0;
}
.auth-input-group .auth-timer {
position: absolute;
right: 16px;
right: 20px;
top: 50%;
transform: translateY(-50%);
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
font-weight: 400;
font-size: 13px;
font-weight: 500;
color: #ed5b5b;
pointer-events: none;
}
@media (max-width: 576px) {
.auth-input-group .auth-timer {
font-size: 12px;
right: 12px;
right: 100px;
}
}
.auth-request-button,
.auth-verify-button {
width: 140px;
height: 40px;
padding: 8px;
height: 48px;
padding: 0 16px;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
font-size: 13px;
font-weight: 700;
color: #FFFFFF;
background: #a4d6ea;
background: #3ba4ed;
border: none;
border-radius: 8px;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
margin: 0;
transition: all 0.25s ease;
flex-shrink: 0;
white-space: nowrap;
line-height: 1;
}
.auth-request-button:hover,
.auth-verify-button:hover {
background: rgb(147.83125, 206.7151785714, 230.26875);
background: rgb(37.3117757009, 153.9304672897, 235.0082242991);
transform: none !important;
}
.auth-request-button:active,
.auth-verify-button:active {
background: rgb(131.6625, 199.4303571429, 226.5375);
background: rgb(21.411588785, 146.3125233645, 233.148411215);
}
.auth-request-button:disabled,
.auth-verify-button:disabled {
opacity: 0.6;
opacity: 0.5;
cursor: not-allowed;
}
@media (max-width: 576px) {
.auth-request-button,
.auth-verify-button {
width: 100%;
height: 40px;
height: 44px;
font-size: 13px;
margin-top: 8px;
margin-top: 4px;
}
}
.account-recovery-card .form-actions {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 32px;
padding: 32px 0;
gap: 12px;
margin-top: 28px;
padding: 0;
border-top: none;
background: transparent;
}
.account-recovery-card .form-actions .cancel-button,
.account-recovery-card .form-actions .submit-button {
width: 160px;
height: 40px;
padding: 8px;
flex: 1;
height: 48px;
padding: 0 8px;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
font-size: 15px;
font-weight: 700;
border: none;
border-radius: 8px;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
transition: all 0.25s ease;
line-height: 1;
display: flex;
align-items: center;
@@ -12525,20 +12541,20 @@ body.index-page-body {
}
.account-recovery-card .form-actions .cancel-button {
color: #5f666c;
background: #e5e7eb;
background: #f0f2f5;
}
.account-recovery-card .form-actions .cancel-button:hover {
background: rgb(215.8869565217, 218.8956521739, 224.9130434783);
background: rgb(225.45, 229.39, 235.3);
}
.account-recovery-card .form-actions .cancel-button:active {
background: rgb(202.7739130435, 206.7913043478, 214.8260869565);
background: rgb(210.9, 216.78, 225.6);
}
.account-recovery-card .form-actions .submit-button {
color: #FFFFFF;
background: #0049B4;
}
.account-recovery-card .form-actions .submit-button:hover {
background: rgb(0, 69.35, 171);
background: rgb(6, 54, 125);
}
.account-recovery-card .form-actions .submit-button:active {
background: rgb(0, 65.7, 162);
@@ -12549,15 +12565,12 @@ body.index-page-body {
}
@media (max-width: 576px) {
.account-recovery-card .form-actions {
flex-direction: column;
gap: 10px;
padding: 20px 0;
}
.account-recovery-card .form-actions .cancel-button,
.account-recovery-card .form-actions .submit-button {
width: 100%;
height: 40px;
font-size: 13px;
height: 44px;
font-size: 14px;
}
}
@@ -12613,7 +12626,6 @@ body.index-page-body {
}
.account-recovery-result {
width: 100%;
background: #F6F9FB;
padding: 60px 40px;
border-radius: 0 0 12px 12px;
text-align: center;
@@ -12765,128 +12777,62 @@ body.index-page-body {
margin: 0;
}
.account-recovery-container {
padding: 20px;
padding: 16px;
}
.account-recovery-card {
padding: 0;
padding: 24px 16px 20px;
border-radius: 16px;
}
.account-recovery-tabs {
margin-bottom: 20px;
}
.account-recovery-tabs .tab-link {
height: 40px;
padding: 10px 16px;
font-size: 14px;
font-weight: 700;
}
.account-recovery-tabs .tab-link:first-child {
border-radius: 8px 0 0 0;
}
.account-recovery-tabs .tab-link:last-child {
border-radius: 0 8px 0 0;
}
.account-recovery-form {
padding: 20px;
border-radius: 0 0 8px 8px;
padding: 9px 12px;
font-size: 13px;
}
.account-recovery-form .form-group {
flex-direction: column;
align-items: stretch;
gap: 8px;
margin-bottom: 16px;
}
.account-recovery-form .form-label {
width: 100%;
font-size: 14px;
font-weight: 500;
margin-bottom: 0;
margin-bottom: 10px;
}
.account-recovery-form .form-input {
flex: none;
width: 100%;
height: 40px;
padding: 0 16px;
font-size: 12px;
border-radius: 8px;
}
.account-recovery-form .form-input::placeholder {
color: #8c959f;
height: 44px;
font-size: 13px;
}
.account-recovery-form .form-select {
height: 40px;
padding: 0 32px 0 12px;
font-size: 12px;
border-radius: 8px;
background-position: right 10px center;
height: 44px;
font-size: 13px;
}
.phone-input-group {
flex-wrap: wrap;
gap: 8px;
align-items: center;
width: 100%;
gap: 6px;
}
.phone-input-group .phone-prefix {
flex: 1;
min-width: 0;
width: auto;
}
.phone-input-group .phone-middle,
.phone-input-group .phone-last {
flex: 1;
min-width: 0;
width: auto;
}
.phone-input-group .phone-separator {
display: flex;
width: auto;
height: auto;
background: transparent;
font-size: 12px;
color: #000;
}
.phone-input-group .phone-separator::before {
content: "-";
}
.auth-input-group {
width: 100%;
}
.auth-input-group .auth-input {
width: 100%;
padding-right: 60px;
display: none;
}
.auth-input-group .auth-timer {
font-size: 12px;
right: 12px;
right: 100px;
}
.auth-request-button,
.auth-verify-button {
width: 100%;
height: 40px;
padding: 10px;
font-size: 14px;
font-weight: 700;
border-radius: 8px;
margin-top: 8px;
height: 44px;
font-size: 13px;
margin-top: 4px;
}
.account-recovery-card .form-actions {
flex-direction: row;
gap: 21px;
margin-top: 24px;
padding: 24px 0;
gap: 10px;
margin-top: 20px;
}
.account-recovery-card .form-actions .cancel-button,
.account-recovery-card .form-actions .submit-button {
flex: 1;
min-width: 144px;
height: 40px;
height: 44px;
font-size: 14px;
font-weight: 700;
border-radius: 8px;
}
.account-recovery-card .form-actions .cancel-button {
background: #e5e7eb;
color: #5f666c;
}
.account-recovery-card .form-actions .submit-button {
background: #0049b4;
color: #ffffff;
}
.account-recovery-result {
padding: 30px 20px;
@@ -13376,7 +13322,7 @@ body.index-page-body {
.corp-manager-wrapper .input-readonly,
.password-change-wrapper .form-input:disabled,
.password-change-wrapper .input-readonly {
background: #ededed;
background: #e9ecef !important;
}
.corp-manager-wrapper .compound-input,
.password-change-wrapper .compound-input {
@@ -21429,7 +21375,6 @@ input[type=checkbox]:checked + .custom-checkbox {
}
.org-compound-input .org-form-input,
.org-compound-input .org-form-select {
flex: 1;
min-width: 0;
}
.org-compound-input .org-form-input.phone-number {
@@ -21571,16 +21516,15 @@ input[type=checkbox]:checked + .custom-checkbox {
padding: 10px 20px;
width: auto;
min-width: 100px;
background: #00A1D7;
color: #FFFFFF;
border: 1px solid #00A1D7;
border-radius: 8px;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
font-weight: 700;
text-align: center;
justify-content: center;
transition: all 0.2s ease;
background: #3BA4ED;
border: 1px solid #3BA4ED;
}
.org-btn-check:not(:disabled):hover, .org-file-label:not(:disabled):hover {
background: #008BC0;
@@ -21806,6 +21750,7 @@ input[type=checkbox]:checked + .custom-checkbox {
flex-direction: column;
gap: 20px;
margin-bottom: 90px;
font-family: "Spoqa Han Sans Neo", "SpoqaHanSans", "Noto Sans KR", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.agreement-all-section {
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
@@ -478,7 +478,7 @@ select.form-control {
&:disabled,
&.input-readonly {
background: $gray-bg;
background: #e9ecef !important;
color: $text-gray;
cursor: not-allowed;
}
@@ -913,7 +913,7 @@
.nav-menu {
display: flex;
list-style: none;
gap: 28px;
gap: 24px;
margin: 0;
padding: 0;
@@ -925,6 +925,7 @@
>.nav-link {
background: var(--light-bg);
color: var(--primary-blue);
border-radius: 9px;
}
.sub-menu {
@@ -978,7 +979,7 @@
font-size: 16px;
font-weight: 500;
color: var(--text-gray);
padding: 8px;
padding: 12px;
position: relative;
transition: var(--transition-smooth);
@@ -9,33 +9,35 @@
.account-recovery-page {
display: flex;
align-items: flex-start;
align-items: center;
justify-content: center;
background: transparent;
padding: 0;
padding: 100px 20px;
position: relative;
min-height: auto;
margin: 0;
border-radius: 12px;
margin-bottom: 50px;
}
.account-recovery-container {
width: 100%;
max-width: 800px;
max-width: 650px;
margin: 0 auto;
position: relative;
padding: $spacing-lg;
}
.account-recovery-card {
background: transparent;
padding: 0;
background: #FFFFFF;
border-radius: 20px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.10);
padding: 36px 36px 28px;
display: flex;
flex-direction: column;
align-items: stretch;
position: relative;
@media (max-width: 576px) {
padding: 0 20px;
padding: 24px 20px 20px;
border-radius: 16px;
}
}
@@ -49,14 +51,13 @@
display: none;
}
// Tab Navigation (Figma 디자인: 약관 페이지와 동일)
// Tab Navigation (Design 2: 클래식 폴더 탭)
.account-recovery-tabs {
display: flex;
gap: 0;
margin-bottom: 0;
margin-bottom: 28px;
width: 100%;
background: transparent;
border-radius: 0;
padding: 0;
.tab-link {
@@ -64,45 +65,46 @@
display: flex;
align-items: center;
justify-content: center;
padding: 14px 24px;
padding: 14px 20px;
font-family: $font-family-primary;
font-size: 16px;
font-weight: 700;
color: #8c959f;
font-size: 15px;
font-weight: 400;
color: #adb5bd;
text-decoration: none;
text-align: center;
background: #eceff4;
background: #FFFFFF;
// 비활성 탭: 하단 border만 (바닥선 역할)
border: 1.5px solid transparent;
border-bottom: 1.5px solid #dee2e6;
border-radius: 0;
transition: all 0.3s ease;
// 왼쪽 탭 둥근 모서리
&:first-child {
border-radius: 30px 0 0 0;
}
// 오른쪽 탭 둥근 모서리
&:last-child {
border-radius: 0 30px 0 0;
}
transition: all 0.2s ease;
cursor: pointer;
position: relative;
&:hover {
color: #3ba4ed;
background: #e4e8ed;
color: $primary-blue;
}
&.active {
color: #FFFFFF;
background: #3ba4ed;
color: $primary-blue;
font-weight: 700;
// 활성 탭: 상/좌/우 파란 테두리 + 하단 흰색으로 바닥선 가려 콘텐츠와 연결
border-top: 1.5px solid $primary-blue;
border-left: 1.5px solid $primary-blue;
border-right: 1.5px solid $primary-blue;
border-bottom: 2px solid #FFFFFF;
border-radius: 8px 8px 0px 0px;
}
@media (max-width: 576px) {
padding: 12px 16px;
font-size: 14px;
padding: 12px 10px;
font-size: 13px;
}
}
}
// Alert Messages
.account-alert {
width: 100%;
@@ -140,73 +142,45 @@
}
}
// Form Content Area (Figma: 아이디찾기BG_box)
// Form Content Area (세로 스택형, 라벨 없는 심플 스타일)
.account-recovery-form {
width: 100%;
margin-bottom: 0;
background: #F6F9FB;
padding: 40px;
border-radius: 0 0 12px 12px;
@media (max-width: 576px) {
padding: 24px 16px;
}
background: transparent;
padding: 0;
.form-group {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 20px;
flex-direction: column;
gap: 0;
margin-bottom: 12px;
&:last-of-type {
margin-bottom: 0;
}
@media (max-width: 768px) {
flex-direction: column;
align-items: stretch;
gap: 10px;
}
}
// 라벨은 숨김 (placeholder로 대체)
.form-label {
display: flex;
align-items: center;
flex-shrink: 0;
width: 170px;
font-family: $font-family-primary;
font-size: 15px;
font-weight: 400;
color: #212529;
margin-bottom: 0;
.required {
color: #ed5b5b;
margin-left: 2px;
}
@media (max-width: 768px) {
width: 100%;
font-size: 14px;
}
display: none;
}
.form-input {
flex: 1;
height: 40px;
width: 100%;
height: 48px;
padding: 0 16px;
font-family: $font-family-primary;
font-size: 14px;
font-weight: 400;
color: #212529;
background: #FFFFFF;
border: 1px solid #dadada;
border-radius: 8px;
border: 1px solid #E2E8F0;
border-radius: 10px;
outline: none;
transition: all 0.3s ease;
transition: all 0.25s ease;
&::placeholder {
color: #dadada;
color: #B0B8C1;
}
&:hover {
@@ -215,7 +189,7 @@
&:focus {
border-color: #3ba4ed;
box-shadow: 0 0 0 2px rgba(59, 164, 237, 0.1);
box-shadow: 0 0 0 3px rgba(59, 164, 237, 0.12);
}
&:disabled {
@@ -231,24 +205,24 @@
}
.form-select {
height: 40px;
padding: 0 32px 0 16px;
height: 48px;
padding: 0 24px 0 12px; // padding을 좀 더 좁혀서 내용이 더 잘 보이도록 수정
font-family: $font-family-primary;
font-size: 14px;
font-weight: 400;
color: #515151;
background: #FFFFFF;
border: 1px solid #dadada;
border-radius: 8px;
border: 1px solid #E2E8F0;
border-radius: 10px;
outline: none;
cursor: pointer;
transition: all 0.3s ease;
transition: all 0.25s ease;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='5' viewBox='0 0 10 5'%3E%3Cpath fill='%231D1B20' d='M5 5L0 0h10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
background-position: right 8px center; // 화살표 아이콘 위치도 조정
background-size: 10px 5px;
&:hover {
@@ -257,7 +231,7 @@
&:focus {
border-color: #3ba4ed;
box-shadow: 0 0 0 2px rgba(59, 164, 237, 0.1);
box-shadow: 0 0 0 3px rgba(59, 164, 237, 0.12);
}
&:disabled {
@@ -275,55 +249,99 @@
}
}
// Phone Input Group (Figma: 휴대폰번호+텍스트필드)
// 인증 방식 선택 pill 탭 (비밀번호 초기화 탭 내부)
.reset-method-group {
margin-bottom: 16px !important;
}
.reset-method-tabs {
display: flex;
gap: 8px;
background: #f0f2f5;
border-radius: 10px;
padding: 4px;
.reset-method-tab {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
margin: 0;
input[type="radio"] {
display: none;
}
span {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
padding: 9px 12px;
font-family: $font-family-primary;
font-size: 13px;
font-weight: 600;
color: #8c959f;
border-radius: 7px;
transition: all 0.2s ease;
text-align: center;
}
input[type="radio"]:checked+span {
background: #FFFFFF;
color: #212529;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.09);
}
&:hover span {
color: #3ba4ed;
}
}
}
// Phone Input Group
.phone-input-group {
display: flex;
align-items: center;
gap: 8px;
flex: 1;
gap: 6px;
width: 100%;
.phone-prefix {
width: 100px;
width: 90px;
min-width: 90px; // select가 줄어들지 않도록 고정
flex-shrink: 0;
}
.phone-middle,
.phone-last {
width: 100px;
flex-shrink: 0;
flex: 1;
min-width: 0;
}
.phone-separator {
display: flex;
align-items: center;
justify-content: center;
width: 8px;
height: 1px;
background: #515151;
color: #B0B8C1;
font-size: 14px;
flex-shrink: 0;
}
width: 10px;
height: auto;
background: transparent;
@media (max-width: 768px) {
flex-wrap: wrap;
gap: 6px;
.phone-prefix,
.phone-middle,
.phone-last {
flex: 1;
min-width: 60px;
}
.phone-separator {
width: 6px;
&::before {
content: '-';
}
}
@media (max-width: 576px) {
.phone-prefix,
.phone-middle,
.phone-last {
width: 100%;
flex-wrap: wrap;
gap: 6px;
.phone-prefix {
flex: 1;
width: auto;
}
.phone-separator {
@@ -332,7 +350,7 @@
}
}
// Auth Number Group (Figma: 인증번호+텍스트필드)
// Auth Number Group
.auth-number-group {
margin-top: 0;
}
@@ -341,95 +359,103 @@
position: relative;
display: flex;
align-items: center;
flex: 1;
width: 100%;
gap: 8px;
&.mg-y {
margin-top: 20px;
margin-bottom: 12px;
}
.auth-input {
flex: 1;
padding-right: 60px;
min-width: 0;
}
.auth-timer {
position: absolute;
right: 16px;
right: 20px; // verify button width + gap
top: 50%;
transform: translateY(-50%);
font-family: $font-family-primary;
font-size: 14px;
font-weight: 400;
font-size: 13px;
font-weight: 500;
color: #ed5b5b;
pointer-events: none;
@media (max-width: 576px) {
font-size: 12px;
right: 12px;
right: 100px;
}
}
}
// Buttons (Figma: 인증번호 받기/확인)
// Buttons: 인증번호 받기 / 확인
.auth-request-button,
.auth-verify-button {
width: 140px;
height: 40px;
padding: 8px;
height: 48px;
padding: 0 16px;
font-family: $font-family-primary;
font-size: 14px;
font-size: 13px;
font-weight: 700;
color: #FFFFFF;
background: #a4d6ea;
background: #3ba4ed;
border: none;
border-radius: 8px;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
margin: 0;
transition: all 0.25s ease;
flex-shrink: 0;
white-space: nowrap;
line-height: 1;
&:hover {
background: darken(#a4d6ea, 5%);
background: darken(#3ba4ed, 8%);
transform: none !important;
}
&:active {
background: darken(#a4d6ea, 10%);
background: darken(#3ba4ed, 14%);
}
&:disabled {
opacity: 0.6;
opacity: 0.5;
cursor: not-allowed;
}
@media (max-width: 576px) {
width: 100%;
height: 40px;
height: 44px;
font-size: 13px;
margin-top: 8px;
margin-top: 4px;
}
}
// Form Actions (Figma: btn_취소, btn_신청)
// Form Actions
.account-recovery-card .form-actions {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 32px;
padding: 32px 0;
gap: 12px;
margin-top: 28px;
padding: 0;
border-top: none;
background: transparent;
.cancel-button,
.submit-button {
width: 160px;
height: 40px;
padding: 8px;
flex: 1;
height: 48px;
padding: 0 8px;
font-family: $font-family-primary;
font-size: 14px;
font-size: 15px;
font-weight: 700;
border: none;
border-radius: 8px;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
transition: all 0.25s ease;
line-height: 1;
// <a> 태그 지원
display: flex;
align-items: center;
justify-content: center;
@@ -438,14 +464,14 @@
.cancel-button {
color: #5f666c;
background: #e5e7eb;
background: #f0f2f5;
&:hover {
background: darken(#e5e7eb, 5%);
background: darken(#f0f2f5, 5%);
}
&:active {
background: darken(#e5e7eb, 10%);
background: darken(#f0f2f5, 10%);
}
}
@@ -454,7 +480,9 @@
background: #0049B4;
&:hover {
background: darken(#0049B4, 5%);
// background: darken(#0049B4, 5%);
background: rgb(6 54 125);
}
&:active {
@@ -468,15 +496,12 @@
}
@media (max-width: 576px) {
flex-direction: column;
gap: 10px;
padding: 20px 0;
.cancel-button,
.submit-button {
width: 100%;
height: 40px;
font-size: 13px;
height: 44px;
font-size: 14px;
}
}
}
@@ -521,6 +546,7 @@
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
@@ -545,7 +571,6 @@
// Result Page Styles (아이디 찾기 결과 페이지)
.account-recovery-result {
width: 100%;
background: #F6F9FB;
padding: 60px 40px;
border-radius: 0 0 12px 12px;
text-align: center;
@@ -701,7 +726,7 @@
}
// -----------------------------------------------------------------------------
// Figma Mobile Design - node 1152-7047 (sm: 768px breakpoint)
// Mobile Design (sm: 768px breakpoint)
// -----------------------------------------------------------------------------
@include respond-to('sm') {
.account-recovery-page {
@@ -710,164 +735,78 @@
}
.account-recovery-container {
padding: 20px;
padding: 16px;
}
.account-recovery-card {
padding: 0;
padding: 24px 16px 20px;
border-radius: 16px;
}
// Figma: 탭 - 167px × 40px, 14px Bold
.account-recovery-tabs {
margin-bottom: 20px;
.tab-link {
height: 40px;
padding: 10px 16px;
font-size: 14px;
font-weight: 700;
&:first-child {
border-radius: 8px 0 0 0;
}
&:last-child {
border-radius: 0 8px 0 0;
}
padding: 9px 12px;
font-size: 13px;
}
}
// Figma: 폼 영역
.account-recovery-form {
padding: 20px;
border-radius: 0 0 8px 8px;
.form-group {
flex-direction: column;
align-items: stretch;
gap: 8px;
margin-bottom: 16px;
margin-bottom: 10px;
}
// Figma: 라벨 - 14px Medium
.form-label {
width: 100%;
font-size: 14px;
font-weight: 500;
margin-bottom: 0;
}
// Figma: 입력 필드 - 335px × 40px, border-radius 8px
.form-input {
flex: none;
width: 100%;
height: 40px;
padding: 0 16px;
font-size: 12px;
border-radius: 8px;
&::placeholder {
color: #8c959f;
}
height: 44px;
font-size: 13px;
}
// Figma: 셀렉트 - 40px 높이, 8px radius
.form-select {
height: 40px;
padding: 0 32px 0 12px;
font-size: 12px;
border-radius: 8px;
background-position: right 10px center;
height: 44px;
font-size: 13px;
}
}
// 모바일: 휴대폰 번호 입력 - 화면 폭 채우기
.phone-input-group {
flex-wrap: wrap;
gap: 8px;
align-items: center;
width: 100%;
gap: 6px;
.phone-prefix {
flex: 1;
min-width: 0;
width: auto;
}
.phone-middle,
.phone-last {
flex: 1;
min-width: 0;
width: auto;
}
.phone-separator {
display: flex;
width: auto;
height: auto;
background: transparent;
font-size: 12px;
color: #000;
&::before {
content: '-';
}
display: none;
}
}
// 모바일: 인증번호 입력 그룹 - 화면 폭 채우기
.auth-input-group {
width: 100%;
.auth-input {
width: 100%;
padding-right: 60px;
}
// 타이머 - 12px, #ed5b5b
.auth-timer {
font-size: 12px;
right: 12px;
right: 100px;
}
}
// 모바일: 인증번호 받기/확인 버튼 - 화면 폭 채우기, 다음 줄에 배치
.auth-request-button,
.auth-verify-button {
width: 100%;
height: 40px;
padding: 10px;
font-size: 14px;
font-weight: 700;
border-radius: 8px;
margin-top: 8px;
height: 44px;
font-size: 13px;
margin-top: 4px;
}
// Figma: 하단 버튼 - 144px × 40px, gap 21px, 가로 배치
.account-recovery-card .form-actions {
flex-direction: row;
gap: 21px;
margin-top: 24px;
padding: 24px 0;
gap: 10px;
margin-top: 20px;
.cancel-button,
.submit-button {
flex: 1;
min-width: 144px;
height: 40px;
height: 44px;
font-size: 14px;
font-weight: 700;
border-radius: 8px;
}
// Figma: 취소 버튼 - #e5e7eb 배경, #5f666c 텍스트
.cancel-button {
background: #e5e7eb;
color: #5f666c;
}
// Figma: 제출 버튼 - #0049b4 배경, 흰색 텍스트
.submit-button {
background: #0049b4;
color: #ffffff;
}
}
@@ -159,7 +159,7 @@
.form-input:disabled,
.input-readonly {
background: #ededed;
background: #e9ecef !important;
}
.compound-input {
@@ -295,7 +295,6 @@
.org-form-input,
.org-form-select {
flex: 1;
min-width: 0;
}
@@ -455,16 +454,16 @@
padding: 10px 20px;
width: auto;
min-width: 100px;
background: #00A1D7;
color: $white;
border: 1px solid #00A1D7;
border-radius: 8px;
font-family: $font-family-primary;
font-size: 14px;
font-weight: 700;
text-align: center;
justify-content: center;
transition: all 0.2s ease;
// transition: all 0.2s ease;
background: #3BA4ED;
border: 1px solid #3BA4ED;
&:not(:disabled):hover {
background: #008BC0;
@@ -721,6 +720,7 @@
flex-direction: column;
gap: 20px;
margin-bottom: 90px;
font-family: $font-family-primary;
}
// Agree All Section
@@ -10,7 +10,8 @@
</div>
</section>
<section layout:fragment="contentFragment">
<div class="service-main">
<div class="service-main container" style="padding-top: 70px; padding-bottom:100px;">
<th:block th:replace="~{fragment/djbank/service_sidebar :: sidebar('profile')}"></th:block>
<div class="app-management-content">
<div class="password-change-wrapper">
<h2 class="page-outer-title">본인 확인</h2>
@@ -1,12 +1,14 @@
<!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/kbank_base_layout}">
<body>
<section layout:fragment="contentFragment" class="content">
<div class="content_wrap">
<div class="account-recovery-container">
<div class="account-recovery-card">
<!-- 탭 메뉴 -->
<!-- 탭 메뉴 (pill 스타일) -->
<div class="account-recovery-tabs">
<a href="#tab1" class="tab-link active" data-tab="tab1">아이디 찾기</a>
<a href="#tab2" class="tab-link" data-tab="tab2">비밀번호 초기화</a>
@@ -14,19 +16,18 @@
<!-- 아이디 찾기 폼 -->
<div id="tab1" class="account-recovery-form">
<form id="findIdForm" role="form" name="findIdForm" th:action="@{/find_id}" method="post" data-form-type="findId">
<form id="findIdForm" role="form" name="findIdForm" th:action="@{/find_id}" method="post"
data-form-type="findId">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<input type="hidden" id="findId-phoneNumber" name="phoneNumber">
<!-- 성명 입력 -->
<div class="form-group">
<label class="form-label">성명</label>
<input type="text" name="name" class="form-input" placeholder="이름" required>
<input type="text" name="name" class="form-input" placeholder="성명" required>
</div>
<!-- 휴대폰 번호 입력 -->
<div class="form-group">
<label class="form-label">휴대폰 번호</label>
<div class="phone-input-group">
<select class="form-select phone-prefix select_mobile_prefix">
<option>선택</option>
@@ -46,7 +47,6 @@
<!-- 인증번호 입력 -->
<div class="form-group auth-number-container" id="findId-authNumberContainer" style="display: none;">
<label class="form-label">인증번호 입력</label>
<div class="auth-input-group">
<input type="number" class="form-input auth-input auth-number-input" placeholder="SMS 인증번호" required>
<span class="auth-timer" id="findId-certify_time">03:00</span>
@@ -63,41 +63,38 @@
</div>
<!-- 비밀번호 초기화 폼 -->
<div id="tab2" class="account-recovery-form">
<form id="resetPasswordForm" role="form" name="resetPasswordForm" th:action="@{/reset_password}" method="post" data-form-type="resetPassword">
<div id="tab2" class="account-recovery-form" style="display: none;">
<form id="resetPasswordForm" role="form" name="resetPasswordForm" th:action="@{/reset_password}"
method="post" data-form-type="resetPassword">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<input type="hidden" id="resetPassword-phoneNumber" name="phoneNumber">
<!-- 인증 방식 선택 -->
<div class="form-group">
<label class="form-label">초기화 방법</label>
<div style="display: flex; gap: 20px; align-items: center;">
<label style="display: flex; align-items: center; gap: 6px; font-size: 14px; margin: 0;">
<!-- 인증 방식 선택 (pill 버튼 스타일) -->
<div class="form-group reset-method-group">
<div class="reset-method-tabs">
<label class="reset-method-tab">
<input type="radio" id="radio_hp" name="resetMethod" value="hp" checked>
휴대폰 번호
<span>휴대폰 번호</span>
</label>
<label style="display: flex; align-items: center; gap: 6px; font-size: 14px; margin: 0;">
<label class="reset-method-tab">
<input type="radio" id="radio_email" name="resetMethod" value="email_id">
이메일 아이디
<span>이메일 아이디</span>
</label>
</div>
</div>
<!-- 성명 입력 -->
<div class="form-group">
<label class="form-label">성명</label>
<input type="text" name="name" class="form-input" placeholder="성명" required>
</div>
<!-- 아이디 입력 (이메일) -->
<div class="form-group" id="emailInputContainer" style="display: none;">
<label class="form-label">이메일 아이디</label>
<input type="text" name="emailId" class="form-input" placeholder="이메일 아이디">
</div>
<!-- 휴대폰 번호 입력 -->
<div class="form-group" id="phoneInputContainer">
<label class="form-label">휴대폰 번호</label>
<div class="phone-input-group">
<select class="form-select phone-prefix select_mobile_prefix">
<option>선택</option>
@@ -117,8 +114,7 @@
<!-- 인증번호 입력 -->
<div class="form-group auth-number-container" id="authNumberContainer" style="display: none;">
<label class="form-label">인증번호 입력</label>
<div class="auth-input-group">
<div class="auth-input-group mg-y">
<input type="number" class="form-input auth-input auth-number-input" placeholder="SMS 인증번호" required>
<span class="auth-timer" id="certify_time">03:00</span>
<button type="button" class="auth-verify-button btn_verify_auth">확인</button>
@@ -132,6 +128,7 @@
</div>
</form>
</div>
</div>
</div>
</div>
@@ -216,4 +213,5 @@
});
</script>
</th:block>
</html>
@@ -1,6 +1,7 @@
<!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/djbank_title_layout}">
<body>
<section layout:fragment="title">
<div class="page-title-banner">
@@ -22,13 +23,15 @@
<div id="alertContainer"></div>
<!-- Account Recovery Form -->
<form id="accountForm" role="form" name="accountForm" th:action="@{/find_id}" method="post" class="account-recovery-form">
<form id="accountForm" role="form" name="accountForm" th:action="@{/find_id}" method="post"
class="account-recovery-form">
<input type="hidden" id="mobileNumber" name="mobileNumber" th:value="${mobileNumber}">
<!-- Name Field -->
<div class="form-group">
<label for="userName" class="form-label">성명<span class="required-badge">필수</span></label>
<input type="text" id="userName" name="userName" th:value="${userName}" class="form-input" placeholder="성명" required>
<input type="text" id="userName" name="userName" th:value="${userName}" class="form-input"
placeholder="성명" required>
</div>
<!-- Phone Number Fields -->
@@ -45,27 +48,13 @@
<option value="018">018</option>
</select>
<span class="separator">-</span>
<input type="tel"
id="phoneMiddle"
name="phoneMiddle"
maxlength="4"
class="form-input phone-number"
placeholder="1234"
pattern="[0-9]*"
inputmode="numeric"
required>
<input type="tel" id="phoneMiddle" name="phoneMiddle" maxlength="4" class="form-input phone-number"
placeholder="1234" pattern="[0-9]*" inputmode="numeric" required>
<span class="separator">-</span>
<input type="tel"
id="phoneLast"
name="phoneLast"
maxlength="4"
class="form-input phone-number"
placeholder="1234"
pattern="[0-9]*"
inputmode="numeric"
required>
<input type="tel" id="phoneLast" name="phoneLast" maxlength="4" class="form-input phone-number"
placeholder="1234" pattern="[0-9]*" inputmode="numeric" required>
</div>
<button type="button" class="btn org-btn-check btn_auth" id="requestAuthButton">
<button type="button" class="org-btn-check btn_auth" id="requestAuthButton">
인증번호 받기
</button>
</div>
@@ -74,16 +63,9 @@
<!-- Auth Number Input -->
<div class="form-group auth-number-group" id="authNumberGroup" style="display: none;">
<label for="authNumber" class="form-label">인증번호 입력<span class="required-badge">필수</span></label>
<div class="auth-input-group">
<input type="text"
id="authNumber"
name="authNumber"
maxlength="6"
class="form-input auth-input"
placeholder="인증번호 6자리"
pattern="[0-9]*"
inputmode="numeric"
required>
<div class="auth-input-group mg-y">
<input type="text" id="authNumber" name="authNumber" maxlength="6" class="form-input auth-input"
placeholder="인증번호 6자리" pattern="[0-9]*" inputmode="numeric" required>
<span class="auth-timer" id="authTimer">03:00</span>
</div>
<button type="button" class="auth-verify-button" id="verifyAuthButton">
@@ -343,4 +325,5 @@
});
</script>
</th:block>
</html>
@@ -1,6 +1,7 @@
<!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/djbank_title_layout}">
<body>
<section layout:fragment="title">
<div class="page-title-banner">
@@ -22,32 +23,23 @@
<div id="alertContainer"></div>
<!-- Account Recovery Form -->
<form id="accountForm" role="form" name="accountForm" th:action="@{/reset_password}" method="post" class="account-recovery-form">
<form id="accountForm" role="form" name="accountForm" th:action="@{/reset_password}" method="post"
class="account-recovery-form">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<input type="hidden" id="mobileNumber" name="mobileNumber" th:value="${mobileNumber}">
<!-- Name Field -->
<div class="form-group">
<label for="userName" class="form-label">성명<span class="required-badge">필수</span></label>
<input type="text"
id="userName"
name="userName"
th:value="${userName}"
class="form-input"
placeholder="성명"
required>
<input type="text" id="userName" name="userName" th:value="${userName}" class="form-input"
placeholder="성명" required>
</div>
<!-- Email ID Field -->
<div class="form-group">
<label for="loginId" class="form-label">이메일 아이디<span class="required-badge">필수</span></label>
<input type="email"
id="loginId"
name="loginId"
th:value="${loginId}"
class="form-input"
placeholder="이메일 아이디"
required>
<input type="email" id="loginId" name="loginId" th:value="${loginId}" class="form-input"
placeholder="이메일 아이디" required>
</div>
<!-- Phone Number Fields -->
@@ -64,27 +56,13 @@
<option value="018">018</option>
</select>
<span class="separator">-</span>
<input type="tel"
id="phoneMiddle"
name="phoneMiddle"
maxlength="4"
class="form-input phone-number"
placeholder="1234"
pattern="[0-9]*"
inputmode="numeric"
required>
<input type="tel" id="phoneMiddle" name="phoneMiddle" maxlength="4" class="form-input phone-number"
placeholder="1234" pattern="[0-9]*" inputmode="numeric" required>
<span class="separator">-</span>
<input type="tel"
id="phoneLast"
name="phoneLast"
maxlength="4"
class="form-input phone-number"
placeholder="1234"
pattern="[0-9]*"
inputmode="numeric"
required>
<input type="tel" id="phoneLast" name="phoneLast" maxlength="4" class="form-input phone-number"
placeholder="1234" pattern="[0-9]*" inputmode="numeric" required>
</div>
<button type="button" class="btn org-btn-check btn_auth" id="requestAuthButton">
<button type="button" class="org-btn-check btn_auth" id="requestAuthButton">
인증번호 받기
</button>
</div>
@@ -93,16 +71,9 @@
<!-- Auth Number Input -->
<div class="form-group auth-number-group" id="authNumberGroup" style="display: none;">
<label for="authNumber" class="form-label">인증번호 입력<span class="required-badge">필수</span></label>
<div class="auth-input-group">
<input type="text"
id="authNumber"
name="authNumber"
maxlength="6"
class="form-input auth-input"
placeholder="인증번호 6자리"
pattern="[0-9]*"
inputmode="numeric"
required>
<div class="auth-input-group mg-y">
<input type="text" id="authNumber" name="authNumber" maxlength="6" class="form-input auth-input"
placeholder="인증번호 6자리" pattern="[0-9]*" inputmode="numeric" required>
<span class="auth-timer" id="authTimer">03:00</span>
</div>
<button type="button" class="auth-verify-button" id="verifyAuthButton">
@@ -396,4 +367,5 @@
});
</script>
</th:block>
</html>
@@ -9,7 +9,7 @@
</div>
<div class="form-field-wrapper">
<input type="text" th:value="${loginId}" name="loginId" class="form-input input-readonly"
placeholder="이메일" disabled="disabled">
placeholder="이메일" disabled="disabled" style="background: #ededed !important;">
<input type="hidden" th:value="${loginId}" name="loginId">
</div>
</div>
@@ -19,8 +19,7 @@
<span class="form-label-text">성명</span> <span class="required-badge">필수</span>
</div>
<div class="form-field-wrapper">
<input type="text" th:value="${userName}" id="userName" name="userName" class="form-input"
placeholder="성명">
<input type="text" th:value="${userName}" id="userName" name="userName" class="form-input">
</div>
</div>
<div class="form-row">
@@ -36,13 +35,13 @@
mobileLast=${hasHyphen ? (parts != null and #arrays.length(parts) > 2 ? parts[2] : '') : (len == 11 ? #strings.substring(mobileNumber, 7, 11) : (len == 10 ? #strings.substring(mobileNumber, 6, 10) : ''))}">
<div class="compound-input">
<input type="text" th:value="${mobilePrefix}" name="mobilePrefix" class="form-input input-readonly"
maxlength="3" disabled="disabled">
maxlength="3" disabled="disabled" style="background: #ededed !important;">
<span class="separator">-</span>
<input type="text" th:value="${mobileMiddle}" name="mobileMiddle" class="form-input input-readonly"
maxlength="4" disabled="disabled">
maxlength="4" disabled="disabled" style="background: #ededed !important;">
<span class="separator">-</span>
<input type="text" th:value="${mobileLast}" name="mobileLast" class="form-input input-readonly"
maxlength="4" disabled="disabled">
maxlength="4" disabled="disabled" style="background: #ededed !important;">
</div>
<button type="button" class="btn-input-action btn-change change_mobile_phone"
id="changePhoneBtn">변경</button>
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{layout/djbank_base_layout}">
layout:decorate="~{layout/djbank_title_layout}">
<body>
<section layout:fragment="title">
<div class="page-title-banner">
@@ -10,19 +10,32 @@
</div>
</section>
<section layout:fragment="contentFragment" class="content">
<div class="org-register-page corporate-register">
<div class="org-register-container">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<input type="hidden" name="registrationType" th:value="${registrationType}"/>
<div class="register-card-wrapper">
<!-- Info Notice -->
<div class="org-info-notice">
<div class="notice-icon-wrapper">
<svg class="notice-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
</div>
<p class="notice-text">법인회원 전환 신청 완료 후 서비스 또는 API 이용을 하실 수 있습니다.</p>
</div>
<!-- 약관동의 섹션 -->
<th:block
th:replace="apps/register/userAgreementContent :: agreementContent(${termsOfUse}, ${privacyCollect})"></th:block>
<th:block th:replace="~{apps/register/userAgreementContent :: agreementContent(${termsOfUse}, ${privacyCollect})}"></th:block>
<!-- 법인 기본 정보 폼 -->
<form name="portalOrg" id="businessTransferForm" method="post" th:action="@{/mypage/org-transfer}"
th:object="${portalOrg}" enctype="multipart/form-data">
<div class="org-section-header">
<div class="org-section-header org-section-header--agreement">
<h3>법인 기본 정보</h3>
<span class="required-badge">필수 입력</span>
</div>
@@ -30,16 +43,20 @@
<th:block th:replace="~{apps/register/components/orgBasicInfoForm :: orgInfoForm}"></th:block>
<!-- 법인 관리자 정보 -->
<div class="org-section-header">
<div class="org-section-header org-section-header--agreement" style="margin-top: 48px;">
<h3>법인 관리자 정보</h3>
<span class="required-badge">필수 입력</span>
</div>
<div class="org-info-notice">
<ul>
<li>법인 관리자는 API 신청 및 개발자 초대 등 모든 권한을 보유합니다.</li>
<li>법인회원 전환은 반드시 법인이메일 주소로 입력하시기 바랍니다. 개인이메일로 전환 신청시, 법인 승인이 거절 될 수 있습니다</li>
</ul>
<div class="notice-icon-wrapper">
<svg class="notice-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
</div>
<p class="notice-text">법인 관리자는 API 신청 및 개발자 초대 등 모든 권한을 보유합니다. 법인회원 전환은 반드시 법인이메일 주소로 입력하시기 바랍니다.</p>
</div>
<div class="org-form-container">
@@ -63,6 +80,8 @@
</div>
</form>
</div>
</div>
</div>
</section>
<th:block layout:fragment="contentScript">
<script th:if="${error}" th:inline="javascript">
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/djbank_title_layout}">
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/djbank_title_layout}">
<body>
<section layout:fragment="title">
<div class="page-title-banner">
@@ -9,55 +9,75 @@
</div>
</section>
<section layout:fragment="contentFragment">
<div class="org-register-container">
<div class="service-main container" style="padding-top: 70px; padding-bottom:100px;">
<th:block th:replace="~{fragment/djbank/service_sidebar :: sidebar('profile')}"></th:block>
<div class="app-management-content">
<div class="corp-manager-wrapper">
<!-- 초대 알림 배너 -->
<div th:if="${hasPendingInvitation}" class="invitation_alert_banner" style="background-color: #f0f8ff; border: 1px solid #2196F3; border-radius: 4px; padding: 15px 20px; margin: 20px 0;">
<div th:if="${hasPendingInvitation}" class="invitation_alert_banner"
style="background-color: #f0f8ff; border: 1px solid #2196F3; border-radius: 4px; padding: 15px 20px; margin: 20px 0;">
<div style="display: flex; align-items: center; justify-content: space-between;">
<div>
<strong style="color: #1976D2;">법인 회원 초대가 대기 중입니다</strong>
<p style="margin: 5px 0 0 0; color: #666;">기관에서 귀하를 법인 회원으로 초대했습니다. 초대를 수락하면 해당 기관의 법인 회원으로 전환됩니다.</p>
<p style="margin: 5px 0 0 0; color: #666;">기관에서 귀하를 법인 회원으로 초대했습니다. 초대를 수락하면 해당 기관의 법인
회원으로 전환됩니다.</p>
</div>
<div>
<a th:href="@{/signup/decision(invitation=${invitationToken})}" class="common_btn_type_1 blue" style="white-space: nowrap;">
<a th:href="@{/signup/decision(invitation=${invitationToken})}"
class="common_btn_type_1 blue" style="white-space: nowrap;">
<span>초대 확인</span>
</a>
</div>
</div>
</div>
<h2 class="page-outer-title">정보 관리</h2>
<div class="common-title-bar">
<h2 class="common-title">기본 정보</h2>
</div>
<div class="register-form-container">
<form id="updateForm" method="post" th:action="@{/mypage/update}" th:object="${user}">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<div class="register-form-container">
<!-- Section Title -->
<div class="inner-section-title">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="#000"
stroke-width="2">
<rect x="3" y="3" width="7" height="7"></rect>
<rect x="14" y="3" width="7" height="7"></rect>
<rect x="14" y="14" width="7" height="7"></rect>
<rect x="3" y="14" width="7" height="7"></rect>
</svg>
<h3>기본 정보</h3>
</div>
<div class="register-form">
<th:block th:replace="~{apps/mypage/components/commonUserInfo :: commonUserInfo}"></th:block>
<th:block th:replace="~{apps/mypage/components/commonUserInfo :: commonUserInfo}">
</th:block>
</div>
<!-- Corporate Transfer Button -->
<div class="corporate-transfer-section">
<button type="button" class="btn btn-secondary btn_business btn-block">
<div class="corporate-transfer-section" style="margin-top: 24px;">
<button type="button" class="btn btn_business"
style="background: #FFFFFF; border: 1.5px solid #2a69de; color: #2a69de; font-weight: 700; border-radius: 12px; padding: 12px 24px; font-size: 15px; cursor: pointer; transition: all 0.2s ease; display: inline-flex; align-items: center; justify-content: center; width: 100%; box-shadow: none;">
법인회원 전환
</button>
</div>
</form>
</div>
</form>
<input type="hidden" name="finalMobileNumber" />
<!-- Action Buttons -->
<div class="form-actions form-actions--with-withdrawal">
<a class="withdrawal-link"><img th:src="@{/img/btn_withdrawal.png}" alt="회원탈퇴">회원탈퇴</a>
<div class="form-actions-buttons">
<button type="button" class="btn btn-submit btn-secondary" th:onclick="|location.href='@{/}'|">취소</button>
<button type="button" class="btn btn-submit btn-primary submit-btn">수정</button>
</div>
</div>
<div class="form-actions">
<a class="withdrawal-link btn-withdrawal">회원탈퇴</a>
<div class="right-buttons">
<button type="button" class="btn-cancel" th:onclick="|location.href='@{/}'|">취소</button>
<button type="button" class="btn-apply btn-primary submit-btn">수정</button>
</div>
</div>
</div>
</div>
</div>
</section>
<th:block layout:fragment="contentScript">
<script th:if="${error}" th:inline="javascript">
@@ -196,4 +216,5 @@
<th:block th:replace="~{fragment/popup/withdrawalPopup :: withdrawalPopup}"></th:block>
</section>
</body>
</html>
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/djbank_title_layout}">
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout/djbank_title_layout}">
<body>
<section layout:fragment="title">
<div class="page-title-banner">
@@ -9,61 +9,63 @@
</div>
</section>
<section layout:fragment="contentFragment">
<div class="org-register-container">
<div class="service-main">
<div class="app-management-content">
<div class="password-change-wrapper">
<h2 class="page-outer-title">이메일 인증</h2>
<div class="common-title-bar">
<h2 class="common-title">이메일 인증</h2>
</div>
<div class="register-form-container">
<form id="verificationEmailForm" role="form" name="verificationEmailForm" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<input type="hidden" id="userId" name="userId" th:value="${userId}">
<div class="register-form">
<!-- 이메일 주소 + 인증코드 받기 버튼 (한 줄) -->
<div class="form-row" style="margin-bottom: 0">
<div class="form-label-wrapper label-offset">
<div class="register-form-container">
<!-- 안내 Notice Box -->
<div class="info-notice-box" style="margin-bottom: 24px;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4685ef" stroke-width="2">
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 16v-4"></path>
<path d="M12 8h.01"></path>
</svg>
<p>본인 확인을 위해 이메일 인증을 진행해 주세요. 아래 이메일 주소로 인증코드가 발송됩니다.</p>
</div>
<!-- 이메일 주소 행 -->
<div class="form-row">
<div class="form-label-wrapper">
<span class="form-label-text">이메일 주소</span>
</div>
<div class="form-field-wrapper input-with-button">
<input type="email" id="email" name="email" class="form-input input-readonly"
th:value="${email}" readonly disabled="disabled">
<input type="email" id="email" name="email" class="form-input input-readonly" th:value="${email}"
readonly disabled="disabled" style="flex: 1;">
<button type="button" class="btn-input-action btn-auth btn_send_code">인증코드 받기</button>
</div>
</div>
<div class="form-row" style="margin-bottom: 0">
<div class="form-label-wrapper label-offset">
<span class="form-label-text">&nbsp;</span>
</div>
<div class="form-field-wrapper">
<p class="form-hint" style="margin-top: 0;">위 이메일 주소로 인증코드가 발송됩니다.</p>
</div>
</div>
<!-- 인증번호 입력 -->
<!-- 인증번호 입력 행 (초기 숨김) -->
<div class="form-row" id="authCodeContainer" style="display: none;">
<div class="form-label-wrapper label-offset">
<span class="form-label-text">인증코드 입력</span> <span class="required-badge">필수</span>
<div class="form-label-wrapper">
<span class="form-label-text">인증코드 입력</span>
</div>
<div class="form-field-wrapper input-with-button">
<div class="auth-input-group">
<input type="text" id="authCode" name="authCode" maxlength="6" pattern="[0-9]*"
inputmode="numeric" class="form-input"
placeholder="이메일로 받은 인증코드 6자리">
<span class="auth-timer" id="certify_time">05:00</span>
<div class="auth-input-group" style="flex: 1; position: relative;">
<input type="text" id="authCode" name="authCode" maxlength="6" pattern="[0-9]*" inputmode="numeric"
class="form-input" placeholder="이메일로 받은 인증코드 6자리" style="width: 100%; padding-right: 70px;">
<span class="auth-timer" id="certify_time"
style="position: absolute; right: 16px; top: 50%; transform: translateY(-50%); font-weight: 500; font-size: 13px;">05:00</span>
</div>
<button type="button" class="btn-input-action btn-auth btn_verify_code">인증코드 확인</button>
</div>
</div>
</div>
</form>
</div>
<!-- Action Buttons -->
<div class="form-actions">
<button type="button" class="btn-submit btn-secondary">취소</button>
<div class="form-actions" style="justify-content: flex-end; margin-top: 24px;">
<div class="right-buttons">
<button type="button" class="btn-cancel btn_cancel">취소</button>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
@@ -268,4 +270,5 @@
});
</script>
</th:block>
</html>
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/djbank_title_layout}">
<body>
<section layout:fragment="title">
<div class="page-title-banner">
@@ -10,63 +10,62 @@
</div>
</section>
<section layout:fragment="contentFragment">
<div class="org-register-container">
<div class="service-main">
<div class="app-management-content">
<div class="password-change-wrapper">
<h2 class="page-outer-title">이메일 인증</h2>
<div class="common-title-bar">
<h2 class="common-title">이메일 인증</h2>
</div>
<div class="register-form-container">
<p class="form-hint" style="margin-bottom: 16px;">
회원가입을 완료하려면 가입하신 이메일 주소로 인증을 진행해 주세요.
</p>
<form id="signupVerificationEmailForm" role="form" name="signupVerificationEmailForm" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<div class="register-form">
<!-- 이메일 주소 + 인증코드 받기 버튼 (한 줄) -->
<div class="form-row" style="margin-bottom: 0">
<div class="form-label-wrapper label-offset">
<div class="register-form-container">
<!-- 안내 Notice Box -->
<div class="info-notice-box" style="margin-bottom: 24px;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4685ef" stroke-width="2">
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 16v-4"></path>
<path d="M12 8h.01"></path>
</svg>
<p>회원가입을 완료하려면 가입하신 이메일 주소로 인증을 진행해 주세요.</p>
</div>
<!-- 이메일 주소 행 -->
<div class="form-row">
<div class="form-label-wrapper">
<span class="form-label-text">이메일 주소</span>
</div>
<div class="form-field-wrapper input-with-button">
<input type="email" id="email" name="email" class="form-input input-readonly"
th:value="${email}" readonly disabled="disabled">
<input type="email" id="email" name="email" class="form-input input-readonly" th:value="${email}"
readonly disabled="disabled" style="flex: 1;">
<button type="button" class="btn-input-action btn-auth btn_send_code">인증코드 받기</button>
</div>
</div>
<div class="form-row" style="margin-bottom: 0">
<div class="form-label-wrapper label-offset">
<span class="form-label-text">&nbsp;</span>
</div>
<div class="form-field-wrapper">
<p class="form-hint" style="margin-top: 0;">위 이메일 주소로 인증코드가 발송됩니다.</p>
</div>
</div>
<!-- 인증번호 입력 -->
<!-- 인증번호 입력 행 (초기 숨김) -->
<div class="form-row" id="authCodeContainer" style="display: none;">
<div class="form-label-wrapper label-offset">
<span class="form-label-text">인증코드 입력</span> <span class="required-badge">필수</span>
<div class="form-label-wrapper">
<span class="form-label-text">인증코드 입력</span>
</div>
<div class="form-field-wrapper input-with-button">
<div class="auth-input-group">
<input type="text" id="authCode" name="authCode" maxlength="6" pattern="[0-9]*"
inputmode="numeric" class="form-input"
placeholder="이메일로 받은 인증코드 6자리">
<span class="auth-timer" id="certify_time">05:00</span>
<div class="auth-input-group" style="flex: 1; position: relative;">
<input type="text" id="authCode" name="authCode" maxlength="6" pattern="[0-9]*" inputmode="numeric"
class="form-input" placeholder="이메일로 받은 인증코드 6자리" style="width: 100%; padding-right: 70px;">
<span class="auth-timer" id="certify_time"
style="position: absolute; right: 16px; top: 50%; transform: translateY(-50%); font-weight: 500; font-size: 13px;">05:00</span>
</div>
<button type="button" class="btn-input-action btn-auth btn_verify_code">인증코드 확인</button>
</div>
</div>
</div>
</form>
</div>
<!-- Action Buttons -->
<div class="form-actions">
<button type="button" class="btn-submit btn-secondary btn_cancel">나중에 인증</button>
<div class="form-actions" style="justify-content: flex-end; margin-top: 24px;">
<div class="right-buttons">
<button type="button" class="btn-cancel btn_cancel">나중에 인증</button>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
@@ -274,4 +273,5 @@
});
</script>
</th:block>
</html>
@@ -57,7 +57,8 @@
<a th:href="@{/myapikey}"
th:classappend="${activeMenu == 'apiKey'} ? 'service-nav__item--active' : ''"
class="service-nav__item">앱 관리</a>
class="service-nav__item"
sec:authorize="hasRole('ROLE_APP')">앱 관리</a>
<a th:href="@{/webhook}"
th:classappend="${activeMenu == 'webhook'} ? 'service-nav__item--active' : ''"