feat: add common utilities and feedback handling scripts
- Introduced common.js for shared functions including API calls, error reporting, and UI helpers. - Implemented feedback.js for the feedback reporting page, including form handling and displaying feedback status. - Added layout.js for managing galaxy and section layouts in the visualization. - Created login.js for user authentication with session management. - Developed search.js for term searching based on user input and synonyms. - Implemented signup.js for user registration with validation and immediate login.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
// 회원 가입: 수업에서 받은 가입 코드가 있어야 함. 가입하면 바로 이용.
|
||||
import { api, toast } from "./common.js";
|
||||
|
||||
const main = document.getElementById("main");
|
||||
const next = new URLSearchParams(location.search).get("next") || "";
|
||||
const safe = (u) => (u && u.startsWith("/") && !u.startsWith("//") ? u : "");
|
||||
|
||||
main.innerHTML = `<h1>회원 가입</h1>
|
||||
<p class="acc-note">수업에서 교수자에게 받은 <b>가입 코드</b>가 있어야 가입할 수 있습니다. 가입하면 바로 사례와 문제를 볼 수 있어요.</p>
|
||||
<form class="card" id="f">
|
||||
<label class="field"><span>가입 코드</span><input class="input" name="code" required maxlength="40" autocomplete="off" placeholder="예: K7P-2QX" style="text-transform:uppercase"></label>
|
||||
<label class="field"><span>아이디 (영문·숫자 3~30자)</span><input class="input" name="username" autocomplete="username" required minlength="3" maxlength="30" pattern="[A-Za-z0-9_.\\-]{3,30}"></label>
|
||||
<label class="field"><span>비밀번호 (6자 이상)</span><input class="input" name="password" type="password" autocomplete="new-password" required minlength="6"></label>
|
||||
<label class="field"><span>비밀번호 확인</span><input class="input" name="password2" type="password" autocomplete="new-password" required minlength="6"></label>
|
||||
<label class="field"><span>이름</span><input class="input" name="name" required maxlength="40"></label>
|
||||
<label class="field"><span>학번 (선택)</span><input class="input" name="student_no" maxlength="30"></label>
|
||||
<input class="hp" name="website" tabindex="-1" autocomplete="off" aria-hidden="true">
|
||||
<button class="btn primary" type="submit">가입하기</button>
|
||||
</form>
|
||||
<p class="auth-alt">이미 회원인가요? <a href="/login${next ? "?next=" + encodeURIComponent(next) : ""}">로그인</a></p>`;
|
||||
|
||||
document.getElementById("f").addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
const v = Object.fromEntries(new FormData(e.target).entries());
|
||||
if (v.password !== v.password2) return toast("비밀번호 확인이 일치하지 않습니다.", true);
|
||||
delete v.password2;
|
||||
const btn = e.target.querySelector("button");
|
||||
btn.disabled = true;
|
||||
try {
|
||||
await api("/api/members/signup", { method: "POST", body: v });
|
||||
await api("/api/members/login", { method: "POST", body: { username: v.username, password: v.password } });
|
||||
toast("가입했습니다!");
|
||||
location.href = safe(next) || "/";
|
||||
} catch (err) {
|
||||
toast(err.message, true);
|
||||
btn.disabled = false;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user