From 96e408e15f623e150ccd70b56d2246e7d3d1fc3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=ED=98=95=EC=84=9D?= Date: Fri, 25 Apr 2025 22:46:33 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EC=95=A0=ED=94=8C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 12 ++++++ ios/Runner.xcodeproj/project.pbxproj | 5 +++ ios/Runner/Runner.entitlements | 10 +++++ .../presentation/pages/login/login_page.dart | 33 +++++++++++---- .../pages/login/login_viewmodel.dart | 42 +++++++++++++++++-- lib/main.dart | 2 +- pubspec.lock | 24 +++++++++++ pubspec.yaml | 1 + 8 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 ios/Runner/Runner.entitlements diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0079ea1..70d1b84 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,18 @@ android:label="code_l" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> + + + + + + + + + + + + + + com.apple.developer.applesignin + + Default + + + diff --git a/lib/auth/presentation/pages/login/login_page.dart b/lib/auth/presentation/pages/login/login_page.dart index 7c4a875..bffead7 100644 --- a/lib/auth/presentation/pages/login/login_page.dart +++ b/lib/auth/presentation/pages/login/login_page.dart @@ -19,7 +19,7 @@ class LoginPage extends ConsumerWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ Flexible( - flex: 4, + flex: 3, child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ @@ -32,11 +32,22 @@ class LoginPage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text("코드가 맞는 우리만의", style: AppTypography.body1), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text("공간에서 시작되는 ", style: AppTypography.body1), + Text( + "코드가 맞는 우리만의 공간", + style: AppTypography.subtitle2.copyWith( + color: AppColors.primary, + ), + ), + Text(" 에서", style: AppTypography.body1), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text("시작되는 ", style: AppTypography.body1), Text("진짜 인연", style: AppTypography.subtitle1), ], ), @@ -88,12 +99,7 @@ class LoginPage extends ConsumerWidget { side: const BorderSide(color: AppColors.black), ), onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const LoginPage(), - ), - ); + ref.read(loginViewModelProvider).loginWithApple(); }, child: Padding( padding: const EdgeInsets.all(AppGaps.gap16), @@ -116,6 +122,15 @@ class LoginPage extends ConsumerWidget { ], ), ), + Flexible( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text("레즈비언", style: AppTypography.subtitle2), + Text("을 위한 더 깊이있는 매칭앱", style: AppTypography.body1), + ], + ), + ), ], ), ), diff --git a/lib/auth/presentation/pages/login/login_viewmodel.dart b/lib/auth/presentation/pages/login/login_viewmodel.dart index 830484f..896e9f5 100644 --- a/lib/auth/presentation/pages/login/login_viewmodel.dart +++ b/lib/auth/presentation/pages/login/login_viewmodel.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:code_l/auth/domain/model/login_type.dart'; import 'package:flutter/cupertino.dart'; import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart'; +import 'package:sign_in_with_apple/sign_in_with_apple.dart'; import '../../../domain/usecases/login_usecase.dart'; @@ -15,10 +16,9 @@ class LoginViewModel extends ChangeNotifier { try { bool installed = await isKakaoTalkInstalled(); - OAuthToken token = - installed - ? await UserApi.instance.loginWithKakaoTalk() - : await UserApi.instance.loginWithKakaoAccount(); + OAuthToken token = installed + ? await UserApi.instance.loginWithKakaoTalk() + : await UserApi.instance.loginWithKakaoAccount(); final user = await UserApi.instance.me(); @@ -38,4 +38,38 @@ class LoginViewModel extends ChangeNotifier { log(name: 'LoginViewModel::loginOauth', 'error: $e'); } } + + Future loginWithApple() async { + try { + // 애플 인증 정보 가져오기 + final AuthorizationCredentialAppleID credential = + await SignInWithApple.getAppleIDCredential( + scopes: [ + AppleIDAuthorizationScopes.email, + AppleIDAuthorizationScopes.fullName, + ], + webAuthenticationOptions: WebAuthenticationOptions( + clientId: "codel.codel.com", // Apple Developer Console에 등록된 clientId + redirectUri: Uri.parse( + "https://chartreuse-gratis-lungfish.glitch.me/callbacks/sign_in_with_apple", + ), + ), + ); + + // authorizationCode와 identityToken 확인 + final authorizationCode = credential.authorizationCode; + final identityToken = credential.identityToken; + + if (authorizationCode == null || identityToken == null) { + throw Exception("Authorization Code 또는 Identity Token을 가져오지 못했습니다."); + } + + // 백엔드로 OAuth 인증 요청 + await loginOauth(LoginType.apple, identityToken); + + log(name: 'LoginViewModel::loginWithApple', 'success: $identityToken'); + } catch (e) { + log(name: 'LoginViewModel::loginWithApple', 'error: $e'); + } + } } diff --git a/lib/main.dart b/lib/main.dart index c30236d..1fb6a0b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -27,7 +27,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: 'Kakao Login Demo', - home: const ProfileInterestPage(), + home: const LoginPage(), theme: ThemeData( primarySwatch: Colors.blue, scaffoldBackgroundColor: Colors.white, diff --git a/pubspec.lock b/pubspec.lock index 3f6ba92..cffe782 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -584,6 +584,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.1" + sign_in_with_apple: + dependency: "direct main" + description: + name: sign_in_with_apple + sha256: "8bd875c8e8748272749eb6d25b896f768e7e9d60988446d543fe85a37a2392b8" + url: "https://pub.dev" + source: hosted + version: "7.0.1" + sign_in_with_apple_platform_interface: + dependency: transitive + description: + name: sign_in_with_apple_platform_interface + sha256: "981bca52cf3bb9c3ad7ef44aace2d543e5c468bb713fd8dda4275ff76dfa6659" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + sign_in_with_apple_web: + dependency: transitive + description: + name: sign_in_with_apple_web + sha256: f316400827f52cafcf50d00e1a2e8a0abc534ca1264e856a81c5f06bd5b10fed + url: "https://pub.dev" + source: hosted + version: "3.0.0" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index d867a8a..a052e9a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: kakao_flutter_sdk_user: ^1.9.7+3 flutter_dotenv: ^5.2.1 screen_protector: ^1.4.2+1 + sign_in_with_apple: ^7.0.1 dev_dependencies: flutter_test: From 65faa0020297c1a9c2114869889541da65fc7446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=ED=98=95=EC=84=9D?= Date: Sat, 26 Apr 2025 00:34:58 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=EA=B8=B0=EB=8A=A5=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20dart=20format=20=EC=8B=A4=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../remote/login_remote_datasource.dart | 18 ++++ .../default_login_repository.dart | 5 +- .../domain/repositories/login_repository.dart | 3 +- lib/auth/domain/usecases/login_usecase.dart | 14 +-- .../congratulation/congratulation_page.dart | 1 - .../pages/login/login_viewmodel.dart | 26 ++--- .../terms_and_condition_page.dart | 28 +++--- .../pages/woman/woman_verification_Page.dart | 14 ++- .../pages/code_job/code_job_page.dart | 75 +++++++------- .../code_lifestyle_drink_page.dart | 19 ++-- .../code_lifestyle_smoke_page.dart | 18 ++-- .../pages/profile_area/profile_area_page.dart | 98 +++++++++---------- .../profile_intereset_page.dart | 14 ++- .../profile_lovestyle_page.dart | 1 - .../pages/profile_mbti/profile_mbti_page.dart | 81 +++++++-------- .../pages/profile_mbti/providers.dart | 4 +- 16 files changed, 202 insertions(+), 217 deletions(-) diff --git a/lib/auth/data/datasources/remote/login_remote_datasource.dart b/lib/auth/data/datasources/remote/login_remote_datasource.dart index e710c19..c1deaf0 100644 --- a/lib/auth/data/datasources/remote/login_remote_datasource.dart +++ b/lib/auth/data/datasources/remote/login_remote_datasource.dart @@ -1,4 +1,5 @@ import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart'; +import 'package:sign_in_with_apple/sign_in_with_apple.dart'; class LoginRemoteDataSource { Future loginWithKakao() async { @@ -12,4 +13,21 @@ class LoginRemoteDataSource { return await UserApi.instance.me(); } + + Future loginWithApple() async { + final AuthorizationCredentialAppleID credential = + await SignInWithApple.getAppleIDCredential( + scopes: [ + AppleIDAuthorizationScopes.email, + AppleIDAuthorizationScopes.fullName, + ], + webAuthenticationOptions: WebAuthenticationOptions( + clientId: "codel.codel.com", // Apple Developer Console에 등록된 clientId + redirectUri: Uri.parse( + "https://chartreuse-gratis-lungfish.glitch.me/callbacks/sign_in_with_apple", + ), + ), + ); + return credential; + } } diff --git a/lib/auth/data/repositories/default_login_repository.dart b/lib/auth/data/repositories/default_login_repository.dart index 5a5034c..b07e1cc 100644 --- a/lib/auth/data/repositories/default_login_repository.dart +++ b/lib/auth/data/repositories/default_login_repository.dart @@ -1,5 +1,6 @@ import 'package:code_l/auth/domain/repositories/login_repository.dart'; import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart'; +import 'package:sign_in_with_apple/sign_in_with_apple.dart'; import '../datasources/remote/auth_remote_datasource.dart'; import '../datasources/remote/login_remote_datasource.dart'; @@ -19,8 +20,8 @@ class DefaultLoginRepository implements LoginRepository { } @override - Future loginWithApple() { - throw UnimplementedError(); + Future loginWithApple() { + throw loginRemoteDataSource.loginWithApple(); } @override diff --git a/lib/auth/domain/repositories/login_repository.dart b/lib/auth/domain/repositories/login_repository.dart index 1ca0adb..fa76f39 100644 --- a/lib/auth/domain/repositories/login_repository.dart +++ b/lib/auth/domain/repositories/login_repository.dart @@ -1,7 +1,8 @@ import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart'; +import 'package:sign_in_with_apple/sign_in_with_apple.dart'; abstract class LoginRepository { Future loginOauth(String type, String id); Future loginWithKakao(); - Future loginWithApple(); + Future loginWithApple(); } diff --git a/lib/auth/domain/usecases/login_usecase.dart b/lib/auth/domain/usecases/login_usecase.dart index 4f755b4..3203eb9 100644 --- a/lib/auth/domain/usecases/login_usecase.dart +++ b/lib/auth/domain/usecases/login_usecase.dart @@ -1,18 +1,18 @@ import 'package:code_l/auth/domain/model/login_type.dart'; import 'package:code_l/auth/domain/repositories/login_repository.dart'; import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart'; +import 'package:sign_in_with_apple/sign_in_with_apple.dart'; class LoginUseCase { final LoginRepository repository; LoginUseCase(this.repository); - Future call(LoginType type) async { - switch (type) { - case LoginType.kakao: - return await repository.loginWithKakao(); - case LoginType.apple: - return await repository.loginWithApple(); - } + Future callKakaoLogin(LoginType type) async { + return await repository.loginWithKakao(); + } + + Future callAppleLogin(LoginType type) async { + return await repository.loginWithApple(); } Future callOauth(LoginType type, String id) async { diff --git a/lib/auth/presentation/pages/congratulation/congratulation_page.dart b/lib/auth/presentation/pages/congratulation/congratulation_page.dart index 86e1ffc..a31ea27 100644 --- a/lib/auth/presentation/pages/congratulation/congratulation_page.dart +++ b/lib/auth/presentation/pages/congratulation/congratulation_page.dart @@ -100,7 +100,6 @@ class CongratulationPage extends StatelessWidget { height: 40, ), ), - Padding( padding: const EdgeInsets.all(AppGaps.gap4), child: CongratulationConfirmButton( diff --git a/lib/auth/presentation/pages/login/login_viewmodel.dart b/lib/auth/presentation/pages/login/login_viewmodel.dart index 896e9f5..4a33a4a 100644 --- a/lib/auth/presentation/pages/login/login_viewmodel.dart +++ b/lib/auth/presentation/pages/login/login_viewmodel.dart @@ -42,32 +42,22 @@ class LoginViewModel extends ChangeNotifier { Future loginWithApple() async { try { // 애플 인증 정보 가져오기 - final AuthorizationCredentialAppleID credential = - await SignInWithApple.getAppleIDCredential( - scopes: [ - AppleIDAuthorizationScopes.email, - AppleIDAuthorizationScopes.fullName, - ], - webAuthenticationOptions: WebAuthenticationOptions( - clientId: "codel.codel.com", // Apple Developer Console에 등록된 clientId - redirectUri: Uri.parse( - "https://chartreuse-gratis-lungfish.glitch.me/callbacks/sign_in_with_apple", - ), - ), - ); - + final credential = useCase.callAppleLogin(LoginType.apple); // authorizationCode와 identityToken 확인 - final authorizationCode = credential.authorizationCode; - final identityToken = credential.identityToken; + final authorizationCode = + credential.then((value) => value.authorizationCode); + final identityToken = credential.then((value) => value.identityToken); if (authorizationCode == null || identityToken == null) { throw Exception("Authorization Code 또는 Identity Token을 가져오지 못했습니다."); } // 백엔드로 OAuth 인증 요청 - await loginOauth(LoginType.apple, identityToken); + await loginOauth(LoginType.apple, identityToken.toString()); - log(name: 'LoginViewModel::loginWithApple', 'success: $identityToken'); + log( + name: 'LoginViewModel::loginWithApple', + 'success: ${identityToken.toString()}'); } catch (e) { log(name: 'LoginViewModel::loginWithApple', 'error: $e'); } diff --git a/lib/auth/presentation/pages/terms_and_conditions/terms_and_condition_page.dart b/lib/auth/presentation/pages/terms_and_conditions/terms_and_condition_page.dart index 4c8c842..87332b0 100644 --- a/lib/auth/presentation/pages/terms_and_conditions/terms_and_condition_page.dart +++ b/lib/auth/presentation/pages/terms_and_conditions/terms_and_condition_page.dart @@ -73,10 +73,9 @@ class TermsAndConditionPage extends ConsumerWidget { Text( "모두 동의합니다.", style: AppTypography.subtitle2.copyWith( - color: - viewmodel.checkState[0] - ? AppColors.grey900 - : AppColors.grey500, + color: viewmodel.checkState[0] + ? AppColors.grey900 + : AppColors.grey500, ), ), IconButton( @@ -84,10 +83,9 @@ class TermsAndConditionPage extends ConsumerWidget { iconSize: 36, icon: Icon( Icons.check_circle_outline, - color: - viewmodel.checkState[0] - ? AppColors.grey900 - : AppColors.grey500, + color: viewmodel.checkState[0] + ? AppColors.grey900 + : AppColors.grey500, ), ), ], @@ -104,10 +102,9 @@ class TermsAndConditionPage extends ConsumerWidget { getLabel(i), style: AppTypography.body2.copyWith( decoration: TextDecoration.underline, - color: - viewmodel.checkState[i] - ? AppColors.grey900 - : AppColors.grey500, + color: viewmodel.checkState[i] + ? AppColors.grey900 + : AppColors.grey500, ), ), ), @@ -116,10 +113,9 @@ class TermsAndConditionPage extends ConsumerWidget { iconSize: 24, icon: Icon( Icons.check, - color: - viewmodel.checkState[i] - ? AppColors.grey900 - : AppColors.grey500, + color: viewmodel.checkState[i] + ? AppColors.grey900 + : AppColors.grey500, ), ), ], diff --git a/lib/auth/presentation/pages/woman/woman_verification_Page.dart b/lib/auth/presentation/pages/woman/woman_verification_Page.dart index 9b45753..44cf916 100644 --- a/lib/auth/presentation/pages/woman/woman_verification_Page.dart +++ b/lib/auth/presentation/pages/woman/woman_verification_Page.dart @@ -130,10 +130,9 @@ class WomanVerificationPage extends ConsumerWidget { Text( "위 안내사항을 모두 확인하였습니다.", style: AppTypography.subtitle2.copyWith( - color: - viewModel.isChecked - ? AppColors.grey800 - : AppColors.grey400, + color: viewModel.isChecked + ? AppColors.grey800 + : AppColors.grey400, ), ), IconButton( @@ -142,10 +141,9 @@ class WomanVerificationPage extends ConsumerWidget { }, icon: Icon( Icons.check_circle_outline, - color: - viewModel.isChecked - ? AppColors.grey800 - : AppColors.grey400, + color: viewModel.isChecked + ? AppColors.grey800 + : AppColors.grey400, ), ), ], diff --git a/lib/sign_up/presentation/pages/code_job/code_job_page.dart b/lib/sign_up/presentation/pages/code_job/code_job_page.dart index fcfa1b4..7fd1d29 100644 --- a/lib/sign_up/presentation/pages/code_job/code_job_page.dart +++ b/lib/sign_up/presentation/pages/code_job/code_job_page.dart @@ -63,47 +63,44 @@ class _JobSelectionPageState extends ConsumerState { mainAxisSpacing: 12, crossAxisSpacing: 12, childAspectRatio: 1.1, - children: - jobList.map((job) { - final isSelected = selectedJob == job['label']; - return GestureDetector( - onTap: () { - setState(() => selectedJob = job['label']); - }, - child: Container( - decoration: BoxDecoration( - color: - isSelected - ? AppColors.primaryLight - : AppColors.grey100, - border: Border.all( - color: - isSelected - ? AppColors.primary - : AppColors.grey100, - width: 1.5, - ), - borderRadius: BorderRadius.circular(8), + children: jobList.map((job) { + final isSelected = selectedJob == job['label']; + return GestureDetector( + onTap: () { + setState(() => selectedJob = job['label']); + }, + child: Container( + decoration: BoxDecoration( + color: isSelected + ? AppColors.primaryLight + : AppColors.grey100, + border: Border.all( + color: isSelected + ? AppColors.primary + : AppColors.grey100, + width: 1.5, + ), + borderRadius: BorderRadius.circular(8), + ), + padding: EdgeInsets.symmetric(vertical: 16), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + job['image']!, + width: 16, + height: 22, ), - padding: EdgeInsets.symmetric(vertical: 16), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - job['image']!, - width: 16, - height: 22, - ), - SizedBox(height: AppGaps.gap4), - Text( - job['label'] ?? '', - style: AppTypography.body2, - ), - ], + SizedBox(height: AppGaps.gap4), + Text( + job['label'] ?? '', + style: AppTypography.body2, ), - ), - ); - }).toList(), + ], + ), + ), + ); + }).toList(), ), ), ], diff --git a/lib/sign_up/presentation/pages/code_lifestyle/code_lifestyle_drink_page.dart b/lib/sign_up/presentation/pages/code_lifestyle/code_lifestyle_drink_page.dart index 76147d2..13b66d8 100644 --- a/lib/sign_up/presentation/pages/code_lifestyle/code_lifestyle_drink_page.dart +++ b/lib/sign_up/presentation/pages/code_lifestyle/code_lifestyle_drink_page.dart @@ -52,12 +52,11 @@ class _CodeLifestyleDrinkPageState extends State { style: AppTypography.body2.copyWith(color: AppColors.grey600), ), SizedBox(height: AppGaps.gap40), - Expanded( child: ListView.separated( itemCount: drinkOptions.length, - separatorBuilder: - (_, __) => const SizedBox(height: AppGaps.gap16), + separatorBuilder: (_, __) => + const SizedBox(height: AppGaps.gap16), itemBuilder: (context, index) { final item = drinkOptions[index]; final isSelected = selectedIndex == index; @@ -75,15 +74,13 @@ class _CodeLifestyleDrinkPageState extends State { ), decoration: BoxDecoration( border: Border.all( - color: - isSelected - ? AppColors.primary - : AppColors.grey400, + color: isSelected + ? AppColors.primary + : AppColors.grey400, ), - color: - isSelected - ? AppColors.primaryLight - : AppColors.white, + color: isSelected + ? AppColors.primaryLight + : AppColors.white, ), child: Row( children: [ diff --git a/lib/sign_up/presentation/pages/code_lifestyle/code_lifestyle_smoke_page.dart b/lib/sign_up/presentation/pages/code_lifestyle/code_lifestyle_smoke_page.dart index 2ed14aa..5f9a069 100644 --- a/lib/sign_up/presentation/pages/code_lifestyle/code_lifestyle_smoke_page.dart +++ b/lib/sign_up/presentation/pages/code_lifestyle/code_lifestyle_smoke_page.dart @@ -63,8 +63,8 @@ class _CodeLifestyleDrinkPageState extends State { Expanded( child: ListView.separated( itemCount: drinkOptions.length, - separatorBuilder: - (_, __) => const SizedBox(height: AppGaps.gap16), + separatorBuilder: (_, __) => + const SizedBox(height: AppGaps.gap16), itemBuilder: (context, index) { final item = drinkOptions[index]; final isSelected = selectedIndex == index; @@ -82,15 +82,13 @@ class _CodeLifestyleDrinkPageState extends State { ), decoration: BoxDecoration( border: Border.all( - color: - isSelected - ? AppColors.primary - : AppColors.grey400, + color: isSelected + ? AppColors.primary + : AppColors.grey400, ), - color: - isSelected - ? AppColors.primaryLight - : AppColors.white, + color: isSelected + ? AppColors.primaryLight + : AppColors.white, ), child: Row( children: [ diff --git a/lib/sign_up/presentation/pages/profile_area/profile_area_page.dart b/lib/sign_up/presentation/pages/profile_area/profile_area_page.dart index cc4556e..43a082f 100644 --- a/lib/sign_up/presentation/pages/profile_area/profile_area_page.dart +++ b/lib/sign_up/presentation/pages/profile_area/profile_area_page.dart @@ -356,58 +356,56 @@ class _ProfileRegionPageState extends State { ), SizedBox(width: AppGaps.gap20), Expanded( - child: - selectedMainRegionIndex == null - ? const SizedBox.shrink() - : ListView.builder( - itemCount: - subRegions[mainRegions[selectedMainRegionIndex!]]! - .length, - itemBuilder: (context, index) { - final subRegionName = - subRegions[mainRegions[selectedMainRegionIndex!]]![index]; - final isSelected = - selectedSubRegionIndex == index; - return GestureDetector( - onTap: () { - setState(() { - selectedSubRegionIndex = index; - }); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 16, - horizontal: 8, - ), - decoration: BoxDecoration( - color: Colors.transparent, - borderRadius: BorderRadius.circular(8), - ), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Text( - subRegionName, - style: AppTypography.body1.copyWith( - color: - isSelected - ? AppColors.primary - : AppColors.grey900, - ), + child: selectedMainRegionIndex == null + ? const SizedBox.shrink() + : ListView.builder( + itemCount: subRegions[ + mainRegions[selectedMainRegionIndex!]]! + .length, + itemBuilder: (context, index) { + final subRegionName = subRegions[mainRegions[ + selectedMainRegionIndex!]]![index]; + final isSelected = + selectedSubRegionIndex == index; + return GestureDetector( + onTap: () { + setState(() { + selectedSubRegionIndex = index; + }); + }, + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 16, + horizontal: 8, + ), + decoration: BoxDecoration( + color: Colors.transparent, + borderRadius: BorderRadius.circular(8), + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + subRegionName, + style: AppTypography.body1.copyWith( + color: isSelected + ? AppColors.primary + : AppColors.grey900, + ), + ), + if (isSelected) + const Icon( + Icons.check, + color: AppColors.primary, + size: 20, ), - if (isSelected) - const Icon( - Icons.check, - color: AppColors.primary, - size: 20, - ), - ], - ), + ], ), - ); - }, - ), + ), + ); + }, + ), ), ], ), diff --git a/lib/sign_up/presentation/pages/profile_interest/profile_intereset_page.dart b/lib/sign_up/presentation/pages/profile_interest/profile_intereset_page.dart index 99b0f5f..a7a3d42 100644 --- a/lib/sign_up/presentation/pages/profile_interest/profile_intereset_page.dart +++ b/lib/sign_up/presentation/pages/profile_interest/profile_intereset_page.dart @@ -109,15 +109,13 @@ class _ProfileInterestPageState extends State { ), decoration: BoxDecoration( border: Border.all( - color: - isSelected - ? AppColors.primary - : AppColors.grey400, + color: isSelected + ? AppColors.primary + : AppColors.grey400, ), - color: - isSelected - ? AppColors.primaryLight - : AppColors.white, + color: isSelected + ? AppColors.primaryLight + : AppColors.white, borderRadius: BorderRadius.circular(100), ), child: Text( diff --git a/lib/sign_up/presentation/pages/profile_lovestyle/profile_lovestyle_page.dart b/lib/sign_up/presentation/pages/profile_lovestyle/profile_lovestyle_page.dart index 0a9a834..0ed62f7 100644 --- a/lib/sign_up/presentation/pages/profile_lovestyle/profile_lovestyle_page.dart +++ b/lib/sign_up/presentation/pages/profile_lovestyle/profile_lovestyle_page.dart @@ -161,7 +161,6 @@ class _ProfileLoveStylePageState extends State { }, ), ), - SizedBox(height: AppGaps.gap32), Text("갈등 해결", style: AppTypography.subtitle1), SizedBox(height: AppGaps.gap12), diff --git a/lib/sign_up/presentation/pages/profile_mbti/profile_mbti_page.dart b/lib/sign_up/presentation/pages/profile_mbti/profile_mbti_page.dart index 7b8a276..a1342ca 100644 --- a/lib/sign_up/presentation/pages/profile_mbti/profile_mbti_page.dart +++ b/lib/sign_up/presentation/pages/profile_mbti/profile_mbti_page.dart @@ -48,7 +48,6 @@ class ProfileMBTIPage extends ConsumerWidget { SizedBox(height: screenHeight * 0.05), Text("MBTI를\n선택해주세요", style: AppTypography.header1), const SizedBox(height: AppGaps.gap40), - ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), @@ -58,54 +57,50 @@ class ProfileMBTIPage extends ConsumerWidget { return Padding( padding: const EdgeInsets.only(bottom: AppGaps.gap20), child: Row( - children: - group.map((option) { - final isSelected = viewModel.isSelected( - groupIndex, - option, - ); - return Expanded( - child: Padding( + children: group.map((option) { + final isSelected = viewModel.isSelected( + groupIndex, + option, + ); + return Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 6, + ), + child: GestureDetector( + onTap: () => viewModel.select( + groupIndex, + option, + ), + child: Container( padding: const EdgeInsets.symmetric( - horizontal: 6, + horizontal: 74, + vertical: 34, ), - child: GestureDetector( - onTap: - () => viewModel.select( - groupIndex, - option, - ), - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 74, - vertical: 34, - ), - decoration: BoxDecoration( - color: - isSelected - ? AppColors.primaryLight - : AppColors.grey100, - border: Border.all( - color: - isSelected - ? AppColors.primary - : AppColors.grey100, - ), - borderRadius: BorderRadius.circular(8), - ), - child: Center( - child: Text( - option, - style: AppTypography.body1.copyWith( - color: AppColors.grey900, - ), - ), + decoration: BoxDecoration( + color: isSelected + ? AppColors.primaryLight + : AppColors.grey100, + border: Border.all( + color: isSelected + ? AppColors.primary + : AppColors.grey100, + ), + borderRadius: BorderRadius.circular(8), + ), + child: Center( + child: Text( + option, + style: AppTypography.body1.copyWith( + color: AppColors.grey900, ), ), ), ), - ); - }).toList(), + ), + ), + ); + }).toList(), ), ); }, diff --git a/lib/sign_up/presentation/pages/profile_mbti/providers.dart b/lib/sign_up/presentation/pages/profile_mbti/providers.dart index 90f47cd..9159df2 100644 --- a/lib/sign_up/presentation/pages/profile_mbti/providers.dart +++ b/lib/sign_up/presentation/pages/profile_mbti/providers.dart @@ -5,5 +5,5 @@ import '../../../domain/model/profile_mbti/profile_mbti_state.dart'; final profileMBTIProvider = StateNotifierProvider( - (ref) => ProfileMBTIViewModel(), - ); + (ref) => ProfileMBTIViewModel(), +);