diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 9200564..8640a8f 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -7,9 +7,9 @@
{
File? _imageFile;
final ImagePicker _picker = ImagePicker();
+ String? _kakaoProfileImageUrl;
+ String? _apiProfileImageUrl;
+
+ @override
+ void initState() {
+ super.initState();
+ _loadProfileImage(); // 프로필 이미지 로드
+ }
+
+ Future _loadProfileImage() async {
+ await _loadKakaoProfile();
+ await _getApiProfileImage(); // API로 프로필 이미지 불러오기
+ }
+
+ Future _getApiProfileImage() async {
+ const url = 'http://15.164.88.94/users/isFirst';
+
+ try {
+ // API 호출을 위한 GET 요청
+ final response = await http.get(
+ Uri.parse(url),
+ headers: {'Authorization': 'Bearer $token'}, // 토큰 추가
+ );
+
+ if (response.statusCode == 200) {
+ // 서버로부터 응답을 받은 경우
+ final data = json.decode(response.body);
+ setState(() {
+ _apiProfileImageUrl = data['profileImage']; // API에서 프로필 이미지 URL 받아오기
+ });
+ } else {
+ print('Failed to get profile image: ${response.statusCode}');
+ }
+ } catch (e) {
+ print('Error during profile image fetch: $e');
+ }
+ }
+
+ // 카카오 프로필 이미지 불러오기
+ Future _loadKakaoProfile() async {
+ try {
+ User user = await UserApi.instance.me(); // 카카오 사용자 정보 불러오기
+ setState(() {
+ _kakaoProfileImageUrl =
+ user.kakaoAccount?.profile?.profileImageUrl; // 프로필 이미지 URL 저장
+ });
+ } catch (error) {
+ print('Failed to load Kakao profile: $error');
+ setState(() {
+ _kakaoProfileImageUrl = null;
+ });
+ }
+ }
Future _pickImage() async {
final pickedFile = await _picker.pickImage(source: ImageSource.gallery);
@@ -62,13 +115,13 @@ class _ProfileSettingState extends State {
}
Future _registerUserInfo() async {
- const url = 'http://15.164.88.94/users/infos'; // API URL
+ const url = 'http://15.164.88.94/users/infos';
// POST 요청 준비
final request = http.MultipartRequest('POST', Uri.parse(url));
// 토큰 확인 및 추가
- if (token == null || token.isEmpty) {
+ if (token.isEmpty) {
print('Token is missing.');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('토큰이 없습니다. 다시 로그인해주세요.')),
@@ -85,7 +138,8 @@ class _ProfileSettingState extends State {
// 선택한 이미지가 있으면 파일로 추가
if (_imageFile != null) {
- request.files.add(await http.MultipartFile.fromPath('image', _imageFile!.path));
+ request.files
+ .add(await http.MultipartFile.fromPath('image', _imageFile!.path));
}
try {
@@ -108,11 +162,12 @@ class _ProfileSettingState extends State {
} else {
// 실패 시 서버에서 보낸 오류 메시지 출력
final errorBody = utf8.decode(responseData.bodyBytes);
- print('Failed to register user info. Status code: ${response.statusCode}');
+ print(
+ 'Failed to register user info. Status code: ${response.statusCode}');
print('Response body: $errorBody');
ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(content: Text('정보 등록 실패: 이미 사용 중인 닉네임입니다.')),
+ const SnackBar(content: Text('정보 등록 실패: 이미 사용 중인 닉네임입니다.')),
);
}
} catch (e) {
@@ -123,7 +178,6 @@ class _ProfileSettingState extends State {
}
}
-
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -159,8 +213,15 @@ class _ProfileSettingState extends State {
radius: 50,
backgroundImage: _imageFile != null
? FileImage(_imageFile!)
- : const AssetImage('assets/images/defaultProfile.png')
- as ImageProvider,
+ : (_kakaoProfileImageUrl != null &&
+ _kakaoProfileImageUrl!.isNotEmpty
+ ? NetworkImage(_kakaoProfileImageUrl!)
+ : (_apiProfileImageUrl != null &&
+ _apiProfileImageUrl!.isNotEmpty
+ ? NetworkImage(_apiProfileImageUrl!)
+ : const AssetImage(
+ 'assets/images/defaultProfile.png')))
+ as ImageProvider,
),
Positioned(
bottom: 0,
@@ -192,13 +253,13 @@ class _ProfileSettingState extends State {
counterText: '', // 글자수 카운터 삭제
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
- borderSide: BorderSide(
+ borderSide: const BorderSide(
color: Colors.black, // 기본 테두리 검은색
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
- borderSide: BorderSide(
+ borderSide: const BorderSide(
color: Colors.black, // 포커스 시 테두리 검은색
width: 2.0,
),
@@ -234,13 +295,13 @@ class _ProfileSettingState extends State {
counterText: '', // 글자수 카운터 삭제
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
- borderSide: BorderSide(
+ borderSide: const BorderSide(
color: Colors.black, // 기본 테두리 검은색
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
- borderSide: BorderSide(
+ borderSide: const BorderSide(
color: Colors.black, // 포커스 시 테두리 검은색
width: 2.0,
),
diff --git a/lib/RoutineAdeIntro/RoutineAde1.dart b/lib/RoutineAdeIntro/RoutineAde1.dart
index d287bcc..68fbd89 100644
--- a/lib/RoutineAdeIntro/RoutineAde1.dart
+++ b/lib/RoutineAdeIntro/RoutineAde1.dart
@@ -27,10 +27,10 @@ class RoutineAde1 extends StatefulWidget {
class _RoutineAde1State extends State {
final List imgList = [
- "assets/images/tap-bar/routine02.png",
- "assets/images/tap-bar/group02.png",
- "assets/images/tap-bar/statistics02.png",
- "assets/images/tap-bar/more02.png",
+ "assets/images/new-icons/onBoarding1.png",
+ "assets/images/new-icons/onBoarding2.png",
+ "assets/images/new-icons/onBoarding3.png",
+ "assets/images/new-icons/onBoarding4.png",
];
int _currentIndex = 0; // 현재 선택된 이미지 인덱스
@@ -45,30 +45,7 @@ class _RoutineAde1State extends State {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Spacer(),
- // Image.asset(
- // 'assets/images/new-icons/RoutineAde.png',
- // width: 100,
- // height: 100,
- // ),
- // const SizedBox(height: 20),
- // const Text(
- // '더 나은 하루, 루틴 에이드',
- // style: TextStyle(
- // fontSize: 18,
- // fontWeight: FontWeight.bold,
- // color: Colors.black,
- // ),
- // ),
- // const SizedBox(height: 8),
- // Text(
- // '루틴으로 더 나은 일상을\n함께 관리해보세요!',
- // textAlign: TextAlign.center,
- // style: TextStyle(
- // fontSize: 14,
- // color: Colors.grey[700],
- // ),
- // ),
- const SizedBox(height: 50),
+ const SizedBox(height: 100),
// Carousel Slider 부분
CarouselSlider(
@@ -81,19 +58,24 @@ class _RoutineAde1State extends State {
_currentIndex = index; // 슬라이드가 바뀔 때 현재 인덱스 업데이트
});
},
+ enableInfiniteScroll: false, // 무한 스크롤 비활성화
),
- items: imgList.map((item) => Container(
- child: Center(
- child: Image.asset(
- item,
- fit: BoxFit.contain,
- width: 1000,
- ),
- ),
- )).toList(),
+ items: imgList
+ .map((item) => Container(
+ child: Center(
+ child: Image.asset(
+ item,
+ fit: BoxFit.contain,
+ width: 1000,
+ ),
+ ),
+ ))
+ .toList(),
),
- SizedBox(height: 50,),
+ const SizedBox(
+ height: 50,
+ ),
// 인디케이터 부분
Row(
@@ -106,24 +88,32 @@ class _RoutineAde1State extends State {
child: Container(
width: 12.0,
height: 12.0,
- margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 4.0),
+ margin: const EdgeInsets.symmetric(
+ vertical: 10.0, horizontal: 4.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _currentIndex == entry.key
- ? Colors.blueAccent // 현재 인덱스일 경우 채워진 동그라미
- : Colors.grey, // 그렇지 않은 경우 빈 동그라미
+ ? Colors.grey // 현재 인덱스일 경우 채워진 동그라미
+ : Colors.grey[300], // 그렇지 않은 경우 빈 동그라미
),
),
);
}).toList(),
),
-
const Spacer(),
+ const SizedBox(height: 10),
+ const Text(
+ "sns로 간편 가입하기 !",
+ style: TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.bold,
+ color: Colors.grey),
+ ),
Padding(
- padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
+ padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: SizedBox(
width: double.infinity,
- height: 150,
+ height: 100,
child: GestureDetector(
onTap: () {
// WebView 페이지로 이동
@@ -135,13 +125,16 @@ class _RoutineAde1State extends State {
},
child: Image.asset(
"assets/images/new-icons/kakaoTalk.png",
- width: 200,
+ width: 250,
height: 200,
fit: BoxFit.contain,
),
),
),
),
+ const SizedBox(
+ height: 10,
+ ),
],
),
),
diff --git a/lib/RoutineAdeIntro/WebViewPage.dart b/lib/RoutineAdeIntro/WebViewPage.dart
index e1fe023..540bc0f 100644
--- a/lib/RoutineAdeIntro/WebViewPage.dart
+++ b/lib/RoutineAdeIntro/WebViewPage.dart
@@ -1,7 +1,10 @@
import 'package:flutter/material.dart';
+import 'package:http/http.dart' as http;
import 'package:routine_ade/RoutineAdeIntro/ProfileSetting.dart';
+import 'package:routine_ade/routine_home/MyRoutinePage.dart';
import 'package:webview_flutter/webview_flutter.dart';
import '../routine_user/token.dart';
+import 'dart:convert';
class WebViewPage extends StatefulWidget {
const WebViewPage({super.key});
@@ -16,11 +19,10 @@ class _WebViewPageState extends State {
@override
void initState() {
super.initState();
- // 웹뷰 초기화 전에 SharedPreferences에서 토큰을 불러옴.
_loadToken();
}
- // 토큰을 불러와서 출력 (필요시 다른 처리)
+ // 토큰을 불러오는 메서드
Future _loadToken() async {
String? token = await TokenManager.getToken();
if (token != null) {
@@ -30,43 +32,72 @@ class _WebViewPageState extends State {
}
}
+ // 최초 로그인 여부를 확인하는 메서드
+ Future _checkIfFirstLogin(String token) async {
+ final response = await http.get(
+ Uri.parse('http://15.164.88.94/users/isFirst'),
+ headers: {
+ 'Authorization': 'Bearer $token',
+ 'Content-Type': 'application/json; charset=UTF-8',
+ },
+ );
+
+ if (response.statusCode == 200) {
+ final responseBody = json.decode(utf8.decode(response.bodyBytes));
+ bool isFirst = responseBody['isFirst'] ?? false;
+ print('isFirst: $isFirst');
+
+ // 최초 로그인 여부에 따라 페이지 이동
+ if (isFirst) {
+ print("ProfileSetting 페이지로 이동");
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(builder: (context) => const ProfileSetting()),
+ // ProfileSetting 페이지로 이동
+ );
+ } else {
+ print("MyRoutinePage로 이동");
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(builder: (context) => const MyRoutinePage()),
+ );
+ }
+ } else {
+ print('최초 로그인 확인 실패: ${response.statusCode}');
+ // 오류 처리
+ }
+ }
+
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
- title: const Text('Kakao Login WebView'),
+ title: const Text('카카오앱으로 로그인하기'),
),
body: WebView(
initialUrl:
- 'https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=25a0f887ecba2fdb77884c01ca0325b0&redirect_uri=http://15.164.88.94/users/login/kakao',
+ 'https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=25a0f887ecba2fdb77884c01ca0325b0&redirect_uri=http://15.164.88.94/users/login/kakao',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
},
onPageFinished: (String url) async {
- // 페이지 로딩이 끝나면 URL을 확인
if (url.contains('token=')) {
final tokenStartIndex =
url.indexOf('token=') + 6; // 'token='의 시작 위치
final token = url.substring(tokenStartIndex);
- // URL이 정상적으로 응답하지 않을 때 예외 처리
if (token.isNotEmpty) {
print('OAuth 토큰: $token'); // 콘솔에 토큰 출력
- // 추출한 토큰을 SharedPreferences에 저장
- await TokenManager.saveToken(token);
- print('토큰 저장 완료');
+ // 추출한 토큰으로 최초 로그인 확인
+ await _checkIfFirstLogin(token);
} else {
print('토큰이 유효하지 않습니다.');
}
- Navigator.pushReplacement(
- context,
- MaterialPageRoute(builder: (context) => const ProfileSetting()),
- );
}
},
),
);
}
-}
\ No newline at end of file
+}
diff --git a/lib/RoutineAdelntro/ProfileSetting.dart b/lib/RoutineAdelntro/ProfileSetting.dart
deleted file mode 100644
index fb1e60e..0000000
--- a/lib/RoutineAdelntro/ProfileSetting.dart
+++ /dev/null
@@ -1,182 +0,0 @@
-import 'dart:io';
-import 'package:flutter/material.dart';
-import 'package:image_picker/image_picker.dart';
-import 'package:permission_handler/permission_handler.dart';
-
-import '../routine_home/MyRoutinePage.dart';
-
-class ProfileSetting extends StatefulWidget {
- const ProfileSetting({super.key});
-
- @override
- _ProfileSettingState createState() => _ProfileSettingState();
-}
-
-class _ProfileSettingState extends State {
- File? _imageFile;
- final ImagePicker _picker = ImagePicker();
-
- Future _pickImage() async {
- final pickedFile = await _picker.pickImage(source: ImageSource.gallery);
-
- if (pickedFile != null) {
- setState(() {
- _imageFile = File(pickedFile.path);
- });
- } else {
- print('No image selected.');
- }
- }
-
- final TextEditingController _nicknameController = TextEditingController();
- final TextEditingController _bioController = TextEditingController();
- bool _isNicknameValid = true;
- String _nicknameErrorMessage = '';
-
- void _validateNickname(String value) {
- setState(() {
- if (value.length > 10) {
- _isNicknameValid = false;
- _nicknameErrorMessage = '10글자 이내로 입력해주세요.';
- } else {
- _isNicknameValid = true;
- _nicknameErrorMessage = '';
- }
- });
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- resizeToAvoidBottomInset: false,
- appBar: AppBar(
- backgroundColor: const Color(0xFF8DCCFF),
- centerTitle: true,
- title: const Text(
- '프로필 설정',
- style: TextStyle(
- color: Colors.white, fontSize: 25, fontWeight: FontWeight.bold),
- ),
- leading: IconButton(
- icon: const Icon(Icons.arrow_back, color: Colors.white),
- onPressed: () {
- Navigator.of(context).pop();
- },
- ),
- ),
- body: Stack(
- children: [
- Padding(
- padding: const EdgeInsets.all(20.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- const SizedBox(height: 20),
- GestureDetector(
- onTap: _pickImage, // 프로필 사진을 클릭했을 때 이미지 선택 기능 실행
- child: Stack(
- children: [
- CircleAvatar(
- radius: 50,
- backgroundImage: _imageFile != null
- ? FileImage(_imageFile!)
- : const AssetImage(
- 'assets/images/default_profile.png')
- as ImageProvider,
- ),
- Positioned(
- bottom: 0,
- right: 0,
- child: GestureDetector(
- onTap: _pickImage, // 카메라 아이콘 클릭 시 이미지 선택 기능 실행
- child: const CircleAvatar(
- backgroundColor: Colors.white,
- radius: 16,
- child: Icon(Icons.camera_alt, color: Colors.grey),
- ),
- ),
- ),
- ],
- ),
- ),
- const SizedBox(height: 50),
- const Align(
- alignment: Alignment.centerLeft,
- child: Text("닉네임"),
- ),
- const SizedBox(height: 10),
- TextField(
- controller: _nicknameController,
- onChanged: _validateNickname,
- decoration: InputDecoration(
- hintText: '닉네임',
- errorText: !_isNicknameValid
- ? _nicknameErrorMessage
- : '10글자 이내로 입력해주세요.',
- border: OutlineInputBorder(
- borderRadius: BorderRadius.circular(10.0),
- borderSide: BorderSide(
- color: _isNicknameValid ? Colors.red : Colors.grey,
- ),
- ),
- focusedBorder: OutlineInputBorder(
- borderRadius: BorderRadius.circular(10.0),
- borderSide: BorderSide(
- color: _isNicknameValid ? Colors.blue : Colors.red,
- ),
- ),
- ),
- maxLength: 10,
- ),
- const SizedBox(height: 20),
- const Align(
- alignment: Alignment.centerLeft,
- child: Text("한 줄 소개"),
- ),
- const SizedBox(height: 10),
- TextField(
- controller: _bioController,
- decoration: InputDecoration(
- hintText: '한 줄 소개',
- border: OutlineInputBorder(
- borderRadius: BorderRadius.circular(10.0),
- ),
- ),
- ),
- ],
- ),
- ),
- Positioned(
- bottom: 20,
- left: 10,
- right: 10,
- child: SizedBox(
- width: double.infinity,
- height: 50,
- child: ElevatedButton(
- style: ElevatedButton.styleFrom(
- backgroundColor: const Color(0xFF8DCCFF),
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(8),
- ),
- ),
- onPressed: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) => const MyRoutinePage(),
- ),
- );
- },
- child: const Text(
- '완료',
- style: TextStyle(fontSize: 16, color: Colors.white),
- ),
- ),
- ),
- ),
- ],
- ),
- );
- }
-}
diff --git a/lib/RoutineAdelntro/ProfileSetting2.dart b/lib/RoutineAdelntro/ProfileSetting2.dart
deleted file mode 100644
index 99f57ed..0000000
--- a/lib/RoutineAdelntro/ProfileSetting2.dart
+++ /dev/null
@@ -1,81 +0,0 @@
-// import 'dart:io';
-//
-// import 'package:flutter/material.dart';
-// import 'package:image_picker/image_picker.dart';
-//
-//
-// class ProfileSetting2 extends StatefulWidget {
-// const ProfileSetting2({Key? key}) : super(key: key);
-//
-// @override
-// State createState() => _MyAppState();
-// }
-//
-// class _MyAppState extends State {
-// XFile? _image; //이미지를 담을 변수 선언
-// final ImagePicker picker = ImagePicker(); //ImagePicker 초기화
-//
-// //이미지를 가져오는 함수
-// Future getImage(ImageSource imageSource) async {
-// //pickedFile에 ImagePicker로 가져온 이미지가 담긴다.
-// final XFile? pickedFile = await picker.pickImage(source: imageSource);
-// if (pickedFile != null) {
-// setState(() {
-// _image = XFile(pickedFile.path); //가져온 이미지를 _image에 저장
-// });
-// }
-// }
-//
-// @override
-// Widget build(BuildContext context) {
-// return MaterialApp(
-// home: Scaffold(
-// appBar: AppBar(title: Text("Camera Test")),
-// body: Column(
-// crossAxisAlignment: CrossAxisAlignment.center,
-// children: [
-// SizedBox(height: 30, width: double.infinity),
-// _buildPhotoArea(),
-// SizedBox(height: 20),
-// _buildButton(),
-// ],
-// ),
-// ),
-// );
-// }
-//
-// Widget _buildPhotoArea() {
-// return _image != null
-// ? Container(
-// width: 300,
-// height: 300,
-// child: Image.file(File(_image!.path)), //가져온 이미지를 화면에 띄워주는 코드
-// )
-// : Container(
-// width: 300,
-// height: 300,
-// color: Colors.grey,
-// );
-// }
-//
-// Widget _buildButton() {
-// return Row(
-// mainAxisAlignment: MainAxisAlignment.center,
-// children: [
-// ElevatedButton(
-// onPressed: () {
-// getImage(ImageSource.camera); //getImage 함수를 호출해서 카메라로 찍은 사진 가져오기
-// },
-// child: Text("카메라"),
-// ),
-// SizedBox(width: 30),
-// ElevatedButton(
-// onPressed: () {
-// getImage(ImageSource.gallery); //getImage 함수를 호출해서 갤러리에서 사진 가져오기
-// },
-// child: Text("갤러리"),
-// ),
-// ],
-// );
-// }
-// }
\ No newline at end of file
diff --git a/lib/RoutineAdelntro/RoutineAde1.dart b/lib/RoutineAdelntro/RoutineAde1.dart
deleted file mode 100644
index 642625b..0000000
--- a/lib/RoutineAdelntro/RoutineAde1.dart
+++ /dev/null
@@ -1,79 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:routine_ade/RoutineAdelntro/ProfileSetting.dart';
-// import 'Pro';
-import 'package:routine_ade/routine_home/MyRoutinePage.dart';
-
-import 'ProfileSetting2.dart';
-
-class RoutineAde1 extends StatelessWidget {
- const RoutineAde1({super.key});
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- backgroundColor: Colors.white, // Set the background color
- body: SafeArea(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- const Spacer(), // Pushes content towards the center
- Image.asset(
- 'assets/images/new-icons/RoutineAde.png',
- width: 100, // Adjust width as needed
- height: 100, // Adjust height as needed
- ),
- const SizedBox(height: 20), // Spacing between image and text
- const Text(
- '더 나은 하루, 루틴 에이드',
- style: TextStyle(
- fontSize: 18,
- fontWeight: FontWeight.bold,
- color: Colors.black,
- ),
- ),
- const SizedBox(height: 8),
- Text(
- '루틴으로 더 나은 일상을\n함께 관리해보세요!',
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 14,
- color: Colors.grey[700],
- ),
- ),
- const Spacer(), // Pushes content towards the center
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
- child: SizedBox(
- width: double.infinity,
- height: 50,
- child: ElevatedButton(
- style: ElevatedButton.styleFrom(
- backgroundColor: const Color(0xFF8DCCFF), // Button color
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(8), // Rounded corners
- ),
- ),
- onPressed: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) => const ProfileSetting()),
- );
- },
- child: const Text(
- '시작하기',
- style: TextStyle(
- fontSize: 16,
- color: Colors.white,
- ),
- ),
- ),
- ),
- ),
- ],
- ),
- ),
- );
- }
-}
diff --git a/lib/main.dart b/lib/main.dart
index 01e411e..762a65a 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -4,9 +4,15 @@ import 'RoutineAdeIntro/RoutineAde1.dart';
import 'routine_home/MyRoutinePage.dart';
import 'package:http/http.dart' as http;
import 'routine_group/GroupMainPage.dart';
+import 'package:kakao_flutter_sdk_common/kakao_flutter_sdk_common.dart';
void main() async {
+ // WidgetsFlutterBinding.ensureInitialized();
+
+ // KakaoSdk.init(nativeAppKey: '90e5f5e8125f01adae4434fd72182a74'); //네이티브 앱 키
+
await initializeDateFormatting();
+
runApp(const MyApp());
}
@@ -20,4 +26,4 @@ class MyApp extends StatelessWidget {
home: RoutineAde1(),
);
}
-}
\ No newline at end of file
+}
diff --git a/lib/routine_group/AddGroupPage.dart b/lib/routine_group/AddGroupPage.dart
index a522a3e..c14035e 100644
--- a/lib/routine_group/AddGroupPage.dart
+++ b/lib/routine_group/AddGroupPage.dart
@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
+import 'package:routine_ade/routine_group/GroupMainPage.dart';
import 'GroupType.dart';
import 'package:routine_ade/routine_user/token.dart';
@@ -16,7 +17,7 @@ class _AddGroupPageState extends State {
final TextEditingController _groupNameController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _groupDescriptionController =
- TextEditingController();
+ TextEditingController();
int _selectedMemberCount = 0;
// 카테고리 선택 (한번에 하나만)
@@ -49,7 +50,7 @@ class _AddGroupPageState extends State {
// 비밀번호 값 설정
final groupPassword =
- _passwordController.text.isEmpty ? null : _passwordController.text;
+ _passwordController.text.isEmpty ? null : _passwordController.text;
// 요청 바디 준비
final url = Uri.parse('http://15.164.88.94/groups');
@@ -71,7 +72,8 @@ class _AddGroupPageState extends State {
print('Response body: ${response.body}');
if (response.statusCode == 200 || response.statusCode == 201) {
- _showDialog('성공', '그룹이 성공적으로 추가되었습니다.');
+ Navigator.pushReplacement(context,
+ MaterialPageRoute(builder: (ctx) => const GroupMainPage()));
} else {
_showDialog('오류', '그룹 추가에 실패했습니다: ${response.body}');
}
@@ -193,7 +195,7 @@ class _AddGroupPageState extends State {
borderSide: BorderSide.none,
),
contentPadding:
- EdgeInsets.symmetric(vertical: 15), // 세로 여백 조정
+ EdgeInsets.symmetric(vertical: 15), // 세로 여백 조정
counterText: "", // 글자 수 표시 없애기
),
),
@@ -209,13 +211,13 @@ class _AddGroupPageState extends State {
borderSide: BorderSide.none,
),
contentPadding:
- EdgeInsets.symmetric(vertical: 15), // 세로 여백 조정
+ EdgeInsets.symmetric(vertical: 15), // 세로 여백 조정
),
),
Container(
color: Colors.white,
padding:
- const EdgeInsets.only(left: 10, right: 10, top: 10),
+ const EdgeInsets.only(left: 10, right: 10, top: 10),
margin: const EdgeInsets.only(top: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -236,7 +238,7 @@ class _AddGroupPageState extends State {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(
5,
- (index) => GestureDetector(
+ (index) => GestureDetector(
onTap: () {
setState(() {
selectedCategoryIndex = index;
@@ -359,4 +361,4 @@ class _AddGroupPageState extends State {
),
);
}
-}
+}
\ No newline at end of file
diff --git a/lib/routine_group/GroupMainPage.dart b/lib/routine_group/GroupMainPage.dart
index 0beaba4..eac2bc3 100644
--- a/lib/routine_group/GroupMainPage.dart
+++ b/lib/routine_group/GroupMainPage.dart
@@ -164,16 +164,6 @@ class _GroupMainPageState extends State {
backgroundColor:
isExpanded ? Colors.grey[600] : const Color(0xFF8DCCFF),
automaticallyImplyLeading: false, // 뒤로가기 제거
- // actions: [
- // Padding(
- // padding: const EdgeInsets.only(right: 16.0),
- // child: Image.asset(
- // "assets/images/bell.png",
- // width: 35,
- // height: 35,
- // ),
- // ),
- // ],
),
body: DarkOverlay(
isDark: isExpanded, // 눌렀을때만 어둡게
@@ -186,11 +176,26 @@ class _GroupMainPageState extends State {
color: const Color(0xFFF8F8EF),
child: Column(
children: [
- const SizedBox(
- height: 20,
- ),
Expanded(
- child: ListView.builder(
+ child: groups.isEmpty
+ ? const Center(
+ child: Column(
+ children: [
+ SizedBox(height: 200,),
+ Image(
+ image: AssetImage('assets/images/new-icons/ice.png'),
+ width: 150, // 원하는 크기로 설정
+ height: 150,
+ ),
+ Text(
+ ' 아래 + 버튼을 눌러 \n 새로운 그룹에 가입해보세요',
+ style: TextStyle(fontSize: 20, color: Colors.grey, fontWeight: FontWeight.bold),
+ textAlign: TextAlign.center, // 텍스트 중앙 정렬
+ ),
+ ],
+ ),
+ )
+ : ListView.builder(
itemCount: groups.length,
itemBuilder: (context, index) {
final group = groups[index];
@@ -223,8 +228,7 @@ class _GroupMainPageState extends State {
),
if (!group.isPublic)
Padding(
- padding:
- const EdgeInsets.only(left: 8.0),
+ padding: const EdgeInsets.only(left: 8.0),
child: Image.asset(
"assets/images/lock.png",
width: 20,
@@ -238,7 +242,6 @@ class _GroupMainPageState extends State {
),
const SizedBox(height: 8.0),
Row(
- // mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text("대표 카테고리 "),
Text(group.groupCategory,
@@ -304,7 +307,6 @@ class _GroupMainPageState extends State {
),
GestureDetector(
onTap: () {
- // 통계 버튼 클릭 시 동작할 코드
Navigator.push(
context,
MaterialPageRoute(
@@ -319,7 +321,6 @@ class _GroupMainPageState extends State {
),
GestureDetector(
onTap: () {
- // 더보기 버튼 클릭 시 동작할 코드
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const MyInfo()),
@@ -359,7 +360,7 @@ class _GroupMainPageState extends State {
onPressed: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) {
- return const GroupRoutinePage(); // 그룹 루틴 페이지 이동 바꿔야함
+ return const GroupRoutinePage();
},
));
},
@@ -424,4 +425,5 @@ class _GroupMainPageState extends State {
),
);
}
+
}
\ No newline at end of file
diff --git a/lib/routine_group/GroupRoutinePage.dart b/lib/routine_group/GroupRoutinePage.dart
index 9c7ece7..2b253c9 100644
--- a/lib/routine_group/GroupRoutinePage.dart
+++ b/lib/routine_group/GroupRoutinePage.dart
@@ -118,7 +118,7 @@ class _GroupRoutinePageState extends State {
children: [
Text(Egroup.groupTitle,
style: const TextStyle(color: Colors.black)),
- const SizedBox(height: 1.0), //그룹 여백
+ const SizedBox(height: 1.0),
Text("그룹 코드 #${Egroup.groupId}",
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.grey, fontSize: 13)),
@@ -129,7 +129,7 @@ class _GroupRoutinePageState extends State {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
- const SizedBox(height: 0), //그룹 코드와 대표 카테고리 사이의 여백
+ const SizedBox(height: 0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
@@ -175,19 +175,24 @@ class _GroupRoutinePageState extends State {
child: const Text("취소",
style: TextStyle(
color: Color.fromARGB(255, 128, 121, 121))),
- onPressed: () {
+ onPressed: () async {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text("그룹 가입",
style: TextStyle(color: Color(0xff8DCCFF))),
- onPressed: () {
- Navigator.of(context).pop();
+ onPressed: () async {
+ Navigator.of(context).pop(); // 다이얼로그 닫기
if (Egroup.isPublic) {
- print("참여 성공!");
+ bool joinSuccess = await _joinGroup(Egroup.groupId);
+ if (joinSuccess) {
+ navigateToGroupPage(Egroup.groupId); // 가입 성공 시 페이지 이동
+ } else {
+ print("그룹 참여 실패!");
+ }
} else {
- _showPasswordDialog(Egroup);
+ _showPasswordDialog(Egroup); // 비밀번호 입력 필요 시 다이얼로그 표시
}
},
),
diff --git a/lib/routine_group/OnClickGroupPage.dart b/lib/routine_group/OnClickGroupPage.dart
index b4cfd4d..e36e924 100644
--- a/lib/routine_group/OnClickGroupPage.dart
+++ b/lib/routine_group/OnClickGroupPage.dart
@@ -8,6 +8,7 @@ import 'package:routine_ade/routine_groupLeader/AddGroupRoutinePage.dart';
import 'package:routine_ade/routine_group/ChatScreen.dart';
import 'package:routine_ade/routine_group/GroupMainPage.dart';
import 'package:routine_ade/routine_group/GroupRoutinePage.dart';
+import 'package:routine_ade/routine_groupLeader/groupEdit.dart';
import 'package:routine_ade/routine_home/MyRoutinePage.dart';
import 'package:http/http.dart' as http;
import 'groupType.dart';
@@ -334,8 +335,8 @@ class _OnClickGroupPageState extends State
Navigator.push(
context,
MaterialPageRoute(
- builder: (context) =>
- OtherUserRoutinePage(userId: groupmember.userId),
+ builder: (context) => OtherUserRoutinePage(
+ userId: groupmember.userId, groupId: widget.groupId),
),
);
},
diff --git a/lib/routine_groupLeader/AddGroupRoutinePage.dart b/lib/routine_groupLeader/AddGroupRoutinePage.dart
index 7fb0e4c..db25149 100644
--- a/lib/routine_groupLeader/AddGroupRoutinePage.dart
+++ b/lib/routine_groupLeader/AddGroupRoutinePage.dart
@@ -5,6 +5,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/cupertino.dart';
+import 'package:routine_ade/routine_groupLeader/glOnClickGroupPage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/intl.dart'; //날짜 포맷팅 init 패키지
import 'package:http/http.dart' as http;
@@ -96,7 +97,12 @@ class _AddRoutinePageState extends State {
print('Response body: ${utf8.decode(response.bodyBytes)}');
if (response.statusCode == 200 || response.statusCode == 201) {
- _showDialog('성공', '루틴이 성공적으로 추가되었습니다.');
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(
+ builder: (ctx) => glOnClickGroupPage(
+ groupId: widget.groupId,
+ )));
} else {
_showDialog('오류', '루틴 추가에 실패했습니다: ${utf8.decode(response.bodyBytes)}');
}
diff --git a/lib/routine_groupLeader/glOnClickGroupPage.dart b/lib/routine_groupLeader/glOnClickGroupPage.dart
index 8fcb4a6..949d3cd 100644
--- a/lib/routine_groupLeader/glOnClickGroupPage.dart
+++ b/lib/routine_groupLeader/glOnClickGroupPage.dart
@@ -44,7 +44,7 @@ class glOnClickGroupPage extends StatefulWidget {
class _glOnClickGroupPageState extends State
with SingleTickerProviderStateMixin {
final GlobalKey _scaffoldKey = GlobalKey();
- bool _isSwitchOn = false;
+ final bool _isSwitchOn = false;
late TabController _tabController;
late Future futureGroupResponse;
bool _isFloatingActionButtonVisible = true;
@@ -365,7 +365,8 @@ class _glOnClickGroupPageState extends State
Navigator.push(
context,
MaterialPageRoute(
- builder: (context) => OtherUserRoutinePage(userId: member.userId),
+ builder: (context) => OtherUserRoutinePage(
+ userId: member.userId, groupId: widget.groupId),
),
);
},
diff --git a/lib/routine_groupLeader/groupRoutineEditPage.dart b/lib/routine_groupLeader/groupRoutineEditPage.dart
index 6b26112..1db0be2 100644
--- a/lib/routine_groupLeader/groupRoutineEditPage.dart
+++ b/lib/routine_groupLeader/groupRoutineEditPage.dart
@@ -308,7 +308,7 @@ class _groupRoutineEditPageState extends State {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(
5,
- (index) => GestureDetector(
+ (index) => GestureDetector(
onTap: () {
setState(() {
selectedCategoryIndex = index;
@@ -353,7 +353,7 @@ class _groupRoutineEditPageState extends State {
onPressed: _ModifiedRoutine,
style: ButtonStyle(
backgroundColor:
- WidgetStateProperty.all(const Color(0xFFB4DDFF)),
+ WidgetStateProperty.all(const Color(0xFFB4DDFF)),
shape: WidgetStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
@@ -396,4 +396,4 @@ class _groupRoutineEditPageState extends State {
return '';
}
}
-}
\ No newline at end of file
+}
diff --git a/lib/routine_groupLeader/groupType.dart b/lib/routine_groupLeader/groupType.dart
index 309f5c4..8b13789 100644
--- a/lib/routine_groupLeader/groupType.dart
+++ b/lib/routine_groupLeader/groupType.dart
@@ -1,465 +1 @@
-import 'dart:convert';
-import 'package:flutter/material.dart';
-import 'package:http/http.dart' as http;
-import 'package:routine_ade/routine_user/token.dart';
-class GroupRoutinePage extends StatefulWidget {
- const GroupRoutinePage({super.key});
-
- @override
- _GroupRoutinePageState createState() => _GroupRoutinePageState();
-}
-
-class _GroupRoutinePageState extends State {
- final TextEditingController _searchController = TextEditingController();
- final TextEditingController _passwordController = TextEditingController();
- List allGroups = [];
- List filteredGroups = [];
- bool _isSearching = false;
- bool _isPasswordIncorrect = false;
- bool _isLoading = false;
- int _currentPage = 1;
- final int _pageSize = 10;
- String? selectedCategory = '전체';
-
- @override
- void initState() {
- super.initState();
- // _fetchGroups();
- }
-
- Future _fetchGroups({bool loadMore = false, String? category}) async {
- if (loadMore) {
- _currentPage++;
- } else {
- setState(() {
- _isLoading = true;
- _currentPage = 1;
- allGroups.clear();
- });
- }
-
- String categoryQuery = category != null && category != '전체'
- ? 'groupCategory=${Uri.encodeComponent(category)}'
- : 'groupCategory=%EC%A0%84%EC%B2%B4';
- final url = Uri.parse('http://15.164.88.94/groups?$categoryQuery');
- final response = await http.get(url, headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer $token',
- });
-
- if (response.statusCode == 200) {
- final decodedResponse = utf8.decode(response.bodyBytes);
- final data = jsonDecode(decodedResponse);
-
- setState(() {
- if (data is Map && data.containsKey('groups')) {
- final newGroups = (data['groups'] as List)
- .map((json) => EntireGroup.fromJson(json))
- .toList();
- allGroups.addAll(newGroups);
- }
-
- filteredGroups = allGroups;
- _sortGroupsByGroupIdDescending(); // 그룹 정렬 추가
- _isLoading = false;
- });
- } else {
- setState(() {
- _isLoading = false;
- });
- print("그룹 불러오기를 실패하였습니다.");
- print("Status Code: ${response.statusCode}");
- print("Response Body: ${response.body}");
- }
- }
-
- Color getCategoryColor(String category) {
- switch (category) {
- case "전체":
- return Colors.black;
- case "건강":
- return const Color(0xff6ACBF3);
- case "자기개발":
- return const Color(0xff7BD7C6);
- case "일상":
- return const Color(0xffF5A77B);
- case "자기관리":
- return const Color(0xffC69FEC);
- default:
- return const Color(0xffF4A2D8);
- }
- }
-
- void toggleSearch() {
- setState(() {
- _isSearching = !_isSearching;
- if (!_isSearching) {
- _searchController.clear();
- filterGroups('');
- }
- });
- }
-
- void _sortGroupsByGroupIdDescending() {
- filteredGroups.sort((a, b) => b.groupId.compareTo(a.groupId));
- }
-
- void filterGroups(String query) {
- setState(() {
- if (query.isNotEmpty) {
- filteredGroups = allGroups
- .where((group) =>
- group.groupTitle.toLowerCase().contains(query.toLowerCase()))
- .toList();
- } else {
- filteredGroups = allGroups;
- }
- _sortGroupsByGroupIdDescending(); // 필터 후 정렬 유지
- });
- }
-
- void _showGroupDialog(EntireGroup Egroup) {
- if (Egroup.isPublic) {
- showDialog(
- context: context,
- builder: (BuildContext context) {
- return AlertDialog(
- backgroundColor: Colors.white, // 배경색을 하얀색으로 설정
- title: Center(child: Text(Egroup.groupTitle)), // 가운데 정렬
- content: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.center, // 가운데 정렬
- children: [
- Text("그룹 코드 #${Egroup.groupId}"),
- Text("대표 카테고리 ${Egroup.groupCategory}"),
- Text("루틴장 ${Egroup.createdUserNickname}"),
- Text("인원 ${Egroup.joinMemberCount}/${Egroup.maxMemberCount}명"),
- ],
- ),
- actions: [
- OverflowBar(
- alignment: MainAxisAlignment.end, // 버튼들을 오른쪽에 정렬
- children: [
- TextButton(
- child: const Text("가입하기"),
- onPressed: () {
- Navigator.of(context).pop();
- },
- ),
- TextButton(
- child: const Text("취소"),
- onPressed: () {
- Navigator.of(context).pop();
- // 참여 로직 추가 가능
- },
- ),
- ],
- ),
- ],
- );
- },
- );
- } else {
- _showPasswordDialog(Egroup);
- }
- }
-
- void _showPasswordDialog(EntireGroup group) {
- showDialog(
- context: context,
- builder: (BuildContext context) {
- return AlertDialog(
- backgroundColor: Colors.white, // 배경색을 하얀색으로 설정
- title: const Center(child: Text("비공개 그룹")), // 가운데 정렬
- content: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.center, // 가운데 정렬
- children: [
- TextField(
- controller: _passwordController,
- obscureText: true,
- decoration: InputDecoration(
- labelText: "비밀번호 4자리 입력",
- errorText: _isPasswordIncorrect ? "비밀번호가 틀렸습니다." : null,
- ),
- ),
- ],
- ),
- actions: [
- OverflowBar(
- alignment: MainAxisAlignment.end, // 버튼들을 오른쪽에 정렬
- children: [
- TextButton(
- child: const Text("취소"),
- onPressed: () {
- Navigator.of(context).pop();
- _passwordController.clear();
- _isPasswordIncorrect = false;
- },
- ),
- TextButton(
- child: const Text("확인"),
- onPressed: () {
- _checkPassword(group);
- },
- ),
- ],
- ),
- ],
- );
- },
- );
- }
-
- void _checkPassword(EntireGroup group) {
- setState(() {
- if (_passwordController.text == group.groupPassword) {
- Navigator.of(context).pop();
- _passwordController.clear();
- _isPasswordIncorrect = false;
- // 비밀번호가 맞으면, 참여 로직 추가 가능
- print("참여 성공!");
- } else {
- _isPasswordIncorrect = true;
- }
- });
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: _isSearching
- ? TextField(
- controller: _searchController,
- decoration: const InputDecoration(
- hintText: " 그룹명을 입력하세요",
- fillColor: Colors.white,
- filled: true,
- contentPadding: EdgeInsets.symmetric(
- vertical: 12.0,
- ),
- ),
- onChanged: (value) {
- filterGroups(value);
- },
- )
- : const Text(
- "루틴 그룹",
- style: TextStyle(
- color: Colors.black,
- fontSize: 23,
- fontWeight: FontWeight.bold),
- ),
- centerTitle: true,
- backgroundColor: Colors.grey[200],
- actions: [
- IconButton(
- icon: _isSearching
- ? const Icon(Icons.close)
- : Image.asset("assets/images/search.png",
- width: 27, height: 27),
- onPressed: toggleSearch,
- ),
- ],
- ),
- body: Stack(
- children: [
- Container(
- color: Colors.grey[200],
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 7.0),
- child: Container(
- color: Colors.grey[200],
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- Container(
- color: Colors.grey[200],
- child: Padding(
- padding: const EdgeInsets.symmetric(vertical: 1.0),
- child: SingleChildScrollView(
- scrollDirection: Axis.horizontal,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.start,
- children: ['전체', '일상', '건강', '자기개발', '자기관리', '기타']
- .map((category) {
- bool isSelected = selectedCategory == category;
- return Padding(
- padding:
- const EdgeInsets.symmetric(horizontal: 3.0),
- child: ElevatedButton(
- onPressed: () {
- setState(() {
- selectedCategory = category;
- });
- _fetchGroups(category: category);
- },
- style: ButtonStyle(
- backgroundColor: WidgetStateProperty.all(
- isSelected
- ? Colors.white
- : const Color(0xE8E8E8EF),
- ),
- ),
- child: Text(
- category,
- style: TextStyle(
- color: getCategoryColor(
- category), // Always set the color based on the category
- ),
- ),
- ),
- );
- }).toList(),
- ),
- ),
- ),
- ),
- Expanded(
- child: _isLoading
- ? const Center(child: CircularProgressIndicator())
- // : (!_isSearching && filteredGroups.isEmpty)
- : filteredGroups.isEmpty
- ? const Center(child: Text('검색 결과가 없습니다.'))
- : (!_isSearching)
- ? const Center(child: Text('그룹을 검색하세요.'))
- : ListView.builder(
- itemCount: filteredGroups.length,
- itemBuilder: (context, index) {
- final group = filteredGroups[index];
- Color textColor = getCategoryColor(
- group.groupCategory);
- return InkWell(
- onTap: () {
- _showGroupDialog(group);
- },
- child: Card(
- margin: const EdgeInsets.all(8.0),
- color: Colors.white,
- child: Padding(
- padding:
- const EdgeInsets.all(16.0),
- child: Column(
- crossAxisAlignment:
- CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment:
- MainAxisAlignment
- .spaceBetween,
- children: [
- Row(
- children: [
- Text(
- group.groupTitle,
- style:
- const TextStyle(
- fontSize: 18,
- fontWeight:
- FontWeight
- .bold,
- ),
- ),
- if (!group.isPublic)
- Padding(
- padding:
- const EdgeInsets
- .only(
- left:
- 8.0),
- child:
- Image.asset(
- "assets/images/lock.png",
- width: 20,
- height: 20,
- ),
- ),
- ],
- ),
- ],
- ),
- const SizedBox(height: 8.0),
- Row(
- children: [
- const Text("대표 카테고리 "),
- Text(group.groupCategory,
- style: TextStyle(
- color:
- textColor)),
- Expanded(
- child: Container()),
- Align(
- alignment: Alignment
- .centerRight,
- child: Text(
- "인원 ${group.joinMemberCount}/${group.maxMemberCount}명"),
- ),
- ],
- ),
- const SizedBox(height: 8.0),
- Row(
- mainAxisAlignment:
- MainAxisAlignment
- .spaceBetween,
- children: [
- Text(
- "루틴장 ${group.createdUserNickname}"),
- Text(
- "그룹코드 ${group.groupId}"),
- ],
- ),
- ],
- ),
- ),
- ),
- );
- },
- ),
- ),
- ],
- ),
- ),
- ),
- ),
- ],
- ),
- );
- }
-}
-
-class EntireGroup {
- final int groupId;
- final String groupTitle;
- final String groupCategory;
- final String createdUserNickname;
- final int maxMemberCount;
- final int joinMemberCount;
- final bool isPublic;
- final String? groupPassword;
-
- EntireGroup({
- required this.groupId,
- required this.groupTitle,
- required this.groupCategory,
- required this.createdUserNickname,
- required this.maxMemberCount,
- required this.joinMemberCount,
- required this.isPublic,
- this.groupPassword,
- });
-
- factory EntireGroup.fromJson(Map json) {
- return EntireGroup(
- groupId: json['groupId'] ?? 0,
- groupTitle: json['groupTitle'] ?? 'Unknown',
- groupCategory: json['groupCategory'] ?? '기타',
- createdUserNickname: json['createdUserNickname'] ?? 'Unknown',
- maxMemberCount: json['maxMemberCount'] ?? 0,
- joinMemberCount: json['joinMemberCount'] ?? 0,
- isPublic: json['isPublic'] ?? true,
- groupPassword: json['groupPassword'],
- );
- }
-}
\ No newline at end of file
diff --git a/lib/routine_home/AddRoutinePage.dart b/lib/routine_home/AddRoutinePage.dart
index cb4db22..b6a06f9 100644
--- a/lib/routine_home/AddRoutinePage.dart
+++ b/lib/routine_home/AddRoutinePage.dart
@@ -99,7 +99,8 @@ class _AddRoutinePageState extends State {
print('Response body: ${response.body}');
if (response.statusCode == 200 || response.statusCode == 201) {
- _showDialog('성공', '루틴이 성공적으로 추가되었습니다.');
+ Navigator.pushReplacement(context,
+ MaterialPageRoute(builder: (ctx) => const MyRoutinePage()));
} else {
_showDialog('오류', '루틴 추가에 실패했습니다: ${response.body}');
}
@@ -302,7 +303,7 @@ class _AddRoutinePageState extends State {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(
5,
- (index) => GestureDetector(
+ (index) => GestureDetector(
onTap: () {
setState(() {
selectedCategoryIndex = index;
@@ -320,7 +321,7 @@ class _AddRoutinePageState extends State {
: const Color(0xFFF0F0F0),
borderRadius: BorderRadius.circular(20),
border:
- Border.all(color: const Color(0xFFF0F0F0)),
+ Border.all(color: const Color(0xFFF0F0F0)),
),
alignment: Alignment.center,
child: Text(
@@ -449,7 +450,7 @@ class _AddRoutinePageState extends State {
onPressed: _addRoutine,
style: ButtonStyle(
backgroundColor:
- WidgetStateProperty.all(const Color(0xffB4DDFF)),
+ WidgetStateProperty.all(const Color(0xffB4DDFF)),
shape: WidgetStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0), //테두리 둥글게
@@ -494,4 +495,4 @@ class _AddRoutinePageState extends State {
return '';
}
}
-}
+}
\ No newline at end of file
diff --git a/lib/routine_home/MyRoutinePage.dart b/lib/routine_home/MyRoutinePage.dart
index 480fd9c..1de2665 100644
--- a/lib/routine_home/MyRoutinePage.dart
+++ b/lib/routine_home/MyRoutinePage.dart
@@ -173,6 +173,7 @@ class _MyRoutinePageState extends State
style: const TextStyle(fontSize: 20),
),
),
+ const SizedBox(height: 25),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
@@ -346,15 +347,30 @@ class _MyRoutinePageState extends State
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(
- child: Text('루틴을 불러오는 중 오류가 발생했습니다: ${snapshot.error}'));
+ child:
+ Text('루틴을 불러오는 중 오류가 발생했습니다: ${snapshot.error}'));
} else if (!snapshot.hasData ||
- (snapshot.data!.personalRoutines.isEmpty && snapshot.data!.groupRoutines.isEmpty)) {
+ (snapshot.data!.personalRoutines.isEmpty &&
+ snapshot.data!.groupRoutines.isEmpty)) {
// 개인 루틴과 그룹 루틴이 모두 비어있을 때 문구 표시
return const Center(
- child: Text(
- '\n\t\t\t\t\t\t\t\t 아래 + 버튼을 눌러 \n 새로운 루틴을 추가해보세요',
- style: TextStyle(fontSize: 20, color: Colors.grey),
- ));
+ child: Column(
+ children: [
+ SizedBox(height: 100,),
+ Image(
+ image: AssetImage('assets/images/new-icons/ice.png'),
+ width: 150, // 원하는 크기로 설정
+ height: 150,
+ ),
+ Text(
+ ' 아래 + 버튼을 눌러 \n 새로운 루틴을 추가해보세요',
+ style: TextStyle(fontSize: 20, color: Colors.grey, fontWeight: FontWeight.bold),
+ textAlign: TextAlign.center, // 텍스트 중앙 정렬
+ ),
+ ],
+ ),
+ );
+
}
// 감정 상태를 업데이트
@@ -369,7 +385,8 @@ class _MyRoutinePageState extends State
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
decoration: BoxDecoration(
color: const Color(0xFFE6F5F8), // 배경색 설정
- borderRadius: BorderRadius.circular(12), // 둥근 모서리 설정
+ borderRadius:
+ BorderRadius.circular(12), // 둥근 모서리 설정
),
child: Theme(
data: Theme.of(context).copyWith(
@@ -381,16 +398,21 @@ class _MyRoutinePageState extends State
fontSize: 20,
color: Colors.black)), // 텍스트 색상 변경
initiallyExpanded: true, // 초기상태를 펼친상태로 변경
- children: snapshot.data!.personalRoutines.map((category) {
+ children: snapshot.data!.personalRoutines
+ .map((category) {
return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
children: [
Padding(
- padding: const EdgeInsets.only(left: 10, top: 5),
+ padding: const EdgeInsets.only(
+ left: 10, top: 5),
child: Container(
decoration: BoxDecoration(
- color: const Color.fromARGB(255, 255, 255, 255),
- borderRadius: BorderRadius.circular(20.0),
+ color: const Color.fromARGB(
+ 255, 255, 255, 255),
+ borderRadius:
+ BorderRadius.circular(20.0),
),
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 1),
@@ -407,7 +429,8 @@ class _MyRoutinePageState extends State
),
// 카테고리 밑에 루틴 추가
...category.routines.map((routine) {
- return _buildRoutineTile(routine); // 기존 _buildRoutineTile 메서드 사용
+ return _buildRoutineTile(
+ routine); // 기존 _buildRoutineTile 메서드 사용
}),
],
);
@@ -424,7 +447,8 @@ class _MyRoutinePageState extends State
return Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Container(
- padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
+ padding:
+ const EdgeInsets.fromLTRB(10, 5, 10, 5),
decoration: BoxDecoration(
color: const Color(0xFFE6F5F8),
borderRadius: BorderRadius.circular(12),
@@ -435,8 +459,10 @@ class _MyRoutinePageState extends State
),
child: ExpansionTile(
title: Row(
- mainAxisAlignment: MainAxisAlignment.start, // 시작 부분에 배치
- crossAxisAlignment: CrossAxisAlignment.center, // 수직 중앙 정렬
+ mainAxisAlignment:
+ MainAxisAlignment.start, // 시작 부분에 배치
+ crossAxisAlignment:
+ CrossAxisAlignment.center, // 수직 중앙 정렬
children: [
Text(
group.groupTitle,
@@ -445,8 +471,10 @@ class _MyRoutinePageState extends State
color: Colors.black,
),
),
- const SizedBox(width: 8), // 제목과 아이콘 사이 간격
- if (group.isAlarmEnabled) // 알림이 활성화된 경우에만 벨 아이콘 표시
+ const SizedBox(
+ width: 8), // 제목과 아이콘 사이 간격
+ if (group
+ .isAlarmEnabled) // 알림이 활성화된 경우에만 벨 아이콘 표시
Image.asset(
'assets/images/bell.png', // bell.png 이미지 경로
width: 20,
@@ -454,26 +482,37 @@ class _MyRoutinePageState extends State
),
],
),
- children: group.groupRoutines.map((categoryGroup) {
+ children: group.groupRoutines
+ .map((categoryGroup) {
return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
children: [
Padding(
- padding: const EdgeInsets.only(left: 10),
+ padding:
+ const EdgeInsets.only(left: 10),
child: Container(
decoration: BoxDecoration(
- color: const Color.fromARGB(255, 255, 255, 255),
- borderRadius: BorderRadius.circular(20.0),
+ color: const Color.fromARGB(
+ 255, 255, 255, 255),
+ borderRadius:
+ BorderRadius.circular(20.0),
),
- padding: const EdgeInsets.symmetric(
- horizontal: 10.0, vertical: 1),
+ padding:
+ const EdgeInsets.symmetric(
+ horizontal: 10.0,
+ vertical: 1),
child: Column(
children: [
Text(
- categoryGroup.routineCategory, // 카테고리 이름
+ categoryGroup
+ .routineCategory, // 카테고리 이름
style: TextStyle(
- color: _getCategoryColor(categoryGroup.routineCategory),
- fontWeight: FontWeight.bold,
+ color: _getCategoryColor(
+ categoryGroup
+ .routineCategory),
+ fontWeight:
+ FontWeight.bold,
fontSize: 18,
),
),
@@ -482,7 +521,8 @@ class _MyRoutinePageState extends State
),
),
...categoryGroup.routines.map(
- (routine) => _buildRoutineTile2(routine)), // 루틴 목록
+ (routine) => _buildRoutineTile2(
+ routine)), // 루틴 목록
],
);
}).toList(),
@@ -499,7 +539,6 @@ class _MyRoutinePageState extends State
),
),
)
-
],
),
);
diff --git a/lib/routine_otherUser/OtherUserRoutinePage.dart b/lib/routine_otherUser/OtherUserRoutinePage.dart
index f23ca3d..e2a36f0 100644
--- a/lib/routine_otherUser/OtherUserRoutinePage.dart
+++ b/lib/routine_otherUser/OtherUserRoutinePage.dart
@@ -4,12 +4,12 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_calendar_week/flutter_calendar_week.dart';
-import 'package:intl/date_symbol_data_local.dart';
-import 'package:routine_ade/routine_myInfo/MyInfo.dart';
-import 'package:routine_ade/routine_group/GroupType.dart';
-import 'package:routine_ade/routine_group/GroupMainPage.dart';
-import 'package:routine_ade/routine_home/AlarmListPage.dart';
-import 'package:routine_ade/routine_home/ModifiedRoutinePage.dart';
+// import 'package:intl/date_symbol_data_local.dart';
+// import 'package:routine_ade/routine_myInfo/MyInfo.dart';
+// import 'package:routine_ade/routine_group/GroupType.dart';
+// import 'package:routine_ade/routine_group/GroupMainPage.dart';
+// import 'package:routine_ade/routine_home/AlarmListPage.dart';
+// import 'package:routine_ade/routine_home/ModifiedRoutinePage.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
@@ -20,7 +20,10 @@ import 'package:routine_ade/routine_statistics/StaticsCalendar.dart';
class OtherUserRoutinePage extends StatefulWidget {
final int userId;
- const OtherUserRoutinePage({required this.userId, super.key});
+ final int groupId;
+
+ const OtherUserRoutinePage(
+ {required this.userId, required this.groupId, super.key});
@override
State createState() => _OtherUserRoutinePageState();
@@ -47,8 +50,10 @@ class _OtherUserRoutinePageState extends State
super.initState();
_controller = CalendarWeekController();
+ String todayDate = DateFormat('yyyy.MM.dd').format(DateTime.now());
// 여기서 widget.userId로 접근해야 함
- futureRoutineResponse2 = fetchRoutinesByUserId(widget.userId);
+ futureRoutineResponse2 =
+ fetchRoutinesByUserId(widget.userId, widget.groupId, todayDate);
_tabController = TabController(length: 3, vsync: this);
}
@@ -98,7 +103,7 @@ class _OtherUserRoutinePageState extends State
final nickname = snapshot.data?.nickname ?? 'No nickname available';
final intro = snapshot.data?.intro ?? 'No intro available';
final userEmotion = snapshot.data?.userEmotion ?? 'null';
- final personalRoutines = snapshot.data?.personalRoutines ?? [];
+ // final personalRoutines = snapshot.data?.personalRoutines ?? [];
final groupRoutines = snapshot.data?.groupRoutines ?? [];
return Column(
@@ -114,7 +119,7 @@ class _OtherUserRoutinePageState extends State
backgroundImage: profileImage.isNotEmpty
? NetworkImage(profileImage)
: const AssetImage('assets/profile_placeholder.png')
- as ImageProvider,
+ as ImageProvider,
),
const SizedBox(width: 20),
Column(
@@ -154,7 +159,7 @@ class _OtherUserRoutinePageState extends State
unselectedLabelColor: Colors.grey,
indicator: const UnderlineTabIndicator(
borderSide:
- BorderSide(width: 3.0, color: Color(0xFF8DCCFF)),
+ BorderSide(width: 3.0, color: Color(0xFF8DCCFF)),
insets: EdgeInsets.symmetric(horizontal: 90.0),
),
),
@@ -190,17 +195,17 @@ class _OtherUserRoutinePageState extends State
children: [
const SizedBox(width: 10),
userEmotion.isNotEmpty &&
- getImageEmotion(userEmotion) != null
+ getImageEmotion(userEmotion) != null
? Image.asset(
- getImageEmotion(userEmotion)!,
- fit: BoxFit.cover,
- width: 50,
- height: 50,
- )
+ getImageEmotion(userEmotion)!,
+ fit: BoxFit.cover,
+ width: 50,
+ height: 50,
+ )
: Image.asset(
- "assets/images/new-icons/김외롭.png",
- width: 50,
- height: 50),
+ "assets/images/emotion/no-emotion.png",
+ width: 50,
+ height: 50),
const SizedBox(width: 10),
Expanded(
child: RichText(
@@ -208,7 +213,7 @@ class _OtherUserRoutinePageState extends State
style: const TextStyle(
fontSize: 18, color: Colors.black),
children:
- _buildEmotionText(userEmotion),
+ _buildEmotionText(userEmotion),
),
),
),
@@ -220,28 +225,27 @@ class _OtherUserRoutinePageState extends State
Expanded(
child: Container(
color: const Color(0xFFF8F8EF),
- child: personalRoutines.isEmpty &&
- groupRoutines.isEmpty
+ child: groupRoutines.isEmpty
? const Center(
- child: Text(
- ' 등록된 루틴이 없습니다.',
- style: TextStyle(
- fontSize: 20, color: Colors.grey),
- ),
- )
+ child: Text(
+ ' 등록된 루틴이 없습니다.',
+ style: TextStyle(
+ fontSize: 20, color: Colors.grey),
+ ),
+ )
: ListView(
- padding: const EdgeInsets.fromLTRB(
- 24, 10, 24, 16),
- children: [
- _buildRoutineSection(
- "개인 루틴", personalRoutines),
- const SizedBox(height: 10),
- ...groupRoutines.map((group) {
- return _buildGroupRoutineSection(group);
- }),
- const SizedBox(height: 10),
- ],
- ),
+ padding: const EdgeInsets.fromLTRB(
+ 24, 10, 24, 16),
+ children: [
+ // _buildRoutineSection(
+ // "개인 루틴", personalRoutines),
+ const SizedBox(height: 10),
+ ...groupRoutines.map((group) {
+ return _buildGroupRoutineSection(group);
+ }),
+ const SizedBox(height: 10),
+ ],
+ ),
),
),
],
@@ -297,7 +301,7 @@ class _OtherUserRoutinePageState extends State
const TextSpan(
text: '나쁜',
style:
- TextStyle(fontWeight: FontWeight.bold, color: Colors.redAccent),
+ TextStyle(fontWeight: FontWeight.bold, color: Colors.redAccent),
),
const TextSpan(text: ' 날이에요')
];
@@ -311,59 +315,6 @@ class _OtherUserRoutinePageState extends State
}
}
-// 개인 루틴 섹션 빌드
- Widget _buildRoutineSection(
- String title, List routines) {
- return routines.isNotEmpty
- ? Container(
- padding: const EdgeInsets.all(10),
- decoration: BoxDecoration(
- color: const Color(0xFFE6F5F8),
- borderRadius: BorderRadius.circular(12),
- ),
- child: Theme(
- data:
- Theme.of(context).copyWith(dividerColor: Colors.transparent),
- child: ExpansionTile(
- title: Text(
- title,
- style: const TextStyle(fontSize: 20, color: Colors.black),
- ),
- children: routines.map((category) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Padding(
- padding: const EdgeInsets.only(left: 10, top: 5),
- child: Container(
- decoration: BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.circular(20),
- ),
- padding: const EdgeInsets.symmetric(
- horizontal: 10, vertical: 1),
- child: Text(
- category.routineCategory,
- style: TextStyle(
- fontSize: 18,
- fontWeight: FontWeight.bold,
- color:
- _getCategoryColor(category.routineCategory),
- ),
- ),
- ),
- ),
- ...category.routines
- .map((routine) => _buildRoutineTile(routine)),
- ],
- );
- }).toList(),
- ),
- ),
- )
- : Container(); // 빈 루틴 섹션 처리
- }
-
// 그룹 루틴 섹션 빌드
Widget _buildGroupRoutineSection(Group2 group) {
return Container(
@@ -372,24 +323,36 @@ class _OtherUserRoutinePageState extends State
color: const Color(0xFFE6F5F8),
borderRadius: BorderRadius.circular(12),
),
- child: Theme(
- data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
- child: ExpansionTile(
- title: Text(group.groupTitle,
- style: const TextStyle(fontSize: 20, color: Colors.black)),
- children: group.groupRoutines.map((categoryGroup) {
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ // 그룹 제목 표시
+ Padding(
+ padding: const EdgeInsets.only(left: 10),
+ child: Text(
+ group.groupTitle,
+ style: const TextStyle(
+ fontSize: 20,
+ color: Colors.black,
+ fontWeight: FontWeight.bold),
+ ),
+ ),
+ const SizedBox(height: 15),
+
+ // 그룹 루틴 카테고리 및 루틴 항목들 표시
+ ...group.groupRoutines.map((categoryGroup) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
- padding: const EdgeInsets.only(left: 10),
+ padding: const EdgeInsets.only(left: 10, bottom: 5),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
padding:
- const EdgeInsets.symmetric(horizontal: 10, vertical: 1),
+ const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: Text(
categoryGroup.routineCategory,
style: TextStyle(
@@ -404,8 +367,8 @@ class _OtherUserRoutinePageState extends State
.map((routine) => _buildRoutineTile2(routine)),
],
);
- }).toList(),
- ),
+ }),
+ ],
),
);
}
@@ -466,12 +429,12 @@ class _OtherUserRoutinePageState extends State
activeColor: const Color(0xFF8DCCFF),
checkColor: Colors.white,
fillColor: WidgetStateProperty.resolveWith(
- (Set states) {
- if (states.contains(WidgetState.selected)) {
- return const Color(0xFF8DCCFF);
- }
- return Colors.transparent;
- }),
+ (Set states) {
+ if (states.contains(WidgetState.selected)) {
+ return const Color(0xFF8DCCFF);
+ }
+ return Colors.transparent;
+ }),
),
),
),
@@ -507,69 +470,21 @@ class _OtherUserRoutinePageState extends State
),
);
}
-
- Widget _buildRoutineTile(Routine routine) {
- Color categoryColor = _getCategoryColor(routine.routineCategory);
-
-//개인루틴
- return Padding(
- padding: const EdgeInsets.symmetric(vertical: 0),
- child: ListTile(
- contentPadding: const EdgeInsets.symmetric(horizontal: 20), // 좌우 여백 조절
- minLeadingWidth: 0,
- leading: const Icon(
- Icons.brightness_1,
- size: 8,
- color: Colors.black,
- ),
- title: Row(
- mainAxisSize: MainAxisSize.min,
- mainAxisAlignment:
- MainAxisAlignment.start, // Align elements to the start of the row
- children: [
- Text(routine.routineTitle,
- style: const TextStyle(fontWeight: FontWeight.bold)),
- const SizedBox(width: 3), // Adjust the width as needed
- if (routine.isAlarmEnabled) // Conditionally display the bell icon
- GestureDetector(
- onTap: () {
- // Do nothing when the image is tapped3
- },
- child: Image.asset('assets/images/bell.png',
- width: 20, height: 20),
- ),
- ],
- ),
- trailing: Transform.scale(
- scale: 1.2, // Checkbox size increased by 1.5 times
- child: Checkbox(
- value: routine.isCompletion,
- onChanged: (bool? value) {},
- activeColor: const Color(0xFF8DCCFF),
- checkColor: Colors.white,
- fillColor: WidgetStateProperty.resolveWith(
- (Set states) {
- if (states.contains(WidgetState.selected)) {
- return const Color(0xFF8DCCFF);
- }
- return Colors.transparent;
- }),
- ),
- ),
- ),
- );
- }
}
//루틴, 감정 조회
-Future fetchRoutinesByUserId(int userId) async {
+Future fetchRoutinesByUserId(
+ int userId, int groupId, String routineDate) async {
+ print('사용할 토큰: $token'); // 요청 전에 토큰을 출력하여 확인
print('API 요청 사용자 ID: $userId'); // 요청할 사용자 ID를 출력하여 확인
+ print('요청그룹: $groupId ');
try {
final response = await http.get(
- Uri.parse('http://15.164.88.94/users/$userId/routines'), // userId로 조회
+ Uri.parse(
+ 'http://15.164.88.94/groups/$groupId/users/$userId/routines?routineDate=$routineDate'),
headers: {
- 'Authorization': 'Bearer $token', // 적절한 토큰 사용
+ 'Authorization': 'Bearer $token',
'Content-Type': 'application/json; charset=UTF-8', // UTF-8 설정
},
);
@@ -605,7 +520,7 @@ String? getImageEmotion(String emotion) {
case 'ANGRY':
return 'assets/images/emotion/angry.png';
default:
- return "assets/images/new-icons/김외롭.png"; // 기본 이미지
+ return "assets/images/emotion/no-emotion.png"; // 기본 이미지
}
}
@@ -620,8 +535,8 @@ String getTextForEmotion(String emotion) {
return '이 날은 기분이 우중충한 날이에요';
case 'ANGRY':
return '이 날은 기분이 나쁜 날이에요';
- // case 'null':
- // return '기분을 추가해보세요!';
+ // case 'null':
+ // return '기분을 추가해보세요!';
default:
return '기분을 추가해보세요!'; // 기본 텍스트
}
@@ -633,10 +548,10 @@ class RoutineResponse2 {
final String profileImage;
final String nickname;
final String intro;
- final List personalRoutines;
- final List groupRoutines;
+ // final List personalRoutines;
+ final List groupRoutines; //userGroupInfo
final String userEmotion;
- final List routines;
+ // final List routines;
// final List groupRoutineCategories;
RoutineResponse2({
@@ -644,10 +559,10 @@ class RoutineResponse2 {
required this.profileImage,
required this.nickname,
required this.intro,
- required this.personalRoutines,
+ // required this.personalRoutines,
required this.groupRoutines,
required this.userEmotion,
- required this.routines,
+ // required this.routines,
// required this.groupRoutineCategories,
});
@@ -657,75 +572,11 @@ class RoutineResponse2 {
profileImage: json['profileImage'] ?? '', // 한국어로 된 필드명을 사용하여 데이터를 파싱
nickname: json['nickname'] ?? '기타',
intro: json['intro'] ?? '기타',
- personalRoutines: (json['personalRoutines'] as List?)
- ?.map((item) =>
- UserRoutineCategory.fromJson(item as Map))
- .toList() ??
- [],
- groupRoutines: (json['groupRoutines'] as List?)
- ?.map((item) => Group2.fromJson(item as Map))
- .toList() ??
+ groupRoutines: (json['userGroupInfo'] as List?)
+ ?.map((item) => Group2.fromJson(item as Map))
+ .toList() ??
[],
userEmotion: json['userEmotion'] ?? 'null',
- routines: (json['routines'] as List?)
- ?.map((item) =>
- UserRoutineCategory.fromJson(item as Map))
- .toList() ??
- [],
- );
- }
-}
-
-// 개인 루틴
-class Routine {
- final int routineId;
- final String routineTitle;
- final String routineCategory;
- bool isAlarmEnabled; // isAlarmEnabled를 mutable로 변경
- final String startDate;
- final List repeatDays;
- bool isCompletion;
-
- Routine(
- {required this.routineId,
- required this.routineTitle,
- required this.routineCategory,
- required this.isAlarmEnabled,
- required this.startDate,
- required this.repeatDays,
- this.isCompletion = false});
-
- factory Routine.fromJson(Map json) {
- return Routine(
- routineId: json['routineId'] ?? 0, //기본값 설정
- routineTitle: json['routineTitle'] ?? '', // 한국어로 된 필드명을 사용하여 데이터를 파싱
- routineCategory: json['routineCategory'] ?? '기타',
- isAlarmEnabled: json['isAlarmEnabled'] ?? false,
- startDate:
- json["startDate"] ?? DateFormat('yyyy.MM.dd').format(DateTime.now()),
- repeatDays: List.from(json["repeatDays"] ?? []),
- isCompletion: json['isCompletion'] ?? false,
- );
- }
-}
-
-// 개인 카테고리 그룹
-class UserRoutineCategory {
- final String routineCategory;
- final List routines;
-
- UserRoutineCategory({
- required this.routineCategory,
- required this.routines,
- });
-
- factory UserRoutineCategory.fromJson(Map json) {
- return UserRoutineCategory(
- routineCategory: json['routineCategory'] ?? '',
- routines: (json['routines'] as List)
- .map((item) => Routine.fromJson(item))
- .toList() ??
- [],
);
}
}
@@ -795,4 +646,4 @@ class Group2 {
.toList(),
);
}
-}
+}
\ No newline at end of file
diff --git a/lib/routine_statistics/StaticsCalendar.dart b/lib/routine_statistics/StaticsCalendar.dart
index eaf4542..01e617d 100644
--- a/lib/routine_statistics/StaticsCalendar.dart
+++ b/lib/routine_statistics/StaticsCalendar.dart
@@ -164,8 +164,7 @@ class _StaticsCalendarState extends State
// 더보기 버튼 클릭 시 동작할 코드
Navigator.push(
context,
- MaterialPageRoute(
- builder: (context) => const MyInfo()),
+ MaterialPageRoute(builder: (context) => const MyInfo()),
);
},
child: SizedBox(
diff --git a/lib/routine_user/token.dart b/lib/routine_user/token.dart
index 537a01f..5704b31 100644
--- a/lib/routine_user/token.dart
+++ b/lib/routine_user/token.dart
@@ -10,7 +10,7 @@ class TokenManager {
// 토큰을 저장하고 전역 변수 업데이트
static Future saveToken(String newToken) async {
final prefs =
- await SharedPreferences.getInstance(); // SharedPreferences에 저장
+ await SharedPreferences.getInstance(); // SharedPreferences에 저장
await prefs.setString('authToken', newToken);
token = newToken; // 전역 변수 업데이트
@@ -19,7 +19,7 @@ class TokenManager {
// 저장된 토큰을 불러오고 전역 변수 업데이트
static Future getToken() async {
final prefs =
- await SharedPreferences.getInstance(); // SharedPreferences에서 불러오기
+ await SharedPreferences.getInstance(); // SharedPreferences에서 불러오기
String? storedToken = prefs.getString('authToken');
if (storedToken != null) {
@@ -32,8 +32,8 @@ class TokenManager {
// 토큰을 삭제
static Future clearToken() async {
final prefs =
- await SharedPreferences.getInstance(); // SharedPreferences에서 삭제
+ await SharedPreferences.getInstance(); // SharedPreferences에서 삭제
await prefs.remove('authToken');
token = ''; // 전역 변수 초기화
}
-}
\ No newline at end of file
+}
diff --git a/pubspec.lock b/pubspec.lock
index a225998..2932bbe 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -149,10 +149,10 @@ packages:
dependency: transitive
description:
name: file
- sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
+ sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev"
source: hosted
- version: "7.0.0"
+ version: "7.0.1"
file_selector_linux:
dependency: transitive
description:
@@ -369,7 +369,7 @@ packages:
source: hosted
version: "1.4.2"
kakao_flutter_sdk_common:
- dependency: transitive
+ dependency: "direct main"
description:
name: kakao_flutter_sdk_common
sha256: "76eccd72a4e94db9c6be69b670477528d958d2bf38f50a2158dfd306640c7abf"
@@ -425,7 +425,7 @@ packages:
source: hosted
version: "1.4.2"
kakao_flutter_sdk_user:
- dependency: transitive
+ dependency: "direct main"
description:
name: kakao_flutter_sdk_user
sha256: "168bff0eb2742a352cbf3b64c60dff88deb89d959cf7375ea3e0e8416ab138e4"
@@ -436,18 +436,18 @@ packages:
dependency: transitive
description:
name: leak_tracker
- sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
+ sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted
- version: "10.0.4"
+ version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
- sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
+ sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
- version: "3.0.3"
+ version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
@@ -476,18 +476,18 @@ packages:
dependency: transitive
description:
name: material_color_utilities
- sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
+ sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
- version: "0.8.0"
+ version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
- sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
+ sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
- version: "1.12.0"
+ version: "1.15.0"
mime:
dependency: "direct main"
description:
@@ -761,10 +761,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
+ sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted
- version: "0.7.0"
+ version: "0.7.2"
typed_data:
dependency: transitive
description:
@@ -801,10 +801,10 @@ packages:
dependency: "direct main"
description:
name: url_launcher
- sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
+ sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
url: "https://pub.dev"
source: hosted
- version: "6.3.0"
+ version: "6.3.1"
url_launcher_android:
dependency: transitive
description:
@@ -873,10 +873,10 @@ packages:
dependency: transitive
description:
name: vm_service
- sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
+ sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev"
source: hosted
- version: "14.2.1"
+ version: "14.2.5"
web:
dependency: transitive
description:
@@ -942,5 +942,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
- dart: "3.4.4"
+ dart: "3.5.3"
flutter: ">=3.22.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 9fe039a..260441b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -4,7 +4,7 @@ description: "A new Flutter project."
version: 1.0.0+1
environment:
- sdk: '3.4.4'
+ sdk: "3.5.3"
dependencies:
flutter:
@@ -14,10 +14,9 @@ dependencies:
image: ^3.0.1
permission_handler: ^10.2.0
- #추가한 패키지
+ # 추가한 패키지
flutter_calendar_week: ^3.0.1
intl: ^0.18.0
-
cupertino_icons: ^1.0.6
json_annotation: ^4.0.1
shelf_swagger_ui: ^1.0.0+2
@@ -27,7 +26,10 @@ dependencies:
shared_preferences: ^2.0.8
table_calendar: ^3.0.0
fl_chart: ^0.69.0
- kakao_flutter_sdk: ^1.1.0 #카카오로그인
+ kakao_flutter_sdk: ^1.1.0 # 카카오 로그인
+ kakao_flutter_sdk_user: ^1.2.0
+ kakao_flutter_sdk_common: ^1.0.0
+
url_launcher: ^6.0.20 # 카카오 로그인
webview_flutter: ^3.0.4
uni_links: ^0.5.1
@@ -36,9 +38,16 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
-
flutter_lints: ^3.0.0
+# Flutter Icons 설정 추가
+flutter_icons:
+ android: true
+ ios: true
+ image_path: "assets/images/new-icons/routineade.png"
+ adaptive_icon_background: "#FFFFFF" # 안드로이드용 Adaptive 아이콘 배경색
+ adaptive_icon_foreground: "assets/images/new-icons/RoutineAde.png" # 안드로이드 Adaptive 아이콘
+
flutter:
uses-material-design: true
@@ -53,4 +62,4 @@ fonts:
fonts:
- asset: assets/fonts/NotoSansKR-Regular.otf
- asset: assets/fonts/NotoSansKR-Bold.otf
- - asset: assets/fonts/NotoSansKR-Medium.otf
\ No newline at end of file
+ - asset: assets/fonts/NotoSansKR-Medium.otf