Skip to content

[JDDEV-65] [JDDEV-66] Feat: 자소서 작성 페이지 UI 구현#57

Merged
yiyoonseo merged 10 commits into
developfrom
feature/JDDEV-66-cl_write-ui-feat
May 21, 2026
Merged

[JDDEV-65] [JDDEV-66] Feat: 자소서 작성 페이지 UI 구현#57
yiyoonseo merged 10 commits into
developfrom
feature/JDDEV-66-cl_write-ui-feat

Conversation

@yiyoonseo
Copy link
Copy Markdown
Contributor

@yiyoonseo yiyoonseo commented May 21, 2026

🔗 관련 이슈

  • Close #

📝 개요

⌨️ 작업 상세 내용

1. 자소서 입력 화면 (/apply/virtual/[id]/write)

  • InputSection 컴포넌트 신규 구현
    • 문항 선택 페이지에서 넘어온 질문 목록을 sessionStorage에서 읽어 동적으로 표시
    • Q1~Qn 칩 클릭 시 해당 질문으로 전환, 질문별 텍스트 독립 관리
    • 완성 뱃지 로직: 글자수 ≥ 50% & ≤ 최대글자수 시 ChipQnumberCompleteBadge 활성화
  • 페이지 구조를 min-h-screen flex flex-col 래퍼로 변경하여 Footer를 페이지 내부에 위치

2. 문항 선택 → 자소서 입력 연동 (/apply/virtual/[id]/questions)

  • SelectQuestion 컴포넌트에 onQuestionsChange 콜백 추가
    • 선택된 질문 전체 데이터(id, question, maxLength)를 상위로 전달
  • 확정하기 클릭 시 선택 질문을 sessionStorage("selectedQuestions")에 저장 후 write 페이지로 이동

3. 공고 입력 흐름 리팩토링 (/apply/virtual/[id]/(jd)/)

  • mock-application 라우트 삭제 → apply/virtual/[id]/(jd)/ 하위로 이동
  • jd-input
    • Footer를 JdInputPageClientpage.tsx로 분리
    • selectedMethod 상태를 page.tsx로 lift up
    • useImperativeHandlehandleCtaClick 노출
    • id는 prop 대신 useParams() 직접 사용
  • jd-review
    • Footer + 모달 상태를 JdReviewPageClientpage.tsx로 분리
    • JdReviewPageClient는 콘텐츠(Header + JdReviewMain)만 담당
    • page.tsx에서 useParams(), useSearchParams()로 id/mode 처리

4. 헤더 현재 스텝 표시 개선

  • 현재 스텝 번호 뱃지만 흰색 배경으로 구분
    • 현재 스텝: bg-white
    • 지나온 스텝: bg-fill-quaternary-default
    • 미완료 스텝: bg-fill-disabled

5. 모의 지원 메인 페이지 연결

  • MockApplicationHomePageClient/apply 메인 페이지에 적용
  • "모의 지원하기" 버튼 경로 /apply-type/apply/virtual 수정

6. 폴더 구조 정리

  • apply-type 페이지를 apply/ 하위로 이동
  • mock-application 라우트 전체 삭제

변경 파일 목록

파일 변경 내용
apply/page.tsx MockApplicationHomePageClient 연결
apply/virtual/[id]/(jd)/jd-input/page.tsx 신규 - Footer, selectedMethod 관리
apply/virtual/[id]/(jd)/jd-input/JdInputPageClient.tsx Footer 분리, useImperativeHandle 적용
apply/virtual/[id]/(jd)/jd-review/page.tsx 신규 - Footer, 모달 상태 관리
apply/virtual/[id]/(jd)/jd-review/JdReviewPageClient.tsx Footer/모달 분리, id prop 제거
apply/virtual/[id]/questions/page.tsx sessionStorage 저장, onQuestionsChange 연동
apply/virtual/[id]/write/page.tsx 페이지 래퍼 구조 변경
apply/virtual/[id]/result/page.tsx 페이지 래퍼 구조 변경
components/apply/InputSection.tsx 신규 구현 - 질문 동적 렌더링, complete badge 로직
components/apply/SelectQuestion.tsx onQuestionsChange 콜백 추가
components/common/chips/ChipQnumber.tsx 외부 controlled 방식으로 변경
components/common/header/Header.tsx 현재 스텝 흰색 뱃지 UI 추가
components/mock-application/MockApplicationHomePageClient.tsx 라우팅 경로 수정

