Files
submanager/lib/screens/detail_screen.dart
JiWoong Sul 111c519883 feat: 폼 필드 컴포넌트 분리 및 구독 카드 인터랙션 개선
- billing_cycle_selector, category_selector, currency_selector 컴포넌트 분리
- 구독 카드 클릭 이슈 해결을 위한 리팩토링
- SMS 스캔 화면 UI/UX 개선 및 기능 강화
- 상세 화면 컨트롤러 로직 개선
- 알림 서비스 및 구독 URL 매칭 기능 추가
- CLAUDE.md 프로젝트 가이드라인 대폭 확장
- 전반적인 코드 구조 개선 및 타입 안정성 강화

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-14 15:47:46 +09:00

162 lines
5.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../models/subscription_model.dart';
import '../controllers/detail_screen_controller.dart';
import '../widgets/detail/detail_header_section.dart';
import '../widgets/detail/detail_form_section.dart';
import '../widgets/detail/detail_event_section.dart';
import '../widgets/detail/detail_url_section.dart';
import '../widgets/detail/detail_action_buttons.dart';
import '../theme/app_colors.dart';
/// 구독 상세 정보를 표시하고 편집할 수 있는 화면
class DetailScreen extends StatefulWidget {
final SubscriptionModel subscription;
const DetailScreen({
super.key,
required this.subscription,
});
@override
State<DetailScreen> createState() => _DetailScreenState();
}
class _DetailScreenState extends State<DetailScreen>
with SingleTickerProviderStateMixin {
late DetailScreenController _controller;
@override
void initState() {
super.initState();
_controller = DetailScreenController(
context: context,
subscription: widget.subscription,
);
_controller.initialize(vsync: this);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final baseColor = _controller.getCardColor();
return ChangeNotifierProvider<DetailScreenController>.value(
value: _controller,
child: Scaffold(
backgroundColor: AppColors.backgroundColor,
body: CustomScrollView(
controller: _controller.scrollController,
slivers: [
// 상단 헤더 섹션
SliverToBoxAdapter(
child: DetailHeaderSection(
subscription: widget.subscription,
controller: _controller,
fadeAnimation: _controller.fadeAnimation!,
slideAnimation: _controller.slideAnimation!,
rotateAnimation: _controller.rotateAnimation!,
),
),
// 본문 콘텐츠
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
// 편집 모드 안내
Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
baseColor.withValues(alpha: 0.15),
baseColor.withValues(alpha: 0.08),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: baseColor.withValues(alpha: 0.2),
width: 1,
),
),
child: Row(
children: [
Icon(
Icons.edit_rounded,
color: baseColor,
size: 20,
),
const SizedBox(width: 8),
Text(
'편집 모드',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: baseColor,
),
),
const Spacer(),
Text(
'변경사항은 저장 후 적용됩니다',
style: TextStyle(
fontSize: 14,
color: AppColors.darkNavy,
),
),
],
),
),
const SizedBox(height: 16),
// 기본 정보 폼 섹션
DetailFormSection(
controller: _controller,
fadeAnimation: _controller.fadeAnimation!,
slideAnimation: _controller.slideAnimation!,
),
const SizedBox(height: 16),
// 이벤트 가격 섹션
DetailEventSection(
controller: _controller,
fadeAnimation: _controller.fadeAnimation!,
slideAnimation: _controller.slideAnimation!,
),
const SizedBox(height: 16),
// 웹사이트 URL 섹션
DetailUrlSection(
controller: _controller,
fadeAnimation: _controller.fadeAnimation!,
slideAnimation: _controller.slideAnimation!,
),
const SizedBox(height: 32),
// 액션 버튼
DetailActionButtons(
controller: _controller,
fadeAnimation: _controller.fadeAnimation!,
slideAnimation: _controller.slideAnimation!,
),
],
),
),
),
],
),
),
);
}
}