From 5fbabe92380115a24ead9fca1289506e11e195ea Mon Sep 17 00:00:00 2001 From: girinb Date: Tue, 15 Jul 2025 01:17:16 +0900 Subject: [PATCH] =?UTF-8?q?=ED=95=98=EB=8B=A8=20=EA=B4=91=EA=B3=A0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/home_page.dart | 224 +++++++++++++++++++++------------------------ 1 file changed, 103 insertions(+), 121 deletions(-) diff --git a/lib/home_page.dart b/lib/home_page.dart index 1bb9874..219c17b 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -6,7 +6,6 @@ import 'package:intl/intl.dart'; import 'package:csp2/common/widgets/upcoming_class_card.dart'; import 'package:csp2/common/widgets/course_card.dart'; import 'package:csp2/course.dart'; // Course 클래스 import -// import 'package:flutter_native_timezone/flutter_native_timezone.dart'; // 주석 처리된 상태 유지 import '../plan_page.dart'; // PlanPage import // CaseStudyPlan 클래스 (변경 없음) @@ -309,110 +308,110 @@ class _HomePageState extends State { } Widget _buildHomeContent() { - return Column( - - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), - child: IntrinsicHeight( - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Expanded( - flex: 1, - child: _buildLocalTimeBar(), - ), - const SizedBox(width: 12.0), - Expanded( - flex: 1, - child: _buildButtons(), - ), - ], + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), + child: IntrinsicHeight( + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + flex: 1, + child: _buildLocalTimeBar(), + ), + const SizedBox(width: 12.0), + Expanded( + flex: 1, + child: _buildButtons(), + ), + ], + ), ), ), - ), - const Padding( - padding: EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0), // vertical을 위아래 다르게 조정 - child: Text('Upcoming Study', style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - SizedBox( - height: 200, // 가로 리스트의 높이를 줄입니다. - child: FutureBuilder>( - future: _caseStudyPlans, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator()); - } else if (snapshot.hasError) { - return Center(child: Padding( - padding: const EdgeInsets.all(16.0), - child: Text('Error loading upcoming classes: ${snapshot.error}', textAlign: TextAlign.center), - )); - } else if (!snapshot.hasData || snapshot.data!.isEmpty) { - return const Center(child: Text('No upcoming classes available.')); - } else { - final plans = snapshot.data!; - return ListView.builder( - scrollDirection: Axis.horizontal, // 가로 스크롤로 변경 - padding: const EdgeInsets.only(left: 16.0, right: 16.0, top: 8.0), - itemCount: plans.length, - itemBuilder: (context, index) { - final plan = plans[index]; - return Align( - alignment: Alignment.topCenter, // 항목을 상단 중앙에 정렬 - child: UpcomingClassCard( - plan: plan, - onTap: () { - widget.onNavigateToPlanTab(1); - }, - ), - ); - }, - ); - } - }, + const Padding( + padding: EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0), // vertical을 위아래 다르게 조정 + child: Text('Upcoming Study', style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), ), - ), - // --- ▼▼▼ Find Your New Course 섹션 ▼▼▼ --- - const Padding( - padding: EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0), - child: Text('Find Your New Course', style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - SizedBox( - height: 175, // 가로 리스트의 높이 - child: FutureBuilder>( - future: _newCoursesFuture, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator()); - } else if (snapshot.hasError) { - return Center(child: Padding( - padding: const EdgeInsets.all(16.0), - child: Text('Error loading new courses: ${snapshot.error}', textAlign: TextAlign.center), - )); - } else if (!snapshot.hasData || snapshot.data!.isEmpty) { - return const Center(child: Text('No new courses available.')); - } else { - final courses = snapshot.data!; - return ListView.builder( - scrollDirection: Axis.horizontal, - padding: const EdgeInsets.only(left: 16.0, right: 16.0, top: 8.0), - itemCount: courses.length, - itemBuilder: (context, index) { - final course = courses[index]; - return CourseCard(course: course,); - }, - ); - } - }, + SizedBox( + height: 200, // 가로 리스트의 높이를 줄입니다. + child: FutureBuilder>( + future: _caseStudyPlans, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Center(child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text('Error loading upcoming classes: ${snapshot.error}', textAlign: TextAlign.center), + )); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return const Center(child: Text('No upcoming classes available.')); + } else { + final plans = snapshot.data!; + return ListView.builder( + scrollDirection: Axis.horizontal, // 가로 스크롤로 변경 + padding: const EdgeInsets.only(left: 16.0, right: 16.0, top: 8.0), + itemCount: plans.length, + itemBuilder: (context, index) { + final plan = plans[index]; + return Align( + alignment: Alignment.topCenter, // 항목을 상단 중앙에 정렬 + child: UpcomingClassCard( + plan: plan, + onTap: () { + widget.onNavigateToPlanTab(1); + }, + ), + ); + }, + ); + } + }, + ), ), - ), - // --- ▲▲▲ Find Your New Course 섹션 끝 ▲▲▲ --- - // --- ▼▼▼ 추천 클래스 섹션 호출 ▼▼▼ --- - // _buildRecommendSection(), - // --- ▲▲▲ 추천 클래스 섹션 호출 끝 ▲▲▲ --- - - ], + // --- ▼▼▼ Find Your New Course 섹션 ▼▼▼ --- + const Padding( + padding: EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0), + child: Text('Find Your New Course', style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + SizedBox( + height: 180, + child: FutureBuilder>( + future: _newCoursesFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Center(child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text('Error loading new courses: ${snapshot.error}', textAlign: TextAlign.center), + )); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return const Center(child: Text('No new courses available.')); + } else { + final courses = snapshot.data!; + return ListView.builder( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.only(left: 16.0, right: 16.0, top: 8.0), + itemCount: courses.length, + itemBuilder: (context, index) { + final course = courses[index]; + return CourseCard(course: course); + }, + ); + } + }, + ), + ), + // --- ▲▲▲ Find Your New Course 섹션 끝 ▲▲▲ --- + // --- ▼▼▼ 추천 클래스 섹션 호출 ▼▼▼ --- + _buildRecommendSection(), + // --- ▲▲▲ 추천 클래스 섹션 호출 끝 ▲▲▲ --- + ], + ), ); } @@ -474,8 +473,8 @@ class _HomePageState extends State { final currentPlan = _recommendPlans[_currentRecommendIndex]; return Container( - margin: const EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 16.0), // 하단 마진 추가 - padding: const EdgeInsets.all(12.0), + margin: const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 0.0), // 하단 마진 추가 + // padding: const EdgeInsets.all(12.0), decoration: BoxDecoration( color: Theme.of(context).cardColor, // 카드 색상 사용 borderRadius: BorderRadius.circular(12.0), @@ -491,26 +490,9 @@ class _HomePageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - '✨ Recommend Classes', // 이모지 추가 - style: Theme.of(context).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), - ), - - const SizedBox(height: 12.0), - - Text( - currentPlan.planName, - style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w500), - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - // Test: Plan ID 표시 (디버깅용) - // Text('ID: ${currentPlan.planId}', style: TextStyle(fontSize: 10, color: Colors.grey)), - AspectRatio( - aspectRatio: 16 / 9, + aspectRatio: 6 / 1, child: ClipRRect( - borderRadius: BorderRadius.circular(8.0), child: currentPlan.thumbnail.isNotEmpty ? Image.network( currentPlan.thumbnail,