Skip to content

205 feat 이미지 전처리 기능 구현#206

Merged
ff1451 merged 3 commits intodevelopfrom
205-feat-이미지-전처리-기능-구현
Mar 21, 2026

Hidden character warning

The head ref may contain hidden characters: "205-feat-\uc774\ubbf8\uc9c0-\uc804\ucc98\ub9ac-\uae30\ub2a5-\uad6c\ud604"
Merged

205 feat 이미지 전처리 기능 구현#206
ff1451 merged 3 commits intodevelopfrom
205-feat-이미지-전처리-기능-구현

Conversation

@ff1451
Copy link
Copy Markdown
Collaborator

@ff1451 ff1451 commented Mar 21, 2026

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능
    • 클럽 비용, 관리 클럽 프로필, 모집 작성 페이지에 이미지 자동 전처리 도입 — 이미지가 업로드 전에 최적화됩니다.
    • 전처리 중에는 업로드/변경/삭제와 탐색이 차단되고 제출 버튼이 비활성화되며 버튼에 "이미지 준비 중..." 상태가 표시됩니다.
    • 다중 이미지 업로드는 병렬 처리로 점진적 추가 및 빠른 미리보기를 지원합니다.

@ff1451 ff1451 self-assigned this Mar 21, 2026
@ff1451 ff1451 linked an issue Mar 21, 2026 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 21, 2026

Walkthrough

클라이언트 사이드 이미지 전처리 기능을 추가했습니다. 새 유틸리티 prepareImageFile(Web Worker + 메인스레드 폴백)을 도입하고, 세 페이지(clubFeePage, ManagedClubProfile, ManagedRecruitmentWrite)의 이미지 선택 로직을 비동기 처리로 변경해 선택된 파일을 전처리합니다. 각 컴포넌트는 전처리 상태(isPreparingImage / isPreparingImages)를 도입해 전처리 중 이미지 조작 및 제출을 비활성화하고 버튼 레이블을 "이미지 준비 중..."으로 표시합니다.

Possibly related PRs

  • 관련 PR: 동일 파일의 제출 비활성화 로직을 수정한 변경과 연관됨 (클라이언트 측 전처리 상태 추가와 관련).
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 이미지 전처리 기능 구현이라는 주요 변화를 명확하게 요약하고 있으며, 변경 사항의 핵심을 잘 나타냅니다.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 205-feat-이미지-전처리-기능-구현

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Tip

CodeRabbit can use TruffleHog to scan for secrets in your code with verification capabilities.

Add a TruffleHog config file (e.g. trufflehog-config.yml, trufflehog.yml) to your project to customize detectors and scanning behavior. The tool runs only when a config file is present.

Copy link
Copy Markdown
Contributor

