react-native-elearn-ui 0.1.0

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 (100) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +37 -0
  3. package/lib/module/components/Button.js +82 -0
  4. package/lib/module/components/Button.js.map +1 -0
  5. package/lib/module/components/Card.js +49 -0
  6. package/lib/module/components/Card.js.map +1 -0
  7. package/lib/module/components/CircularProgress.js +80 -0
  8. package/lib/module/components/CircularProgress.js.map +1 -0
  9. package/lib/module/components/Icon.js +268 -0
  10. package/lib/module/components/Icon.js.map +1 -0
  11. package/lib/module/components/ProgressBar.js +39 -0
  12. package/lib/module/components/ProgressBar.js.map +1 -0
  13. package/lib/module/components/Typography.js +102 -0
  14. package/lib/module/components/Typography.js.map +1 -0
  15. package/lib/module/components/index.js +10 -0
  16. package/lib/module/components/index.js.map +1 -0
  17. package/lib/module/context/ElearnConfigContext.js +76 -0
  18. package/lib/module/context/ElearnConfigContext.js.map +1 -0
  19. package/lib/module/context/ThemeContext.js +45 -0
  20. package/lib/module/context/ThemeContext.js.map +1 -0
  21. package/lib/module/index.js +13 -0
  22. package/lib/module/index.js.map +1 -0
  23. package/lib/module/multiply.js +6 -0
  24. package/lib/module/multiply.js.map +1 -0
  25. package/lib/module/package.json +1 -0
  26. package/lib/module/screens/HomeScreen.js +330 -0
  27. package/lib/module/screens/HomeScreen.js.map +1 -0
  28. package/lib/module/screens/QbankScreen.js +200 -0
  29. package/lib/module/screens/QbankScreen.js.map +1 -0
  30. package/lib/module/screens/QuestionScreen.js +383 -0
  31. package/lib/module/screens/QuestionScreen.js.map +1 -0
  32. package/lib/module/screens/QuizStartScreen.js +230 -0
  33. package/lib/module/screens/QuizStartScreen.js.map +1 -0
  34. package/lib/module/screens/ResultScreen.js +318 -0
  35. package/lib/module/screens/ResultScreen.js.map +1 -0
  36. package/lib/module/screens/TopicListScreen.js +222 -0
  37. package/lib/module/screens/TopicListScreen.js.map +1 -0
  38. package/lib/module/screens/index.js +9 -0
  39. package/lib/module/screens/index.js.map +1 -0
  40. package/lib/module/types/index.js +2 -0
  41. package/lib/module/types/index.js.map +1 -0
  42. package/lib/typescript/package.json +1 -0
  43. package/lib/typescript/src/components/Button.d.ts +14 -0
  44. package/lib/typescript/src/components/Button.d.ts.map +1 -0
  45. package/lib/typescript/src/components/Card.d.ts +12 -0
  46. package/lib/typescript/src/components/Card.d.ts.map +1 -0
  47. package/lib/typescript/src/components/CircularProgress.d.ts +15 -0
  48. package/lib/typescript/src/components/CircularProgress.d.ts.map +1 -0
  49. package/lib/typescript/src/components/Icon.d.ts +11 -0
  50. package/lib/typescript/src/components/Icon.d.ts.map +1 -0
  51. package/lib/typescript/src/components/ProgressBar.d.ts +11 -0
  52. package/lib/typescript/src/components/ProgressBar.d.ts.map +1 -0
  53. package/lib/typescript/src/components/Typography.d.ts +12 -0
  54. package/lib/typescript/src/components/Typography.d.ts.map +1 -0
  55. package/lib/typescript/src/components/index.d.ts +9 -0
  56. package/lib/typescript/src/components/index.d.ts.map +1 -0
  57. package/lib/typescript/src/context/ElearnConfigContext.d.ts +22 -0
  58. package/lib/typescript/src/context/ElearnConfigContext.d.ts.map +1 -0
  59. package/lib/typescript/src/context/ThemeContext.d.ts +11 -0
  60. package/lib/typescript/src/context/ThemeContext.d.ts.map +1 -0
  61. package/lib/typescript/src/index.d.ts +6 -0
  62. package/lib/typescript/src/index.d.ts.map +1 -0
  63. package/lib/typescript/src/multiply.d.ts +2 -0
  64. package/lib/typescript/src/multiply.d.ts.map +1 -0
  65. package/lib/typescript/src/screens/HomeScreen.d.ts +3 -0
  66. package/lib/typescript/src/screens/HomeScreen.d.ts.map +1 -0
  67. package/lib/typescript/src/screens/QbankScreen.d.ts +3 -0
  68. package/lib/typescript/src/screens/QbankScreen.d.ts.map +1 -0
  69. package/lib/typescript/src/screens/QuestionScreen.d.ts +11 -0
  70. package/lib/typescript/src/screens/QuestionScreen.d.ts.map +1 -0
  71. package/lib/typescript/src/screens/QuizStartScreen.d.ts +10 -0
  72. package/lib/typescript/src/screens/QuizStartScreen.d.ts.map +1 -0
  73. package/lib/typescript/src/screens/ResultScreen.d.ts +11 -0
  74. package/lib/typescript/src/screens/ResultScreen.d.ts.map +1 -0
  75. package/lib/typescript/src/screens/TopicListScreen.d.ts +9 -0
  76. package/lib/typescript/src/screens/TopicListScreen.d.ts.map +1 -0
  77. package/lib/typescript/src/screens/index.d.ts +7 -0
  78. package/lib/typescript/src/screens/index.d.ts.map +1 -0
  79. package/lib/typescript/src/types/index.d.ts +107 -0
  80. package/lib/typescript/src/types/index.d.ts.map +1 -0
  81. package/package.json +121 -0
  82. package/src/components/Button.tsx +101 -0
  83. package/src/components/Card.tsx +57 -0
  84. package/src/components/CircularProgress.tsx +93 -0
  85. package/src/components/Icon.tsx +338 -0
  86. package/src/components/ProgressBar.tsx +47 -0
  87. package/src/components/Typography.tsx +112 -0
  88. package/src/components/index.ts +8 -0
  89. package/src/context/ElearnConfigContext.tsx +90 -0
  90. package/src/context/ThemeContext.tsx +37 -0
  91. package/src/index.tsx +33 -0
  92. package/src/multiply.tsx +3 -0
  93. package/src/screens/HomeScreen.tsx +291 -0
  94. package/src/screens/QbankScreen.tsx +176 -0
  95. package/src/screens/QuestionScreen.tsx +402 -0
  96. package/src/screens/QuizStartScreen.tsx +215 -0
  97. package/src/screens/ResultScreen.tsx +303 -0
  98. package/src/screens/TopicListScreen.tsx +200 -0
  99. package/src/screens/index.ts +6 -0
  100. package/src/types/index.ts +122 -0
