From 3f21a084bdfe8ad00bb0ed2b014bfed7ed29c896 Mon Sep 17 00:00:00 2001 From: Naresh Pratista <2141720057@student.polinema.ac.id> Date: Wed, 6 Nov 2024 13:28:28 +0700 Subject: [PATCH] refactor: auto refresh after submit feedback and app configuration --- android/app/src/main/AndroidManifest.xml | 2 +- .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 8691 bytes lib/core/services/constants.dart | 2 +- .../history/screens/history_screen.dart | 3 - .../exercises/screens/exercise_screen.dart | 6 ++ .../exercises/widgets/exercise_navigator.dart | 6 ++ .../feedback/providers/feedback_provider.dart | 0 .../feedback/screens/feedback_screen.dart | 35 +++++--- .../level/providers/level_provider.dart | 59 -------------- .../level/screens/level_list_screen.dart | 75 +++++++++--------- .../modules/level/widgets/level_card.dart | 2 + .../modules/level/widgets/pretest_card.dart | 29 +------ .../material/screens/material_screen.dart | 6 ++ .../modules/result/screens/result_screen.dart | 10 +++ .../widgets/complete_result_widget.dart | 6 ++ .../result/widgets/down_result_widget.dart | 6 ++ .../result/widgets/jump_result_widget.dart | 17 ++-- .../topics/screens/topics_list_screen.dart | 4 +- 18 files changed, 125 insertions(+), 143 deletions(-) delete mode 100644 lib/features/learning/modules/feedback/providers/feedback_provider.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d0dd89a..82dcef6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ khACW+E6a2Q4IJ6GGZH_v4JO%*iEgOFbaQEIeScr)6aorDU`qif4FQ_m_4@UrM zbEO5R#R1UDbaQs}OGL~wSaE7DpCractXZ7Z1J9gL4k#JLU~LCy%{|C^#Vj?1Hu5k^ z1O84^c$vH+KveGEYK+{Y|i5R8BVnN6r%{}9tMQU6RW-B0Rvv0EQ1itA0SZv^<*R=vnx>Of^L{m%wRy?fCe6>;>`8TasR0-}*Ndk?D zI%vmI3eL*ru90}^5*|x#J4vY3{NXDrl2&5)#bq$)@*d1uGi7 z^|(9>bUgms(CIr2KMkz&_O_jpW}1L@zwF$Vq#9AdKV-R*Wj4+FR4j9oF+5kblWE~b zsbvm}9}PA2wKJ|x56FYtI>5o8+Fs&H;9jmy#Wu-xZn7j|KFcj#MG*w+Uo6-3*e=kj zFuVBK8yqG95JKvt5yu05C77)J-0zAoc0+!cDRmWa`$ty71C9 zKSm>enkbK*F`aDXY|jzWeC3eSBZi-xEV*VVv7Cc|U{$4#Y#G;`c)~ZR*h%e+S~hgD zc30^=moq$)t0tAkkul5A1~j!FC4^yb*5&)*ZHhNLJa;=CnQ4?3nO2b$W4K(y^QQ@AqA_4j>%*4_k2WX9D?1QTzy<7JU3+A;Cf|r ze$6Z7hL;iMu$)*Jqbc3l#2pFVF+#~mhwRzQla`y_NJC$qEmAY5S!-xL|5K-AF+U5O zBwOX0{)SxzuyjjB7YMZ;?oXWj2{w07k}(DS*9JYGwH5J~ew3SudPS>|mOi~ie4SdF zh>}j}#ALb2E6Kqv}tf#EZq}%!c9{MplikWE_)3NP_n_zGXG$ zEaePK+&mma}hpQ&wQ&y)ZWx?lbpt5oU;2UU^FeE7sgt*7-hGiUXt zj}qZ0?6oAo`_uEkV~b7-a;Lwn%^vcFU3sLL)U3qODh<9ikJBgcfk=lCSURZF^A#Um z%PpvrysHfyi0fRlp07BzCu3Sw)bncs>$su1F~|tSvVD&UdVft)|4-)rH7wyy7r&+C zs84%X(c}GqurHgBUz`5MOk~!1Hux%qXTnoaO#pAEM5L7lZi=Md7EtO@qfQzAS{)3g1w6R$xvY@JLPBZtey^mll(UuD0mhe<%L!?B}UA z+gxl1wxpA6pWhmMviSTr#DNi$(SQ28UlRM*BHRy|o?k3<>mW$O#}oXDbcYANK!HOPJ{DEVLBM+KCjcEF~!c0H?pG}<5DstOlU zEb|_3iho zh}p@MV}X@>lPy^j!>wtTzd08&0}o;vaq;(OtuGEv=!|VefUotLbqjJ})dm{e&l8p% znn;TFLQ{|$j)1T=56>6Yw6c32wes=L+r`K>i}$T`5c`X|qNK;nBYOIxw&L&Z0uDtz zGIx`vI;9+}8|{bk8dATXi*o;I4%d-S-yg@k*aLbWP4%cJDu7ZKqVDV@kGmQV6*2z8 zoGsCDI7>I}Szo+o#}HEd5x*w1Pc{7}aa{`3>tOcz_IEoGG)$X*ZabxNRg48M#4YPq z*6LGu8)d^k%P(T!)DBhok(!8l|JuTPG%q}HQ45}q&qIO85PYwFLDcn_M5j0dLOzL^ zii>0bT|2y{i8Oja6FBTSDhwy##TV%(@n=-Z<3@&;2`Aw!b}4S<%yJiFbT5f%^=ZE6 z$tS@3DbAZqRr$dvd4XM*q%~oiGT@YL%3K;vS$r2Mrxog|kbn+yM8Q{AVe1Kb)(V^d z6!ScDU^H#T3fRDfiRm&F^&53`-3*@l2@d9)*MHTlH$tA(_B0UjYmx;PcEQCujvX@; zJm6E{N zqInjt^kRiQV%L{I)IGQ5KLfYhxYV2h&O9^0=P7H<3EklczQHv)u-%@ewPn+*eow6|fJHati=oi~QFZgBBgu%fDb3q1B@5fAmFfzkatX zltX}unNa+`2d^=45M)Dm%cX*f(2tnyTSeq_agIxt%LxI7%J&N5m9GPHwSU84{ar~7 z_?9z`ne5Lp=m2?c8hk%y?f`{X>Sw8Q0T1Hh%Mg>Yc_UD4;aT!ep_W8|Iyui9)wp}I*uf&$^}>28R8n%$N;Z79N})1i^wvVymG+?Utf zogJIUJoP}-+39N?x4DrMtwQX+ptHZ`;Jk5mn+%$O&P&W@f~Va6@d zIWO;Y8j0L^ML-oXz9E0rYA6b=e^zbVKS6%-u>PAQ_as0ofH8Yszlgs}v`-DkrduEk z`2*PmCcN@!MKIQI)LoG9mLV#L4lL5OD)-u<`OOUwz6V{$#IYMK_pkNEzoDn?NJH;t zqI7wCMeb;jau}3eV9_UW<*%UHzS|iBThHkOG{4twmqXNPkR+%N(+EkD4{aae6?{{t zJZuYv0VD!Ji2po~fAlU1>W(l+#ved-UO)*gmrVcB+# zSDr#u6z|2B9a(pGfC{%5X65;GhgiihhLOpcB+d7xJ?`D$2hN@*X@v|#eFdzN2$3e52h7ee-pY7fCi6 z7vBwP#0G3#K^9hzGlj4>y29~D7{`aHH|t|>%o3jM0LGDzzfp$pBWhbk`WysF23(&d zDCB@`)k6&CYr5j=qE}t#?WLh?!LlHLw5oF|7Lqx8574+z)~8@7P=h%skIk*VZoXzW z3S%dlwtEi+T_dLYQ=22~fnY>;MNG9%4-w9;bGb_F$&BmCn)eXed_wX8vPvgzoW{ifj0eZ#Td< zz8Hayt=D4L%E=O*o}GRUsyg6^>w?I07xXE8z3ex9#Lr9Ro9FF*kR>|qNa=$2`mTU9 z{4)t!Z@-59!fQA&jPMXIJBR45#RcEa!-|sl5voPdD`8dmdG*7pS9dZ%lyWgWM9N!9L>YQ$rCAeVVwviUoyN` zl4Zv-)E9~Wpu}ZA%$q`FD+0?W1w#2PL4xH-YAz+?8rJui2TwKhIBy%cJ0VHve7i*? z$_)4Zi7rZ!StRTBO*)t#5GQmdT8!ZJM$Z?mFMXkyLWSSS#5mH_HbR9YunjsTz;^qc z;ZONcui@XVOAYc`xH_d;NZ>X6TCbv(OG%K1q@|%>?KhVEz}XubpyZ6II#e_sBk&Gk zz6xBMwjR@VH&wcs{s=sy`a>xzM7;eJ^c5P~{fM%3kZxM4sDr2@rz}u!uvjxK zlnm_Ug6L0qUNJG%$37=aR3A1Z*vM?_slb}F^+?7~`QFe&~~YMEvoYdEY{7TMf$EBSYTjuv_&Q8*GXYc6A#OQ#iMw2z*upjJ8IWGg2?3Ux2tsal2nW9xz7|dFL(w<9)6=lo?l+6TyL>}A<4C)K@gXE&eJ}1ejhJqKnU-s!kumg7 zZu&lN*egsjv{6R$o<|pma6@-ojYX70$5RCwyW-fPG#U7ruPBF~-RJBM73tz^oo;qL zTp4y2CmjC`yt%lHEq?yf(C|;Gh(M=3?IXqMairCE&If)T1e(>u0*+pP%Yaw=0wtIE z;7RXTg9oWniZ&++UM-aHOe3~U(#T$|H!gZ4otuIZ9t}!1NfxRg2!E->1$snYK1B42 zIHv#dX(m4pqw0;=AUbC9phE^_8S$g#b%N;aAJ!AYIgneC?qebz_3j-cexbL|qgNM~ z+zN44*}`YKZ8?*qbV>%LZ?NXCiaT<<*?o&iqjQ0S^q8ts0`=zW3&~}Z`RIr(p^t$v z3_C-yjjbQLV^yJrTmSY}Q8yzp<`kIcJ73%T6xv*WKF-3|3h%Akba*uiFQmb?o1LGseShNGJpzmoa%kub-!FJxIFAKS^qE6U67tQ?_E z)j>&D?rDcI4ie*%+ZV%?vMokN6pUKBsaFcOme&(FBePfd zhDRz#+`FnM7Mqu9XTG5nK%o+%G&E@q(ssXeQeY^IE?0;eEtVrLD(A`|aSeTGNy8AA zFA8VVT@@jJG2lT6^+i`FG&nsXQg>5;GwB3k6vyjwp4BQw4|Uk>u*HgTGGA`_B?Y^Rx3Hn1zg&)(GcDmcym;4N3LQG zg=hvdO#5JyKeoT!_ws&LdBMb&HMVAO9g46o9Neohk@dBHYP&sHan~xFNr1Vrjdl`6 zaC%FTs0p!+SVNNJ>NL=Q9!0^uV9dxZXfnlYWD0+7dXj0fHArxzR@ng%b}N9d4+WSw zp8F5$E-fL)uTttrM*$4oV68R%2Ro-Kx<7R1n&gW=CZ3>(=gU1W+Hhpq;1QKL#W*90 zV0K&T>v>4%+tK&K2N@3Gd1jr!Yx&rKw}TuagsY0lz1731+xef?*N4#&p8c%>PLf>f z2qVuQxriQ?Xzz1VGo-^M6rtIz8)4L96yGQok=jmHvfreu4$PmM!sn^GVRMfq%P{^U z;e=MON_i~XgH(1WPvtid>>067B0q@a55}&;;U>~T7cRz(!6*0lU%E#$Fm0I|jT_+( z9Muj`KdwEaCQkZ%r(jg*+NS(*Kpv|lX50T>l-G?SD7?-SSA zZROiRF=XZohquph`%+DudZ@u<;nCD8WBmtZ_9B@=Ed*iG`Z^x9y23t5dXYJK;z0Or zwsmkij7erM2+SVASLqK!;pDH0R^9ohQeb%}sPF!(Bma8{p$;>(+jU0l&C5SkLN7Et zSAum2Ya}^9EN!UsINx2p4p)IV+TqPWEkGHPn$csvYRC-Hg~pDoC)9|YaR+DVI_@*8 zAd9BcV=Z|0*!lVqU`HSavjD>Rvhi!W?-O)H#iJ}vC7^~l>)k8Gq~{8`8ct(!sW2{SK;tk(IKim zT)1(%4$(-5qJ7>zys49q&uz(w@(E>oeL~2>$>+D8x*X=3s+mqd{%WWUI<>Bs01YaB zG5YUe{q?1MM+2hn<6P?G;*V)jr3%u4*xwo}9lT|i)uu<`ilKJ%`EH{^tg~#Y zC4b{-t2A+s{sZ1OsLGd=iBG#6 z`8S-z`Ftcv@x^YXH8zW|310i&R4}V+(9Wunib{z~H?p$@Wl}D}t|P4*#87<=<>K07 zsi^bSBJ&>B6H3DUrPD3kKO&y zHY%nY^yEsX+vO_H5XQRq6clFzS;Rw{;O0<^>`j9VmqSit_hVtIWsz&OzPgTC=e}M* zqd?>e+cd(h9W?)uRr#hEip%kS*>rLnTnOaLgM8-o93rJs z=FiZ=0@uRR_xF|7e=+#Z|6?%bmc47Ydz1tW^#Yw4rwGoHTv9=*9)CFKbIUw_Hy`FS zCz|{Tzn`JXZm(a#54I_Mxp>jijVT*9|c0RcjJe-2DtrXN6XU>W2G>wy`tmFm9EoO z^Z?bt+y4?j)6WE~H7;jJC;)E#N<#|gQNrk{B%Qv9f}wQdj8O*U1OLBez-r~V1#>!b`oh%|I$k9t`UwLHy2$Ka9%u4G zQv$Djbyn3OQJ$PS$sK2-fW48C^R#ZT;-ncp!l9yD)cj8wdSEOA+_VTQ@39ztWAj!G<#Zw2zVbvm*`_R&&36NberZB`93p7@2U zOio~gQQ|2M;)HG$=2JrJ`FJ5>un;O~Wx`B>%4Dpd3sY)|AauVa`b#0`e+u^fv;B2f z^QFEma#+9A9*!1CbUGgeG;jhTNH{J}UjC?Ch2+h`4Of9lyp?SbY6A=MkFP4{G4C@2 zW;DG{kNLM{Gl}!(2Op3r_2mrF?^V064`ATpN)sIwe*D!tOir+yyNJ*IU218tHsg+V zK@WceYtlVKMX}^mJ)$VPA>F|7ZxmQ7pgbvmNU&=ERG^0%{-?56Xr(^^spyI0yM^*Q z4ANQ4x#Rp4lN1AyBJW&n=ClD9-LoSOD{g!eZa>Wyv>fL;n=$5&U~IZXlqntZ&w<&J zgi6G_5=RHyptM2Z$eZDX!kX9>6NaNZ?cpO3WvPeot(cZq-2tMG?Wg^ITyWnJ2{Lx0 z4qtzbR)y104Hg~~+=mNGw;A0E5p$ZI(FNaK%qpsy=#Y(c*S{0;O`8rPrWnNeD3z|U zuM_e+^#JKM_T?egsL_?Bft%!5I@ES)i^DQZ5cKq2rlxlg>asZEk&56^NDFPH6w{?h#z~70$scP#k75HkIBDuDtj(M&#zzZRsh?K9LHit z&(qg;7;XrD1KTi;VUQ(#tPTLZGtV{@^SB1F<^vJ^%m! literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ diff --git a/lib/core/services/constants.dart b/lib/core/services/constants.dart index fc39cc8..2dbb1a9 100644 --- a/lib/core/services/constants.dart +++ b/lib/core/services/constants.dart @@ -1 +1 @@ -const String baseUrl = 'https://c62a-139-255-101-170.ngrok-free.app/'; +const String baseUrl = 'https://7558-114-6-25-184.ngrok-free.app/'; diff --git a/lib/features/history/screens/history_screen.dart b/lib/features/history/screens/history_screen.dart index 161bbba..055846b 100644 --- a/lib/features/history/screens/history_screen.dart +++ b/lib/features/history/screens/history_screen.dart @@ -51,9 +51,6 @@ class HistoryScreen extends StatelessWidget { } Widget _buildContent(BuildContext context, HistoryProvider historyProvider) { - print("isLoading: ${historyProvider.isLoading}"); - print("error: ${historyProvider.error}"); - print("historyLength: ${historyProvider.learningHistory.length}"); if (historyProvider.isLoading) { return const Center(child: CircularProgressIndicator()); } diff --git a/lib/features/learning/modules/exercises/screens/exercise_screen.dart b/lib/features/learning/modules/exercises/screens/exercise_screen.dart index be88765..49a06fb 100644 --- a/lib/features/learning/modules/exercises/screens/exercise_screen.dart +++ b/lib/features/learning/modules/exercises/screens/exercise_screen.dart @@ -12,12 +12,16 @@ class ExerciseScreen extends StatefulWidget { final String? levelId; final String studentLearningId; final bool isReview; + final String topicId; // Tambahkan ini + final String topicTitle; // Tambahkan ini const ExerciseScreen({ super.key, required this.levelId, required this.studentLearningId, this.isReview = false, + required this.topicId, + required this.topicTitle, }); @override @@ -142,6 +146,8 @@ class _ExerciseScreenState extends State { ExerciseNavigator( onScrollToTop: _scrollToTop, isReview: widget.isReview, + topicId: widget.topicId, + topicTitle: widget.topicTitle, ), const SizedBox(height: 32), ], diff --git a/lib/features/learning/modules/exercises/widgets/exercise_navigator.dart b/lib/features/learning/modules/exercises/widgets/exercise_navigator.dart index 8a604c3..e30c7a1 100644 --- a/lib/features/learning/modules/exercises/widgets/exercise_navigator.dart +++ b/lib/features/learning/modules/exercises/widgets/exercise_navigator.dart @@ -11,11 +11,15 @@ import 'package:provider/provider.dart'; class ExerciseNavigator extends StatelessWidget { final VoidCallback? onScrollToTop; final bool isReview; + final String topicId; + final String topicTitle; const ExerciseNavigator({ super.key, required this.onScrollToTop, this.isReview = false, + required this.topicId, + required this.topicTitle, }); @override @@ -43,6 +47,8 @@ class ExerciseNavigator extends StatelessWidget { score: int.tryParse(result['SCORE'].toString()) ?? 0, isCompleted: result['IS_PASS'] == 1, stdLearningId: result['STUDENT_LEARNING_ID']?.toString(), + topicId: topicId, + topicTitle: topicTitle, ), ), ); diff --git a/lib/features/learning/modules/feedback/providers/feedback_provider.dart b/lib/features/learning/modules/feedback/providers/feedback_provider.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/features/learning/modules/feedback/screens/feedback_screen.dart b/lib/features/learning/modules/feedback/screens/feedback_screen.dart index 435a486..0c1f76c 100644 --- a/lib/features/learning/modules/feedback/screens/feedback_screen.dart +++ b/lib/features/learning/modules/feedback/screens/feedback_screen.dart @@ -2,15 +2,20 @@ import 'package:english_learning/core/widgets/global_button.dart'; import 'package:english_learning/core/utils/styles/theme.dart'; import 'package:english_learning/features/learning/modules/exercises/providers/exercise_provider.dart'; import 'package:english_learning/features/learning/modules/feedback/widgets/feedback_dialog.dart'; +import 'package:english_learning/features/learning/modules/level/screens/level_list_screen.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class FeedbackScreen extends StatefulWidget { final String stdLearningId; + final String topicId; + final String topicTitle; const FeedbackScreen({ super.key, required this.stdLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -75,7 +80,16 @@ class _FeedbackScreenState extends State { return FeedbackDialog( onSubmit: () { Navigator.of(dialogContext).pop(); // Close the dialog - Navigator.of(context).pop(); // Return to the previous screen + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute( + builder: (context) => LevelListScreen( + topicId: widget.topicId, + topicTitle: widget.topicTitle, + ), + ), + (route) => false, // This removes all previous routes + ); }, ); }, @@ -189,16 +203,15 @@ class _FeedbackScreenState extends State { backgroundColor: Colors.transparent, borderColor: AppColors.blueColor, onPressed: () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => LevelListScreen( - // topicId: widget.topicId!, - // topicTitle: widget.topicTitle!, - // ), - // ), - // ); - Navigator.of(context).pop(true); + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => LevelListScreen( + topicId: widget.topicId, + topicTitle: widget.topicTitle, + ), + ), + ); }, ) ], diff --git a/lib/features/learning/modules/level/providers/level_provider.dart b/lib/features/learning/modules/level/providers/level_provider.dart index af5730b..ff2b54f 100644 --- a/lib/features/learning/modules/level/providers/level_provider.dart +++ b/lib/features/learning/modules/level/providers/level_provider.dart @@ -46,31 +46,6 @@ class LevelProvider with ChangeNotifier { orElse: () => throw Exception('Pretest not found')); } - // int getLevelScore(String levelId) { - // final level = _levels.firstWhere((level) => level.idLevel == levelId, - // orElse: () => const Level( - // idLevel: '', - // idTopic: '', - // idSection: '', - // nameSection: '', - // nameTopic: '', - // nameLevel: '', - // content: '', - // isPretest: 0, - // timeLevel: '', - // )); - // return level.score ?? 0; - // } - - // bool isLevelAllowed(String levelName) { - // return _unlockedLevels.contains(levelName); - // } - - // bool isLevelCompleted(String levelId) { - // return _lastCompletedLevel != null && - // _lastCompletedLevel!['ID_LEVEL'] == levelId; - // } - bool isPretestFinished(String levelId) { return _levels.any( (level) => level.idLevel == levelId && level.idStudentLearning != null); @@ -98,38 +73,4 @@ class LevelProvider with ChangeNotifier { return _levels.any( (level) => level.idLevel == levelId && level.idStudentLearning != null); } - - // bool isLevelAllowed(String levelId) { - // if (_lastCompletedLevel == null) { - // // Jika tidak ada level yang selesai, hanya pretest yang diizinkan - // return levelId == _levels.first.idLevel; - // } - - // String lastCompletedLevelId = _lastCompletedLevel!['ID_LEVEL']; - // int lastCompletedIndex = - // _levels.indexWhere((level) => level.idLevel == lastCompletedLevelId); - // int currentIndex = _levels.indexWhere((level) => level.idLevel == levelId); - - // // Level diizinkan jika indeksnya kurang dari atau sama dengan indeks terakhir yang selesai + 1 - // return currentIndex <= lastCompletedIndex + 1; - // } - - // bool isLevelAllowed(int levelIndex) { - // if (levelIndex == 0) return true; // Pretest is always allowed - // if (_lastCompletedLevel == null) - // return levelIndex == - // 1; // If no level completed, only first level is allowed - // String lastCompletedLevelId = _lastCompletedLevel!['ID_LEVEL']; - // int lastCompletedIndex = - // _levels.indexWhere((level) => level.idLevel == lastCompletedLevelId); - // return levelIndex <= lastCompletedIndex + 2; - // } - - // bool isLevelFinished(int levelIndex) { - // return _levels[levelIndex].idStudentLearning != null; - // } - - // int getLevelScore(int levelIndex) { - // return _levels[levelIndex].score ?? 0; - // } } diff --git a/lib/features/learning/modules/level/screens/level_list_screen.dart b/lib/features/learning/modules/level/screens/level_list_screen.dart index f215fa9..14530ef 100644 --- a/lib/features/learning/modules/level/screens/level_list_screen.dart +++ b/lib/features/learning/modules/level/screens/level_list_screen.dart @@ -78,43 +78,46 @@ class _LevelListScreenState extends State { .where((level) => level.isPretest == 0) .toList(); - return Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - children: [ - PretestCard( - pretest: pretest, - score: levelProvider.getPretestScore(pretest.idLevel), - isCompleted: - levelProvider.isPretestFinished(pretest.idLevel), - isAllowed: levelProvider.isLevelAllowed(pretest.idLevel), - ), - const SizedBox(height: 12), - Expanded( - child: GridView.builder( - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 1.0, - crossAxisSpacing: 16, - mainAxisSpacing: 16, - ), - itemCount: otherLevels.length, - itemBuilder: (context, index) { - final level = otherLevels[index]; - - return LevelCard( - level: level, - isAllowed: - levelProvider.isLevelAllowed(level.idLevel), - score: levelProvider.getLevelScore(level.idLevel), - isCompleted: - levelProvider.isLevelCompleted(level.idLevel), - ); - }, + return RefreshIndicator( + onRefresh: _fetchLevels, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + PretestCard( + pretest: pretest, + score: levelProvider.getPretestScore(pretest.idLevel), + isCompleted: + levelProvider.isPretestFinished(pretest.idLevel), + isAllowed: levelProvider.isLevelAllowed(pretest.idLevel), ), - ), - ], + const SizedBox(height: 12), + Expanded( + child: GridView.builder( + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 1.0, + crossAxisSpacing: 16, + mainAxisSpacing: 16, + ), + itemCount: otherLevels.length, + itemBuilder: (context, index) { + final level = otherLevels[index]; + + return LevelCard( + level: level, + isAllowed: + levelProvider.isLevelAllowed(level.idLevel), + score: levelProvider.getLevelScore(level.idLevel), + isCompleted: + levelProvider.isLevelCompleted(level.idLevel), + ); + }, + ), + ), + ], + ), ), ); } diff --git a/lib/features/learning/modules/level/widgets/level_card.dart b/lib/features/learning/modules/level/widgets/level_card.dart index 83e2e6d..8c9ebf0 100644 --- a/lib/features/learning/modules/level/widgets/level_card.dart +++ b/lib/features/learning/modules/level/widgets/level_card.dart @@ -141,6 +141,8 @@ class LevelCard extends StatelessWidget { MaterialPageRoute( builder: (context) => MaterialScreen( levelId: level.idLevel, + topicId: level.idTopic, + topicTitle: level.nameTopic, ), ), ); diff --git a/lib/features/learning/modules/level/widgets/pretest_card.dart b/lib/features/learning/modules/level/widgets/pretest_card.dart index 1b4dc8d..00c7475 100644 --- a/lib/features/learning/modules/level/widgets/pretest_card.dart +++ b/lib/features/learning/modules/level/widgets/pretest_card.dart @@ -37,6 +37,8 @@ class PretestCard extends StatelessWidget { levelId: pretest.idLevel, isReview: true, studentLearningId: pretest.idStudentLearning, + topicId: pretest.idTopic, + topicTitle: pretest.nameTopic, ), ), ); @@ -48,6 +50,8 @@ class PretestCard extends StatelessWidget { builder: (context) => MaterialScreen( levelId: pretest.idLevel, isReview: false, + topicId: pretest.idTopic, + topicTitle: pretest.nameTopic, ), ), ); @@ -141,31 +145,6 @@ class PretestCard extends StatelessWidget { width: double.infinity, height: 36, color: isFinished ? Colors.green : AppColors.yellowButtonColor, - // onPressed: () { - // if (!isCompleted) { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => MaterialScreen( - // levelId: pretest.idLevel, - // ), - // ), - // ); - // } - // // Jika isCompleted true, tidak melakukan apa-apa - // }, - // onPressed: isAllowed - // ? () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => MaterialScreen( - // levelId: pretest.idLevel, - // ), - // ), - // ); - // } - // : () {}, onPressed: navigateToMaterial, ), ], diff --git a/lib/features/learning/modules/material/screens/material_screen.dart b/lib/features/learning/modules/material/screens/material_screen.dart index 8f11dc4..42a8ea1 100644 --- a/lib/features/learning/modules/material/screens/material_screen.dart +++ b/lib/features/learning/modules/material/screens/material_screen.dart @@ -16,12 +16,16 @@ class MaterialScreen extends StatefulWidget { final String levelId; final bool isReview; final String? studentLearningId; + final String topicId; + final String topicTitle; const MaterialScreen({ super.key, required this.levelId, this.isReview = false, this.studentLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -100,6 +104,8 @@ class _MaterialScreenState extends State levelId: widget.levelId, studentLearningId: studentLearningId, isReview: widget.isReview, + topicId: widget.topicId, + topicTitle: widget.topicTitle, ), ), ); diff --git a/lib/features/learning/modules/result/screens/result_screen.dart b/lib/features/learning/modules/result/screens/result_screen.dart index 6d8bebc..d8c294f 100644 --- a/lib/features/learning/modules/result/screens/result_screen.dart +++ b/lib/features/learning/modules/result/screens/result_screen.dart @@ -10,6 +10,8 @@ class ResultScreen extends StatelessWidget { final int score; final bool isCompleted; final String? stdLearningId; + final String topicId; + final String topicTitle; const ResultScreen({ super.key, @@ -18,6 +20,8 @@ class ResultScreen extends StatelessWidget { required this.score, required this.isCompleted, this.stdLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -37,18 +41,24 @@ class ResultScreen extends StatelessWidget { currentLevel: currentLevel, score: score, stdLearningId: stdLearningId ?? '', + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ) else if (nextLevel != currentLevel) JumpResultWidget( nextLevel: nextLevel, score: score, stdLearningId: stdLearningId ?? '', + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ) else DownResultWidget( nextLevel: nextLevel, score: score, stdLearningId: stdLearningId ?? '', + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ), ], ), diff --git a/lib/features/learning/modules/result/widgets/complete_result_widget.dart b/lib/features/learning/modules/result/widgets/complete_result_widget.dart index f6732fb..347be09 100644 --- a/lib/features/learning/modules/result/widgets/complete_result_widget.dart +++ b/lib/features/learning/modules/result/widgets/complete_result_widget.dart @@ -8,12 +8,16 @@ class CompleteResultWidget extends StatelessWidget { final String? currentLevel; final int? score; final String stdLearningId; + final String topicId; + final String topicTitle; const CompleteResultWidget({ super.key, required this.currentLevel, required this.score, required this.stdLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -57,6 +61,8 @@ class CompleteResultWidget extends StatelessWidget { MaterialPageRoute( builder: (context) => FeedbackScreen( stdLearningId: stdLearningId, + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ), ), ); diff --git a/lib/features/learning/modules/result/widgets/down_result_widget.dart b/lib/features/learning/modules/result/widgets/down_result_widget.dart index 00f8339..f22f287 100644 --- a/lib/features/learning/modules/result/widgets/down_result_widget.dart +++ b/lib/features/learning/modules/result/widgets/down_result_widget.dart @@ -8,12 +8,16 @@ class DownResultWidget extends StatelessWidget { final String? nextLevel; final int? score; final String stdLearningId; + final String topicId; + final String topicTitle; const DownResultWidget({ super.key, required this.nextLevel, required this.score, required this.stdLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -67,6 +71,8 @@ class DownResultWidget extends StatelessWidget { MaterialPageRoute( builder: (context) => FeedbackScreen( stdLearningId: stdLearningId, + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ), ), ); diff --git a/lib/features/learning/modules/result/widgets/jump_result_widget.dart b/lib/features/learning/modules/result/widgets/jump_result_widget.dart index 89cb251..04bb499 100644 --- a/lib/features/learning/modules/result/widgets/jump_result_widget.dart +++ b/lib/features/learning/modules/result/widgets/jump_result_widget.dart @@ -8,12 +8,17 @@ class JumpResultWidget extends StatelessWidget { final String? nextLevel; final int? score; final String stdLearningId; + final String topicId; + final String topicTitle; - const JumpResultWidget( - {super.key, - required this.nextLevel, - required this.score, - required this.stdLearningId}); + const JumpResultWidget({ + super.key, + required this.nextLevel, + required this.score, + required this.stdLearningId, + required this.topicId, + required this.topicTitle, + }); @override Widget build(BuildContext context) { @@ -66,6 +71,8 @@ class JumpResultWidget extends StatelessWidget { MaterialPageRoute( builder: (context) => FeedbackScreen( stdLearningId: stdLearningId, + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ), ), ); diff --git a/lib/features/learning/modules/topics/screens/topics_list_screen.dart b/lib/features/learning/modules/topics/screens/topics_list_screen.dart index bc332a0..227eef5 100644 --- a/lib/features/learning/modules/topics/screens/topics_list_screen.dart +++ b/lib/features/learning/modules/topics/screens/topics_list_screen.dart @@ -137,7 +137,7 @@ class _TopicsListScreenState extends State { child: Consumer( builder: (context, topicProvider, _) { if (topicProvider.topics.isEmpty) { - return Center(child: CircularProgressIndicator()); + return const Center(child: CircularProgressIndicator()); } else if (topicProvider.error != null) { return const Center(child: Text('No topics available')); } else { @@ -150,7 +150,7 @@ class _TopicsListScreenState extends State { description: topic.description, isCompleted: topic.isCompleted, onTap: () { - Navigator.push( + Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => LevelListScreen(