@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: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/pages/Manager/ManagedClubProfile/index.tsx`:
- Around line 91-116: The bug: deleting an image during async prepare can be
undone when prepare completes; update handleImageSelect and handleDeleteImage so
a delete during preparation prevents the prepared result from being applied.
Concretely, add a ref flag (e.g., imageDeletedRef) and set it true in
handleDeleteImage and false at start of handleImageSelect; before calling
setImageFile/setImagePreview (and before creating/assigning localPreviewUrlRef),
check that isPreparingImage is still true and imageDeletedRef is false (or
simply that imageDeletedRef is false) — if deletion occurred, discard the
preparedFile and don't set state. Also disable the delete UI when
isPreparingImage or ensure handleDeleteImage sets imageDeletedRef and clears any
pending preview refs (localPreviewUrlRef) so the prepared result cannot restore
the deleted image.

In `@src/pages/Manager/ManagedRecruitmentWrite/index.tsx`:
- Around line 169-193: The images are being appended in completion order because
onResolved uses setImages((prev) => [...prev, newItem]) inside
mapWithConcurrencyLimit; change this so uploads preserve the user's selection
order: either have mapWithConcurrencyLimit provide the original index for each
result and insert each preparedFile at that fixed index into images (use
setImages(prev => { const next=[...prev]; next[index]=newItem; return next; })),
or await mapWithConcurrencyLimit(...) to get an array of prepared files in the
original order and then call setImages once to append them in order and
setCurrentImageIndex based on previousImageCount; update references to
mapWithConcurrencyLimit, prepareImageFile, setImages, and setCurrentImageIndex
accordingly.

In `@src/utils/ts/imagePreprocessor.ts`:
- Around line 65-73: The worker initialization currently lets any exception from
new Worker(...) or runWorkerPreprocess() short-circuit and return the original
file, disabling the canvas fallback; update getWorker() to wrap the Worker
construction in a try/catch and on any error set imagePreprocessWorker = null
and return null so runMainThreadPreprocess() remains possible, and likewise wrap
calls to runWorkerPreprocess() (and the worker message/setup blocks referenced
around lines 103-121 and 196-210) so any thrown error clears
imagePreprocessWorker and returns null instead of failing the whole preprocess;
reference functions/variables imagePreprocessWorker, getWorker,
runWorkerPreprocess, and runMainThreadPreprocess when making these changes.
- Around line 39-41: getOutputMimeType() is hardcoded to always return
WEBP_MIME_TYPE which forces conversion to image/webp; update imagePreprocessor
logic to avoid breaking uploads by either preserving the original input mime
type or consulting a runtime capability flag before returning WebP.
Specifically, modify getOutputMimeType() (and callers in imagePreprocessor) to:
1) accept the original file mime/type or an options object, 2) check a
config/env flag or a new function like isBackendWebPSupported() (or query
src/apis/upload/entity.ts capabilities) and only return WEBP_MIME_TYPE when
supported, otherwise return the original mime (e.g., image/jpeg or image/png) as
a safe fallback, and 3) ensure upload code paths in src/apis/upload/index.ts
still handle the returned mime type.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d855c1ad-8080-489d-9b5a-69c0cf0b1111

📥 Commits

Reviewing files that changed from the base of the PR and between a731d40 and b28773f.

📒 Files selected for processing (6)
  • src/pages/Club/Application/clubFeePage.tsx
  • src/pages/Manager/ManagedClubProfile/index.tsx
  • src/pages/Manager/ManagedRecruitmentWrite/index.tsx
  • src/utils/ts/imagePreprocessor.ts
  • src/utils/ts/imagePreprocessor.worker.ts
  • src/utils/ts/promise.ts

Comment on lines +32 to 35
const [isPreparingImage, setIsPreparingImage] = useState(false);
const { value: isImageOpen, setTrue: openImage, setFalse: closeImage } = useBooleanState();
const isSubmitting = isApplyingToClub || isUploadingImage;
const isSubmitting = isApplyingToClub || isPreparingImage || isUploadingImage;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

전처리 중에도 파일 선택 버튼이 다시 열립니다.

초기 업로드에서는 previewUrl이 아직 없어서 큰 추가 버튼이 계속 렌더링되는데, 이 버튼은 여전히 fileInputRef.current?.click()를 바로 호출합니다. 그래서 전처리 중 두 번째 파일 선택창을 열 수 있고, 새 선택은 handleImageSelect의 early return으로 조용히 버려집니다. 이 CTA도 isPreparingImage 동안 비활성화해 주세요.

Also applies to: 43-58

Comment thread src/pages/Manager/ManagedClubProfile/index.tsx
Comment thread src/pages/Manager/ManagedRecruitmentWrite/index.tsx
Comment on lines +39 to +41
function getOutputMimeType() {
return WEBP_MIME_TYPE;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check the structure and find the relevant files
git ls-files src/utils/ts/imagePreprocessor.ts src/apis/upload/index.ts src/apis/upload/entity.ts

Repository: BCSDLab/KONECT_FRONT_END

Length of output: 152


🏁 Script executed:

# Read the imagePreprocessor file to see lines 39-41 and 164-193
wc -l src/utils/ts/imagePreprocessor.ts

Repository: BCSDLab/KONECT_FRONT_END

Length of output: 105


🏁 Script executed:

# Read the imagePreprocessor file
cat -n src/utils/ts/imagePreprocessor.ts

Repository: BCSDLab/KONECT_FRONT_END

Length of output: 7417


🏁 Script executed:

# Read the upload API files
cat -n src/apis/upload/index.ts

Repository: BCSDLab/KONECT_FRONT_END

Length of output: 567


🏁 Script executed:

# Read the upload entity file
cat -n src/apis/upload/entity.ts

Repository: BCSDLab/KONECT_FRONT_END

Length of output: 250


🏁 Script executed:

# Search for usages of getOutputMimeType
rg "getOutputMimeType" -A 2 -B 2

Repository: BCSDLab/KONECT_FRONT_END

Length of output: 1501


🏁 Script executed:

# Search for MIME type handling and WebP references
rg "image/webp|WEBP_MIME|webp" -i

Repository: BCSDLab/KONECT_FRONT_END

Length of output: 1040


WebP 변환이 백엔드에서 지원되는지 확인 필요

getOutputMimeType()이 항상 image/webp를 반환하도록 하드코딩되어 있어서 JPEG/PNG 입력이 모두 WebP로 변환됩니다(line 164). 그런데 src/apis/upload/index.ts에서는 파일을 그대로 업로드하고, src/apis/upload/entity.ts에 지원 포맷 제약이 없어서 백엔드가 WebP를 받아주는지 명확하지 않습니다. 서버/스토리지가 WebP를 지원하지 않으면 이미지 업로드가 전체적으로 깨질 수 있으므로, 원본 포맷 유지 옵션이나 명시적인 WebP 지원 확인이 필요합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/ts/imagePreprocessor.ts` around lines 39 - 41, getOutputMimeType()
is hardcoded to always return WEBP_MIME_TYPE which forces conversion to
image/webp; update imagePreprocessor logic to avoid breaking uploads by either
preserving the original input mime type or consulting a runtime capability flag
before returning WebP. Specifically, modify getOutputMimeType() (and callers in
imagePreprocessor) to: 1) accept the original file mime/type or an options
object, 2) check a config/env flag or a new function like
isBackendWebPSupported() (or query src/apis/upload/entity.ts capabilities) and
only return WEBP_MIME_TYPE when supported, otherwise return the original mime
(e.g., image/jpeg or image/png) as a safe fallback, and 3) ensure upload code
paths in src/apis/upload/index.ts still handle the returned mime type.

