feat(redesign): 모집 작성 필수표시/글자수/sticky 미리보기

recruit-form.jsp에 .req 필수표시(4곳), summary 글자수 카운터
(.count/#sc, 독립 oninput), .preview-card sticky 외형 추가.
제출은 기존 AJAX(fetch /recruit/new)+BibimbapCsrf.headers·필드명
10종(projectName 등) 보존, render() 미리보기 IIFE 무손실.
디자인 name=title·/recruit·CSRF누락 form 미채택.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
이정수 2026-06-30 16:26:59 +09:00
parent e998847139
commit 239d33c218
1 changed files with 25 additions and 6 deletions

View File

@ -172,6 +172,22 @@
background: var(--accent); background: var(--accent);
color: #1a1a1a; color: #1a1a1a;
} }
.req {
color: var(--accent);
font-weight: 900;
margin-left: 0.15em;
}
.field-head {
display: flex;
justify-content: space-between;
align-items: baseline;
}
.count {
font-size: 0.75rem;
color: var(--text-muted);
font-weight: 400;
white-space: nowrap;
}
.preview-card { .preview-card {
position: sticky; position: sticky;
top: 5rem; top: 5rem;
@ -256,7 +272,7 @@
<form id="recruit-form" action="<%= ctx %>/recruit/new" method="post" novalidate> <form id="recruit-form" action="<%= ctx %>/recruit/new" method="post" novalidate>
<div class="form-grid"> <div class="form-grid">
<div class="field"> <div class="field">
<label for="project-name">프로젝트명</label> <label for="project-name">프로젝트명 <span class="req">*</span></label>
<input id="project-name" name="projectName" type="text" maxlength="80" placeholder="예: 달빛 정거장" required> <input id="project-name" name="projectName" type="text" maxlength="80" placeholder="예: 달빛 정거장" required>
</div> </div>
<div class="field"> <div class="field">
@ -264,11 +280,14 @@
<input id="genre" name="genre" type="text" maxlength="60" placeholder="예: 2D 어드벤처"> <input id="genre" name="genre" type="text" maxlength="60" placeholder="예: 2D 어드벤처">
</div> </div>
<div class="field field--full"> <div class="field field--full">
<label for="summary">한 줄 소개</label> <div class="field-head">
<input id="summary" name="summary" type="text" maxlength="120" placeholder="프로젝트를 한 문장으로 소개해 주세요." required> <label for="summary">한 줄 소개 <span class="req">*</span></label><span class="count"><span id="sc">0</span> / 120</span>
</div>
<input id="summary" name="summary" type="text" maxlength="120" placeholder="프로젝트를 한 문장으로 소개해 주세요." required
oninput="document.getElementById('sc').textContent=this.value.length">
</div> </div>
<div class="field"> <div class="field">
<label for="role">모집 역할</label> <label for="role">모집 역할 <span class="req">*</span></label>
<select id="role" name="role"> <select id="role" name="role">
<option selected>기획</option> <option selected>기획</option>
<option>아트</option> <option>아트</option>
@ -302,7 +321,7 @@
<input id="team" name="team" type="text" maxlength="80" placeholder="예: 기획 1명, 프로그래머 1명"> <input id="team" name="team" type="text" maxlength="80" placeholder="예: 기획 1명, 프로그래머 1명">
</div> </div>
<div class="field"> <div class="field">
<label for="contact">연락 방법</label> <label for="contact">연락 방법 <span class="req">*</span></label>
<input id="contact" name="contact" type="text" maxlength="100" placeholder="이메일, 디스코드, 오픈채팅 등" required> <input id="contact" name="contact" type="text" maxlength="100" placeholder="이메일, 디스코드, 오픈채팅 등" required>
</div> </div>
<div class="field field--full"> <div class="field field--full">
@ -312,7 +331,7 @@
</div> </div>
<div class="form-actions"> <div class="form-actions">
<a class="form-button" href="<%= ctx %>/recruit">취소</a> <a class="form-button" href="<%= ctx %>/recruit">취소</a>
<button class="form-button form-button--primary" type="submit">미리보기 완료</button> <button class="form-button form-button--primary" type="submit">모집글 등록</button>
</div> </div>
</form> </form>
</section> </section>