Skip to content

Commit

Permalink
✨feat : 데일리기록 보기 완성
Browse files Browse the repository at this point in the history
  • Loading branch information
seochan99 committed Feb 19, 2024
1 parent eda6bcc commit d38bb98
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 95 deletions.
1 change: 1 addition & 0 deletions lib/main_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class MainApp extends StatelessWidget {
Routes.routes[1],
Routes.routes[2],
Routes.routes[3],
Routes.routes[4],
],
);
}
Expand Down
5 changes: 5 additions & 0 deletions lib/utilities/app_routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:earlips/views/home/home_screen.dart';
import 'package:earlips/views/profile/profile_account/profile_account_screen.dart';
import 'package:earlips/views/profile/profile_language_setting/profile_language_setting.dart';
import 'package:earlips/views/profile/profile_screen.dart';
import 'package:earlips/views/study/study_main.dart';
import 'package:get/get.dart';

abstract class Routes {
Expand All @@ -20,6 +21,10 @@ abstract class Routes {
name: HOME,
page: () => HomeScreen(),
),
GetPage(
name: STUDY,
page: () => const StudyMain(),
),
GetPage(
name: PROFILE,
page: () => const ProfileScreen(),
Expand Down
61 changes: 49 additions & 12 deletions lib/viewModels/study/date_study_screen_viewmodel.dart
Original file line number Diff line number Diff line change
@@ -1,24 +1,61 @@
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:intl/intl.dart';

class LearningSession {
final String type; // 세션 유형 (음소, 단어, 문장)
final DateTime createdDate; // 세션 생성 날짜
final int type; // 세션 유형 (음소, 단어, 문장)
final String createdDate; // 세션 생성 날짜
final String text; // 세션과 관련된 텍스트
final int index; // 세션 인덱스

LearningSession({required this.type, required this.createdDate, required this.text});
LearningSession(
{required this.type,
required this.createdDate,
required this.text,
required this.index});
}

class DateStudyViewModel {
final DateTime date;

final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final FirebaseAuth _auth = FirebaseAuth.instance;
DateStudyViewModel({required this.date});

List<LearningSession> getSessions() {
// 실제 애플리케이션에서는 여기서 날짜에 따라 데이터를 조회하거나 필터링하는 로직을 구현할 수 있습니다.
return [
LearningSession(type: '음소', createdDate: DateTime(2024, 2, 12), text: "가"),
LearningSession(type: '단어', createdDate: DateTime(2024, 2, 13), text: "가다"),
LearningSession(type: '문장', createdDate: DateTime(2024, 2, 14), text: "가다 보면 길이 있다."),
];
Future<List<LearningSession>> getSessions() async {
// 파이어스토어에 저장된 날짜 형식에 맞게 날짜를 변환
final uid = _auth.currentUser?.uid;

String formattedDate = DateFormat('yyyyMMdd').format(date);
try {
// 해당 날짜의 daily record 문서를 가져옴
DocumentSnapshot dailyRecordSnapshot = await _firestore
.collection('users')
.doc(uid)
.collection('daily_records')
.doc(formattedDate)
.get();

if (dailyRecordSnapshot.exists) {
// 해당 날짜의 세션 데이터를 가져옴
List<Map<String, dynamic>> sessionsData =
List<Map<String, dynamic>>.from(
dailyRecordSnapshot.get('wordsList') ?? []);
// 세션 데이터를 LearningSession 객체로 변환
List<LearningSession> sessions = sessionsData.map((session) {
return LearningSession(
type: session['type'],
createdDate: formattedDate,
text: session['word'],
index: session['index'],
);
}).toList();

return sessions;
} else {
return [];
}
} catch (error) {
return [];
}
}
}
4 changes: 3 additions & 1 deletion lib/viewModels/word/word_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,21 @@ class WordViewModel extends GetxController {
existingWordsList.add({
'word': word.word,
'type': word.type,
'index': currentIndex.value
});

// 업데이트
transaction
.update(dailyRecordRef, {'wordsList': existingWordsList});
}
} else {
// If the document doesn't exist, create a new one with the initial word
// 만약 daily record가 없다면 새로 생성
transaction.set(dailyRecordRef, {
'wordsList': [
{
'word': word.word,
'type': word.type,
'index': currentIndex.value
},
],
});
Expand Down
178 changes: 106 additions & 72 deletions lib/views/study/date_study_screen.dart
Original file line number Diff line number Diff line change
@@ -1,96 +1,130 @@
import 'package:earlips/utilities/style/color_styles.dart';
import 'package:earlips/viewModels/study/date_study_screen_viewmodel.dart';
import 'package:earlips/views/base/default_back_appbar.dart';
import 'package:earlips/views/study/widget/study_row_card_widget.dart';
import 'package:earlips/views/word/word_screen.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
// ViewModel import 경로는 실제 프로젝트 구조에 따라 달라질 수 있습니다.
import 'package:earlips/viewModels/study/date_study_screen_viewmodel.dart';

class DateStudyScreen extends StatelessWidget {
final DateTime date;

const DateStudyScreen({super.key, required this.date});

@override
Widget build(BuildContext context) {
final viewModel = DateStudyViewModel(date: date);
final sessions = viewModel.getSessions();

return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(kToolbarHeight),
child: DefaultBackAppbar(
title: DateFormat('yyyy/MM/dd').format(date),
),
),
body: ListView.separated(
padding: const EdgeInsets.fromLTRB(25, 20, 25, 20),
itemCount: sessions.length,
itemBuilder: (context, index) {
var session = sessions[index];
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.15),
spreadRadius: 0.1,
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
Container(
alignment: Alignment.centerLeft,
margin: const EdgeInsets.only(left: 20.0, top: 16.0),
child: _SmallCard(name: session.type)), // 세션 유형을 표시
ListTile(
contentPadding:
const EdgeInsets.only(left: 20, right: 20, bottom: 30),
title: Container(
alignment: Alignment.center,
child: Text(
session.text, // 세션과 관련된 텍스트를 표시
style: const TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
body: FutureBuilder<List<LearningSession>>(
future: DateStudyViewModel(date: date).getSessions(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.hasError) {
return Center(
child: Text('Error: ${snapshot.error}'),
);
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('등록된 학습 기록이 없습니다.'),
const SizedBox(height: 20),
// 학습하러가기
ElevatedButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(
const EdgeInsets.fromLTRB(20, 10, 20, 10),
),
backgroundColor:
MaterialStateProperty.all(ColorSystem.main2),
),
onPressed: () {
Get.back();
},
child: const Text(
'학습하러가기',
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
),
),
),
onTap: () {},
),
],
),
);
],
),
);
} else {
return ListView.separated(
padding: const EdgeInsets.fromLTRB(25, 20, 25, 20),
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var session = snapshot.data![index];
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.15),
spreadRadius: 0.1,
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
children: [
Container(
alignment: Alignment.centerLeft,
margin: const EdgeInsets.only(left: 20.0, top: 16.0),
child: SmallCard(type: session.type),
),
ListTile(
contentPadding: const EdgeInsets.only(
left: 20, right: 20, bottom: 30),
title: Container(
alignment: Alignment.center,
child: Text(
session.text,
style: const TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
),
),
),
onTap: () {
Get.to(
() => WordScreen(
// session type에 따라 다른 tttle
title: session.type == 0
? '음소'
: (session.type == 1
? '단어'
: (session.type == 2
? '문장'
: '문단')),
type: 0,
),
arguments: session.index);
},
),
],
),
);
},
separatorBuilder: (context, index) => const SizedBox(height: 20),
);
}
},
separatorBuilder: (context, index) => const SizedBox(height: 20),
),
);
}
}

class _SmallCard extends StatelessWidget {
final String name;

const _SmallCard({super.key, required this.name});

@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.0),
color: const Color(0xFF1FA9DC),
),
alignment: Alignment.center,
width: 50,
height: 24,
child: Text(
name,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
);
}
Expand Down
20 changes: 18 additions & 2 deletions lib/views/study/widget/study_row_card_widget.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
import 'package:flutter/material.dart';

class SmallCard extends StatelessWidget {
final String name;
final int type;

const SmallCard({super.key, required this.name});
const SmallCard({super.key, required this.type});

// type에 따라 name을 반환
String get name {
switch (type) {
case 0:
return '음소';
case 1:
return '단어';
case 2:
return '문장';
case 3:
return '문단';
default:
return '음소';
}
}

@override
Widget build(BuildContext context) {
Expand Down
3 changes: 3 additions & 0 deletions lib/views/word/widget/word_list_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ class _WordListState extends State<WordList> {
color: ColorSystem.gray5,
),
),
const SizedBox(
width: 5,
),
const Icon(
Icons.check_circle_rounded,
color: ColorSystem.green,
Expand Down
Loading

0 comments on commit d38bb98

Please sign in to comment.