Comment thread src/utils/ts/imagePreprocessor.ts Outdated
Copy link
Copy Markdown
Contributor

@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.

Caution

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

⚠️ Outside diff range comments (1)
src/pages/Manager/ManagedRecruitmentWrite/index.tsx (1)

536-542: ⚠️ Potential issue | 🟡 Minor

disabled={isPreparingImages} 누락

다른 이미지 관련 버튼들(삭제, 이전, 다음)은 isPreparingImages 시 비활성화되지만, "이미지 추가" 버튼은 누락되어 있습니다. handleImageClick에서 early return 하지만 UI 일관성을 위해 추가하세요.

수정 제안
                   <button
                     type="button"
                     onClick={handleImageClick}
+                    disabled={isPreparingImages}
-                    className="bg-primary-500 rounded-full px-4 py-2 text-[13px] leading-[1.6] font-semibold text-white"
+                    className="bg-primary-500 rounded-full px-4 py-2 text-[13px] leading-[1.6] font-semibold text-white disabled:cursor-not-allowed disabled:opacity-50"
                   >
                     이미지 추가
                   </button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/Manager/ManagedRecruitmentWrite/index.tsx` around lines 536 - 542,
The "이미지 추가" button lacks the disabled prop used elsewhere and should be
disabled while images are preparing; update the button rendered for the "이미지 추가"
action to include disabled={isPreparingImages} so it matches the other image
buttons and prevents clicks that are already handled by the early return in
handleImageClick; locate the button element in ManagedRecruitmentWrite (the one
with onClick={handleImageClick}) and add the disabled prop (and optionally the
same visual styling/aria attributes used on the other image control buttons) to
keep UI state consistent.
🧹 Nitpick comments (4)
src/pages/Manager/ManagedRecruitmentWrite/index.tsx (4)

567-573: 중첩 삼항 연산자 - 가독성 고려

현재 구현이 동작하지만, 상태가 더 추가되면 유지보수가 어려워질 수 있습니다. 필요 시 헬퍼 함수로 추출을 고려해보세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/Manager/ManagedRecruitmentWrite/index.tsx` around lines 567 - 573,
Replace the nested ternary used to render the submit button label (the JSX using
isPreparingImages, isUploading, isPending) with a small helper function (e.g.,
getSubmitButtonLabel) or a prior if/else/switch block inside the
ManagedRecruitmentWrite component that returns the correct string; update the
JSX to call that helper (getSubmitButtonLabel()) so the logic is clearer and
easier to extend when additional states are added.

203-203: 빈 catch 블록 - 의도된 동작인지 확인 필요

prepareImageFile은 에러 시 원본 파일을 반환하므로 reject하지 않지만, mapWithConcurrencyLimit 자체의 예외는 무시됩니다. 로깅이나 최소한의 처리를 고려해보세요.

선택적 개선안
     )
