-
Notifications
You must be signed in to change notification settings - Fork 0
feat: 마이페이지 화면 구현 완료 #55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5edbccb
90dbe65
a4b794c
97983e9
e927d5a
86e5b0f
371a714
a5a6024
de6ac3d
c58f171
236a798
a82edc4
5193530
fbb9b29
e437104
631b716
a6c38fc
d85e155
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,185 @@ | ||||||||||||||||||||||||||||||||||
| import 'package:flutter/material.dart'; | ||||||||||||||||||||||||||||||||||
| import 'package:ongi/core/app_colors.dart'; | ||||||||||||||||||||||||||||||||||
| import 'package:ongi/utils/prefs_manager.dart'; | ||||||||||||||||||||||||||||||||||
| import 'package:flutter/services.dart'; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| class Myinfo extends StatelessWidget { | ||||||||||||||||||||||||||||||||||
| const Myinfo({Key? key}) : super(key: key); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @override | ||||||||||||||||||||||||||||||||||
| Widget build(BuildContext context) { | ||||||||||||||||||||||||||||||||||
| final screenWidth = MediaQuery.of(context).size.width; | ||||||||||||||||||||||||||||||||||
| final screenHeight = MediaQuery.of(context).size.height; | ||||||||||||||||||||||||||||||||||
| return FutureBuilder<Map<String, String?>> ( | ||||||||||||||||||||||||||||||||||
| future: PrefsManager.getUserInfo(), | ||||||||||||||||||||||||||||||||||
| builder: (context, snapshot) { | ||||||||||||||||||||||||||||||||||
| if (snapshot.connectionState == ConnectionState.waiting) { | ||||||||||||||||||||||||||||||||||
| return const Center(child: CircularProgressIndicator()); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| if (snapshot.hasError) { | ||||||||||||||||||||||||||||||||||
| return Center(child: Text('에러: \\${snapshot.error}', style: TextStyle(color: Colors.red))); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| final userInfo = snapshot.data ?? {}; | ||||||||||||||||||||||||||||||||||
| final name = userInfo['name'] ?? '사용자님'; | ||||||||||||||||||||||||||||||||||
| final familycode = userInfo['familycode'] ?? '33HYF6'; | ||||||||||||||||||||||||||||||||||
| final familyName = userInfo['familyName'] ?? '가족이름'; | ||||||||||||||||||||||||||||||||||
| final profileImage = userInfo['profileImage'] ?? 'assets/images/users/elderly_woman.png'; | ||||||||||||||||||||||||||||||||||
| final isParent = userInfo['isParent'] == 'true'; | ||||||||||||||||||||||||||||||||||
| final roleText = isParent ? '부모' : '자녀'; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return Padding( | ||||||||||||||||||||||||||||||||||
| padding: EdgeInsets.symmetric( | ||||||||||||||||||||||||||||||||||
| horizontal: screenWidth * 0.05, // 32/375 | ||||||||||||||||||||||||||||||||||
| vertical: screenHeight * 0.02, // 16/812 | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| child: Row( | ||||||||||||||||||||||||||||||||||
| crossAxisAlignment: CrossAxisAlignment.start, | ||||||||||||||||||||||||||||||||||
| children: [ | ||||||||||||||||||||||||||||||||||
| // 프로필 이미지 | ||||||||||||||||||||||||||||||||||
| ClipOval( | ||||||||||||||||||||||||||||||||||
| child: Image.asset( | ||||||||||||||||||||||||||||||||||
| profileImage, | ||||||||||||||||||||||||||||||||||
| width: screenWidth * 0.3, // 112/375 | ||||||||||||||||||||||||||||||||||
| height: screenWidth * 0.4, // 160/375 | ||||||||||||||||||||||||||||||||||
| fit: BoxFit.contain, | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+39
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 프로필 이미지의 가로세로 비율이 일치하지 않습니다. ClipOval을 사용하면서 width와 height가 다른 비율(0.3 vs 0.4)로 설정되어 있어 이미지가 왜곡될 수 있습니다. 정사각형으로 수정하세요: ClipOval(
child: Image.asset(
profileImage,
- width: screenWidth * 0.3, // 112/375
- height: screenWidth * 0.4, // 160/375
+ width: screenWidth * 0.3, // 112/375
+ height: screenWidth * 0.3, // 112/375 (정사각형)
fit: BoxFit.contain,
),
),📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| SizedBox(width: screenWidth * 0.0053), | ||||||||||||||||||||||||||||||||||
| // 오른쪽 정보들 | ||||||||||||||||||||||||||||||||||
| Expanded( | ||||||||||||||||||||||||||||||||||
| child: Column( | ||||||||||||||||||||||||||||||||||
| crossAxisAlignment: CrossAxisAlignment.start, | ||||||||||||||||||||||||||||||||||
| children: [ | ||||||||||||||||||||||||||||||||||
| Row( | ||||||||||||||||||||||||||||||||||
| crossAxisAlignment: CrossAxisAlignment.center, | ||||||||||||||||||||||||||||||||||
| children: [ | ||||||||||||||||||||||||||||||||||
| Text( | ||||||||||||||||||||||||||||||||||
| '$name님', | ||||||||||||||||||||||||||||||||||
| style: TextStyle( | ||||||||||||||||||||||||||||||||||
| color: Colors.white, | ||||||||||||||||||||||||||||||||||
| fontSize: screenWidth * 0.064, // 24/375 | ||||||||||||||||||||||||||||||||||
| fontWeight: FontWeight.w800, | ||||||||||||||||||||||||||||||||||
| fontFamily: 'Pretendard', | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| SizedBox(width: screenWidth * 0.015), | ||||||||||||||||||||||||||||||||||
| Container( | ||||||||||||||||||||||||||||||||||
| padding: EdgeInsets.symmetric( | ||||||||||||||||||||||||||||||||||
| horizontal: screenWidth * 0.01, | ||||||||||||||||||||||||||||||||||
| vertical: screenHeight * 0.001, | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| decoration: BoxDecoration( | ||||||||||||||||||||||||||||||||||
| color: Colors.white, | ||||||||||||||||||||||||||||||||||
| borderRadius: BorderRadius.circular(20), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| child: Text( | ||||||||||||||||||||||||||||||||||
| roleText, | ||||||||||||||||||||||||||||||||||
| style: TextStyle( | ||||||||||||||||||||||||||||||||||
| color: AppColors.ongiOrange, | ||||||||||||||||||||||||||||||||||
| fontSize: screenWidth * 0.019, | ||||||||||||||||||||||||||||||||||
| fontWeight: FontWeight.w600, | ||||||||||||||||||||||||||||||||||
| fontFamily: 'Pretendard', | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| Padding( | ||||||||||||||||||||||||||||||||||
| padding: EdgeInsets.only(left: screenWidth * 0.021), // 8/375 | ||||||||||||||||||||||||||||||||||
| child: Column( | ||||||||||||||||||||||||||||||||||
| crossAxisAlignment: CrossAxisAlignment.start, | ||||||||||||||||||||||||||||||||||
| children: [ | ||||||||||||||||||||||||||||||||||
| SizedBox(height: screenHeight * 0.005), // 4/812 | ||||||||||||||||||||||||||||||||||
| Row( | ||||||||||||||||||||||||||||||||||
| children: [ | ||||||||||||||||||||||||||||||||||
| Text( | ||||||||||||||||||||||||||||||||||
| familyName, | ||||||||||||||||||||||||||||||||||
| style: TextStyle( | ||||||||||||||||||||||||||||||||||
| color: Colors.white, | ||||||||||||||||||||||||||||||||||
| fontSize: 15, | ||||||||||||||||||||||||||||||||||
| fontWeight: FontWeight.w700, | ||||||||||||||||||||||||||||||||||
| fontFamily: 'Pretendard', | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| SizedBox(width: screenWidth * 0.011), // 4/375 | ||||||||||||||||||||||||||||||||||
| Text( | ||||||||||||||||||||||||||||||||||
| familycode, | ||||||||||||||||||||||||||||||||||
| style: TextStyle( | ||||||||||||||||||||||||||||||||||
| color: Colors.white, | ||||||||||||||||||||||||||||||||||
| fontSize: 10, | ||||||||||||||||||||||||||||||||||
| fontWeight: FontWeight.w600, | ||||||||||||||||||||||||||||||||||
| fontFamily: 'Pretendard', | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| SizedBox(width: screenWidth * 0.021), // 8/375 | ||||||||||||||||||||||||||||||||||
| Builder( | ||||||||||||||||||||||||||||||||||
| builder: (context) => OutlinedButton( | ||||||||||||||||||||||||||||||||||
| onPressed: () async { | ||||||||||||||||||||||||||||||||||
| await Clipboard.setData(ClipboardData(text: familycode)); | ||||||||||||||||||||||||||||||||||
| ScaffoldMessenger.of(context).showSnackBar( | ||||||||||||||||||||||||||||||||||
| SnackBar(content: Text('가족코드가 복사되었습니다.')), | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| style: OutlinedButton.styleFrom( | ||||||||||||||||||||||||||||||||||
| side: const BorderSide(color: AppColors.ongiOrange, width: 1), | ||||||||||||||||||||||||||||||||||
| shape: RoundedRectangleBorder( | ||||||||||||||||||||||||||||||||||
| borderRadius: BorderRadius.circular(20), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| minimumSize: Size.zero, | ||||||||||||||||||||||||||||||||||
| tapTargetSize: MaterialTapTargetSize.shrinkWrap, | ||||||||||||||||||||||||||||||||||
| backgroundColor: Colors.white, | ||||||||||||||||||||||||||||||||||
| padding: EdgeInsets.symmetric( | ||||||||||||||||||||||||||||||||||
| horizontal: screenWidth * 0.01, | ||||||||||||||||||||||||||||||||||
| vertical: screenHeight * 0.001, | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| child: Text( | ||||||||||||||||||||||||||||||||||
| '가족코드 공유', | ||||||||||||||||||||||||||||||||||
| style: TextStyle( | ||||||||||||||||||||||||||||||||||
| color: AppColors.ongiOrange, | ||||||||||||||||||||||||||||||||||
| fontSize: screenWidth * 0.019, | ||||||||||||||||||||||||||||||||||
| fontWeight: FontWeight.w600, | ||||||||||||||||||||||||||||||||||
| fontFamily: 'Pretendard', | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| SizedBox(height: screenHeight * 0.02), // 4/812 | ||||||||||||||||||||||||||||||||||
| OutlinedButton( | ||||||||||||||||||||||||||||||||||
| onPressed: () {}, | ||||||||||||||||||||||||||||||||||
| style: OutlinedButton.styleFrom( | ||||||||||||||||||||||||||||||||||
| side: const BorderSide(color: AppColors.ongiOrange, width: 1), | ||||||||||||||||||||||||||||||||||
| shape: RoundedRectangleBorder( | ||||||||||||||||||||||||||||||||||
| borderRadius: BorderRadius.circular(30), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| backgroundColor: Colors.white, | ||||||||||||||||||||||||||||||||||
| padding: EdgeInsets.symmetric( | ||||||||||||||||||||||||||||||||||
| horizontal: screenWidth * 0.027, // 10/375 | ||||||||||||||||||||||||||||||||||
| vertical: screenHeight * 0.002, // 1/812 | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| child: const Text( | ||||||||||||||||||||||||||||||||||
| '프로필 수정', | ||||||||||||||||||||||||||||||||||
| style: TextStyle( | ||||||||||||||||||||||||||||||||||
| color: AppColors.ongiOrange, | ||||||||||||||||||||||||||||||||||
| fontWeight: FontWeight.w400, | ||||||||||||||||||||||||||||||||||
| fontSize: 13, | ||||||||||||||||||||||||||||||||||
| fontFamily: 'Pretendard', | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| import 'package:flutter/material.dart'; | ||
| import 'package:ongi/utils/prefs_manager.dart'; | ||
| import 'package:ongi/screens/start_screen.dart'; | ||
| import 'package:ongi/core/app_colors.dart'; | ||
| import 'package:ongi/screens/mypage/mypage_myinfo.dart'; | ||
|
|
||
| class ProfileScreen extends StatelessWidget { | ||
| const ProfileScreen({Key? key}) : super(key: key); | ||
|
|
||
| Widget buildMenuList(BuildContext context) { | ||
| final menuItems = [ | ||
| '개인정보 보호', | ||
| '시스템 알림', | ||
| '공지사항', | ||
| '정보', | ||
| '문의하기', | ||
| '로그아웃', | ||
| ]; | ||
|
|
||
| final double gap = MediaQuery.of(context).size.height * 0.02; | ||
| final screenWidth = MediaQuery.of(context).size.width; | ||
| return Container( | ||
| margin: EdgeInsets.only(left: 0, right: screenWidth * 0.3), | ||
| child: Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
| for (final item in menuItems) ...[ | ||
| SizedBox(height: gap), | ||
| item == '로그아웃' | ||
| ? GestureDetector( | ||
| onTap: () async { | ||
| await PrefsManager.logout(); | ||
| ScaffoldMessenger.of(context).showSnackBar( | ||
| const SnackBar(content: Text('로그아웃되었습니다.')), | ||
| ); | ||
| await Future.delayed(const Duration(milliseconds: 500)); | ||
| Navigator.of(context).pushAndRemoveUntil( | ||
| MaterialPageRoute(builder: (context) => const StartScreen()), | ||
| (route) => false, | ||
| ); | ||
| }, | ||
| child: const Text( | ||
| '로그아웃', | ||
| style: TextStyle( | ||
| fontSize: 24, | ||
| color: Colors.black, | ||
| ), | ||
| ), | ||
| ) | ||
| : Text(item, style: const TextStyle(fontSize: 24)), | ||
| ] | ||
| ], | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| return Scaffold( | ||
| backgroundColor: AppColors.ongiOrange, | ||
| appBar: AppBar(backgroundColor: AppColors.ongiOrange, elevation: 0), | ||
| body: Stack( | ||
| children: [ | ||
| Positioned( | ||
| bottom: -MediaQuery.of(context).size.width * 0.6, | ||
| left: 0, | ||
| right: 0, | ||
| height: MediaQuery.of(context).size.height * 0.75, | ||
| child: OverflowBox( | ||
| maxWidth: double.infinity, | ||
| maxHeight: double.infinity, | ||
| child: Center( | ||
| child: Container( | ||
| width: MediaQuery.of(context).size.width * 1.5, | ||
| height: MediaQuery.of(context).size.height, | ||
| decoration: BoxDecoration( | ||
| color: AppColors.ongiLigntgrey, | ||
| borderRadius: const BorderRadius.only( | ||
| topLeft: Radius.circular(260), | ||
| topRight: Radius.circular(260), | ||
| ), | ||
| ), | ||
| ), | ||
| ), | ||
| ), | ||
| ), | ||
| // 기존 내용 | ||
| Center( | ||
| child: Column( | ||
| mainAxisAlignment: MainAxisAlignment.start, | ||
| children: [ | ||
| const Text( | ||
| '마이페이지', | ||
| style: TextStyle( | ||
| color: Colors.white, | ||
| fontSize: 24, | ||
| fontFamily: 'Pretendard', | ||
| fontWeight: FontWeight.w600, | ||
| ), | ||
| ), | ||
| const SizedBox(height: 8), | ||
| const Padding( | ||
| padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8), | ||
| child: Myinfo(), | ||
| ), | ||
| const SizedBox(height: 24), | ||
| buildMenuList(context), | ||
| ], | ||
| ), | ||
| ), | ||
| ], | ||
| ), | ||
| ); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
사용되지 않는 import를 확인하세요.
dart:ui패키지가 추가되었지만 코드에서 사용되는 곳을 찾을 수 없습니다. 필요없다면 제거하는 것이 좋겠습니다.🏁 Script executed:
Length of output: 100
dart:ui불필요한 import 제거 요청frontend/ongi/lib/screens/bottom_nav.dart파일에서dart:ui를 참조하는 구문이 발견되지 않아, 해당 import는 제거하는 것이 적절합니다.삭제할 라인: 9
제안하는 변경:
- import 'dart:ui';📝 Committable suggestion
🤖 Prompt for AI Agents