react-native-elearn-ui 0.1.28 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/lib/module/components/Icon.js +9 -0
  2. package/lib/module/components/Icon.js.map +1 -1
  3. package/lib/module/index.js +1 -0
  4. package/lib/module/index.js.map +1 -1
  5. package/lib/module/screens/index.js +2 -0
  6. package/lib/module/screens/index.js.map +1 -1
  7. package/lib/module/screens/qbank/QBankOverviewScreen.js +435 -0
  8. package/lib/module/screens/qbank/QBankOverviewScreen.js.map +1 -0
  9. package/lib/module/screens/qbank/QBankQuestionScreen.js +181 -123
  10. package/lib/module/screens/qbank/QBankQuestionScreen.js.map +1 -1
  11. package/lib/module/screens/qbank/QBankSuccessScreen.js +336 -0
  12. package/lib/module/screens/qbank/QBankSuccessScreen.js.map +1 -0
  13. package/lib/typescript/src/components/Icon.d.ts +1 -1
  14. package/lib/typescript/src/components/Icon.d.ts.map +1 -1
  15. package/lib/typescript/src/index.d.ts +1 -0
  16. package/lib/typescript/src/index.d.ts.map +1 -1
  17. package/lib/typescript/src/screens/index.d.ts +2 -0
  18. package/lib/typescript/src/screens/index.d.ts.map +1 -1
  19. package/lib/typescript/src/screens/qbank/QBankOverviewScreen.d.ts +4 -0
  20. package/lib/typescript/src/screens/qbank/QBankOverviewScreen.d.ts.map +1 -0
  21. package/lib/typescript/src/screens/qbank/QBankQuestionScreen.d.ts +7 -9
  22. package/lib/typescript/src/screens/qbank/QBankQuestionScreen.d.ts.map +1 -1
  23. package/lib/typescript/src/screens/qbank/QBankSuccessScreen.d.ts +4 -0
  24. package/lib/typescript/src/screens/qbank/QBankSuccessScreen.d.ts.map +1 -0
  25. package/lib/typescript/src/types/index.d.ts +39 -7
  26. package/lib/typescript/src/types/index.d.ts.map +1 -1
  27. package/package.json +1 -1
  28. package/src/components/Icon.tsx +6 -1
  29. package/src/index.tsx +1 -0
  30. package/src/screens/index.ts +2 -0
  31. package/src/screens/qbank/QBankOverviewScreen.tsx +392 -0
  32. package/src/screens/qbank/QBankQuestionScreen.tsx +164 -109
  33. package/src/screens/qbank/QBankSuccessScreen.tsx +292 -0
  34. package/src/types/index.ts +43 -7