-      .catch(() => {})
+      .catch((error) => {
+        console.error('Image preparation failed:', error);
+      })
       .finally(() => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/Manager/ManagedRecruitmentWrite/index.tsx` at line 203, 현재
.catch(() => {})로 예외를 완전히 무시하고 있어 mapWithConcurrencyLimit 내부 또는 prepareImageFile
호출 중 발생한 에러를 놓칩니다; prepareImageFile이 항상 원본을 반환하더라도 mapWithConcurrencyLimit의 예외는
처리해야 하므로 빈 catch를 제거하고 에러를 로깅하거나 적절히 처리하도록 변경하세요: 해당 catch를 잡아 prepareImageFile,
mapWithConcurrencyLimit 호출 컨텍스트(예: 파일 이름 또는 인덱스)를 포함한 에러 메시지를 콘솔 또는 기존
로거(processLogger 등)에 기록하고, 필요 시 재시도 또는 rethrow하여 상위에서 인지되게 만드세요.

3-3: cn() 유틸리티 사용 권장

가이드라인에 따르면 cn() from src/utils/ts/cn.ts 사용을 권장합니다. twMerge 직접 사용 대신 cn()으로 통일하면 clsx와 tailwind-merge를 함께 활용할 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/Manager/ManagedRecruitmentWrite/index.tsx` at line 3, Replace
direct use of twMerge with the shared cn utility: remove the import of twMerge
and import cn from src/utils/ts/cn.ts, then replace all calls to twMerge(...)
with cn(...) so clsx + tailwind-merge behavior is preserved; update any
exported/used identifiers in this file (e.g., where twMerge is referenced in
ManagedRecruitmentWrite component) to use cn instead.

44-297: 페이지 로직 분리 고려

가이드라인에 따르면 페이지별 로직은 hooks/ 디렉토리로 분리하는 것을 권장합니다. 이미지 핸들링(handleImageSelect, handleDeleteImage 등)과 폼 상태 관리를 커스텀 훅으로 분리하면 테스트와 재사용성이 향상됩니다.

현재 PR 범위를 넘어서므로 후속 작업으로 진행해도 무방합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/Manager/ManagedRecruitmentWrite/index.tsx` around lines 44 - 297,
The page contains a lot of state and image-handling logic that should be moved
into reusable hooks; extract the form state and image logic into one or two
custom hooks (e.g., useRecruitmentForm and/or useRecruitmentImages) that
encapsulate state variables (startDate, endDate, startTime, endTime, content,
isRecruitmentEnabled, isAlwaysRecruiting, images, currentImageIndex,
isPreparingImages, isUploading, hasHandledExisting,
hasInitializedRecruitmentEnabled), refs (textareaRef, fileInputRef) and handlers
(handleImageSelect, handlePrevImage, handleNextImage, handleDeleteImage,
handleImageClick, handleContentChange, handleReset,
handleRecruitmentEnabledChange) and return only the state and functions the
component needs; keep submit logic (handleSubmit) either in the form hook or
left in the page but adapt it to consume the hook-provided state and image
upload utilities (uploadImage, saveRecruitment, patchSettings), and update
ManagedRecruitmentWrite to use these hooks so the component becomes a thin view
layer.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/pages/Manager/ManagedRecruitmentWrite/index.tsx`:
- Around line 536-542: The "이미지 추가" button lacks the disabled prop used
elsewhere and should be disabled while images are preparing; update the button
rendered for the "이미지 추가" action to include disabled={isPreparingImages} so it
matches the other image buttons and prevents clicks that are already handled by
the early return in handleImageClick; locate the button element in
ManagedRecruitmentWrite (the one with onClick={handleImageClick}) and add the
disabled prop (and optionally the same visual styling/aria attributes used on
the other image control buttons) to keep UI state consistent.

---

Nitpick comments:
In `@src/pages/Manager/ManagedRecruitmentWrite/index.tsx`:
- Around line 567-573: Replace the nested ternary used to render the submit
button label (the JSX using isPreparingImages, isUploading, isPending) with a
small helper function (e.g., getSubmitButtonLabel) or a prior if/else/switch
block inside the ManagedRecruitmentWrite component that returns the correct
string; update the JSX to call that helper (getSubmitButtonLabel()) so the logic
is clearer and easier to extend when additional states are added.
- Line 203: 현재 .catch(() => {})로 예외를 완전히 무시하고 있어 mapWithConcurrencyLimit 내부 또는
prepareImageFile 호출 중 발생한 에러를 놓칩니다; prepareImageFile이 항상 원본을 반환하더라도
mapWithConcurrencyLimit의 예외는 처리해야 하므로 빈 catch를 제거하고 에러를 로깅하거나 적절히 처리하도록 변경하세요:
해당 catch를 잡아 prepareImageFile, mapWithConcurrencyLimit 호출 컨텍스트(예: 파일 이름 또는 인덱스)를
포함한 에러 메시지를 콘솔 또는 기존 로거(processLogger 등)에 기록하고, 필요 시 재시도 또는 rethrow하여 상위에서 인지되게
만드세요.
- Line 3: Replace direct use of twMerge with the shared cn utility: remove the
import of twMerge and import cn from src/utils/ts/cn.ts, then replace all calls
to twMerge(...) with cn(...) so clsx + tailwind-merge behavior is preserved;
update any exported/used identifiers in this file (e.g., where twMerge is
referenced in ManagedRecruitmentWrite component) to use cn instead.
- Around line 44-297: The page contains a lot of state and image-handling logic
that should be moved into reusable hooks; extract the form state and image logic
into one or two custom hooks (e.g., useRecruitmentForm and/or
useRecruitmentImages) that encapsulate state variables (startDate, endDate,
startTime, endTime, content, isRecruitmentEnabled, isAlwaysRecruiting, images,
currentImageIndex, isPreparingImages, isUploading, hasHandledExisting,
hasInitializedRecruitmentEnabled), refs (textareaRef, fileInputRef) and handlers
(handleImageSelect, handlePrevImage, handleNextImage, handleDeleteImage,
handleImageClick, handleContentChange, handleReset,
handleRecruitmentEnabledChange) and return only the state and functions the
component needs; keep submit logic (handleSubmit) either in the form hook or
left in the page but adapt it to consume the hook-provided state and image
upload utilities (uploadImage, saveRecruitment, patchSettings), and update
ManagedRecruitmentWrite to use these hooks so the component becomes a thin view
layer.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 37bb061c-b71b-42a9-9e4e-f2f19b00e3f9

📥 Commits

Reviewing files that changed from the base of the PR and between b28773f and bfd4cef.

📒 Files selected for processing (3)
  • src/pages/Manager/ManagedClubProfile/index.tsx
  • src/pages/Manager/ManagedRecruitmentWrite/index.tsx
  • src/utils/ts/imagePreprocessor.ts
✅ Files skipped from review due to trivial changes (1)
  • src/utils/ts/imagePreprocessor.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/pages/Manager/ManagedClubProfile/index.tsx

@ff1451 ff1451 merged commit 930d150 into develop Mar 21, 2026
2 checks passed
ff1451 added a commit that referenced this pull request Mar 23, 2026
* 205 feat 이미지 전처리 기능 구현 (#206)

* feat: 전처리 로직 및 WebWorker 구현

* feat: 전처리 적용 및 preview 동시성 제어 로직 추가

* refactor: 리뷰 반영

* [hotfix] 하단바 너비 수정 (#208)

* hotfix: 하단바 너비 수정

* chore: 불필요한 값 제거

* refactor: 고정 gap 제거
ff1451 added a commit that referenced this pull request Apr 1, 2026
* 205 feat 이미지 전처리 기능 구현 (#206)

* feat: 전처리 로직 및 WebWorker 구현

* feat: 전처리 적용 및 preview 동시성 제어 로직 추가

* refactor: 리뷰 반영

* [hotfix] 하단바 너비 수정 (#208)

* hotfix: 하단바 너비 수정

* chore: 불필요한 값 제거

* refactor: 고정 gap 제거

* Reapply "[feat] 광고 배너 추가 (#200)"

This reverts commit c51ec85.

* [feat] 하단바 리디자인 (#213)

* chore: asset 추가

* feat: 하단바 리디자인 반영 및 레이아웃 수정

* [refactor] 광고 카드 레이아웃 밀림 수정 (#215)

* refactor: 광고 개수 측정 시기 변경 및 기본값 제거

* feat: 스켈레톤 UI 추가

* feat: 인앱 알림 페이지 및 토스트 구현 (#217)

* feat: 알림 API 및 스트림 기반 추가

* feat: 인앱 알림 레이어 추가

* feat: 알림 페이지 및 헤더 진입 구현

* fix: 알림 스트림 401 재시도 조건 정리

* fix: 알림 목록 이동 차단 제거

* refactor: 알림 공용 훅 위치 정리

* fix: 알림 재연결 캐시 동기화 추가

* fix: 알림 목록 토스트 큐 누적 방지

* fix: 알림 읽음 카운트 감소 조건 보강

* [refactor] 도메인별 TanStack Query 훅 정리 (#219)

* chore: pwa용 이미지 제거

* refactor: auth 도메인 쿼리와 뮤테이션 정리

* refactor: council과 schedule 조회 훅 정리

* refactor: chat과 notification 캐시 처리 정리

* refactor: club 조회와 지원 플로우 정리

* refactor: manager 도메인 캐시 처리 정리

* refactor: studyTime 도메인 쿼리와 뮤테이션 정리

* refactor: 광고와 업로드 도메인 훅 정리

* [refactor] mutaton query 및 hook 추가 수정 (#221)

* refactor: auth와 user myInfo 훅 정리

* refactor: club과 schedule 조회 훅 정리

* refactor: chat과 notification 훅 구조 정리

* refactor: club 지원 뮤테이션 훅 정리

* refactor: manager 뮤테이션 훅 구조 정리

* refactor: mutation 훅 cache 정리

* refactor: 컨벤션 통일

* refactor: isRead 조건 정리

* fix: 채팅 스크롤 문제 수정

* refactor: 불필요한 코드 제거

* [fix] 모바일 환경 입력창과 키보드 간의 간격이 큰 문제 수정 (#223)

* chore: 가공용 safeArea 변수 선언

* refactor: 고정 패딩 값 수정 및 safeArea 적용 변경

* feat: 키보드 활성화 감지 및 safeArea 적용 여부 기능 추가

* refactor: 매직넘버 상수화 및 가로모드 처리

* [fix] 키보드 활성화 시 화면 흔들림 문제 수정 (#225)

* refactor: 채팅 viewport 훅 네이밍 정리

* refactor: viewport 높이 잠금 훅 적용 시점 조정

* [fix] 키보드 활성화 시 채팅 화면 전체가 흔들리는 문제 수정 (#227)

* refactor: 채팅 viewport 훅 네이밍 정리

* refactor: viewport 높이 잠금 훅 적용 시점 조정

* fix: 채팅 화면 스크롤 잠금으로 키보드 흔들림 완화

* fix: 입력 포커스 중 viewport offset 고정 (#229)

* fix: 문서 루트 스크롤 잠금으로 빈 공간 잔류 방지 (#232)

* [fix] 키보드 활성화 시 채팅 화면 상단 고정이 깨지고 빈 공간이 남는 문제 수정 (#234)

* fix: 채팅 화면 상단 고정 깨짐과 빈 공간 잔류 수정

* refactor: 라우트 조건 수정

* fix: 문서 스크롤 위치 감지 보강

* refactor: 입력 요소 판별 유틸과 스크롤 주석 정리

* [fix] 키보드 활성화 시 채팅 화면에서 문서 스크롤이 발생하는 문제 수정 (#236)

* fix: 채팅 문서 스크롤 제스처 차단

* fix: 입력 요소 터치 동작 예외 처리

* [fix] 키보드 활성화 시 채팅방이 마지막 메시지 위치를 유지하지 못하는 문제 수정 (#238)

* fix: 키보드 활성화 시 채팅 하단 정렬 유지

* refactor: 채팅 리사이즈 관찰 안정화

* fix: mypage 연계 약관 페이지 뒤로가기 수정 (#240)

* refactor: alias import 경로 정리

* fix: query 설정과 suspense 분기 정리

* refactor: 관리자 화면 스타일 유틸 정리

* fix: 이미지 전처리 예외 처리 보강

* fix: 헤더와 회비 화면 동작 정리

* fix: 공통 유틸 안정성 개선

* fix: 이미지 전처리 실패 처리를 보정

* fix: 모집 공고 저장 후 설정 반영 순서 조정

* fix: 부원 직책 변경 실패 처리를 보강

* fix: 약관 링크 접근성을 개선

* fix: 공통 쿼리와 유틸 안정성을 보완

* [feat] 동적 버전 정보 표시 구현 (#211)

* feat: 동적 버전 정보 표시 구현

* refactor: 버전 정보 미 존재시 v 표시 제거

* [feat] 메인화면 동아리 카드 디자인 수정 반영 (#242)

* feat: 메인화면 동아리 카드 디자인 수정

* chore: 하단바 아이콘 수정

* refactor: 코드래빗 리뷰 반영

* refactor: and 연산자로 변경

* apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화 (#244)

* refactor: apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화

* refactor: body 직렬화 가드를 plain object/array로 한정

* fix: body 읽기 중 AbortError가 ParseError로 오분류되는 문제 수정

* [refactor] 에러 처리 유틸 및 utils 구조 정리 (#246)

* refactor: 에러 처리 유틸 및 공통 토스트 흐름 정리

* refactor: utils 폴더 구조를 역할별로 정리

* refactor: 코드래빗 리뷰 반영

* refactor: 코드래빗 리뷰 반영

* Update src/pages/Home/components/HomeClubSection.tsx

* fix: 인증 세션 복구 흐름 정리

* fix: 홈 동아리 카드 레이아웃 정리

* [feat] 총동아리 페이지 리디자인 및 하단 오버레이 정리 (#249)

* refactor: 하단 오버레이 처리 공통화

* feat: 총동아리 페이지와 헤더 리디자인 반영

* fix: 채팅 하단 여백과 외부 링크 속성 수정

* refactor: 총동아리 헤더 설정 정리

* fix: 총동아리 상세 접근성과 스타일 보완

* [feat] 마이페이지 관리자 카드 분리 및 채팅 미확인 배지 반영 (#251)

* feat: 하단 채팅 배지 표시 및 조회 조건 보완

* refactor: 관리자 정보 카드 컴포넌트 분리

* feat: 채팅 페이지 리디자인 (#252)

* feat: 채팅 페이지 리디자인

* fix:tailwind 문법 수정

* fix: 코드 수정

* fix: 폰트 색상 및 위치 수정

* fix: 채팅방 사람수 정렬

* fix: 오타 수정

* chore: conflict 해결 중 누락된 부분 수정

* [refactor] 광고 렌더링 조건 수정 (#254)

* refactor: 광고 렌더링 조건 수정

* docs: 문서명 변경

---------

Co-authored-by: 박성주 <145267904+ParkSungju01@users.noreply.github.com>
@ff1451 ff1451 deleted the 205-feat-이미지-전처리-기능-구현 branch April 7, 2026 09:33
ff1451 added a commit that referenced this pull request Apr 21, 2026
* [배포] 이미지 전처리, 광고 기능, 하단바 리디자인, 인앱 알림 페이지 및 토스트 프로덕션 배포 (#230)

* 205 feat 이미지 전처리 기능 구현 (#206)

* feat: 전처리 로직 및 WebWorker 구현

* feat: 전처리 적용 및 preview 동시성 제어 로직 추가

* refactor: 리뷰 반영

* [hotfix] 하단바 너비 수정 (#208)

* hotfix: 하단바 너비 수정

* chore: 불필요한 값 제거

* refactor: 고정 gap 제거

* Reapply "[feat] 광고 배너 추가 (#200)"

This reverts commit c51ec85.

* [feat] 하단바 리디자인 (#213)

* chore: asset 추가

* feat: 하단바 리디자인 반영 및 레이아웃 수정

* [refactor] 광고 카드 레이아웃 밀림 수정 (#215)

* refactor: 광고 개수 측정 시기 변경 및 기본값 제거

* feat: 스켈레톤 UI 추가

* feat: 인앱 알림 페이지 및 토스트 구현 (#217)

* feat: 알림 API 및 스트림 기반 추가

* feat: 인앱 알림 레이어 추가

* feat: 알림 페이지 및 헤더 진입 구현

* fix: 알림 스트림 401 재시도 조건 정리

* fix: 알림 목록 이동 차단 제거

* refactor: 알림 공용 훅 위치 정리

* fix: 알림 재연결 캐시 동기화 추가

* fix: 알림 목록 토스트 큐 누적 방지

* fix: 알림 읽음 카운트 감소 조건 보강

* [refactor] 도메인별 TanStack Query 훅 정리 (#219)

* chore: pwa용 이미지 제거

* refactor: auth 도메인 쿼리와 뮤테이션 정리

* refactor: council과 schedule 조회 훅 정리

* refactor: chat과 notification 캐시 처리 정리

* refactor: club 조회와 지원 플로우 정리

* refactor: manager 도메인 캐시 처리 정리

* refactor: studyTime 도메인 쿼리와 뮤테이션 정리

* refactor: 광고와 업로드 도메인 훅 정리

* [refactor] mutaton query 및 hook 추가 수정 (#221)

* refactor: auth와 user myInfo 훅 정리

* refactor: club과 schedule 조회 훅 정리

* refactor: chat과 notification 훅 구조 정리

* refactor: club 지원 뮤테이션 훅 정리

* refactor: manager 뮤테이션 훅 구조 정리

* refactor: mutation 훅 cache 정리

* refactor: 컨벤션 통일

* refactor: isRead 조건 정리

* fix: 채팅 스크롤 문제 수정

* refactor: 불필요한 코드 제거

* [fix] 모바일 환경 입력창과 키보드 간의 간격이 큰 문제 수정 (#223)

* chore: 가공용 safeArea 변수 선언

* refactor: 고정 패딩 값 수정 및 safeArea 적용 변경

* feat: 키보드 활성화 감지 및 safeArea 적용 여부 기능 추가

* refactor: 매직넘버 상수화 및 가로모드 처리

* [fix] 키보드 활성화 시 화면 흔들림 문제 수정 (#225)

* refactor: 채팅 viewport 훅 네이밍 정리

* refactor: viewport 높이 잠금 훅 적용 시점 조정

* [fix] 키보드 활성화 시 채팅 화면 전체가 흔들리는 문제 수정 (#227)

* refactor: 채팅 viewport 훅 네이밍 정리

* refactor: viewport 높이 잠금 훅 적용 시점 조정

* fix: 채팅 화면 스크롤 잠금으로 키보드 흔들림 완화

* fix: 입력 포커스 중 viewport offset 고정 (#229)

* fix: 문서 루트 스크롤 잠금으로 빈 공간 잔류 방지 (#232)

* [fix] 키보드 활성화 시 채팅 화면 상단 고정이 깨지고 빈 공간이 남는 문제 수정 (#234)

* fix: 채팅 화면 상단 고정 깨짐과 빈 공간 잔류 수정

* refactor: 라우트 조건 수정

* fix: 문서 스크롤 위치 감지 보강

* refactor: 입력 요소 판별 유틸과 스크롤 주석 정리

* [fix] 키보드 활성화 시 채팅 화면에서 문서 스크롤이 발생하는 문제 수정 (#236)

* fix: 채팅 문서 스크롤 제스처 차단

* fix: 입력 요소 터치 동작 예외 처리

* [fix] 키보드 활성화 시 채팅방이 마지막 메시지 위치를 유지하지 못하는 문제 수정 (#238)

* fix: 키보드 활성화 시 채팅 하단 정렬 유지

* refactor: 채팅 리사이즈 관찰 안정화

* fix: mypage 연계 약관 페이지 뒤로가기 수정 (#240)

* refactor: alias import 경로 정리

* fix: query 설정과 suspense 분기 정리

* refactor: 관리자 화면 스타일 유틸 정리

* fix: 이미지 전처리 예외 처리 보강

* fix: 헤더와 회비 화면 동작 정리

* fix: 공통 유틸 안정성 개선

* fix: 이미지 전처리 실패 처리를 보정

* fix: 모집 공고 저장 후 설정 반영 순서 조정

* fix: 부원 직책 변경 실패 처리를 보강

* fix: 약관 링크 접근성을 개선

* fix: 공통 쿼리와 유틸 안정성을 보완

* [feat] 동적 버전 정보 표시 구현 (#211)

* feat: 동적 버전 정보 표시 구현

* refactor: 버전 정보 미 존재시 v 표시 제거

* [feat] 메인화면 동아리 카드 디자인 수정 반영 (#242)

* feat: 메인화면 동아리 카드 디자인 수정

* chore: 하단바 아이콘 수정

* refactor: 코드래빗 리뷰 반영

* refactor: and 연산자로 변경

* apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화 (#244)

* refactor: apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화

* refactor: body 직렬화 가드를 plain object/array로 한정

* fix: body 읽기 중 AbortError가 ParseError로 오분류되는 문제 수정

* [refactor] 에러 처리 유틸 및 utils 구조 정리 (#246)

* refactor: 에러 처리 유틸 및 공통 토스트 흐름 정리

* refactor: utils 폴더 구조를 역할별로 정리

* refactor: 코드래빗 리뷰 반영

* refactor: 코드래빗 리뷰 반영

* Update src/pages/Home/components/HomeClubSection.tsx

* fix: 인증 세션 복구 흐름 정리

* fix: 홈 동아리 카드 레이아웃 정리

* [feat] 총동아리 페이지 리디자인 및 하단 오버레이 정리 (#249)

* refactor: 하단 오버레이 처리 공통화

* feat: 총동아리 페이지와 헤더 리디자인 반영

* fix: 채팅 하단 여백과 외부 링크 속성 수정

* refactor: 총동아리 헤더 설정 정리

* fix: 총동아리 상세 접근성과 스타일 보완

* [feat] 마이페이지 관리자 카드 분리 및 채팅 미확인 배지 반영 (#251)

* feat: 하단 채팅 배지 표시 및 조회 조건 보완

* refactor: 관리자 정보 카드 컴포넌트 분리

* feat: 채팅 페이지 리디자인 (#252)

* feat: 채팅 페이지 리디자인

* fix:tailwind 문법 수정

* fix: 코드 수정

* fix: 폰트 색상 및 위치 수정

* fix: 채팅방 사람수 정렬

* fix: 오타 수정

* chore: conflict 해결 중 누락된 부분 수정

* [refactor] 광고 렌더링 조건 수정 (#254)

* refactor: 광고 렌더링 조건 수정

* docs: 문서명 변경

---------

Co-authored-by: 박성주 <145267904+ParkSungju01@users.noreply.github.com>

* refactor: 가이드 페이지 이미지 변경 및 구조 개선 (#260)

* hotfix: 가이드 이미지 경로 변경

---------

Co-authored-by: 박성주 <145267904+ParkSungju01@users.noreply.github.com>
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.

[feat] 이미지 전처리 기능 구현

1 participant