Skip to content

Commit 79bb2f4

Browse files
authored
Merge pull request #30 from CODE-LG/ui/sign_up_profile_mbti
코드 프로필 작성페이지 (MBTI)
2 parents bffdc1c + c8514bf commit 79bb2f4

4 files changed

Lines changed: 172 additions & 0 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class MBTIState {
2+
final String? ei, ns, tf, pj;
3+
4+
const MBTIState({this.ei, this.ns, this.tf, this.pj});
5+
6+
MBTIState copyWith({String? ei, String? ns, String? tf, String? pj}) {
7+
return MBTIState(
8+
ei: ei ?? this.ei,
9+
ns: ns ?? this.ns,
10+
tf: tf ?? this.tf,
11+
pj: pj ?? this.pj,
12+
);
13+
}
14+
15+
bool get isValid => ei != null && ns != null && tf != null && pj != null;
16+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import 'package:code_l/sign_up/presentation/pages/profile_mbti/providers.dart';
2+
import 'package:flutter/material.dart';
3+
import 'package:flutter_riverpod/flutter_riverpod.dart';
4+
5+
import '../../../../core/utills/design/app_colors.dart';
6+
import '../../../../core/utills/design/app_gaps.dart';
7+
import '../../../../core/utills/design/app_typography.dart';
8+
import '../../widgets/sign_up_app_bar.dart';
9+
import '../../widgets/sign_up_confirm_button.dart';
10+
11+
class ProfileMBTIPage extends ConsumerWidget {
12+
const ProfileMBTIPage({super.key});
13+
14+
final mbtiOptions = const [
15+
['E', 'I'],
16+
['N', 'S'],
17+
['T', 'F'],
18+
['P', 'J'],
19+
];
20+
21+
@override
22+
Widget build(BuildContext context, WidgetRef ref) {
23+
final screenHeight = MediaQuery.of(context).size.height;
24+
final mbtiState = ref.watch(profileMBTIProvider);
25+
final viewModel = ref.read(profileMBTIProvider.notifier);
26+
27+
return Scaffold(
28+
appBar: const SignUpAppBar(),
29+
bottomNavigationBar: Padding(
30+
padding: const EdgeInsets.symmetric(
31+
horizontal: AppGaps.gap20,
32+
vertical: 34,
33+
),
34+
child: ConfirmButton(
35+
enabled: mbtiState.isValid,
36+
onPressed: () {
37+
// TODO: 다음 페이지 이동 로직
38+
},
39+
),
40+
),
41+
body: SafeArea(
42+
child: Padding(
43+
padding: const EdgeInsets.symmetric(horizontal: AppGaps.gap20),
44+
child: SingleChildScrollView(
45+
child: Column(
46+
crossAxisAlignment: CrossAxisAlignment.start,
47+
children: [
48+
SizedBox(height: screenHeight * 0.05),
49+
Text("MBTI를\n선택해주세요", style: AppTypography.header1),
50+
const SizedBox(height: AppGaps.gap40),
51+
52+
ListView.builder(
53+
shrinkWrap: true,
54+
physics: const NeverScrollableScrollPhysics(),
55+
itemCount: mbtiOptions.length,
56+
itemBuilder: (context, groupIndex) {
57+
final group = mbtiOptions[groupIndex];
58+
return Padding(
59+
padding: const EdgeInsets.only(bottom: AppGaps.gap20),
60+
child: Row(
61+
children:
62+
group.map((option) {
63+
final isSelected = viewModel.isSelected(
64+
groupIndex,
65+
option,
66+
);
67+
return Expanded(
68+
child: Padding(
69+
padding: const EdgeInsets.symmetric(
70+
horizontal: 6,
71+
),
72+
child: GestureDetector(
73+
onTap:
74+
() => viewModel.select(
75+
groupIndex,
76+
option,
77+
),
78+
child: Container(
79+
padding: const EdgeInsets.symmetric(
80+
horizontal: 74,
81+
vertical: 34,
82+
),
83+
decoration: BoxDecoration(
84+
color:
85+
isSelected
86+
? AppColors.primaryLight
87+
: AppColors.grey100,
88+
border: Border.all(
89+
color:
90+
isSelected
91+
? AppColors.primary
92+
: AppColors.grey100,
93+
),
94+
borderRadius: BorderRadius.circular(8),
95+
),
96+
child: Center(
97+
child: Text(
98+
option,
99+
style: AppTypography.body1.copyWith(
100+
color: AppColors.grey900,
101+
),
102+
),
103+
),
104+
),
105+
),
106+
),
107+
);
108+
}).toList(),
109+
),
110+
);
111+
},
112+
),
113+
],
114+
),
115+
),
116+
),
117+
),
118+
);
119+
}
120+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import 'package:flutter_riverpod/flutter_riverpod.dart';
2+
3+
import '../../../domain/model/profile_mbti/profile_mbti_state.dart';
4+
5+
class ProfileMBTIViewModel extends StateNotifier<MBTIState> {
6+
ProfileMBTIViewModel() : super(const MBTIState());
7+
8+
void select(int groupIndex, String value) {
9+
state = switch (groupIndex) {
10+
0 => state.copyWith(ei: value),
11+
1 => state.copyWith(ns: value),
12+
2 => state.copyWith(tf: value),
13+
3 => state.copyWith(pj: value),
14+
_ => state,
15+
};
16+
}
17+
18+
bool isSelected(int groupIndex, String value) {
19+
return switch (groupIndex) {
20+
0 => state.ei == value,
21+
1 => state.ns == value,
22+
2 => state.tf == value,
23+
3 => state.pj == value,
24+
_ => false,
25+
};
26+
}
27+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import 'package:code_l/sign_up/presentation/pages/profile_mbti/profile_mbti_viewmodel.dart';
2+
import 'package:flutter_riverpod/flutter_riverpod.dart';
3+
4+
import '../../../domain/model/profile_mbti/profile_mbti_state.dart';
5+
6+
final profileMBTIProvider =
7+
StateNotifierProvider<ProfileMBTIViewModel, MBTIState>(
8+
(ref) => ProfileMBTIViewModel(),
9+
);

0 commit comments

Comments
 (0)