@@ -0,0 +1,292 @@
1
+ import React, { useState } from 'react';
2
+ import {
3
+ View,
4
+ ScrollView,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ TextInput,
8
+ KeyboardAvoidingView,
9
+ Platform,
10
+ } from 'react-native';
11
+ import { SafeAreaView } from 'react-native-safe-area-context';
12
+ import { useTheme } from '../../context/ThemeContext';
13
+ import { Typography, Icon, Button } from '../../components';
14
+ import type { QBankSuccessScreenProps } from '../../types';
15
+
16
+ export const QBankSuccessScreen: React.FC<QBankSuccessScreenProps> = ({
17
+ moduleTitle,
18
+ completedDate,
19
+ totalQuestions,
20
+ correctCount,
21
+ incorrectCount,
22
+ missedCount,
23
+ onBack,
24
+ onSubmitFeedback,
25
+ }) => {
26
+ const theme = useTheme();
27
+ const [rating, setRating] = useState(0);
28
+ const [feedback, setFeedback] = useState('');
29
+
30
+ const percentage = Math.round((correctCount / totalQuestions) * 100) || 0;
31
+
32
+ // Calculate segments for the progress bar (percentages of the width)
33
+ const correctWidth = (correctCount / totalQuestions) * 100;
34
+ const incorrectWidth = (incorrectCount / totalQuestions) * 100;
35
+ const missedWidth = (missedCount / totalQuestions) * 100;
36
+
37
+ return (
38
+ <SafeAreaView style={styles.container} edges={['top', 'bottom']}>
39
+ <KeyboardAvoidingView
40
+ style={styles.container}
41
+ behavior={Platform.OS === 'ios' ? 'padding' : undefined}
42
+ >
43
+ <ScrollView contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
44
+ {/* Header */}
45
+ <View style={styles.header}>
46
+ <TouchableOpacity onPress={onBack} style={styles.headerIconBtnLeft}>
47
+ <Icon name="chevron-left" size={24} color={theme.textPrimary} />
48
+ </TouchableOpacity>
49
+ </View>
50
+
51
+ {/* Success Icon & Title */}
52
+ <View style={styles.successHeader}>
53
+ <View style={styles.iconCircle}>
54
+ <Icon name="check" size={40} color="#FFFFFF" />
55
+ </View>
56
+ <Typography variant="h2" bold color={theme.textPrimary} style={styles.successTitle}>
57
+ Module Completed
58
+ </Typography>
59
+ </View>
60
+
61
+ {/* Summary Card */}
62
+ <View style={styles.card}>
63
+ <View style={styles.cardHeader}>
64
+ <Typography variant="h3" bold color={theme.textPrimary}>
65
+ {moduleTitle}
66
+ </Typography>
67
+ <Typography variant="caption" color={theme.textSecondary} style={styles.dateText}>
68
+ Completed on {completedDate}
69
+ </Typography>
70
+ </View>
71
+
72
+ <View style={styles.divider} />
73
+
74
+ <View style={styles.statsSection}>
75
+ <Typography variant="caption" color={theme.textSecondary} style={styles.totalText}>
76
+ Total Question {totalQuestions}
77
+ </Typography>
78
+
79
+ <View style={styles.statsRow}>
80
+ <View style={styles.statsLabels}>
81
+ <Typography variant="caption" color={theme.success} style={styles.statLabel}>
82
+ {String(correctCount).padStart(2, '0')} Correct
83
+ </Typography>
84
+ <Typography variant="caption" color="#EF4444" style={styles.statLabel}>
85
+ {String(incorrectCount).padStart(2, '0')} Incorrect
86
+ </Typography>
87
+ <Typography variant="caption" color="#F59E0B" style={styles.statLabel}>
88
+ {String(missedCount).padStart(2, '0')} Missed
89
+ </Typography>
90
+ </View>
91
+
92
+ <View style={styles.percentageBlock}>
93
+ <Typography variant="h3" bold color={theme.textPrimary}>
94
+ {percentage}%
95
+ </Typography>
96
+ <Typography variant="caption" color={theme.textSecondary} style={{fontSize: 10}}>
97
+ Correct
98
+ </Typography>
99
+ </View>
100
+ </View>
101
+
102
+ {/* Multi-color Progress Bar */}
103
+ <View style={styles.progressBarContainer}>
104
+ {correctWidth > 0 && <View style={[styles.progressSegment, { width: `${correctWidth}%`, backgroundColor: theme.success }]} />}
105
+ {incorrectWidth > 0 && <View style={[styles.progressSegment, { width: `${incorrectWidth}%`, backgroundColor: '#EF4444' }]} />}
106
+ {missedWidth > 0 && <View style={[styles.progressSegment, { width: `${missedWidth}%`, backgroundColor: '#F59E0B' }]} />}
107
+ {/* Fallback empty bar if no questions */}
108
+ {totalQuestions === 0 && <View style={[styles.progressSegment, { width: '100%', backgroundColor: '#E5E7EB' }]} />}
109
+ </View>
110
+ </View>
111
+ </View>
112
+
113
+ {/* Feedback Section */}
114
+ <View style={styles.feedbackSection}>
115
+ <Typography variant="h3" bold color={theme.textPrimary} style={styles.feedbackTitle}>
116
+ How was your QBank{'\n'}taking experience?
117
+ </Typography>
118
+ <Typography variant="body" color={theme.textSecondary} style={styles.feedbackSubtitle}>
119
+ Your feedback will help us improve your QBank experience
120
+ </Typography>
121
+
122
+ <View style={styles.starsContainer}>
123
+ {[1, 2, 3, 4, 5].map((star) => (
124
+ <TouchableOpacity key={star} onPress={() => setRating(star)}>
125
+ <Icon
126
+ name="star"
127
+ size={36}
128
+ color={star <= rating ? '#EAB308' : '#D1D5DB'}
129
+ />
130
+ </TouchableOpacity>
131
+ ))}
132
+ </View>
133
+
134
+ <TextInput
135
+ style={styles.textInput}
136
+ placeholder="Type Your Feedback Here"
137
+ placeholderTextColor="#9CA3AF"
138
+ multiline
139
+ numberOfLines={4}
140
+ value={feedback}
141
+ onChangeText={setFeedback}
142
+ />
143
+
144
+ <Button
145
+ title="Submit"
146
+ onPress={() => onSubmitFeedback?.(rating, feedback)}
147
+ style={styles.submitBtn}
148
+ />
149
+ </View>
150
+ </ScrollView>
151
+ </KeyboardAvoidingView>
152
+ </SafeAreaView>
153
+ );
154
+ };
155
+
156
+ const styles = StyleSheet.create({
157
+ container: {
158
+ flex: 1,
159
+ backgroundColor: '#F9FAFB',
160
+ },
161
+ scrollContent: {
162
+ padding: 20,
163
+ paddingBottom: 40,
164
+ },
165
+ header: {
166
+ marginBottom: 20,
167
+ },
168
+ headerIconBtnLeft: {
169
+ width: 40,
170
+ height: 40,
171
+ justifyContent: 'center',
172
+ alignItems: 'flex-start',
173
+ },
174
+ successHeader: {
175
+ alignItems: 'center',
176
+ marginBottom: 32,
177
+ },
178
+ iconCircle: {
179
+ width: 80,
180
+ height: 80,
181
+ borderRadius: 40,
182
+ backgroundColor: '#10B981', // Success green
183
+ justifyContent: 'center',
184
+ alignItems: 'center',
185
+ shadowColor: '#10B981',
186
+ shadowOffset: { width: 0, height: 4 },
187
+ shadowOpacity: 0.3,
188
+ shadowRadius: 8,
189
+ elevation: 8,
190
+ marginBottom: 16,
191
+ },
192
+ successTitle: {
193
+ fontSize: 20,
194
+ },
195
+ card: {
196
+ backgroundColor: '#FFFFFF',
197
+ borderRadius: 12,
198
+ borderWidth: 1,
199
+ borderColor: '#F3F4F6',
200
+ shadowColor: '#000',
201
+ shadowOffset: { width: 0, height: 2 },
202
+ shadowOpacity: 0.05,
203
+ shadowRadius: 8,
204
+ elevation: 2,
205
+ marginBottom: 40,
206
+ },
207
+ cardHeader: {
208
+ padding: 16,
209
+ },
210
+ dateText: {
211
+ marginTop: 4,
212
+ },
213
+ divider: {
214
+ height: 1,
215
+ backgroundColor: '#F3F4F6',
216
+ },
217
+ statsSection: {
218
+ padding: 16,
219
+ },
220
+ totalText: {
221
+ marginBottom: 8,
222
+ },
223
+ statsRow: {
224
+ flexDirection: 'row',
225
+ justifyContent: 'space-between',
226
+ alignItems: 'flex-end',
227
+ marginBottom: 12,
228
+ },
229
+ statsLabels: {
230
+ flexDirection: 'row',
231
+ alignItems: 'center',
232
+ flex: 1,
233
+ flexWrap: 'wrap',
234
+ },
235
+ statLabel: {
236
+ marginRight: 16,
237
+ fontSize: 12,
238
+ marginBottom: 4,
239
+ },
240
+ percentageBlock: {
241
+ alignItems: 'center',
242
+ justifyContent: 'center',
243
+ },
244
+ progressBarContainer: {
245
+ height: 8,
246
+ backgroundColor: '#E5E7EB',
247
+ borderRadius: 4,
248
+ flexDirection: 'row',
249
+ overflow: 'hidden',
250
+ },
251
+ progressSegment: {
252
+ height: '100%',
253
+ },
254
+ feedbackSection: {
255
+ alignItems: 'center',
256
+ },
257
+ feedbackTitle: {
258
+ textAlign: 'center',
259
+ fontSize: 18,
260
+ marginBottom: 8,
261
+ lineHeight: 26,
262
+ },
263
+ feedbackSubtitle: {
264
+ textAlign: 'center',
265
+ fontSize: 12,
266
+ marginBottom: 24,
267
+ paddingHorizontal: 20,
268
+ },
269
+ starsContainer: {
270
+ flexDirection: 'row',
271
+ justifyContent: 'center',
272
+ gap: 12, // Space between stars
273
+ marginBottom: 32,
274
+ },
275
+ textInput: {
276
+ width: '100%',
277
+ height: 120,
278
+ backgroundColor: '#FFFFFF',
279
+ borderWidth: 1,
280
+ borderColor: '#10B981', // Green border as in design
281
+ borderRadius: 8,
282
+ padding: 16,
283
+ fontSize: 14,
284
+ color: '#1F2937',
285
+ marginBottom: 24,
286
+ },
287
+ submitBtn: {
288
+ backgroundColor: '#10B981',
289
+ paddingHorizontal: 40,
290
+ borderRadius: 8,
291
+ },
292
+ });
@@ -239,23 +239,59 @@ export interface QBankSubTopicSection {
239
239
  modules: QBankSubTopicModule[];
240
240
  }
