142 lines
4.7 KiB
TypeScript
142 lines
4.7 KiB
TypeScript
/* =============================================================================
|
|
* A07_Register_UI_Page.ts
|
|
* 로그인 전 07: 회원가입 (회사명 + 이름 + 이메일 + 비밀번호 폼)
|
|
*
|
|
* 제약 준수:
|
|
* - 모든 문구는 ui_template_locale.ts 참조 (하드코딩 금지).
|
|
* - 색상/간격은 A07_Register_UI_Style.css + theme.css 변수만 사용.
|
|
* - 공통 컴포넌트(createButton/createInputField) 우선 사용.
|
|
* - 이벤트 핸들러는 on[페이지]_[기능]_[액션] 명명.
|
|
* - 백엔드 전송 전 1차 유효성 검사 (frontend.md §4).
|
|
* ========================================================================== */
|
|
|
|
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
|
|
import { createButton, createInputField } from "@ui/ui_template_elements";
|
|
import { isBlank, isValidEmail, hasMinLength } from "@util/common_util_validate";
|
|
import { navigateTo } from "../A00_Common/router";
|
|
import { ROUTES } from "@config/config_frontend";
|
|
import "./A07_Register_UI_Style.css";
|
|
|
|
/** locale 헬퍼 */
|
|
function L(key: keyof typeof ui_locales): string {
|
|
return ui_locales[key][currentLanguageIndex];
|
|
}
|
|
|
|
/** 비밀번호 최소 길이 */
|
|
const PASSWORD_MIN_LENGTH = 8;
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* 페이지 진입점
|
|
* -------------------------------------------------------------------------- */
|
|
export function renderA07Register(root: HTMLElement): void {
|
|
const page = document.createElement("div");
|
|
page.className = "a07-register";
|
|
|
|
const card = document.createElement("div");
|
|
card.className = "a07-register__card";
|
|
|
|
const title = document.createElement("h1");
|
|
title.className = "a07-register__title";
|
|
title.textContent = L("A07_Register_Title");
|
|
|
|
const subtitle = document.createElement("p");
|
|
subtitle.className = "a07-register__subtitle";
|
|
subtitle.textContent = L("A07_Register_Subtitle");
|
|
|
|
// 입력 필드
|
|
const companyField = createInputField({
|
|
label: L("A07_Register_Field_Company"),
|
|
placeholder: L("A07_Register_Field_Company_Placeholder"),
|
|
type: "text",
|
|
required: true,
|
|
});
|
|
const nameField = createInputField({
|
|
label: L("A07_Register_Field_Name"),
|
|
placeholder: L("A07_Register_Field_Name_Placeholder"),
|
|
type: "text",
|
|
required: true,
|
|
});
|
|
const emailField = createInputField({
|
|
label: L("A07_Register_Field_Email"),
|
|
placeholder: L("A07_Register_Field_Email_Placeholder"),
|
|
type: "email",
|
|
required: true,
|
|
});
|
|
const passwordField = createInputField({
|
|
label: L("A07_Register_Field_Password"),
|
|
placeholder: L("A07_Register_Field_Password_Placeholder"),
|
|
type: "password",
|
|
required: true,
|
|
});
|
|
|
|
const form = document.createElement("form");
|
|
form.className = "a07-register__form";
|
|
form.noValidate = true;
|
|
|
|
const submitBtn = createButton({
|
|
label: L("A07_Register_Submit"),
|
|
variant: "filled",
|
|
type: "submit",
|
|
});
|
|
submitBtn.classList.add("a07-register__submit");
|
|
|
|
/* 이벤트 핸들러: 제출 시 1차 유효성 검사 */
|
|
function onA07_Register_Submit_Click(event: Event): void {
|
|
event.preventDefault();
|
|
[companyField, nameField, emailField, passwordField].forEach((f) => f.setError());
|
|
|
|
const company = companyField.input.value;
|
|
const name = nameField.input.value;
|
|
const email = emailField.input.value;
|
|
const password = passwordField.input.value;
|
|
|
|
// 필수값 검사
|
|
let hasError = false;
|
|
if (isBlank(company)) {
|
|
companyField.setError(L("A07_Register_Error_Required"));
|
|
hasError = true;
|
|
}
|
|
if (isBlank(name)) {
|
|
nameField.setError(L("A07_Register_Error_Required"));
|
|
hasError = true;
|
|
}
|
|
if (isBlank(email)) {
|
|
emailField.setError(L("A07_Register_Error_Required"));
|
|
hasError = true;
|
|
}
|
|
if (isBlank(password)) {
|
|
passwordField.setError(L("A07_Register_Error_Required"));
|
|
hasError = true;
|
|
}
|
|
if (hasError) return;
|
|
|
|
// 형식 검사
|
|
if (!isValidEmail(email)) {
|
|
emailField.setError(L("A07_Register_Error_Email"));
|
|
return;
|
|
}
|
|
if (!hasMinLength(password, PASSWORD_MIN_LENGTH)) {
|
|
passwordField.setError(L("A07_Register_Error_Password"));
|
|
return;
|
|
}
|
|
|
|
// TODO: POST /api/a07/register 연동. 성공 시 로그인 페이지로.
|
|
navigateTo(ROUTES.A06_LOGIN);
|
|
}
|
|
|
|
form.addEventListener("submit", onA07_Register_Submit_Click);
|
|
form.append(companyField.root, nameField.root, emailField.root, passwordField.root, submitBtn);
|
|
|
|
// 로그인 링크
|
|
const toLogin = createButton({
|
|
label: L("A07_Register_ToLogin"),
|
|
variant: "ghost",
|
|
onClick: () => navigateTo(ROUTES.A06_LOGIN),
|
|
});
|
|
toLogin.classList.add("a07-register__link");
|
|
|
|
card.append(title, subtitle, form, toLogin);
|
|
page.append(card);
|
|
root.append(page);
|
|
}
|