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.
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/screens/HomeScreen.js +672 -662
- package/lib/module/screens/HomeScreen.js.map +1 -1
- package/lib/module/screens/index.js +0 -8
- package/lib/module/screens/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/screens/HomeScreen.d.ts.map +1 -1
- package/lib/typescript/src/screens/index.d.ts +0 -8
- package/lib/typescript/src/screens/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +0 -8
- package/src/screens/HomeScreen.tsx +471 -534
- package/src/screens/index.ts +0 -8
- package/lib/module/screens/PearlChaptersScreen.js +0 -359
- package/lib/module/screens/PearlChaptersScreen.js.map +0 -1
- package/lib/module/screens/PearlReaderScreen.js +0 -313
- package/lib/module/screens/PearlReaderScreen.js.map +0 -1
- package/lib/module/screens/PearlsScreen.js +0 -153
- package/lib/module/screens/PearlsScreen.js.map +0 -1
- package/lib/module/screens/QbankScreen.js +0 -370
- package/lib/module/screens/QbankScreen.js.map +0 -1
- package/lib/module/screens/QuestionScreen.js +0 -437
- package/lib/module/screens/QuestionScreen.js.map +0 -1
- package/lib/module/screens/QuizStartScreen.js +0 -283
- package/lib/module/screens/QuizStartScreen.js.map +0 -1
- package/lib/module/screens/ResultScreen.js +0 -646
- package/lib/module/screens/ResultScreen.js.map +0 -1
- package/lib/module/screens/TopicListScreen.js +0 -420
- package/lib/module/screens/TopicListScreen.js.map +0 -1
- package/lib/module/screens/pearlsMockData.js +0 -77
- package/lib/module/screens/pearlsMockData.js.map +0 -1
- package/lib/typescript/src/screens/PearlChaptersScreen.d.ts +0 -13
- package/lib/typescript/src/screens/PearlChaptersScreen.d.ts.map +0 -1
- package/lib/typescript/src/screens/PearlReaderScreen.d.ts +0 -14
- package/lib/typescript/src/screens/PearlReaderScreen.d.ts.map +0 -1
- package/lib/typescript/src/screens/PearlsScreen.d.ts +0 -11
- package/lib/typescript/src/screens/PearlsScreen.d.ts.map +0 -1
- package/lib/typescript/src/screens/QbankScreen.d.ts +0 -10
- package/lib/typescript/src/screens/QbankScreen.d.ts.map +0 -1
- package/lib/typescript/src/screens/QuestionScreen.d.ts +0 -14
- package/lib/typescript/src/screens/QuestionScreen.d.ts.map +0 -1
- package/lib/typescript/src/screens/QuizStartScreen.d.ts +0 -14
- package/lib/typescript/src/screens/QuizStartScreen.d.ts.map +0 -1
- package/lib/typescript/src/screens/ResultScreen.d.ts +0 -13
- package/lib/typescript/src/screens/ResultScreen.d.ts.map +0 -1
- package/lib/typescript/src/screens/TopicListScreen.d.ts +0 -12
- package/lib/typescript/src/screens/TopicListScreen.d.ts.map +0 -1
- package/lib/typescript/src/screens/pearlsMockData.d.ts +0 -3
- package/lib/typescript/src/screens/pearlsMockData.d.ts.map +0 -1
- package/src/screens/PearlChaptersScreen.tsx +0 -330
- package/src/screens/PearlReaderScreen.tsx +0 -306
- package/src/screens/PearlsScreen.tsx +0 -147
- package/src/screens/QbankScreen.tsx +0 -327
- package/src/screens/QuestionScreen.tsx +0 -423
- package/src/screens/QuizStartScreen.tsx +0 -260
- package/src/screens/ResultScreen.tsx +0 -618
- package/src/screens/TopicListScreen.tsx +0 -388
- package/src/screens/pearlsMockData.ts +0 -70
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
ScrollView,
|
|
5
|
-
StyleSheet,
|
|
6
|
-
TouchableOpacity,
|
|
7
|
-
StatusBar,
|
|
8
|
-
} from 'react-native';
|
|
9
|
-
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
10
|
-
import type { Course, Topic } from '../types';
|
|
11
|
-
import { useElearnConfig } from '../context/ElearnConfigContext';
|
|
12
|
-
import { useTheme } from '../context/ThemeContext';
|
|
13
|
-
import { Typography, Card, Icon } from '../components';
|
|
14
|
-
|
|
15
|
-
interface TopicListScreenProps {
|
|
16
|
-
course?: Course;
|
|
17
|
-
courseId?: string;
|
|
18
|
-
onBack: () => void;
|
|
19
|
-
hideHeader?: boolean;
|
|
20
|
-
onSelectTopic?: (course: Course, topic: Topic) => void;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const TopicListScreen: React.FC<TopicListScreenProps> = ({
|
|
24
|
-
course,
|
|
25
|
-
courseId,
|
|
26
|
-
onBack,
|
|
27
|
-
hideHeader = false,
|
|
28
|
-
onSelectTopic,
|
|
29
|
-
}) => {
|
|
30
|
-
const { config, callbacks } = useElearnConfig();
|
|
31
|
-
const theme = useTheme();
|
|
32
|
-
|
|
33
|
-
const activeCourse = course || config.courses?.find((c) => c.id === courseId);
|
|
34
|
-
|
|
35
|
-
// Active filter tab
|
|
36
|
-
const [activeTab, setActiveTab] = useState('All');
|
|
37
|
-
const tabs = ['All', 'New', 'Completed', 'Paused', 'Not Started'];
|
|
38
|
-
|
|
39
|
-
if (!activeCourse) {
|
|
40
|
-
return (
|
|
41
|
-
<SafeAreaView style={[styles.safeArea, { backgroundColor: theme.background }]}>
|
|
42
|
-
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 }}>
|
|
43
|
-
<Typography variant="h2" bold style={{ marginBottom: 12 }}>Course not found</Typography>
|
|
44
|
-
<TouchableOpacity
|
|
45
|
-
onPress={onBack}
|
|
46
|
-
style={{
|
|
47
|
-
paddingHorizontal: 20,
|
|
48
|
-
paddingVertical: 10,
|
|
49
|
-
borderRadius: 8,
|
|
50
|
-
backgroundColor: theme.primary,
|
|
51
|
-
}}
|
|
52
|
-
>
|
|
53
|
-
<Typography variant="body" bold color="#FFFFFF">Go Back</Typography>
|
|
54
|
-
</TouchableOpacity>
|
|
55
|
-
</View>
|
|
56
|
-
</SafeAreaView>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Group topics by category
|
|
61
|
-
const categoriesMap: { [key: string]: Topic[] } = {};
|
|
62
|
-
activeCourse.topics.forEach((topic) => {
|
|
63
|
-
const cat = topic.category || 'GENERAL';
|
|
64
|
-
if (!categoriesMap[cat]) {
|
|
65
|
-
categoriesMap[cat] = [];
|
|
66
|
-
}
|
|
67
|
-
categoriesMap[cat].push(topic);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
const categories = Object.keys(categoriesMap);
|
|
71
|
-
|
|
72
|
-
// Keep a global sequential counter for the timeline nodes
|
|
73
|
-
let globalIndex = 0;
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
<SafeAreaView style={[styles.safeArea, { backgroundColor: theme.background }]}>
|
|
77
|
-
<StatusBar barStyle="dark-content" />
|
|
78
|
-
|
|
79
|
-
{/* Header */}
|
|
80
|
-
{!hideHeader && (
|
|
81
|
-
<View style={styles.header}>
|
|
82
|
-
<TouchableOpacity onPress={onBack} style={styles.backButton}>
|
|
83
|
-
<Icon name="arrow-left" size={20} color={theme.textPrimary} />
|
|
84
|
-
</TouchableOpacity>
|
|
85
|
-
<Typography variant="h2" bold style={styles.headerTitle}>
|
|
86
|
-
QBank
|
|
87
|
-
</Typography>
|
|
88
|
-
<TouchableOpacity style={styles.searchButton}>
|
|
89
|
-
<Icon name="search" size={20} color={theme.textPrimary} />
|
|
90
|
-
</TouchableOpacity>
|
|
91
|
-
</View>
|
|
92
|
-
)}
|
|
93
|
-
|
|
94
|
-
<ScrollView contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
|
|
95
|
-
|
|
96
|
-
{/* Subject Header Suffix */}
|
|
97
|
-
<View style={styles.subjectHeader}>
|
|
98
|
-
<Typography variant="h1" bold color={theme.textPrimary} style={styles.subjectTitle}>
|
|
99
|
-
{activeCourse.title}
|
|
100
|
-
</Typography>
|
|
101
|
-
<Typography variant="body" color={theme.textSecondary}>
|
|
102
|
-
{activeCourse.topics.length} Modules
|
|
103
|
-
</Typography>
|
|
104
|
-
</View>
|
|
105
|
-
|
|
106
|
-
{/* Horizontal Filters Tabs Bar */}
|
|
107
|
-
<View style={styles.tabsContainer}>
|
|
108
|
-
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.tabsScroll}>
|
|
109
|
-
{tabs.map((tab) => {
|
|
110
|
-
const isActive = activeTab === tab;
|
|
111
|
-
return (
|
|
112
|
-
<TouchableOpacity
|
|
113
|
-
key={tab}
|
|
114
|
-
onPress={() => setActiveTab(tab)}
|
|
115
|
-
style={[
|
|
116
|
-
styles.tabButton,
|
|
117
|
-
isActive
|
|
118
|
-
? { backgroundColor: theme.textPrimary }
|
|
119
|
-
: { borderColor: theme.border, borderWidth: 1 }
|
|
120
|
-
]}
|
|
121
|
-
>
|
|
122
|
-
<Typography
|
|
123
|
-
variant="caption"
|
|
124
|
-
bold
|
|
125
|
-
color={isActive ? '#FFFFFF' : theme.textSecondary}
|
|
126
|
-
>
|
|
127
|
-
{tab}
|
|
128
|
-
</Typography>
|
|
129
|
-
</TouchableOpacity>
|
|
130
|
-
);
|
|
131
|
-
})}
|
|
132
|
-
</ScrollView>
|
|
133
|
-
</View>
|
|
134
|
-
|
|
135
|
-
{/* Timeline of Chapters Categories */}
|
|
136
|
-
<View style={styles.listContainer}>
|
|
137
|
-
{categories.map((category) => {
|
|
138
|
-
const list = categoriesMap[category] || [];
|
|
139
|
-
|
|
140
|
-
return (
|
|
141
|
-
<View key={category} style={styles.categoryBlock}>
|
|
142
|
-
{/* Category Section Title */}
|
|
143
|
-
<Typography variant="caption" bold color={theme.textSecondary} style={styles.categoryTitle}>
|
|
144
|
-
{category.toUpperCase()}
|
|
145
|
-
</Typography>
|
|
146
|
-
|
|
147
|
-
{/* Timeline Items */}
|
|
148
|
-
<View style={styles.categoryItems}>
|
|
149
|
-
{list.map((topic) => {
|
|
150
|
-
globalIndex++;
|
|
151
|
-
const currentIndex = globalIndex;
|
|
152
|
-
const isLastInCourse = currentIndex === activeCourse.topics.length;
|
|
153
|
-
|
|
154
|
-
return (
|
|
155
|
-
<View key={topic.id} style={styles.timelineItemRow}>
|
|
156
|
-
|
|
157
|
-
{/* Left Side Timeline Connectors */}
|
|
158
|
-
<View style={styles.timelineLeftColumn}>
|
|
159
|
-
{/* Top Line connector */}
|
|
160
|
-
{currentIndex > 1 && <View style={[styles.timelineLine, { height: '50%', top: 0 }]} />}
|
|
161
|
-
|
|
162
|
-
{/* Bottom Line connector */}
|
|
163
|
-
{!isLastInCourse && <View style={[styles.timelineLine, { height: '100%', top: 16 }]} />}
|
|
164
|
-
|
|
165
|
-
{/* Sequential Number Circle */}
|
|
166
|
-
<View style={[styles.numberNode, { backgroundColor: '#8C9BAB' }]}>
|
|
167
|
-
<Typography variant="caption" bold color="#FFFFFF" style={styles.nodeText}>
|
|
168
|
-
{currentIndex}
|
|
169
|
-
</Typography>
|
|
170
|
-
</View>
|
|
171
|
-
</View>
|
|
172
|
-
|
|
173
|
-
{/* Right Side Info Card */}
|
|
174
|
-
<TouchableOpacity
|
|
175
|
-
activeOpacity={0.8}
|
|
176
|
-
onPress={() => {
|
|
177
|
-
if (onSelectTopic) {
|
|
178
|
-
onSelectTopic(activeCourse, topic);
|
|
179
|
-
} else {
|
|
180
|
-
callbacks.onSelectTopic?.(activeCourse, topic);
|
|
181
|
-
}
|
|
182
|
-
}}
|
|
183
|
-
style={styles.cardTouchable}
|
|
184
|
-
>
|
|
185
|
-
<Card bordered style={styles.topicCard}>
|
|
186
|
-
<View style={styles.cardMainRow}>
|
|
187
|
-
|
|
188
|
-
{/* Left Text details */}
|
|
189
|
-
<View style={styles.cardInfoCol}>
|
|
190
|
-
<Typography variant="h3" bold color={theme.textPrimary} style={styles.cardTitle}>
|
|
191
|
-
{topic.title}
|
|
192
|
-
</Typography>
|
|
193
|
-
|
|
194
|
-
<View style={styles.ratingRow}>
|
|
195
|
-
<Icon name="star" size={14} color="#EAB308" />
|
|
196
|
-
<Typography variant="caption" bold color={theme.textPrimary} style={styles.ratingVal}>
|
|
197
|
-
{topic.rating || '4.5'}
|
|
198
|
-
</Typography>
|
|
199
|
-
<View style={styles.bulletSeparator} />
|
|
200
|
-
<Typography variant="caption" color={theme.textSecondary}>
|
|
201
|
-
{topic.totalQuestions} Questions
|
|
202
|
-
</Typography>
|
|
203
|
-
</View>
|
|
204
|
-
</View>
|
|
205
|
-
|
|
206
|
-
{/* Right Badge / Lock option */}
|
|
207
|
-
<View style={styles.cardBadgeCol}>
|
|
208
|
-
{topic.isFree ? (
|
|
209
|
-
<View style={[styles.freeBadge, { borderColor: theme.primary }]}>
|
|
210
|
-
<Typography variant="caption" bold color={theme.primary} style={styles.freeBadgeText}>
|
|
211
|
-
FREE
|
|
212
|
-
</Typography>
|
|
213
|
-
</View>
|
|
214
|
-
) : topic.isLocked ? (
|
|
215
|
-
<View style={styles.lockContainer}>
|
|
216
|
-
<Icon name="lock" size={14} color={theme.textSecondary} />
|
|
217
|
-
</View>
|
|
218
|
-
) : null}
|
|
219
|
-
</View>
|
|
220
|
-
|
|
221
|
-
</View>
|
|
222
|
-
</Card>
|
|
223
|
-
</TouchableOpacity>
|
|
224
|
-
|
|
225
|
-
</View>
|
|
226
|
-
);
|
|
227
|
-
})}
|
|
228
|
-
</View>
|
|
229
|
-
</View>
|
|
230
|
-
);
|
|
231
|
-
})}
|
|
232
|
-
</View>
|
|
233
|
-
|
|
234
|
-
</ScrollView>
|
|
235
|
-
</SafeAreaView>
|
|
236
|
-
);
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
const styles = StyleSheet.create({
|
|
240
|
-
safeArea: {
|
|
241
|
-
flex: 1,
|
|
242
|
-
},
|
|
243
|
-
header: {
|
|
244
|
-
flexDirection: 'row',
|
|
245
|
-
justifyContent: 'space-between',
|
|
246
|
-
alignItems: 'center',
|
|
247
|
-
paddingHorizontal: 16,
|
|
248
|
-
paddingVertical: 12,
|
|
249
|
-
},
|
|
250
|
-
backButton: {
|
|
251
|
-
padding: 6,
|
|
252
|
-
},
|
|
253
|
-
headerTitle: {
|
|
254
|
-
fontSize: 18,
|
|
255
|
-
fontWeight: '700',
|
|
256
|
-
},
|
|
257
|
-
searchButton: {
|
|
258
|
-
padding: 6,
|
|
259
|
-
},
|
|
260
|
-
scrollContent: {
|
|
261
|
-
paddingHorizontal: 16,
|
|
262
|
-
paddingBottom: 32,
|
|
263
|
-
},
|
|
264
|
-
subjectHeader: {
|
|
265
|
-
marginTop: 12,
|
|
266
|
-
marginBottom: 16,
|
|
267
|
-
},
|
|
268
|
-
subjectTitle: {
|
|
269
|
-
fontSize: 22,
|
|
270
|
-
marginBottom: 2,
|
|
271
|
-
},
|
|
272
|
-
tabsContainer: {
|
|
273
|
-
marginBottom: 16,
|
|
274
|
-
},
|
|
275
|
-
tabsScroll: {
|
|
276
|
-
paddingVertical: 4,
|
|
277
|
-
},
|
|
278
|
-
tabButton: {
|
|
279
|
-
paddingHorizontal: 16,
|
|
280
|
-
paddingVertical: 6,
|
|
281
|
-
borderRadius: 20,
|
|
282
|
-
marginRight: 10,
|
|
283
|
-
},
|
|
284
|
-
listContainer: {
|
|
285
|
-
marginTop: 8,
|
|
286
|
-
},
|
|
287
|
-
categoryBlock: {
|
|
288
|
-
marginBottom: 24,
|
|
289
|
-
},
|
|
290
|
-
categoryTitle: {
|
|
291
|
-
fontSize: 11,
|
|
292
|
-
letterSpacing: 0.8,
|
|
293
|
-
marginBottom: 16,
|
|
294
|
-
},
|
|
295
|
-
categoryItems: {
|
|
296
|
-
marginTop: 2,
|
|
297
|
-
},
|
|
298
|
-
timelineItemRow: {
|
|
299
|
-
flexDirection: 'row',
|
|
300
|
-
alignItems: 'stretch',
|
|
301
|
-
marginBottom: 12,
|
|
302
|
-
minHeight: 80,
|
|
303
|
-
},
|
|
304
|
-
timelineLeftColumn: {
|
|
305
|
-
width: 36,
|
|
306
|
-
alignItems: 'center',
|
|
307
|
-
justifyContent: 'flex-start',
|
|
308
|
-
paddingTop: 12,
|
|
309
|
-
position: 'relative',
|
|
310
|
-
},
|
|
311
|
-
timelineLine: {
|
|
312
|
-
position: 'absolute',
|
|
313
|
-
left: 17, // center of the 36 width
|
|
314
|
-
width: 2,
|
|
315
|
-
backgroundColor: '#E2E8F0',
|
|
316
|
-
zIndex: -1,
|
|
317
|
-
},
|
|
318
|
-
numberNode: {
|
|
319
|
-
width: 24,
|
|
320
|
-
height: 24,
|
|
321
|
-
borderRadius: 12,
|
|
322
|
-
justifyContent: 'center',
|
|
323
|
-
alignItems: 'center',
|
|
324
|
-
zIndex: 1,
|
|
325
|
-
},
|
|
326
|
-
nodeText: {
|
|
327
|
-
fontSize: 11,
|
|
328
|
-
},
|
|
329
|
-
cardTouchable: {
|
|
330
|
-
flex: 1,
|
|
331
|
-
},
|
|
332
|
-
topicCard: {
|
|
333
|
-
padding: 12,
|
|
334
|
-
borderRadius: 12,
|
|
335
|
-
flex: 1,
|
|
336
|
-
},
|
|
337
|
-
cardMainRow: {
|
|
338
|
-
flexDirection: 'row',
|
|
339
|
-
justifyContent: 'space-between',
|
|
340
|
-
alignItems: 'center',
|
|
341
|
-
flex: 1,
|
|
342
|
-
},
|
|
343
|
-
cardInfoCol: {
|
|
344
|
-
flex: 1,
|
|
345
|
-
paddingRight: 8,
|
|
346
|
-
},
|
|
347
|
-
cardTitle: {
|
|
348
|
-
fontSize: 14,
|
|
349
|
-
lineHeight: 18,
|
|
350
|
-
marginBottom: 6,
|
|
351
|
-
},
|
|
352
|
-
ratingRow: {
|
|
353
|
-
flexDirection: 'row',
|
|
354
|
-
alignItems: 'center',
|
|
355
|
-
},
|
|
356
|
-
ratingVal: {
|
|
357
|
-
fontSize: 11,
|
|
358
|
-
marginLeft: 4,
|
|
359
|
-
},
|
|
360
|
-
bulletSeparator: {
|
|
361
|
-
width: 3,
|
|
362
|
-
height: 3,
|
|
363
|
-
borderRadius: 1.5,
|
|
364
|
-
backgroundColor: '#94A3B8',
|
|
365
|
-
marginHorizontal: 6,
|
|
366
|
-
},
|
|
367
|
-
cardBadgeCol: {
|
|
368
|
-
justifyContent: 'center',
|
|
369
|
-
alignItems: 'flex-end',
|
|
370
|
-
},
|
|
371
|
-
freeBadge: {
|
|
372
|
-
borderWidth: 1.5,
|
|
373
|
-
borderRadius: 6,
|
|
374
|
-
paddingHorizontal: 8,
|
|
375
|
-
paddingVertical: 3,
|
|
376
|
-
},
|
|
377
|
-
freeBadgeText: {
|
|
378
|
-
fontSize: 9,
|
|
379
|
-
},
|
|
380
|
-
lockContainer: {
|
|
381
|
-
width: 24,
|
|
382
|
-
height: 24,
|
|
383
|
-
borderRadius: 12,
|
|
384
|
-
backgroundColor: '#F1F5F9',
|
|
385
|
-
justifyContent: 'center',
|
|
386
|
-
alignItems: 'center',
|
|
387
|
-
},
|
|
388
|
-
});
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import type { PearlTopic } from '../types';
|
|
2
|
-
|
|
3
|
-
export const MOCK_PEARLS_TOPICS: PearlTopic[] = [
|
|
4
|
-
{
|
|
5
|
-
id: 'topic_head_neck',
|
|
6
|
-
title: 'Head and neck',
|
|
7
|
-
sections: {
|
|
8
|
-
'Head and Neck': [
|
|
9
|
-
{
|
|
10
|
-
id: 'hn_c1',
|
|
11
|
-
number: 1,
|
|
12
|
-
title: 'Classify sino-nasal neoplasam. Discuss the newer entities',
|
|
13
|
-
isFree: true,
|
|
14
|
-
bullets: [
|
|
15
|
-
'Benign Neoplasms: Benign sino-nasal tumors are generally slow-growing and less likely to invade surrounding structures. Common benign types include inverted papilloma, oncocytic Schneiderian papilloma, and fungiform papilloma, all of which originate from the Schneiderian mucosa. Inverted papilloma is notable for its local aggressiveness and high recurrence rate, sometimes exhibiting malignant transformation into squamous cell carcinoma.',
|
|
16
|
-
'Malignant Neoplasms: Malignant tumors of the sino-nasal tract are rare but clinically significant due to their aggressive behavior, late presentation, and complex anatomical constraints that limit surgical access. The most common malignant tumor is squamous cell carcinoma, often arising from dysplastic or papillomatous lesions.',
|
|
17
|
-
'Esthesioneuroblastoma: A notable entity originating from the olfactory epithelium and displaying variable degrees of malignancy. Additionally, melanoma, lymphoma, and undifferentiated carcinoma can also occur in the sino-nasal region, often presenting with nasal obstruction, epistaxis, and facial pain.'
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
id: 'hn_c2',
|
|
22
|
-
number: 2,
|
|
23
|
-
title: 'Histologic variants of ameloblastoma',
|
|
24
|
-
isLocked: true,
|
|
25
|
-
bullets: [
|
|
26
|
-
'Ameloblastoma is a benign but locally aggressive odontogenic neoplasm.',
|
|
27
|
-
'Follicular and plexiform are the most common histologic patterns.',
|
|
28
|
-
'Unicystic variants have a better prognosis and lower recurrence rates.'
|
|
29
|
-
]
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
id: 'hn_c3',
|
|
33
|
-
number: 3,
|
|
34
|
-
title: 'Role of brush ctology in diagnosis of oral cancerous and precancerous lessions',
|
|
35
|
-
isLocked: true,
|
|
36
|
-
bullets: [
|
|
37
|
-
'Oral brush cytology is a non-invasive screening aid.',
|
|
38
|
-
'High sensitivity for identifying cellular dysplasias.',
|
|
39
|
-
'Must be followed by scalpel biopsy for definitive diagnosis.'
|
|
40
|
-
]
|
|
41
|
-
}
|
|
42
|
-
],
|
|
43
|
-
'Eye': [
|
|
44
|
-
{
|
|
45
|
-
id: 'eye_c1',
|
|
46
|
-
number: 1,
|
|
47
|
-
title: 'Classify sino-nasal neoplasam. Discuss the newer entities',
|
|
48
|
-
isLocked: true,
|
|
49
|
-
bullets: []
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
id: 'eye_c2',
|
|
53
|
-
number: 2,
|
|
54
|
-
title: 'Histologic variants of ameloblastoma',
|
|
55
|
-
isLocked: true,
|
|
56
|
-
bullets: []
|
|
57
|
-
}
|
|
58
|
-
]
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
{ id: 'topic_brain_spine', title: 'Brain, Spine and Meninges', sections: {} },
|
|
62
|
-
{ id: 'topic_breast', title: 'Breast Pathology', sections: {} },
|
|
63
|
-
{ id: 'topic_skin', title: 'Skin and Connective Tissue', sections: {} },
|
|
64
|
-
{ id: 'topic_kidney', title: 'Kidney & Urinary Tract', sections: {} },
|
|
65
|
-
{ id: 'topic_gastro', title: 'Gastro-Intestinal System', sections: {} },
|
|
66
|
-
{ id: 'topic_endocrine', title: 'Endocrine Pathology', sections: {} },
|
|
67
|
-
{ id: 'topic_general', title: 'General Pathology', sections: {} },
|
|
68
|
-
{ id: 'topic_male_genital', title: 'Male Genital System', sections: {} },
|
|
69
|
-
{ id: 'topic_thoracic', title: 'Thoracic Pathology', sections: {} }
|
|
70
|
-
];
|