react-native-elearn-ui 0.1.11 → 0.1.13

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 (60) hide show
  1. package/lib/module/index.js +1 -1
  2. package/lib/module/index.js.map +1 -1
  3. package/lib/module/screens/HomeScreen.js +672 -662
  4. package/lib/module/screens/HomeScreen.js.map +1 -1
  5. package/lib/module/screens/index.js +0 -8
  6. package/lib/module/screens/index.js.map +1 -1
  7. package/lib/typescript/src/index.d.ts +1 -1
  8. package/lib/typescript/src/index.d.ts.map +1 -1
  9. package/lib/typescript/src/screens/HomeScreen.d.ts.map +1 -1
  10. package/lib/typescript/src/screens/index.d.ts +0 -8
  11. package/lib/typescript/src/screens/index.d.ts.map +1 -1
  12. package/package.json +1 -1
  13. package/src/index.tsx +0 -8
  14. package/src/screens/HomeScreen.tsx +471 -534
  15. package/src/screens/index.ts +0 -8
  16. package/lib/module/screens/PearlChaptersScreen.js +0 -359
  17. package/lib/module/screens/PearlChaptersScreen.js.map +0 -1
  18. package/lib/module/screens/PearlReaderScreen.js +0 -313
  19. package/lib/module/screens/PearlReaderScreen.js.map +0 -1
  20. package/lib/module/screens/PearlsScreen.js +0 -153
  21. package/lib/module/screens/PearlsScreen.js.map +0 -1
  22. package/lib/module/screens/QbankScreen.js +0 -370
  23. package/lib/module/screens/QbankScreen.js.map +0 -1
  24. package/lib/module/screens/QuestionScreen.js +0 -437
  25. package/lib/module/screens/QuestionScreen.js.map +0 -1
  26. package/lib/module/screens/QuizStartScreen.js +0 -283
  27. package/lib/module/screens/QuizStartScreen.js.map +0 -1
  28. package/lib/module/screens/ResultScreen.js +0 -646
  29. package/lib/module/screens/ResultScreen.js.map +0 -1
  30. package/lib/module/screens/TopicListScreen.js +0 -420
  31. package/lib/module/screens/TopicListScreen.js.map +0 -1
  32. package/lib/module/screens/pearlsMockData.js +0 -77
  33. package/lib/module/screens/pearlsMockData.js.map +0 -1
  34. package/lib/typescript/src/screens/PearlChaptersScreen.d.ts +0 -13
  35. package/lib/typescript/src/screens/PearlChaptersScreen.d.ts.map +0 -1
  36. package/lib/typescript/src/screens/PearlReaderScreen.d.ts +0 -14
  37. package/lib/typescript/src/screens/PearlReaderScreen.d.ts.map +0 -1
  38. package/lib/typescript/src/screens/PearlsScreen.d.ts +0 -11
  39. package/lib/typescript/src/screens/PearlsScreen.d.ts.map +0 -1
  40. package/lib/typescript/src/screens/QbankScreen.d.ts +0 -10
  41. package/lib/typescript/src/screens/QbankScreen.d.ts.map +0 -1
  42. package/lib/typescript/src/screens/QuestionScreen.d.ts +0 -14
  43. package/lib/typescript/src/screens/QuestionScreen.d.ts.map +0 -1
  44. package/lib/typescript/src/screens/QuizStartScreen.d.ts +0 -14
  45. package/lib/typescript/src/screens/QuizStartScreen.d.ts.map +0 -1
  46. package/lib/typescript/src/screens/ResultScreen.d.ts +0 -13
  47. package/lib/typescript/src/screens/ResultScreen.d.ts.map +0 -1
  48. package/lib/typescript/src/screens/TopicListScreen.d.ts +0 -12
  49. package/lib/typescript/src/screens/TopicListScreen.d.ts.map +0 -1
  50. package/lib/typescript/src/screens/pearlsMockData.d.ts +0 -3
  51. package/lib/typescript/src/screens/pearlsMockData.d.ts.map +0 -1
  52. package/src/screens/PearlChaptersScreen.tsx +0 -330
  53. package/src/screens/PearlReaderScreen.tsx +0 -306
  54. package/src/screens/PearlsScreen.tsx +0 -147
  55. package/src/screens/QbankScreen.tsx +0 -327
  56. package/src/screens/QuestionScreen.tsx +0 -423
  57. package/src/screens/QuizStartScreen.tsx +0 -260
  58. package/src/screens/ResultScreen.tsx +0 -618
  59. package/src/screens/TopicListScreen.tsx +0 -388
  60. package/src/screens/pearlsMockData.ts +0 -70
