@ubkinfotech/student-erp
v0.2.21
Published
UBK ERP enterprise-grade modular Student ERP foundation for React Native
Downloads
208
Maintainers
Readme
@ubkinfotech/student-erp
Enterprise-grade, modular Student ERP foundation for React Native. Designed for production apps that want reusable ERP screens and API logic without coupling to the host app’s navigation or Redux setup.
- Framework: React Native (Metro)
- HTTP: Axios (shared client via provider)
- Data fetching: React Query
- Authentication: external token injection (no Bearer by default)
- Modules: Transport, TimeTable, Notes, Syllabus, Homework, Attendance, NoticeBoard, Subject, Teacher
Install
npm i @ubkinfotech/student-erpRequirements
- Your app must already include React Query:
npm i @tanstack/react-query- For some modules, the host app must install these libraries (they are not bundled):
- Homework upload: react-native-document-picker, react-native-image-picker
- Attendance calendar: react-native-calendars
Provider
All modules use a shared Axios client created by ERPProvider.
Basic
import React from 'react';
import {ERPProvider} from '@ubkinfotech/student-erp';
export function AppRoot() {
return (
<ERPProvider baseUrl={API_BASE_URL} authToken={authToken} fileBaseUrl={FILE_BASE_URL}>
<App />
</ERPProvider>
);
}Branch-aware file provider
For Homework, Notes, and Syllabus attachments uploaded through the public image server, pass a branch-aware file base URL and schoolCode.
import React from 'react';
import {ERPProvider} from '@ubkinfotech/student-erp';
export function AppRoot({authToken, branchId}: any) {
const staticSchoolDownloadBase = `${IMAGE_BASE_URL}/uploads/school_${branchId}/`;
return (
<ERPProvider
baseUrl={API_BASE_URL}
authToken={authToken}
fileBaseUrl={staticSchoolDownloadBase}
schoolCode={branchId}>
<App />
</ERPProvider>
);
}Async token callback
import React from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {ERPProvider} from '@ubkinfotech/student-erp';
export function AppRoot() {
return (
<ERPProvider baseUrl={API_BASE_URL} getAuthToken={() => AsyncStorage.getItem('token')}>
<App />
</ERPProvider>
);
}Module Imports
import {
ERPProvider,
AttendanceByDayScreen,
AttendanceMonthlyScreen,
HomeworkScreen,
LibraryIssuedBooksScreen,
NoticeBoardScreen,
NotesScreen,
StudentRouteDetailsScreen,
SubjectScreen,
SyllabusScreen,
TeacherScreen,
TimeTableScreen,
} from '@ubkinfotech/student-erp';Tested Integration (Reference)
The modules are verified inside the host app using a “switcher” screen:
Branch ID
The host app should pass the school branch id to the module for branch-aware file URLs.
- Recommended source: login response
fk_createdby - Common fallback chain used in the host app:
user?.fk_createdby || user?.branch_id || user?.branchID || user?.branchId
Host URL Helper
The host app can use one shared helper, like SampleNpm.jsx, to build module file URLs from a single branch-aware base:
const branchId = 82;
const staticSchoolDownloadBase = `${IMAGE_BASE_URL}/uploads/school_${branchId}/`;
const buildStaticAttachmentUrl = (fileName: string, modulePath: string) => {
const normalized = String(fileName || '').replace(/\\/g, '/').replace(/^\/+/, '');
if (!normalized) {
return '';
}
if (/^https?:\/\//i.test(normalized)) {
return normalized;
}
if (normalized.startsWith('school_')) {
return `${IMAGE_BASE_URL}/uploads/${normalized}`;
}
if (normalized.startsWith('uploads/')) {
return `${staticSchoolDownloadBase}${normalized.replace(/^uploads\//, '')}`;
}
if (normalized.startsWith(`${modulePath}/`)) {
return `${staticSchoolDownloadBase}${normalized}`;
}
return `${staticSchoolDownloadBase}${modulePath}/${normalized}`;
};Examples
Transport
import React from 'react';
import {ERPProvider, StudentRouteDetailsScreen} from '@ubkinfotech/student-erp';
export function TransportExample() {
return (
<ERPProvider baseUrl={API_BASE_URL} authToken={authToken} fileBaseUrl={FILE_BASE_URL}>
<StudentRouteDetailsScreen />
</ERPProvider>
);
}TimeTable
import React from 'react';
import {ERPProvider, TimeTableScreen} from '@ubkinfotech/student-erp';
export function TimeTableExample({classId, sectionId, sessionId}: any) {
return (
<ERPProvider baseUrl={API_BASE_URL} authToken={authToken}>
<TimeTableScreen classId={classId} sectionId={sectionId} sessionId={sessionId} />
</ERPProvider>
);
}Notes (View + Download)
Notes supports inline image/PDF viewing inside the module, but the host app can still provide callbacks for opening files and downloading files. For public uploaded files, pass branchId, schoolCode, and staticSchoolDownloadBase.
import React from 'react';
import {Alert, Platform, ToastAndroid} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import ImageView from 'react-native-image-viewing';
import RNFetchBlob from 'react-native-blob-util';
import {ERPProvider, NotesScreen} from '@ubkinfotech/student-erp';
export function NotesExample() {
const navigation = useNavigation();
const branchId = user?.fk_createdby || user?.branch_id || user?.branchID || user?.branchId || 82;
const staticSchoolDownloadBase = `${IMAGE_BASE_URL}/uploads/school_${branchId}/`;
const openFile = ({url, extension, name}: any) => {
if (extension === 'pdf') {
navigation.navigate('FeesReport', {filepath: url, name: name || 'File'});
return;
}
if (['jpg', 'jpeg', 'png', 'webp'].includes(String(extension).toLowerCase())) {
Alert.alert('Image', 'Open image preview in your screen using ImageView');
return;
}
Alert.alert('Unsupported File', 'This file type is not supported for direct viewing.');
};
const downloadFile = async ({url, filename}: any) => {
if (Platform.OS === 'android') {
ToastAndroid.showWithGravityAndOffset('Downloading Started !', ToastAndroid.LONG, ToastAndroid.BOTTOM, 25, 50);
}
const docPath = RNFetchBlob.fs.dirs.DocumentDir;
await RNFetchBlob.config({
path: `${docPath}/${filename}`,
fileCache: true,
addAndroidDownloads: {
useDownloadManager: true,
notification: true,
title: filename,
description: filename,
storeInDownloads: true,
},
}).fetch('GET', url);
};
return (
<ERPProvider
baseUrl={API_BASE_URL}
authToken={authToken}
fileBaseUrl={staticSchoolDownloadBase}
schoolCode={branchId}>
<NotesScreen
branchId={branchId}
onOpenFile={({url, extension, item}) => openFile({url, extension, name: item?.title})}
onDownloadFile={({url, filename}) => downloadFile({url, filename})}
/>
</ERPProvider>
);
}Syllabus
import React from 'react';
import {Alert} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import {ERPProvider, SyllabusScreen} from '@ubkinfotech/student-erp';
export function SyllabusExample({classId}: any) {
const navigation = useNavigation();
const branchId = user?.fk_createdby || user?.branch_id || user?.branchID || user?.branchId || 82;
const staticSchoolDownloadBase = `${IMAGE_BASE_URL}/uploads/school_${branchId}/`;
return (
<ERPProvider
baseUrl={API_BASE_URL}
authToken={authToken}
fileBaseUrl={staticSchoolDownloadBase}
schoolCode={branchId}>
<SyllabusScreen
classId={classId}
branchId={branchId}
onOpenFile={({url, extension, item}) => {
if (extension === 'pdf') {
navigation.navigate('FeesReport', {filepath: url, name: item?.subject_title || 'Syllabus'});
return;
}
if (['jpg', 'jpeg', 'png', 'webp'].includes(String(extension).toLowerCase())) {
Alert.alert('Image', 'Open image preview in your screen using ImageView');
}
}}
/>
</ERPProvider>
);
}Homework (List + Upload)
Homework supports upload internally. For branch-aware attachment URLs, pass branchId, schoolCode, and staticSchoolDownloadBase.
import React from 'react';
import {Alert, Platform, ToastAndroid} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import RNFetchBlob from 'react-native-blob-util';
import {ERPProvider, HomeworkScreen} from '@ubkinfotech/student-erp';
export function HomeworkExample() {
const navigation = useNavigation();
const branchId = user?.fk_createdby || user?.branch_id || user?.branchID || user?.branchId || 82;
const staticSchoolDownloadBase = `${IMAGE_BASE_URL}/uploads/school_${branchId}/`;
const downloadFile = async ({url, filename}: any) => {
if (Platform.OS === 'android') {
ToastAndroid.showWithGravityAndOffset('Downloading Started !', ToastAndroid.LONG, ToastAndroid.BOTTOM, 25, 50);
} else {
Alert.alert('Download', 'Downloading started');
}
const docPath = RNFetchBlob.fs.dirs.DocumentDir;
await RNFetchBlob.config({
path: `${docPath}/${filename}`,
fileCache: true,
addAndroidDownloads: {
useDownloadManager: true,
notification: true,
title: filename,
description: filename,
storeInDownloads: true,
},
}).fetch('GET', url);
};
return (
<ERPProvider
baseUrl={API_BASE_URL}
authToken={authToken}
fileBaseUrl={staticSchoolDownloadBase}
schoolCode={branchId}>
<HomeworkScreen
branchId={branchId}
onOpenFile={({url, extension, item}) => {
if (extension === 'pdf') {
navigation.navigate('FeesReport', {filepath: url, name: item?.title || item?.name || 'Homework'});
return;
}
if (['jpg', 'jpeg', 'png', 'webp'].includes(String(extension).toLowerCase())) {
Alert.alert('Image', 'Open image preview in your screen using ImageView');
}
}}
onDownloadFile={({url, filename}) => downloadFile({url, filename})}
/>
</ERPProvider>
);
}Attendance (Calendar + Monthly)
import React from 'react';
import {ERPProvider, AttendanceByDayScreen, AttendanceMonthlyScreen} from '@ubkinfotech/student-erp';
export function AttendanceExample({studentId, sessionId}: any) {
return (
<ERPProvider baseUrl={API_BASE_URL} authToken={authToken}>
<AttendanceByDayScreen studentId={studentId} sessionId={sessionId} />
<AttendanceMonthlyScreen studentId={studentId} sessionId={sessionId} />
</ERPProvider>
);
}NoticeBoard (List + Details)
By default, details opens inside a modal. If you prefer navigation, use onOpenNotice.
import React from 'react';
import {ERPProvider, NoticeBoardScreen} from '@ubkinfotech/student-erp';
export function NoticeExample() {
return (
<ERPProvider baseUrl={API_BASE_URL} authToken={authToken}>
<NoticeBoardScreen />
</ERPProvider>
);
}Subject
import React from 'react';
import {ERPProvider, SubjectScreen} from '@ubkinfotech/student-erp';
export function SubjectExample() {
return (
<ERPProvider baseUrl={API_BASE_URL} authToken={authToken}>
<SubjectScreen />
</ERPProvider>
);
}Teacher
Teacher requires sessionId and uses fileBaseUrl for teacher images.
import React from 'react';
import {ERPProvider, TeacherScreen} from '@ubkinfotech/student-erp';
export function TeacherExample({sessionId}: any) {
return (
<ERPProvider baseUrl={API_BASE_URL} authToken={authToken} fileBaseUrl={FILE_BASE_URL}>
<TeacherScreen sessionId={sessionId} />
</ERPProvider>
);
}Notes on Authentication
The default header is:
Authorization: <token>
If your backend uses a different header shape, configure the provider using custom headers via headers in ERPProvider.