241
241
 
242
- export interface QBankOption {
242
+ export interface QBankExamOption {
243
243
  id: string;
244
244
  text: string;
245
- status: 'default' | 'correct' | 'incorrect';
245
+ isCorrect: boolean;
246
246
  percentage?: number; // e.g. 20 for [20%]
247
247
  }
248
248
 
249
- export interface QBankQuestionParams {
250
- headerTitle: string;
251
- questionNumber: number;
252
- totalQuestions: number;
249
+ export interface QBankExamQuestion {
250
+ id: string;
253
251
  questionText: string;
254
- options: QBankOption[];
252
+ options: QBankExamOption[];
255
253
  explanation?: string;
256
254
  referenceId?: string;
257
255
  }
258
256
 
257
+ export interface QBankExamData {
258
+ id: string;
259
+ title: string;
260
+ accessType: 'free' | 'pro';
261
+ timeLimitSeconds?: number;
262
+ questions: QBankExamQuestion[];
263
+ }
264
+
265
+ export interface QBankSuccessScreenProps {
266
+ moduleTitle: string;
267
+ completedDate: string;
268
+ totalQuestions: number;
269
+ correctCount: number;
270
+ incorrectCount: number;
271
+ missedCount: number;
272
+ onBack?: () => void;
273
+ onSubmitFeedback?: (rating: number, feedback: string) => void;
274
+ }
275
+
276
+ export interface QBankOverviewQuestion {
277
+ id: string;
278
+ number: number;
279
+ title: string;
280
+ status: 'correct' | 'incorrect' | 'missed';
281
+ }
282
+
283
+ export interface QBankOverviewScreenProps {
284
+ topicTitle: string;
285
+ moduleTitle: string;
286
+ totalQuestions: number;
287
+ correctCount: number;
288
+ incorrectCount: number;
289
+ missedCount: number;
290
+ questions: QBankOverviewQuestion[];
291
+ onBack?: () => void;
292
+ onPressQuestion?: (questionId: string) => void;
293
+ }
294
+
259
295
  export interface QBankSubTopicParams {
260
296
  header: {
261
297
  title: string;