@@ -0,0 +1,291 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ ScrollView,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ SafeAreaView,
8
+ StatusBar,
9
+ Image,
10
+ } from 'react-native';
11
+ import { useElearnConfig } from '../context/ElearnConfigContext';
12
+ import { useTheme } from '../context/ThemeContext';
13
+ import { Typography, Card, CircularProgress, Icon } from '../components';
14
+
15
+ export const HomeScreen: React.FC = () => {
16
+ const { config, callbacks, getString } = useElearnConfig();
17
+ const theme = useTheme();
18
+
19
+ const dailyQuiz = config.dailyQuiz;
20
+ const courses = config.courses || [];
21
+
22
+ const handleDailyQuizPress = () => {
23
+ if (dailyQuiz && callbacks.onStartQuiz) {
24
+ callbacks.onStartQuiz(
25
+ dailyQuiz.id,
26
+ dailyQuiz.questions,
27
+ dailyQuiz.title
28
+ );
29
+ }
30
+ };
31
+
32
+ return (
33
+ <SafeAreaView style={[styles.safeArea, { backgroundColor: theme.background }]}>
34
+ <StatusBar barStyle="dark-content" />
35
+
36
+ {/* Header */}
37
+ <View style={styles.header}>
38
+ <View style={styles.headerLeft}>
39
+ <TouchableOpacity style={styles.avatarContainer}>
40
+ <View style={[styles.avatarPlaceholder, { backgroundColor: theme.secondary }]}>
41
+ <Icon name="user" size={20} color={theme.primary} />
42
+ </View>
43
+ </TouchableOpacity>
44
+ <View>
45
+ <Typography variant="bodyLight" color={theme.textSecondary}>
46
+ {getString('homeHeaderTitle')}
47
+ </Typography>
48
+ <Typography variant="h2" bold>
49
+ Dr. Kimberly
50
+ </Typography>
51
+ </View>
52
+ </View>
53
+ <TouchableOpacity style={[styles.iconButton, { borderColor: theme.border }]}>
54
+ <Icon name="bell" size={20} color={theme.textPrimary} />
55
+ <View style={[styles.badge, { backgroundColor: theme.danger }]} />
56
+ </TouchableOpacity>
57
+ </View>
58
+
59
+ <ScrollView contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
60
+
61
+ {/* Daily Quiz Card */}
62
+ {dailyQuiz && (
63
+ <TouchableOpacity activeOpacity={0.9} onPress={handleDailyQuizPress}>
64
+ <Card style={[styles.dailyQuizCard, { backgroundColor: '#0284C7' }]}>
65
+ <View style={styles.dailyQuizRow}>
66
+ <View style={styles.dailyQuizLeft}>
67
+ <Typography variant="h3" color="#FFFFFF" bold>
68
+ {getString('dailyQuizTitle')}
69
+ </Typography>
70
+ <Typography variant="caption" color="#E0F2FE" style={styles.dailyQuizDesc}>
71
+ {getString('dailyQuizSubtitle')}
72
+ </Typography>
73
+ <View style={styles.trackQuickBadge}>
74
+ <Typography variant="caption" color="#0284C7" bold>
75
+ {getString('trackQuickLabel')}
76
+ </Typography>
77
+ </View>
78
+ </View>
79
+
80
+ <View style={styles.dailyQuizRight}>
81
+ <CircularProgress
82
+ progress={dailyQuiz.progressPercentage / 100}
83
+ size={68}
84
+ strokeWidth={6}
85
+ color="#FFFFFF"
86
+ backgroundColor="rgba(255, 255, 255, 0.25)"
87
+ textStyle={{ color: '#FFFFFF', fontSize: 13 }}
88
+ />
89
+ </View>
90
+ </View>
91
+ </Card>
92
+ </TouchableOpacity>
93
+ )}
94
+
95
+ {/* Subjects Tabs */}
96
+ <View style={styles.sectionHeader}>
97
+ <Typography variant="h2" bold>
98
+ {getString('subjectsTitle')}
99
+ </Typography>
100
+ </View>
101
+
102
+ <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.subjectsContainer}>
103
+ {courses.map((course) => {
104
+ let iconName: any = 'flask';
105
+ if (course.title.toLowerCase().includes('physic')) iconName = 'atom';
106
+ if (course.title.toLowerCase().includes('biolog')) iconName = 'dna';
107
+ if (course.title.toLowerCase().includes('anatom')) iconName = 'book-open';
108
+
109
+ return (
110
+ <TouchableOpacity
111
+ key={course.id}
112
+ style={[
113
+ styles.subjectTab,
114
+ { backgroundColor: theme.cardBackground, borderColor: theme.border },
115
+ ]}
116
+ onPress={() => callbacks.onSelectCourse?.(course)}
117
+ >
118
+ <View style={[styles.subjectIconWrap, { backgroundColor: theme.secondary }]}>
119
+ <Icon name={iconName} size={20} color={theme.primary} />
120
+ </View>
121
+ <Typography variant="label" bold style={styles.subjectText}>
122
+ {course.title}
123
+ </Typography>
124
+ </TouchableOpacity>
125
+ );
126
+ })}
127
+ </ScrollView>
128
+
129
+ {/* Popular Topics Section */}
130
+ <View style={styles.sectionHeader}>
131
+ <Typography variant="h2" bold>
132
+ {getString('popularTopicsTitle')}
133
+ </Typography>
134
+ </View>
135
+
136
+ {/* Mocking a beautiful content card as shown in the UI mockup */}
137
+ <Card bordered style={styles.infoCard}>
138
+ <Image
139
+ source={{ uri: 'https://images.unsplash.com/photo-1576086213369-97a306d36557?q=80&w=600&auto=format&fit=crop' }}
140
+ style={styles.infoCardImage}
141
+ resizeMode="cover"
142
+ />
143
+ <View style={styles.infoCardContent}>
144
+ <View style={styles.infoCardHeader}>
145
+ <Typography variant="caption" color={theme.primary} bold>
146
+ HISTOLOGY
147
+ </Typography>
148
+ <Typography variant="caption" color={theme.textSecondary}>
149
+ 12 min read
150
+ </Typography>
151
+ </View>
152
+ <Typography variant="h3" bold style={styles.infoCardTitle}>
153
+ Tissue structures under microscope examination
154
+ </Typography>
155
+ <Typography variant="body" color={theme.textSecondary} numberOfLines={2}>
156
+ Learn the identification of epithelial tissues, connective tissues, and muscle structures for medical examination prep.
157
+ </Typography>
158
+ </View>
159
+ </Card>
160
+
161
+ </ScrollView>
162
+ </SafeAreaView>
163
+ );
164
+ };
165
+
166
+ const styles = StyleSheet.create({
167
+ safeArea: {
168
+ flex: 1,
169
+ },
170
+ header: {
171
+ flexDirection: 'row',
172
+ justifyContent: 'space-between',
173
+ alignItems: 'center',
174
+ paddingHorizontal: 20,
175
+ paddingVertical: 16,
176
+ },
177
+ headerLeft: {
178
+ flexDirection: 'row',
179
+ alignItems: 'center',
180
+ },
181
+ avatarContainer: {
182
+ marginRight: 12,
183
+ },
184
+ avatarPlaceholder: {
185
+ width: 40,
186
+ height: 40,
187
+ borderRadius: 20,
188
+ justifyContent: 'center',
189
+ alignItems: 'center',
190
+ },
191
+ iconButton: {
192
+ width: 40,
193
+ height: 40,
194
+ borderRadius: 20,
195
+ borderWidth: 1,
196
+ justifyContent: 'center',
197
+ alignItems: 'center',
198
+ position: 'relative',
199
+ },
200
+ badge: {
201
+ position: 'absolute',
202
+ top: 10,
203
+ right: 10,
204
+ width: 8,
205
+ height: 8,
206
+ borderRadius: 4,
207
+ },
208
+ scrollContent: {
209
+ paddingHorizontal: 20,
210
+ paddingBottom: 24,
211
+ },
212
+ dailyQuizCard: {
213
+ marginVertical: 12,
214
+ padding: 20,
215
+ borderRadius: 20,
216
+ },
217
+ dailyQuizRow: {
218
+ flexDirection: 'row',
219
+ justifyContent: 'space-between',
220
+ alignItems: 'center',
221
+ },
222
+ dailyQuizLeft: {
223
+ flex: 1,
224
+ paddingRight: 16,
225
+ },
226
+ dailyQuizDesc: {
227
+ marginTop: 6,
228
+ opacity: 0.9,
229
+ },
230
+ trackQuickBadge: {
231
+ backgroundColor: '#FFFFFF',
232
+ paddingHorizontal: 12,
233
+ paddingVertical: 6,
234
+ borderRadius: 16,
235
+ alignSelf: 'flex-start',
236
+ marginTop: 14,
237
+ },
238
+ dailyQuizRight: {
239
+ justifyContent: 'center',
240
+ alignItems: 'center',
241
+ },
242
+ sectionHeader: {
243
+ marginTop: 20,
244
+ marginBottom: 12,
245
+ },
246
+ subjectsContainer: {
247
+ paddingVertical: 4,
248
+ },
249
+ subjectTab: {
250
+ flexDirection: 'row',
251
+ alignItems: 'center',
252
+ paddingHorizontal: 16,
253
+ paddingVertical: 10,
254
+ borderRadius: 20,
255
+ borderWidth: 1,
256
+ marginRight: 12,
257
+ },
258
+ subjectIconWrap: {
259
+ width: 32,
260
+ height: 32,
261
+ borderRadius: 16,
262
+ justifyContent: 'center',
263
+ alignItems: 'center',
264
+ marginRight: 8,
265
+ },
266
+ subjectText: {
267
+ fontSize: 14,
268
+ },
269
+ infoCard: {
270
+ padding: 0,
271
+ overflow: 'hidden',
272
+ marginTop: 8,
273
+ },
274
+ infoCardImage: {
275
+ width: '100%',
276
+ height: 160,
277
+ },
278
+ infoCardContent: {
279
+ padding: 16,
280
+ },
281
+ infoCardHeader: {
282
+ flexDirection: 'row',
283
+ justifyContent: 'space-between',
284
+ alignItems: 'center',
285
+ marginBottom: 6,
286
+ },
287
+ infoCardTitle: {
288
+ marginBottom: 8,
289
+ lineHeight: 22,
290
+ },
291
+ });
@@ -0,0 +1,176 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ ScrollView,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ SafeAreaView,
8
+ StatusBar,
9
+ } from 'react-native';
10
+ import { useElearnConfig } from '../context/ElearnConfigContext';
11
+ import { useTheme } from '../context/ThemeContext';
12
+ import { Typography, Card, ProgressBar, Icon } from '../components';
13
+
14
+ export const QbankScreen: React.FC = () => {
15
+ const { config, callbacks, getString } = useElearnConfig();
16
+ const theme = useTheme();
17
+
18
+ const courses = config.courses || [];
19
+
20
+ return (
21
+ <SafeAreaView style={[styles.safeArea, { backgroundColor: theme.background }]}>
22
+ <StatusBar barStyle="dark-content" />
23
+
24
+ {/* Header */}
25
+ <View style={styles.header}>
26
+ <TouchableOpacity
27
+ onPress={() => callbacks.onBackToDashboard?.()}
28
+ style={[styles.backButton, { borderColor: theme.border }]}
29
+ >
30
+ <Icon name="arrow-left" size={20} color={theme.textPrimary} />
31
+ </TouchableOpacity>
32
+ <Typography variant="h2" bold style={styles.headerTitle}>
33
+ {getString('qbankTitle')}
34
+ </Typography>
35
+ <View style={styles.headerRightPlaceholder} />
36
+ </View>
37
+
38
+ <ScrollView contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
39
+ <View style={styles.introSection}>
40
+ <Typography variant="h1" bold color={theme.textPrimary}>
41
+ {getString('qbankTitle')}
42
+ </Typography>
43
+ <Typography variant="body" color={theme.textSecondary} style={styles.introDesc}>
44
+ {getString('qbankSubtitle')}
45
+ </Typography>
46
+ </View>
47
+
48
+ {/* Subjects List */}
49
+ <View style={styles.listContainer}>
50
+ {courses.map((course) => {
51
+ const pct = Math.round(course.progress * 100);
52
+
53
+ return (
54
+ <Card
55
+ key={course.id}
56
+ bordered
57
+ onPress={() => callbacks.onSelectCourse?.(course)}
58
+ style={styles.subjectCard}
59
+ >
60
+ <View style={styles.cardHeader}>
61
+ <View style={styles.cardHeaderLeft}>
62
+ <View style={[styles.folderIconContainer, { backgroundColor: theme.secondary }]}>
63
+ <Icon name="folder" size={22} color={theme.primary} />
64
+ </View>
65
+ <View style={styles.subjectInfo}>
66
+ <Typography variant="h3" bold color={theme.textPrimary}>
67
+ {course.title}
68
+ </Typography>
69
+ <Typography variant="caption" color={theme.textSecondary}>
70
+ {course.topics.length} {getString('topicsLabel')}
71
+ </Typography>
72
+ </View>
73
+ </View>
74
+ <Typography variant="h3" bold color={theme.primary}>
75
+ {pct}%
76
+ </Typography>
77
+ </View>
78
+
79
+ {/* Progress Details */}
80
+ <View style={styles.progressSection}>
81
+ <ProgressBar progress={course.progress} style={styles.progressBar} />
82
+ <View style={styles.progressTextRow}>
83
+ <Typography variant="caption" color={theme.textSecondary}>
84
+ {getString('questionsCountLabel')}
85
+ </Typography>
86
+ <Typography variant="caption" bold color={theme.textPrimary}>
87
+ {course.completedQuestions}/{course.totalQuestions}
88
+ </Typography>
89
+ </View>
90
+ </View>
91
+ </Card>
92
+ );
93
+ })}
94
+ </View>
95
+
96
+ </ScrollView>
97
+ </SafeAreaView>
98
+ );
99
+ };
100
+
101
+ const styles = StyleSheet.create({
102
+ safeArea: {
103
+ flex: 1,
104
+ },
105
+ header: {
106
+ flexDirection: 'row',
107
+ justifyContent: 'space-between',
108
+ alignItems: 'center',
109
+ paddingHorizontal: 20,
110
+ paddingVertical: 12,
111
+ },
112
+ backButton: {
113
+ width: 40,
114
+ height: 40,
115
+ borderRadius: 20,
116
+ borderWidth: 1,
117
+ justifyContent: 'center',
118
+ alignItems: 'center',
119
+ },
120
+ headerTitle: {
121
+ fontSize: 18,
122
+ },
123
+ headerRightPlaceholder: {
124
+ width: 40,
125
+ },
126
+ scrollContent: {
127
+ paddingHorizontal: 20,
128
+ paddingBottom: 24,
129
+ },
130
+ introSection: {
131
+ marginVertical: 16,
132
+ },
133
+ introDesc: {
134
+ marginTop: 4,
135
+ lineHeight: 20,
136
+ },
137
+ listContainer: {
138
+ marginTop: 8,
139
+ },
140
+ subjectCard: {
141
+ padding: 16,
142
+ marginBottom: 12,
143
+ },
144
+ cardHeader: {
145
+ flexDirection: 'row',
146
+ justifyContent: 'space-between',
147
+ alignItems: 'center',
148
+ },
149
+ cardHeaderLeft: {
150
+ flexDirection: 'row',
151
+ alignItems: 'center',
152
+ flex: 1,
153
+ },
154
+ folderIconContainer: {
155
+ width: 44,
156
+ height: 44,
157
+ borderRadius: 12,
158
+ justifyContent: 'center',
159
+ alignItems: 'center',
160
+ marginRight: 12,
161
+ },
162
+ subjectInfo: {
163
+ flex: 1,
164
+ },
165
+ progressSection: {
166
+ marginTop: 16,
167
+ },
168
+ progressBar: {
169
+ marginBottom: 8,
170
+ },
171
+ progressTextRow: {
172
+ flexDirection: 'row',
173
+ justifyContent: 'space-between',
174
+ alignItems: 'center',
175
+ },
176
+ });