260705_1
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
/* =============================================================================
|
||||
* B01_AccountDetail_UI_Page.ts
|
||||
* 로그인 후 01: 계정 상세 (기본 정보 수정 + 비밀번호 변경)
|
||||
*
|
||||
* 제약 준수 (frontend.md):
|
||||
* - 모든 문구는 ui_template_locale.ts 참조 (하드코딩 금지, §3).
|
||||
* - 색상/간격은 theme.css 변수 + 공통 컴포넌트만 사용 (§1, §2).
|
||||
* - 이벤트 핸들러는 onB01_[기능]_[액션] 명명 (§4).
|
||||
* - 백엔드 전송 전 1차 유효성 검사 (§4).
|
||||
* ========================================================================== */
|
||||
|
||||
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
|
||||
import { createButton, createInputField, createCard, showToast } from "@ui/ui_template_elements";
|
||||
import { isBlank } from "@util/common_util_validate";
|
||||
import "./B01_AccountDetail_UI_Style.css";
|
||||
|
||||
/** locale 헬퍼 */
|
||||
function L(key: keyof typeof ui_locales): string {
|
||||
return ui_locales[key][currentLanguageIndex];
|
||||
}
|
||||
|
||||
/** 비밀번호 최소 길이 (A07 회원가입과 동일 기준) */
|
||||
const PASSWORD_MIN_LENGTH = 8;
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* 페이지 진입점
|
||||
* -------------------------------------------------------------------------- */
|
||||
export function renderB01AccountDetail(root: HTMLElement): void {
|
||||
const page = document.createElement("div");
|
||||
page.className = "b01-account";
|
||||
|
||||
const header = document.createElement("div");
|
||||
header.className = "b01-account__header";
|
||||
const title = document.createElement("h1");
|
||||
title.className = "b01-account__title";
|
||||
title.textContent = L("B01_Account_Title");
|
||||
const subtitle = document.createElement("p");
|
||||
subtitle.className = "b01-account__subtitle";
|
||||
subtitle.textContent = L("B01_Account_Subtitle");
|
||||
header.append(title, subtitle);
|
||||
|
||||
page.append(header, buildProfileCard(), buildSecurityCard());
|
||||
root.append(page);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* 기본 정보 카드 (회사/이름/이메일/연락처)
|
||||
* -------------------------------------------------------------------------- */
|
||||
function buildProfileCard(): HTMLDivElement {
|
||||
// 회사명·이메일은 읽기 전용(가입 시 확정), 이름·연락처만 수정 가능
|
||||
const companyField = createInputField({
|
||||
label: L("B01_Account_Field_Company"),
|
||||
value: "",
|
||||
});
|
||||
companyField.input.readOnly = true;
|
||||
companyField.input.classList.add("b01-account__readonly");
|
||||
|
||||
const emailField = createInputField({
|
||||
label: L("B01_Account_Field_Email"),
|
||||
type: "email",
|
||||
value: "",
|
||||
});
|
||||
emailField.input.readOnly = true;
|
||||
emailField.input.classList.add("b01-account__readonly");
|
||||
|
||||
const nameField = createInputField({
|
||||
label: L("B01_Account_Field_Name"),
|
||||
required: true,
|
||||
});
|
||||
const phoneField = createInputField({
|
||||
label: L("B01_Account_Field_Phone"),
|
||||
placeholder: L("B01_Account_Field_Phone_Placeholder"),
|
||||
type: "text",
|
||||
});
|
||||
|
||||
const saveBtn = createButton({
|
||||
label: L("B01_Account_Save_Profile"),
|
||||
variant: "filled",
|
||||
onClick: onB01_Profile_Save_Click,
|
||||
});
|
||||
saveBtn.classList.add("b01-account__submit");
|
||||
|
||||
function onB01_Profile_Save_Click(): void {
|
||||
nameField.setError();
|
||||
if (isBlank(nameField.input.value)) {
|
||||
nameField.setError(L("B01_Account_Error_Required"));
|
||||
return;
|
||||
}
|
||||
// TODO: PATCH /api/b01/profile 연동 (로딩 오버레이 + 성공/실패 처리)
|
||||
showToast(L("B01_Account_Success_Profile"), "success");
|
||||
}
|
||||
|
||||
const grid = document.createElement("div");
|
||||
grid.className = "b01-account__grid";
|
||||
grid.append(companyField.root, emailField.root, nameField.root, phoneField.root);
|
||||
|
||||
return createCard({
|
||||
title: L("B01_Account_Section_Profile"),
|
||||
body: [grid, saveBtn],
|
||||
raised: true,
|
||||
});
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* 보안 카드 (비밀번호 변경)
|
||||
* -------------------------------------------------------------------------- */
|
||||
function buildSecurityCard(): HTMLDivElement {
|
||||
const currentPwField = createInputField({
|
||||
label: L("B01_Account_Field_CurrentPw"),
|
||||
type: "password",
|
||||
required: true,
|
||||
});
|
||||
const newPwField = createInputField({
|
||||
label: L("B01_Account_Field_NewPw"),
|
||||
type: "password",
|
||||
required: true,
|
||||
});
|
||||
const confirmPwField = createInputField({
|
||||
label: L("B01_Account_Field_ConfirmPw"),
|
||||
type: "password",
|
||||
required: true,
|
||||
});
|
||||
|
||||
const saveBtn = createButton({
|
||||
label: L("B01_Account_Save_Password"),
|
||||
variant: "ghost",
|
||||
onClick: onB01_Password_Save_Click,
|
||||
});
|
||||
saveBtn.classList.add("b01-account__submit");
|
||||
|
||||
function onB01_Password_Save_Click(): void {
|
||||
currentPwField.setError();
|
||||
newPwField.setError();
|
||||
confirmPwField.setError();
|
||||
|
||||
const current = currentPwField.input.value;
|
||||
const next = newPwField.input.value;
|
||||
const confirm = confirmPwField.input.value;
|
||||
|
||||
// 1차 유효성: 빈 값 검사
|
||||
let hasError = false;
|
||||
if (isBlank(current)) {
|
||||
currentPwField.setError(L("B01_Account_Error_Required"));
|
||||
hasError = true;
|
||||
}
|
||||
if (isBlank(next)) {
|
||||
newPwField.setError(L("B01_Account_Error_Required"));
|
||||
hasError = true;
|
||||
}
|
||||
if (isBlank(confirm)) {
|
||||
confirmPwField.setError(L("B01_Account_Error_Required"));
|
||||
hasError = true;
|
||||
}
|
||||
if (hasError) return;
|
||||
|
||||
// 길이 검사
|
||||
if (next.length < PASSWORD_MIN_LENGTH) {
|
||||
newPwField.setError(L("B01_Account_Error_PwLength"));
|
||||
return;
|
||||
}
|
||||
// 일치 검사
|
||||
if (next !== confirm) {
|
||||
confirmPwField.setError(L("B01_Account_Error_PwMismatch"));
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: PATCH /api/b01/password 연동 (로딩 오버레이 + 성공/실패 처리)
|
||||
currentPwField.input.value = "";
|
||||
newPwField.input.value = "";
|
||||
confirmPwField.input.value = "";
|
||||
showToast(L("B01_Account_Success_Password"), "success");
|
||||
}
|
||||
|
||||
const grid = document.createElement("div");
|
||||
grid.className = "b01-account__grid";
|
||||
grid.append(currentPwField.root, newPwField.root, confirmPwField.root);
|
||||
|
||||
return createCard({
|
||||
title: L("B01_Account_Section_Security"),
|
||||
body: [grid, saveBtn],
|
||||
raised: true,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user