icleafreportui 0.1.0 → 0.1.2

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 (92) hide show
  1. package/dist/App.js +52 -0
  2. package/dist/Login.js +177 -0
  3. package/dist/Reports/CourseReport.js +243 -0
  4. package/dist/Reports/ExamPackReport.js +559 -0
  5. package/dist/Reports/ExamReport.js +290 -0
  6. package/dist/Reports/Report.js +299 -0
  7. package/dist/api/client.js +44 -0
  8. package/dist/components/Header.js +147 -0
  9. package/dist/components/Loader.js +30 -0
  10. package/dist/components/imagePathUrl.js +17 -0
  11. package/dist/components/sidebar.js +78 -0
  12. package/dist/context/TenantProvider.js +34 -0
  13. package/dist/index.js +19 -0
  14. package/dist/package.js +101 -0
  15. package/dist/reportWebVitals.js +27 -0
  16. package/dist/setupTests.js +3 -0
  17. package/package.json +11 -3
  18. package/.env +0 -7
  19. package/public/favicon.ico +0 -0
  20. package/public/images/EResourcesImg.png +0 -0
  21. package/public/images/courseCardImg.png +0 -0
  22. package/public/images/courseInfo.png +0 -0
  23. package/public/images/exam-options.png +0 -0
  24. package/public/images/icleaf-11.png +0 -0
  25. package/public/images/icleaf_logo.png +0 -0
  26. package/public/images/template.png +0 -0
  27. package/public/images/unnamed.png +0 -0
  28. package/public/images/user.jpg +0 -0
  29. package/public/images/young-man-studying-library-using-laptop-1.png +0 -0
  30. package/public/index.html +0 -45
  31. package/public/logo192.png +0 -0
  32. package/public/logo512.png +0 -0
  33. package/public/manifest.json +0 -25
  34. package/public/robots.txt +0 -3
  35. package/src/App.js +0 -37
  36. package/src/Login.js +0 -159
  37. package/src/Reports/CourseReport.js +0 -209
  38. package/src/Reports/ExamPackReport.js +0 -554
  39. package/src/Reports/ExamReport.js +0 -269
  40. package/src/Reports/Report.js +0 -271
  41. package/src/api/client.jsx +0 -42
  42. package/src/components/Header.jsx +0 -192
  43. package/src/components/Loader.jsx +0 -23
  44. package/src/components/imagePathUrl.jsx +0 -11
  45. package/src/components/sidebar.jsx +0 -81
  46. package/src/context/TenantProvider.jsx +0 -22
  47. package/src/index.js +0 -21
  48. package/src/package.js +0 -10
  49. package/src/reportWebVitals.js +0 -13
  50. package/src/setupTests.js +0 -5
  51. /package/{src → dist}/App.css +0 -0
  52. /package/{src → dist}/components/Header.css +0 -0
  53. /package/{src → dist}/components/sidebar.css +0 -0
  54. /package/{src → dist}/fonts/210000.jpg +0 -0
  55. /package/{src → dist}/fonts/210001.jpg +0 -0
  56. /package/{src → dist}/fonts/210003.jpg +0 -0
  57. /package/{src → dist}/fonts/210004.jpg +0 -0
  58. /package/{src → dist}/fonts/210006.jpg +0 -0
  59. /package/{src → dist}/fonts/210018.jpg +0 -0
  60. /package/{src → dist}/fonts/210019.jpg +0 -0
  61. /package/{src → dist}/fonts/210020.jpg +0 -0
  62. /package/{src → dist}/fonts/210279.jpg +0 -0
  63. /package/{src → dist}/fonts/210280.jpg +0 -0
  64. /package/{src → dist}/fonts/Gilroy-Black.ttf +0 -0
  65. /package/{src → dist}/fonts/Gilroy-BlackItalic.ttf +0 -0
  66. /package/{src → dist}/fonts/Gilroy-Bold.ttf +0 -0
  67. /package/{src → dist}/fonts/Gilroy-BoldItalic.ttf +0 -0
  68. /package/{src → dist}/fonts/Gilroy-ExtraBold.ttf +0 -0
  69. /package/{src → dist}/fonts/Gilroy-ExtraBoldItalic.ttf +0 -0
  70. /package/{src → dist}/fonts/Gilroy-Heavy.ttf +0 -0
  71. /package/{src → dist}/fonts/Gilroy-HeavyItalic.ttf +0 -0
  72. /package/{src → dist}/fonts/Gilroy-Light.ttf +0 -0
  73. /package/{src → dist}/fonts/Gilroy-LightItalic.ttf +0 -0
  74. /package/{src → dist}/fonts/Gilroy-Medium.ttf +0 -0
  75. /package/{src → dist}/fonts/Gilroy-MediumItalic.ttf +0 -0
  76. /package/{src → dist}/fonts/Gilroy-Regular.ttf +0 -0
  77. /package/{src → dist}/fonts/Gilroy-RegularItalic.ttf +0 -0
  78. /package/{src → dist}/fonts/Gilroy-SemiBold.ttf +0 -0
  79. /package/{src → dist}/fonts/Gilroy-SemiBoldItalic.ttf +0 -0
  80. /package/{src → dist}/fonts/Gilroy-Thin.ttf +0 -0
  81. /package/{src → dist}/fonts/Gilroy-ThinItalic.ttf +0 -0
  82. /package/{src → dist}/fonts/Gilroy-UltraLight.ttf +0 -0
  83. /package/{src → dist}/fonts/Gilroy-UltraLightItalic.ttf +0 -0
  84. /package/{src → dist}/fonts/Help - Guide Document.pdf +0 -0
  85. /package/{src → dist}/fonts/License.txt +0 -0
  86. /package/{src → dist}/fonts/More Free Fonts on fontshmonts.com.url +0 -0
  87. /package/{src → dist}/fonts/cover.jpg +0 -0
  88. /package/{src → dist}/index.css +0 -0
  89. /package/{src → dist}/login.css +0 -0
  90. /package/{src → dist}/logo.svg +0 -0
  91. /package/{src → dist}/styles.css +0 -0
  92. /package/{src → dist}/theme.css +0 -0
