Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ close #
## 💬리뷰 요구사항


## 다음 작업 계획
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import 'package:code_l/core/utills/design/app_colors.dart';
import 'package:code_l/core/utills/design/app_gaps.dart';
import 'package:code_l/core/utills/design/app_typography.dart';
import 'package:code_l/sign_up/presentation/pages/profile_introduce/providers.dart';
import 'package:flutter/material.dart';

import '../../widgets/sign_up_app_bar.dart';
import '../../widgets/sign_up_confirm_button.dart';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../profile_image/profile_image_page.dart';
import 'profile_introduce_viewmodel.dart';

class ProfileIntroducePage extends ConsumerWidget {
const ProfileIntroducePage({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final screenHeight = MediaQuery.of(context).size.height;
final state = ref.watch(profileIntroduceProvider);
final notifier = ref.read(profileIntroduceProvider.notifier);

return Scaffold(
appBar: SignUpAppBar(currentPage: 10),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(AppGaps.gap24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: screenHeight * 0.05),
_buildHeaderText(),
SizedBox(height: AppGaps.gap40 + AppGaps.gap40),
_buildCodeNameInputField(state.introduction, notifier),
Spacer(),
ConfirmButton(
enabled: state.isValid,
onPressed:
state.isValid
? () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfileImagePage(),
),
),
}
: null,
),
],
),
),
),
);
}

Widget _buildHeaderText() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

함수분리 좋습니다~!

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("간단하게", style: AppTypography.header1),
Text("나를 소개해주세요", style: AppTypography.header1),
SizedBox(height: AppGaps.gap12),
Text(
"자기소개로 다른 사람에게 나를 어필해보세요!",
style: AppTypography.body2.copyWith(color: AppColors.grey600),
),
],
);
}

Widget _buildCodeNameInputField(
String introduction,
ProfileIntroduceViewmodel notifier,
) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
onChanged: notifier.updateIntroduction,
decoration: InputDecoration(
hintText: '자기소개를 입력해주세요',
hintStyle: AppTypography.header2.copyWith(color: AppColors.grey400),
contentPadding: EdgeInsets.symmetric(vertical: AppGaps.gap8),
border: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.grey400, width: 0.6),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.grey400, width: 0.6),
),
),
),
SizedBox(height: AppGaps.gap4),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(introduction.length.toString(), style: AppTypography.caption3),
Text(
" / 15",
style: AppTypography.caption3.copyWith(color: AppColors.grey500),
),
],
),
],
);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 파일명은 viewmodel인데, 안에는 Notifier로 쓰고 있네요 !
이 부분 통일 하는게 좋을 것 같아요
~notifier와 viewmodel 중 어떤 네이밍을 선호하시나요

Copy link
Collaborator Author

@FLU0RITE FLU0RITE Apr 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 그렇네요!! 뷰모델로 변경하겠습니다!!

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';

class ProfileIntroduceState {
final String introduction;
final bool isValid;

ProfileIntroduceState({
this.introduction = '',
this.isValid = false,
});

ProfileIntroduceState copyWith({
String? introduction,
bool? isValid,
}) {
return ProfileIntroduceState(
introduction: introduction ?? this.introduction,
isValid: isValid ?? this.isValid,
);
}
}

class ProfileIntroduceViewmodel extends StateNotifier<ProfileIntroduceState> {
ProfileIntroduceViewmodel() : super(ProfileIntroduceState());

void updateIntroduction(String introduction) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

state를 갱신하는 로직이 조금 어색하게 느껴져요
isValid로 갱신하려는거면 아래와 같은 방법으로 검증하고 값을 넘겨주는게 어떤가요
final isValid = introduction.isNotEmpty && introduction.length <= 15;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

알려주셔서 감사합니다!!

state = state.copyWith(
introduction: introduction,
isValid: introduction.isNotEmpty && introduction.length <= 15,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:code_l/sign_up/presentation/pages/profile_introduce/profile_introduce_viewmodel.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final profileIntroduceProvider =
StateNotifierProvider<ProfileIntroduceViewmodel, ProfileIntroduceState>(
(ref) => ProfileIntroduceViewmodel());
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:code_l/sign_up/presentation/pages/profile_introduce/profile_introduce_page.dart';
import 'package:code_l/sign_up/presentation/pages/profile_mbti/providers.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
Expand Down Expand Up @@ -34,7 +35,11 @@ class ProfileMBTIPage extends ConsumerWidget {
child: ConfirmButton(
enabled: mbtiState.isValid,
onPressed: () {
// TODO: 다음 페이지 이동 로직
Navigator.push(
context,
MaterialPageRoute(builder:
(context) => ProfileIntroducePage()),
);
},
),
),
Expand Down