- Extract business logic from screens into dedicated controllers - Split large screen files into smaller, reusable widget components - Add controllers for AddSubscriptionScreen and DetailScreen - Create modular widgets for subscription and detail features - Improve code organization and maintainability - Remove duplicated code and improve reusability 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
146 lines
4.8 KiB
Dart
146 lines
4.8 KiB
Dart
import 'package:flutter/material.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';
|
|
|
|
/// 구독 상세 정보를 표시하고 편집할 수 있는 화면
|
|
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 Scaffold(
|
|
backgroundColor: const Color(0xFFF5F5F7),
|
|
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(
|
|
color: baseColor.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
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: baseColor.withValues(alpha: 0.8),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
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!,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
} |