package/src/App.js DELETED
@@ -1,37 +0,0 @@
1
- import React, { useState } from 'react';
2
- import Login from './Login';
3
- import Report from './Reports/Report';
4
- import { HashRouter, Route, Routes } from 'react-router-dom';
5
- import CourseReport from './Reports/CourseReport';
6
- import ExamReport from './Reports/ExamReport';
7
- import ExamPackReport from './Reports/ExamPackReport';
8
- import { TenantProvider } from './context/TenantProvider'; // ADD THIS
9
-
10
- const App = () => {
11
- const userToken = localStorage.getItem("token")
12
-
13
- // Configuration for API calls
14
- const config = {
15
- baseURL: process.env.REACT_APP_BASE_URL || 'http://192.168.2.203:8080/icleafreport',
16
- tenantToken: 'tn_852cf0d3242a11f19d84005056575b50' // Your test token
17
- };
18
-
19
- return (
20
- <TenantProvider config={config}>
21
- <div className="App">
22
- <HashRouter>
23
- <Routes>
24
- <Route path="/" element={userToken != null ? <Report /> : <Login />} />
25
- <Route path="/login" element={userToken != null ? <Report /> : <Login />} />
26
- <Route path="/report" element={<Report />} />
27
- <Route path="/coursereport" element={<CourseReport />} />
28
- <Route path="/examReport" element={<ExamReport />} />
29
- <Route path="/examPackReport" element={<ExamPackReport />} />
30
- </Routes>
31
- </HashRouter>
32
- </div>
33
- </TenantProvider>
34
- );
35
- };
36
-
37
- export default App;
package/src/Login.js DELETED
@@ -1,159 +0,0 @@
1
- import React, { useEffect, useState } from 'react';
2
- import axios from 'axios';
3
- import { useHistory, useNavigate } from 'react-router-dom'; // Correct import statement for useHistory
4
- import { logo, youngMan } from './components/imagePathUrl';
5
- import { RiMailLine, RiLockLine, RiEyeOffLine } from 'react-icons/ri';
6
- import { AiOutlineEyeInvisible, AiOutlineEye } from 'react-icons/ai';
7
- import 'bootstrap/dist/css/bootstrap.css';
8
- import './login.css';
9
- import { Alert, Button, Snackbar } from '@mui/material';
10
-
11
- const Login = () => {
12
- const [username, setUsername] = useState('');
13
- const [password, setPassword] = useState('');
14
- const [showPassword, setShowPassword] = useState(false);
15
- const [error, setError] = useState('');
16
- const [openAlert, setOpenAlert] = useState(false);
17
- const navigate = useNavigate(); // Initialize useHistory
18
-
19
-
20
- // const getSubDomain = () => {
21
- // const hostname = window.location.hostname;
22
- // const parts = hostname.split('.');
23
- // if (parts.length > 2) {
24
- // return parts [0];
25
- // }
26
- // }
27
-
28
- const getSubDomain = () => {
29
- const hostname = window.location.hostname;
30
- console.log("Hostname:", hostname); // debug
31
-
32
- // For localhost without subdomain
33
- if (hostname === "localhost" || hostname === "127.0.0.1") {
34
- return "icleaf";
35
- }
36
-
37
- const parts = hostname.split('.');
38
- if (parts.length > 2) {
39
- return parts[0]; // Returns subdomain
40
- }
41
-
42
- // If no subdomain found
43
- return "icleaf";
44
- };
45
-
46
- const baseURL = process.env.REACT_APP_BASE_URL;
47
-
48
- const handleLogin = async (e) => {
49
- e.preventDefault();
50
-
51
- const subdomain = getSubDomain();
52
- try {
53
- // const response = await axios.get(`${baseURL}` + "api/login?userName=" + username + "&password=" + password);
54
- const response = await axios.get(
55
- `${baseURL}api/login?userName=${username}&password=${password}&subdomain=${subdomain}`
56
- );
57
- console.log(response, "response")
58
- if (response.data) {
59
- var res = response.data;
60
- if (res == "User Not Found") {
61
- setError(res);
62
- setOpenAlert(true);
63
- } else if (res == "UserName or Password cannot be empty") {
64
- setError(res);
65
- setOpenAlert(true);
66
- } else {
67
- localStorage.setItem("token", response.data);
68
- localStorage.setItem("subdomain", subdomain);
69
- navigate('/Report');
70
-
71
- }
72
- }
73
-
74
- } catch (error) {
75
- setError('User Not Found');
76
- setOpenAlert(true);
77
- }
78
- };
79
-
80
- const togglePasswordVisibility = () => {
81
- setShowPassword(!showPassword);
82
- };
83
-
84
- return (
85
- <>
86
- <div className="row page_container">
87
- <div className="col-6 login_container1">
88
- <img className='login_img' src={youngMan} />
89
- </div>
90
- <div className="col-6 login_container2_bg">
91
- <div className='login_form_container'>
92
- <div className='logo_container'>
93
- <img className='logo_img' src={logo} alt="Login logo Image" />
94
- </div>
95
- <text className="welcome_text">Welcome</text>
96
- <form onSubmit={handleLogin}>
97
- <label className='login_label'>Username</label>
98
- <div className='input_contanier'>
99
- <div className="input_icons">
100
- <RiMailLine />
101
- </div>
102
- <input
103
- type="username"
104
- id="username"
105
- name="username"
106
- className='input_box'
107
- placeholder="Username"
108
- // onBlur={(e) => validateForm(e.target.value, language.enterUsername, "userName")}
109
- value={username}
110
- onChange={(e) => {
111
- setUsername(e.target.value);
112
- // validateForm(e.target.value, language.enterUsername, "userName")
113
- }}
114
- />
115
- </div>
116
- <label className='login_label'>Password</label>
117
- <div className='input_contanier'>
118
- <div className="input_icons">
119
- <RiLockLine />
120
- </div>
121
- <input
122
- type={showPassword ? "text" : "password"}
123
- id="password"
124
- name="password"
125
- className='input_box'
126
- // onBlur={(e) => validateForm(e.target.value, language.enterPass, "password")}
127
- placeholder="Password"
128
- value={password}
129
- onChange={(e) => {
130
- setPassword(e.target.value);
131
- // validateForm(e.target.value, language.enterPass, "password")
132
- }}
133
- style={{ userSelect: "none" }}
134
- />
135
- {showPassword ? <AiOutlineEye onClick={() => togglePasswordVisibility()} className="eye-icon_login" /> : <AiOutlineEyeInvisible onClick={() => togglePasswordVisibility()} className="eye-icon_login" />}
136
- </div>
137
- <div className='login_btn_container'>
138
- <Button variant="contained" style={{ width: "100%", marginTop: "15px", padding: "10px" }} type="submit">Login</Button>
139
- </div>
140
- </form>
141
- </div>
142
- </div>
143
-
144
- <Snackbar
145
- open={openAlert}
146
- autoHideDuration={6000}
147
- onClose={() => setOpenAlert(false)}
148
- anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
149
- >
150
- <Alert onClose={() => setOpenAlert(false)} severity="info" sx={{ width: '30%' }}>
151
- {error}
152
- </Alert>
153
- </Snackbar>
154
- </div>
155
- </>
156
- );
157
- };
158
-
159
- export default Login;
@@ -1,209 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import axios from 'axios';
3
- import { Autocomplete, FormControl, Button, Grid, Box, Typography, Paper, Snackbar, Alert, CircularProgress, TextField } from '@mui/material';
4
- import { useNavigate } from 'react-router-dom';
5
- import Header from '../components/Header';
6
- import Sidebar from '../components/sidebar';
7
- import '../App.css';
8
-
9
- function CourseReport() {
10
- const [token, setToken] = useState(localStorage.getItem("token"));
11
- const navigate = useNavigate();
12
- const [subjects, setSubjects] = useState([]);
13
- const [courses, setCourses] = useState([]);
14
- const [selectedSubject, setSelectedSubject] = useState(null);
15
- const [selectedCourse, setSelectedCourse] = useState(null);
16
- const [reportTypes] = useState(['Summary', 'Daywise']);
17
- const [selectedReportType, setSelectedReportType] = useState(null);
18
- const [alertMessage, setAlertMessage] = useState('');
19
- const [loading, setLoading] = useState(false);
20
- const [alertOpen, setAlertOpen] = useState(false);
21
-
22
- const baseURL = process.env.REACT_APP_BASE_URL
23
-
24
- useEffect(() => {
25
- if (token == null) {
26
- navigate("/login");
27
- } else {
28
- fetchAllSubjects();
29
- }
30
- }, []);
31
-
32
- const fetchAllSubjects = async () => {
33
- try {
34
- const response = await axios({
35
- method: "get",
36
- url: `${baseURL}api/showAllSubjects`,
37
- headers: { Authorization: `Bearer ${token}` },
38
- });
39
- setSubjects(response.data);
40
- } catch (error) {
41
- console.error('Error fetching subjects:', error);
42
- }
43
- };
44
-
45
- const fetchCourses = async (subjectId) => {
46
- try {
47
- const response = await axios({
48
- method: "get",
49
- params: { subjectId },
50
- url: `${baseURL}api/getCoursesBySubject`,
51
- headers: { Authorization: `Bearer ${token}` },
52
- });
53
- setCourses(response.data);
54
- } catch (error) {
55
- console.error('Error fetching courses:', error);
56
- }
57
- };
58
-
59
- const handleSubjectChange = (event, newValue) => {
60
- setSelectedSubject(newValue);
61
- setSelectedCourse(null);
62
- setCourses([]);
63
- if (newValue) {
64
- fetchCourses(newValue.subjectId);
65
- }
66
- };
67
-
68
- const handleCourseChange = (event, newValue) => {
69
- setSelectedCourse(newValue);
70
- };
71
-
72
- const handleReportTypeChange = (event, newValue) => {
73
- setSelectedReportType(newValue);
74
- };
75
-
76
- const handleDownload = async () => {
77
- setLoading(true);
78
- try {
79
- let url;
80
- if (selectedReportType === 'Summary') {
81
- url = `${baseURL}api/downloadUserCorpCourseExcel?corpCourseId=${selectedCourse.id}`;
82
- } else if (selectedReportType === 'Daywise') {
83
- url = `${baseURL}api/downloadUserCorpCourseExcelDayWise?corpCourseId=${selectedCourse.id}`;
84
- }
85
-
86
- const response = await axios.get(url, {
87
- responseType: 'blob',
88
- headers: {
89
- Authorization: `Bearer ${token}`
90
- }
91
- });
92
- const contentDisposition = response.headers['content-disposition'];
93
- const text = await response.data.text();
94
- if (text.includes('Course not configured')) {
95
- setAlertMessage('Course not configured.');
96
- setAlertOpen(true);
97
- } else {
98
- const filename = 'course_report.xlsx';
99
- const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
100
- const blobUrl = URL.createObjectURL(blob);
101
- const link = document.createElement('a');
102
- link.href = blobUrl;
103
- link.setAttribute('download', filename);
104
- document.body.appendChild(link);
105
- link.click();
106
- link.parentNode.removeChild(link);
107
- URL.revokeObjectURL(blobUrl);
108
- }
109
- } catch (error) {
110
- console.error('Error downloading course report:', error);
111
- } finally {
112
- setLoading(false);
113
- }
114
- };
115
-
116
-
117
- return (
118
- <div>
119
- <Header />
120
- <Sidebar />
121
- <div style={{ padding: "100px 0px 0px 100px", marginLeft: "140px" }}>
122
- <Box sx={{ maxWidth: 800, mx: 'auto', my: 4, p: 3, backgroundColor: '#f5f5f5', borderRadius: 2 }}>
123
- <Paper elevation={6} sx={{ p: 5, textAlign: 'center', backgroundColor: '#fff' }}>
124
- <Typography variant="h4" component="h1" gutterBottom sx={{ color: '#3f51b5', marginBottom: "20px" }}>
125
- Course Report
126
- </Typography>
127
- <Grid container spacing={2} justifyContent="center">
128
- <Grid item xs={12} sm={4}>
129
- <FormControl fullWidth>
130
- <Autocomplete
131
- id="ddlSubject"
132
- options={subjects}
133
- getOptionLabel={(option) => option.subjectName}
134
- value={selectedSubject}
135
- onChange={handleSubjectChange}
136
- renderInput={(params) => <TextField {...params} label="Subject" />}
137
- />
138
- </FormControl>
139
- </Grid>
140
-
141
- <Grid item xs={12} sm={4}>
142
- <FormControl fullWidth>
143
- <Autocomplete
144
- id="ddlCourse"
145
- options={courses}
146
- getOptionLabel={(option) => option.courseName}
147
- value={selectedCourse}
148
- onChange={handleCourseChange}
149
- renderInput={(params) => <TextField {...params} label="Course" />}
150
- />
151
- </FormControl>
152
- </Grid>
153
-
154
- <Grid item xs={12} sm={4}>
155
- <FormControl fullWidth>
156
- <Autocomplete
157
- id="ddlReportType"
158
- options={reportTypes}
159
- getOptionLabel={(option) => option}
160
- value={selectedReportType}
161
- onChange={handleReportTypeChange}
162
- renderInput={(params) => <TextField {...params} label="Report Type" />}
163
- />
164
- </FormControl>
165
- </Grid>
166
- </Grid>
167
-
168
- <Box sx={{ mt: 3, position: 'relative' }}>
169
- <Button
170
- variant="contained"
171
- color="primary"
172
- onClick={handleDownload}
173
- disabled={!selectedSubject || !selectedCourse || !selectedReportType || loading}
174
- sx={{ width: 'auto', backgroundColor: '#3f51b5', '&:hover': { backgroundColor: '#303f9f' } }}
175
- >
176
- {loading ? 'Downloading...' : 'Download Report'}
177
- </Button>
178
- {loading && (
179
- <CircularProgress
180
- size={24}
181
- sx={{
182
- position: 'absolute',
183
- top: '50%',
184
- left: '50%',
185
- marginTop: '-12px',
186
- marginLeft: '-12px',
187
- }}
188
- />
189
- )}
190
- </Box>
191
- </Paper>
192
- </Box>
193
-
194
- <Snackbar
195
- open={alertOpen}
196
- autoHideDuration={6000}
197
- onClose={() => setAlertOpen(false)}
198
- anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
199
- >
200
- <Alert onClose={() => setAlertOpen(false)} severity="info" sx={{ width: '100%' }}>
201
- {alertMessage}
202
- </Alert>
203
- </Snackbar>
204
- </div>
205
- </div>
206
- );
207
- }
208
-
209
- export default CourseReport;