react-native-elearn-ui 0.1.42 → 0.1.43

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/index.js +1 -1
  2. package/lib/module/index.js.map +1 -1
  3. package/lib/module/screens/index.js +1 -0
  4. package/lib/module/screens/index.js.map +1 -1
  5. package/lib/module/screens/notes/NotesDetailScreen.js +297 -0
  6. package/lib/module/screens/notes/NotesDetailScreen.js.map +1 -0
  7. package/lib/module/screens/notes/NotesSubTopicScreen.js +192 -0
  8. package/lib/module/screens/notes/NotesSubTopicScreen.js.map +1 -0
  9. package/lib/module/screens/notes/NotesTopicScreen.js +198 -0
  10. package/lib/module/screens/notes/NotesTopicScreen.js.map +1 -0
  11. package/lib/module/screens/notes/index.js +6 -0
  12. package/lib/module/screens/notes/index.js.map +1 -0
  13. package/lib/typescript/src/index.d.ts +1 -1
  14. package/lib/typescript/src/index.d.ts.map +1 -1
  15. package/lib/typescript/src/screens/index.d.ts +1 -0
  16. package/lib/typescript/src/screens/index.d.ts.map +1 -1
  17. package/lib/typescript/src/screens/notes/NotesDetailScreen.d.ts +4 -0
  18. package/lib/typescript/src/screens/notes/NotesDetailScreen.d.ts.map +1 -0
  19. package/lib/typescript/src/screens/notes/NotesSubTopicScreen.d.ts +4 -0
  20. package/lib/typescript/src/screens/notes/NotesSubTopicScreen.d.ts.map +1 -0
  21. package/lib/typescript/src/screens/notes/NotesTopicScreen.d.ts +4 -0
  22. package/lib/typescript/src/screens/notes/NotesTopicScreen.d.ts.map +1 -0
  23. package/lib/typescript/src/screens/notes/index.d.ts +4 -0
  24. package/lib/typescript/src/screens/notes/index.d.ts.map +1 -0
  25. package/lib/typescript/src/types/index.d.ts +49 -0
  26. package/lib/typescript/src/types/index.d.ts.map +1 -1
  27. package/package.json +1 -1
  28. package/src/index.tsx +3 -0
  29. package/src/screens/index.ts +1 -0
  30. package/src/screens/notes/NotesDetailScreen.tsx +260 -0
  31. package/src/screens/notes/NotesSubTopicScreen.tsx +168 -0
  32. package/src/screens/notes/NotesTopicScreen.tsx +174 -0
  33. package/src/screens/notes/index.ts +3 -0
  34. package/src/types/index.ts +61 -0
