Merge remote-tracking branch 'upstream/main'

This commit is contained in:
dohyeons
2025-11-06 17:22:17 +09:00
179 changed files with 28105 additions and 1726 deletions

132
scripts/add-modal-ids.py Normal file
View File

@@ -0,0 +1,132 @@
#!/usr/bin/env python3
"""
모든 ResizableDialogContent에 modalId와 userId를 추가하는 스크립트
"""
import os
import re
from pathlib import Path
def process_file(file_path):
"""파일을 처리하여 modalId와 userId를 추가"""
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
original_content = content
modified = False
# 파일명에서 modalId 생성 (예: UserFormModal.tsx -> user-form-modal)
file_name = Path(file_path).stem
modal_id = re.sub(r'(?<!^)(?=[A-Z])', '-', file_name).lower()
# useAuth import 확인
has_use_auth = 'useAuth' in content
# useAuth import 추가 (없으면)
if not has_use_auth and 'ResizableDialogContent' in content:
# import 섹션 찾기
import_match = re.search(r'(import.*from.*;\n)', content)
if import_match:
last_import_pos = content.rfind('import')
next_newline = content.find('\n', last_import_pos)
if next_newline != -1:
content = (
content[:next_newline + 1] +
'import { useAuth } from "@/hooks/useAuth";\n' +
content[next_newline + 1:]
)
modified = True
# 함수 컴포넌트 내부에 useAuth 추가
# 패턴: export default function ComponentName() { 또는 const ComponentName = () => {
if 'ResizableDialogContent' in content and 'const { user } = useAuth();' not in content:
# 함수 시작 부분 찾기
patterns = [
r'(export default function \w+\([^)]*\)\s*\{)',
r'(export function \w+\([^)]*\)\s*\{)',
r'(const \w+ = \([^)]*\)\s*=>\s*\{)',
r'(function \w+\([^)]*\)\s*\{)',
]
for pattern in patterns:
match = re.search(pattern, content)
if match:
insert_pos = match.end()
# 이미 useAuth가 있는지 확인
next_100_chars = content[insert_pos:insert_pos + 200]
if 'useAuth' not in next_100_chars:
content = (
content[:insert_pos] +
'\n const { user } = useAuth();' +
content[insert_pos:]
)
modified = True
break
# ResizableDialogContent에 modalId와 userId 추가
# 패턴: <ResizableDialogContent ... > (modalId가 없는 경우)
pattern = r'<ResizableDialogContent\s+([^>]*?)(?<!modalId=")>'
def add_props(match):
nonlocal modified
props = match.group(1).strip()
# 이미 modalId가 있는지 확인
if 'modalId=' in props:
return match.group(0)
# props가 있으면 끝에 추가, 없으면 새로 추가
if props:
if not props.endswith(' '):
props += ' '
new_props = f'{props}modalId="{modal_id}" userId={{user?.userId}}'
else:
new_props = f'modalId="{modal_id}" userId={{user?.userId}}'
modified = True
return f'<ResizableDialogContent {new_props}>'
content = re.sub(pattern, add_props, content)
# 변경사항이 있으면 파일 저장
if modified and content != original_content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
return True
return False
def main():
"""메인 함수"""
frontend_dir = Path('frontend/components')
if not frontend_dir.exists():
print(f"❌ 디렉토리를 찾을 수 없습니다: {frontend_dir}")
return
# 모든 .tsx 파일 찾기
tsx_files = list(frontend_dir.rglob('*.tsx'))
modified_files = []
for file_path in tsx_files:
# ResizableDialogContent가 있는 파일만 처리
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
if 'ResizableDialogContent' not in content:
continue
if process_file(file_path):
modified_files.append(file_path)
print(f"{file_path}")
print(f"\n🎉 총 {len(modified_files)}개 파일 수정 완료!")
if modified_files:
print("\n수정된 파일 목록:")
for f in modified_files:
print(f" - {f}")
if __name__ == '__main__':
main()