# AddRestaurantDialog JSON 스타일 UI 디자인 ## 개요 네이버 URL에서 가져온 맛집 정보를 JSON 형식으로 보여주는 UI 디자인 명세서입니다. ## 디자인 컨셉 - **JSON 시각화**: 개발자 친화적인 JSON 형식으로 데이터를 표현 - **편집 가능**: 각 필드를 직접 수정할 수 있는 인터랙티브 UI - **Material Design 3**: 최신 디자인 가이드라인 준수 - **다크모드 지원**: 라이트/다크 테마 완벽 지원 ## 컴포넌트 구조 ### 1. 메인 컨테이너 ```dart Container( padding: EdgeInsets.all(16), decoration: BoxDecoration( color: isDark ? AppColors.darkBackground : AppColors.lightBackground.withOpacity(0.5), borderRadius: BorderRadius.circular(12), border: Border.all( color: isDark ? AppColors.darkDivider : AppColors.lightDivider, ), ), ) ``` - 반투명 배경으로 깊이감 표현 - 둥근 모서리와 테두리로 구분 ### 2. 헤더 영역 ```dart Row( children: [ Icon(Icons.code, size: 20), SizedBox(width: 8), Text('가져온 정보', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600)), ], ) ``` - 코드 아이콘으로 JSON 데이터임을 시각적으로 표현 - 적절한 간격과 타이포그래피 ### 3. JSON 필드 컴포넌트 각 필드는 `_buildJsonField` 메서드로 일관성 있게 구현: #### 기본 필드 구조 ```dart Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 레이블 Row( children: [ Icon(icon, size: 16), // 필드별 아이콘 SizedBox(width: 8), Text('$label:', style: labelStyle), ], ), SizedBox(height: 4), // 입력 필드 TextFormField( controller: controller, style: TextStyle( fontSize: 14, fontFamily: isLink ? 'monospace' : null, ), decoration: InputDecoration( isDense: true, contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8), filled: true, fillColor: isDark ? AppColors.darkSurface : Colors.white, border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), ), ), ], ) ``` #### 좌표 필드 (특수 처리) ```dart Row( children: [ Expanded(child: TextFormField(...)), // 위도 Text(',', style: monoStyle), Expanded(child: TextFormField(...)), // 경도 ], ) ``` ## 색상 팔레트 ### 라이트 모드 - **배경**: `AppColors.lightBackground.withOpacity(0.5)` - **테두리**: `AppColors.lightDivider` - **필드 배경**: `Colors.white` - **텍스트**: `AppColors.lightText` - **보조 텍스트**: `AppColors.lightTextSecondary` - **링크**: `AppColors.lightPrimary` ### 다크 모드 - **배경**: `AppColors.darkBackground` - **테두리**: `AppColors.darkDivider` - **필드 배경**: `AppColors.darkSurface` - **텍스트**: `AppColors.darkText` - **보조 텍스트**: `AppColors.darkTextSecondary` - **링크**: `AppColors.lightPrimary` (동일) ## 아이콘 매핑 | 필드 | 아이콘 | 의미 | |------|--------|------| | 이름 | `Icons.store` | 가게/상점 | | 카테고리 | `Icons.category` | 분류 | | 세부 카테고리 | `Icons.label_outline` | 태그/라벨 | | 주소 | `Icons.location_on` | 위치 | | 전화 | `Icons.phone` | 연락처 | | 설명 | `Icons.description` | 설명/문서 | | 좌표 | `Icons.my_location` | GPS 좌표 | | 링크 | `Icons.link` | 외부 링크 | ## 타이포그래피 - **레이블**: 13px, FontWeight.w500 - **값**: 14px, 일반 - **링크**: 14px, monospace 폰트, underline - **좌표**: 14px, monospace 폰트 ## 인터랙션 ### 1. 가져오기 플로우 1. URL 입력 2. "가져오기" 버튼 클릭 3. 로딩 상태 표시 4. 성공 시: JSON 스타일 UI 표시 5. 실패 시: 에러 메시지 표시 ### 2. 편집 플로우 1. 각 필드 직접 수정 가능 2. 좌표는 위도/경도 분리 입력 3. 링크는 monospace 폰트와 밑줄로 구분 ### 3. 저장/초기화 - **초기화**: 모든 필드 클리어, UI 리셋 - **저장**: 수정된 데이터로 맛집 추가 ## 반응형 디자인 - 최대 너비: 400px (Dialog 제약) - 스크롤 가능한 영역 - 모바일/태블릿 최적화 ## 접근성 - 적절한 대비율 유지 - 터치 타겟 최소 44x44px - 키보드 네비게이션 지원 - 스크린 리더 호환 ## 애니메이션 - 필드 포커스: 부드러운 테두리 전환 - 버튼 상태: 색상 페이드 - 로딩: CircularProgressIndicator ## 구현 고려사항 1. **상태 관리**: `_fetchedRestaurantData` Map으로 데이터 추적 2. **폼 검증**: 각 필드별 적절한 검증 3. **에러 처리**: 사용자 친화적 메시지 4. **성능**: 불필요한 리빌드 방지