@@ -0,0 +1,168 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ ScrollView,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ } from 'react-native';
8
+ import { SafeAreaView } from 'react-native-safe-area-context';
9
+ import { useTheme } from '../../context/ThemeContext';
10
+ import { Typography, Icon } from '../../components';
11
+ import type { NotesSubTopicScreenProps, NotesSubTopicSection } from '../../types';
12
+
13
+ export const NotesSubTopicScreen: React.FC<NotesSubTopicScreenProps> = ({
14
+ topicTitle,
15
+ sections,
16
+ onBack,
17
+ onPressFilter,
18
+ onPressSubTopic,
19
+ }) => {
20
+ const theme = useTheme();
21
+
22
+ return (
23
+ <SafeAreaView style={[styles.safeArea, { backgroundColor: '#F9FAFB' }]} edges={['top', 'bottom']}>
24
+ {/* Header */}
25
+ <View style={styles.header}>
26
+ <TouchableOpacity style={styles.headerBtnLeft} onPress={onBack}>
27
+ <Icon name="chevron-left" size={24} color={theme.textPrimary} />
28
+ </TouchableOpacity>
29
+ <Typography variant="h2" bold color={theme.textPrimary} style={styles.headerTitle}>
30
+ {topicTitle}
31
+ </Typography>
32
+ <TouchableOpacity style={styles.headerBtnRight} onPress={onPressFilter}>
33
+ <Icon name="filter" size={20} color={theme.textPrimary} />
34
+ </TouchableOpacity>
35
+ </View>
36
+
37
+ <ScrollView style={{ flex: 1 }} contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
38
+ {sections && sections.map((section: NotesSubTopicSection) => (
39
+ <View key={section.id} style={styles.sectionContainer}>
40
+ <View style={styles.sectionHeader}>
41
+ <View style={[styles.dot, { backgroundColor: theme.success }]} />
42
+ <Typography variant="caption" color={theme.textSecondary} style={styles.sectionTitle}>
43
+ {section.title}
44
+ </Typography>
45
+ </View>
46
+
47
+ {section.subTopics.map((subTopic) => (
48
+ <TouchableOpacity
49
+ key={subTopic.id}
50
+ style={styles.subTopicCard}
51
+ activeOpacity={0.8}
52
+ onPress={() => onPressSubTopic?.(subTopic.id)}
53
+ >
54
+ <View style={styles.subTopicLeft}>
55
+ <Typography variant="body" color={theme.textPrimary} style={styles.subTopicTitle}>
56
+ {subTopic.title}
57
+ </Typography>
58
+ </View>
59
+ <View style={styles.subTopicRight}>
60
+ {subTopic.isLocked && (
61
+ <View style={styles.lockIconContainer}>
62
+ <Icon name="lock" size={14} color="#94A3B8" />
63
+ </View>
64
+ )}
65
+ </View>
66
+ </TouchableOpacity>
67
+ ))}
68
+ </View>
69
+ ))}
70
+ </ScrollView>
71
+ </SafeAreaView>
72
+ );
73
+ };
74
+
75
+ const styles = StyleSheet.create({
76
+ safeArea: {
77
+ flex: 1,
78
+ },
79
+ header: {
80
+ flexDirection: 'row',
81
+ alignItems: 'center',
82
+ justifyContent: 'space-between',
83
+ paddingHorizontal: 16,
84
+ paddingVertical: 12,
85
+ backgroundColor: '#FFFFFF',
86
+ borderBottomWidth: 1,
87
+ borderBottomColor: '#F1F5F9',
88
+ },
89
+ headerBtnLeft: {
90
+ width: 40,
91
+ height: 40,
92
+ justifyContent: 'center',
93
+ alignItems: 'flex-start',
94
+ },
95
+ headerBtnRight: {
96
+ width: 40,
97
+ height: 40,
98
+ justifyContent: 'center',
99
+ alignItems: 'flex-end',
100
+ },
101
+ headerTitle: {
102
+ flex: 1,
103
+ textAlign: 'center',
104
+ fontSize: 18,
105
+ },
106
+ scrollContent: {
107
+ padding: 16,
108
+ paddingBottom: 40,
109
+ },
110
+ sectionContainer: {
111
+ marginBottom: 24,
112
+ },
113
+ sectionHeader: {
114
+ flexDirection: 'row',
115
+ alignItems: 'center',
116
+ marginBottom: 12,
117
+ },
118
+ dot: {
119
+ width: 6,
120
+ height: 6,
121
+ borderRadius: 3,
122
+ marginRight: 8,
123
+ },
124
+ sectionTitle: {
125
+ fontSize: 12,
126
+ letterSpacing: 0.5,
127
+ fontWeight: '600',
128
+ textTransform: 'uppercase',
129
+ },
130
+ subTopicCard: {
131
+ backgroundColor: '#FFFFFF',
132
+ flexDirection: 'row',
133
+ alignItems: 'center',
134
+ justifyContent: 'space-between',
135
+ paddingVertical: 16,
136
+ paddingHorizontal: 16,
137
+ borderRadius: 12,
138
+ marginBottom: 12,
139
+ shadowColor: '#000',
140
+ shadowOffset: { width: 0, height: 2 },
141
+ shadowOpacity: 0.05,
142
+ shadowRadius: 4,
143
+ elevation: 2,
144
+ borderWidth: 1,
145
+ borderColor: '#F1F5F9',
146
+ },
147
+ subTopicLeft: {
148
+ flex: 1,
149
+ paddingRight: 12,
150
+ },
151
+ subTopicTitle: {
152
+ fontSize: 14,
153
+ fontWeight: '500',
154
+ lineHeight: 20,
155
+ },
156
+ subTopicRight: {
157
+ justifyContent: 'center',
158
+ alignItems: 'center',
159
+ },
160
+ lockIconContainer: {
161
+ width: 28,
162
+ height: 28,
163
+ borderRadius: 14,
164
+ backgroundColor: '#F1F5F9',
165
+ justifyContent: 'center',
166
+ alignItems: 'center',
167
+ },
168
+ });
@@ -0,0 +1,174 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ ScrollView,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ } from 'react-native';
8
+ import { SafeAreaView } from 'react-native-safe-area-context';
9
+ import { useTheme } from '../../context/ThemeContext';
10
+ import { Typography, Icon } from '../../components';
11
+ import type { NotesTopicScreenProps, NotesTopic } from '../../types';
12
+
13
+ export const NotesTopicScreen: React.FC<NotesTopicScreenProps> = ({
14
+ title = 'BNS/MD',
15
+ recentlyAdded,
16
+ allTopics,
17
+ onBack,
18
+ onPressSearch,
19
+ onPressTopic,
20
+ }) => {
21
+ const theme = useTheme();
22
+
23
+ const renderTopicCard = (item: NotesTopic, isRecentlyAdded: boolean) => (
24
+ <TouchableOpacity
25
+ key={item.id}
26
+ style={styles.topicCard}
27
+ activeOpacity={0.8}
28
+ onPress={() => onPressTopic?.(item.id)}
29
+ >
30
+ <View style={styles.topicCardLeft}>
31
+ <View style={styles.iconContainer}>
32
+ <Icon name="file-text" size={20} color={theme.primary} />
33
+ </View>
34
+ <Typography variant="h3" color={theme.textPrimary} style={styles.topicTitle}>
35
+ {item.title}
36
+ </Typography>
37
+ </View>
38
+ <View style={styles.topicCardRight}>
39
+ {isRecentlyAdded && item.isCompleted ? (
40
+ <Icon name="check" size={20} color={theme.success} />
41
+ ) : (
42
+ <Icon name="chevron-right" size={20} color={theme.textSecondary} />
43
+ )}
44
+ </View>
45
+ </TouchableOpacity>
46
+ );
47
+
48
+ return (
49
+ <SafeAreaView style={[styles.safeArea, { backgroundColor: '#F9FAFB' }]} edges={['top', 'bottom']}>
50
+ {/* Header */}
51
+ <View style={styles.header}>
52
+ <TouchableOpacity style={styles.headerBtnLeft} onPress={onBack}>
53
+ <Icon name="chevron-left" size={24} color={theme.textPrimary} />
54
+ </TouchableOpacity>
55
+ <Typography variant="h2" bold color={theme.textPrimary} style={styles.headerTitle}>
56
+ {title}
57
+ </Typography>
58
+ <TouchableOpacity style={styles.headerBtnRight} onPress={onPressSearch}>
59
+ <Icon name="search" size={22} color={theme.textPrimary} />
60
+ </TouchableOpacity>
61
+ </View>
62
+
63
+ <ScrollView style={{ flex: 1 }} contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
64
+ {/* Recently Added Section */}
65
+ {recentlyAdded && recentlyAdded.length > 0 && (
66
+ <View style={styles.section}>
67
+ <Typography variant="caption" color={theme.textSecondary} style={styles.sectionHeader}>
68
+ RECENTLY ADDED
69
+ </Typography>
70
+ {recentlyAdded.map((topic) => renderTopicCard(topic, true))}
71
+ </View>
72
+ )}
73
+
74
+ {/* All Topics Section */}
75
+ {allTopics && allTopics.length > 0 && (
76
+ <View style={[styles.section, { marginTop: 24 }]}>
77
+ <Typography variant="caption" color={theme.textSecondary} style={styles.sectionHeader}>
78
+ ALL TOPICS
79
+ </Typography>
80
+ {allTopics.map((topic) => renderTopicCard(topic, false))}
81
+ </View>
82
+ )}
83
+ </ScrollView>
84
+ </SafeAreaView>
85
+ );
86
+ };
87
+
88
+ const styles = StyleSheet.create({
89
+ safeArea: {
90
+ flex: 1,
91
+ },
92
+ header: {
93
+ flexDirection: 'row',
94
+ alignItems: 'center',
95
+ justifyContent: 'space-between',
96
+ paddingHorizontal: 16,
97
+ paddingVertical: 12,
98
+ backgroundColor: '#FFFFFF',
99
+ borderBottomWidth: 1,
100
+ borderBottomColor: '#F1F5F9',
101
+ },
102
+ headerBtnLeft: {
103
+ width: 40,
104
+ height: 40,
105
+ justifyContent: 'center',
106
+ alignItems: 'flex-start',
107
+ },
108
+ headerBtnRight: {
109
+ width: 40,
110
+ height: 40,
111
+ justifyContent: 'center',
112
+ alignItems: 'flex-end',
113
+ },
114
+ headerTitle: {
115
+ flex: 1,
116
+ textAlign: 'center',
117
+ fontSize: 18,
118
+ },
119
+ scrollContent: {
120
+ padding: 16,
121
+ paddingBottom: 40,
122
+ },
123
+ section: {
124
+ width: '100%',
125
+ },
126
+ sectionHeader: {
127
+ fontSize: 12,
128
+ letterSpacing: 0.5,
129
+ marginBottom: 12,
130
+ fontWeight: '600',
131
+ textTransform: 'uppercase',
132
+ },
133
+ topicCard: {
134
+ backgroundColor: '#FFFFFF',
135
+ flexDirection: 'row',
136
+ alignItems: 'center',
137
+ justifyContent: 'space-between',
138
+ paddingVertical: 16,
139
+ paddingHorizontal: 16,
140
+ borderRadius: 12,
141
+ marginBottom: 12,
142
+ shadowColor: '#000',
143
+ shadowOffset: { width: 0, height: 2 },
144
+ shadowOpacity: 0.05,
145
+ shadowRadius: 4,
146
+ elevation: 2,
147
+ borderWidth: 1,
148
+ borderColor: '#F1F5F9',
149
+ },
150
+ topicCardLeft: {
151
+ flexDirection: 'row',
152
+ alignItems: 'center',
153
+ flex: 1,
154
+ },
155
+ iconContainer: {
156
+ width: 40,
157
+ height: 40,
158
+ borderRadius: 8,
159
+ backgroundColor: '#F8FAFC',
160
+ justifyContent: 'center',
161
+ alignItems: 'center',
162
+ marginRight: 16,
163
+ borderWidth: 1,
164
+ borderColor: '#E2E8F0',
165
+ },
166
+ topicTitle: {
167
+ fontSize: 16,
168
+ fontWeight: '600',
169
+ },
170
+ topicCardRight: {
171
+ justifyContent: 'center',
172
+ alignItems: 'center',
173
+ },
174
+ });
@@ -0,0 +1,3 @@
1
+ export * from './NotesTopicScreen';
2
+ export * from './NotesSubTopicScreen';
3
+ export * from './NotesDetailScreen';
@@ -304,3 +304,64 @@ export interface QBankSubTopicParams {
304
304
  };