💡 코드 설명 및 참고사항

📸 스크린샷 (UI 변경 시)

jobdri-chrome-2026-05-21-15-29-13_eUGlNRHS.mp4

🔍 리뷰 요구사항 (Reviewers)

URL step
/apply 메인
/apply/apply-type 1
/apply/virtual/[id]/jd-input 2
/apply/virtual/[id]/jd-review 3
/apply/virtual/[id]/questions 4
/apply/virtual/[id]/write 5
/apply/virtual/[id]/result 6

⚠️ 로컬 실행 시 유의사항

Summary by CodeRabbit

  • New Features

    • Added interactive JD input and review steps with selectable input methods and guided flow.
    • Question selection now persists and supports selecting full question objects.
  • Bug Fixes

    • Footer CTAs enable/disable correctly and navigate based on current selections.
    • Under-threshold warning modal shown when submitted text is too short.
  • Style

    • Updated header, footer, and multiline input background styling for improved layout and readability.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

Walkthrough

This PR restructures the virtual job application flow into apply/virtual/[id], lifts state to parent pages (controlled/forwardRef patterns), adds sessionStorage persistence for selected questions and answers, and applies minor UI/layout updates across common components.

Changes

Virtual Job Application Flow Restructure

Layer / File(s) Summary
Entry points and navigation routing
jobdri/src/app/apply/page.tsx, jobdri/src/components/mock-application/MockApplicationHomePageClient.tsx
Apply home page now renders MockApplicationHomePageClient instead of an empty implementation, and the home button navigation updated to route to /apply/virtual.
JD Input flow: controlled component refactoring and page integration
jobdri/src/app/apply/virtual/[id]/(jd)/jd-input/JdInputPageClient.tsx, jobdri/src/app/apply/virtual/[id]/(jd)/jd-input/page.tsx
JdInputPageClient converted to a forwardRef controlled component receiving selectedMethod and onMethodChange props, exposing an imperative handleCtaClick() via the ref. New page wrapper manages selectedMethod state, forwards the ref for CTA handling, and computes the manual review route from the dynamic id param.
JD Review flow: client component and page with conditional sections
jobdri/src/app/apply/virtual/[id]/(jd)/jd-review/JdReviewPageClient.tsx, jobdri/src/app/apply/virtual/[id]/(jd)/jd-review/page.tsx
JdReviewPageClient accepts optional sections and renders Header at step 3 with JdReviewMain. The page reads the mode query param and supplies emptyJdSections when mode==="manual", includes Footer CTA to questions, and shows a back-confirmation modal with navigation handlers.
Questions selection and state persistence
jobdri/src/app/apply/virtual/[id]/questions/page.tsx, jobdri/src/components/apply/SelectQuestion.tsx, jobdri/src/components/common/chips/ChipQnumber.tsx
QuestionsPage now tracks selected Question objects (id, question, optional maxLength). SelectQuestion adds onQuestionsChange to notify parents with full question objects; ChipQnumber is now controlled (derives selected from props). Footer CTA persists selectedQuestions to sessionStorage before routing to the write page.
Answer input section with sessionStorage integration
jobdri/src/components/apply/InputSection.tsx, jobdri/src/app/apply/virtual/[id]/write/page.tsx
InputSection (forwardRef) loads selectedQuestions from sessionStorage, manages per-question texts and selected index, and exposes hasUnderThreshold() / isAllComplete() for validation. The write page uses this ref to show a ModalNotice when inputs are under threshold or navigate to the result page on submit.
Layout and styling updates
jobdri/src/components/common/footer/Footer.tsx, jobdri/src/components/common/header/Header.tsx, jobdri/src/components/common/input/InputMultiLine1000.tsx, jobdri/src/app/apply/virtual/[id]/result/page.tsx, jobdri/src/components/common/modal/ModalInput.tsx, jobdri/src/components/common/modal/ModalNotice.tsx
Footer centering moved into inner container and inner alignment set to center. Header adds bg-bg-default and computes an isCurrent step state. InputMultiLine1000 textarea background utility updated. Result page wrapper changed to a styled flex container. ModalInput import order and ModalNotice constant/props reordering applied; description preserves line breaks.

🎯 3 (Moderate) | ⏱️ ~25 minutes

