|
1 | | -/* eslint-disable complexity */ |
2 | | -import React from 'react'; |
3 | | -import { withRouter, Route, Switch, Redirect } from 'dva/router'; |
4 | | -import dynamic from "dva/dynamic"; |
5 | | -import { env,user } from 'utils'; |
6 | | -// import AppInsightsProvider from './azure-app-insights'; |
| 1 | +// src/App.js |
| 2 | +import React, { Suspense, useEffect } from 'react'; |
7 | 3 | import { |
8 | | - // General |
9 | | - NotFound404, |
10 | | - Maintenance, |
11 | | - SignIn, |
12 | | - AuthCallback, |
13 | | - // Admin |
14 | | - Admin, |
15 | | - // Instructor |
16 | | - MyCourses, |
17 | | - NewCourse, |
18 | | - CourseSettings, |
19 | | - CourseAnalytics, |
20 | | - InstPlaylist, |
21 | | - MediaSettings, |
22 | | - NewPlaylist, |
23 | | - Embed, |
24 | | - EPub, |
25 | | - // Student |
26 | | - Home, |
27 | | - Course, |
28 | | - Search, |
29 | | - History, |
30 | | - Analytics, |
31 | | - Glossary, |
32 | | - Asl, |
33 | | - Watch, |
34 | | - // ComponentAPI, |
35 | | - // Example |
36 | | -} from './screens'; |
| 4 | + Route, |
| 5 | + Routes, |
| 6 | + Navigate, |
| 7 | +} from 'react-router-dom'; |
37 | 8 |
|
| 9 | +import { env, user } from 'utils'; |
38 | 10 | import './App.css'; |
39 | | -// import 'braft-editor/dist/index.scss'; |
40 | | -// Can this be deleted? import { altEl } from './layout'; |
41 | 11 |
|
42 | | -class App extends React.Component { |
43 | | - componentDidMount() { |
| 12 | +// importing components like this (not lazily) is sketchy and inconsistent. |
| 13 | +import { UploadFiles } from 'screens/Instructor/InstPlaylist/components'; |
| 14 | +import { UploadSingleFile } from 'screens/Instructor/InstPlaylist/components/MediaList/UploadFile'; |
| 15 | +import { EPub, Transcriptions } from 'screens/MediaSettings/Tabs'; |
| 16 | +import { adminTabs } from 'screens/Admin/tabs'; |
| 17 | + |
| 18 | +// Lazy load screens |
| 19 | +const lazyImport = (exportName) => |
| 20 | + React.lazy(() => |
| 21 | + import(`./screens`).then(module => ({ default: module[exportName] })) |
| 22 | + ); |
| 23 | +const WatchPage = lazyImport('Watch'); |
| 24 | +const EPubPage = lazyImport('EPub'); |
| 25 | +const CoursePage = lazyImport('Course'); |
| 26 | +const MyCoursesPage = lazyImport('MyCourses'); |
| 27 | +const InstPlaylistPage = lazyImport('InstPlaylist'); |
| 28 | +const MediaSettingsPage = lazyImport('MediaSettings'); |
| 29 | + |
| 30 | +const NotFound404 = lazyImport('NotFound404'); |
| 31 | +const Maintenance = lazyImport('Maintenance'); |
| 32 | +const SignIn = lazyImport('SignIn'); |
| 33 | +const AuthCallback = lazyImport('AuthCallback'); |
| 34 | +const Admin = lazyImport('Admin'); |
| 35 | +const NewCourse = lazyImport('NewCourse'); |
| 36 | +const CourseSettings = lazyImport('CourseSettings'); |
| 37 | +const CourseAnalytics = lazyImport('CourseAnalytics'); |
| 38 | +const NewPlaylist = lazyImport('NewPlaylist'); |
| 39 | +const Embed = lazyImport('Embed'); |
| 40 | +const Home = lazyImport('Home'); |
| 41 | +const Search = lazyImport('Search'); |
| 42 | +const History = lazyImport('History'); |
| 43 | +const Analytics = lazyImport('Analytics'); |
| 44 | +const Glossary = lazyImport('Glossary'); |
| 45 | +const Asl = lazyImport('Asl'); |
| 46 | + |
| 47 | +const UniversityEditing = React.lazy(() => import(`screens/Admin/Universities/UniversityEditing`)); |
| 48 | +const TermEditing = React.lazy(() => import(`screens/Admin/Terms/TermEditing`)); |
| 49 | +const InstructorEditing = React.lazy(() => import(`screens/Admin/Instructors/InstructorEditing`)); |
| 50 | +const CourseEditing = React.lazy(() => import(`screens/Admin/Courses/CourseEditing`)); |
| 51 | +const DepartmentEditing = React.lazy(() => import(`screens/Admin/Departments/DepartmentEditing`)); |
| 52 | + |
| 53 | +function App() { |
| 54 | + useEffect(() => { |
44 | 55 | user.validate(); |
45 | | - } |
46 | | - |
47 | | - render() { |
48 | | - const isAdminOrInstructor = user.isInstructor || user.isAdmin; |
49 | | - |
50 | | - // no apparent purpose const adminRoute = altEl(); |
51 | | - |
52 | | - // Lazy Load |
53 | | - const WatchPage = dynamic({ |
54 | | - app: this.props.app, |
55 | | - models: () => [], |
56 | | - component: () => Watch |
57 | | - }) |
58 | | - const EPubPage = dynamic({ |
59 | | - app: this.props.app, |
60 | | - models: () => [require('./screens/EPub/model').default], |
61 | | - component: () => EPub |
62 | | - }) |
63 | | - const CoursePage = dynamic({ |
64 | | - app: this.props.app, |
65 | | - models: () => [], // require('./screens/Course/model').default |
66 | | - component: () => Course |
67 | | - }) |
68 | | - const MyCoursesPage = dynamic({ |
69 | | - app: this.props.app, |
70 | | - models: () => [require('./screens/Instructor/MyCourses/model').default], // |
71 | | - component: () => MyCourses |
72 | | - }) |
73 | | - const InstPlaylistPage = dynamic({ |
74 | | - app: this.props.app, |
75 | | - models: () => [require('./screens/Instructor/InstPlaylist/model')], |
76 | | - component: () => InstPlaylist |
77 | | - }) |
78 | | - const MediaSettingsPage = dynamic({ |
79 | | - app: this.props.app, |
80 | | - models: () => [require('./screens/MediaSettings/model')], |
81 | | - component: () => MediaSettings |
82 | | - }) |
83 | | - if( env.classTranscribeDownMessage ) return <Maintenance /> |
84 | | - return ( |
85 | | - // <AppInsightsProvider> |
86 | | - <Switch> |
87 | | - {user.callbackPaths.map((path)=><Route exact path={path} key={path} component={AuthCallback} /> )} |
88 | | - <Route exact path="/sign-in" component={SignIn} /> |
| 56 | + }, []); |
| 57 | + |
| 58 | + const isAdminOrInstructor = user.isInstructor || user.isAdmin; |
| 59 | + |
| 60 | + const adminRoutes = !user.isAdmin ? [] : |
| 61 | + adminTabs.map(tab => { |
| 62 | + let RouteElem = tab.component; |
| 63 | + return { |
| 64 | + ...tab, |
| 65 | + element: <RouteElem /> |
| 66 | + } |
| 67 | + }); |
| 68 | + |
| 69 | + if (env.classTranscribeDownMessage) return <Maintenance />; |
| 70 | + |
| 71 | + return ( |
| 72 | + <Suspense fallback={<div>Loading...</div>}> |
| 73 | + <Routes> |
| 74 | + {user.callbackPaths.map((path) => ( |
| 75 | + <Route exact path={path} key={path} element={<AuthCallback />} /> |
| 76 | + ))} |
| 77 | + <Route exact path="/sign-in" element={<SignIn />} /> |
89 | 78 |
|
90 | 79 | {/* Admin */} |
91 | | - {user.isAdmin && <Route path="/admin" component={Admin} />} |
| 80 | + {user.isAdmin && ( |
| 81 | + <Route path="/admin" element={<Admin />}> |
| 82 | + <Route path="/admin" element={<Navigate to={adminRoutes[0].href} replace />} /> |
| 83 | + |
| 84 | + {adminRoutes.map(route => ( |
| 85 | + <Route |
| 86 | + key={route.value} |
| 87 | + path={route.href} |
| 88 | + element={route.element} |
| 89 | + /> |
| 90 | + ))} |
| 91 | + <Route path="/admin/universities/:id/:type?" element={<UniversityEditing />} /> |
| 92 | + <Route path="/admin/terms/:id/:type?" element={<TermEditing />} /> |
| 93 | + <Route path="/admin/instructors/:id/:type?" element={<InstructorEditing />} /> |
| 94 | + <Route path="/admin/course-template/:id/:type?" element={<CourseEditing />} /> |
| 95 | + <Route path="/admin/departments/:id/:type?" element={<DepartmentEditing />} /> |
| 96 | + |
| 97 | + </Route> |
| 98 | + )} |
| 99 | + |
92 | 100 |
|
93 | 101 | {/* Instructor */} |
94 | | - <Route exact path="/instructor" render={() => <Redirect to="/instructor/my-courses" />} /> |
95 | | - { |
96 | | - isAdminOrInstructor |
97 | | - && |
98 | | - <Route exact path="/instructor/my-courses" component={MyCoursesPage} /> |
99 | | - } |
100 | | - { |
101 | | - isAdminOrInstructor |
102 | | - && |
103 | | - <Route exact path="/instructor/new-course" component={NewCourse} /> |
104 | | - } |
105 | | - { |
106 | | - isAdminOrInstructor |
107 | | - && |
108 | | - <Route exact path="/offering/:id/settings" component={CourseSettings} /> |
109 | | - } |
110 | | - { |
111 | | - isAdminOrInstructor |
112 | | - && |
113 | | - <Route exact path="/offering/:id/analytics" component={CourseAnalytics} /> |
114 | | - } |
115 | | - { |
116 | | - isAdminOrInstructor |
117 | | - && |
118 | | - <Route exact path="/offering/:id/new-playlist" component={NewPlaylist} /> |
119 | | - } |
120 | | - { |
121 | | - isAdminOrInstructor |
122 | | - && |
123 | | - <Route path="/media-settings/:id" component={MediaSettingsPage} /> |
124 | | - } |
125 | | - |
126 | | - { |
127 | | - isAdminOrInstructor |
128 | | - && |
129 | | - <Route path="/epub/:id" component={EPubPage} /> |
130 | | - } |
| 102 | + <Route path="/instructor" element={<Navigate to="/instructor/my-courses" replace />} /> |
| 103 | + {isAdminOrInstructor && ( |
| 104 | + <> |
| 105 | + <Route exact path="/instructor/my-courses" element={<MyCoursesPage />} /> |
| 106 | + <Route exact path="/instructor/new-course" element={<NewCourse />} /> |
| 107 | + <Route exact path="/offering/:id/settings" element={<CourseSettings />} /> |
| 108 | + <Route exact path="/offering/:id/analytics" element={<CourseAnalytics />} /> |
| 109 | + <Route exact path="/offering/:id/new-playlist" element={<NewPlaylist />} /> |
| 110 | + <Route path="/media-settings/:id" element={<MediaSettingsPage />}> |
| 111 | + <Route path="/media-settings/:id/epub" element={<EPub />} /> |
| 112 | + <Route path="/media-settings/:id/trans" element={<Transcriptions />} /> |
| 113 | + </Route> |
| 114 | + <Route path="/epub/:id" element={<EPubPage />} /> |
| 115 | + </> |
| 116 | + )} |
131 | 117 |
|
132 | 118 | {/* Student */} |
133 | | - <Route exact path="/" component={Home} /> |
134 | | - <Route exact path="/home" render={() => <Redirect to="/" />} /> |
135 | | - <Route exact path="/offering/:id" component={CoursePage} /> |
136 | | - <Route exact path="/search" component={Search} /> |
137 | | - <Route exact path="/history" component={History} /> |
138 | | - <Route exact path="/personal-analytics" component={Analytics} /> |
139 | | - <Route exact path="/glossary" component={Glossary} /> |
140 | | - <Route exact path="/asl" component={Asl} /> |
141 | | - <Route exact path="/video" component={WatchPage} /> |
142 | | - <Route exact path="/embed/:id" component={Embed} /> |
143 | | - <Route path="/playlist/:id" component={InstPlaylistPage} /> |
144 | | - |
145 | | - <Route path="/404" component={NotFound404} /> |
146 | | - |
147 | | - |
148 | | - { |
149 | | - // env.dev |
150 | | - // && |
151 | | - // <Route exact path="/example" component={Example} /> |
152 | | - } |
153 | | - |
154 | | - <Route component={NotFound404} /> |
155 | | - {/* <Route exact path="/docs/component-api/:type" component={ComponentAPI} /> */} |
156 | | - </Switch> |
157 | | - // </AppInsightsProvider> |
158 | | - ); |
159 | | - } |
| 119 | + <Route exact path="/" element={<Home />} /> |
| 120 | + <Route exact path="/home" element={<Navigate to="/" replace />} /> |
| 121 | + <Route exact path="/offering/:id" element={<CoursePage />} /> |
| 122 | + <Route exact path="/search" element={<Search />} /> |
| 123 | + <Route exact path="/history" element={<History />} /> |
| 124 | + <Route exact path="/personal-analytics" element={<Analytics />} /> |
| 125 | + <Route exact path="/glossary" element={<Glossary />} /> |
| 126 | + <Route exact path="/asl" element={<Asl />} /> |
| 127 | + <Route exact path="/video" element={<WatchPage />} /> |
| 128 | + <Route exact path="/embed/:id" element={<Embed />} /> |
| 129 | + <Route path="/playlist/:id" element={<InstPlaylistPage />}> |
| 130 | + <Route path="/playlist/:id/upload-files" element={<UploadFiles />} /> |
| 131 | + <Route path="/playlist/:id/media/:mediaId/upload-asl" element={<UploadSingleFile />} /> |
| 132 | + </Route> |
| 133 | + |
| 134 | + <Route path="/404" element={<NotFound404 />} /> |
| 135 | + <Route element={<NotFound404 />} /> |
| 136 | + </Routes> |
| 137 | + </Suspense> |
| 138 | + ); |
160 | 139 | } |
161 | 140 |
|
162 | | -export default withRouter(App); |
| 141 | +export default App; |
| 142 | + |
| 143 | + |
0 commit comments