@@ -1,423 +0,0 @@
1
- import React, { useState } from 'react';
2
- import {
3
- View,
4
- ScrollView,
5
- StyleSheet,
6
- TouchableOpacity,
7
- StatusBar,
8
- Image,
9
- } from 'react-native';
10
- import { SafeAreaView } from 'react-native-safe-area-context';
11
- import type { Question, QuizResults } from '../types';
12
- import { useElearnConfig } from '../context/ElearnConfigContext';
13
- import { useTheme } from '../context/ThemeContext';
14
- import { Typography, Button, Icon } from '../components';
15
-
16
- interface QuestionScreenProps {
17
- quizId?: string;
18
- questions?: Question[];
19
- title?: string;
20
- topicId?: string;
21
- onClose: () => void;
22
- onFinishQuiz?: (quizId: string, results: QuizResults) => void;
23
- hideHeader?: boolean;
24
- }
25
-
26
- export const QuestionScreen: React.FC<QuestionScreenProps> = ({
27
- quizId,
28
- questions,
29
- title,
30
- topicId,
31
- onClose,
32
- onFinishQuiz,
33
- hideHeader = false,
34
- }) => {
35
- const { config, callbacks } = useElearnConfig();
36
- const theme = useTheme();
37
-
38
- const activeTopic = topicId ? config.courses?.flatMap((c) => c.topics).find((t) => t.id === topicId) : undefined;
39
- const activeQuestions = questions || activeTopic?.questions || [];
40
- const activeTitle = title || activeTopic?.title || 'Quiz';
41
- const activeQuizId = quizId || topicId || '';
42
-
43
- const [currentIndex, setCurrentIndex] = useState(0);
44
- const [selectedOption, setSelectedOption] = useState<number | null>(null);
45
- const [isAnswered, setIsAnswered] = useState(false);
46
- const [userAnswers, setUserAnswers] = useState<{ [questionId: string]: number }>({});
47
- const [correctCount, setCorrectCount] = useState(0);
48
- const [startTime] = useState(Date.now());
49
- const [isPaused, setIsPaused] = useState(false);
50
-
51
- if (!activeQuestions || activeQuestions.length === 0) {
52
- return (
53
- <SafeAreaView style={[styles.safeArea, { backgroundColor: theme.background }]}>
54
- <View style={styles.errorContainer}>
55
- <Typography variant="h2" bold>No questions available</Typography>
56
- <Button title="Go Back" onPress={onClose} style={styles.errorButton} />
57
- </View>
58
- </SafeAreaView>
59
- );
60
- }
61
-
62
- const currentQuestion = activeQuestions[currentIndex]!;
63
- const optionPrefixes = ['A', 'B', 'C', 'D', 'E', 'F'];
64
-
65
- const handleOptionPress = (index: number) => {
66
- if (isAnswered) return; // Prevent changing answer after selection
67
-
68
- setSelectedOption(index);
69
- setIsAnswered(true);
70
-
71
- const updatedAnswers = { ...userAnswers, [currentQuestion.id]: index };
72
- setUserAnswers(updatedAnswers);
73
-
74
- const isCorrect = index === currentQuestion.correctOptionIndex;
75
- if (isCorrect) {
76
- setCorrectCount((prev) => prev + 1);
77
- }
78
- };
79
-
80
- const handleNext = () => {
81
- if (currentIndex < activeQuestions.length - 1) {
82
- setCurrentIndex((prev) => prev + 1);
83
- setSelectedOption(null);
84
- setIsAnswered(false);
85
- } else {
86
- // Last question - finish quiz
87
- const totalTimeSeconds = Math.round((Date.now() - startTime) / 1000);
88
- const wrongCount = activeQuestions.length - correctCount;
89
- const accuracy = Math.round((correctCount / activeQuestions.length) * 100);
90
-
91
- const results: QuizResults = {
92
- quizId: activeQuizId,
93
- totalQuestions: activeQuestions.length,
94
- correctCount,
95
- wrongCount,
96
- skippedCount: 0,
97
- accuracy,
98
- timeSpentSeconds: totalTimeSeconds,
99
- userAnswers,
100
- };
101
-
102
- if (onFinishQuiz) {
103
- onFinishQuiz(activeQuizId, results);
104
- } else {
105
- callbacks.onFinishQuiz?.(activeQuizId, results);
106
- }
107
- }
108
- };
109
-
110
- return (
111
- <SafeAreaView style={[styles.safeArea, { backgroundColor: theme.background }]}>
112
- <StatusBar barStyle="dark-content" />
113
-
114
- {/* Header */}
115
- {!hideHeader && (
116
- <View style={styles.header}>
117
- <TouchableOpacity onPress={onClose} style={styles.backButton}>
118
- <Icon name="arrow-left" size={20} color={theme.textPrimary} />
119
- </TouchableOpacity>
120
-
121
- <Typography variant="h2" bold style={styles.headerTitle}>
122
- {activeTitle || 'QBank'}
123
- </Typography>
124
-
125
- <TouchableOpacity style={styles.shareButton}>
126
- <Icon name="share" size={20} color={theme.textPrimary} />
127
- </TouchableOpacity>
128
- </View>
129
- )}
130
-
131
- <ScrollView contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
132
-
133
- {/* Question Header & Pause/Bookmark Actions Row */}
134
- <View style={styles.metaRow}>
135
- <Typography variant="caption" bold color={theme.textSecondary} style={styles.questionNumLabel}>
136
- QUESTION {currentIndex + 1}/{activeQuestions.length}
137
- </Typography>
138
- <View style={styles.metaActions}>
139
- <TouchableOpacity style={styles.metaActionBtn}>
140
- <Icon name="bookmark" size={18} color={theme.textSecondary} />
141
- </TouchableOpacity>
142
- <TouchableOpacity onPress={() => setIsPaused(!isPaused)} style={styles.metaActionBtn}>
143
- <Icon name={isPaused ? 'play' : 'pause-circle'} size={18} color={theme.textSecondary} />
144
- </TouchableOpacity>
145
- </View>
146
- </View>
147
-
148
- {/* Question text */}
149
- <Typography variant="h2" bold color={theme.textPrimary} style={styles.questionText}>
150
- {currentQuestion.text}
151
- </Typography>
152
-
153
- {/* Neuron microscope image */}
154
- {currentQuestion.imageUrl && (
155
- <Image
156
- source={{ uri: currentQuestion.imageUrl }}
157
- style={styles.questionImage}
158
- resizeMode="cover"
159
- />
160
- )}
161
-
162
- {/* Options list */}
163
- <View style={styles.optionsList}>
164
- {currentQuestion.options.map((option, idx) => {
165
- const isSelected = selectedOption === idx;
166
- const isCorrectAnswer = idx === currentQuestion.correctOptionIndex;
167
-
168
- let optionBg = '#FFFFFF';
169
- let optionBorder = theme.border;
170
- let labelColor = theme.textPrimary;
171
- let prefixColor = theme.textSecondary;
172
- let statText = '';
173
-
174
- if (isAnswered) {
175
- if (isCorrectAnswer) {
176
- optionBg = '#E6F4F1'; // Tinted green bg
177
- optionBorder = '#10B981'; // Green border
178
- labelColor = '#065F46';
179
- prefixColor = '#065F46';
180
- statText = '73% got this Correct'; // Mock stats matching mockup 5
181
- } else if (isSelected) {
182
- optionBg = '#FEF2F2'; // Tinted red bg
183
- optionBorder = '#EF4444'; // Red border
184
- labelColor = '#991B1B';
185
- prefixColor = '#991B1B';
186
- statText = '27% Marked Wrong'; // Mock stats matching mockup 5
187
- }
188
- } else if (isSelected) {
189
- optionBg = theme.secondary;
190
- optionBorder = theme.primary;
191
- labelColor = theme.primary;
192
- prefixColor = theme.primary;
193
- }
194
-
195
- return (
196
- <TouchableOpacity
197
- key={idx}
198
- activeOpacity={0.8}
199
- onPress={() => handleOptionPress(idx)}
200
- disabled={isAnswered}
201
- style={[
202
- styles.optionCard,
203
- {
204
- backgroundColor: optionBg,
205
- borderColor: optionBorder,
206
- },
207
- ]}
208
- >
209
- <View style={styles.optionRow}>
210
- {/* Option letter label */}
211
- <Typography variant="body" bold color={prefixColor} style={styles.optionPrefix}>
212
- {optionPrefixes[idx] || idx + 1}
213
- </Typography>
214
-
215
- {/* Option text */}
216
- <Typography variant="body" color={labelColor} style={styles.optionText}>
217
- {option}
218
- </Typography>
219
- </View>
220
-
221
- {/* Option stats badge below option text */}
222
- {isAnswered && statText !== '' && (
223
- <View style={styles.statBadgeRow}>
224
- <Typography variant="caption" bold color={isCorrectAnswer ? '#10B981' : '#EF4444'}>
225
- {statText}
226
- </Typography>
227
- </View>
228
- )}
229
- </TouchableOpacity>
230
- );
231
- })}
232
- </View>
233
-
234
- {/* Explanation Card (Appears after answer selection) */}
235
- {isAnswered && (
236
- <View style={styles.explanationSection}>
237
- <Typography variant="h2" bold color={theme.textPrimary} style={styles.explanationTitle}>
238
- Explanation
239
- </Typography>
240
- <Typography variant="body" color={theme.textSecondary} style={styles.explanationBody}>
241
- {currentQuestion.explanation}
242
- </Typography>
243
-
244
- <Typography variant="h3" bold color={theme.textSecondary} style={styles.rxdxId}>
245
- RXDX ID: R23082
246
- </Typography>
247
- </View>
248
- )}
249
-
250
- </ScrollView>
251
-
252
- {/* Answered State Bottom Actions Bar */}
253
- {isAnswered && (
254
- <View style={styles.footerRow}>
255
- {/* Report action */}
256
- <TouchableOpacity style={styles.footerActionBtn}>
257
- <Icon name="alert-circle" size={18} color="#EF4444" />
258
- <Typography variant="caption" bold color="#EF4444" style={styles.footerActionLabel}>
259
- Report
260
- </Typography>
261
- </TouchableOpacity>
262
-
263
- {/* Whatsapp action */}
264
- <TouchableOpacity style={styles.footerActionBtn}>
265
- <Icon name="whatsapp" size={18} color="#22C55E" />
266
- <Typography variant="caption" bold color="#22C55E" style={styles.footerActionLabel}>
267
- Whatsapp
268
- </Typography>
269
- </TouchableOpacity>
270
-
271
- {/* Next action button */}
272
- <TouchableOpacity onPress={handleNext} style={[styles.nextActionBtn, { backgroundColor: theme.primary }]}>
273
- <Typography variant="body" bold color="#FFFFFF">
274
- Next
275
- </Typography>
276
- </TouchableOpacity>
277
- </View>
278
- )}
279
- </SafeAreaView>
280
- );
281
- };
282
-
283
- const styles = StyleSheet.create({
284
- safeArea: {
285
- flex: 1,
286
- },
287
- header: {
288
- flexDirection: 'row',
289
- justifyContent: 'space-between',
290
- alignItems: 'center',
291
- paddingHorizontal: 16,
292
- paddingVertical: 12,
293
- },
294
- backButton: {
295
- padding: 6,
296
- },
297
- headerTitle: {
298
- fontSize: 18,
299
- fontWeight: '700',
300
- },
301
- shareButton: {
302
- padding: 6,
303
- },
304
- scrollContent: {
305
- paddingHorizontal: 16,
306
- paddingTop: 8,
307
- paddingBottom: 32,
308
- },
309
- metaRow: {
310
- flexDirection: 'row',
311
- justifyContent: 'space-between',
312
- alignItems: 'center',
313
- marginBottom: 12,
314
- },
315
- questionNumLabel: {
316
- fontSize: 12,
317
- letterSpacing: 0.8,
318
- },
319
- metaActions: {
320
- flexDirection: 'row',
321
- alignItems: 'center',
322
- },
323
- metaActionBtn: {
324
- padding: 6,
325
- marginLeft: 10,
326
- },
327
- questionText: {
328
- fontSize: 16,
329
- lineHeight: 22,
330
- marginBottom: 14,
331
- },
332
- questionImage: {
333
- width: '100%',
334
- height: 180,
335
- borderRadius: 12,
336
- marginBottom: 16,
337
- backgroundColor: '#F8FAFC',
338
- },
339
- optionsList: {
340
- marginBottom: 12,
341
- },
342
- optionCard: {
343
- borderWidth: 1,
344
- borderRadius: 10,
345
- padding: 12,
346
- marginBottom: 10,
347
- },
348
- optionRow: {
349
- flexDirection: 'row',
350
- alignItems: 'flex-start',
351
- },
352
- optionPrefix: {
353
- width: 24,
354
- fontSize: 14,
355
- fontWeight: '600',
356
- },
357
- optionText: {
358
- flex: 1,
359
- fontSize: 14,
360
- lineHeight: 18,
361
- },
362
- statBadgeRow: {
363
- marginTop: 6,
364
- paddingLeft: 24,
365
- },
366
- explanationSection: {
367
- marginTop: 14,
368
- paddingTop: 14,
369
- borderTopWidth: 1,
370
- borderTopColor: '#E2E8F0',
371
- },
372
- explanationTitle: {
373
- fontSize: 15,
374
- marginBottom: 6,
375
- },
376
- explanationBody: {
377
- fontSize: 13,
378
- lineHeight: 18,
379
- marginBottom: 16,
380
- },
381
- rxdxId: {
382
- fontSize: 12,
383
- textAlign: 'center',
384
- marginTop: 12,
385
- },
386
- footerRow: {
387
- flexDirection: 'row',
388
- alignItems: 'center',
389
- paddingHorizontal: 16,
390
- paddingVertical: 12,
391
- backgroundColor: '#FFFFFF',
392
- borderTopWidth: 1,
393
- borderTopColor: '#E2E8F0',
394
- justifyContent: 'space-between',
395
- },
396
- footerActionBtn: {
397
- flexDirection: 'row',
398
- alignItems: 'center',
399
- paddingVertical: 8,
400
- paddingHorizontal: 12,
401
- },
402
- footerActionLabel: {
403
- marginLeft: 6,
404
- fontSize: 12,
405
- },
406
- nextActionBtn: {
407
- paddingHorizontal: 24,
408
- paddingVertical: 10,
409
- borderRadius: 8,
410
- minWidth: 80,
411
- justifyContent: 'center',
412
- alignItems: 'center',
413
- },
414
- errorContainer: {
415
- flex: 1,
416
- justifyContent: 'center',
417
- alignItems: 'center',
418
- padding: 24,
419
- },
420
- errorButton: {
421
- marginTop: 16,
422
- },
423
- });
@@ -1,260 +0,0 @@
1
- import React from 'react';
2
- import {
3
- View,
4
- StyleSheet,
5
- TouchableOpacity,
6
- StatusBar,
7
- } from 'react-native';
8
- import { SafeAreaView } from 'react-native-safe-area-context';
9
- import type { Topic, Course, Question } from '../types';
10
- import { useElearnConfig } from '../context/ElearnConfigContext';
11
- import { useTheme } from '../context/ThemeContext';
12
- import { Typography, Card, Button, Icon } from '../components';
13
-
14
- interface QuizStartScreenProps {
15
- course?: Course;
16
- courseId?: string;
17
- topic?: Topic;
18
- topicId?: string;
19
- onBack: () => void;
20
- hideHeader?: boolean;
21
- onStartQuiz?: (quizId: string, questions: Question[], title: string) => void;
22
- }
23
-
24
- export const QuizStartScreen: React.FC<QuizStartScreenProps> = ({
25
- course,
26
- courseId,
27
- topic,
28
- topicId,
29
- onBack,
30
- hideHeader = false,
31
- onStartQuiz,
32
- }) => {
33
- const { config, callbacks } = useElearnConfig();
34
- const theme = useTheme();
35
-
36
- const activeCourse = course || config.courses?.find((c) => c.id === courseId);
37
- const activeTopic = topic || activeCourse?.topics.find((t) => t.id === topicId) || config.courses?.flatMap((c) => c.topics).find((t) => t.id === topicId);
38
-
39
- const handleStart = () => {
40
- if (activeTopic && activeTopic.questions) {
41
- if (onStartQuiz) {
42
- onStartQuiz(activeTopic.id, activeTopic.questions, activeTopic.title);
43
- } else {
44
- callbacks.onStartQuiz?.(activeTopic.id, activeTopic.questions, activeTopic.title);
45
- }
46
- }
47
- };
48
-
49
- if (!activeTopic) {
50
- return (
51
- <SafeAreaView style={[styles.safeArea, { backgroundColor: theme.background }]}>
52
- <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 }}>
53
- <Typography variant="h2" bold style={{ marginBottom: 12 }}>Topic not found</Typography>
54
- <TouchableOpacity
55
- onPress={onBack}
56
- style={{
57
- paddingHorizontal: 20,
58
- paddingVertical: 10,
59
- borderRadius: 8,
60
- backgroundColor: theme.primary,
61
- }}
62
- >
63
- <Typography variant="body" bold color="#FFFFFF">Go Back</Typography>
64
- </TouchableOpacity>
65
- </View>
66
- </SafeAreaView>
67
- );
68
- }
69
-
70
- // Mock list of glance topics matching mockup 3
71
- const glanceTopics = [
72
- 'Cerebral Cortex',
73
- 'Cranial Nerves',
74
- 'Spinal Cord Tracts',
75
- 'Brainstem Anatomy',
76
- 'Basal Ganglia',
77
- 'Thalamus and Hypothalamus',
78
- 'Visual and Auditory Pathways',
79
- ];
80
-
81
- return (
82
- <SafeAreaView style={[styles.safeArea, { backgroundColor: theme.background }]}>
83
- <StatusBar barStyle="dark-content" />
84
-
85
- {/* Header */}
86
- {!hideHeader && (
87
- <View style={styles.header}>
88
- <TouchableOpacity onPress={onBack} style={styles.backButton}>
89
- <Icon name="arrow-left" size={20} color={theme.textPrimary} />
90
- </TouchableOpacity>
91
- <Typography variant="h2" bold style={styles.headerTitle}>
92
- QBank
93
- </Typography>
94
- <TouchableOpacity style={styles.shareButton}>
95
- <Icon name="share" size={20} color={theme.textPrimary} />
96
- </TouchableOpacity>
97
- </View>
98
- )}
99
-
100
- <View style={styles.container}>
101
- <View style={styles.content}>
102
-
103
- {/* Section Category Title */}
104
- <Typography variant="h1" bold color={theme.textPrimary} style={styles.categoryTitle}>
105
- {activeTopic.category || 'Neuro Anatomy'}
106
- </Typography>
107
-
108
- {/* Main Info Box */}
109
- <Card bordered style={styles.infoCard}>
110
- <View style={styles.topicHeaderRow}>
111
- {/* Left Circle Icon */}
112
- <View style={[styles.iconCircle, { backgroundColor: 'rgba(59, 130, 246, 0.1)' }]}>
113
- <Icon name="file-text" size={20} color="#3B82F6" />
114
- </View>
115
- {/* Right details */}
116
- <View style={styles.topicHeaderDetails}>
117
- <Typography variant="h2" bold color={theme.textPrimary} style={styles.topicMainTitle}>
118
- {activeTopic.title}
119
- </Typography>
120
- <Typography variant="caption" color={theme.textSecondary}>
121
- {activeTopic.totalQuestions} Questions
122
- </Typography>
123
- </View>
124
- </View>
125
-
126
- {/* Launch Button inside the card box */}
127
- <Button
128
- title="Start QBank"
129
- onPress={handleStart}
130
- variant="primary"
131
- style={[styles.startButton, { backgroundColor: theme.primary }]}
132
- disabled={!activeTopic.questions || activeTopic.questions.length === 0}
133
- />
134
- </Card>
135
-
136
- {/* Glance Topics list */}
137
- <View style={styles.glanceSection}>
138
- <Typography variant="h2" bold color={theme.textPrimary} style={styles.glanceTitle}>
139
- Topics at a Glance
140
- </Typography>
141
- <Typography variant="body" color={theme.textSecondary} style={styles.glanceSub}>
142
- It's recommended that you thoroughly study these topics prior to attempting the QBank.
143
- </Typography>
144
-
145
- <View style={styles.bulletList}>
146
- {glanceTopics.map((item, idx) => (
147
- <View key={idx} style={styles.bulletRow}>
148
- <View style={[styles.bulletDot, { backgroundColor: theme.primary }]} />
149
- <Typography variant="body" color={theme.textPrimary} style={styles.bulletText}>
150
- {item}
151
- </Typography>
152
- </View>
153
- ))}
154
- </View>
155
- </View>
156
-
157
- </View>
158
- </View>
159
- </SafeAreaView>
160
- );
161
- };
162
-
163
- const styles = StyleSheet.create({
164
- safeArea: {
165
- flex: 1,
166
- },
167
- header: {
168
- flexDirection: 'row',
169
- justifyContent: 'space-between',
170
- alignItems: 'center',
171
- paddingHorizontal: 16,
172
- paddingVertical: 12,
173
- },
174
- backButton: {
175
- padding: 6,
176
- },
177
- headerTitle: {
178
- fontSize: 18,
179
- fontWeight: '700',
180
- },
181
- shareButton: {
182
- padding: 6,
183
- },
184
- container: {
185
- flex: 1,
186
- },
187
- content: {
188
- flex: 1,
189
- paddingHorizontal: 16,
190
- paddingTop: 12,
191
- },
192
- categoryTitle: {
193
- fontSize: 22,
194
- marginBottom: 16,
195
- },
196
- infoCard: {
197
- padding: 16,
198
- borderRadius: 16,
199
- backgroundColor: '#FFFFFF',
200
- borderWidth: 1,
201
- borderColor: '#E2E8F0',
202
- },
203
- topicHeaderRow: {
204
- flexDirection: 'row',
205
- alignItems: 'center',
206
- marginBottom: 16,
207
- },
208
- iconCircle: {
209
- width: 44,
210
- height: 44,
211
- borderRadius: 22,
212
- justifyContent: 'center',
213
- alignItems: 'center',
214
- marginRight: 12,
215
- },
216
- topicHeaderDetails: {
217
- flex: 1,
218
- },
219
- topicMainTitle: {
220
- fontSize: 15,
221
- lineHeight: 19,
222
- marginBottom: 2,
223
- },
224
- startButton: {
225
- width: '100%',
226
- height: 46,
227
- justifyContent: 'center',
228
- alignItems: 'center',
229
- borderRadius: 10,
230
- },
231
- glanceSection: {
232
- marginTop: 24,
233
- },
234
- glanceTitle: {
235
- fontSize: 16,
236
- marginBottom: 6,
237
- },
238
- glanceSub: {
239
- fontSize: 13,
240
- lineHeight: 18,
241
- marginBottom: 16,
242
- },
243
- bulletList: {
244
- marginTop: 4,
245
- },
246
- bulletRow: {
247
- flexDirection: 'row',
248
- alignItems: 'center',
249
- marginBottom: 12,
250
- },
251
- bulletDot: {
252
- width: 6,
253
- height: 6,
254
- borderRadius: 3,
255
- marginRight: 12,
256
- },
257
- bulletText: {
258
- fontSize: 14,
259
- },
260
- });