"🐰 I hopped through routes and lifted state high,
Questions kept safe while answers reply,
Controlled refs guide the CTA's way,
Modals and pages now dance and play,
A tiny rabbit cheers the flow today! 🥕"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly describes the main change: implementing UI for the resume/cover-letter writing page (자소서 작성 페이지 UI). It directly aligns with the primary objective of adding the write page and related flow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/JDDEV-66-cl_write-ui-feat

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
jobdri/src/components/common/header/Header.tsx (1)

80-93: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Past steps missing bg-fill-quaternary-default styling.

The PR objectives specify three distinct visual states for step badges:

  • current step: bg-white
  • past steps: bg-fill-quaternary-default
  • incomplete: bg-fill-disabled

However, the current logic only distinguishes isCurrent vs not-current, so past completed steps incorrectly receive bg-fill-disabled instead of bg-fill-quaternary-default.

🎨 Proposed fix to add three-way step styling
                  <span
                    className={clsx(
                      "flex aspect-square h-5 w-5 items-center justify-center gap-2.5 rounded-icon-round text-cap12-med [font-feature-settings:'liga'_off,'clig'_off]",
                      "tracking-normal",
                      isCurrent
                        ? "bg-white text-text-neutral-description "
-                       : "bg-fill-disabled text-text-neutral-disabled",
+                       : reached
+                         ? "bg-fill-quaternary-default text-text-neutral-description"
+                         : "bg-fill-disabled text-text-neutral-disabled",
                    )}
                  >
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jobdri/src/components/common/header/Header.tsx` around lines 80 - 93, The
step badge styling only checks isCurrent (stepNumber === currentStep) so
completed past steps fall into the non-current branch; add a third state by
computing isPast (e.g., const isPast = stepNumber < currentStep) and update the
className conditional in Header.tsx to apply three-way classes: when isCurrent
use the "bg-white text-text-neutral-description" set, when isPast use
"bg-fill-quaternary-default" with the appropriate text color for completed
steps, otherwise use the existing "bg-fill-disabled text-text-neutral-disabled".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jobdri/src/app/apply/virtual/`[id]/questions/page.tsx:
- Line 40: The backAction href currently points to `/apply/virtual/${id}/jd`
which is an invalid route; update the backAction prop in the component (the JSX
line with backAction={{ href: `/apply/virtual/${id}/jd` }}) to point to the
correct previous step route, e.g. `/apply/virtual/${id}/jd-review` (or
`/apply/virtual/${id}/jd-input` if this page should go back to the input step)
so the back navigation doesn't 404.

In `@jobdri/src/app/apply/virtual/`[id]/write/page.tsx:
- Around line 19-25: The page allows navigation to the result even when
selectedQuestions is missing; update the client-side page component (the parent
of InputSection and Footer) to guard using the selectedQuestions state: if
selectedQuestions is undefined or empty, perform a client-side redirect with
next/navigation's useRouter (or useRouter().replace) to the questions step
(e.g., `/apply/virtual/${id}/questions`) or disable the Footer CTA by passing a
falsy/disabled ctaAction/ctaLabel; locate the selectedQuestions usage and add a
useEffect that checks its length and triggers the redirect (or conditionally
render Footer with disabled CTA) so users cannot reach the result without
prerequisites.

In `@jobdri/src/components/apply/InputSection.tsx`:
- Around line 34-35: isComplete currently computes completion using global
COMPLETE_THRESHOLD and MAX_LENGTH (e.g., references to isComplete,
COMPLETE_THRESHOLD, MAX_LENGTH), which yields wrong badges for questions with
different limits; change isComplete to accept the specific question max length
(e.g., isComplete(text: string, maxLength: number)) or compute using the
question's max (question.maxLength) at call sites, and evaluate completion using
that max (for example: text.length >= Math.ceil(maxLength *
COMPLETE_THRESHOLD_PERCENT) && text.length <= maxLength) so every badge/meter
uses the per-question limit instead of the fixed MAX_LENGTH.
- Around line 21-27: The useEffect that reads
sessionStorage.getItem("selectedQuestions") and calls JSON.parse(raw) can throw
on malformed data; wrap the parse in a try/catch, validate the parsed value is
an array of Question-like objects (check length, typeof entries and required
fields) before calling setQuestions and setTexts, and on failure either clear
the session key or skip state updates so the component doesn't crash; update the
block around sessionStorage.getItem("selectedQuestions") / JSON.parse(raw) and
the subsequent setQuestions/setTexts calls to use this guarded
parse-and-validate flow.