305
305
  sections: QBankSubTopicSection[];
306
306
  }
307
+
308
+ // --------------------------------------------------
309
+ // Notes Module Types
310
+ // --------------------------------------------------
311
+
312
+ export interface NotesTopic {
313
+ id: string;
314
+ title: string;
315
+ icon?: string;
316
+ isCompleted?: boolean;
317
+ }
318
+
319
+ export interface NotesTopicScreenProps {
320
+ title?: string;
321
+ recentlyAdded: NotesTopic[];
322
+ allTopics: NotesTopic[];
323
+ onBack?: () => void;
324
+ onPressSearch?: () => void;
325
+ onPressTopic?: (topicId: string) => void;
326
+ }
327
+
328
+ export interface NotesSubTopic {
329
+ id: string;
330
+ title: string;
331
+ isLocked?: boolean;
332
+ }
333
+
334
+ export interface NotesSubTopicSection {
335
+ id: string;
336
+ title: string;
337
+ subTopics: NotesSubTopic[];
338
+ }
339
+
340
+ export interface NotesSubTopicScreenProps {
341
+ topicTitle: string;
342
+ sections: NotesSubTopicSection[];
343
+ onBack?: () => void;
344
+ onPressFilter?: () => void;
345
+ onPressSubTopic?: (subTopicId: string) => void;
346
+ }
347
+
348
+ export interface NotesDetailContent {
349
+ title: string;
350
+ description: string;
351
+ }
352
+
353
+ export interface NotesDetailScreenProps {
354
+ topicTitle: string;
355
+ sectionTitle: string;
356
+ currentProgress: number;
357
+ totalProgress: number;
358
+ subTopicTitle: string;
359
+ content: NotesDetailContent[];
360
+ isCompleted?: boolean;
361
+ onBack?: () => void;
362
+ onPressGroup?: () => void;
363
+ onToggleComplete?: (isComplete: boolean) => void;
364
+ onPressPrev?: () => void;
365
+ onPressNext?: () => void;
366
+ }
367
+