Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SRCT
schedules
Commits
47856176
Commit
47856176
authored
Sep 20, 2018
by
Zac Wood
Browse files
Deleted schedules_web rip
parent
8a7f09b7
Changes
39
Show whitespace changes
Inline
Side-by-side
schedules_web/.gitignore
deleted
100644 → 0
View file @
8a7f09b7
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/dist
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.vscode/
schedules_web/.prettierrc
deleted
100644 → 0
View file @
8a7f09b7
{
"printWidth": 120,
"tabWidth": 4,
"singleQuote": true,
"useTabs": false,
"jsxBracketSameLine": true,
"trailingComma": "es5"
}
schedules_web/Dockerfile
deleted
100644 → 0
View file @
8a7f09b7
FROM
node:9
COPY
. /web
WORKDIR
/web
RUN
yarn
install
&&
yarn run build
FROM
nginx:1.15.0
COPY
--from=0 /web/dist /web
schedules_web/Dockerfile.dev
deleted
100644 → 0
View file @
8a7f09b7
FROM node:9
# Copy the project files to /web
COPY . /web
# Tell Docker to run all commands in /api
WORKDIR /web
# Install project dependencies
RUN yarn
schedules_web/app.js
deleted
100644 → 0
View file @
8a7f09b7
var
path
=
require
(
'
path
'
);
var
express
=
require
(
'
express
'
);
var
DIST_DIR
=
path
.
join
(
__dirname
,
'
dist
'
);
var
PORT
=
8080
;
var
app
=
express
();
//Serving the files on the dist folder
app
.
use
(
express
.
static
(
DIST_DIR
));
//Send index.html when the user access the web
app
.
get
(
'
*
'
,
function
(
req
,
res
)
{
res
.
sendFile
(
path
.
join
(
DIST_DIR
,
'
index.html
'
));
});
app
.
listen
(
PORT
);
schedules_web/favicon.ico
deleted
100644 → 0
View file @
8a7f09b7
1.12 KB
schedules_web/index.html
deleted
100644 → 0
View file @
8a7f09b7
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1, shrink-to-fit=no"
>
<title>
SRCT Schedules • Welcome
</title>
<meta
name=
"theme-color"
content=
"#006633"
/>
<!-- FB/Opengraph tags -->
<meta
property=
"og:url"
content=
"https://schedules.gmu.edu/"
>
<meta
property=
"og:type"
content=
"website"
>
<meta
property=
"og:title"
content=
"SRCT Schedules"
>
<meta
property=
"og:description"
content=
"Easily generate a calendar with your class schedule."
>
<meta
property=
"og:site_name"
content=
"SRCT Schedules"
>
<meta
property=
"og:locale"
content=
"en_US"
>
<meta
property=
"article:author"
content=
"SRCT"
>
<!-- Twitter card tags -->
<meta
name=
"twitter:card"
content=
"summary"
>
<meta
name=
"twitter:site"
content=
"@MasonSRCT"
>
<meta
name=
"twitter:creator"
content=
"@MasonSRCT"
>
<meta
name=
"twitter:url"
content=
"https://schedules.gmu.edu/"
>
<meta
name=
"twitter:title"
content=
"SRCT Schedules"
>
<meta
name=
"twitter:description"
content=
"Easily generate a calendar with your class schedule."
>
</head>
<body>
<div
id=
"root"
></div>
<!-- Matomo -->
<script
type=
"text/javascript"
>
var
_paq
=
_paq
||
[];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq
.
push
([
'
trackPageView
'
]);
_paq
.
push
([
'
enableLinkTracking
'
]);
(
function
()
{
var
u
=
"
//matomo.srct.gmu.edu/
"
;
_paq
.
push
([
'
setTrackerUrl
'
,
u
+
'
piwik.php
'
]);
_paq
.
push
([
'
setSiteId
'
,
'
3
'
]);
var
d
=
document
,
g
=
d
.
createElement
(
'
script
'
),
s
=
d
.
getElementsByTagName
(
'
script
'
)[
0
];
g
.
type
=
'
text/javascript
'
;
g
.
async
=
true
;
g
.
defer
=
true
;
g
.
src
=
u
+
'
piwik.js
'
;
s
.
parentNode
.
insertBefore
(
g
,
s
);
})();
</script>
<!-- End Matomo Code -->
</body>
</html>
schedules_web/nginx.conf
deleted
100644 → 0
View file @
8a7f09b7
user
nginx
;
worker_processes
1
;
error_log
/var/log/nginx/error.log
warn
;
pid
/var/run/nginx.pid
;
events
{
worker_connections
1024
;
}
http
{
upstream
backend
{
server
api
:
3000
;
}
include
/etc/nginx/mime.types
;
default_type
application/octet-stream
;
log_format
main
'
$remote_addr
-
$remote_user
[
$time_local
]
"
$request
"
'
'
$status
$body_bytes_sent
"
$http_referer
"
'
'"
$http_user_agent
"
"
$http_x_forwarded_for
"'
;
access_log
/var/log/nginx/access.log
main
;
sendfile
on
;
#tcp_nopush on;
keepalive_timeout
65
;
#gzip on;
server
{
listen
80
;
location
/
{
root
/web
;
index
index.html
;
}
location
/api
{
proxy_pass
http://backend/
;
}
}
}
schedules_web/package.json
deleted
100644 → 0
View file @
8a7f09b7
{
"name"
:
"schedules_web"
,
"version"
:
"1.0.0"
,
"main"
:
"index.js"
,
"scripts"
:
{
"build"
:
"webpack --config webpack.prod.js --debug --progress"
,
"start"
:
"webpack-dev-server --config webpack.dev.js --inline"
,
"prod"
:
"node app.js"
},
"license"
:
"Apache"
,
"private"
:
true
,
"devDependencies"
:
{
"@types/file-saver"
:
"^1.3.0"
,
"@types/node"
:
"^9.6.6"
,
"awesome-typescript-loader"
:
"^5.0.0"
,
"source-map-loader"
:
"^0.2.3"
,
"typescript"
:
"^2.8.3"
,
"webpack"
:
"^4.6.0"
,
"webpack-cli"
:
"^2.0.15"
,
"webpack-dev-server"
:
"^3.1.3"
},
"dependencies"
:
{
"@types/react"
:
"^16.3.12"
,
"@types/react-dom"
:
"^16.0.5"
,
"@types/react-redux"
:
"^6.0.2"
,
"@types/reactstrap"
:
"^6.0.0"
,
"babel-loader"
:
"^7.1.4"
,
"clean-webpack-plugin"
:
"^0.1.19"
,
"css-loader"
:
"^0.28.11"
,
"express"
:
"^4.16.3"
,
"file-loader"
:
"^1.1.11"
,
"file-saver"
:
"^1.3.8"
,
"html-webpack-plugin"
:
"^3.2.0"
,
"masonstrap"
:
"https://git.gmu.edu/srct/masonstrap.git"
,
"react"
:
"^16.3.2"
,
"react-dom"
:
"^16.3.2"
,
"react-redux"
:
"^5.0.7"
,
"reactstrap"
:
"^6.1.0"
,
"redux"
:
"^4.0.0"
,
"redux-thunk"
:
"^2.3.0"
,
"style-loader"
:
"^0.21.0"
,
"url-loader"
:
"^1.0.1"
,
"webpack-merge"
:
"^4.1.4"
},
"babel"
:
{
"presets"
:
[
"es2015"
]
}
}
schedules_web/src/actions/schedule/schedule.action-types.ts
deleted
100644 → 0
View file @
8a7f09b7
export
const
ADD_COURSE_SECTION
:
string
=
'
[Schedule] ADD_COURSE_SECTION
'
;
export
const
REMOVE_COURSE_SECTION
:
string
=
'
[Schedule] REMOVE_COURSE_SECTION
'
;
schedules_web/src/actions/schedule/schedule.actions.ts
deleted
100644 → 0
View file @
8a7f09b7
import
CourseSection
from
'
../../util/CourseSection
'
;
import
{
ADD_COURSE_SECTION
,
REMOVE_COURSE_SECTION
}
from
'
./schedule.action-types
'
;
export
interface
ScheduleAction
{
type
:
string
;
// What action is to be performed
courseSection
:
CourseSection
;
// The section that is being added/removed
}
/**
* Add a section to the Schedule
* @param section The section that is to be added
*/
export
const
addCourseSection
=
(
courseSectionToAdd
:
CourseSection
):
ScheduleAction
=>
({
type
:
ADD_COURSE_SECTION
,
courseSection
:
courseSectionToAdd
,
});
/**
* Remove a section from the Schedule
* @param section The section that is to be removed
*/
export
const
removeCourseSection
=
(
courseSectionToRemove
:
CourseSection
):
ScheduleAction
=>
({
type
:
REMOVE_COURSE_SECTION
,
courseSection
:
courseSectionToRemove
,
});
schedules_web/src/actions/search/search.action-types.ts
deleted
100644 → 0
View file @
8a7f09b7
export
const
SET_SEARCH_RESULTS
:
string
=
'
[Search] SET_SEARCH_RESULTS
'
;
schedules_web/src/actions/search/search.actions.ts
deleted
100644 → 0
View file @
8a7f09b7
import
ApiService
from
'
../../util/ApiService
'
;
import
CourseSection
from
'
../../util/CourseSection
'
;
import
{
SET_SEARCH_RESULTS
}
from
'
./search.action-types
'
;
export
interface
SearchAction
{
type
:
string
;
searchResults
:
CourseSection
[];
error
:
string
;
}
export
const
searchCourseSections
=
(
crn
:
string
)
=>
async
(
dispatch
:
any
)
=>
{
const
objects
=
await
ApiService
.
searchCourseSections
(
crn
);
const
results
:
CourseSection
[]
=
objects
.
map
(
(
object
:
any
):
CourseSection
=>
({
id
:
object
.
id
,
name
:
object
.
name
,
title
:
object
.
title
,
crn
:
object
.
crn
,
instructor
:
object
.
instructor_name
,
location
:
object
.
location
,
days
:
object
.
days
,
startTime
:
object
.
start_time
,
endTime
:
object
.
end_time
,
})
);
dispatch
({
type
:
SET_SEARCH_RESULTS
,
searchResults
:
results
,
error
:
results
.
length
===
0
?
'
No course sections found with the given CRN.
'
:
''
,
});
};
schedules_web/src/components/App.tsx
deleted
100644 → 0
View file @
8a7f09b7
import
*
as
React
from
'
react
'
;
import
{
Container
}
from
'
reactstrap
'
;
import
Schedule
from
'
../containers/Schedule
'
;
import
Search
from
'
../containers/Search
'
;
import
Header
from
'
./Header
'
;
require
(
'
../css/core.css
'
);
/**
* The root component for the app
*/
const
App
=
()
=>
(
<
div
>
<
Container
>
<
Schedule
/>
<
Header
/>
<
Search
/>
</
Container
>
</
div
>
);
export
default
App
;
schedules_web/src/components/CourseSectionCard.tsx
deleted
100644 → 0
View file @
8a7f09b7
import
*
as
React
from
'
react
'
;
import
{
Button
,
Card
,
CardBody
,
CardTitle
,
Col
,
Row
}
from
'
reactstrap
'
;
import
CourseSection
from
'
../util/CourseSection
'
;
interface
CourseSectionCardProps
{
courseSectionAction
:
(
courseSection
:
CourseSection
)
=>
void
;
courseSection
:
CourseSection
;
courseSectionActionButtonText
:
string
;
destructive
?:
boolean
;
}
require
(
'
../css/button-text-override.css
'
);
/**
* Renders information about a single course section, and includes a
* button for adding/removing it from the current schedule.
*/
const
CourseSectionCard
=
({
courseSection
,
courseSectionAction
,
courseSectionActionButtonText
,
destructive
,
}:
CourseSectionCardProps
)
=>
(
<
Row
className
=
"justify-content-center my-3"
>
<
Col
md
=
"9"
>
<
Card
>
<
CardBody
>
<
CardTitle
className
=
"mb-4"
>
<
i
className
=
"fas fa-hashtag"
/>
{
courseSection
.
crn
}
</
CardTitle
>
<
Row
>
<
Col
md
=
"6"
>
<
div
className
=
"mb-4"
>
<
h4
>
{
courseSection
.
title
}
</
h4
>
<
p
>
{
courseSection
.
name
}
</
p
>
</
div
>
<
i
className
=
"fas fa-chalkboard-teacher fa-fw"
/>
{
courseSection
.
instructor
}
<
br
/>
<
i
className
=
"fas fa-clock fa-fw"
/>
{
courseSection
.
days
}
,
{
courseSection
.
startTime
}
-
{
'
'
}
{
courseSection
.
endTime
}
<
br
/>
<
i
className
=
"fas fa-school fa-fw"
/>
{
courseSection
.
location
}
</
Col
>
<
Col
md
=
"6"
>
<
Button
onClick
=
{
()
=>
courseSectionAction
(
courseSection
)
}
color
=
{
destructive
?
'
danger
'
:
'
primary
'
}
size
=
"lg"
block
className
=
"shadow-sm mt-3"
>
<
i
className
=
{
`fas fa-
${
destructive
?
'
minus
'
:
'
plus
'
}
-circle mr-2 fa-fw`
}
/>
{
'
'
}
{
courseSectionActionButtonText
}
</
Button
>
</
Col
>
</
Row
>
</
CardBody
>
</
Card
>
</
Col
>
</
Row
>
);
export
default
CourseSectionCard
;
schedules_web/src/components/CourseSectionList.tsx
deleted
100644 → 0
View file @
8a7f09b7
import
*
as
React
from
'
react
'
;
import
CourseSection
from
'
../util/CourseSection
'
;
import
CourseSectionCard
from
'
./CourseSectionCard
'
;
interface
CourseSectionListProps
{
courseSections
:
CourseSection
[];
courseSectionAction
:
(
courseSection
:
CourseSection
)
=>
void
;
courseSectionActionButtonText
:
string
;
destructive
?:
boolean
;
}
/**
* Renders a list of CourseSectionCards for every course section in
* the current schedule.
*/
const
CourseSectionList
=
({
courseSections
,
courseSectionAction
,
courseSectionActionButtonText
,
destructive
,
}:
CourseSectionListProps
)
=>
(
<
div
>
{
courseSections
.
map
(
courseSection
=>
(
<
CourseSectionCard
key
=
{
courseSection
.
crn
}
courseSection
=
{
courseSection
}
courseSectionAction
=
{
courseSectionAction
}
courseSectionActionButtonText
=
{
courseSectionActionButtonText
}
destructive
=
{
destructive
}
/>
))
}
</
div
>
);
export
default
CourseSectionList
;
schedules_web/src/components/ExportModal.tsx
deleted
100644 → 0
View file @
8a7f09b7
import
*
as
React
from
'
react
'
;
import
{
Button
,
Modal
,
ModalHeader
,
ModalBody
,
ModalFooter
}
from
'
reactstrap
'
;
import
{
downloadFile
}
from
'
../util/utilities
'
;
interface
ExportModalProps
{
isModalOpen
:
boolean
;
toggleModal
:
()
=>
void
;
calendarUrl
:
()
=>
string
;
openCalendarAsWebcal
:
()
=>
void
;
downloadIcs
:
()
=>
Promise
<
void
>
;
}
/**
* Modal view that contains buttons for exporting your schedule as
* well as instructions for importing your schedule into different
* calendar managers
*/
const
ExportModal
=
({
isModalOpen
,
toggleModal
,
calendarUrl
,
openCalendarAsWebcal
,
downloadIcs
,
}:
ExportModalProps
)
=>
(
<
Modal
isOpen
=
{
isModalOpen
}
toggle
=
{
toggleModal
}
>
<
ModalHeader
toggle
=
{
toggleModal
}
>
Your calendar has been generated!
</
ModalHeader
>
<
ModalBody
>
<
h5
>
Apple Calendar
</
h5
>
To add your schedule to Apple Calendar, click the "Add to calendar" button below. If you are on a device
running macOS or iOS, this will open a dialogue which will walk you through adding the calendar.
<
hr
/>
<
h5
>
Google Calendar
</
h5
>
<
strong
>
On desktop:
</
strong
>
<
br
/>
Open your
<
a
href
=
"https://calendar.google.com/"
>
Google Calendar
</
a
>
. Click the "Settings" button in the top
right, and then click the Settings tab. In the menu on the left, click "Add calendar" and "From URL". Now,
paste the following link inside the text box:
<
br
/>
<
code
>
{
calendarUrl
()
}
</
code
>
<
br
/>
<
strong
>
On mobile (Android only):
</
strong
>
<
br
/>
Click the "Download calendar file" button. This will download the calendar file which you may then open and
add to your calendar.
<
hr
/>
<
h5
>
.ics file
</
h5
>
To download a .ics file containing your schedule, click the "Download calendar file" button below.
</
ModalBody
>
<
ModalFooter
>
<
Button
color
=
"secondary"
onClick
=
{
downloadIcs
}
>
Download calendar file
</
Button
>
<
Button
color
=
"primary"
onClick
=
{
openCalendarAsWebcal
}
>
Add to calendar
</
Button
>
{
'
'
}
</
ModalFooter
>
</
Modal
>
);
export
default
ExportModal
;
schedules_web/src/components/Header.tsx
deleted
100644 → 0
View file @
8a7f09b7
import
*
as
React
from
'
react
'
;
import
{
Col
,
Row
,
UncontrolledTooltip
}
from
'
reactstrap
'
;
/**
* Renders the app header with information and instructions for using Schedules.
*/
const
Header
=
()
=>
(
<
div
>
<
Row
className
=
"justify-content-center my-5"
>
<
h1
>
<
i
className
=
"far fa-calendar-alt"
/>
Schedules
</
h1
>
<
div
className
=
"w-100 mb-3"
/>
<
Col
md
=
"6"
>
<
p
>
An application to generate a schedule
{
'
(
'
}
<
span
style
=
{
{
textDecoration
:
'
underline
'
}
}
id
=
"UncontrolledTooltipExample"
>
<
i
className
=
"fas fa-question"
/>
</
span
>
<
UncontrolledTooltip
placement
=
"right"
target
=
"UncontrolledTooltipExample"
>
Find your class' CRNs on Patriot Web under Student Services > Registration > Student Schedule
</
UncontrolledTooltip
>
{
'
)
'
}
to place into your calendar populated with class times. Built and maintained by
{
'
'
}
<
a
href
=
"https://srct.gmu.edu"
>
Mason SRCT
</
a
>
.
</
p
>
</
Col
>
</
Row
>
</
div
>
);
export
default
Header
;
schedules_web/src/components/ScheduleBadge.tsx
deleted
100644 → 0
View file @
8a7f09b7
import
*
as
React
from
'
react
'
;
import
{
Button
,
Card
,
CardBody
,
CardTitle
,
Collapse
,
Row
}
from
'
reactstrap
'
;
import
CourseSection
from
'
../util/CourseSection
'
;
import
CourseSectionList
from
'
./CourseSectionList
'
;
import
ExportModal
from
'
./ExportModal
'
;
interface
ScheduleBadgeProps
{
schedule
:
CourseSection
[];
removeCourseSection
:
(
courseSection
:
CourseSection
)
=>
void
;
generateCalendarUrl
:
()
=>
string
;
openCalendarAsWebcal
:
()
=>
void
;
downloadIcs
:
()
=>
Promise
<
void
>
;
}
interface
State
{
collapse
:
boolean
;
isModalOpen
:
boolean
;
}
require
(
'
../css/icon-badge.css
'
);
/**
* Contains all functionality for viewing your schedule, such as the
* shopping cart, list of course sections, and the generate calendar modal.
*
* TODO: Split this component up
*/
class
ScheduleBadge
extends
React
.
Component
<
ScheduleBadgeProps
,
State
>
{
constructor
(
props
:
ScheduleBadgeProps
)
{
super
(
props
);
this
.
state
=
{
collapse
:
false
,
isModalOpen
:
false
};
}
toggleCollapse
=
()
=>
this
.
setState
({
collapse
:
!
this
.
state
.
collapse
});
toggleModal
=
()
=>
this
.
setState
({
isModalOpen
:
!
this
.
state
.
isModalOpen
});
render
()
{
const
{
schedule
,
removeCourseSection
,
generateCalendarUrl
,
openCalendarAsWebcal
,
downloadIcs
}
=
this
.
props
;
return
(
<
div
>
<
Row
className
=
"justify-content-end"
>
<
Button
children
=
{
<
span
className
=
"fa-stack fa-3x has-badge"
data
-
count
=
{
this
.
props
.
schedule
.
length
}
>
<
i
className
=
"fa fas fa-shopping-bag fa-stack-1x"
/>
</
span
>
}
onClick
=
{
this
.
toggleCollapse
}
id
=
"cart"
/>
</
Row
>
<
Collapse
isOpen
=
{
this
.
state
.
collapse
}
>
<
Card
>
<
CardBody
>
<
Row
className
=
"my-3"
>
<
h1
className
=
"px-5"
>
Your Schedule
</
h1
>
<
Button
className
=
"ml-auto px-5"
outline
color
=
"danger"
onClick
=
{
this
.
toggleCollapse
}
>
Close
</
Button
>
</
Row
>
<
CourseSectionList
courseSections
=
{
schedule
}
courseSectionAction
=
{
removeCourseSection
}
courseSectionActionButtonText
=
"Remove from schedule"
destructive
/>
<
Row
className
=
"justify-content-center"
>
<
Button
size
=
"sm"
outline
color
=
"primary"
onClick
=
{
this
.
toggleModal
}
disabled
=
{
schedule
.
length
===
0
}
>
Generate
</
Button
>
</
Row
>
</
CardBody
>
</
Card
>
</
Collapse
>
<
ExportModal
isModalOpen
=
{
this
.
state
.
isModalOpen
}
toggleModal
=
{
this
.
toggleModal
}
calendarUrl
=
{
generateCalendarUrl
}
openCalendarAsWebcal
=
{
openCalendarAsWebcal
}
downloadIcs
=
{
downloadIcs
}
/>
</
div
>
);
}
}
export
default
ScheduleBadge
;