---

Outside diff comments:
In `@jobdri/src/components/common/header/Header.tsx`:
- Around line 80-93: The step badge styling only checks isCurrent (stepNumber
=== currentStep) so completed past steps fall into the non-current branch; add a
third state by computing isPast (e.g., const isPast = stepNumber < currentStep)
and update the className conditional in Header.tsx to apply three-way classes:
when isCurrent use the "bg-white text-text-neutral-description" set, when isPast
use "bg-fill-quaternary-default" with the appropriate text color for completed
steps, otherwise use the existing "bg-fill-disabled text-text-neutral-disabled".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 485446f0-d028-4d52-ae2c-ad3427686328

📥 Commits

Reviewing files that changed from the base of the PR and between c6574cc and 4f06d9f.

📒 Files selected for processing (25)
  • jobdri/src/app/apply/apply-type/ApplyTypePageClient.tsx
  • jobdri/src/app/apply/apply-type/page.tsx
  • jobdri/src/app/apply/page.tsx
  • jobdri/src/app/apply/virtual/[id]/(jd)/jd-input/JdInputPageClient.tsx
  • jobdri/src/app/apply/virtual/[id]/(jd)/jd-input/page.tsx
  • jobdri/src/app/apply/virtual/[id]/(jd)/jd-review/JdReviewPageClient.tsx
  • jobdri/src/app/apply/virtual/[id]/(jd)/jd-review/page.tsx
  • jobdri/src/app/apply/virtual/[id]/(jd)/page.tsx
  • jobdri/src/app/apply/virtual/[id]/questions/page.tsx
  • jobdri/src/app/apply/virtual/[id]/result/page.tsx
  • jobdri/src/app/apply/virtual/[id]/write/page.tsx
  • jobdri/src/app/apply/virtual/page.tsx
  • jobdri/src/app/mock-application/jd-input/page.tsx
  • jobdri/src/app/mock-application/jd-review/JdReviewPageClient.tsx
  • jobdri/src/app/mock-application/jd-review/page.tsx
  • jobdri/src/app/mock-application/page.tsx
  • jobdri/src/components/apply/InputSection.tsx
  • jobdri/src/components/apply/SelectQuestion.tsx
  • jobdri/src/components/common/chips/ChipQnumber.tsx
  • jobdri/src/components/common/footer/Footer.tsx
  • jobdri/src/components/common/header/Header.tsx
  • jobdri/src/components/common/input/InputMultiLine1000.tsx
  • jobdri/src/components/common/modal/ModalInput.tsx
  • jobdri/src/components/common/modal/ModalNotice.tsx
  • jobdri/src/components/mock-application/MockApplicationHomePageClient.tsx
💤 Files with no reviewable changes (5)
  • jobdri/src/app/apply/virtual/page.tsx
  • jobdri/src/app/mock-application/page.tsx
  • jobdri/src/app/mock-application/jd-review/JdReviewPageClient.tsx
  • jobdri/src/app/mock-application/jd-review/page.tsx
  • jobdri/src/app/mock-application/jd-input/page.tsx

</main>
<Footer
ctaLabel="확정하기"
backAction={{ href: `/apply/virtual/${id}/jd` }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix back navigation to a valid JD step route.

Line 40 uses /apply/virtual/${id}/jd, but this flow uses /apply/virtual/${id}/jd-review/jd-input. This back link is likely broken and can 404.

🔧 Proposed fix
-        backAction={{ href: `/apply/virtual/${id}/jd` }}
+        backAction={{ href: `/apply/virtual/${id}/jd-review` }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
backAction={{ href: `/apply/virtual/${id}/jd` }}
backAction={{ href: `/apply/virtual/${id}/jd-review` }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jobdri/src/app/apply/virtual/`[id]/questions/page.tsx at line 40, The
backAction href currently points to `/apply/virtual/${id}/jd` which is an
invalid route; update the backAction prop in the component (the JSX line with
backAction={{ href: `/apply/virtual/${id}/jd` }}) to point to the correct
previous step route, e.g. `/apply/virtual/${id}/jd-review` (or
`/apply/virtual/${id}/jd-input` if this page should go back to the input step)
so the back navigation doesn't 404.

Comment thread jobdri/src/app/apply/virtual/[id]/write/page.tsx Outdated
Comment on lines +21 to +27
useEffect(() => {
const raw = sessionStorage.getItem("selectedQuestions");
if (raw) {
const parsed: Question[] = JSON.parse(raw);
setQuestions(parsed);
setTexts(new Array(parsed.length).fill(""));
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Harden sessionStorage parsing to prevent client-side crashes.

Malformed or stale selectedQuestions data will throw during JSON.parse and break the page. Add guarded parsing + shape checks before setting state.

Proposed fix
 useEffect(() => {
   const raw = sessionStorage.getItem("selectedQuestions");
-  if (raw) {
-    const parsed: Question[] = JSON.parse(raw);
-    setQuestions(parsed);
-    setTexts(new Array(parsed.length).fill(""));
-  }
+  if (!raw) return;
+  try {
+    const parsed = JSON.parse(raw);
+    if (!Array.isArray(parsed)) return;
+
+    const normalized = parsed.filter(
+      (q): q is Question =>
+        typeof q?.id === "string" && typeof q?.question === "string",
+    );
+
+    setQuestions(normalized);
+    setTexts(new Array(normalized.length).fill(""));
+  } catch {
+    setQuestions([]);
+    setTexts([]);
+  }
 }, []);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jobdri/src/components/apply/InputSection.tsx` around lines 21 - 27, The
useEffect that reads sessionStorage.getItem("selectedQuestions") and calls
JSON.parse(raw) can throw on malformed data; wrap the parse in a try/catch,
validate the parsed value is an array of Question-like objects (check length,
typeof entries and required fields) before calling setQuestions and setTexts,
and on failure either clear the session key or skip state updates so the
component doesn't crash; update the block around
sessionStorage.getItem("selectedQuestions") / JSON.parse(raw) and the subsequent
setQuestions/setTexts calls to use this guarded parse-and-validate flow.

Comment thread jobdri/src/components/apply/InputSection.tsx Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jobdri/src/components/apply/InputSection.tsx`:
- Around line 37-44: isComplete currently uses a fixed ">= 1" threshold which is
too lenient; change the logic to use a percentage-based required length per
question (based on each question's maxLength) instead of a fixed 1 char.
Introduce or use a COMPLETION_PERCENT constant (e.g. 0.6) and compute
requiredLength = Math.ceil((q.maxLength ?? 1000) * COMPLETION_PERCENT), then
update isComplete/checkAllComplete so they compare currentTexts[i].length >=
requiredLength (or change isComplete signature to accept maxLength and compute
the threshold there) and ensure questions.every uses that threshold calculation
for each question.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b5be9f1b-c931-4e62-a920-c8417ce57ec3

📥 Commits

Reviewing files that changed from the base of the PR and between ad64420 and fafbd68.

📒 Files selected for processing (2)
  • jobdri/src/app/apply/virtual/[id]/write/page.tsx
  • jobdri/src/components/apply/InputSection.tsx

Comment on lines +37 to +44
const isComplete = (text: string, maxLength: number) =>
text.length >= 1 && text.length <= maxLength;

const checkAllComplete = (currentTexts: string[]) =>
questions.length > 0 &&
questions.every((q, i) =>
isComplete(currentTexts[i] ?? "", q.maxLength ?? 1000),
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

isComplete threshold is too lenient and breaks completion semantics.

isComplete now marks answers complete at >= 1 char, but this flow’s completion rule is percentage-based per question max length. This causes chips and allComplete to flip to complete too early.

Proposed fix
-    const isComplete = (text: string, maxLength: number) =>
-      text.length >= 1 && text.length <= maxLength;
+    const COMPLETE_RATIO = 0.5;
+    const isComplete = (text: string, maxLength: number) => {
+      const minLength = Math.ceil(maxLength * COMPLETE_RATIO);
+      return text.length >= minLength && text.length <= maxLength;
+    };

Also applies to: 75-75

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jobdri/src/components/apply/InputSection.tsx` around lines 37 - 44,
isComplete currently uses a fixed ">= 1" threshold which is too lenient; change
the logic to use a percentage-based required length per question (based on each
question's maxLength) instead of a fixed 1 char. Introduce or use a
COMPLETION_PERCENT constant (e.g. 0.6) and compute requiredLength =
Math.ceil((q.maxLength ?? 1000) * COMPLETION_PERCENT), then update
isComplete/checkAllComplete so they compare currentTexts[i].length >=
requiredLength (or change isComplete signature to accept maxLength and compute
the threshold there) and ensure questions.every uses that threshold calculation
for each question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants